drink-socially 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,54 @@
1
+ # drink-socially
2
+
3
+ [![Build Status](https://secure.travis-ci.org/NewRepublicBrewing/drink-socially.png)](http://travis-ci.org/NewRepublicBrewing/drink-socially)
4
+ [![Dependency Status](https://gemnasium.com/NewRepublicBrewing/drink-socially.png)](https://gemnasium.com/NewRepublicBrewing/drink-socially)
5
+ [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/NewRepublicBrewing/drink-socially)
6
+
7
+ A gem for interfacing with the Untappd API
8
+
9
+ ## Requirements
10
+
11
+ Ruby 1.9
12
+
13
+ ## Usage
14
+
15
+ ### Acting as a person
16
+
17
+ ```ruby
18
+ require 'drink-socially'
19
+
20
+ # Per-user access token taken from OAuth
21
+ brundage = NRB::Untappd::API.new access_token: '7A23A8BEER81D2580E&CEFC405C60693AC476AA'
22
+
23
+ new_republic = brundage.brewery_info 8767
24
+ => #<Hashie::Mash beer_count=13 beer_list=....
25
+
26
+ new_republic.brewery_name
27
+ => "New Republic Brewing Company"
28
+
29
+ ```
30
+
31
+ ### Acting as an app
32
+
33
+ ```ruby
34
+ # Get your id & secret from http://untappd.com/api/dashboard
35
+ new_republic_app = NRB::Untappd::API.new client_id: '645c10bc59f30e34d6fd265cfdeb75e', client_secret: '9ffe686c814207df12f9b0e0bc0cdab'
36
+ ```
37
+
38
+ ## Methods
39
+
40
+ ### NRB::Untappd::API
41
+
42
+ `new` takes a user access token or a application id and secret. Once you have an instance of the API you can make calls on behalf of the user or application.
43
+
44
+ The Untappd api enforces a rate limit per token. After the first call you can ask your object the current limit with the `rate_limit` call.
45
+
46
+ ```
47
+ brundage.rate_limit
48
+ => @rate_limit= #<NRB::Untappd::API::RateLimit:0x930af6c @limit="100", @remaining="99">>
49
+ ```
50
+
51
+ All API calls return an `NRB::Untappd::API::Response` object. You can access the full response object with the `last_response` method.
52
+
53
+ Full documentation for the API calls are detailed [in the wiki](drink-socially/wiki/api_calls). Also have a look at the [Untappd v4 API documentation](http://untappd.com/api/docs/v4) for details.
54
+
@@ -0,0 +1,231 @@
1
+ ---
2
+ :accept_friend:
3
+ :endpoint: "friend/accept/:user_id:"
4
+ :required_args:
5
+ - :user_id
6
+ :verb: :post
7
+
8
+ :add_comment:
9
+ :endpoint: "checkin/addcomment/:checkin_id:"
10
+ :required_args:
11
+ - :checkin_id
12
+ - :comment
13
+ :results_path:
14
+ - :response
15
+ - :comments
16
+ - :items
17
+ :verb: :post
18
+
19
+ :add_to_wish_list:
20
+ :endpoint: user/wishlist/add
21
+ :method_aliases:
22
+ - :add_to_wishlist
23
+ :required_args:
24
+ - :bid
25
+ :results_path:
26
+ - :response
27
+ - :beer
28
+
29
+ :beer_checkins:
30
+ :endpoint: "beer/checkins/:bid:"
31
+ :method_aliases:
32
+ - :beer_feed
33
+ :required_args:
34
+ - :bid
35
+ :results_path:
36
+ - :response
37
+ - :checkins
38
+ - :items
39
+
40
+ :beer_info:
41
+ :endpoint: "beer/info/:bid:"
42
+ :required_args:
43
+ - :bid
44
+ :results_path:
45
+ - :response
46
+ - :beer
47
+
48
+ :beer_search:
49
+ :endpoint: search/beer
50
+ :required_args:
51
+ - :q
52
+
53
+ :brewery_checkins:
54
+ :endpoint: "brewery/checkins/:brewery_id:"
55
+ :method_aliases:
56
+ - :brewery_feed
57
+ :required_args:
58
+ - :brewery_id
59
+ :results_path:
60
+ - :response
61
+ - :checkins
62
+ - :items
63
+
64
+ :brewery_info:
65
+ :endpoint: "brewery/info/:brewery_id:"
66
+ :required_args:
67
+ - :brewery_id
68
+ :results_path:
69
+ - :response
70
+ - :brewery
71
+
72
+ :brewery_search:
73
+ :endpoint: search/brewery
74
+ :required_args:
75
+ - :q
76
+ :results_path:
77
+ - :response
78
+ - :brewery
79
+ - :items
80
+
81
+ :checkin_info:
82
+ :endpoint: "checkin/view/:checkin_id:"
83
+ :required_args:
84
+ - :checkin_id
85
+ :results_path:
86
+ - :response
87
+ - :checkin
88
+
89
+ :delete_comment:
90
+ :endpoint: "checkin/deletecomment/:comment_id:"
91
+ :method_aliases:
92
+ - :remove_comment
93
+ :required_args:
94
+ - :comment_id
95
+ :results_path:
96
+ - :response
97
+ - :comments
98
+ :verb: :post
99
+
100
+ :foursquare_venue_info:
101
+ :endpoint: "venue/foursquare_lookup/:venue_id:"
102
+ :required_args:
103
+ - :venue_id
104
+ :results_path:
105
+ - :response
106
+ - :venue
107
+ - :items
108
+ - :first
109
+ :verb: :post
110
+
111
+ :friend_feed:
112
+ :endpoint: checkin/recent
113
+ :results_path:
114
+ - :response
115
+ - :checkins
116
+ - :items
117
+
118
+ :news:
119
+ :endpoint: notifications
120
+ :results_path:
121
+ - :response
122
+ - :news
123
+ - :items
124
+
125
+ :notifications:
126
+ :endpoint: notifications
127
+ :results_path:
128
+ - :response
129
+ - :notifications
130
+ - :items
131
+
132
+ :pending_friends:
133
+ :endpoint: user/pending
134
+ :results_path:
135
+ - :response
136
+
137
+ :reject_friend:
138
+ :endpoint: "friend/reject/:user_id:"
139
+ :required_args:
140
+ - :user_id
141
+ :verb: :post
142
+
143
+ :remove_friend:
144
+ :endpoint: "friend/remove/:user_id:"
145
+ :required_args:
146
+ - :user_id
147
+
148
+ :remove_from_wish_list:
149
+ :endpoint: user/wishlist/remove
150
+ :method_aliases:
151
+ - :delete_from_wish_list
152
+ :required_args:
153
+ - :bid
154
+
155
+ :request_friend:
156
+ :endpoint: "friend/request/:user_id:"
157
+ :required_args:
158
+ - :user_id
159
+
160
+ :the_pub:
161
+ :endpoint: thepub
162
+ :results_path:
163
+ - :response
164
+ - :checkins
165
+ - :items
166
+
167
+ :trending:
168
+ :endpoint: beer/trending
169
+
170
+ :toast:
171
+ :endpoint: "checkin/toast/:checkin_id:"
172
+ :method_aliases:
173
+ - :add_toast
174
+ - :delete_toast
175
+ :required_args:
176
+ - :checkin_id
177
+
178
+ :user_badges:
179
+ :endpoint: "user/badges/:username:"
180
+
181
+ :user_distinct_beers:
182
+ :endpoint: "user/beers/:username:"
183
+ :method_aliases:
184
+ - :user_beers
185
+ :results_path:
186
+ - :response
187
+ - :beers
188
+ - :items
189
+
190
+ :user_feed:
191
+ :endpoint: "user/checkins/:username:"
192
+ :results_path:
193
+ - :response
194
+ - :checkins
195
+ - :items
196
+
197
+ :user_friends:
198
+ :endpoint: "user/friends/:username:"
199
+ :results_path:
200
+ - :response
201
+ - :items
202
+
203
+ :user_info:
204
+ :endpoint: "user/info/:username:"
205
+ :results_path:
206
+ - :response
207
+ - :user
208
+
209
+ :user_wish_list:
210
+ :endpoint: "user/wishlist/:username:"
211
+ :results_path:
212
+ - :response
213
+ - :beers
214
+ - :items
215
+
216
+ :venue_feed:
217
+ :endpoint: "venue/checkins/:venue_id:"
218
+ :required_args:
219
+ - :venue_id
220
+ :results_path:
221
+ - :response
222
+ - :checkins
223
+ - :items
224
+
225
+ :venue_info:
226
+ :endpoint: "venue/info/:venue_id:"
227
+ :required_args:
228
+ - :venue_id
229
+ :results_path:
230
+ - :response
231
+ - :venue
@@ -0,0 +1,43 @@
1
+ require 'drink-socially/http_service'
2
+ require 'drink-socially/version'
3
+ require 'drink-socially/extensions/hash'
4
+
5
+ module NRB
6
+ module Untappd
7
+
8
+ autoload :API, 'drink-socially/api'
9
+ autoload :Config, 'drink-socially/config'
10
+
11
+ class << self
12
+
13
+ attr_accessor :http_service
14
+
15
+ def config_file_path(key)
16
+ return key if File.absolute_path(key) == key
17
+ File.expand_path( File.join( config_dir, key ) )
18
+ end
19
+
20
+
21
+ def load_config(args)
22
+ reader = args.delete(:config_reader) || Config
23
+ !! args[:filekey] && args[:filename] = config_file_path(args.delete(:filekey))
24
+ reader.new(args)
25
+ end
26
+
27
+
28
+ def make_request(args)
29
+ http_service.make_request args
30
+ end
31
+
32
+ private
33
+
34
+ def config_dir
35
+ File.expand_path( File.join( File.dirname(__FILE__), '..', 'config' ) )
36
+ end
37
+
38
+ end
39
+
40
+ self.http_service = HTTPService
41
+
42
+ end
43
+ end
@@ -0,0 +1,124 @@
1
+ module NRB
2
+ module Untappd
3
+ class API
4
+
5
+ API_VERSION = :v4 # Use NRB::Untappd::API.api_version instead
6
+ SERVER = 'api.untappd.com' # Use NRB::Untappd::API.server instead
7
+
8
+ autoload :Credential, 'drink-socially/api/credential'
9
+ autoload :Pagination, 'drink-socially/api/pagination'
10
+ autoload :RateLimit, 'drink-socially/api/rate_limit'
11
+ autoload :Object, 'drink-socially/api/object'
12
+ autoload :URLTokenizer, 'drink-socially/api/url_tokenizer'
13
+
14
+ attr_reader :credential, :endpoints, :rate_limit
15
+
16
+ def self.api_version; API_VERSION; end
17
+ def self.default_rate_limit_class; RateLimit; end
18
+ def self.default_response_class; Object; end
19
+ def self.requestor; NRB::Untappd; end
20
+ def self.server; SERVER; end
21
+
22
+
23
+ # http://untappd.com/api/docs/v4#checkin
24
+ # Required args: bid
25
+ def add_checkin(args)
26
+ validate_api_args args, :bid
27
+ t = Time.now
28
+ args[:endpoint] = 'checkin/add'
29
+ args[:gmt_offset] ||= t.gmt_offset / 3600
30
+ args[:timezone] ||= t.zone
31
+ args[:verb] = :post
32
+ api_call args
33
+ end
34
+
35
+
36
+ def api_call(args)
37
+ endpoint = args.delete(:endpoint)
38
+ config = get_config endpoint
39
+ return unless config
40
+
41
+ validate_api_args args, *config[:required_args]
42
+
43
+ args.merge!(config)
44
+
45
+ args[:response_class] ||= self.class.default_response_class
46
+
47
+ tokenizer = URLTokenizer.new map: args, string: args.delete(:endpoint)
48
+ args[:url] = find_path_at tokenizer.tr
49
+
50
+ response = self.class.requestor.make_request(args)
51
+ @rate_limit = self.class.default_rate_limit_class.new(response.headers)
52
+ response
53
+ end
54
+
55
+
56
+ def initialize(args={})
57
+ @api_version = args[:api_version] || self.class.api_version
58
+ @credential = args[:credential] || Credential.new(args.dup)
59
+ @server = args[:server] || self.class.server
60
+ define_endpoints_from(args)
61
+ end
62
+
63
+ private
64
+
65
+ def api_call_lambda(args)
66
+ lambda { |opts={}| api_call opts.merge({endpoint: args[:endpoint]}) }
67
+ end
68
+
69
+ def credential_string_for_url
70
+ @credential.is_user? ? "?access_token=#{@credential.access_token}" : ""
71
+ end
72
+
73
+
74
+ def define_endpoint_aliases(args)
75
+ return unless args[:orig]
76
+ args[:aliases].each do |name|
77
+ define_singleton_method name, api_call_lambda(endpoint: name)
78
+ end
79
+ end
80
+
81
+
82
+ def define_endpoints_from(args)
83
+ @endpoints = args[:endpoints] || NRB::Untappd.load_config(filekey: (args[:config_file] || 'endpoints.yml'))
84
+ @endpoints.each do |endpoint,endpoint_config|
85
+ define_singleton_method endpoint, api_call_lambda(endpoint: endpoint)
86
+ endpoint_config[:method_aliases] && define_endpoint_aliases(orig: endpoint, aliases: endpoint_config[:method_aliases])
87
+ end
88
+ end
89
+
90
+
91
+ def endpoint_base
92
+ "http://#{@server}/#{@api_version}/"
93
+ end
94
+
95
+
96
+ def extract_info_from(response, *keys)
97
+ return unless response.success?
98
+ keys.inject(response.body) { |hash, key| hash[key] }
99
+ end
100
+
101
+
102
+ def find_path_at(endpoint)
103
+ endpoint_base + endpoint.to_s + credential_string_for_url
104
+ end
105
+
106
+
107
+ def get_config(endpoint)
108
+ config = @endpoints[endpoint]
109
+ return unless config
110
+ config[:verb] ||= :get
111
+ config
112
+ end
113
+
114
+
115
+ def validate_api_args(args, *required_args)
116
+ raise ArgumentError.new("Please supply a hash") unless args.is_a?(Hash)
117
+ required_args.each do |arg|
118
+ raise ArgumentError.new("Missing required #{arg} parameter") unless !! args[arg]
119
+ end
120
+ end
121
+
122
+ end
123
+ end
124
+ end