rest-graph 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. data/.gitignore +6 -0
  2. data/CHANGES +44 -0
  3. data/CONTRIBUTORS +1 -0
  4. data/README +221 -191
  5. data/README.md +367 -0
  6. data/Rakefile +28 -43
  7. data/TODO +1 -0
  8. data/doc/ToC.md +10 -0
  9. data/doc/dependency.md +78 -0
  10. data/doc/design.md +206 -0
  11. data/doc/rails.md +12 -0
  12. data/doc/test.md +46 -0
  13. data/doc/tutorial.md +142 -0
  14. data/example/rails2/Gemfile +13 -0
  15. data/example/rails2/app/controllers/application_controller.rb +10 -8
  16. data/example/rails2/app/views/application/helper.html.erb +1 -0
  17. data/example/rails2/config/boot.rb +16 -0
  18. data/example/rails2/config/environment.rb +3 -30
  19. data/example/rails2/config/preinitializer.rb +23 -0
  20. data/example/rails2/test/functional/application_controller_test.rb +72 -32
  21. data/example/rails2/test/test_helper.rb +10 -6
  22. data/example/rails3/Gemfile +13 -0
  23. data/example/rails3/Rakefile +7 -0
  24. data/example/rails3/app/controllers/application_controller.rb +118 -0
  25. data/example/rails3/app/views/application/helper.html.erb +1 -0
  26. data/example/rails3/config.ru +4 -0
  27. data/example/rails3/config/application.rb +23 -0
  28. data/example/rails3/config/environment.rb +5 -0
  29. data/example/rails3/config/environments/development.rb +26 -0
  30. data/example/rails3/config/environments/production.rb +49 -0
  31. data/example/rails3/config/environments/test.rb +30 -0
  32. data/example/rails3/config/initializers/secret_token.rb +7 -0
  33. data/example/rails3/config/initializers/session_store.rb +8 -0
  34. data/example/rails3/config/rest-graph.yaml +11 -0
  35. data/example/rails3/config/routes.rb +5 -0
  36. data/example/rails3/test/functional/application_controller_test.rb +183 -0
  37. data/example/rails3/test/test_helper.rb +18 -0
  38. data/example/rails3/test/unit/rails_util_test.rb +44 -0
  39. data/init.rb +1 -1
  40. data/lib/rest-graph.rb +5 -571
  41. data/lib/rest-graph/auto_load.rb +3 -3
  42. data/lib/rest-graph/autoload.rb +3 -3
  43. data/lib/rest-graph/config_util.rb +43 -0
  44. data/lib/rest-graph/core.rb +608 -0
  45. data/lib/rest-graph/facebook_util.rb +74 -0
  46. data/lib/rest-graph/rails_util.rb +85 -37
  47. data/lib/rest-graph/test_util.rb +18 -2
  48. data/lib/rest-graph/version.rb +2 -2
  49. data/rest-graph.gemspec +42 -47
  50. data/task/gemgem.rb +155 -0
  51. data/test/test_api.rb +16 -0
  52. data/test/test_cache.rb +28 -8
  53. data/test/test_error.rb +9 -0
  54. data/test/test_facebook.rb +36 -0
  55. data/test/test_load_config.rb +16 -14
  56. data/test/test_misc.rb +4 -4
  57. data/test/test_parse.rb +10 -4
  58. metadata +146 -186
  59. data/Gemfile.lock +0 -45
  60. data/README.rdoc +0 -337
  61. data/example/rails2/script/console +0 -3
  62. data/example/rails2/script/server +0 -3
  63. data/lib/rest-graph/load_config.rb +0 -41
data/README.md ADDED
@@ -0,0 +1,367 @@
1
+ # rest-graph
2
+ by Cardinal Blue <http://cardinalblue.com>
3
+
4
+ Tutorial on setting up a sample Facebook application with Rails 3
5
+ and RestGraph could be found on [samplergthree][]. Instead, if you're
6
+ an experienced Ruby programmer, you might also want to look at
7
+ [detailed documents][].
8
+
9
+ [samplergthree]: https://github.com/cardinalblue/samplergthree
10
+ [detailed documents]: https://github.com/cardinalblue/rest-graph/blob/master/doc/ToC.md
11
+
12
+ ## LINKS:
13
+
14
+ * [github](http://github.com/cardinalblue/rest-graph)
15
+ * [rubygems](http://rubygems.org/gems/rest-graph)
16
+ * [rdoc](http://rdoc.info/projects/cardinalblue/rest-graph)
17
+ * [mailing list](http://groups.google.com/group/rest-graph/topics)
18
+
19
+ ## DESCRIPTION:
20
+
21
+ A lightweight Facebook Graph API client
22
+
23
+ ## FEATURES:
24
+
25
+ * Simple Graph API call
26
+ * Simple FQL call
27
+ * Utility to extract access_token and check sig in cookies/signed_request
28
+
29
+ ## REQUIREMENTS:
30
+
31
+ * Tested with MRI 1.8.7 and 1.9.2 and Rubinius 1.2.2.
32
+ Because of development gems can't work well on JRuby,
33
+ let me know if rest-graph is working on JRuby, thanks!
34
+
35
+ * (must) pick one HTTP client:
36
+ - gem install rest-client
37
+ - gem install em-http-request
38
+
39
+ * (optional) pick one JSON parser/generator:
40
+ - gem install yajl-ruby
41
+ - gem install json
42
+ - gem install json_pure
43
+
44
+ * (optional) parse access_token in HTTP_COOKIE
45
+ - gem install rack
46
+
47
+ * (optional) to use rest-graph/test_util
48
+ - gem install rr
49
+
50
+ ## INSTALLATION:
51
+
52
+ gem install rest-graph
53
+
54
+ Or if you want development version, put this in Gemfile:
55
+
56
+ gem 'rest-graph', :git => 'git://github.com/cardinalblue/rest-graph.git
57
+
58
+ Or as a Rails2 plugin:
59
+
60
+ ./script/plugin install git://github.com/cardinalblue/rest-graph.git
61
+
62
+ ## QUICK START:
63
+
64
+ require 'rest-graph'
65
+ rg = RestGraph.new(:access_token => 'myaccesstokenfromfb')
66
+ rg.get('me')
67
+ rg.get('me/likes')
68
+ rg.get('search', :q => 'taiwan')
69
+
70
+ ### Obtaining an access token
71
+
72
+ If you are using Rails, we recommend that you include a module called
73
+ RestGraph::RailsUtil into your controllers. (Your code contributions
74
+ for other Ruby frameworks would be appreciated!). RestGraph::RailsUtil
75
+ adds the following two methods to your controllers:
76
+
77
+ rest_graph_setup: Attempts to find an access_token from the environment
78
+ and initializes a RestGraph object with it.
79
+ Most commonly used inside a filter.
80
+
81
+ rest_graph: Accesses the RestGraph object by rest_graph_setup.
82
+
83
+ ### Example usage:
84
+
85
+ class MyController < ActionController::Base
86
+ include RestGraph::RailsUtil
87
+ before_filter :setup
88
+
89
+ def myaction
90
+ @medata = rest_graph.get('me')
91
+ end
92
+
93
+ private
94
+ def setup
95
+ rest_graph_setup(:app_id => '123',
96
+ :canvas => 'mycanvas',
97
+ :auto_authorize_scope => 'email')
98
+ # See below for more options
99
+ end
100
+ end
101
+
102
+ ### Default setup
103
+
104
+ New RestGraph objects can read their default setup configuration from a
105
+ YAML configuration file. Which is the same as passing to rest_graph_setup.
106
+
107
+ * [Example](test/config/rest-graph.yaml)
108
+
109
+ To enable, just require anywhere:
110
+
111
+ require 'rest-graph'
112
+
113
+ Or if you're using bundler, add this line into Gemfile:
114
+
115
+ gem 'rest-graph'
116
+
117
+ ## SETUP OPTIONS:
118
+
119
+ Here are ALL the available options for new instance of RestGraph.
120
+
121
+ rg = RestGraph.new(
122
+ :access_token => TOKEN , # default nil
123
+ :graph_server => 'https://graph.facebook.com/', # this is default
124
+ :old_server => 'https://api.facebook.com/' , # this is default
125
+ :accept => 'text/javascript' , # this is default
126
+ :lang => 'en-us' , # affect search
127
+ :auto_decode => true , # decode by json
128
+ # default true
129
+ :app_id => '123' , # default nil
130
+ :secret => '1829' , # default nil
131
+
132
+ :cache => {} ,
133
+ # A cache for the same API call. Any object quacks like a hash
134
+ # should work, and Rails.cache works, too. (because of a patch in
135
+ # RailsUtil)
136
+
137
+ :error_handler => lambda{|hash| raise RestGraph::Error.new(hash)},
138
+ # This handler callback is only called if auto_decode is
139
+ # set to true, otherwise, it's ignored. And raising exception
140
+ # is the default unless you're using RailsUtil and enabled
141
+ # auto_authorize. That way, RailsUtil would do redirect
142
+ # instead of raising an exception.
143
+
144
+ :log_method => method(:puts),
145
+ # This way, any log message would be output by puts. If you want to
146
+ # change the log format, use log_handler instead. See below:
147
+
148
+ :log_handler => lambda{ |event|
149
+ Rails.logger.
150
+ debug("Spent #{event.duration} requesting #{event.url}")})
151
+ # You might not want to touch this if you're using RailsUtil.
152
+ # Otherwise, the default behavior is do nothing. (i.e. no logging)
153
+
154
+ And here are ALL the available options for rest_graph_setup. Note that all
155
+ options for RestGraph instance are also valid options for rest_graph_setup.
156
+
157
+ rest_graph_setup(#
158
+ # == All the above RestGraph options, plus
159
+ #
160
+ :canvas => 'mycanvas', # default ''
161
+ :auto_authorize => true , # default false
162
+ :auto_authorize_scope => 'email' , # default ''
163
+ :auto_authorize_options => {} , # default {}
164
+ # auto_authorize means it will do redirect to oauth
165
+ # API automatically if the access_token is invalid or
166
+ # missing. So you would like to setup scope if you're
167
+ # using it. Note that: setting scope implies setting
168
+ # auto_authorize to true, even it's false.
169
+
170
+ :ensure_authorized => false , # default false
171
+ # This means if the access_token is not there,
172
+ # then do auto_authorize.
173
+
174
+ :write_session => true , # default false
175
+ :write_cookies => false , # default false
176
+ :write_handler =>
177
+ lambda{ |fbs| @cache[uid] = fbs } , # default nil
178
+ :check_handler =>
179
+ lambda{ @cache[uid] }) # default nil
180
+ # If we're not using Facebook JavaScript SDK,
181
+ # then we'll need to find a way to store the fbs,
182
+ # which contains access_token and/or user id. In a
183
+ # standalone site or iframe canvas application, you might
184
+ # want to just use the Rails (or other framework) session
185
+
186
+ ### Alternate ways to setup RestGraph:
187
+
188
+ 1. Set upon RestGraph object creation:
189
+
190
+ rg = RestGraph.new :app_id => 1234
191
+
192
+ 2. Set via the rest_graph_setup call in a Controller:
193
+
194
+ rest_graph_setup :app_id => 1234
195
+
196
+ 3. Load from a YAML file
197
+
198
+ require 'rest-graph/config_util'
199
+ RestGraph.load_config('path/to/rest-graph.yaml', 'production')
200
+ rg = RestGraph.new
201
+
202
+ 4. Load config automatically
203
+
204
+ require 'rest-graph' # under Rails, would load config/rest-graph.yaml
205
+ rg = RestGraph.new
206
+
207
+ 5. Override directly
208
+
209
+ module MyDefaults
210
+ def default_app_id
211
+ '456'
212
+ end
213
+
214
+ def default_secret
215
+ 'category theory'
216
+ end
217
+ end
218
+ RestGraph.send(:extend, MyDefaults)
219
+ rg = RestGraph.new
220
+
221
+ ## API REFERENCE:
222
+
223
+ ### Facebook Graph API:
224
+
225
+ #### get
226
+ # GET https://graph.facebook.com/me?access_token=TOKEN
227
+ rg.get('me')
228
+
229
+ # GET https://graph.facebook.com/me?metadata=1&access_token=TOKEN
230
+ rg.get('me', :metadata => '1')
231
+
232
+ # extra options:
233
+ # auto_decode: Bool # decode with json or not in this method call
234
+ # # default: auto_decode in rest-graph instance
235
+ # secret: Bool # use secret_acccess_token or not
236
+ # # default: false
237
+ # cache: Bool # use cache or not; if it's false, update cache, too
238
+ # # default: true
239
+ # expires_in: Int # control when would the cache be expired
240
+ # # default: nothing
241
+ # async: Bool # use eventmachine for http client or not
242
+ # # default: false, but true in aget family
243
+ rg.get('me', {:metadata => '1'}, :secret => true, expires_in => 600)
244
+
245
+ #### post
246
+
247
+ rg.post('me/feed', :message => 'bread!')
248
+
249
+ #### fql
250
+
251
+ Make an arbitrary [FQL][] query
252
+
253
+ [FQL]: http://developers.facebook.com/docs/reference/fql/
254
+
255
+ rg.fql('SELECT name FROM page WHERE page_id="123"')
256
+
257
+ #### fql_multi
258
+
259
+ rg.fql_multi(:q1 => 'SELECT name FROM page WHERE page_id="123"',
260
+ :q2 => 'SELECT name FROM page WHERE page_id="456"')
261
+
262
+ #### old_rest
263
+
264
+ Call functionality from Facebook's old REST API:
265
+
266
+ rg.old_rest(
267
+ 'stream.publish',
268
+ { :message => 'Greetings',
269
+ :attachment => {:name => 'Wikipedia',
270
+ :href => 'http://wikipedia.org/',
271
+ :caption => 'Wikipedia says hi.',
272
+ :media => [{:type => 'image',
273
+ :src => 'http://wikipedia.org/logo.png',
274
+ :href => 'http://wikipedia.org/'}]
275
+ }.to_json,
276
+ :action_links => [{:text => 'Go to Wikipedia',
277
+ :href => 'http://wikipedia.org/'}
278
+ ].to_json
279
+ },
280
+ :auto_decode => false) # You'll need to set auto_decode to false for
281
+ # this API request if Facebook is not returning
282
+ # a proper formatted JSON response. Otherwise,
283
+ # this could be omitted.
284
+
285
+ # Some Old Rest API requires a special access token with app secret
286
+ # inside of it. For those methods, use secret_old_rest instead of the
287
+ # usual old_rest with common access token.
288
+ rg.secret_old_rest('admin.getAppProperties', :properties => 'app_id')
289
+
290
+ ### Utility Methods:
291
+
292
+ #### parse_???
293
+
294
+ All the methods that obtain an access_token will automatically save it.
295
+
296
+ If you have the session in the cookies,
297
+ then RestGraph can parse the cookies:
298
+
299
+ rg.parse_cookies!(cookies)
300
+
301
+ If you're writing a Rack application, you might want to parse
302
+ the session directly from Rack env:
303
+
304
+ rg.parse_rack_env!(env)
305
+
306
+ #### access_token
307
+
308
+ rg.access_token
309
+
310
+ Data associated with the access_token (which might or might not
311
+ available, depending on how the access_token was obtained).
312
+
313
+ rg.data
314
+ rg.data['uid']
315
+ rg.data['expires']
316
+
317
+ #### Default values
318
+
319
+ Read from the rest-graph.yaml file.
320
+
321
+ RestGraph.default_???
322
+
323
+ ### Other ways of getting an access token
324
+
325
+ #### authorize_url
326
+
327
+ Returns the redirect URL for authorizing
328
+
329
+ # https://graph.facebook.com/oauth/authorize?
330
+ # client_id=123&redirect_uri=http%3A%2F%2Fw3.org%2F
331
+ rg.authorize_url(:redirect_uri => 'http://w3.org/', :scope => 'email')
332
+
333
+ #### authorize!
334
+
335
+ Makes a call to Facebook to convert
336
+ the authorization "code" into an access token:
337
+
338
+ # https://graph.facebook.com/oauth/access_token?
339
+ # code=CODE&client_id=123&client_secret=1829&
340
+ # redirect_uri=http%3A%2F%2Fw3.org%2F
341
+ rg.authorize!(:redirect_uri => 'http://w3.org/', :code => 'CODE')
342
+
343
+ #### exchange_sessions
344
+
345
+ Takes a session key from the old REST API
346
+ (non-Graph API) and converts to an access token:
347
+
348
+ # https://graph.facebook.com/oauth/exchange_sessions?sessions=SESSION
349
+ rg.exchange_sessions(:sessions => params[:fb_sig_session_key])
350
+
351
+ ## LICENSE:
352
+
353
+ Apache License 2.0
354
+
355
+ Copyright (c) 2010, Cardinal Blue
356
+
357
+ Licensed under the Apache License, Version 2.0 (the "License");
358
+ you may not use this file except in compliance with the License.
359
+ You may obtain a copy of the License at
360
+
361
+ <http://www.apache.org/licenses/LICENSE-2.0>
362
+
363
+ Unless required by applicable law or agreed to in writing, software
364
+ distributed under the License is distributed on an "AS IS" BASIS,
365
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
366
+ See the License for the specific language governing permissions and
367
+ limitations under the License.
data/Rakefile CHANGED
@@ -1,57 +1,42 @@
1
1
  # encoding: utf-8
2
2
 
3
- begin
4
- require 'bones'
5
- rescue LoadError
6
- abort '### Please install the "bones" gem ###'
7
- end
8
-
9
- ensure_in_path 'lib'
10
- proj = 'rest-graph'
11
- require "#{proj}/version"
12
-
13
- Bones{
14
- ruby_opts [''] # silence warning for now
15
-
16
- version RestGraph::VERSION
17
-
18
- depend_on 'rest-client' , :development => true
19
- depend_on 'em-http-request', :development => true
3
+ require "#{dir = File.dirname(__FILE__)}/task/gemgem"
4
+ Gemgem.dir = dir
20
5
 
21
- depend_on 'rack' , :development => true
6
+ ($LOAD_PATH << File.expand_path("#{Gemgem.dir}/lib" )).uniq!
22
7
 
23
- depend_on 'yajl-ruby', :development => true
24
- depend_on 'json' , :development => true
25
- depend_on 'json_pure', :development => true
8
+ desc 'Generate gemspec'
9
+ task 'gem:spec' do
10
+ Gemgem.spec = Gemgem.create do |s|
11
+ require 'rest-graph/version'
12
+ s.name = 'rest-graph'
13
+ s.version = RestGraph::VERSION
14
+ # s.executables = [s.name]
26
15
 
27
- depend_on 'ruby-hmac', :development => true
16
+ %w[].each{ |g| s.add_runtime_dependency(g) }
17
+ %w[rest-client em-http-request rack yajl-ruby json json_pure ruby-hmac
18
+ webmock bacon rr].each{ |g| s.add_development_dependency(g) }
28
19
 
29
- depend_on 'rr' , :development => true
30
- depend_on 'webmock' , :development => true
31
- depend_on 'bacon' , :development => true
20
+ s.authors = ['Cardinal Blue', 'Lin Jen-Shin (godfat)']
21
+ s.email = ['dev (XD) cardinalblue.com']
22
+ end
32
23
 
33
- name proj
34
- url "http://github.com/cardinalblue/#{proj}"
35
- authors ['Cardinal Blue', 'Lin Jen-Shin (aka godfat 真常)']
36
- email 'dev (XD) cardinalblue.com'
37
-
38
- history_file 'CHANGES'
39
- readme_file 'README.rdoc'
40
- ignore_file '.gitignore'
41
- rdoc.include ['\w+']
42
- rdoc.exclude ['test', 'doc', 'Rakefile', 'example']
43
- }
44
-
45
- CLEAN.include Dir['**/*.rbc']
46
-
47
- task :default do
48
- Rake.application.options.show_task_pattern = /./
49
- Rake.application.display_tasks_and_comments
24
+ Gemgem.write
50
25
  end
51
26
 
52
27
  desc 'Run example tests'
53
28
  task 'test:example' => ['gem:install'] do
54
- sh "cd example/rails2; #{Gem.ruby} -S rake test"
29
+ %w[rails3 rails2].each{ |framework|
30
+ opts = Rake.application.options
31
+ args = (opts.singleton_methods - [:rakelib, 'rakelib']).map{ |arg|
32
+ if arg.to_s !~ /=$/ && opts.send(arg)
33
+ "--#{arg}"
34
+ else
35
+ ''
36
+ end
37
+ }.join(' ')
38
+ sh "cd example/#{framework}; #{Gem.ruby} -S rake test #{args}"
39
+ }
55
40
  end
56
41
 
57
42
  desc 'Run all tests'