vermonster 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ *.gem
2
+ .bundle
3
+ pkg/*
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,43 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ vermonster (0.1.1)
5
+ faraday (~> 0.8.0)
6
+ faraday_middleware (~> 0.8.8)
7
+ hashie (~> 1.2.0)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ addressable (2.2.8)
13
+ crack (0.3.1)
14
+ diff-lcs (1.1.3)
15
+ faraday (0.8.1)
16
+ multipart-post (~> 1.1)
17
+ faraday_middleware (0.8.8)
18
+ faraday (>= 0.7.4, < 0.9)
19
+ hashie (1.2.0)
20
+ multipart-post (1.1.5)
21
+ rake (0.9.2.2)
22
+ rspec (2.11.0)
23
+ rspec-core (~> 2.11.0)
24
+ rspec-expectations (~> 2.11.0)
25
+ rspec-mocks (~> 2.11.0)
26
+ rspec-core (2.11.0)
27
+ rspec-expectations (2.11.1)
28
+ diff-lcs (~> 1.1.3)
29
+ rspec-mocks (2.11.1)
30
+ vcr (2.2.3)
31
+ webmock (1.8.7)
32
+ addressable (>= 2.2.7)
33
+ crack (>= 0.1.7)
34
+
35
+ PLATFORMS
36
+ ruby
37
+
38
+ DEPENDENCIES
39
+ rake
40
+ rspec
41
+ vcr
42
+ vermonster!
43
+ webmock
data/README.markdown ADDED
@@ -0,0 +1,105 @@
1
+ # Vermonster
2
+
3
+ Vermonster is a way to consume the [Cheddar API](https://cheddarapp.com/developer).
4
+
5
+ **Want Python instead? Check out [vermonster-py](https://github.com/jpennell/vermonster-py).**
6
+
7
+ ## Usage
8
+
9
+ ```ruby
10
+ cheddar = Vermonster::Client.new(:id => "client-id", :secret => "client-secret")
11
+ ```
12
+
13
+
14
+ ### Authentication
15
+
16
+ ```ruby
17
+ # Get the URL for the user to authorize the application (all parameters optional).
18
+ url = cheddar.authorize_url(:callback => "http://github.com", :state => "Foobar")
19
+
20
+ # Do whatever to send the user to that URL...
21
+ # It redirects back to whatever you set as the callback URL.
22
+
23
+ # In your controller (or wherever Cheddar sent the user back to),
24
+ # request the token with the code Cheddar sent back.
25
+ cheddar.token!(code)
26
+
27
+ # Or, if you're just using your own user with your own
28
+ # user token...
29
+ cheddar.use_token!("your-user-token")
30
+
31
+ # You're now authorized!
32
+ cheddar.authorized?
33
+ ```
34
+
35
+
36
+ ### Lists
37
+
38
+ ```ruby
39
+ # Get all of your lists.
40
+ lists = cheddar.lists.all
41
+
42
+ # Get a list "Foobar" with the ID of 42.
43
+ foobar = cheddar.lists.find(42)
44
+
45
+ # Get the tasks in that list.
46
+ tasks = foobar.tasks
47
+
48
+ # Update that list.
49
+ foobar.update(:title => "Foosbar")
50
+
51
+ # Create a new list called "Foobaz".
52
+ foobaz = cheddar.lists.create(:title => "Foobaz")
53
+
54
+ # Reorder your lists.
55
+ cheddar.lists.reorder([42, 12, 35])
56
+ ```
57
+
58
+
59
+ ### Tasks
60
+
61
+ ```ruby
62
+ # Get all the tasks in a list.
63
+ tasks = cheddar.lists.find(42).tasks
64
+
65
+ # Find a single task.
66
+ task = cheddar.tasks.find(4242)
67
+
68
+ # Update that task.
69
+ task.update(:text => "Foo to the bar.")
70
+
71
+ # Create a task in list 42.
72
+ awesome = cheddar.tasks.create(42, :text => "Be awesome!")
73
+
74
+ # Reorder task in list 42.
75
+ cheddar.tasks.reorder(42, [54, 23, 42])
76
+
77
+ # Archive completed items in list 42.
78
+ cheddar.tasks.archive(42)
79
+
80
+ # Archive all items in list 42.
81
+ cheddar.tasks.archive!(42)
82
+
83
+ # Move to another list.
84
+ awesome.move(32)
85
+ ```
86
+
87
+
88
+ ### User
89
+
90
+ ```ruby
91
+ # Get information about the authorized user.
92
+ cheddar.me
93
+ ```
94
+
95
+
96
+ ## Contributing
97
+
98
+ Vermonster is under active development, and we would really appreciate you helping us out! Here's how.
99
+
100
+ 1. Fork this repository.
101
+ 2. Take a look [at the issues](https://github.com/eturk/vermonster/issues). What needs to be done?
102
+ 3. Make a topic branch for what you want to do. Bonus points for referencing an issue (like `2-authentication`).
103
+ 4. Make your changes.
104
+ 5. Create a Pull Request.
105
+ 6. Profit!
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec) do |t|
5
+ t.rspec_opts = %w(-fs --color)
6
+ end
7
+
8
+ task :default => :spec
9
+
10
+ namespace :vcr do
11
+ desc "Delete all of the saves cassettes"
12
+ task :clear do
13
+ exec("rm -rf spec/fixtures/cassettes/*")
14
+ end
15
+ end
@@ -0,0 +1,49 @@
1
+ module Vermonster
2
+ module Authentication
3
+ # Returns the URL for authorizing the user.
4
+ def authorize_url(options={})
5
+ url = "https://api.cheddarapp.com/oauth/authorize?client_id=#{@client[:id]}"
6
+
7
+ options.each do |key, value|
8
+ url = url << "&#{key}=#{value}"
9
+ end
10
+
11
+ url
12
+ end
13
+
14
+ # Get the token for the user.
15
+ def token!(code)
16
+ Vermonster::Client.connection.basic_auth(@client[:id], @client[:secret])
17
+
18
+ response = Vermonster::Client.connection.post "/oauth/token", { :grant_type => "authorization_code", :code => code }
19
+
20
+ if response.body["access_token"]
21
+ @client = @client.merge(:token => response.body["access_token"])
22
+
23
+ self.connect!(@client[:token])
24
+
25
+ authorized?
26
+ else
27
+ false
28
+ end
29
+ end
30
+
31
+ # Skip the code and just use the developer's user access token.
32
+ def use_token!(token)
33
+ @client = @client.merge(:token => token)
34
+
35
+ self.connect!(@client[:token])
36
+
37
+ authorized?
38
+ end
39
+
40
+ # Check if authorized or not.
41
+ def authorized?
42
+ if Vermonster::Client.connection.get("me").status == 200
43
+ true
44
+ else
45
+ false
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,51 @@
1
+ module Vermonster
2
+ module Lists
3
+ def lists
4
+ self.class::List
5
+ end
6
+
7
+ class List < Hash
8
+ def initialize(options = {})
9
+ self.merge!(options)
10
+
11
+ options.each do |(attr, val)|
12
+ instance_variable_set("@#{attr}", val)
13
+ instance_eval "def #{attr}() @#{attr} end"
14
+ end
15
+ end
16
+
17
+ # Note this overrides Hash#update. Use Hash#merge! instead.
18
+ def update(options = {})
19
+ self.merge!(Vermonster::Client.connection.put("lists/#{self["id"]}", "{\"list\": #{options.to_json}}").body)
20
+ end
21
+
22
+ def tasks
23
+ Vermonster::Tasks::Task.from_list(self["id"])
24
+ end
25
+
26
+ class << self
27
+ def all
28
+ lists_raw = Vermonster::Client.connection.get("lists").body
29
+ lists = []
30
+ lists_raw.each do |list|
31
+ lists.push(List.new(list))
32
+ end
33
+
34
+ lists
35
+ end
36
+
37
+ def find(id)
38
+ List.new(Vermonster::Client.connection.get("lists/#{id}").body)
39
+ end
40
+
41
+ def create(options = {})
42
+ List.new(Vermonster::Client.connection.post("lists", "{\"list\": #{options.to_json}}").body)
43
+ end
44
+
45
+ def reorder(lists)
46
+
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,58 @@
1
+ module Vermonster
2
+ module Tasks
3
+ def tasks
4
+ self.class::Task
5
+ end
6
+
7
+ class Task < Hash
8
+ def initialize(options = {})
9
+ self.merge!(options)
10
+
11
+ options.each do |(attr, val)|
12
+ instance_variable_set("@#{attr}", val)
13
+ instance_eval "def #{attr}() @#{attr} end"
14
+ end
15
+ end
16
+
17
+ # Note this overrides Hash#update. Use Hash#merge! instead.
18
+ def update(options = {})
19
+ self.merge!(Vermonster::Client.connection.put("tasks/#{self["id"]}", "{\"task\": #{options.to_json}}").body)
20
+ end
21
+
22
+ def move(list)
23
+ self.replace(Vermonster::Client.connection.put("tasks/#{self["id"]}/move", "{\"task\": { \"list_id\": #{list} } }").body)
24
+ end
25
+
26
+ class << self
27
+ def from_list(id)
28
+ tasks_raw = Vermonster::Client.connection.get("lists/#{id}/tasks").body
29
+ tasks = []
30
+ tasks_raw.each do |task|
31
+ tasks.push(Task.new(task))
32
+ end
33
+
34
+ tasks
35
+ end
36
+
37
+ def find(id)
38
+ Task.new(Vermonster::Client.connection.get("tasks/#{id}").body)
39
+ end
40
+
41
+ def create(list, options = {})
42
+ Task.new(Vermonster::Client.connection.post("lists/#{list}/tasks", "{\"task\": #{options.to_json}}").body)
43
+ end
44
+
45
+ def reorder(list, options = {})
46
+ end
47
+
48
+ def archive(list)
49
+ Vermonster::Client.connection.post("lists/#{list}/tasks/archive_completed")
50
+ end
51
+
52
+ def archive!(list)
53
+ Vermonster::Client.connection.post("lists/#{list}/tasks/archive_all")
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,27 @@
1
+ module Vermonster
2
+ module Users
3
+ def me
4
+ self.users.me
5
+ end
6
+
7
+ def users
8
+ self.class::User
9
+ end
10
+
11
+ class User < Hash
12
+ def initialize(options = {})
13
+ self.merge!(options)
14
+
15
+ options.each do |(attr, val)|
16
+ instance_variable_set("@#{attr}", val)
17
+ instance_eval "def #{attr}() @#{attr} end"
18
+ end
19
+ end
20
+
21
+ def self.me
22
+ User.new(Vermonster::Client.connection.get("me").body)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,3 @@
1
+ module Vermonster
2
+ VERSION = "0.1.1"
3
+ end
data/lib/vermonster.rb ADDED
@@ -0,0 +1,40 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+ require 'hashie'
4
+
5
+ require 'vermonster/authentication'
6
+ require 'vermonster/lists'
7
+ require 'vermonster/tasks'
8
+ require 'vermonster/users'
9
+
10
+ module Vermonster
11
+ class Client
12
+ attr_accessor :client
13
+
14
+ def initialize(options={})
15
+ @client = options
16
+
17
+ self.connect!
18
+ end
19
+
20
+ def connect!(token = nil)
21
+ @@connection = Faraday.new(:url => "https://api.cheddarapp.com/v1") do |f|
22
+ f.headers["Authorization"] = "Bearer #{token}" if !token.nil?
23
+ f.request :json
24
+ f.response :json, :content_type => /\bjson$/
25
+ f.adapter Faraday.default_adapter
26
+ end
27
+
28
+ self
29
+ end
30
+
31
+ def self.connection
32
+ @@connection
33
+ end
34
+
35
+ include Authentication
36
+ include Lists
37
+ include Tasks
38
+ include Users
39
+ end
40
+ end
@@ -0,0 +1,104 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.cheddarapp.com/v1/me
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Authorization:
11
+ - Bearer 6e8c9e570805e75d683a963b1290116a
12
+ Accept-Encoding:
13
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
14
+ Accept:
15
+ - ! '*/*'
16
+ User-Agent:
17
+ - Ruby
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Access-Control-Allow-Headers:
24
+ - ! '*,X-Pusher-Socket-ID,Content-Type,Authorization'
25
+ Access-Control-Allow-Methods:
26
+ - GET, POST, PUT, OPTIONS
27
+ Access-Control-Allow-Origin:
28
+ - ! '*'
29
+ Access-Control-Max-Age:
30
+ - '86400'
31
+ Access-Control-Request-Method:
32
+ - ! '*'
33
+ Cache-Control:
34
+ - must-revalidate, private, max-age=0
35
+ Content-Type:
36
+ - application/json; charset=utf-8
37
+ Date:
38
+ - Sun, 29 Jul 2012 23:38:27 GMT
39
+ Etag:
40
+ - ! '"ef42e623e164e34871846180e276f9de"'
41
+ Server:
42
+ - thin 1.4.1 codename Chromeo
43
+ X-Rack-Cache:
44
+ - miss
45
+ X-Request-Id:
46
+ - 6ef32226d03bdf001084760c54c846d7
47
+ X-Runtime:
48
+ - '0.030929'
49
+ X-Ua-Compatible:
50
+ - IE=Edge,chrome=1
51
+ Content-Length:
52
+ - '354'
53
+ Connection:
54
+ - keep-alive
55
+ body:
56
+ encoding: US-ASCII
57
+ string: ! '{"created_at":"2012-07-18T19:33:13Z","first_name":null,"has_plus":false,"id":13055,"last_name":null,"updated_at":"2012-07-18T19:33:13Z","username":"vermonster","url":"https://api.cheddarapp.com/v1/users/13055","socket":{"auth_url":"https://api.cheddarapp.com/pusher/auth","api_key":"675f10a650f18b4eb0a8","app_id":"15197","channel":"private-user-13055"}}'
58
+ http_version:
59
+ recorded_at: Sun, 29 Jul 2012 23:38:27 GMT
60
+ - request:
61
+ method: get
62
+ uri: https://api.cheddarapp.com/v1/me
63
+ body:
64
+ encoding: US-ASCII
65
+ string: ''
66
+ headers:
67
+ Accept-Encoding:
68
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
69
+ Accept:
70
+ - ! '*/*'
71
+ User-Agent:
72
+ - Ruby
73
+ response:
74
+ status:
75
+ code: 401
76
+ message: Unauthorized
77
+ headers:
78
+ Cache-Control:
79
+ - no-cache
80
+ Content-Type:
81
+ - application/json; charset=utf-8
82
+ Date:
83
+ - Sun, 29 Jul 2012 23:38:27 GMT
84
+ Server:
85
+ - thin 1.4.1 codename Chromeo
86
+ X-Rack-Cache:
87
+ - miss
88
+ X-Request-Id:
89
+ - 09075fb8096e51115c5273212bd24679
90
+ X-Runtime:
91
+ - '0.004310'
92
+ X-Ua-Compatible:
93
+ - IE=Edge,chrome=1
94
+ Content-Length:
95
+ - '85'
96
+ Connection:
97
+ - keep-alive
98
+ body:
99
+ encoding: US-ASCII
100
+ string: ! '{"error":"not_authorized","error_description":"This method requires
101
+ authentication."}'
102
+ http_version:
103
+ recorded_at: Sun, 29 Jul 2012 23:38:28 GMT
104
+ recorded_with: VCR 2.2.3