rest-more 0.7.2.1 → 0.8.0

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/CHANGES.md CHANGED
@@ -1,5 +1,70 @@
1
1
  # CHANGES
2
2
 
3
+ ## rest-more 0.8.0 -- 2011-11-29
4
+
5
+ ### Incompatible changes
6
+
7
+ * [Facebook::RailsUtil] Some methods are renamed. For example,
8
+ `rc_facebook_write_rg_fbs` is renamed to `rc_facebook_write_fbs`.
9
+ All renamed methods are considered private, so we're not listing them here.
10
+
11
+ * [Facebook::RailsUtil] `rc_facebook_storage_key` is changed to:
12
+ `"rc_facebook_#{rc_facebook.app_id}"`, your users might need to
13
+ login again in order to save the access_token into the new place.
14
+
15
+ ### Bugs fixes
16
+
17
+ * [Github] Fixed usage of Oauth2Query.
18
+
19
+ * [Facebook] Now we're using POST in `authorize!` to exchange the
20
+ access_token with the code instead of GET. If we're using GET,
21
+ we would run into a risk where a user might use the code to
22
+ get other people's access_token via the cache. Using POST would
23
+ prevent this because POSTs are not cached.
24
+
25
+ * [Facebook::RailsUtil] Fixed a serious bug. The bug would jump up if
26
+ you're using :write_session or :write_cookies or :write_handler along
27
+ with :auto_authorize, for example:
28
+ `rc_facebook_setup(:auto_authorize => true, :write_session => true)`
29
+ The problem is that Facebook::RailsUtil is not removing the invalid
30
+ access_token stored in session or cookie, and yet it is considered
31
+ authorized, making redirecting to Facebook and redirecting back doesn't
32
+ update the access_token. `rc_facebook_cleanup` is introduced to remove
33
+ all invalid access_tokens, which would get called once the user is
34
+ redirected to Facebook, fixing this bug.
35
+
36
+ ### Enhancement
37
+
38
+ * [Facebook] Now we use `default_data` to get the default data,
39
+ instead of relying `Defaults` middleware.
40
+
41
+ * [Facebook] Protected methods are changed to private.
42
+
43
+ * [Flurry] `app_info` now accepts opts.
44
+ * [Flurry] `event_metrics` is renamed to `event_summary`
45
+ * [Flurry] `event_metrics` is now the API for accessing 'eventMetrics/Event'
46
+ * [Flurry] If you didn't pass dates, now default to for 7 days.
47
+ * [Flurry] Instead of overriding `query`, defining `default_query`
48
+
49
+ * [Linkedin+Twitter] Removed `Defaults` middleware because now we're using
50
+ the data from `Oauth1Client` instead.
51
+
52
+ * [Linkedin+Twitter] Removed `oauth_token`, `oauth_token=`,
53
+ `oauth_token_secret`, and `oauth_token_secret=` because we're using them
54
+ from `Oauth1Client` instead.
55
+
56
+ * [Linkedin+Twitter] Removed `set_token` because it's handled in
57
+ `Oauth1Client` now.
58
+
59
+ * [Twitter::RailsUtil] Now `rc_twitter_setup` accepts options like
60
+ `rc_facebook_setup`: `auto_authorize`, `ensure_authorized`,
61
+ `write_session`, `write_cookies`, `write_handler`, and `check_handler`.
62
+
63
+ * [Mixi] Removed `Defaults` middleware in favor of `default_data`.
64
+
65
+ * [Facebook+Github+Mixi+Twitter] Added a `me` method for accessing current
66
+ user information.
67
+
3
68
  ## rest-more 0.7.2.1 -- 2011-11-05
4
69
 
5
70
  ### Bugs fixes
data/README.md CHANGED
@@ -5,7 +5,7 @@ by Cardinal Blue <http://cardinalblue.com>
5
5
  ## LINKS:
6
6
 
7
7
  * [github](https://github.com/cardinalblue/rest-more)
8
- * [rubygems](http://rubygems.org/gems/rest-more)
8
+ * [rubygems](https://rubygems.org/gems/rest-more)
9
9
  * [rdoc](http://rdoc.info/projects/cardinalblue/rest-more)
10
10
  * [mailing list](http://groups.google.com/group/rest-core/topics)
11
11
 
@@ -125,10 +125,10 @@ class ApplicationController < ActionController::Base
125
125
  end
126
126
 
127
127
  def filter_session
128
- rc_facebook_setup(:write_session => true)
128
+ rc_facebook_setup(:write_session => true, :auto_authorize => true)
129
129
  end
130
130
 
131
131
  def filter_cookies
132
- rc_facebook_setup(:write_cookies => true)
132
+ rc_facebook_setup(:write_cookies => true, :auto_authorize => true)
133
133
  end
134
134
  end
@@ -166,6 +166,32 @@ class ApplicationControllerTest < ActionController::TestCase
166
166
  assert_equal '["yeti"]', @response.body
167
167
  end
168
168
 
169
+ def test_wrong_session
170
+ WebMock.reset!
171
+ stub_request(:get, 'https://graph.facebook.com/me').
172
+ to_return(:body => '{"error":{"type":"OAuthException"}}')
173
+
174
+ session = @request.session
175
+ key = @controller.send(:rc_facebook_storage_key)
176
+ session[key] = 'bad'
177
+
178
+ get(:session_)
179
+ assert_equal nil, session[key]
180
+ end
181
+
182
+ def test_wrong_cookies
183
+ WebMock.reset!
184
+ stub_request(:get, 'https://graph.facebook.com/me').
185
+ to_return(:body => '{"error":{"type":"OAuthException"}}')
186
+
187
+ cookies = @request.cookies
188
+ key = @controller.send(:rc_facebook_storage_key)
189
+ session[key] = 'bad'
190
+
191
+ get(:cookies_)
192
+ assert_equal nil, cookies[key]
193
+ end
194
+
169
195
  def test_error
170
196
  get(:error)
171
197
  rescue => e
@@ -125,10 +125,10 @@ class ApplicationController < ActionController::Base
125
125
  end
126
126
 
127
127
  def filter_session
128
- rc_facebook_setup(:write_session => true)
128
+ rc_facebook_setup(:write_session => true, :auto_authorize => true)
129
129
  end
130
130
 
131
131
  def filter_cookies
132
- rc_facebook_setup(:write_cookies => true)
132
+ rc_facebook_setup(:write_cookies => true, :auto_authorize => true)
133
133
  end
134
134
  end
@@ -166,6 +166,32 @@ class ApplicationControllerTest < ActionController::TestCase
166
166
  assert_equal '["yeti"]', @response.body
167
167
  end
168
168
 
169
+ def test_wrong_session
170
+ WebMock.reset!
171
+ stub_request(:get, 'https://graph.facebook.com/me').
172
+ to_return(:body => '{"error":{"type":"OAuthException"}}')
173
+
174
+ session = @request.session
175
+ key = @controller.send(:rc_facebook_storage_key)
176
+ session[key] = 'bad'
177
+
178
+ get(:session_)
179
+ assert_equal nil, session[key]
180
+ end
181
+
182
+ def test_wrong_cookies
183
+ WebMock.reset!
184
+ stub_request(:get, 'https://graph.facebook.com/me').
185
+ to_return(:body => '{"error":{"type":"OAuthException"}}')
186
+
187
+ cookies = @request.cookies
188
+ key = @controller.send(:rc_facebook_storage_key)
189
+ session[key] = 'bad'
190
+
191
+ get(:cookies_)
192
+ assert_equal nil, cookies[key]
193
+ end
194
+
169
195
  def test_error
170
196
  get(:error)
171
197
  rescue => e
@@ -1,6 +1,7 @@
1
1
 
2
2
  require 'rest-core'
3
3
 
4
+ # http://msdn.microsoft.com/en-us/library/dd250846.aspx
4
5
  RestCore::Bing = RestCore::Builder.client(:AppId) do
5
6
  s = self.class # this is only for ruby 1.8!
6
7
  use s::Timeout , 10
@@ -22,23 +23,7 @@ RestCore::Bing = RestCore::Builder.client(:AppId) do
22
23
  end
23
24
  end
24
25
 
25
- module RestCore::Bing::Client
26
- def query
27
- {'AppId' => self.AppId,
28
- 'JsonType' => 'raw' ,
29
- 'Version' => '2.2' }
30
- end
31
-
32
- def search_image term, query={}, opts={}
33
- get('', {:Query => term, :Sources => 'Image'}.merge(query), opts)[
34
- 'SearchResponse']['Image']['Results'] || []
35
- end
36
-
37
- def search_image_urls term, query={}, opts={}
38
- search_image(term, query, opts).map{ |i| i['MediaUrl'] }
39
- end
40
- end
41
-
26
+ # http://msdn.microsoft.com/en-us/library/dd251042.aspx
42
27
  class RestCore::Bing::Error < RestCore::Error
43
28
  include RestCore
44
29
  class MissingParameter < Bing::Error; end
@@ -87,6 +72,23 @@ class RestCore::Bing::Error < RestCore::Error
87
72
  end
88
73
  end
89
74
 
75
+ module RestCore::Bing::Client
76
+ def query
77
+ {'AppId' => self.AppId,
78
+ 'JsonType' => 'raw' ,
79
+ 'Version' => '2.2' }
80
+ end
81
+
82
+ def search_image term, query={}, opts={}
83
+ get('', {:Query => term, :Sources => 'Image'}.merge(query), opts)[
84
+ 'SearchResponse']['Image']['Results'] || []
85
+ end
86
+
87
+ def search_image_urls term, query={}, opts={}
88
+ search_image(term, query, opts).map{ |i| i['MediaUrl'] }
89
+ end
90
+ end
91
+
90
92
  RestCore::Bing.send(:include, RestCore::Bing::Client)
91
93
  require 'rest-core/client/bing/rails_util' if
92
94
  Object.const_defined?(:Rails)
@@ -2,6 +2,8 @@
2
2
  require 'rest-core'
3
3
  require 'rest-core/util/hmac'
4
4
 
5
+ # https://developers.facebook.com/docs/reference/api
6
+ # https://developers.facebook.com/tools/explorer
5
7
  RestCore::Facebook = RestCore::Builder.client(
6
8
  :data, :app_id, :secret, :old_site) do
7
9
 
@@ -26,8 +28,7 @@ RestCore::Facebook = RestCore::Builder.client(
26
28
  use s::JsonDecode , true
27
29
  end
28
30
 
29
- use s::Defaults , :data => lambda{{}},
30
- :old_site => 'https://api.facebook.com/'
31
+ use s::Defaults , :old_site => 'https://api.facebook.com/'
31
32
  end
32
33
 
33
34
  class RestCore::Facebook::Error < RestCore::Error
@@ -69,6 +70,10 @@ end
69
70
  module RestCore::Facebook::Client
70
71
  include RestCore
71
72
 
73
+ def me query={}, opts={}
74
+ get('me', query, opts)
75
+ end
76
+
72
77
  def access_token
73
78
  data['access_token'] || data['oauth_token'] if data.kind_of?(Hash)
74
79
  end
@@ -179,9 +184,9 @@ module RestCore::Facebook::Client
179
184
  end
180
185
 
181
186
  def authorize! opts={}
182
- query = {:client_id => app_id, :client_secret => secret}.merge(opts)
187
+ payload = {:client_id => app_id, :client_secret => secret}.merge(opts)
183
188
  self.data = ParseQuery.parse_query(
184
- get(url('oauth/access_token'), query,
189
+ post('oauth/access_token', payload, {},
185
190
  {:json_decode => false}.merge(opts)))
186
191
  end
187
192
 
@@ -222,7 +227,11 @@ module RestCore::Facebook::Client
222
227
  {}, {}, opts, &cb)
223
228
  end
224
229
 
225
- protected
230
+ private
231
+ def default_data
232
+ {}
233
+ end
234
+
226
235
  def build_env env={}
227
236
  super(env.inject({}){ |r, (k, v)|
228
237
  case k.to_s
@@ -44,7 +44,7 @@ module RestCore::Facebook::RailsUtil
44
44
  # before, in that case, the fbs would be inside session,
45
45
  # as we just saved it there
46
46
 
47
- rc_facebook_check_rg_fbs # check rc_facebook storage
47
+ rc_facebook_check_fbs # check rc_facebook storage
48
48
 
49
49
  if rc_options_get(RestCore::Facebook, :ensure_authorized) &&
50
50
  !rc_facebook.authorized?
@@ -65,6 +65,8 @@ module RestCore::Facebook::RailsUtil
65
65
  logger.warn("WARN: Facebook: #{error.inspect}")
66
66
 
67
67
  if force_redirect || rc_facebook_auto_authorize?
68
+ rc_facebook_cleanup
69
+
68
70
  @rc_facebook_authorize_url = rc_facebook.authorize_url(
69
71
  {:redirect_uri => rc_facebook_normalized_request_uri,
70
72
  :scope =>
@@ -72,9 +74,8 @@ module RestCore::Facebook::RailsUtil
72
74
  merge(rc_options_get(RestCore::Facebook, :auto_authorize_options)))
73
75
 
74
76
  logger.debug(
75
- "DEBUG: Facebook: redirect to #{@rc_facebook_authorize_url}")
77
+ "DEBUG: Facebook: redirect to #{@rc_facebook_authorize_url}")
76
78
 
77
- cookies.delete("fbs_#{rc_facebook.app_id}")
78
79
  rc_facebook_authorize_redirect
79
80
  end
80
81
  end
@@ -132,7 +133,7 @@ module RestCore::Facebook::RailsUtil
132
133
  " parsed: #{rc_facebook.data.inspect}")
133
134
 
134
135
  if rc_facebook.authorized?
135
- rc_facebook_write_rg_fbs
136
+ rc_facebook_write_fbs
136
137
  else
137
138
  logger.warn(
138
139
  "WARN: Facebook: bad signed_request: #{params[:signed_request]}")
@@ -151,7 +152,7 @@ module RestCore::Facebook::RailsUtil
151
152
  " #{rc_facebook.data.inspect}")
152
153
 
153
154
  if rc_facebook.authorized?
154
- rc_facebook_write_rg_fbs
155
+ rc_facebook_write_fbs
155
156
  else
156
157
  logger.warn("WARN: Facebook: bad session: #{params[:session]}")
157
158
  end
@@ -182,7 +183,7 @@ module RestCore::Facebook::RailsUtil
182
183
  "#{rc_facebook_normalized_request_uri}," \
183
184
  " parsed: #{rc_facebook.data.inspect}")
184
185
 
185
- rc_facebook_write_rg_fbs if rc_facebook.authorized?
186
+ rc_facebook_write_fbs if rc_facebook.authorized?
186
187
  end
187
188
  # ==================== end facebook check ======================
188
189
 
@@ -190,16 +191,16 @@ module RestCore::Facebook::RailsUtil
190
191
 
191
192
  # ==================== begin check ================================
192
193
  def rc_facebook_storage_key
193
- "rc_facebook_fbs_#{rc_options_get(RestCore::Facebook, :app_id)}"
194
+ "rc_facebook_#{rc_facebook.app_id}"
194
195
  end
195
196
 
196
- def rc_facebook_check_rg_fbs
197
- rc_facebook_check_rg_handler # custom method to store fbs
198
- rc_facebook_check_rg_session # prefered way to store fbs
199
- rc_facebook_check_rg_cookies # in canvas, session might not work..
197
+ def rc_facebook_check_fbs
198
+ rc_facebook_check_handler # custom method to store fbs
199
+ rc_facebook_check_session # prefered way to store fbs
200
+ rc_facebook_check_cookies # in canvas, session might not work..
200
201
  end
201
202
 
202
- def rc_facebook_check_rg_handler handler=
203
+ def rc_facebook_check_handler handler=
203
204
  rc_options_get(RestCore::Facebook, :check_handler)
204
205
 
205
206
  return if rc_facebook.authorized? || !handler
@@ -208,7 +209,7 @@ module RestCore::Facebook::RailsUtil
208
209
  " #{rc_facebook.data.inspect}")
209
210
  end
210
211
 
211
- def rc_facebook_check_rg_session
212
+ def rc_facebook_check_session
212
213
  return if rc_facebook.authorized? ||
213
214
  !rc_options_get(RestCore::Facebook, :write_session) ||
214
215
  !(fbs = session[rc_facebook_storage_key])
@@ -218,7 +219,7 @@ module RestCore::Facebook::RailsUtil
218
219
  " #{rc_facebook.data.inspect}")
219
220
  end
220
221
 
221
- def rc_facebook_check_rg_cookies
222
+ def rc_facebook_check_cookies
222
223
  return if rc_facebook.authorized? ||
223
224
  !rc_options_get(RestCore::Facebook, :write_cookies) ||
224
225
  !(fbs = cookies[rc_facebook_storage_key])
@@ -229,14 +230,13 @@ module RestCore::Facebook::RailsUtil
229
230
  end
230
231
  # ==================== end check ================================
231
232
  # ==================== begin write ================================
232
- def rc_facebook_write_rg_fbs
233
- cookies.delete("fbs_#{rc_facebook.app_id}")
234
- rc_facebook_write_rg_handler
235
- rc_facebook_write_rg_session
236
- rc_facebook_write_rg_cookies
233
+ def rc_facebook_write_fbs
234
+ rc_facebook_write_handler
235
+ rc_facebook_write_session
236
+ rc_facebook_write_cookies
237
237
  end
238
238
 
239
- def rc_facebook_write_rg_handler handler=
239
+ def rc_facebook_write_handler handler=
240
240
  rc_options_get(RestCore::Facebook, :write_handler)
241
241
 
242
242
  return if !handler
@@ -244,13 +244,13 @@ module RestCore::Facebook::RailsUtil
244
244
  logger.debug("DEBUG: Facebook: called write_handler: fbs => #{fbs}")
245
245
  end
246
246
 
247
- def rc_facebook_write_rg_session
247
+ def rc_facebook_write_session
248
248
  return if !rc_options_get(RestCore::Facebook, :write_session)
249
249
  session[rc_facebook_storage_key] = fbs = rc_facebook.fbs
250
250
  logger.debug("DEBUG: Facebook: wrote session: fbs => #{fbs}")
251
251
  end
252
252
 
253
- def rc_facebook_write_rg_cookies
253
+ def rc_facebook_write_cookies
254
254
  return if !rc_options_get(RestCore::Facebook, :write_cookies)
255
255
  cookies[rc_facebook_storage_key] = fbs = rc_facebook.fbs
256
256
  logger.debug("DEBUG: Facebook: wrote cookies: fbs => #{fbs}")
@@ -260,6 +260,13 @@ module RestCore::Facebook::RailsUtil
260
260
 
261
261
 
262
262
  # ==================== begin misc ================================
263
+ def rc_facebook_cleanup
264
+ cookies.delete("fbs_#{rc_facebook.app_id}")
265
+ cookies.delete("fbsr_#{rc_facebook.app_id}")
266
+ cookies.delete(rc_facebook_storage_key)
267
+ session.delete(rc_facebook_storage_key)
268
+ end
269
+
263
270
  def rc_facebook_normalized_request_uri
264
271
  uri = if rc_facebook_in_canvas?
265
272
  # rails 3 uses newer rack which has fullpath
@@ -3,6 +3,7 @@ require 'rest-core'
3
3
 
4
4
  require 'time' # for Time.parse
5
5
 
6
+ # http://wiki.flurry.com
6
7
  RestCore::Flurry = RestCore::Builder.client(:apiKey, :apiAccessCode) do
7
8
  s = self.class # this is only for ruby 1.8!
8
9
  use s::Timeout , 10
@@ -26,34 +27,47 @@ module RestCore::Flurry::Client
26
27
  # "@createdDate"=>"2011-07-24", "@category"=>"Photography",
27
28
  # "@version"=>"1.0", "@generatedDate"=>"9/15/11 7:08 AM",
28
29
  # "version"=>[{"@name"=>"2.1", ...
29
- def app_info query={}
30
- get('appInfo/getApplication', query)
30
+ def app_info query={}, opts={}
31
+ get('appInfo/getApplication', query, opts)
31
32
  end
32
33
 
33
34
  # see: http://wiki.flurry.com/index.php?title=EventMetrics
34
- # >> f.event_matrics({}, :days => 7)
35
- # => {"Facebook share error"=>{"@usersLastWeek"=>"948",
36
- # "@usersLastMonth"=>"2046",
37
- # "@usersLastDay"=>"4",...}}
38
- def event_metrics query={}, opts={}
39
- get('eventMetrics/Summary', *calculate_query_and_opts(query, opts)
40
- )['event'].inject({}){ |r, i|
41
- r[i['@eventName']] = i.reject{ |k, _| k == '@eventName' }
42
- r }
35
+ # >> f.event_names
36
+ # => ["Products", "Save To Photo Library", ...]
37
+ def event_names query={}, opts={}
38
+ event_summary(query, opts).keys
39
+ end
40
+
41
+ # see: http://wiki.flurry.com/index.php?title=EventMetrics
42
+ # >> f.event_summary({}, :days => 7)
43
+ # => {"Products" => {"@usersLastWeek" => "948" ,
44
+ # "@usersLastMonth" => "2046",
45
+ # "@usersLastDay" => "4" , ...}}
46
+ def event_summary query={}, opts={}
47
+ array2hash(get('eventMetrics/Summary',
48
+ *calculate_query_and_opts(query, opts))['event'],
49
+ '@eventName')
50
+ end
51
+
52
+ # see: http://wiki.flurry.com/index.php?title=EventMetrics
53
+ # >> f.event_metrics('Products', {}, :days => 7)
54
+ # => [["2011-11-23", {"@uniqueUsers" => "12" ,
55
+ # "@totalSessions" => "108392" ,
56
+ # "@totalCount" => "30" ,
57
+ # "@duration" => "9754723"}],
58
+ # ["2011-11-22", {...}]]
59
+ def event_metrics name, query={}, opts={}
60
+ array2hash(get('eventMetrics/Event',
61
+ *calculate_query_and_opts(
62
+ {'eventName' => name}.merge(query), opts))['day'],
63
+ '@date').sort{ |a, b| b <=> a }
43
64
  end
44
65
 
45
66
  # see: http://wiki.flurry.com/index.php?title=AppMetrics
46
67
  # >> f.metrics('ActiveUsers', {}, :weeks => 4)
47
68
  # => [["2011-09-19", 6516], ["2011-09-18", 43920], ["2011-09-17", 45412],
48
69
  # ["2011-09-16", 40972], ["2011-09-15", 37587], ["2011-09-14", 34918],
49
- # ["2011-09-13", 35223], ["2011-09-12", 37750], ["2011-09-11", 45057],
50
- # ["2011-09-10", 44077], ["2011-09-09", 36683], ["2011-09-08", 34871],
51
- # ["2011-09-07", 35960], ["2011-09-06", 35829], ["2011-09-05", 37777],
52
- # ["2011-09-04", 40233], ["2011-09-03", 39306], ["2011-09-02", 33467],
53
- # ["2011-09-01", 31558], ["2011-08-31", 32096], ["2011-08-30", 34076],
54
- # ["2011-08-29", 34950], ["2011-08-28", 40456], ["2011-08-27", 41332],
55
- # ["2011-08-26", 37737], ["2011-08-25", 34392], ["2011-08-24", 33560],
56
- # ["2011-08-23", 34722]]
70
+ # ...]
57
71
  def metrics path, query={}, opts={}
58
72
  get("appMetrics/#{path}", *calculate_query_and_opts(query, opts)
59
73
  )['day'].map{ |i| [i['@date'], i['@value'].to_i] }.reverse
@@ -80,7 +94,7 @@ module RestCore::Flurry::Client
80
94
  }.reverse
81
95
  end
82
96
 
83
- def query
97
+ def default_query
84
98
  {'apiKey' => apiKey ,
85
99
  'apiAccessCode' => apiAccessCode}
86
100
  end
@@ -88,7 +102,7 @@ module RestCore::Flurry::Client
88
102
  private
89
103
  def calculate_query_and_opts query, opts
90
104
  days = opts[:days] || (opts[:weeks] && opts[:weeks] * 7) ||
91
- (opts[:months] && opts[:months] * 30)
105
+ (opts[:months] && opts[:months] * 30) || 7
92
106
 
93
107
  startDate = query[:startDate] || (Time.now + 86400 - 86400*days).
94
108
  strftime('%Y-%m-%d')
@@ -100,6 +114,12 @@ module RestCore::Flurry::Client
100
114
  :endDate => endDate),
101
115
  opts.reject{ |k, _| [:days, :weeks, :months].include?(k) }]
102
116
  end
117
+
118
+ def array2hash array, key
119
+ array.inject({}){ |r, i|
120
+ r[i[key]] = i.reject{ |k, _| k == key }
121
+ r }
122
+ end
103
123
  end
104
124
 
105
125
  RestCore::Flurry.send(:include, RestCore::Flurry::Client)
@@ -1,13 +1,14 @@
1
1
 
2
2
  require 'rest-core'
3
3
 
4
+ # http://developer.github.com/v3/
4
5
  RestCore::Github = RestCore::Builder.client do
5
6
  s = self.class # this is only for ruby 1.8!
6
7
  use s::Timeout , 10
7
8
 
8
9
  use s::DefaultSite , 'https://api.github.com/'
9
10
  use s::DefaultHeaders, {'Accept' => 'application/json'}
10
- use s::Oauth2Query , 'access_token', nil
11
+ use s::Oauth2Query , nil
11
12
 
12
13
  use s::CommonLogger , nil
13
14
  use s::Cache , nil, 600 do
@@ -17,5 +18,14 @@ RestCore::Github = RestCore::Builder.client do
17
18
  end
18
19
  end
19
20
 
21
+ module RestCore::Github::Client
22
+ include RestCore
23
+
24
+ def me query={}, opts={}
25
+ get('user', query, opts)
26
+ end
27
+ end
28
+
29
+ RestCore::Github.send(:include, RestCore::Github::Client)
20
30
  require 'rest-core/client/github/rails_util' if
21
31
  Object.const_defined?(:Rails)
@@ -1,7 +1,8 @@
1
1
 
2
2
  require 'rest-core'
3
3
 
4
- RestCore::Linkedin = RestCore::Builder.client(:data) do
4
+ # http://developer.linkedin.com/documents/linkedin-api-resource-map
5
+ RestCore::Linkedin = RestCore::Builder.client do
5
6
  s = self.class # this is only for ruby 1.8!
6
7
  use s::Timeout , 10
7
8
 
@@ -25,33 +26,17 @@ RestCore::Linkedin = RestCore::Builder.client(:data) do
25
26
  use s::ErrorDetectorHttp
26
27
  use s::JsonDecode , true
27
28
  end
28
-
29
- use s::Defaults , :data => lambda{{}}
30
29
  end
31
30
 
32
31
  module RestCore::Linkedin::Client
33
32
  include RestCore
34
33
 
35
- def oauth_token
36
- data['oauth_token'] if data.kind_of?(Hash)
37
- end
38
- def oauth_token= token
39
- data['oauth_token'] = token if data.kind_of?(Hash)
40
- end
41
- def oauth_token_secret
42
- data['oauth_token_secret'] if data.kind_of?(Hash)
43
- end
44
- def oauth_token_secret= secret
45
- data['oauth_token_secret'] = secret if data.kind_of?(Hash)
46
- end
47
-
48
- def me queries={}, opts={}
49
- get('v1/people/~', queries, opts)
34
+ def me query={}, opts={}
35
+ get('v1/people/~', query, opts)
50
36
  end
51
37
 
52
- private
53
- def set_token query
54
- self.data = query
38
+ def authorize_url
39
+ url(authorize_path, :oauth_token => oauth_token, :format => false)
55
40
  end
56
41
  end
57
42
 
@@ -1,4 +1,5 @@
1
1
 
2
+ # http://developer.mixi.co.jp/connect/mixi_graph_api/
2
3
  RestCore::Mixi = RestCore::Builder.client(
3
4
  :data, :consumer_key, :consumer_secret, :redirect_uri) do
4
5
  s = self.class # this is only for ruby 1.8!
@@ -7,7 +8,7 @@ RestCore::Mixi = RestCore::Builder.client(
7
8
  use s::DefaultSite , 'http://api.mixi-platform.com/'
8
9
  use s::DefaultHeaders, {'Accept' => 'application/json'}
9
10
 
10
- use s::Oauth2Header , nil
11
+ use s::Oauth2Header , 'OAuth', nil
11
12
 
12
13
  use s::CommonLogger , nil
13
14
  use s::Cache , nil, 600 do
@@ -15,13 +16,15 @@ RestCore::Mixi = RestCore::Builder.client(
15
16
  use s::ErrorDetectorHttp
16
17
  use s::JsonDecode , true
17
18
  end
18
-
19
- use s::Defaults , :data => lambda{{}}
20
19
  end
21
20
 
22
21
  module RestCore::Mixi::Client
23
22
  include RestCore
24
23
 
24
+ def me query={}, opts={}
25
+ get('2/people/@me/@self', query, opts)
26
+ end
27
+
25
28
  def access_token
26
29
  data['access_token'] if data.kind_of?(Hash)
27
30
  end
@@ -45,6 +48,11 @@ module RestCore::Mixi::Client
45
48
 
46
49
  self.data = post('https://secure.mixi-platform.com/2/token', pl, {}, opts)
47
50
  end
51
+
52
+ private
53
+ def default_data
54
+ {}
55
+ end
48
56
  end
49
57
 
50
58
  RestCore::Mixi.send(:include, RestCore::Mixi::Client)
@@ -1,7 +1,8 @@
1
1
 
2
2
  require 'rest-core'
3
3
 
4
- RestCore::Twitter = RestCore::Builder.client(:data) do
4
+ # https://dev.twitter.com/docs
5
+ RestCore::Twitter = RestCore::Builder.client do
5
6
  s = self.class # this is only for ruby 1.8!
6
7
  use s::Timeout , 10
7
8
 
@@ -18,10 +19,9 @@ RestCore::Twitter = RestCore::Builder.client(:data) do
18
19
  use s::ErrorDetectorHttp
19
20
  use s::JsonDecode , true
20
21
  end
21
-
22
- use s::Defaults , :data => lambda{{}}
23
22
  end
24
23
 
24
+ # https://dev.twitter.com/docs/error-codes-responses
25
25
  class RestCore::Twitter::Error < RestCore::Error
26
26
  include RestCore
27
27
  class ServerError < Twitter::Error; end
@@ -64,36 +64,24 @@ end
64
64
  module RestCore::Twitter::Client
65
65
  include RestCore
66
66
 
67
- def oauth_token
68
- data['oauth_token'] if data.kind_of?(Hash)
69
- end
70
- def oauth_token= token
71
- data['oauth_token'] = token if data.kind_of?(Hash)
72
- end
73
- def oauth_token_secret
74
- data['oauth_token_secret'] if data.kind_of?(Hash)
75
- end
76
- def oauth_token_secret= secret
77
- data['oauth_token_secret'] = secret if data.kind_of?(Hash)
67
+ def me query={}, opts={}
68
+ get('1/account/verify_credentials.json', query, opts)
78
69
  end
79
70
 
80
- def tweet status, media=nil, opts={}
71
+ def tweet status, media=nil, payload={}, query={}, opts={}
81
72
  if media
82
73
  post('https://upload.twitter.com/1/statuses/update_with_media.json',
83
- {:status => status, 'media[]' => media},
84
- {}, opts)
74
+ {:status => status, 'media[]' => media}.merge(payload),
75
+ query, opts)
85
76
  else
86
- post('1/statuses/update.json', {:status => status}, {}, opts)
77
+ post('1/statuses/update.json',
78
+ {:status => status}.merge(payload),
79
+ query, opts)
87
80
  end
88
81
  end
89
82
 
90
- def statuses user, queries={}, opts={}
91
- get('1/statuses/user_timeline.json', {:id => user}.merge(queries), opts)
92
- end
93
-
94
- private
95
- def set_token query
96
- self.data = query
83
+ def statuses user, query={}, opts={}
84
+ get('1/statuses/user_timeline.json', {:id => user}.merge(query), opts)
97
85
  end
98
86
  end
99
87
 
@@ -2,12 +2,160 @@
2
2
  require 'rest-core/util/rails_util_util'
3
3
 
4
4
  module RestCore::Twitter::DefaultAttributes
5
- def default_log_method; Rails.logger.method(:debug); end
6
- def default_cache ; Rails.cache ; end
5
+ def default_log_method ; Rails.logger.method(:debug); end
6
+ def default_cache ; Rails.cache ; end
7
+ def default_auto_authorize ; false ; end
8
+ def default_ensure_authorized; false ; end
9
+ def default_write_session ; false ; end
10
+ def default_write_cookies ; false ; end
11
+ def default_write_handler ; nil ; end
12
+ def default_check_handler ; nil ; end
7
13
  end
8
14
 
9
15
  module RestCore::Twitter::RailsUtil
10
16
  include RestCore::RailsUtilUtil
17
+
18
+ def self.included controller
19
+ # skip if included already, any better way to detect this?
20
+ return if controller.respond_to?(:rc_twitter, true)
21
+ super
22
+ controller.rescue_from(RestCore::Twitter::Error::Unauthorized,
23
+ :with => :rc_twitter_on_unauthorized)
24
+ end
25
+
26
+ def rc_twitter_setup options={}
27
+ super
28
+
29
+ rc_twitter_check_handler
30
+ rc_twitter_check_session
31
+ rc_twitter_check_cookies
32
+ rc_twitter_check_oauth_verifier
33
+
34
+ if rc_options_get(RestCore::Twitter, :ensure_authorized) &&
35
+ !rc_twitter.authorized?
36
+
37
+ rc_twitter_authorize('ensure authorized')
38
+ false # action halt, redirect to do authorize,
39
+ # eagerly, as opposed to auto_authorize
40
+ else
41
+ true # keep going
42
+ end
43
+ end
44
+
45
+ def rc_twitter_on_unauthorized error=nil
46
+ rc_twitter_authorize(error, false)
47
+ end
48
+
49
+ def rc_twitter_authorize error=nil, force_redirect=true
50
+ logger.warn("WARN: Twitter: #{error.inspect}")
51
+
52
+ if force_redirect || rc_options_get(RestCore::Twitter, :auto_authorize)
53
+ rc_twitter_cleanup
54
+
55
+ callback = rc_twitter_normalized_request_uri
56
+ redirect_url = rc_twitter.authorize_url!(:oauth_callback => callback)
57
+ rc_twitter.oauth_callback = callback
58
+ rc_twitter_write_data_json
59
+
60
+ logger.debug(
61
+ "DEBUG: Twitter: redirect to #{redirect_url} from #{callback}")
62
+
63
+ redirect_to redirect_url
64
+ end
65
+ end
66
+
67
+ # ==================== begin check ================================
68
+ def rc_twitter_storage_key
69
+ "rc_twitter_#{rc_twitter.consumer_key}"
70
+ end
71
+
72
+ def rc_twitter_check_oauth_verifier
73
+ return if !rc_twitter.oauth_callback || !params[:oauth_verifier]
74
+
75
+ rc_twitter.authorize!(:oauth_verifier => params[:oauth_verifier])
76
+ rc_twitter.data.delete('oauth_callback')
77
+
78
+ logger.debug(
79
+ "DEBUG: Twitter: detected oauth_verifier with #{request.url}," \
80
+ " parsed: #{rc_twitter.data.inspect}")
81
+
82
+ rc_twitter_write_data_json if rc_twitter.authorized?
83
+ end
84
+
85
+ def rc_twitter_check_handler handler=
86
+ rc_options_get(RestCore::Twitter, :check_handler)
87
+
88
+ return if rc_twitter.authorized? || !handler
89
+ rc_twitter.data_json = handler.call
90
+ logger.debug("DEBUG: Twitter: called check_handler, parsed:" \
91
+ " #{rc_twitter.data.inspect}")
92
+ end
93
+
94
+ def rc_twitter_check_session
95
+ return if rc_twitter.authorized? ||
96
+ !rc_options_get(RestCore::Twitter, :write_session) ||
97
+ !(data_json = session[rc_twitter_storage_key])
98
+
99
+ rc_twitter.data_json = data_json
100
+ logger.debug("DEBUG: Twitter: detected rc_twitter session, parsed:" \
101
+ " #{rc_twitter.data.inspect}")
102
+ end
103
+
104
+ def rc_twitter_check_cookies
105
+ return if rc_twitter.authorized? ||
106
+ !rc_options_get(RestCore::Twitter, :write_cookies) ||
107
+ !(data_json = cookies[rc_twitter_storage_key])
108
+
109
+ rc_twitter.data_json = data_json
110
+ logger.debug("DEBUG: Twitter: detected rc_twitter cookies, parsed:" \
111
+ " #{rc_twitter.data.inspect}")
112
+ end
113
+ # ==================== end check ================================
114
+ # ==================== begin write ================================
115
+ def rc_twitter_write_data_json
116
+ rc_twitter_write_handler
117
+ rc_twitter_write_session
118
+ rc_twitter_write_cookies
119
+ end
120
+
121
+ def rc_twitter_write_handler handler=
122
+ rc_options_get(RestCore::Twitter, :write_handler)
123
+
124
+ return if !handler
125
+ handler.call(data_json = rc_twitter.data_json)
126
+ logger.debug("DEBUG: Twitter: write_handler: data_json => #{data_json}")
127
+ end
128
+
129
+ def rc_twitter_write_session
130
+ return if !rc_options_get(RestCore::Twitter, :write_session)
131
+ session[rc_twitter_storage_key] = data_json = rc_twitter.data_json
132
+ logger.debug("DEBUG: Twitter: wrote session: data_json => #{data_json}")
133
+ end
134
+
135
+ def rc_twitter_write_cookies
136
+ return if !rc_options_get(RestCore::Twitter, :write_cookies)
137
+ cookies[rc_twitter_storage_key] = data_json = rc_twitter.data_json
138
+ logger.debug("DEBUG: Twitter: wrote cookies: data_json => #{data_json}")
139
+ end
140
+ # ==================== end write ================================
141
+
142
+
143
+
144
+ # ==================== begin misc ================================
145
+ def rc_twitter_cleanup
146
+ session.delete(rc_twitter_storage_key)
147
+ cookies.delete(rc_twitter_storage_key)
148
+ end
149
+
150
+ def rc_twitter_normalized_request_uri
151
+ URI.parse(request.url).tap{ |uri|
152
+ uri.query = uri.query.split('&').reject{ |q|
153
+ q =~ /^(oauth_verifier|oauth_token)\=/
154
+ }.join('&') if uri.query
155
+ uri.query = nil if uri.query.blank?
156
+ }.to_s
157
+ end
158
+ # ==================== end misc ================================
11
159
  end
12
160
 
13
161
  RestCore::Twitter::RailsUtil.init(Rails)
@@ -1,4 +1,4 @@
1
1
 
2
2
  module RestMore
3
- VERSION = '0.7.2.1'
3
+ VERSION = '0.8.0'
4
4
  end
data/rest-more.gemspec CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "rest-more"
5
- s.version = "0.7.2.1"
5
+ s.version = "0.8.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = [
9
9
  "Cardinal Blue",
10
10
  "Lin Jen-Shin (godfat)"]
11
- s.date = "2011-11-05"
11
+ s.date = "2011-11-29"
12
12
  s.description = "Various REST clients such as Facebook and Twitter built with [rest-core][]\n\n[rest-core]: https://github.com/cardinalblue/rest-core"
13
13
  s.email = ["dev (XD) cardinalblue.com"]
14
14
  s.executables = ["rib-rest-core"]
@@ -18,9 +18,11 @@ describe RC::Facebook do
18
18
  end
19
19
 
20
20
  should 'do authorizing and parse result and save it in data' do
21
- stub_request(:get, 'https://graph.facebook.com/oauth/access_token?' \
22
- 'client_id=29&client_secret=18&code=zzz&' \
23
- 'redirect_uri=http%3A%2F%2Fzzz.tw').
21
+ stub_request(:post, 'https://graph.facebook.com/oauth/access_token'). \
22
+ with(:body => {'client_id' => '29' ,
23
+ 'client_secret' => '18' ,
24
+ 'redirect_uri' => 'http://zzz.tw',
25
+ 'code' => 'zzz'}).
24
26
  to_return(:body => 'access_token=baken&expires=2918')
25
27
 
26
28
  result = {'access_token' => 'baken', 'expires' => '2918'}
@@ -9,74 +9,85 @@ describe RC::Flurry do
9
9
  RR.verify
10
10
  end
11
11
 
12
- before do
13
- startDate = '2011-08-23'
14
- endDate = '2011-09-19'
15
- @flurry = RestCore::Flurry.new
16
- stub(Time).now{ Time.parse(endDate, nil) }
17
- stub_request(:get,
18
- "http://api.flurry.com/appMetrics/ActiveUsers?" \
19
- "startDate=#{startDate}&endDate=#{endDate}").
20
- to_return(:body =>
21
- '{"@startDate":"2011-08-23",
22
- "@metric":"ActiveUsersByDay",
23
- "@endDate":"2011-09-19",
24
- "@version":"1.0",
25
- "@generatedDate":"9/19/11 5:54 AM",
26
- "day":
27
- [{"@value":"34722","@date":"2011-08-23"},
28
- {"@value":"33560","@date":"2011-08-24"},
29
- {"@value":"34392","@date":"2011-08-25"},
30
- {"@value":"37737","@date":"2011-08-26"},
31
- {"@value":"41332","@date":"2011-08-27"},
32
- {"@value":"40456","@date":"2011-08-28"},
33
- {"@value":"34950","@date":"2011-08-29"},
34
- {"@value":"34076","@date":"2011-08-30"},
35
- {"@value":"32096","@date":"2011-08-31"},
36
- {"@value":"31558","@date":"2011-09-01"},
37
- {"@value":"33467","@date":"2011-09-02"},
38
- {"@value":"39306","@date":"2011-09-03"},
39
- {"@value":"40233","@date":"2011-09-04"},
40
- {"@value":"37777","@date":"2011-09-05"},
41
- {"@value":"35829","@date":"2011-09-06"},
42
- {"@value":"35960","@date":"2011-09-07"},
43
- {"@value":"34871","@date":"2011-09-08"},
44
- {"@value":"36683","@date":"2011-09-09"},
45
- {"@value":"44077","@date":"2011-09-10"},
46
- {"@value":"45057","@date":"2011-09-11"},
47
- {"@value":"37750","@date":"2011-09-12"},
48
- {"@value":"35223","@date":"2011-09-13"},
49
- {"@value":"34918","@date":"2011-09-14"},
50
- {"@value":"37587","@date":"2011-09-15"},
51
- {"@value":"40972","@date":"2011-09-16"},
52
- {"@value":"45412","@date":"2011-09-17"},
53
- {"@value":"43920","@date":"2011-09-18"},
54
- {"@value":"6516","@date":"2011-09-19"}]}')
12
+ describe 'metrics' do
13
+ before do
14
+ startDate = '2011-08-23'
15
+ endDate = '2011-09-19'
16
+ @flurry = RestCore::Flurry.new
17
+ stub(Time).now{ Time.parse(endDate, nil) }
18
+ stub_request(:get,
19
+ "http://api.flurry.com/appMetrics/ActiveUsers?" \
20
+ "startDate=#{startDate}&endDate=#{endDate}").
21
+ to_return(:body =>
22
+ '{"@startDate":"2011-08-23",
23
+ "@metric":"ActiveUsersByDay",
24
+ "@endDate":"2011-09-19",
25
+ "@version":"1.0",
26
+ "@generatedDate":"9/19/11 5:54 AM",
27
+ "day":
28
+ [{"@value":"34722","@date":"2011-08-23"},
29
+ {"@value":"33560","@date":"2011-08-24"},
30
+ {"@value":"34392","@date":"2011-08-25"},
31
+ {"@value":"37737","@date":"2011-08-26"},
32
+ {"@value":"41332","@date":"2011-08-27"},
33
+ {"@value":"40456","@date":"2011-08-28"},
34
+ {"@value":"34950","@date":"2011-08-29"},
35
+ {"@value":"34076","@date":"2011-08-30"},
36
+ {"@value":"32096","@date":"2011-08-31"},
37
+ {"@value":"31558","@date":"2011-09-01"},
38
+ {"@value":"33467","@date":"2011-09-02"},
39
+ {"@value":"39306","@date":"2011-09-03"},
40
+ {"@value":"40233","@date":"2011-09-04"},
41
+ {"@value":"37777","@date":"2011-09-05"},
42
+ {"@value":"35829","@date":"2011-09-06"},
43
+ {"@value":"35960","@date":"2011-09-07"},
44
+ {"@value":"34871","@date":"2011-09-08"},
45
+ {"@value":"36683","@date":"2011-09-09"},
46
+ {"@value":"44077","@date":"2011-09-10"},
47
+ {"@value":"45057","@date":"2011-09-11"},
48
+ {"@value":"37750","@date":"2011-09-12"},
49
+ {"@value":"35223","@date":"2011-09-13"},
50
+ {"@value":"34918","@date":"2011-09-14"},
51
+ {"@value":"37587","@date":"2011-09-15"},
52
+ {"@value":"40972","@date":"2011-09-16"},
53
+ {"@value":"45412","@date":"2011-09-17"},
54
+ {"@value":"43920","@date":"2011-09-18"},
55
+ {"@value":"6516","@date":"2011-09-19"}]}')
55
56
 
56
- @active_users =
57
- [["2011-09-19", 6516], ["2011-09-18", 43920], ["2011-09-17", 45412],
58
- ["2011-09-16", 40972], ["2011-09-15", 37587], ["2011-09-14", 34918],
59
- ["2011-09-13", 35223], ["2011-09-12", 37750], ["2011-09-11", 45057],
60
- ["2011-09-10", 44077], ["2011-09-09", 36683], ["2011-09-08", 34871],
61
- ["2011-09-07", 35960], ["2011-09-06", 35829], ["2011-09-05", 37777],
62
- ["2011-09-04", 40233], ["2011-09-03", 39306], ["2011-09-02", 33467],
63
- ["2011-09-01", 31558], ["2011-08-31", 32096], ["2011-08-30", 34076],
64
- ["2011-08-29", 34950], ["2011-08-28", 40456], ["2011-08-27", 41332],
65
- ["2011-08-26", 37737], ["2011-08-25", 34392], ["2011-08-24", 33560],
66
- ["2011-08-23", 34722]]
57
+ @active_users =
58
+ [["2011-09-19", 6516], ["2011-09-18", 43920], ["2011-09-17", 45412],
59
+ ["2011-09-16", 40972], ["2011-09-15", 37587], ["2011-09-14", 34918],
60
+ ["2011-09-13", 35223], ["2011-09-12", 37750], ["2011-09-11", 45057],
61
+ ["2011-09-10", 44077], ["2011-09-09", 36683], ["2011-09-08", 34871],
62
+ ["2011-09-07", 35960], ["2011-09-06", 35829], ["2011-09-05", 37777],
63
+ ["2011-09-04", 40233], ["2011-09-03", 39306], ["2011-09-02", 33467],
64
+ ["2011-09-01", 31558], ["2011-08-31", 32096], ["2011-08-30", 34076],
65
+ ["2011-08-29", 34950], ["2011-08-28", 40456], ["2011-08-27", 41332],
66
+ ["2011-08-26", 37737], ["2011-08-25", 34392], ["2011-08-24", 33560],
67
+ ["2011-08-23", 34722]]
67
68
 
68
- @weekly = [244548, 270227, 248513, 257149]
69
- end
69
+ @weekly = [244548, 270227, 248513, 257149]
70
+ end
70
71
 
71
- should 'metrics("ActiveUsers")' do
72
- @flurry.metrics('ActiveUsers', {}, :weeks => 4).should.eq @active_users
73
- end
72
+ should 'metrics("ActiveUsers")' do
73
+ @flurry.metrics('ActiveUsers', {}, :weeks => 4).should.eq @active_users
74
+ end
74
75
 
75
- should 'weekly(metrics("ActiveUsers"))' do
76
- @flurry.weekly(@active_users).should.eq @weekly
76
+ should 'weekly(metrics("ActiveUsers"))' do
77
+ @flurry.weekly(@active_users).should.eq @weekly
78
+ end
79
+
80
+ should 'sum(weekly(metrics("ActiveUsers")))' do
81
+ @flurry.sum(@weekly).should.eq [1020437, 775889, 505662, 257149]
82
+ end
77
83
  end
78
84
 
79
- should 'sum(weekly(metrics("ActiveUsers")))' do
80
- @flurry.sum(@weekly).should.eq [1020437, 775889, 505662, 257149]
85
+ should 'bring apiKey and apiAccessCode' do
86
+ stub_request(:get,
87
+ "http://api.flurry.com/?apiKey=a&apiAccessCode=b").
88
+ to_return(:body => '["ok"]')
89
+
90
+ f = RC::Flurry.new(:apiKey => 'a', :apiAccessCode => 'b')
91
+ f.get('').should.eq ['ok']
81
92
  end
82
93
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest-more
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.2.1
4
+ version: 0.8.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-11-05 00:00:00.000000000 Z
13
+ date: 2011-11-29 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rest-core
17
- requirement: &2153326960 !ruby/object:Gem::Requirement
17
+ requirement: &2158239560 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,7 +22,7 @@ dependencies:
22
22
  version: '0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *2153326960
25
+ version_requirements: *2158239560
26
26
  description: ! 'Various REST clients such as Facebook and Twitter built with [rest-core][]
27
27
 
28
28