facebook_client 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+