rest-more 1.0.2 → 2.0.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/.gitignore +0 -5
- data/.travis.yml +4 -6
- data/CHANGES.md +16 -0
- data/Gemfile +6 -3
- data/README.md +43 -129
- data/Rakefile +2 -3
- data/example/multi.rb +12 -23
- data/example/rails3/Gemfile +2 -1
- data/example/rails3/app/controllers/application_controller.rb +9 -4
- data/example/rails3/test/functional/application_controller_test.rb +1 -1
- data/example/rainbows.rb +48 -7
- data/example/simple.rb +3 -3
- data/example/sinatra/config.ru +1 -1
- data/lib/rest-core/client/dropbox.rb +19 -27
- data/lib/rest-core/client/facebook.rb +28 -51
- data/lib/rest-core/client/facebook/rails_util.rb +13 -11
- data/lib/rest-core/client/github.rb +13 -21
- data/lib/rest-core/client/linkedin.rb +19 -27
- data/lib/rest-core/client/twitter.rb +13 -21
- data/lib/rest-more.rb +0 -2
- data/lib/rest-more/test.rb +11 -0
- data/lib/rest-more/version.rb +1 -1
- data/rest-more.gemspec +7 -41
- data/task/.gitignore +1 -0
- data/task/gemgem.rb +267 -0
- data/test/dropbox/test_api.rb +1 -1
- data/test/facebook/config/rest-core.yaml +1 -1
- data/test/facebook/test_api.rb +10 -14
- data/test/facebook/test_error.rb +2 -2
- data/test/facebook/test_handler.rb +6 -6
- data/test/facebook/test_load_config.rb +4 -4
- data/test/facebook/test_misc.rb +3 -3
- data/test/facebook/test_old.rb +2 -37
- data/test/facebook/test_page.rb +26 -24
- data/test/facebook/test_parse.rb +1 -1
- data/test/facebook/test_serialize.rb +3 -19
- data/test/facebook/test_timeout.rb +6 -2
- data/test/twitter/test_api.rb +1 -1
- metadata +6 -40
- data/doc/ToC.md +0 -9
- data/doc/dependency.md +0 -4
- data/doc/design.md +0 -4
- data/doc/rest-graph.md +0 -4
- data/example/async.rb +0 -89
- data/example/facebook.rb +0 -13
- data/example/rails2/Gemfile +0 -22
- data/example/rails2/README +0 -4
- data/example/rails2/Rakefile +0 -11
- data/example/rails2/app/controllers/application_controller.rb +0 -138
- data/example/rails2/app/views/application/helper.html.erb +0 -1
- data/example/rails2/config/boot.rb +0 -130
- data/example/rails2/config/environment.rb +0 -25
- data/example/rails2/config/environments/development.rb +0 -17
- data/example/rails2/config/environments/production.rb +0 -28
- data/example/rails2/config/environments/test.rb +0 -30
- data/example/rails2/config/initializers/cookie_verification_secret.rb +0 -7
- data/example/rails2/config/initializers/new_rails_defaults.rb +0 -21
- data/example/rails2/config/initializers/session_store.rb +0 -15
- data/example/rails2/config/preinitializer.rb +0 -23
- data/example/rails2/config/rest-core.yaml +0 -12
- data/example/rails2/config/routes.rb +0 -43
- data/example/rails2/log +0 -0
- data/example/rails2/test/functional/application_controller_test.rb +0 -259
- data/example/rails2/test/test_helper.rb +0 -18
- data/example/rails2/test/unit/rails_util_test.rb +0 -49
- data/lib/rest-core/client/bing.rb +0 -102
- data/lib/rest-core/client/bing/rails_util.rb +0 -13
- data/lib/rest-core/client/mixi.rb +0 -60
- data/lib/rest-core/client/mixi/rails_util.rb +0 -13
- data/test/bing/test_api.rb +0 -34
- data/test/facebook/test_cache.rb +0 -58
- data/test/mixi/test_api.rb +0 -20
@@ -124,7 +124,7 @@ class ApplicationControllerTest < ActionController::TestCase
|
|
124
124
|
|
125
125
|
get(:cache)
|
126
126
|
assert_response :success
|
127
|
-
assert_equal
|
127
|
+
assert_equal %Q|200\n\n\n{"message":"ok"}|, @response.body
|
128
128
|
end
|
129
129
|
|
130
130
|
def test_handler
|
data/example/rainbows.rb
CHANGED
@@ -4,7 +4,9 @@ preload_app true
|
|
4
4
|
|
5
5
|
Rainbows! do
|
6
6
|
use :EventMachine, :em_client_class => lambda{
|
7
|
-
|
7
|
+
RainbowsEventMachineThreadPoolClient
|
8
|
+
# or
|
9
|
+
# RainbowsEventMachineFiberSpawnClient
|
8
10
|
}
|
9
11
|
worker_connections 100
|
10
12
|
|
@@ -12,14 +14,53 @@ Rainbows! do
|
|
12
14
|
client_header_buffer_size 8*1024 # 8 kilobytes
|
13
15
|
end
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
+
after_fork{ |_, _|
|
18
|
+
EM.threadpool_size = 32
|
19
|
+
class RainbowsEventMachineThreadPoolClient < Rainbows::EventMachine::Client
|
20
|
+
def app_call input
|
21
|
+
set_comm_inactivity_timeout 0
|
22
|
+
@env[RACK_INPUT] = input
|
23
|
+
@env[REMOTE_ADDR] = @_io.kgio_addr
|
24
|
+
@env[ASYNC_CALLBACK] = method(:write_async_response)
|
25
|
+
@env[ASYNC_CLOSE] = EM::DefaultDeferrable.new
|
26
|
+
@deferred = true
|
27
|
+
EM.defer{
|
28
|
+
status, headers, body = catch(:async) {
|
29
|
+
APP.call(@env.merge!(RACK_DEFAULTS))
|
30
|
+
}
|
31
|
+
if nil == status || -1 == status
|
32
|
+
@deferred = true
|
33
|
+
else
|
34
|
+
@deferred = nil
|
35
|
+
ev_write_response(status, headers, body, @hp.next?)
|
36
|
+
end
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
17
40
|
|
18
|
-
class
|
19
|
-
|
20
|
-
|
41
|
+
class RainbowsEventMachineFiberSpawnClient < Rainbows::EventMachine::Client
|
42
|
+
def app_call input
|
43
|
+
set_comm_inactivity_timeout 0
|
44
|
+
@env[RACK_INPUT] = input
|
45
|
+
@env[REMOTE_ADDR] = @_io.kgio_addr
|
46
|
+
@env[ASYNC_CALLBACK] = method(:write_async_response)
|
47
|
+
@env[ASYNC_CLOSE] = EM::DefaultDeferrable.new
|
48
|
+
f = Fiber.new{
|
49
|
+
status, headers, body = catch(:async) {
|
50
|
+
APP.call(@env.merge!(RACK_DEFAULTS))
|
51
|
+
}
|
52
|
+
if nil == status || -1 == status
|
53
|
+
@deferred = true
|
54
|
+
else
|
55
|
+
@deferred = nil
|
56
|
+
ev_write_response(status, headers, body, @hp.next?)
|
57
|
+
end
|
58
|
+
}
|
59
|
+
f.resume
|
60
|
+
@deferred = true if f.alive?
|
61
|
+
end
|
21
62
|
end
|
22
|
-
|
63
|
+
}
|
23
64
|
|
24
65
|
EM.error_handler{ |e|
|
25
66
|
puts "Error: EM.error_handler: #{e.inspect} #{e.backtrace.inspect}"
|
data/example/simple.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
|
2
2
|
require 'rest-more'
|
3
3
|
|
4
|
-
p
|
4
|
+
p RC::Twitter.new.statuses('_cardinalblue').first # get user tweets
|
5
5
|
puts
|
6
|
-
p
|
6
|
+
p RC::Github.new.get('users/cardinalblue') # get user info
|
7
7
|
puts
|
8
|
-
p
|
8
|
+
p RC::Facebook.new.get('4') # get user info
|
data/example/sinatra/config.ru
CHANGED
@@ -2,32 +2,24 @@
|
|
2
2
|
require 'rest-core'
|
3
3
|
|
4
4
|
# https://www.dropbox.com/developers/reference/api
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
else
|
24
|
-
env.merge(s::RESPONSE_BODY => ::RestCore::Dropbox::Error.call(env))
|
25
|
-
end
|
26
|
-
else
|
27
|
-
raise ::RestCore::Dropbox::Error.call(env)
|
28
|
-
end}
|
29
|
-
use s::ErrorDetectorHttp
|
30
|
-
use s::JsonDecode , true
|
5
|
+
module RestCore
|
6
|
+
Dropbox = Builder.client(:root) do
|
7
|
+
use Timeout , 10
|
8
|
+
|
9
|
+
use DefaultSite , 'https://api.dropbox.com/'
|
10
|
+
use DefaultHeaders, {'Accept' => 'application/json',
|
11
|
+
'Content-Type' => 'application/octet-stream'}
|
12
|
+
|
13
|
+
use Oauth1Header ,
|
14
|
+
'1/oauth/request_token', '1/oauth/access_token',
|
15
|
+
'https://www.dropbox.com/1/oauth/authorize'
|
16
|
+
|
17
|
+
use CommonLogger , nil
|
18
|
+
use Cache , nil, 600 do
|
19
|
+
use ErrorHandler, lambda{ |env| Dropbox::Error.call(env) }
|
20
|
+
use ErrorDetectorHttp
|
21
|
+
use JsonResponse, true
|
22
|
+
end
|
31
23
|
end
|
32
24
|
end
|
33
25
|
|
@@ -86,7 +78,7 @@ module RestCore::Dropbox::Client
|
|
86
78
|
|
87
79
|
def download path, query={}, opts={}
|
88
80
|
get("https://api-content.dropbox.com/1/files/#{root}/#{path}",
|
89
|
-
query, {:
|
81
|
+
query, {:json_response => false}.merge(opts))
|
90
82
|
end
|
91
83
|
|
92
84
|
def upload path, file, query={}, opts={}
|
@@ -4,39 +4,27 @@ require 'rest-core/util/hmac'
|
|
4
4
|
|
5
5
|
# https://developers.facebook.com/docs/reference/api
|
6
6
|
# https://developers.facebook.com/tools/explorer
|
7
|
-
|
8
|
-
:data, :app_id, :secret, :old_site) do
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
env.merge(s::RESPONSE_BODY => ::RestCore::Facebook::Error.call(env))
|
26
|
-
end
|
27
|
-
else
|
28
|
-
raise ::RestCore::Facebook::Error.call(env)
|
29
|
-
end}
|
30
|
-
use s::ErrorDetector, lambda{ |env|
|
31
|
-
if env[s::RESPONSE_BODY].kind_of?(Hash)
|
32
|
-
env[s::RESPONSE_BODY]['error'] ||
|
33
|
-
env[s::RESPONSE_BODY]['error_code']
|
34
|
-
end}
|
35
|
-
|
36
|
-
use s::JsonDecode , true
|
37
|
-
end
|
7
|
+
module RestCore
|
8
|
+
Facebook = Builder.client(:data, :app_id, :secret, :old_site) do
|
9
|
+
use Timeout , 10
|
10
|
+
|
11
|
+
use DefaultSite , 'https://graph.facebook.com/'
|
12
|
+
use DefaultHeaders, {'Accept' => 'application/json',
|
13
|
+
'Accept-Language' => 'en-us'}
|
14
|
+
use Oauth2Query , nil
|
15
|
+
|
16
|
+
use CommonLogger , nil
|
17
|
+
use Cache , nil, 600 do
|
18
|
+
use ErrorHandler, lambda{ |env| Facebook::Error.call(env) }
|
19
|
+
use ErrorDetector, lambda{ |env|
|
20
|
+
env[RESPONSE_BODY].kind_of?(Hash) &&
|
21
|
+
(env[RESPONSE_BODY]['error'] || env[RESPONSE_BODY]['error_code'])}
|
22
|
+
|
23
|
+
use JsonResponse, true
|
24
|
+
end
|
38
25
|
|
39
|
-
|
26
|
+
use Defaults , :old_site => 'https://api.facebook.com/'
|
27
|
+
end
|
40
28
|
end
|
41
29
|
|
42
30
|
class RestCore::Facebook::Error < RestCore::Error
|
@@ -195,8 +183,8 @@ module RestCore::Facebook::Client
|
|
195
183
|
|
196
184
|
def parse_json! json
|
197
185
|
self.data = json &&
|
198
|
-
check_sig_and_return_data(
|
199
|
-
rescue
|
186
|
+
check_sig_and_return_data(Json.decode(json))
|
187
|
+
rescue Json::ParseError
|
200
188
|
self.data = nil
|
201
189
|
end
|
202
190
|
|
@@ -213,10 +201,10 @@ module RestCore::Facebook::Client
|
|
213
201
|
"#{str.tr('-_', '+/')}==".unpack('m').first
|
214
202
|
}
|
215
203
|
self.data = check_sig_and_return_data(
|
216
|
-
|
204
|
+
Json.decode(json).merge('sig' => sig)){
|
217
205
|
Hmac.sha256(secret, json_encoded)
|
218
206
|
}
|
219
|
-
rescue
|
207
|
+
rescue Json::ParseError
|
220
208
|
self.data = nil
|
221
209
|
end
|
222
210
|
|
@@ -231,24 +219,14 @@ module RestCore::Facebook::Client
|
|
231
219
|
payload = {:client_id => app_id, :client_secret => secret}.merge(opts)
|
232
220
|
self.data = ParseQuery.parse_query(
|
233
221
|
post('oauth/access_token', payload, {},
|
234
|
-
{:
|
222
|
+
{:json_response => false}.merge(opts)))
|
235
223
|
end
|
236
224
|
|
237
225
|
# old rest facebook api, i will definitely love to remove them someday
|
238
226
|
|
239
227
|
def old_rest path, query={}, opts={}, &cb
|
240
|
-
|
241
|
-
|
242
|
-
if opts[:post]
|
243
|
-
post(url("method/#{path}", {:format => 'json'},
|
244
|
-
{:site => old_site}.merge(opts)),
|
245
|
-
query,
|
246
|
-
{} ,
|
247
|
-
opts.merge('cache.key' => uri, 'cache.post' => true),
|
248
|
-
&cb)
|
249
|
-
else
|
250
|
-
get(uri, {}, opts, &cb)
|
251
|
-
end
|
228
|
+
get("method/#{path}", {:format => 'json'}.merge(query),
|
229
|
+
{:site => old_site}.merge(opts), &cb)
|
252
230
|
end
|
253
231
|
|
254
232
|
def secret_old_rest path, query={}, opts={}, &cb
|
@@ -261,7 +239,7 @@ module RestCore::Facebook::Client
|
|
261
239
|
|
262
240
|
def fql_multi codes, query={}, opts={}, &cb
|
263
241
|
old_rest('fql.multiquery',
|
264
|
-
{:queries =>
|
242
|
+
{:queries => Json.encode(codes)}.merge(query), opts, &cb)
|
265
243
|
end
|
266
244
|
|
267
245
|
def exchange_sessions query={}, opts={}, &cb
|
@@ -280,7 +258,6 @@ module RestCore::Facebook::Client
|
|
280
258
|
super(env.inject({}){ |r, (k, v)|
|
281
259
|
case k.to_s
|
282
260
|
when 'secret' ; r['access_token'] = secret_access_token
|
283
|
-
when 'cache' ; r['cache.update'] = !!!v
|
284
261
|
else ; r[k.to_s] = v
|
285
262
|
end
|
286
263
|
r
|
@@ -268,17 +268,19 @@ module RestCore::Facebook::RailsUtil
|
|
268
268
|
end
|
269
269
|
|
270
270
|
def rc_facebook_normalized_request_uri
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
request.fullpath
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
271
|
+
@rc_facebook_normalized_request_uri ||= begin
|
272
|
+
uri = if rc_facebook_in_canvas?
|
273
|
+
# rails 3 uses newer rack which has fullpath
|
274
|
+
"http://apps.facebook.com/#{
|
275
|
+
rc_options_get(RestCore::Facebook, :canvas)}" +
|
276
|
+
(request.respond_to?(:fullpath) ?
|
277
|
+
request.fullpath : request.request_uri)
|
278
|
+
else
|
279
|
+
request.url
|
280
|
+
end
|
281
|
+
|
282
|
+
rc_facebook_filter_uri(uri)
|
283
|
+
end
|
282
284
|
end
|
283
285
|
|
284
286
|
def rc_facebook_filter_uri uri
|
@@ -2,29 +2,21 @@
|
|
2
2
|
require 'rest-core'
|
3
3
|
|
4
4
|
# http://developer.github.com/v3/
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
module RestCore
|
6
|
+
Github = Builder.client do
|
7
|
+
use Timeout , 10
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
use DefaultSite , 'https://api.github.com/'
|
10
|
+
use DefaultHeaders, {'Accept' => 'application/json'}
|
11
|
+
use Oauth2Query , nil
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
env.merge(s::RESPONSE_BODY =>
|
21
|
-
RuntimeError.new(env[s::RESPONSE_BODY]['message']))
|
22
|
-
end
|
23
|
-
else
|
24
|
-
raise env[s::RESPONSE_BODY]['message']
|
25
|
-
end}
|
26
|
-
use s::ErrorDetectorHttp
|
27
|
-
use s::JsonDecode , true
|
13
|
+
use CommonLogger , nil
|
14
|
+
use Cache , nil, 600 do
|
15
|
+
use ErrorHandler, lambda{ |env|
|
16
|
+
RuntimeError.new(env[RESPONSE_BODY]['message'])}
|
17
|
+
use ErrorDetectorHttp
|
18
|
+
use JsonResponse, true
|
19
|
+
end
|
28
20
|
end
|
29
21
|
end
|
30
22
|
|
@@ -2,33 +2,25 @@
|
|
2
2
|
require 'rest-core'
|
3
3
|
|
4
4
|
# http://developer.linkedin.com/documents/linkedin-api-resource-map
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
env.merge(s::RESPONSE_BODY =>
|
25
|
-
RuntimeError.new(env[s::RESPONSE_BODY]['message']))
|
26
|
-
end
|
27
|
-
else
|
28
|
-
raise env[s::RESPONSE_BODY]['message']
|
29
|
-
end}
|
30
|
-
use s::ErrorDetectorHttp
|
31
|
-
use s::JsonDecode , true
|
5
|
+
module RestCore
|
6
|
+
Linkedin = Builder.client do
|
7
|
+
use Timeout , 10
|
8
|
+
|
9
|
+
use DefaultSite , 'https://api.linkedin.com/'
|
10
|
+
use DefaultHeaders, {'Accept' => 'application/json'}
|
11
|
+
use DefaultQuery , {'format' => 'json'}
|
12
|
+
|
13
|
+
use Oauth1Header ,
|
14
|
+
'uas/oauth/requestToken', 'uas/oauth/accessToken',
|
15
|
+
'https://www.linkedin.com/uas/oauth/authorize'
|
16
|
+
|
17
|
+
use CommonLogger , nil
|
18
|
+
use Cache , nil, 600 do
|
19
|
+
use ErrorHandler, lambda{ |env|
|
20
|
+
RuntimeError.new(env[RESPONSE_BODY]['message'])}
|
21
|
+
use ErrorDetectorHttp
|
22
|
+
use JsonResponse, true
|
23
|
+
end
|
32
24
|
end
|
33
25
|
end
|
34
26
|
|
@@ -2,30 +2,22 @@
|
|
2
2
|
require 'rest-core'
|
3
3
|
|
4
4
|
# https://dev.twitter.com/docs
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
module RestCore
|
6
|
+
Twitter = Builder.client do
|
7
|
+
use Timeout , 10
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
use DefaultSite , 'https://api.twitter.com/'
|
10
|
+
use DefaultHeaders, {'Accept' => 'application/json'}
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
use Oauth1Header ,
|
13
|
+
'oauth/request_token', 'oauth/access_token', 'oauth/authorize'
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
else
|
22
|
-
env.merge(s::RESPONSE_BODY => ::RestCore::Twitter::Error.call(env))
|
23
|
-
end
|
24
|
-
else
|
25
|
-
raise ::RestCore::Twitter::Error.call(env)
|
26
|
-
end}
|
27
|
-
use s::ErrorDetectorHttp
|
28
|
-
use s::JsonDecode , true
|
15
|
+
use CommonLogger , nil
|
16
|
+
use Cache , nil, 600 do
|
17
|
+
use ErrorHandler, lambda{ |env| Twitter::Error.call(env) }
|
18
|
+
use ErrorDetectorHttp
|
19
|
+
use JsonResponse, true
|
20
|
+
end
|
29
21
|
end
|
30
22
|
end
|
31
23
|
|