rest-more 0.7.2.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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