rest-graph 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +7 -2
- data/README.rdoc +12 -1
- data/TODO +15 -2
- data/lib/rest-graph/version.rb +1 -1
- data/lib/rest-graph.rb +29 -9
- data/test/common.rb +8 -0
- data/test/test_oauth.rb +34 -0
- data/test/test_rest-graph.rb +7 -8
- metadata +31 -10
data/CHANGES
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
= rest-graph changes history
|
2
2
|
|
3
|
+
== rest-graph 1.1.1 -- 2010-05-21
|
4
|
+
* Add oauth realted utilites -- authorize_url and authorize!
|
5
|
+
* Fixed a bug that in Ruby 1.8.7-, nil =~ /regexp/ equals to false.
|
6
|
+
It is nil as expected in Ruby 1.9.1+
|
7
|
+
|
3
8
|
== rest-graph 1.1.0 -- 2010-05-13
|
4
9
|
* Main repository was moved to http://github.com/cardinalblue/rest-graph
|
5
10
|
Sorry for the inconvenience. I'll keep pushing to both repositories until
|
@@ -12,8 +17,8 @@
|
|
12
17
|
if you're using rails plugin, we do require 'rest-graph/auto_load'
|
13
18
|
for you.
|
14
19
|
|
15
|
-
* Config could be
|
16
|
-
RestGraph::LoadConfig.load_config!('path/to/rest-graph.yaml', 'env')
|
20
|
+
* Config could be loaded manually as well. require 'rest-graph/load_config'
|
21
|
+
and RestGraph::LoadConfig.load_config!('path/to/rest-graph.yaml', 'env')
|
17
22
|
|
18
23
|
== rest-graph 1.0.0 -- 2010-05-06
|
19
24
|
* now access_token is saved in data attributes.
|
data/README.rdoc
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= rest-graph 1.1.
|
1
|
+
= rest-graph 1.1.1
|
2
2
|
by Cardinal Blue ( http://cardinalblue.com )
|
3
3
|
|
4
4
|
== LINKS:
|
@@ -77,6 +77,17 @@ by Cardinal Blue ( http://cardinalblue.com )
|
|
77
77
|
|
78
78
|
# see test/config/rest-graph.yaml for an example for config
|
79
79
|
|
80
|
+
# oauth utilites:
|
81
|
+
# https://graph.facebook.com/oauth/authorize?client_id=...&
|
82
|
+
RestGraph.new.authorize_url(:redirect_uri => '...')
|
83
|
+
|
84
|
+
# get access token by:
|
85
|
+
# https://graph.facebook.com/oauth/access_token?code=...&
|
86
|
+
rg = RestGraph.new
|
87
|
+
rg.authorize!(:redirect_uri => '...', :code => 'zzz')
|
88
|
+
rg.access_token # your access_token is now available
|
89
|
+
rg.data['expires'] # other values as well
|
90
|
+
|
80
91
|
== REQUIREMENTS:
|
81
92
|
|
82
93
|
* tested with MRI 1.8.7 and 1.9.1
|
data/TODO
CHANGED
@@ -1,4 +1,17 @@
|
|
1
1
|
= rest-graph todo list
|
2
2
|
|
3
|
-
= 1.
|
4
|
-
*
|
3
|
+
= 1.1
|
4
|
+
* auto authorization?
|
5
|
+
|
6
|
+
class AuthError < RuntimeError; end
|
7
|
+
|
8
|
+
rg = RestGraph.new(:scope => 'publish_stream,read_friendlists',
|
9
|
+
:error_callback => lambda{ |json| raise AuthError } )
|
10
|
+
|
11
|
+
begin
|
12
|
+
rg.get('me')
|
13
|
+
rescue AuthError
|
14
|
+
# ...
|
15
|
+
end
|
16
|
+
|
17
|
+
rg.error_callback = lambda{ |json| redirect request.url }
|
data/lib/rest-graph/version.rb
CHANGED
data/lib/rest-graph.rb
CHANGED
@@ -77,9 +77,16 @@ class RestGraph < RestGraphStruct
|
|
77
77
|
|
78
78
|
# cookies, app_id, secrect related below
|
79
79
|
|
80
|
-
|
81
|
-
|
82
|
-
|
80
|
+
if RUBY_VERSION >= '1.9.1'
|
81
|
+
def parse_rack_env! env
|
82
|
+
self.data = env['HTTP_COOKIE'] =~ /fbs_#{app_id}="(.+?)"/ &&
|
83
|
+
check_sig_and_return_data(Rack::Utils.parse_query($1))
|
84
|
+
end
|
85
|
+
else
|
86
|
+
def parse_rack_env! env
|
87
|
+
self.data = (env['HTTP_COOKIE'] || '') =~ /fbs_#{app_id}="(.+?)"/ &&
|
88
|
+
check_sig_and_return_data(Rack::Utils.parse_query($1))
|
89
|
+
end
|
83
90
|
end
|
84
91
|
|
85
92
|
def parse_cookies! cookies
|
@@ -91,6 +98,19 @@ class RestGraph < RestGraphStruct
|
|
91
98
|
check_sig_and_return_data(Rack::Utils.parse_query(fbs[1..-2]))
|
92
99
|
end
|
93
100
|
|
101
|
+
# oauth related
|
102
|
+
|
103
|
+
def authorize_url opts={}
|
104
|
+
query = {:client_id => app_id}.merge(opts)
|
105
|
+
"#{graph_server}oauth/authorize#{build_query_string(query)}"
|
106
|
+
end
|
107
|
+
|
108
|
+
def authorize! opts={}
|
109
|
+
query = {:client_id => app_id, :client_secret => secret}.merge(opts)
|
110
|
+
self.data = Rack::Utils.parse_query(
|
111
|
+
request(graph_server, 'oauth/access_token', query, :get, nil, true))
|
112
|
+
end
|
113
|
+
|
94
114
|
private
|
95
115
|
def check_arguments!
|
96
116
|
if auto_decode
|
@@ -111,15 +131,15 @@ class RestGraph < RestGraphStruct
|
|
111
131
|
end
|
112
132
|
end
|
113
133
|
|
114
|
-
def request server, path, opts, method, payload =
|
134
|
+
def request server, path, opts, method, payload=nil, suppress_decode=false
|
115
135
|
post_request(
|
116
136
|
RestClient::Resource.new(server)[path + build_query_string(opts)].
|
117
|
-
send(method, *[payload, build_headers].compact))
|
137
|
+
send(method, *[payload, build_headers].compact), suppress_decode)
|
118
138
|
rescue RestClient::InternalServerError => e
|
119
|
-
post_request(e.http_body)
|
139
|
+
post_request(e.http_body, suppress_decode)
|
120
140
|
end
|
121
141
|
|
122
|
-
def build_query_string q
|
142
|
+
def build_query_string q={}
|
123
143
|
query = q.merge(access_token ? {:access_token => access_token} : {})
|
124
144
|
return '' if query.empty?
|
125
145
|
return '?' + query.map{ |(k, v)| "#{k}=#{CGI.escape(v.to_s)}" }.join('&')
|
@@ -132,8 +152,8 @@ class RestGraph < RestGraphStruct
|
|
132
152
|
headers
|
133
153
|
end
|
134
154
|
|
135
|
-
def post_request result
|
136
|
-
auto_decode ? JSON.parse(result) : result
|
155
|
+
def post_request result, suppress_decode=false
|
156
|
+
(auto_decode && !suppress_decode) ? JSON.parse(result) : result
|
137
157
|
end
|
138
158
|
|
139
159
|
def check_sig_and_return_data cookies
|
data/test/common.rb
CHANGED
@@ -25,4 +25,12 @@ module TestHelper
|
|
25
25
|
RestGraph::DefaultAttributes.send("default_#{name}")
|
26
26
|
}
|
27
27
|
end
|
28
|
+
|
29
|
+
def normalize_query query
|
30
|
+
'?' + query[1..-1].split('&').sort.join('&')
|
31
|
+
end
|
32
|
+
|
33
|
+
def normalize_url url
|
34
|
+
url.sub(/\?.+/){ |query| TestHelper.normalize_query(query) }
|
35
|
+
end
|
28
36
|
end
|
data/test/test_oauth.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
if respond_to?(:require_relative, true)
|
3
|
+
require_relative 'common'
|
4
|
+
else
|
5
|
+
require File.dirname(__FILE__) + '/common'
|
6
|
+
end
|
7
|
+
|
8
|
+
describe RestGraph do
|
9
|
+
before do
|
10
|
+
reset_webmock
|
11
|
+
@rg = RestGraph.new(:app_id => '29', :secret => '18')
|
12
|
+
@uri = 'http://zzz.tw'
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'would return correct oauth url' do
|
16
|
+
TestHelper.normalize_url(@rg.authorize_url(:redirect_uri => @uri)).
|
17
|
+
should == 'https://graph.facebook.com/oauth/authorize?' \
|
18
|
+
'client_id=29&redirect_uri=http%3A%2F%2Fzzz.tw'
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'would do authorizing and parse result and save it in data' do
|
22
|
+
stub_request(:get, 'https://graph.facebook.com/oauth/access_token?' \
|
23
|
+
'client_id=29&client_secret=18&code=zzz&' \
|
24
|
+
'redirect_uri=http%3A%2F%2Fzzz.tw').
|
25
|
+
to_return(:body => 'access_token=baken&expires=2918')
|
26
|
+
|
27
|
+
result = {'access_token' => 'baken', 'expires' => '2918'}
|
28
|
+
|
29
|
+
@rg.authorize!(:redirect_uri => @uri, :code => 'zzz').
|
30
|
+
should == result
|
31
|
+
@rg.data.should == result
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
data/test/test_rest-graph.rb
CHANGED
@@ -10,10 +10,6 @@ describe RestGraph do
|
|
10
10
|
reset_webmock
|
11
11
|
end
|
12
12
|
|
13
|
-
def normalize_query query
|
14
|
-
'?' + query[1..-1].split('&').sort.join('&')
|
15
|
-
end
|
16
|
-
|
17
13
|
it 'would build correct headers' do
|
18
14
|
rg = RestGraph.new(:accept => 'text/html',
|
19
15
|
:lang => 'zh-tw')
|
@@ -31,12 +27,12 @@ describe RestGraph do
|
|
31
27
|
end
|
32
28
|
|
33
29
|
it 'would build correct query string' do
|
34
|
-
normalize_query(
|
30
|
+
TestHelper.normalize_query(
|
35
31
|
RestGraph.new(:access_token => 'token').send(:build_query_string,
|
36
32
|
:message => 'hi!!')).
|
37
33
|
should == '?access_token=token&message=hi%21%21'
|
38
34
|
|
39
|
-
normalize_query(
|
35
|
+
TestHelper.normalize_query(
|
40
36
|
RestGraph.new.send(:build_query_string, :message => 'hi!!',
|
41
37
|
:subject => '(&oh&)')).
|
42
38
|
should == '?message=hi%21%21&subject=%28%26oh%26%29'
|
@@ -79,7 +75,7 @@ describe RestGraph do
|
|
79
75
|
stub_request(:put, 'https://graph.facebook.com/feed/me').
|
80
76
|
with(:body => 'message=hi%20there').to_return(:body => '[]')
|
81
77
|
|
82
|
-
mock.proxy(rg = RestGraph.new).post_request('[]')
|
78
|
+
mock.proxy(rg = RestGraph.new).post_request('[]', false)
|
83
79
|
rg.put('feed/me', :message => 'hi there').
|
84
80
|
should == []
|
85
81
|
end
|
@@ -109,6 +105,9 @@ describe RestGraph do
|
|
109
105
|
should.kind_of?(token ? Hash : NilClass)
|
110
106
|
rg.access_token.should == token
|
111
107
|
|
108
|
+
rg.parse_rack_env!('HTTP_COOKIE' => nil).should == nil
|
109
|
+
rg.data.should == {}
|
110
|
+
|
112
111
|
rg.parse_cookies!({"fbs_#{app_id}" => fbs}).
|
113
112
|
should.kind_of?(token ? Hash : NilClass)
|
114
113
|
rg.access_token.should == token
|
@@ -136,7 +135,7 @@ describe RestGraph do
|
|
136
135
|
|
137
136
|
it 'would do fql query with/without access_token' do
|
138
137
|
fql = 'SELECT name FROM likes where id="123"'
|
139
|
-
query = "query=#{fql}
|
138
|
+
query = "format=json&query=#{CGI.escape(fql)}"
|
140
139
|
stub_request(:get, "https://api.facebook.com/method/fql.query?#{query}").
|
141
140
|
to_return(:body => '[]')
|
142
141
|
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rest-graph
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 17
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 1
|
7
8
|
- 1
|
8
|
-
-
|
9
|
-
version: 1.1.
|
9
|
+
- 1
|
10
|
+
version: 1.1.1
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Cardinal Blue
|
@@ -15,30 +16,34 @@ autorequire:
|
|
15
16
|
bindir: bin
|
16
17
|
cert_chain: []
|
17
18
|
|
18
|
-
date: 2010-05-
|
19
|
+
date: 2010-05-21 00:00:00 +08:00
|
19
20
|
default_executable:
|
20
21
|
dependencies:
|
21
22
|
- !ruby/object:Gem::Dependency
|
22
23
|
name: rest-client
|
23
24
|
prerelease: false
|
24
25
|
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
25
27
|
requirements:
|
26
28
|
- - ">="
|
27
29
|
- !ruby/object:Gem::Version
|
30
|
+
hash: 1
|
28
31
|
segments:
|
29
32
|
- 1
|
30
33
|
- 5
|
31
|
-
-
|
32
|
-
version: 1.5.
|
34
|
+
- 1
|
35
|
+
version: 1.5.1
|
33
36
|
type: :runtime
|
34
37
|
version_requirements: *id001
|
35
38
|
- !ruby/object:Gem::Dependency
|
36
39
|
name: json
|
37
40
|
prerelease: false
|
38
41
|
requirement: &id002 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
39
43
|
requirements:
|
40
44
|
- - ">="
|
41
45
|
- !ruby/object:Gem::Version
|
46
|
+
hash: 1
|
42
47
|
segments:
|
43
48
|
- 1
|
44
49
|
- 4
|
@@ -50,9 +55,11 @@ dependencies:
|
|
50
55
|
name: rack
|
51
56
|
prerelease: false
|
52
57
|
requirement: &id003 !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
53
59
|
requirements:
|
54
60
|
- - ">="
|
55
61
|
- !ruby/object:Gem::Version
|
62
|
+
hash: 19
|
56
63
|
segments:
|
57
64
|
- 1
|
58
65
|
- 1
|
@@ -64,9 +71,11 @@ dependencies:
|
|
64
71
|
name: rr
|
65
72
|
prerelease: false
|
66
73
|
requirement: &id004 !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
67
75
|
requirements:
|
68
76
|
- - ">="
|
69
77
|
- !ruby/object:Gem::Version
|
78
|
+
hash: 33
|
70
79
|
segments:
|
71
80
|
- 0
|
72
81
|
- 10
|
@@ -78,23 +87,27 @@ dependencies:
|
|
78
87
|
name: webmock
|
79
88
|
prerelease: false
|
80
89
|
requirement: &id005 !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
81
91
|
requirements:
|
82
92
|
- - ">="
|
83
93
|
- !ruby/object:Gem::Version
|
94
|
+
hash: 31
|
84
95
|
segments:
|
85
96
|
- 1
|
86
|
-
-
|
97
|
+
- 2
|
87
98
|
- 0
|
88
|
-
version: 1.
|
99
|
+
version: 1.2.0
|
89
100
|
type: :development
|
90
101
|
version_requirements: *id005
|
91
102
|
- !ruby/object:Gem::Dependency
|
92
103
|
name: bacon
|
93
104
|
prerelease: false
|
94
105
|
requirement: &id006 !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
95
107
|
requirements:
|
96
108
|
- - ">="
|
97
109
|
- !ruby/object:Gem::Version
|
110
|
+
hash: 19
|
98
111
|
segments:
|
99
112
|
- 1
|
100
113
|
- 1
|
@@ -106,14 +119,16 @@ dependencies:
|
|
106
119
|
name: bones
|
107
120
|
prerelease: false
|
108
121
|
requirement: &id007 !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
109
123
|
requirements:
|
110
124
|
- - ">="
|
111
125
|
- !ruby/object:Gem::Version
|
126
|
+
hash: 17
|
112
127
|
segments:
|
113
128
|
- 3
|
114
129
|
- 4
|
115
|
-
-
|
116
|
-
version: 3.4.
|
130
|
+
- 3
|
131
|
+
version: 3.4.3
|
117
132
|
type: :development
|
118
133
|
version_requirements: *id007
|
119
134
|
description: " super simple facebook open graph api client"
|
@@ -142,6 +157,7 @@ files:
|
|
142
157
|
- test/common.rb
|
143
158
|
- test/config/rest-graph.yaml
|
144
159
|
- test/test_load_config.rb
|
160
|
+
- test/test_oauth.rb
|
145
161
|
- test/test_rest-graph.rb
|
146
162
|
has_rdoc: true
|
147
163
|
homepage: http://github.com/cardinalblue/rest-graph
|
@@ -154,26 +170,31 @@ rdoc_options:
|
|
154
170
|
require_paths:
|
155
171
|
- lib
|
156
172
|
required_ruby_version: !ruby/object:Gem::Requirement
|
173
|
+
none: false
|
157
174
|
requirements:
|
158
175
|
- - ">="
|
159
176
|
- !ruby/object:Gem::Version
|
177
|
+
hash: 3
|
160
178
|
segments:
|
161
179
|
- 0
|
162
180
|
version: "0"
|
163
181
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
182
|
+
none: false
|
164
183
|
requirements:
|
165
184
|
- - ">="
|
166
185
|
- !ruby/object:Gem::Version
|
186
|
+
hash: 3
|
167
187
|
segments:
|
168
188
|
- 0
|
169
189
|
version: "0"
|
170
190
|
requirements: []
|
171
191
|
|
172
192
|
rubyforge_project: rest-graph
|
173
|
-
rubygems_version: 1.3.
|
193
|
+
rubygems_version: 1.3.7
|
174
194
|
signing_key:
|
175
195
|
specification_version: 3
|
176
196
|
summary: super simple facebook open graph api client
|
177
197
|
test_files:
|
178
198
|
- test/test_load_config.rb
|
199
|
+
- test/test_oauth.rb
|
179
200
|
- test/test_rest-graph.rb
|