drink-socially 0.0.4

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.
@@ -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