facebook_client 0.0.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/lib/auth.rb +62 -0
- data/lib/ext.rb +58 -0
- data/lib/facebook_client.rb +47 -0
- data/lib/graph.rb +36 -0
- data/lib/rest_api.rb +42 -0
- metadata +107 -0
data/lib/auth.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'rack'
|
3
|
+
|
4
|
+
module FacebookClient
|
5
|
+
|
6
|
+
class ResponseError < StandardError; end
|
7
|
+
|
8
|
+
class Auth
|
9
|
+
|
10
|
+
def initialize(fb)
|
11
|
+
@fb=fb
|
12
|
+
end
|
13
|
+
|
14
|
+
def url(params={})
|
15
|
+
# params
|
16
|
+
# - scope
|
17
|
+
# - redirect_uri
|
18
|
+
params = params.stringify_keys
|
19
|
+
params['client_id'] = @fb.app_id
|
20
|
+
params.require_keys('redirect_uri', 'client_id')
|
21
|
+
params.assert_valid_keys('redirect_uri', 'client_id', 'scope')
|
22
|
+
connection.build_url('/oauth/authorize', params).to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
def request_access(params={})
|
26
|
+
# required params
|
27
|
+
# - code
|
28
|
+
# - redirect_uri
|
29
|
+
response = connection.get(access_token_url(params))
|
30
|
+
data = Rack::Utils.parse_query(response.body)
|
31
|
+
validate_access_token_response(data)
|
32
|
+
@fb.graph(data['access_token'], data['expires'])
|
33
|
+
end
|
34
|
+
|
35
|
+
def validate_access_token_response(data)
|
36
|
+
if !data.is_a?(Hash)
|
37
|
+
raise ResponseError, "response must be a hash"
|
38
|
+
end
|
39
|
+
data = data.stringify_keys
|
40
|
+
missing_keys = ['access_token']-data.keys
|
41
|
+
if missing_keys.size>0
|
42
|
+
raise ResponseError, "response missing key(s) #{missing_keys.join(', ')}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def access_token_url(params={})
|
47
|
+
params = params.stringify_keys
|
48
|
+
params['client_id'] = @fb.app_id
|
49
|
+
params['client_secret'] = @fb.secret
|
50
|
+
params.require_keys('redirect_uri', 'client_id', 'client_secret', 'code')
|
51
|
+
params.assert_valid_keys('redirect_uri', 'client_id', 'client_secret', 'code')
|
52
|
+
connection.build_url('/oauth/access_token', params).to_s
|
53
|
+
end
|
54
|
+
|
55
|
+
def connection
|
56
|
+
@connection ||= Faraday::Connection.new(:url => Base::GRAPH_URL) do |builder|
|
57
|
+
builder.adapter :net_http
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
data/lib/ext.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
def reverse_merge(other_hash)
|
4
|
+
other_hash.merge(self)
|
5
|
+
end
|
6
|
+
|
7
|
+
# Return a new hash with all keys converted to strings.
|
8
|
+
def stringify_keys
|
9
|
+
dup.stringify_keys!
|
10
|
+
end
|
11
|
+
|
12
|
+
# Destructively convert all keys to strings.
|
13
|
+
def stringify_keys!
|
14
|
+
keys.each do |key|
|
15
|
+
self[key.to_s] = delete(key)
|
16
|
+
end
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
# Return a new hash with all keys converted to symbols, as long as
|
21
|
+
# they respond to +to_sym+.
|
22
|
+
def symbolize_keys
|
23
|
+
dup.symbolize_keys!
|
24
|
+
end
|
25
|
+
|
26
|
+
# Destructively convert all keys to symbols, as long as they respond
|
27
|
+
# to +to_sym+.
|
28
|
+
def symbolize_keys!
|
29
|
+
keys.each do |key|
|
30
|
+
self[(key.to_sym rescue key)] = delete(key) if key.respond_to?(:to_sym) && !key.is_a?(Fixnum)
|
31
|
+
end
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
alias_method :to_options, :symbolize_keys
|
36
|
+
alias_method :to_options!, :symbolize_keys!
|
37
|
+
|
38
|
+
# Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch.
|
39
|
+
# Note that keys are NOT treated indifferently, meaning if you use strings for keys but assert symbols
|
40
|
+
# as keys, this will fail.
|
41
|
+
#
|
42
|
+
# ==== Examples
|
43
|
+
# { :name => "Rob", :years => "28" }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key(s): years"
|
44
|
+
# { :name => "Rob", :age => "28" }.assert_valid_keys("name", "age") # => raises "ArgumentError: Unknown key(s): name, age"
|
45
|
+
# { :name => "Rob", :age => "28" }.assert_valid_keys(:name, :age) # => passes, raises nothing
|
46
|
+
def assert_valid_keys(*valid_keys)
|
47
|
+
unknown_keys = keys - [valid_keys].flatten
|
48
|
+
raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") unless unknown_keys.empty?
|
49
|
+
end
|
50
|
+
|
51
|
+
def require_keys(*required_keys)
|
52
|
+
missing_keys = [required_keys].flatten - keys
|
53
|
+
if missing_keys.size>0
|
54
|
+
raise(ArgumentError, "Missing key(s): #{missing_keys.join(', ')}")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/ext'
|
2
|
+
|
3
|
+
require File.dirname(__FILE__)+'/graph'
|
4
|
+
require File.dirname(__FILE__)+'/auth'
|
5
|
+
require File.dirname(__FILE__)+'/rest_api'
|
6
|
+
|
7
|
+
module FacebookClient
|
8
|
+
|
9
|
+
class Base
|
10
|
+
|
11
|
+
GRAPH_URL = 'https://graph.facebook.com'
|
12
|
+
|
13
|
+
attr_reader :params
|
14
|
+
|
15
|
+
def initialize(default_params={})
|
16
|
+
@params = default_params.reverse_merge({
|
17
|
+
:app_id => ENV['FB_APP_ID'],
|
18
|
+
:api_key => ENV['FB_API_KEY'],
|
19
|
+
:secret => ENV['FB_SECRET'],
|
20
|
+
:canvas => ENV['FB_CANVAS'],
|
21
|
+
:callback_url => ENV['FB_CALLBACK_URL']
|
22
|
+
})
|
23
|
+
end
|
24
|
+
|
25
|
+
def auth
|
26
|
+
@auth ||= Auth.new(self)
|
27
|
+
end
|
28
|
+
|
29
|
+
def graph(token, expires=nil)
|
30
|
+
Graph.new(self,token,expires)
|
31
|
+
end
|
32
|
+
|
33
|
+
def rest_api
|
34
|
+
@rest_api ||= RestApi.new(self)
|
35
|
+
end
|
36
|
+
|
37
|
+
def method_missing(name, *args)
|
38
|
+
if @params.has_key?(name)
|
39
|
+
return @params[name]
|
40
|
+
else
|
41
|
+
super
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
data/lib/graph.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
module FacebookClient
|
4
|
+
|
5
|
+
class Graph
|
6
|
+
|
7
|
+
attr_reader :access_token
|
8
|
+
|
9
|
+
def initialize(fb, access_token, expires=nil)
|
10
|
+
@fb=fb
|
11
|
+
@access_token=access_token
|
12
|
+
if expires.nil?
|
13
|
+
expires=0
|
14
|
+
end
|
15
|
+
expires=expires.to_i
|
16
|
+
end
|
17
|
+
|
18
|
+
def get(path, params={})
|
19
|
+
params = params.stringify_keys
|
20
|
+
params['access_token'] = @access_token
|
21
|
+
resp = connection.run_request(:get, path, nil, {}) do |request|
|
22
|
+
request.params.update(params)
|
23
|
+
end
|
24
|
+
resp.body
|
25
|
+
end
|
26
|
+
|
27
|
+
def connection
|
28
|
+
@connection ||= Faraday::Connection.new(:url => Base::GRAPH_URL) do |builder|
|
29
|
+
builder.adapter :net_http
|
30
|
+
builder.response :yajl
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
data/lib/rest_api.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
module FacebookClient
|
2
|
+
|
3
|
+
class ResponseError < StandardError; end
|
4
|
+
|
5
|
+
require 'digest'
|
6
|
+
require 'faraday'
|
7
|
+
|
8
|
+
class RestApi
|
9
|
+
|
10
|
+
def initialize(fb)
|
11
|
+
@fb = fb
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(method, params={})
|
15
|
+
params[:format] = 'JSON'
|
16
|
+
params[:v] = '1.0'
|
17
|
+
params[:method] = 'facebook.' + method
|
18
|
+
params[:call_id] = Time.now.to_f.to_s
|
19
|
+
params[:timeout] ||= 8 # seconds
|
20
|
+
params[:api_key] = @fb.api_key
|
21
|
+
|
22
|
+
timeout = params.delete(:timeout)
|
23
|
+
|
24
|
+
raw_string = params.inject([]) { |args, pair| args << pair.join('=') }.sort.join
|
25
|
+
params[:sig] = Digest::MD5.hexdigest(raw_string + @fb.secret)
|
26
|
+
|
27
|
+
response = connection.post do |request|
|
28
|
+
request.body = params
|
29
|
+
end
|
30
|
+
response.body
|
31
|
+
end
|
32
|
+
|
33
|
+
def connection
|
34
|
+
@connection ||= Faraday::Connection.new(:url => 'http://api.facebook.com/restserver.php') do |builder|
|
35
|
+
builder.adapter :net_http
|
36
|
+
builder.response :yajl
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: facebook_client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- David Crockett
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-05-13 00:00:00 -07:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: faraday
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 4
|
30
|
+
- 5
|
31
|
+
version: 0.4.5
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: yajl-ruby
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
- 7
|
44
|
+
- 6
|
45
|
+
version: 0.7.6
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rack
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 1
|
57
|
+
- 0
|
58
|
+
- 1
|
59
|
+
version: 1.0.1
|
60
|
+
type: :runtime
|
61
|
+
version_requirements: *id003
|
62
|
+
description: Facebook Client
|
63
|
+
email: davy@davcro.com
|
64
|
+
executables: []
|
65
|
+
|
66
|
+
extensions: []
|
67
|
+
|
68
|
+
extra_rdoc_files: []
|
69
|
+
|
70
|
+
files:
|
71
|
+
- lib/auth.rb
|
72
|
+
- lib/ext.rb
|
73
|
+
- lib/facebook_client.rb
|
74
|
+
- lib/graph.rb
|
75
|
+
- lib/rest_api.rb
|
76
|
+
has_rdoc: true
|
77
|
+
homepage:
|
78
|
+
licenses: []
|
79
|
+
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
segments:
|
90
|
+
- 0
|
91
|
+
version: "0"
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
segments:
|
97
|
+
- 0
|
98
|
+
version: "0"
|
99
|
+
requirements: []
|
100
|
+
|
101
|
+
rubyforge_project:
|
102
|
+
rubygems_version: 1.3.6
|
103
|
+
signing_key:
|
104
|
+
specification_version: 3
|
105
|
+
summary: Facebook Client
|
106
|
+
test_files: []
|
107
|
+
|