rest-more 0.8.0 → 1.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.
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.