rest-more 0.8.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/.travis.yml +4 -2
  2. data/CHANGES.md +54 -34
  3. data/Gemfile +3 -1
  4. data/README.md +187 -14
  5. data/Rakefile +1 -1
  6. data/TODO.md +2 -12
  7. data/doc/ToC.md +9 -0
  8. data/doc/dependency.md +4 -0
  9. data/doc/design.md +4 -0
  10. data/doc/rest-graph.md +4 -0
  11. data/doc/tutorial/facebook.md +173 -0
  12. data/example/async.rb +89 -0
  13. data/example/facebook.rb +13 -0
  14. data/example/multi.rb +28 -0
  15. data/example/rails3/Gemfile +1 -1
  16. data/example/rainbows.rb +40 -0
  17. data/example/simple.rb +8 -0
  18. data/lib/rest-core/client/bing.rb +15 -7
  19. data/lib/rest-core/client/dropbox.rb +104 -0
  20. data/lib/rest-core/client/facebook.rb +59 -15
  21. data/lib/rest-core/client/flurry.rb +11 -1
  22. data/lib/rest-core/client/github.rb +11 -1
  23. data/lib/rest-core/client/linkedin.rb +10 -6
  24. data/lib/rest-core/client/twitter.rb +18 -9
  25. data/lib/rest-core/util/config.rb +15 -9
  26. data/lib/rest-more.rb +1 -0
  27. data/lib/rest-more/version.rb +1 -1
  28. data/rest-more.gemspec +54 -41
  29. data/test/{client/bing → bing}/test_api.rb +0 -0
  30. data/test/dropbox/test_api.rb +37 -0
  31. data/test/{client/facebook → facebook}/config/rest-core.yaml +0 -0
  32. data/test/{client/facebook → facebook}/test_api.rb +0 -0
  33. data/test/{client/facebook → facebook}/test_cache.rb +0 -0
  34. data/test/{client/facebook → facebook}/test_default.rb +0 -0
  35. data/test/{client/facebook → facebook}/test_error.rb +0 -0
  36. data/test/{client/facebook → facebook}/test_handler.rb +0 -0
  37. data/test/{client/facebook → facebook}/test_load_config.rb +0 -0
  38. data/test/{client/facebook → facebook}/test_misc.rb +0 -0
  39. data/test/{client/facebook → facebook}/test_oauth.rb +0 -0
  40. data/test/{client/facebook → facebook}/test_old.rb +0 -0
  41. data/test/{client/facebook → facebook}/test_page.rb +16 -29
  42. data/test/{client/facebook → facebook}/test_parse.rb +2 -2
  43. data/test/{client/facebook → facebook}/test_serialize.rb +0 -0
  44. data/test/{client/facebook → facebook}/test_timeout.rb +0 -0
  45. data/test/{client/flurry → flurry}/test_metrics.rb +0 -0
  46. data/test/{client/mixi → mixi}/test_api.rb +0 -0
  47. data/test/{client/twitter → twitter}/test_api.rb +4 -3
  48. metadata +60 -41
@@ -1,4 +1,5 @@
1
- script: 'git submodule update --init; bundle exec rake test:travis'
1
+ before_install: 'git submodule update --init'
2
+ script: 'bundle exec rake test:travis'
2
3
 
3
4
  env:
4
5
  - 'RESTMORE=rest-more'
@@ -11,4 +12,5 @@ rvm:
11
12
  - 1.9.3
12
13
  - rbx-18mode
13
14
  - rbx-19mode
14
- - jruby
15
+ - jruby-18mode
16
+ - jruby-19mode
data/CHANGES.md CHANGED
@@ -1,32 +1,52 @@
1
1
  # CHANGES
2
2
 
3
+ ## rest-more 1.0.0 -- 2012-03-17
4
+
5
+ ### Enhancement
6
+
7
+ All clients are now asynchrony-aware. Asynchrony support is added in
8
+ rest-core >=1.0.0. Whenever you pass a callback block, the response
9
+ would then be passed to the block. Error handling is different, too.
10
+ In synchronous style, usually an exception would be raised, but in
11
+ asynchronous style, the exception would be passed to the block instead
12
+ of being raised.
13
+
14
+ * [`Dropbox`] Added Dropbox support.
15
+ * [`Bing::Error`] Added `code` method to get the original error code.
16
+ * [`Twitter::Error`] Added `code` method to get HTTP status code.
17
+ * [`Facebook::Error`] Instead of passing `[true]`, pass error messages.
18
+ * [`Facebook`] Pages related API is reimplemented. Passing a block would
19
+ result a serious call to the callback block, ending with a nil.
20
+ * [`Config`] Make sure the default attributes module is there even if
21
+ the config file isn't presented.
22
+
3
23
  ## rest-more 0.8.0 -- 2011-11-29
4
24
 
5
25
  ### Incompatible changes
6
26
 
7
- * [Facebook::RailsUtil] Some methods are renamed. For example,
27
+ * [`Facebook::RailsUtil`] Some methods are renamed. For example,
8
28
  `rc_facebook_write_rg_fbs` is renamed to `rc_facebook_write_fbs`.
9
29
  All renamed methods are considered private, so we're not listing them here.
10
30
 
11
- * [Facebook::RailsUtil] `rc_facebook_storage_key` is changed to:
31
+ * [`Facebook::RailsUtil`] `rc_facebook_storage_key` is changed to:
12
32
  `"rc_facebook_#{rc_facebook.app_id}"`, your users might need to
13
33
  login again in order to save the access_token into the new place.
14
34
 
15
35
  ### Bugs fixes
16
36
 
17
- * [Github] Fixed usage of Oauth2Query.
37
+ * [`Github`] Fixed usage of `Oauth2Query`.
18
38
 
19
- * [Facebook] Now we're using POST in `authorize!` to exchange the
39
+ * [`Facebook`] Now we're using POST in `authorize!` to exchange the
20
40
  access_token with the code instead of GET. If we're using GET,
21
41
  we would run into a risk where a user might use the code to
22
42
  get other people's access_token via the cache. Using POST would
23
43
  prevent this because POSTs are not cached.
24
44
 
25
- * [Facebook::RailsUtil] Fixed a serious bug. The bug would jump up if
45
+ * [`Facebook::RailsUtil`] Fixed a serious bug. The bug would jump up if
26
46
  you're using :write_session or :write_cookies or :write_handler along
27
47
  with :auto_authorize, for example:
28
48
  `rc_facebook_setup(:auto_authorize => true, :write_session => true)`
29
- The problem is that Facebook::RailsUtil is not removing the invalid
49
+ The problem is that `Facebook::RailsUtil` is not removing the invalid
30
50
  access_token stored in session or cookie, and yet it is considered
31
51
  authorized, making redirecting to Facebook and redirecting back doesn't
32
52
  update the access_token. `rc_facebook_cleanup` is introduced to remove
@@ -35,72 +55,72 @@
35
55
 
36
56
  ### Enhancement
37
57
 
38
- * [Facebook] Now we use `default_data` to get the default data,
58
+ * [`Facebook`] Now we use `default_data` to get the default data,
39
59
  instead of relying `Defaults` middleware.
40
60
 
41
- * [Facebook] Protected methods are changed to private.
61
+ * [`Facebook`] Protected methods are changed to private.
42
62
 
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`
63
+ * [`Flurry`] `app_info` now accepts opts.
64
+ * [`Flurry`] `event_metrics` is renamed to `event_summary`
65
+ * [`Flurry`] `event_metrics` is now the API for accessing 'eventMetrics/Event'
66
+ * [`Flurry`] If you didn't pass dates, now default to for 7 days.
67
+ * [`Flurry`] Instead of overriding `query`, defining `default_query`
48
68
 
49
- * [Linkedin+Twitter] Removed `Defaults` middleware because now we're using
69
+ * [`Linkedin`+`Twitter`] Removed `Defaults` middleware because now we're using
50
70
  the data from `Oauth1Client` instead.
51
71
 
52
- * [Linkedin+Twitter] Removed `oauth_token`, `oauth_token=`,
72
+ * [`Linkedin`+`Twitter`] Removed `oauth_token`, `oauth_token=`,
53
73
  `oauth_token_secret`, and `oauth_token_secret=` because we're using them
54
74
  from `Oauth1Client` instead.
55
75
 
56
- * [Linkedin+Twitter] Removed `set_token` because it's handled in
76
+ * [`Linkedin`+`Twitter`] Removed `set_token` because it's handled in
57
77
  `Oauth1Client` now.
58
78
 
59
- * [Twitter::RailsUtil] Now `rc_twitter_setup` accepts options like
79
+ * [`Twitter::RailsUtil`] Now `rc_twitter_setup` accepts options like
60
80
  `rc_facebook_setup`: `auto_authorize`, `ensure_authorized`,
61
81
  `write_session`, `write_cookies`, `write_handler`, and `check_handler`.
62
82
 
63
- * [Mixi] Removed `Defaults` middleware in favor of `default_data`.
83
+ * [`Mixi`] Removed `Defaults` middleware in favor of `default_data`.
64
84
 
65
- * [Facebook+Github+Mixi+Twitter] Added a `me` method for accessing current
66
- user information.
85
+ * [`Facebook`+`Github`+`Mixi`+`Twitter`] Added a `me` method for accessing
86
+ current user information.
67
87
 
68
88
  ## rest-more 0.7.2.1 -- 2011-11-05
69
89
 
70
90
  ### Bugs fixes
71
91
 
72
- * [Facebook::RailsUtil] Fixed a missed change which should be made.
92
+ * [`Facebook::RailsUtil`] Fixed a missed change which should be made.
73
93
 
74
94
  ## rest-more 0.7.2 -- 2011-11-05
75
95
 
76
96
  ### Incompatible changes
77
97
 
78
- * [Flurry] renamed `api_key` to `apiKey` to better match the original name
98
+ * [`Flurry`] renamed `api_key` to `apiKey` to better match the original name
79
99
  from flurry. Also renamed `access_code` to `apiAccessCode`.
80
- * [Facebook::RailsUtil] Some `module_function`s are changed to controller's
100
+ * [`Facebook::RailsUtil`] Some `module_function`s are changed to controller's
81
101
  private methods. You aren't using it if you don't know what does this mean.
82
102
 
83
103
  ### Enhancement
84
104
 
85
105
  * Added `rib-rest-core` command line tool, extracted from rest-core.
86
- * [RailsUtilUtil] Introduced this to ease the pain writing RailsUtil for
106
+ * [`RailsUtilUtil`] Introduced this to ease the pain writing RailsUtil for
87
107
  various clients.
88
- * [Bing] Added Bing client and its RailsUtil.
89
- * [Github] Added RailsUtil for Github client.
90
- * [Linkedin] Added RailsUtil for Linkedin client.
91
- * [Mixi] Added RailsUtil for Mixi client.
92
- * [Twitter] Added RailsUtil for Twitter client.
108
+ * [`Bing`] Added `Bing` client and its RailsUtil.
109
+ * [`Github`] Added RailsUtil for Github client.
110
+ * [`Linkedin`] Added RailsUtil for Linkedin client.
111
+ * [`Mixi`] Added RailsUtil for Mixi client.
112
+ * [`Twitter`] Added RailsUtil for Twitter client.
93
113
 
94
114
  ## rest-more 0.7.1 -- 2011-10-31
95
115
 
96
116
  ### Bugs fixes
97
117
 
98
- * [Mixi] Fixed `RC::Mixi.new(:access_token => 'access_token')` which is not
118
+ * [`Mixi`] Fixed `RC::Mixi.new(:access_token => 'access_token')` which is not
99
119
  working before.
100
120
 
101
121
  ### Enhancement
102
122
 
103
- * [Mixi] `RC::Mixi#authorize!` now works like `RC::Facebook#authorize!`
123
+ * [`Mixi`] `RC::Mixi#authorize!` now works like `RC::Facebook#authorize!`
104
124
  That is now we pass code like this: `mixi.authorize!(:code => code)`
105
125
 
106
126
  * `RestCore::Config` and `RestCore::RailsUtilUtil` are now moved to rest-more
@@ -108,10 +128,10 @@
108
128
  ## rest-more 0.7.0 -- 2011-10-08
109
129
 
110
130
  * Extracted from [rest-core][] 0.4.0
111
- * [Facebook] Added `RC::Facebook#parse_fbsr!` which can parse Facebook's new
131
+ * [`Facebook`] Added `RC::Facebook#parse_fbsr!` which can parse Facebook's new
112
132
  cookie. Also, `RC::Facebook#parse_cookies!` would look for that too.
113
- * [Facebook] Fixed that parsing an invalid signed_request would raise an
133
+ * [`Facebook`] Fixed that parsing an invalid signed_request would raise an
114
134
  error. From now on it would simply ignore it and wipe out the data.
115
- * [Flurry] Some minor updates.
135
+ * [`Flurry`] Some minor updates.
116
136
 
117
137
  [rest-core]: https://github.com/cardinalblue/rest-core
data/Gemfile CHANGED
@@ -5,6 +5,7 @@ source 'http://rubygems.org'
5
5
  gem 'rest-core', :path => 'rest-core' if
6
6
  File.exist?("#{File.dirname(File.expand_path(__FILE__))}/rest-core/Gemfile")
7
7
  gem 'rest-client'
8
+ gem 'em-http-request'
8
9
  gem 'rest-more', :path => '.'
9
10
 
10
11
  gem 'rake'
@@ -20,6 +21,7 @@ gem 'ruby-hmac'
20
21
 
21
22
  platforms(:ruby) do
22
23
  gem 'yajl-ruby'
24
+ gem 'cool.io-http'
23
25
  end
24
26
 
25
27
  platforms(:jruby) do
@@ -27,4 +29,4 @@ platforms(:jruby) do
27
29
  end
28
30
 
29
31
  gem 'rails', '2.3.14' if ENV['RESTMORE'] == 'rails2'
30
- gem 'rails', '3.0.9' if ENV['RESTMORE'] == 'rails3'
32
+ gem 'rails', '3.2.1' if ENV['RESTMORE'] == 'rails3'
data/README.md CHANGED
@@ -1,7 +1,16 @@
1
- # rest-more [![Build Status](http://travis-ci.org/godfat/rest-more.png)](http://travis-ci.org/godfat/rest-more)
1
+ # rest-more [![Build Status](https://secure.travis-ci.org/godfat/rest-more.png?branch=master)](http://travis-ci.org/godfat/rest-more)
2
2
 
3
3
  by Cardinal Blue <http://cardinalblue.com>
4
4
 
5
+ Lin Jen-Shin ([godfat][]) had given a talk about rest-core on
6
+ [RubyConf Taiwan 2011][talk]. The slide is in English, but the
7
+ talk is in Mandarin.
8
+
9
+ You can also read some other topics at [doc](https://github.com/cardinalblue/rest-core/blob/master/doc/ToC.md).
10
+
11
+ [godfat]: https://github.com/godfat
12
+ [talk]: http://rubyconf.tw/2011/#6
13
+
5
14
  ## LINKS:
6
15
 
7
16
  * [github](https://github.com/cardinalblue/rest-more)
@@ -15,22 +24,56 @@ Various REST clients such as Facebook and Twitter built with [rest-core][]
15
24
 
16
25
  [rest-core]: https://github.com/cardinalblue/rest-core
17
26
 
27
+ ## FEATURES:
28
+
29
+ Out-of-box REST clients built with rest-core for:
30
+
31
+ * Bing
32
+ * Dropbox
33
+ * Facebook
34
+ * Flurry
35
+ * Github
36
+ * Linkedin
37
+ * Mixi
38
+ * Twitter
39
+
40
+ Rails utilities are also included.
41
+
18
42
  ## REQUIREMENTS:
19
43
 
20
- * Tested with MRI (official CRuby) 1.8.7, 1.9.2, 1.9.3, Rubinius and JRuby
21
- * gem install rest-core
44
+ ### Mandatory:
45
+
46
+ * MRI (official CRuby) 1.8.7, 1.9.2, 1.9.3, Rubinius 1.8/1.9 and JRuby 1.8/1.9
47
+ * gem rest-client
48
+
49
+ ### Optional:
50
+
51
+ * Fibers only work on Ruby 1.9+
52
+ * gem [em-http-request][] (if using eventmachine)
53
+ * gem [cool.io-http][] (if using cool.io)
54
+ * gem json or yajl-ruby (if using `JsonDecode` middleware)
55
+
56
+ [em-http-request]: https://github.com/igrigorik/em-http-request
57
+ [cool.io-http]: https://github.com/godfat/cool.io-http
22
58
 
23
59
  ## INSTALLATION:
24
60
 
61
+ ``` shell
25
62
  gem install rest-more
63
+ ```
26
64
 
27
65
  Or if you want development version, put this in Gemfile:
28
66
 
67
+ ``` ruby
29
68
  gem 'rest-more', :git => 'git://github.com/cardinalblue/rest-more.git',
30
69
  :submodules => true
70
+ ```
31
71
 
32
72
  ## SYNOPSIS:
33
73
 
74
+ The simplest usage:
75
+
76
+ ``` ruby
34
77
  require 'rest-more'
35
78
 
36
79
  RestCore::Twitter.new.statuses('_cardinalblue') # get user tweets
@@ -43,20 +86,136 @@ Or if you want development version, put this in Gemfile:
43
86
  linkedin.me # get current user info
44
87
 
45
88
  RestCore::Facebook.new.get('4') # get user info
89
+ ```
46
90
 
47
- See [example][] for more complex examples.
91
+ Runnable example is here: [example/simple.rb][]. Please see [slides][] from
92
+ [rubyconf.tw/2011][rubyconf.tw] for concepts.
48
93
 
49
- [example]: https://github.com/cardinalblue/rest-more/tree/master/example
94
+ [example/simple.rb]: https://github.com/cardinalblue/rest-more/blob/master/example/simple.rb
95
+ [slides]: http://www.godfat.org/slide/2011-08-27-rest-core.html
96
+ [rubyconf.tw]: http://rubyconf.tw/2011/#6
50
97
 
51
- ## List of supported clients:
98
+ ## Asynchronous HTTP Requests:
52
99
 
53
- * Bing
54
- * Facebook
55
- * Flurry
56
- * Github
57
- * Linkedin
58
- * Mixi
59
- * Twitter
100
+ I/O bound operations shouldn't be blocking the CPU! If you have a reactor,
101
+ i.e. event loop, you should take the advantage of that to make HTTP requests
102
+ not block the whole process/thread. For now, we support eventmachine and
103
+ cool.io. By default, all clients are using `RestClient`, which is a
104
+ synchronous HTTP client, thus blocking. It's very easy to use, but not
105
+ very scalable (not concurrent-efficient). You can change the default app
106
+ (i.e. HTTP clients) to an asynchronous one:
107
+
108
+ ``` ruby
109
+ require 'rest-more'
110
+ RestCore::Builder.default_app = RestCore::EmHttpRequest
111
+ ```
112
+
113
+ or an auto-picking one, which would try to infer the correct HTTP client
114
+ depending on the context. Either em-http-request, cool.io-http, or even
115
+ rest-client if none of reactors is available.
116
+
117
+ ``` ruby
118
+ require 'rest-more'
119
+ RestCore::Builder.default_app = RestCore::Auto
120
+ ```
121
+
122
+ You can also setup the `default_app` for a specific client, so that it won't
123
+ change all the `default_app` for all the clients, like this:
124
+
125
+ ``` ruby
126
+ require 'rest-more'
127
+ RestCore::Facebook.builder.default_app = RestCore::Auto
128
+ ```
129
+
130
+ If you're passing a block, the block is called after the response is
131
+ available. That is the block is the callback for the request.
132
+
133
+ ``` ruby
134
+ require 'rest-more'
135
+ require 'eventmachine'
136
+ RestCore::Builder.default_app = RestCore::EmHttpRequest
137
+ EM.run{
138
+ RestCore::Facebook.new.get('4'){ |response|
139
+ p response
140
+ EM.stop
141
+ }
142
+ puts "It's not blocking..."
143
+ }
144
+ ```
145
+
146
+ Otherwise, if you don't pass a block as the callback, EmHttpRequest (i.e.
147
+ the HTTP client for eventmachine) would call `Fiber.yield` to yield to the
148
+ original fiber, making asynchronous HTTP requests look like synchronous.
149
+ If you don't understand what does this mean, you can take a look at
150
+ [em-synchrony][]. It's basically the same idea.
151
+
152
+ ``` ruby
153
+ require 'rest-more'
154
+ require 'eventmachine'
155
+
156
+ RestCore::Builder.default_app = RestCore::EmHttpRequest
157
+
158
+ EM.run{
159
+ Fiber.new{
160
+ p RestCore::Facebook.new.get('4')
161
+ EM.stop
162
+ }.resume
163
+ puts "It's not blocking..."
164
+ }
165
+ ```
166
+
167
+ [em-synchrony]: https://github.com/igrigorik/em-synchrony
168
+
169
+ Runnable example is here: [example/facebook.rb][].
170
+ You can also make multi-requests synchronously like this:
171
+
172
+ ``` ruby
173
+ require 'rest-more'
174
+ require 'eventmachine'
175
+
176
+ RestCore::Builder.default_app = RestCore::Auto
177
+ facebook = RestCore::Facebook.new(:log_method => method(:puts))
178
+
179
+ EM.run{
180
+ Fiber.new{
181
+ fiber = Fiber.current
182
+ result = {}
183
+ facebook.get('4'){ |response|
184
+ result[0] = response
185
+ fiber.resume(result) if result.size == 2
186
+ }
187
+ puts "It's not blocking..."
188
+ facebook.get('4'){ |response|
189
+ result[1] = response
190
+ fiber.resume(result) if result.size == 2
191
+ }
192
+ p Fiber.yield
193
+ EM.stop
194
+ }.resume
195
+ puts "It's not blocking..."
196
+ }
197
+ ```
198
+
199
+ Runnable example is here: [example/multi.rb][]. All `RestCore::EmHttpRequest`
200
+ above is interchangeable with `RestCore::Auto` because `RestCore::Auto` would
201
+ pick the right HTTP client when running inside the eventmachine's event loop.
202
+
203
+ [example/facebook.rb]: https://github.com/cardinalblue/rest-more/blob/master/example/facebook.rb
204
+ [example/multi.rb]: https://github.com/cardinalblue/rest-more/blob/master/example/multi.rb
205
+
206
+ ## Supported HTTP clients:
207
+
208
+ * `RestCore::RestClient` (gem rest-client)
209
+ * `RestCore::EmHttpRequest` (gem em-http-request)
210
+ * `RestCore::Coolio` (gem cool.io)
211
+ * `RestCore::Auto` (which would pick one of the above depending on the
212
+ context)
213
+
214
+ ## Rails Utilities
215
+
216
+ To be added. But you can take a look at the [Facebook tutorial][] first.
217
+
218
+ [Facebook tutorial]: https://github.com/cardinalblue/rest-more/blob/master/doc/tutorial/facebook.md
60
219
 
61
220
  ## A simple interactive shell with [rib][]:
62
221
 
@@ -79,11 +238,25 @@ Which is using `RestCore::Universal` for accessing arbitrary websites.
79
238
  * [s2sync](https://github.com/brucehsu/s2sync)
80
239
  * [s2sync_web](https://github.com/brucehsu/s2sync_web)
81
240
 
241
+ ## Powered sites:
242
+
243
+ * [PicCollage](http://pic-collage.com/)
244
+
245
+ ## CHANGES:
246
+
247
+ * [CHANGES](https://github.com/cardinalblue/rest-more/blob/master/CHANGES.md)
248
+
249
+ ## CONTRIBUTORS:
250
+
251
+ * ayaya (@ayamomiji)
252
+ * Lin Jen-Shin (@godfat)
253
+ * Yun-Yan Chi (@jaiyalas)
254
+
82
255
  ## LICENSE:
83
256
 
84
257
  Apache License 2.0
85
258
 
86
- Copyright (c) 2011, Cardinal Blue
259
+ Copyright (c) 2011-2012, Cardinal Blue
87
260
 
88
261
  Licensed under the Apache License, Version 2.0 (the "License");
89
262
  you may not use this file except in compliance with the License.