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.
@@ -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