facebook-client 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,16 @@
1
+ # Ignore the _creds.rb spec file
2
+ spec/_creds.rb
3
+
4
+ # Ignore tempfiles
5
+ *.sw[op]
6
+ .DS_Store
7
+
8
+ # RVM
9
+ .rvmrc
10
+
11
+ # Gems
12
+ *.gem
13
+
14
+ # IDEs
15
+ .idea
16
+ .project
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --color
2
+ --backtrace
3
+ --require rspec/instafail
4
+ --format RSpec::Instafail
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'https://rubygems.org'
2
+
3
+ #gem 'saddle', :path => '../saddle'
4
+ gem 'saddle', '~> 0.0.38'
5
+
6
+ group :test do
7
+ gem 'rspec', '~> 2.14.1'
8
+ gem 'rspec-instafail', '~> 0.2'
9
+ end
10
+
11
+ group :development, :test do
12
+ gem 'pry'
13
+ end
@@ -0,0 +1,51 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ activesupport (4.0.0)
5
+ i18n (~> 0.6, >= 0.6.4)
6
+ minitest (~> 4.2)
7
+ multi_json (~> 1.3)
8
+ thread_safe (~> 0.1)
9
+ tzinfo (~> 0.3.37)
10
+ atomic (1.1.10)
11
+ coderay (1.0.9)
12
+ diff-lcs (1.2.4)
13
+ faraday (0.8.8)
14
+ multipart-post (~> 1.2.0)
15
+ faraday_middleware (0.9.0)
16
+ faraday (>= 0.7.4, < 0.9)
17
+ i18n (0.6.4)
18
+ method_source (0.8.2)
19
+ minitest (4.7.5)
20
+ multi_json (1.7.7)
21
+ multipart-post (1.2.0)
22
+ pry (0.9.12.2)
23
+ coderay (~> 1.0.5)
24
+ method_source (~> 0.8)
25
+ slop (~> 3.4)
26
+ rspec (2.14.1)
27
+ rspec-core (~> 2.14.0)
28
+ rspec-expectations (~> 2.14.0)
29
+ rspec-mocks (~> 2.14.0)
30
+ rspec-core (2.14.4)
31
+ rspec-expectations (2.14.0)
32
+ diff-lcs (>= 1.1.3, < 2.0)
33
+ rspec-instafail (0.2.4)
34
+ rspec-mocks (2.14.1)
35
+ saddle (0.0.38)
36
+ activesupport (>= 3.0)
37
+ faraday (~> 0.8.7)
38
+ faraday_middleware (~> 0.9.0)
39
+ slop (3.4.6)
40
+ thread_safe (0.1.2)
41
+ atomic
42
+ tzinfo (0.3.37)
43
+
44
+ PLATFORMS
45
+ ruby
46
+
47
+ DEPENDENCIES
48
+ pry
49
+ rspec (~> 2.14.1)
50
+ rspec-instafail (~> 0.2)
51
+ saddle (~> 0.0.38)
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2013, Airbnb
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
@@ -0,0 +1,17 @@
1
+ # Ruby Facebook OAuth2 client
2
+
3
+
4
+ ## Usage
5
+
6
+ client = Facebook::Client.create(
7
+ :oauth2_access_token => YOUR_USER_ACCESS_TOKEN
8
+ )
9
+ user = client.people.me
10
+ user = client.people.by_id(123)
11
+
12
+ data = client.fql.query('SELECT name FROM user WHERE uid = me()')
13
+
14
+
15
+ ## License
16
+ (c) Airbnb 2013
17
+ Released under the [MIT License](http://www.opensource.org/licenses/MIT).
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/facebook-client/version', __FILE__)
3
+
4
+ lib = File.expand_path('../lib', __FILE__)
5
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = 'facebook-client'
9
+ s.version = ::Facebook::VERSION
10
+ s.authors = ['Mike Lewis']
11
+ s.email = ['mike.lewis@airbnb.com']
12
+ s.description = %q{Facebook OAuth2 client}
13
+ s.summary = %q{
14
+ This is a Facebook OAuth2 client implemented on Saddle
15
+ }
16
+ s.homepage = 'https://github.com/airbnb/facebook-client'
17
+ s.license = 'MIT'
18
+
19
+ s.require_path = 'lib'
20
+ s.files = `git ls-files`.split($\)
21
+ s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
22
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
23
+
24
+ s.add_dependency 'saddle', '~> 0.0.38'
25
+ end
@@ -0,0 +1,42 @@
1
+ require 'saddle'
2
+ require 'saddle/middleware/authentication/oauth2'
3
+
4
+ require 'facebook-client/exceptions'
5
+ require 'facebook-client/middleware/exception_raiser'
6
+ require 'facebook-client/version'
7
+
8
+
9
+
10
+ module Facebook
11
+
12
+ class Client < Saddle::Client
13
+
14
+ def self.host
15
+ 'graph.facebook.com'
16
+ end
17
+
18
+ def self.use_ssl
19
+ true
20
+ end
21
+
22
+ def self.num_retries
23
+ 1
24
+ end
25
+
26
+ def self.timeout
27
+ 5 # seconds
28
+ end
29
+
30
+
31
+ add_middleware({
32
+ :klass => Middleware::ExceptionRaiser,
33
+ })
34
+
35
+ add_middleware({
36
+ :klass => Saddle::Middleware::Authentication::OAuth2,
37
+ :args => ['access_token'],
38
+ })
39
+
40
+ end
41
+
42
+ end
@@ -0,0 +1,17 @@
1
+ require 'saddle/endpoint'
2
+
3
+
4
+
5
+ module Facebook
6
+ module Endpoints
7
+
8
+ class FQL < Saddle::TraversalEndpoint
9
+
10
+ def query(q, opts = {})
11
+ get(nil, {'q' => q}, opts)['data']
12
+ end
13
+
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,33 @@
1
+ require 'saddle/endpoint'
2
+
3
+
4
+
5
+ module Facebook
6
+ module Endpoints
7
+
8
+ class User < Saddle::TraversalEndpoint
9
+
10
+ ABSOLUTE_PATH = ''
11
+
12
+ def me(opts = {})
13
+ by_id('me', opts)
14
+ end
15
+
16
+ def by_id(_id, opts = {})
17
+ get(_id, opts_to_params(opts), opts)
18
+ end
19
+
20
+
21
+ private
22
+
23
+ # Put useful params out of the opts
24
+ def opts_to_params(opts)
25
+ params = {}
26
+ params['fields'] = opts[:fields].map(&:to_s).join(',') if opts[:fields]
27
+ params
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,86 @@
1
+
2
+ ##
3
+ # Exceptions for using the Facebook client
4
+ # It is recommended that you handle these.
5
+ ##
6
+
7
+ module Facebook
8
+
9
+ class GenericException < StandardError; end
10
+
11
+ class TimeoutError < GenericException; end
12
+
13
+ # Some problems might take care of themselves if you try again later. Others won't.
14
+ class TemporaryError < GenericException; end # fire warnings on these
15
+ class PermanentError < GenericException; end # fire errors on these
16
+
17
+
18
+ # Error codes are based upon:
19
+ # http://fbdevwiki.com/wiki/Error_codes#Error_Code_Table
20
+
21
+ # And for the record, this page is LIES:
22
+ # https://developers.facebook.com/docs/reference/api/errors/
23
+ # Do not trust it.
24
+
25
+ # (0-99) General Errors
26
+ class GeneralError < GenericException; end
27
+ ## (2) Service temporarily unavailable
28
+ class ServiceError < GeneralError; end
29
+ ## (3) Unknown method
30
+ class UnknownMethodError < GeneralError; end
31
+ ## (4, 18) Application request limit reached
32
+ class RequestLimitError < GeneralError; end
33
+ ## (9, 17) User is performing too many actions
34
+ class UserRequestLimitError < RequestLimitError; end
35
+ ## (10) Application does not have permission for this action
36
+ class ApplicationPermissionError < GeneralError; end
37
+ ## (11) This method is deprecated
38
+ class MethodDeprecatedError < GeneralError; end
39
+
40
+ # (100-199) Parameter Errors
41
+ class ParameterError < GenericException; end
42
+ ## (101) Invalid API key
43
+ class InvalidAPIKeyError < ParameterError; end
44
+ ## (102) Session key invalid or no longer valid
45
+ class InvalidSessionKeyError < ParameterError; end
46
+ ## (190) Invalid OAuth 2.0 Access Token
47
+ class InvalidAccessTokenError < ParameterError; end
48
+
49
+ # (200-299) User Permission Errors
50
+ class UserPermissionError < GenericException; end
51
+ ## (200) Permissions error
52
+ class PermissionError < UserPermissionError; end
53
+ ## (210) User not visible
54
+ class UserNotVisibleError < UserPermissionError; end
55
+ ## (212) Renewing a session offline requires the extended permission offline_access
56
+ class OfflineAccessPermissionError < UserPermissionError; end
57
+
58
+ # (300-399) Data Editing Errors
59
+ class DataEditingError < GenericException; end
60
+
61
+ # (400-449) Authentication Errors
62
+ class AuthenticationError < GenericException; end
63
+
64
+ # (450-455) Session Errors
65
+ class SessionError < GenericException; end
66
+
67
+ # (500-599) Application Messaging Errors
68
+ class ApplicationMessagingError < GenericException; end
69
+
70
+ # (600-699) FQL Errors
71
+ class FQLError < GenericException; end
72
+
73
+ # (700-749) Ref Errors
74
+ class RefError < GenericException; end
75
+
76
+ # (750-799) Application Integration Errors
77
+ class ApplicationIntegrationError < GenericException; end
78
+
79
+ # (900-949) Application Information Errors
80
+ class ApplicationInformationError < GenericException; end
81
+
82
+ # (950-999) Batch API Errors
83
+ class BatchAPIError < GenericException; end
84
+
85
+ # ... There's more. Include when needed.
86
+ end
@@ -0,0 +1,97 @@
1
+ require 'faraday'
2
+
3
+ require 'facebook-client/exceptions'
4
+
5
+
6
+
7
+ module Facebook
8
+ module Middleware
9
+
10
+ ## Raise beautiful exceptions
11
+ #
12
+ class ExceptionRaiser < Faraday::Middleware
13
+
14
+ ## For handling errors, the message that gets returned is of the following format:
15
+ # {:status => env[:status], :headers => env[:response_headers], :body => env[:body]}
16
+
17
+ def call(env)
18
+ begin
19
+ @app.call(env)
20
+ rescue Faraday::Error::ClientError => e
21
+ # Error codes are based upon:
22
+ # http://fbdevwiki.com/wiki/Error_codes#Error_Code_Table
23
+ fb_error_code = e.response[:body].try(:[], 'error').try(:[], 'code')
24
+
25
+ # Translate our error code into an exception
26
+ exception =
27
+ case fb_error_code
28
+ ## (0-99) General Errors
29
+ when 2
30
+ Facebook::ServiceError
31
+ when 3
32
+ Facebook::UnknownMethodError
33
+ when 4, 18, 9, 17
34
+ Facebook::RequestLimitError
35
+ when 10
36
+ Facebook::ApplicationPermissionError
37
+ when 11
38
+ Facebook::MethodDeprecatedError
39
+ when 0..99
40
+ Facebook::GeneralError
41
+ ## (100-199) Parameter Errors
42
+ when 101
43
+ Facebook::InvalidAPIKeyError
44
+ when 102
45
+ Facebook::InvalidSessionKeyError
46
+ when 190
47
+ Facebook::InvalidAccessTokenError
48
+ when 100..199
49
+ Facebook::ParameterError
50
+ ## (200-299) User Permission Errors
51
+ when 200
52
+ Facebook::PermissionError
53
+ when 212
54
+ Facebook::OfflineAccessPermissionError
55
+ when 200..299
56
+ Facebook::UserPermissionError
57
+ ## (300-399) Data Editing Errors
58
+ when 300..399
59
+ Facebook::DataEditingError
60
+ ## (400-449) Authentication Errors
61
+ when 400..449
62
+ Facebook::AuthenticationError
63
+ ## (450-455) Session Errors
64
+ when 450..455
65
+ Facebook::SessionError
66
+ ## (500-599) Application Messaging Errors
67
+ when 500..599
68
+ Facebook::ApplicationMessagingError
69
+ ## (600-699) FQL Errors
70
+ when 600..699
71
+ Facebook::FQLError
72
+ ## (700-749) Ref Errors
73
+ when 700..749
74
+ Facebook::RefError
75
+ ## (750-799) Application Integration Errors
76
+ when 750..799
77
+ Facebook::ApplicationIntegrationError
78
+ ## (900-949) Application Information Errors
79
+ when 900..949
80
+ Facebook::ApplicationInformationError
81
+ ## (950-999) Batch API Errors
82
+ when 950..999
83
+ Facebook::BatchAPIError
84
+ else
85
+ Facebook::GenericException
86
+ end
87
+
88
+ raise exception, e.response
89
+ rescue Saddle::TimeoutError => e
90
+ raise Facebook::TimeoutError, e.response
91
+ end
92
+ end
93
+
94
+ end
95
+
96
+ end
97
+ end
@@ -0,0 +1,3 @@
1
+ module Facebook
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1 @@
1
+ TEST_ACCESS_TOKEN = 'XXX_YOUR_OAUTH2_ACCESS_TOKEN_XXX'
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ ###
5
+ # NOTE: This spec will actually hit Facebook's servers
6
+ ###
7
+
8
+ describe 'Facebook::Endpoints::FQL' do
9
+ context "Test integration of FQL endpoints" do
10
+
11
+ # Skip if the creds aren't setup
12
+ if defined?(TEST_ACCESS_TOKEN)
13
+
14
+ before :each do
15
+ @client = Facebook::Client.create(:access_token => TEST_ACCESS_TOKEN)
16
+ end
17
+
18
+ it 'should get self info' do
19
+ @client.fql.query('SELECT name FROM user WHERE uid = me()').should_not be_nil
20
+ end
21
+
22
+ else
23
+ puts "You should put valid creds in _creds.rb"
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ ###
5
+ # NOTE: This spec will actually hit Facebook's servers
6
+ ###
7
+
8
+ describe 'Facebook::Endpoints::User' do
9
+ context "Test integration of user endpoints" do
10
+
11
+ # Skip if the creds aren't setup
12
+ if defined?(TEST_ACCESS_TOKEN)
13
+
14
+ before :each do
15
+ @client = Facebook::Client.create(:access_token => TEST_ACCESS_TOKEN)
16
+ end
17
+
18
+ it 'should get self profile' do
19
+ @client.user.me.should be_a(Hash)
20
+ end
21
+
22
+ else
23
+ puts "You should put valid creds in _creds.rb"
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe Facebook::Middleware::ExceptionRaiser do
5
+
6
+ describe "Test raising various exceptions using stubs" do
7
+
8
+ before :each do
9
+ @stubs = Faraday::Adapter::Test::Stubs.new
10
+ @client = Facebook::Client.create(:stubs => @stubs)
11
+ end
12
+
13
+
14
+ it 'should detect a service error' do
15
+ @stubs.get('/') { [ 400, {}, { 'error' => { 'code' => 2 } } ] }
16
+ expect { @client.requester.get('') }.to raise_error(Facebook::ServiceError)
17
+ end
18
+
19
+ it 'should detect throttling' do
20
+ @stubs.get('/') { [ 400, {}, { 'error' => { 'code' => 9 } } ] }
21
+ expect { @client.requester.get('') }.to raise_error(Facebook::RequestLimitError)
22
+ end
23
+
24
+ it 'should detect invalid access tokens' do
25
+ @stubs.get('/') { [ 400, {}, { 'error' => { 'code' => 190 } } ] }
26
+ expect { @client.requester.get('') }.to raise_error(Facebook::InvalidAccessTokenError)
27
+ end
28
+
29
+ it 'should detect permission errors' do
30
+ @stubs.get('/') { [ 400, {}, { 'error' => { 'code' => 200 } } ] }
31
+ expect { @client.requester.get('') }.to raise_error(Facebook::PermissionError)
32
+ end
33
+
34
+ it 'should detect offline access permission errors' do
35
+ @stubs.get('/') { [ 400, {}, { 'error' => { 'code' => 212 } } ] }
36
+ expect { @client.requester.get('') }.to raise_error(Facebook::OfflineAccessPermissionError)
37
+ end
38
+
39
+ it 'should detect general user permission errors' do
40
+ @stubs.get('/') { [ 400, {}, { 'error' => { 'code' => 249 } } ] }
41
+ expect { @client.requester.get('') }.to raise_error(Facebook::UserPermissionError)
42
+ end
43
+
44
+ it 'should detect FQL errors' do
45
+ @stubs.get('/') { [ 400, {}, { 'error' => { 'code' => 600 } } ] }
46
+ expect { @client.requester.get('') }.to raise_error(Facebook::FQLError)
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -0,0 +1,13 @@
1
+ require 'facebook-client'
2
+
3
+
4
+ # Load credentials from ENV if possible, or load from _creds.rb
5
+ if ENV['TEST_ACCESS_TOKEN']
6
+ TEST_ACCESS_TOKEN = ENV['TEST_ACCESS_TOKEN']
7
+ else
8
+ begin
9
+ require '_creds'
10
+ rescue LoadError
11
+ puts "Using _creds.stub.rb, create a _creds.rb with actual credentials for a live test."
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: facebook-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mike Lewis
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-07-31 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: saddle
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.0.38
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.0.38
30
+ description: Facebook OAuth2 client
31
+ email:
32
+ - mike.lewis@airbnb.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - .gitignore
38
+ - .rspec
39
+ - Gemfile
40
+ - Gemfile.lock
41
+ - LICENSE
42
+ - README.md
43
+ - facebook-client.gemspec
44
+ - lib/facebook-client.rb
45
+ - lib/facebook-client/endpoints/fql.rb
46
+ - lib/facebook-client/endpoints/user.rb
47
+ - lib/facebook-client/exceptions.rb
48
+ - lib/facebook-client/middleware/exception_raiser.rb
49
+ - lib/facebook-client/version.rb
50
+ - spec/_creds.stub.rb
51
+ - spec/integration/fql_spec.rb
52
+ - spec/integration/user_spec.rb
53
+ - spec/middleware/exception_raiser_spec.rb
54
+ - spec/spec_helper.rb
55
+ homepage: https://github.com/airbnb/facebook-client
56
+ licenses:
57
+ - MIT
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubyforge_project:
76
+ rubygems_version: 1.8.25
77
+ signing_key:
78
+ specification_version: 3
79
+ summary: This is a Facebook OAuth2 client implemented on Saddle
80
+ test_files:
81
+ - spec/_creds.stub.rb
82
+ - spec/integration/fql_spec.rb
83
+ - spec/integration/user_spec.rb
84
+ - spec/middleware/exception_raiser_spec.rb
85
+ - spec/spec_helper.rb