vermonster 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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