rest-graph 1.2.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +22 -0
- data/README.rdoc +62 -39
- data/Rakefile +8 -0
- data/TODO +0 -1
- data/example/rails/app/controllers/application_controller.rb +63 -5
- data/example/rails/config/environment.rb +0 -1
- data/example/rails/config/rest-graph.yaml +10 -4
- data/example/rails/config/routes.rb +1 -1
- data/example/rails/log +0 -0
- data/example/rails/test/functional/application_controller_test.rb +114 -0
- data/example/rails/test/test_helper.rb +13 -0
- data/init.rb +0 -1
- data/lib/rest-graph/rails_util.rb +99 -49
- data/lib/rest-graph/version.rb +1 -1
- data/lib/rest-graph.rb +56 -50
- data/rest-graph.gemspec +8 -8
- data/test/{test_fql.rb → test_old.rb} +28 -0
- data/test/test_parse.rb +6 -5
- data/test/test_rest-graph.rb +16 -5
- metadata +14 -12
- data/example/rails/app/views/rest-graph/authorization.erb +0 -16
data/CHANGES
CHANGED
@@ -1,5 +1,27 @@
|
|
1
1
|
= rest-graph changes history
|
2
2
|
|
3
|
+
== rest-graph 1.3.0 -- 2010-06-11
|
4
|
+
* Now rest-graph is rescuing all exceptions from rest-client.
|
5
|
+
* Added RestGraph#exchange_sessions to exchange old sessions to access tokens.
|
6
|
+
|
7
|
+
* Added RestGraph#old_rest, see:
|
8
|
+
http://developers.facebook.com/docs/reference/rest/
|
9
|
+
|
10
|
+
* Now all API request accept an additional options argument,
|
11
|
+
you may pass :suppress_decode => true to turn off auto-decode this time.
|
12
|
+
e.g. rg.get('bad/json', {:query => 'string'}, :suppress_decode => true)
|
13
|
+
This is for Facebook who didn't always return JSON in response.
|
14
|
+
|
15
|
+
* Renamed fql_server to old_server.
|
16
|
+
* Favor yaji/json_gem first, then falls back to json, and json_pure.
|
17
|
+
* Fixed a bug that cookie format from Facebook varies. No idea why.
|
18
|
+
|
19
|
+
for RailsUtil:
|
20
|
+
|
21
|
+
* Big and fat refactoring in RailsUtil, see example for detail:
|
22
|
+
http://github.com/cardinalblue/rest-graph/tree/rest-graph-1.3.0/example
|
23
|
+
* url_for and link_to would auto pass :host option if it's inside canvas.
|
24
|
+
|
3
25
|
== rest-graph 1.2.1 -- 2010-06-02
|
4
26
|
* Deprecated RailsController, use RailsUtil instead.
|
5
27
|
* Fixed a bug that passing access_token in query string
|
data/README.rdoc
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= rest-graph 1.
|
1
|
+
= rest-graph 1.3.0
|
2
2
|
by Cardinal Blue ( http://cardinalblue.com )
|
3
3
|
|
4
4
|
== LINKS:
|
@@ -6,6 +6,7 @@ by Cardinal Blue ( http://cardinalblue.com )
|
|
6
6
|
* {github}[http://github.com/cardinalblue/rest-graph]
|
7
7
|
* {rubygems}[http://rubygems.org/gems/rest-graph]
|
8
8
|
* {rdoc}[http://rdoc.info/projects/cardinalblue/rest-graph]
|
9
|
+
* {mailing list}[http://groups.google.com/group/rest-graph/topics]
|
9
10
|
|
10
11
|
== DESCRIPTION:
|
11
12
|
|
@@ -25,21 +26,21 @@ by Cardinal Blue ( http://cardinalblue.com )
|
|
25
26
|
require 'rest-graph'
|
26
27
|
|
27
28
|
# Every option is optional.
|
28
|
-
rg = RestGraph.new(:access_token => '
|
29
|
+
rg = RestGraph.new(:access_token => 'tok',
|
29
30
|
:graph_server => 'https://graph.facebook.com/',
|
30
|
-
:
|
31
|
+
:old_server => 'https://api.facebook.com/',
|
31
32
|
:accept => 'text/javascript',
|
32
33
|
:lang => 'en-us', # this affect search
|
33
|
-
:auto_decode =>
|
34
|
-
:app_id => '123',
|
35
|
-
:secret => '1829',
|
34
|
+
:auto_decode => true , # decode by json
|
35
|
+
:app_id => '123' ,
|
36
|
+
:secret => '1829' ,
|
36
37
|
|
37
38
|
# This handler callback is only called if auto_decode is set to true,
|
38
39
|
# otherwise, it's ignored.
|
39
40
|
:error_handler =>
|
40
41
|
lambda{ |hash| raise ::RestGraph::Error.new(hash) },
|
41
42
|
|
42
|
-
# You
|
43
|
+
# You might want to do this in Rails to do debug logging:
|
43
44
|
:log_handler =>
|
44
45
|
lambda{ |duration, url|
|
45
46
|
Rails.logger.debug("RestGraph " \
|
@@ -47,34 +48,35 @@ by Cardinal Blue ( http://cardinalblue.com )
|
|
47
48
|
"requesting #{url}")
|
48
49
|
})
|
49
50
|
|
50
|
-
# You
|
51
|
-
#
|
52
|
-
|
53
|
-
|
51
|
+
# You might want to do redirect instead of raising an exception,
|
52
|
+
# that is automatically redirect the user to authorization page
|
53
|
+
# if the access token is unavailable. This way, you don't have to
|
54
|
+
# check if the token is expired or not. If the token is expired,
|
55
|
+
# it will automatically do authorization again. For that purpose,
|
56
|
+
# you might want to include RestGraph::RailsUtil in your Rails'
|
57
|
+
# controller. For example:
|
58
|
+
class UserController < ApplicationController
|
59
|
+
include RestGraph::RailsUtil
|
60
|
+
before_filter :rest_graph_setup
|
54
61
|
end
|
55
|
-
|
56
|
-
#
|
57
|
-
|
58
|
-
@rg = RestGraph.new(:error_handler => method(:redirect_to_authorize))
|
59
|
-
end
|
60
|
-
|
61
|
-
# This way, you don't have to check if the token is expired or not.
|
62
|
-
# If the token is expired, it will automatically do authorization again.
|
62
|
+
# Please read:
|
63
|
+
# {examples}[http://github.com/cardinalblue/rest-graph/tree/master/example].
|
64
|
+
# for more detail, and other frameworks utils wanted!
|
63
65
|
|
64
66
|
# Other simple API call:
|
65
|
-
rg.get('me') # GET https://graph.facebook.com/me?access_token
|
66
|
-
rg.get('4/likes') # GET https://graph.facebook.com/4/likes?access_token
|
67
|
+
rg.get('me') # GET https://graph.facebook.com/me?access_token=tok
|
68
|
+
rg.get('4/likes') # GET https://graph.facebook.com/4/likes?access_token=tok
|
67
69
|
|
68
|
-
# GET https://graph.facebook.com/search?q=taiwan&access_token
|
70
|
+
# GET https://graph.facebook.com/search?q=taiwan&access_token=tok
|
69
71
|
rg.get('search', :q => 'taiwan')
|
70
72
|
|
71
|
-
# GET https://graph.facebook.com/me?metadata=1&access_token
|
73
|
+
# GET https://graph.facebook.com/me?metadata=1&access_token=tok
|
72
74
|
rg.get('me', :metadata => '1')
|
73
75
|
|
74
|
-
# POST https://graph.facebook.com/me/feed?message=bread%21&access_token
|
76
|
+
# POST https://graph.facebook.com/me/feed?message=bread%21&access_token=tok
|
75
77
|
rg.post('me/feed', :message => 'bread!')
|
76
78
|
|
77
|
-
#
|
79
|
+
# For fully blown cookies hash
|
78
80
|
rg = RestGraph.new(:app_id => '123', :secret => '1829')
|
79
81
|
rg.parse_cookies!(cookies) # auto save access_token if sig checked
|
80
82
|
rg.data['uid'] # => facebook uid
|
@@ -93,40 +95,61 @@ by Cardinal Blue ( http://cardinalblue.com )
|
|
93
95
|
rg.fql_multi(:q1 => 'SELECT name FROM page WHERE page_id="123"',
|
94
96
|
:q2 => 'SELECT name FROM page WHERE page_id="456"')
|
95
97
|
|
96
|
-
# default
|
97
|
-
|
98
|
-
def
|
98
|
+
# Setup default settings:
|
99
|
+
module MyDefaults
|
100
|
+
def default_app_id
|
99
101
|
'456'
|
100
102
|
end
|
101
103
|
|
102
|
-
def
|
104
|
+
def default_secret
|
103
105
|
'category theory'
|
104
106
|
end
|
105
107
|
end
|
108
|
+
RestGraph.send(:extend, MyDefaults)
|
106
109
|
|
107
|
-
#
|
108
|
-
require 'rest-graph'
|
110
|
+
# Automatically load config:
|
109
111
|
require 'rest-graph/auto_load' # under Rails, load config/rest-graph.yaml
|
110
112
|
RestGraph.new # all default options would honor config
|
111
113
|
RestGraph.new(:app_id => '123') # default could be override as well
|
112
114
|
|
113
|
-
#
|
115
|
+
# Manually load config:
|
114
116
|
require 'rest-graph/load_config'
|
115
117
|
RestGraph::LoadConfig.load_config!('path/to/rest-graph.yaml', 'env')
|
116
118
|
|
117
|
-
#
|
119
|
+
# See test/config/rest-graph.yaml for an example for config.
|
118
120
|
|
119
|
-
#
|
120
|
-
# https://graph.facebook.com/oauth/authorize?client_id
|
121
|
-
RestGraph.new.authorize_url(:redirect_uri => '
|
121
|
+
# OAuth utilites:
|
122
|
+
# https://graph.facebook.com/oauth/authorize?client_id=123&
|
123
|
+
RestGraph.new.authorize_url(:redirect_uri => 'http://w3.org/')
|
122
124
|
|
123
|
-
#
|
124
|
-
# https://graph.facebook.com/oauth/access_token?code
|
125
|
+
# Get access token by:
|
126
|
+
# https://graph.facebook.com/oauth/access_token?code=edoc&
|
125
127
|
rg = RestGraph.new
|
126
|
-
rg.authorize!(:redirect_uri => '
|
128
|
+
rg.authorize!(:redirect_uri => 'http://w3.org/', :code => 'edoc')
|
127
129
|
rg.access_token # your access_token is now available
|
128
130
|
rg.data['expires'] # other values as well
|
129
131
|
|
132
|
+
# Exchange old session key for access token:
|
133
|
+
# https://graph.facebook.com/oauth/exchange_sessions?sessions=...
|
134
|
+
rg.exchange_sessions(:sessions => params[:fb_sig_session_key])
|
135
|
+
|
136
|
+
# Call Facebook's old REST API:
|
137
|
+
rg.old_rest(
|
138
|
+
'stream.publish',
|
139
|
+
{ :message => 'Greetings',
|
140
|
+
:attachment => {:name => 'Wikipedia',
|
141
|
+
:href => 'http://wikipedia.org/',
|
142
|
+
:caption => 'Wikipedia says hi.',
|
143
|
+
:media => [{:type => 'image',
|
144
|
+
:src => 'http://wikipedia.org/favicon.ico',
|
145
|
+
:href => 'http://wikipedia.org/'}]
|
146
|
+
}.to_json,
|
147
|
+
:action_links => [{:text => 'Go to Wikipedia',
|
148
|
+
:href => 'http://wikipedia.org/'}
|
149
|
+
].to_json
|
150
|
+
},
|
151
|
+
:suppress_decode => true)
|
152
|
+
|
130
153
|
== REQUIREMENTS:
|
131
154
|
|
132
155
|
* Tested with MRI 1.8.7 and 1.9.1
|
data/Rakefile
CHANGED
@@ -41,3 +41,11 @@ task :default do
|
|
41
41
|
Rake.application.options.show_task_pattern = /./
|
42
42
|
Rake.application.display_tasks_and_comments
|
43
43
|
end
|
44
|
+
|
45
|
+
desc 'Run example tests'
|
46
|
+
task 'test:example' => ['gem:install'] do
|
47
|
+
sh "cd example/rails; #{Gem.ruby} -S rake test"
|
48
|
+
end
|
49
|
+
|
50
|
+
desc 'Run all tests'
|
51
|
+
task 'test:all' => ['test', 'test:example']
|
data/TODO
CHANGED
@@ -9,12 +9,70 @@ class ApplicationController < ActionController::Base
|
|
9
9
|
# filter_parameter_logging :password
|
10
10
|
|
11
11
|
include RestGraph::RailsUtil
|
12
|
-
|
13
|
-
before_filter :
|
12
|
+
|
13
|
+
before_filter :rest_graph_setup, :only => [:index, :url_for_standalone,
|
14
|
+
:url_for_view_stand,
|
15
|
+
:link_to_stand,
|
16
|
+
:redirect_stand]
|
17
|
+
before_filter :filter_canvas, :only => [:canvas, :url_for_canvas,
|
18
|
+
:url_for_view_canvas,
|
19
|
+
:link_to_canvas,
|
20
|
+
:redirect_canvas]
|
21
|
+
before_filter :filter_options, :only => [:options]
|
22
|
+
before_filter :filter_no_auto, :only => [:no_auto]
|
23
|
+
before_filter :filter_diff_app_id, :only => [:app_id]
|
14
24
|
|
15
25
|
def index
|
16
|
-
|
17
|
-
|
18
|
-
|
26
|
+
render :text => rest_graph.get('me').to_json
|
27
|
+
end
|
28
|
+
alias_method :canvas, :index
|
29
|
+
alias_method :options, :index
|
30
|
+
|
31
|
+
def no_auto
|
32
|
+
rest_graph.get('me')
|
33
|
+
rescue RestGraph::Error
|
34
|
+
render :text => 'XD'
|
35
|
+
end
|
36
|
+
|
37
|
+
def app_id
|
38
|
+
render :text => rest_graph.app_id
|
39
|
+
end
|
40
|
+
|
41
|
+
def url_for_standalone
|
42
|
+
render :text => url_for(:action => 'index')
|
43
|
+
end
|
44
|
+
alias_method :url_for_canvas, :url_for_standalone
|
45
|
+
|
46
|
+
def url_for_view_stand
|
47
|
+
render :inline => '<%= url_for(:action => "index") %>'
|
48
|
+
end
|
49
|
+
alias_method :url_for_view_canvas, :url_for_view_stand
|
50
|
+
|
51
|
+
def link_to_stand
|
52
|
+
render :inline => '<%= link_to("test", :action => "index") %>'
|
53
|
+
end
|
54
|
+
alias_method :link_to_canvas, :link_to_stand
|
55
|
+
|
56
|
+
def redirect_stand
|
57
|
+
redirect_to :action => 'index'
|
58
|
+
end
|
59
|
+
alias_method :redirect_canvas, :redirect_stand
|
60
|
+
|
61
|
+
private
|
62
|
+
def filter_canvas
|
63
|
+
rest_graph_setup(:canvas => true,
|
64
|
+
:auto_authorize_scope => 'publish_stream')
|
65
|
+
end
|
66
|
+
|
67
|
+
def filter_no_auto
|
68
|
+
rest_graph_setup(:auto_authorize => false)
|
69
|
+
end
|
70
|
+
|
71
|
+
def filter_diff_app_id
|
72
|
+
rest_graph_setup(:app_id => 'zzz')
|
73
|
+
end
|
74
|
+
|
75
|
+
def filter_options
|
76
|
+
rest_graph_setup(:auto_authorize_options => {:scope => 'bogus'})
|
19
77
|
end
|
20
78
|
end
|
@@ -19,7 +19,6 @@ Rails::Initializer.run do |config|
|
|
19
19
|
# config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net"
|
20
20
|
# config.gem "sqlite3-ruby", :lib => "sqlite3"
|
21
21
|
# config.gem "aws-s3", :lib => "aws/s3"
|
22
|
-
config.gem 'rest-graph'
|
23
22
|
config.gem 'rest-graph', :lib => 'rest-graph/auto_load'
|
24
23
|
|
25
24
|
# Only load the plugins named here, in the order given (default is alphabetical).
|
@@ -31,7 +31,7 @@ ActionController::Routing::Routes.draw do |map|
|
|
31
31
|
# end
|
32
32
|
|
33
33
|
# You can have the root of your site routed with map.root -- just remember to delete public/index.html.
|
34
|
-
map.
|
34
|
+
map.connect ':action', :controller => 'application'
|
35
35
|
|
36
36
|
# See how all your routes lay out with "rake routes"
|
37
37
|
|
data/example/rails/log
ADDED
File without changes
|
@@ -0,0 +1,114 @@
|
|
1
|
+
|
2
|
+
require 'test_helper'
|
3
|
+
require 'webmock'
|
4
|
+
|
5
|
+
WebMock.disable_net_connect!
|
6
|
+
|
7
|
+
class ApplicationControllerTest < ActionController::TestCase
|
8
|
+
include WebMock
|
9
|
+
|
10
|
+
def setup
|
11
|
+
stub_request(:get, 'https://graph.facebook.com/me').
|
12
|
+
to_return(:body => '{"error":"not authorized"}')
|
13
|
+
end
|
14
|
+
|
15
|
+
def teardown
|
16
|
+
reset_webmock
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_index
|
20
|
+
get(:index)
|
21
|
+
assert_response :redirect
|
22
|
+
assert_equal(
|
23
|
+
normalize_url(
|
24
|
+
'https://graph.facebook.com/oauth/authorize?client_id=123&' \
|
25
|
+
'scope=offline_access%2Cpublish_stream%2Cread_friendlists&' \
|
26
|
+
'redirect_uri=http%3A%2F%2Ftest.host%2F'),
|
27
|
+
normalize_url(assigns(:rest_graph_authorize_url)))
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_canvas
|
31
|
+
get(:canvas)
|
32
|
+
assert_response :success
|
33
|
+
assert_equal(
|
34
|
+
normalize_url(
|
35
|
+
'https://graph.facebook.com/oauth/authorize?client_id=123&' \
|
36
|
+
'scope=publish_stream&' \
|
37
|
+
'redirect_uri=http%3A%2F%2Fapps.facebook.com%2Fcan%2Fcanvas'),
|
38
|
+
normalize_url((assigns(:rest_graph_authorize_url))))
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_options
|
42
|
+
get(:options)
|
43
|
+
assert_response :redirect
|
44
|
+
assert_equal(
|
45
|
+
normalize_url(
|
46
|
+
'https://graph.facebook.com/oauth/authorize?client_id=123&' \
|
47
|
+
'scope=bogus&' \
|
48
|
+
'redirect_uri=http%3A%2F%2Ftest.host%2Foptions'),
|
49
|
+
normalize_url((assigns(:rest_graph_authorize_url))))
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_no_auto
|
53
|
+
get(:no_auto)
|
54
|
+
assert_response :success
|
55
|
+
assert_equal 'XD', @response.body
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_app_id
|
59
|
+
get(:app_id)
|
60
|
+
assert_response :success
|
61
|
+
assert_equal 'zzz', @response.body
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_url_for_standalone
|
65
|
+
get(:url_for_standalone)
|
66
|
+
assert_response :success
|
67
|
+
assert_equal 'http://test.host/', @response.body
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_url_for_canvas
|
71
|
+
get(:url_for_canvas)
|
72
|
+
assert_response :success
|
73
|
+
assert_equal 'http://apps.facebook.com/can/',
|
74
|
+
@response.body
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_url_for_view_stand
|
78
|
+
get(:url_for_view_stand)
|
79
|
+
assert_response :success
|
80
|
+
assert_equal '/', @response.body
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_url_for_view_canvas
|
84
|
+
get(:url_for_view_canvas)
|
85
|
+
assert_response :success
|
86
|
+
assert_equal 'http://apps.facebook.com/can/',
|
87
|
+
@response.body
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_link_to_stand
|
91
|
+
get(:link_to_stand)
|
92
|
+
assert_response :success
|
93
|
+
assert_equal '<a href="/">test</a>', @response.body
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_link_to_canvas
|
97
|
+
get(:link_to_canvas)
|
98
|
+
assert_response :success
|
99
|
+
assert_equal '<a href="http://apps.facebook.com/can/">test</a>',
|
100
|
+
@response.body
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_redirect_stand
|
104
|
+
get(:redirect_stand)
|
105
|
+
assert_response :redirect
|
106
|
+
assert_redirected_to '/'
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_redirect_canvas
|
110
|
+
get(:redirect_canvas)
|
111
|
+
assert_response :redirect
|
112
|
+
assert_redirected_to 'http://apps.facebook.com/can/'
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
ENV["RAILS_ENV"] = "test"
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
|
3
|
+
require 'test_help'
|
4
|
+
|
5
|
+
class ActiveSupport::TestCase
|
6
|
+
def normalize_query query
|
7
|
+
'?' + query[1..-1].split('&').sort.join('&')
|
8
|
+
end
|
9
|
+
|
10
|
+
def normalize_url url
|
11
|
+
url.sub(/\?.+/){ |query| normalize_query(query) }
|
12
|
+
end
|
13
|
+
end
|
data/init.rb
CHANGED
@@ -2,46 +2,77 @@
|
|
2
2
|
require 'rest-graph'
|
3
3
|
|
4
4
|
module RestGraph::RailsUtil
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
module Helper
|
6
|
+
def url_for options
|
7
|
+
caller = respond_to?(:controller) ? controller : self
|
8
|
+
if caller.rest_graph_in_canvas? && options.kind_of?(Hash)
|
9
|
+
super({:host => "apps.facebook.com/#{RestGraph.default_canvas}"}.
|
10
|
+
merge(options))
|
11
|
+
else
|
12
|
+
super(options)
|
13
|
+
end
|
14
|
+
end
|
9
15
|
end
|
10
16
|
|
11
|
-
def
|
12
|
-
|
17
|
+
def self.included controller
|
18
|
+
controller.rescue_from(::RestGraph::Error){ |exception|
|
19
|
+
logger.debug("DEBUG: RestGraph: action halt")
|
20
|
+
}
|
21
|
+
controller.send(:include, ::RestGraph::RailsUtil::Helper)
|
22
|
+
controller.helper(::RestGraph::RailsUtil::Helper)
|
23
|
+
end
|
24
|
+
|
25
|
+
def rest_graph_options
|
26
|
+
@rest_graph_options ||=
|
27
|
+
{:canvas => false,
|
28
|
+
:auto_authorize => true,
|
29
|
+
:auto_authorize_options => {},
|
30
|
+
:auto_authorize_scope =>
|
31
|
+
'offline_access,publish_stream,read_friendlists'}
|
32
|
+
end
|
33
|
+
|
34
|
+
def rest_graph_options_new
|
35
|
+
@rest_graph_options_new ||=
|
36
|
+
{:error_handler => method(:rest_graph_authorize),
|
37
|
+
:log_handler => method(:rest_graph_log)}
|
38
|
+
end
|
39
|
+
|
40
|
+
def rest_graph_setup options={}
|
41
|
+
rest_graph_options .merge!(rest_graph_extract_options(options, :reject))
|
42
|
+
rest_graph_options_new.merge!(rest_graph_extract_options(options, :select))
|
13
43
|
|
14
44
|
# exchange the code with access_token
|
15
45
|
if params[:code]
|
16
|
-
|
17
|
-
|
46
|
+
rest_graph.authorize!(:code => params[:code],
|
47
|
+
:redirect_uri => rest_graph_normalized_request_uri)
|
18
48
|
logger.debug(
|
19
|
-
"DEBUG: RestGraph: detected code with
|
20
|
-
"
|
49
|
+
"DEBUG: RestGraph: detected code with " \
|
50
|
+
"#{rest_graph_normalized_request_uri}, " \
|
51
|
+
"parsed: #{rest_graph.data.inspect}")
|
21
52
|
end
|
22
53
|
|
23
54
|
# if the code is bad or not existed,
|
24
55
|
# check if there's one in session,
|
25
56
|
# meanwhile, there the sig and access_token is correct,
|
26
|
-
# that means we're in the context of
|
27
|
-
if
|
28
|
-
|
29
|
-
logger.debug(
|
30
|
-
|
31
|
-
|
32
|
-
if
|
33
|
-
@
|
57
|
+
# that means we're in the context of canvas
|
58
|
+
if !rest_graph.authorized? && params[:session]
|
59
|
+
rest_graph.parse_json!(params[:session])
|
60
|
+
logger.debug("DEBUG: RestGraph: detected session, parsed:" \
|
61
|
+
" #{rest_graph.data.inspect}")
|
62
|
+
|
63
|
+
if rest_graph.authorized?
|
64
|
+
@fb_sig_in_canvas = true
|
34
65
|
else
|
35
66
|
logger.warn("WARN: RestGraph: bad session: #{params[:session]}")
|
36
67
|
end
|
37
68
|
end
|
38
69
|
|
39
|
-
# if we're not in
|
70
|
+
# if we're not in canvas nor code passed,
|
40
71
|
# we could check out cookies as well.
|
41
|
-
if
|
42
|
-
|
43
|
-
logger.debug(
|
44
|
-
|
72
|
+
if !rest_graph.authorized?
|
73
|
+
rest_graph.parse_cookies!(cookies)
|
74
|
+
logger.debug("DEBUG: RestGraph: detected cookies, parsed:" \
|
75
|
+
" #{rest_graph.data.inspect}")
|
45
76
|
end
|
46
77
|
|
47
78
|
# there are above 3 ways to check the user identity!
|
@@ -50,46 +81,57 @@ module RestGraph::RailsUtil
|
|
50
81
|
end
|
51
82
|
|
52
83
|
# override this if you need different app_id and secret
|
53
|
-
def
|
54
|
-
@
|
55
|
-
:log_handler => method(:rest_graph_log))
|
84
|
+
def rest_graph
|
85
|
+
@rest_graph ||= RestGraph.new(rest_graph_options_new)
|
56
86
|
end
|
57
87
|
|
58
|
-
def rest_graph_authorize error
|
59
|
-
logger.warn("WARN: RestGraph: #{error.inspect}")
|
60
|
-
|
61
|
-
@authorize_url = @rg.authorize_url(
|
62
|
-
{:redirect_uri => normalized_request_uri,
|
63
|
-
:scope => rest_graph_authorize_scope}.
|
64
|
-
merge(rest_graph_authorize_options))
|
88
|
+
def rest_graph_authorize error
|
89
|
+
logger.warn("WARN: RestGraph: #{error.inspect}")
|
65
90
|
|
66
|
-
|
91
|
+
@rest_graph_authorize_url = rest_graph.authorize_url(
|
92
|
+
{:redirect_uri => rest_graph_normalized_request_uri,
|
93
|
+
:scope => rest_graph_options[:auto_authorize_scope]}.
|
94
|
+
merge( rest_graph_options[:auto_authorize_options]))
|
67
95
|
|
68
|
-
|
69
|
-
return false
|
70
|
-
end
|
96
|
+
logger.debug("DEBUG: RestGraph: redirect to #{@rest_graph_authorize_url}")
|
71
97
|
|
72
|
-
|
73
|
-
|
74
|
-
@rest_graph_authorize_scope ||=
|
75
|
-
'offline_access,publish_stream,read_friendlists'
|
98
|
+
rest_graph_authorize_redirect if rest_graph_options[:auto_authorize]
|
99
|
+
raise ::RestGraph::Error.new(error)
|
76
100
|
end
|
77
101
|
|
78
102
|
# override this if you want the simple redirect_to
|
79
103
|
def rest_graph_authorize_redirect
|
80
|
-
|
81
|
-
|
104
|
+
if !rest_graph_in_canvas?
|
105
|
+
redirect_to @rest_graph_authorize_url
|
82
106
|
|
83
|
-
|
84
|
-
|
107
|
+
else
|
108
|
+
render :inline => <<-HTML
|
109
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
110
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
111
|
+
<html>
|
112
|
+
<head>
|
113
|
+
<script type="text/javascript">
|
114
|
+
window.top.location.href = '<%= @rest_graph_authorize_url %>'
|
115
|
+
</script>
|
116
|
+
<noscript>
|
117
|
+
<meta http-equiv="refresh" content="0;url=<%= h @rest_graph_authorize_url %>" />
|
118
|
+
<meta http-equiv="window-target" content="_top" />
|
119
|
+
</noscript>
|
120
|
+
</head>
|
121
|
+
<body>
|
122
|
+
<div>Please <a href="<%= h @rest_graph_authorize_url %>" target="_top">authorize</a> if this page is not automatically redirected.</div>
|
123
|
+
</body>
|
124
|
+
</html>
|
125
|
+
HTML
|
126
|
+
end
|
85
127
|
end
|
86
128
|
|
87
129
|
def rest_graph_log duration, url
|
88
130
|
logger.debug("DEBUG: RestGraph: spent #{duration} requesting #{url}")
|
89
131
|
end
|
90
132
|
|
91
|
-
def
|
92
|
-
if
|
133
|
+
def rest_graph_normalized_request_uri
|
134
|
+
if rest_graph_in_canvas?
|
93
135
|
"http://apps.facebook.com/" \
|
94
136
|
"#{RestGraph.default_canvas}#{request.request_uri}"
|
95
137
|
else
|
@@ -97,6 +139,14 @@ module RestGraph::RailsUtil
|
|
97
139
|
end.sub(/[\&\?]session=[^\&]+/, '').
|
98
140
|
sub(/[\&\?]code=[^\&]+/, '')
|
99
141
|
end
|
100
|
-
end
|
101
142
|
|
102
|
-
|
143
|
+
def rest_graph_in_canvas?
|
144
|
+
rest_graph_options[:canvas] || @fb_sig_in_canvas
|
145
|
+
end
|
146
|
+
|
147
|
+
def rest_graph_extract_options options, method
|
148
|
+
result = options.send(method){ |(k, v)| RestGraph::Attributes.member?(k) }
|
149
|
+
return result if result.kind_of?(Hash) # RUBY_VERSION >= 1.9.1
|
150
|
+
result.inject({}){ |r, (k, v)| r[k] = v; r }
|
151
|
+
end
|
152
|
+
end
|
data/lib/rest-graph/version.rb
CHANGED
data/lib/rest-graph.rb
CHANGED
@@ -11,17 +11,18 @@ begin
|
|
11
11
|
require 'rack'
|
12
12
|
rescue LoadError; end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
rescue LoadError
|
14
|
+
# pick a json gem if available
|
15
|
+
%w[ yajl/json_gem json json_pure ].each{ |json|
|
17
16
|
begin
|
18
|
-
require
|
19
|
-
|
20
|
-
|
17
|
+
require json
|
18
|
+
break
|
19
|
+
rescue LoadError
|
20
|
+
end
|
21
|
+
}
|
21
22
|
|
22
23
|
# the data structure used in RestGraph
|
23
24
|
RestGraphStruct = Struct.new(:data, :auto_decode,
|
24
|
-
:graph_server, :
|
25
|
+
:graph_server, :old_server,
|
25
26
|
:accept, :lang,
|
26
27
|
:app_id, :secret,
|
27
28
|
:error_handler,
|
@@ -47,7 +48,7 @@ class RestGraph < RestGraphStruct
|
|
47
48
|
def default_data ; {} ; end
|
48
49
|
def default_auto_decode ; true ; end
|
49
50
|
def default_graph_server; 'https://graph.facebook.com/'; end
|
50
|
-
def
|
51
|
+
def default_old_server ; 'https://api.facebook.com/' ; end
|
51
52
|
def default_accept ; 'text/javascript' ; end
|
52
53
|
def default_lang ; 'en-us' ; end
|
53
54
|
def default_app_id ; nil ; end
|
@@ -79,52 +80,27 @@ class RestGraph < RestGraphStruct
|
|
79
80
|
!!access_token
|
80
81
|
end
|
81
82
|
|
82
|
-
def get path, opts={}
|
83
|
-
request(graph_server, path,
|
84
|
-
end
|
85
|
-
|
86
|
-
def delete path, opts={}
|
87
|
-
request(graph_server, path, opts, :delete)
|
88
|
-
end
|
89
|
-
|
90
|
-
def post path, payload, opts={}
|
91
|
-
request(graph_server, path, opts, :post, payload)
|
83
|
+
def get path, query={}, opts={}
|
84
|
+
request(graph_server, path, query, :get, nil, opts[:suppress_decode])
|
92
85
|
end
|
93
86
|
|
94
|
-
def
|
95
|
-
request(graph_server, path,
|
87
|
+
def delete path, query={}, opts={}
|
88
|
+
request(graph_server, path, query, :delete, nil, opts[:suppress_decode])
|
96
89
|
end
|
97
90
|
|
98
|
-
def
|
99
|
-
request(
|
100
|
-
{:query => query, :format => 'json'}.merge(opts), :get)
|
91
|
+
def post path, payload, query={}, opts={}
|
92
|
+
request(graph_server, path, query, :post, payload, opts[:suppress_decode])
|
101
93
|
end
|
102
94
|
|
103
|
-
def
|
104
|
-
|
105
|
-
queries.to_json
|
106
|
-
else
|
107
|
-
middle = queries.inject([]){ |r, (k, v)|
|
108
|
-
r << "\"#{k}\":\"#{v.gsub('"','\\"')}\""
|
109
|
-
}.join(',')
|
110
|
-
"{#{middle}}"
|
111
|
-
end
|
112
|
-
request(fql_server, 'method/fql.multiquery',
|
113
|
-
{:queries => q, :format => 'json'}.merge(opts), :get)
|
95
|
+
def put path, payload, query={}, opts={}
|
96
|
+
request(graph_server, path, query, :put, payload, opts[:suppress_decode])
|
114
97
|
end
|
115
98
|
|
116
99
|
# cookies, app_id, secrect related below
|
117
100
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
check_sig_and_return_data(Rack::Utils.parse_query($1))
|
122
|
-
end
|
123
|
-
else
|
124
|
-
def parse_rack_env! env
|
125
|
-
self.data = (env['HTTP_COOKIE'] || '') =~ /fbs_#{app_id}=([^\;]+)/ &&
|
126
|
-
check_sig_and_return_data(Rack::Utils.parse_query($1))
|
127
|
-
end
|
101
|
+
def parse_rack_env! env
|
102
|
+
env['HTTP_COOKIE'].to_s =~ /fbs_#{app_id}=([^\;]+)/
|
103
|
+
self.data = parse_fbs!($1)
|
128
104
|
end
|
129
105
|
|
130
106
|
def parse_cookies! cookies
|
@@ -132,13 +108,14 @@ class RestGraph < RestGraphStruct
|
|
132
108
|
end
|
133
109
|
|
134
110
|
def parse_fbs! fbs
|
135
|
-
self.data =
|
136
|
-
|
111
|
+
self.data = check_sig_and_return_data(
|
112
|
+
# take out facebook sometimes there but sometimes not quotes in cookies
|
113
|
+
Rack::Utils.parse_query(fbs.to_s.gsub('"', '')))
|
137
114
|
end
|
138
115
|
|
139
116
|
def parse_json! json
|
140
117
|
self.data = json &&
|
141
|
-
check_sig_and_return_data(JSON.
|
118
|
+
check_sig_and_return_data(JSON.parse(json))
|
142
119
|
rescue JSON::ParserError
|
143
120
|
end
|
144
121
|
|
@@ -155,13 +132,42 @@ class RestGraph < RestGraphStruct
|
|
155
132
|
request(graph_server, 'oauth/access_token', query, :get, nil, true))
|
156
133
|
end
|
157
134
|
|
135
|
+
# old rest facebook api, i will definitely love to remove them someday
|
136
|
+
|
137
|
+
def old_rest path, query={}, opts={}
|
138
|
+
request(old_server, "method/#{path}",
|
139
|
+
{:format => 'json'}.merge(query), :get, nil, opts[:suppress_decode])
|
140
|
+
end
|
141
|
+
|
142
|
+
def exchange_sessions opts={}
|
143
|
+
query = {:client_id => app_id, :client_secret => secret,
|
144
|
+
:type => 'client_cred'}.merge(opts)
|
145
|
+
request(graph_server, 'oauth/exchange_sessions', query, :post)
|
146
|
+
end
|
147
|
+
|
148
|
+
def fql code, query={}, opts={}
|
149
|
+
old_rest('fql.query', {:query => code}.merge(query), opts)
|
150
|
+
end
|
151
|
+
|
152
|
+
def fql_multi codes, query={}, opts={}
|
153
|
+
c = if codes.respond_to?(:to_json)
|
154
|
+
codes.to_json
|
155
|
+
else
|
156
|
+
middle = codes.inject([]){ |r, (k, v)|
|
157
|
+
r << "\"#{k}\":\"#{v.gsub('"','\\"')}\""
|
158
|
+
}.join(',')
|
159
|
+
"{#{middle}}"
|
160
|
+
end
|
161
|
+
old_rest('fql.multiquery', {:queries => c}.merge(query), opts)
|
162
|
+
end
|
163
|
+
|
158
164
|
private
|
159
|
-
def request server, path, opts, method, payload=nil, suppress_decode=
|
165
|
+
def request server, path, opts, method, payload=nil, suppress_decode=nil
|
160
166
|
start_time = Time.now
|
161
167
|
res = RestClient::Resource.new(server)[path + build_query_string(opts)]
|
162
168
|
post_request(
|
163
169
|
res.send(method, *[payload, build_headers].compact), suppress_decode)
|
164
|
-
rescue RestClient::
|
170
|
+
rescue RestClient::Exception => e
|
165
171
|
post_request(e.http_body, suppress_decode)
|
166
172
|
ensure
|
167
173
|
log_handler.call(Time.now - start_time, res.url)
|
@@ -181,7 +187,7 @@ class RestGraph < RestGraphStruct
|
|
181
187
|
headers
|
182
188
|
end
|
183
189
|
|
184
|
-
def post_request result, suppress_decode=
|
190
|
+
def post_request result, suppress_decode=nil
|
185
191
|
if auto_decode && !suppress_decode
|
186
192
|
check_error(JSON.parse(result))
|
187
193
|
else
|
data/rest-graph.gemspec
CHANGED
@@ -2,22 +2,22 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{rest-graph}
|
5
|
-
s.version = "1.
|
5
|
+
s.version = "1.3.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Cardinal Blue", "Lin Jen-Shin (aka godfat 真常)"]
|
9
|
-
s.date = %q{2010-06-
|
9
|
+
s.date = %q{2010-06-10}
|
10
10
|
s.description = %q{ A super simple Facebook Open Graph API client}
|
11
11
|
s.email = %q{dev (XD) cardinalblue.com}
|
12
|
-
s.extra_rdoc_files = ["CHANGES", "LICENSE", "TODO", "example/rails/README", "example/rails/
|
13
|
-
s.files = ["CHANGES", "LICENSE", "README.rdoc", "Rakefile", "TODO", "example/rails/README", "example/rails/Rakefile", "example/rails/app/controllers/application_controller.rb", "example/rails/
|
12
|
+
s.extra_rdoc_files = ["CHANGES", "LICENSE", "TODO", "example/rails/README", "example/rails/config/rest-graph.yaml", "example/rails/log", "example/rails/script/console", "example/rails/script/server", "rest-graph.gemspec"]
|
13
|
+
s.files = ["CHANGES", "LICENSE", "README.rdoc", "Rakefile", "TODO", "example/rails/README", "example/rails/Rakefile", "example/rails/app/controllers/application_controller.rb", "example/rails/config/boot.rb", "example/rails/config/environment.rb", "example/rails/config/environments/development.rb", "example/rails/config/environments/production.rb", "example/rails/config/environments/test.rb", "example/rails/config/initializers/cookie_verification_secret.rb", "example/rails/config/initializers/new_rails_defaults.rb", "example/rails/config/initializers/session_store.rb", "example/rails/config/rest-graph.yaml", "example/rails/config/routes.rb", "example/rails/log", "example/rails/script/console", "example/rails/script/server", "example/rails/test/functional/application_controller_test.rb", "example/rails/test/test_helper.rb", "init.rb", "lib/rest-graph.rb", "lib/rest-graph/auto_load.rb", "lib/rest-graph/load_config.rb", "lib/rest-graph/rails_util.rb", "lib/rest-graph/version.rb", "rest-graph.gemspec", "test/common.rb", "test/config/rest-graph.yaml", "test/test_default.rb", "test/test_handler.rb", "test/test_load_config.rb", "test/test_oauth.rb", "test/test_old.rb", "test/test_parse.rb", "test/test_rest-graph.rb"]
|
14
14
|
s.homepage = %q{http://github.com/cardinalblue/rest-graph}
|
15
15
|
s.rdoc_options = ["--main", "README.rdoc"]
|
16
16
|
s.require_paths = ["lib"]
|
17
17
|
s.rubyforge_project = %q{rest-graph}
|
18
18
|
s.rubygems_version = %q{1.3.7}
|
19
19
|
s.summary = %q{A super simple Facebook Open Graph API client}
|
20
|
-
s.test_files = ["test/test_default.rb", "test/
|
20
|
+
s.test_files = ["test/test_default.rb", "test/test_handler.rb", "test/test_load_config.rb", "test/test_oauth.rb", "test/test_old.rb", "test/test_parse.rb", "test/test_rest-graph.rb"]
|
21
21
|
|
22
22
|
if s.respond_to? :specification_version then
|
23
23
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
@@ -30,7 +30,7 @@ Gem::Specification.new do |s|
|
|
30
30
|
s.add_development_dependency(%q<rr>, [">= 0.10.11"])
|
31
31
|
s.add_development_dependency(%q<webmock>, [">= 1.2.2"])
|
32
32
|
s.add_development_dependency(%q<bacon>, [">= 1.1.0"])
|
33
|
-
s.add_development_dependency(%q<bones>, [">= 3.4.
|
33
|
+
s.add_development_dependency(%q<bones>, [">= 3.4.6"])
|
34
34
|
else
|
35
35
|
s.add_dependency(%q<rest-client>, [">= 1.5.1"])
|
36
36
|
s.add_dependency(%q<json>, [">= 1.4.3"])
|
@@ -38,7 +38,7 @@ Gem::Specification.new do |s|
|
|
38
38
|
s.add_dependency(%q<rr>, [">= 0.10.11"])
|
39
39
|
s.add_dependency(%q<webmock>, [">= 1.2.2"])
|
40
40
|
s.add_dependency(%q<bacon>, [">= 1.1.0"])
|
41
|
-
s.add_dependency(%q<bones>, [">= 3.4.
|
41
|
+
s.add_dependency(%q<bones>, [">= 3.4.6"])
|
42
42
|
end
|
43
43
|
else
|
44
44
|
s.add_dependency(%q<rest-client>, [">= 1.5.1"])
|
@@ -47,6 +47,6 @@ Gem::Specification.new do |s|
|
|
47
47
|
s.add_dependency(%q<rr>, [">= 0.10.11"])
|
48
48
|
s.add_dependency(%q<webmock>, [">= 1.2.2"])
|
49
49
|
s.add_dependency(%q<bacon>, [">= 1.1.0"])
|
50
|
-
s.add_dependency(%q<bones>, [">= 3.4.
|
50
|
+
s.add_dependency(%q<bones>, [">= 3.4.6"])
|
51
51
|
end
|
52
52
|
end
|
@@ -35,11 +35,16 @@ describe RestGraph do
|
|
35
35
|
f1 = 'SELECT display_name FROM application WHERE app_id="110225210740"'
|
36
36
|
f0q, f1q = "\"#{f0.gsub('"', '\\"')}\"", "\"#{f1.gsub('"', '\\"')}\""
|
37
37
|
q = "format=json&queries=#{CGI.escape("{\"f0\":#{f0q},\"f1\":#{f1q}}")}"
|
38
|
+
p = "format=json&queries=#{CGI.escape("{\"f1\":#{f1q},\"f0\":#{f0q}}")}"
|
38
39
|
|
39
40
|
stub_multi = lambda{
|
40
41
|
stub_request(:get,
|
41
42
|
"https://api.facebook.com/method/fql.multiquery?#{q}").
|
42
43
|
to_return(:body => '[]')
|
44
|
+
|
45
|
+
stub_request(:get,
|
46
|
+
"https://api.facebook.com/method/fql.multiquery?#{p}").
|
47
|
+
to_return(:body => '[]')
|
43
48
|
}
|
44
49
|
|
45
50
|
stub_multi.call
|
@@ -57,4 +62,27 @@ describe RestGraph do
|
|
57
62
|
stub_multi.call
|
58
63
|
RestGraph.new.fql_multi(queries).should == []
|
59
64
|
end
|
65
|
+
|
66
|
+
it 'would do facebook old rest api' do
|
67
|
+
body = 'hate facebook inconsistent'
|
68
|
+
stub_request(:get,
|
69
|
+
'https://api.facebook.com/method/notes.create?format=json').
|
70
|
+
to_return(:body => body)
|
71
|
+
|
72
|
+
RestGraph.new.old_rest('notes.create', {}, :suppress_decode => true).
|
73
|
+
should == body
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'would exchange sessions for access token' do
|
77
|
+
stub_request(:post,
|
78
|
+
'https://graph.facebook.com/oauth/exchange_sessions?' \
|
79
|
+
'type=client_cred&client_id=id&client_secret=di&' \
|
80
|
+
'sessions=bad%20bed').
|
81
|
+
to_return(:body => '[{"access_token":"bogus"}]')
|
82
|
+
|
83
|
+
RestGraph.new(:app_id => 'id',
|
84
|
+
:secret => 'di').
|
85
|
+
exchange_sessions(:sessions => 'bad bed').
|
86
|
+
first['access_token'].should == 'bogus'
|
87
|
+
end
|
60
88
|
end
|
data/test/test_parse.rb
CHANGED
@@ -21,7 +21,7 @@ describe RestGraph do
|
|
21
21
|
fbs = "access_token=#{CGI.escape(access_token)}&expires=0&" \
|
22
22
|
"secret=abc&session_key=def-456&sig=#{sig}&uid=3"
|
23
23
|
|
24
|
-
check = lambda{ |token|
|
24
|
+
check = lambda{ |token, fbs|
|
25
25
|
http_cookie =
|
26
26
|
"__utma=123; __utmz=456.utmcsr=(d)|utmccn=(d)|utmcmd=(n); " \
|
27
27
|
"fbs_#{app_id}=#{fbs}"
|
@@ -42,10 +42,11 @@ describe RestGraph do
|
|
42
42
|
should.kind_of?(token ? Hash : NilClass)
|
43
43
|
rg.access_token.should == token
|
44
44
|
}
|
45
|
-
check.call(access_token)
|
46
|
-
fbs
|
47
|
-
fbs
|
48
|
-
check.call(nil)
|
45
|
+
check.call(access_token, fbs)
|
46
|
+
check.call(access_token, "\"#{fbs}\"")
|
47
|
+
fbs << '&inject=evil"'
|
48
|
+
check.call(nil, fbs)
|
49
|
+
check.call(nil, "\"#{fbs}\"")
|
49
50
|
end
|
50
51
|
|
51
52
|
it 'would not pass if there is no secret, prevent from forgery' do
|
data/test/test_rest-graph.rb
CHANGED
@@ -75,20 +75,31 @@ describe RestGraph do
|
|
75
75
|
should == '[]'
|
76
76
|
end
|
77
77
|
|
78
|
+
it 'could suppress auto-decode in an api call' do
|
79
|
+
stub_request(:get, 'https://graph.facebook.com/woot').
|
80
|
+
to_return(:body => 'bad json')
|
81
|
+
|
82
|
+
rg = RestGraph.new(:auto_decode => true)
|
83
|
+
rg.get('woot', {}, :suppress_decode => true).should == 'bad json'
|
84
|
+
rg.auto_decode.should == true
|
85
|
+
end
|
86
|
+
|
78
87
|
it 'would call post_request after request' do
|
79
88
|
stub_request(:put, 'https://graph.facebook.com/feed/me').
|
80
89
|
with(:body => 'message=hi%20there').to_return(:body => '[]')
|
81
90
|
|
82
|
-
mock.proxy(rg = RestGraph.new).post_request('[]',
|
91
|
+
mock.proxy(rg = RestGraph.new).post_request('[]', nil)
|
83
92
|
rg.put('feed/me', :message => 'hi there').
|
84
93
|
should == []
|
85
94
|
end
|
86
95
|
|
87
|
-
it 'would not raise exception when encountering
|
88
|
-
|
89
|
-
:
|
96
|
+
it 'would not raise exception when encountering error' do
|
97
|
+
[500, 401, 402, 403].each{ |status|
|
98
|
+
stub_request(:delete, 'https://graph.facebook.com/123').to_return(
|
99
|
+
:body => '[]', :status => status)
|
90
100
|
|
91
|
-
|
101
|
+
RestGraph.new.delete('123').should == []
|
102
|
+
}
|
92
103
|
end
|
93
104
|
|
94
105
|
it 'would return true in authorized? if there is an access_token' do
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rest-graph
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 1.
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 1.3.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Cardinal Blue
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-06-
|
19
|
+
date: 2010-06-11 00:00:00 +08:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -123,12 +123,12 @@ dependencies:
|
|
123
123
|
requirements:
|
124
124
|
- - ">="
|
125
125
|
- !ruby/object:Gem::Version
|
126
|
-
hash:
|
126
|
+
hash: 27
|
127
127
|
segments:
|
128
128
|
- 3
|
129
129
|
- 4
|
130
|
-
-
|
131
|
-
version: 3.4.
|
130
|
+
- 6
|
131
|
+
version: 3.4.6
|
132
132
|
type: :development
|
133
133
|
version_requirements: *id007
|
134
134
|
description: " A super simple Facebook Open Graph API client"
|
@@ -142,8 +142,8 @@ extra_rdoc_files:
|
|
142
142
|
- LICENSE
|
143
143
|
- TODO
|
144
144
|
- example/rails/README
|
145
|
-
- example/rails/app/views/rest-graph/authorization.erb
|
146
145
|
- example/rails/config/rest-graph.yaml
|
146
|
+
- example/rails/log
|
147
147
|
- example/rails/script/console
|
148
148
|
- example/rails/script/server
|
149
149
|
- rest-graph.gemspec
|
@@ -156,7 +156,6 @@ files:
|
|
156
156
|
- example/rails/README
|
157
157
|
- example/rails/Rakefile
|
158
158
|
- example/rails/app/controllers/application_controller.rb
|
159
|
-
- example/rails/app/views/rest-graph/authorization.erb
|
160
159
|
- example/rails/config/boot.rb
|
161
160
|
- example/rails/config/environment.rb
|
162
161
|
- example/rails/config/environments/development.rb
|
@@ -167,8 +166,11 @@ files:
|
|
167
166
|
- example/rails/config/initializers/session_store.rb
|
168
167
|
- example/rails/config/rest-graph.yaml
|
169
168
|
- example/rails/config/routes.rb
|
169
|
+
- example/rails/log
|
170
170
|
- example/rails/script/console
|
171
171
|
- example/rails/script/server
|
172
|
+
- example/rails/test/functional/application_controller_test.rb
|
173
|
+
- example/rails/test/test_helper.rb
|
172
174
|
- init.rb
|
173
175
|
- lib/rest-graph.rb
|
174
176
|
- lib/rest-graph/auto_load.rb
|
@@ -179,10 +181,10 @@ files:
|
|
179
181
|
- test/common.rb
|
180
182
|
- test/config/rest-graph.yaml
|
181
183
|
- test/test_default.rb
|
182
|
-
- test/test_fql.rb
|
183
184
|
- test/test_handler.rb
|
184
185
|
- test/test_load_config.rb
|
185
186
|
- test/test_oauth.rb
|
187
|
+
- test/test_old.rb
|
186
188
|
- test/test_parse.rb
|
187
189
|
- test/test_rest-graph.rb
|
188
190
|
has_rdoc: true
|
@@ -222,9 +224,9 @@ specification_version: 3
|
|
222
224
|
summary: A super simple Facebook Open Graph API client
|
223
225
|
test_files:
|
224
226
|
- test/test_default.rb
|
225
|
-
- test/test_fql.rb
|
226
227
|
- test/test_handler.rb
|
227
228
|
- test/test_load_config.rb
|
228
229
|
- test/test_oauth.rb
|
230
|
+
- test/test_old.rb
|
229
231
|
- test/test_parse.rb
|
230
232
|
- test/test_rest-graph.rb
|
@@ -1,16 +0,0 @@
|
|
1
|
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
-
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
-
<html>
|
4
|
-
<head>
|
5
|
-
<script type="text/javascript">
|
6
|
-
window.top.location.href = '<%= @authorize_url %>'
|
7
|
-
</script>
|
8
|
-
<noscript>
|
9
|
-
<meta http-equiv="refresh" content="0;url=<%= h @authorize_url %>" />
|
10
|
-
<meta http-equiv="window-target" content="_top" />
|
11
|
-
</noscript>
|
12
|
-
</head>
|
13
|
-
<body>
|
14
|
-
<div>Please <a href="<%= h @authorize_url %>" target="_top">authorize</a> if this page is not automatically redirected.</div>
|
15
|
-
</body>
|
16
|
-
</html>
|