f00px 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Arthur Neves
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,40 @@
1
+ # F00px
2
+
3
+ 500px api ruby gem
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'f00px'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install f00px
18
+
19
+ ## Usage
20
+
21
+ Add this code to some initializer:
22
+
23
+ F00px.configure do |config|
24
+ config.consumer_key = __consumer_key__
25
+ config.consumer_secret = __consumer_secret__
26
+ config.token = __token__
27
+ config.token_secret = __token_secret__
28
+ end
29
+
30
+ Then just use the api:
31
+
32
+ response = F00px.get('/users/1')
33
+
34
+ ## Contributing
35
+
36
+ 1. Fork it
37
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
38
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
39
+ 4. Push to the branch (`git push origin my-new-feature`)
40
+ 5. Create new Pull Request
@@ -0,0 +1,35 @@
1
+ require "bundler"
2
+ Bundler.setup
3
+
4
+ require "rake"
5
+ require "rspec/core/rake_task"
6
+
7
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
8
+ require "f00px/version"
9
+
10
+ task :gem => :build
11
+ task :build do
12
+ system "gem build f00px.gemspec"
13
+ end
14
+
15
+ task :install => :build do
16
+ system "gem install f00px-#{F00px::VERSION}.gem"
17
+ end
18
+
19
+ task :release => :build do
20
+ system "git tag -a v#{F00px::VERSION} -m 'Tagging #{F00px::VERSION}'"
21
+ system "git push --tags"
22
+ system "gem push f00px-#{F00px::VERSION}.gem"
23
+ system "rm f00px-#{F00px::VERSION}.gem"
24
+ end
25
+
26
+ RSpec::Core::RakeTask.new("spec") do |spec|
27
+ spec.pattern = "spec/**/*_spec.rb"
28
+ end
29
+
30
+ RSpec::Core::RakeTask.new('spec:progress') do |spec|
31
+ spec.rspec_opts = %w(--format progress)
32
+ spec.pattern = "spec/**/*_spec.rb"
33
+ end
34
+
35
+ task :default => :spec
@@ -0,0 +1,33 @@
1
+ require "f00px/version"
2
+ require "cgi"
3
+ require "faraday_middleware"
4
+ require "typhoeus"
5
+ require "typhoeus/adapters/faraday"
6
+ require "f00px/error"
7
+ require "f00px/authentication"
8
+ require "f00px/configuration"
9
+ require "f00px/connection"
10
+ require "f00px/request"
11
+ require "f00px/client"
12
+
13
+ module F00px
14
+
15
+ class << self
16
+
17
+ include Configuration
18
+
19
+ def client
20
+ @client ||= F00px::Client.new
21
+ end
22
+
23
+ private
24
+
25
+ def method_missing(method_name, *args, &block)
26
+ return super unless client.respond_to?(method_name)
27
+ client.send(method_name, *args, &block)
28
+ end
29
+
30
+ end
31
+
32
+
33
+ end
@@ -0,0 +1,36 @@
1
+ module F00px
2
+ module Authentication
3
+
4
+ def xauth(username, password)
5
+ unless token? && token_secret?
6
+ begin
7
+ response = post('oauth/request_token')
8
+ parse_oauth_response(response)
9
+
10
+ params = { x_auth_mode: "client_auth", x_auth_username: username, x_auth_password: password}
11
+ response = post("oauth/access_token", params)
12
+ parse_oauth_response(response)
13
+ rescue F00px::Error => e
14
+ self.token = self.token_secret = nil
15
+ raise e
16
+ end
17
+ end
18
+ end
19
+
20
+ private
21
+ def parse_oauth_response(response)
22
+ unless response.status == 200
23
+ raise F00px::Error.from_response(response)
24
+ end
25
+
26
+ hash = CGI.parse(response.body).inject({}) do |h, (k,v)|
27
+ h[k.strip.to_sym] = v.first
28
+ h
29
+ end
30
+
31
+ self.token = hash[:oauth_token]
32
+ self.token_secret = hash[:oauth_token_secret]
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,21 @@
1
+ module F00px
2
+
3
+ class Client
4
+ include Authentication
5
+ include Configuration
6
+ include Connection
7
+ include Request
8
+
9
+ def self.configure(&block)
10
+ Client.new.configure(&block)
11
+ end
12
+
13
+ def initialize(options = {})
14
+ F00px::Configuration.options.each do |key|
15
+ settings[key] = options[key] || F00px.__send__("#{key}".to_sym)
16
+ end
17
+ end
18
+
19
+
20
+ end
21
+ end
@@ -0,0 +1,35 @@
1
+ require "f00px/configuration/options"
2
+
3
+ module F00px
4
+ module Configuration
5
+ extend self
6
+ include Options
7
+
8
+ option :endpoint, default: 'https://api.500px.com'
9
+ option :api_version, default: 'v1'
10
+ option :middleware, default: ::FaradayMiddleware::OAuth
11
+ option :consumer_key
12
+ option :consumer_secret
13
+ option :token
14
+ option :token_secret
15
+ option :logger
16
+ option :user_id
17
+
18
+ def self.included(base)
19
+ end
20
+
21
+ def configure
22
+ yield(self) if block_given?
23
+ self
24
+ end
25
+
26
+ def credentials
27
+ { :consumer_key => consumer_key,
28
+ :consumer_secret => consumer_secret,
29
+ :token => token,
30
+ :token_secret => token_secret
31
+ }
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,48 @@
1
+ module F00px
2
+ module Configuration
3
+ module Options
4
+
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+
11
+ def defaults
12
+ @defaults ||= {}
13
+ end
14
+
15
+ def options
16
+ self.defaults.keys
17
+ end
18
+
19
+ def option(name, options = {})
20
+ self.defaults[name] = options[:default]
21
+
22
+ class_eval <<-RUBY
23
+ def #{name}
24
+ settings['#{name}'.to_sym] || #{self}.defaults['#{name}'.to_sym]
25
+ end
26
+
27
+ def #{name}=(value)
28
+ settings['#{name}'.to_sym] = value
29
+ end
30
+
31
+ def #{name}?
32
+ !!#{name}
33
+ end
34
+ RUBY
35
+ end
36
+
37
+ end
38
+
39
+ def reset
40
+ settings.replace(defaults)
41
+ end
42
+
43
+ def settings
44
+ @settings ||= {}
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,40 @@
1
+ module F00px
2
+ module Connection
3
+
4
+ def connection
5
+ options = {
6
+ headers: {'Accept' => "application/json"},
7
+ url: "#{endpoint}/#{api_version}"
8
+ }
9
+
10
+ Faraday.new(options) do |builder|
11
+
12
+ if middleware?
13
+ args = Array(middleware)
14
+ if args.first == ::FaradayMiddleware::OAuth
15
+ tokens = credentials.dup
16
+ tokens.merge!(args.last) if args.length > 1
17
+ builder.use(args.first, tokens)
18
+ else
19
+ builder.use(*middleware)
20
+ end
21
+ end
22
+
23
+ builder.request :url_encoded
24
+
25
+ # builder.response :json, content_type: /\bjson$/
26
+
27
+ builder.use Faraday::Response::Logger, logger if logger?
28
+
29
+ builder.adapter connection_adapter
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def connection_adapter
36
+ :typhoeus
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,36 @@
1
+ module F00px
2
+ class Error < StandardError
3
+
4
+ class << self
5
+
6
+ def register_error(error)
7
+ @errors ||= {}
8
+ @errors[error::STATUS_CODE] = error
9
+ end
10
+
11
+ def from_response(response)
12
+ klass = @errors[response.status] || self
13
+ klass.new(parse_error(response.body))
14
+ end
15
+
16
+ def parse_error(body)
17
+ return body if body.is_a? String
18
+ if body.nil?
19
+ ''
20
+ elsif body[:error]
21
+ body[:error]
22
+ elsif body[:errors]
23
+ first = Array(body[:errors]).first
24
+ if first.is_a?(Hash)
25
+ first[:message].chomp
26
+ else
27
+ first.chomp
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ require 'f00px/error/forbidden'
36
+ require 'f00px/error/unauthorized'
@@ -0,0 +1,10 @@
1
+ module F00px
2
+ class Error
3
+
4
+ class Forbidden < F00px::Error
5
+ STATUS_CODE = 403
6
+ end
7
+
8
+ register_error(Forbidden)
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ module F00px
2
+ class Error
3
+
4
+ class Unauthorized < F00px::Error
5
+ STATUS_CODE = 401
6
+ end
7
+
8
+ register_error(Unauthorized)
9
+
10
+ end
11
+ end
@@ -0,0 +1,32 @@
1
+ require 'f00px/request/callback'
2
+ require 'f00px/request/runner'
3
+
4
+ module F00px
5
+ module Request
6
+
7
+ def queue(&block)
8
+ queue = Request::Runner.new(connection)
9
+ queue.user_id = user_id if user_id?
10
+ queue.consumer_key = consumer_key if consumer_key?
11
+ yield(queue)
12
+ queue.run!
13
+ end
14
+
15
+ def get(url, params = {})
16
+ queue do |q|
17
+ q.get(url, params).complete do |response|
18
+ return response
19
+ end
20
+ end
21
+ end
22
+
23
+ def post(url, params = {})
24
+ queue do |q|
25
+ q.post(url, params).complete do |response|
26
+ return response
27
+ end
28
+ end
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,70 @@
1
+ module F00px
2
+ module Request
3
+ class Callback
4
+
5
+ attr_reader :method, :url, :params
6
+
7
+ def initialize(method, url, params={})
8
+ @method, @url, @params = [method, url, params]
9
+ end
10
+
11
+ def info
12
+ [method, url, params]
13
+ end
14
+
15
+ def perform(response)
16
+ if response.status != 200
17
+ on_error!(response)
18
+ else
19
+ on_success!(response)
20
+ end
21
+
22
+ on_complete!(response)
23
+ end
24
+
25
+ # Registers an error callback. The callback will be executed if any 400 or 500 HTTP status is returned.
26
+ #
27
+ # PxApi.get('/photos').
28
+ # error{|res| puts "HTTP Status: #{res.status}" }
29
+ def error(&block)
30
+ @on_error = block
31
+ self
32
+ end
33
+ alias_method :on_error, :error
34
+
35
+ # Registers a success callback. This will be triggered if the status code is not 4xx or 5xx.
36
+ def success(&block)
37
+ @on_success = block
38
+ self
39
+ end
40
+ alias_method :on_success, :success
41
+
42
+ # Register a complete callback. This will be triggered after success or error on all requests.
43
+ def complete(&block)
44
+ @on_complete = block
45
+ self
46
+ end
47
+ alias_method :on_complete, :complete
48
+
49
+ private
50
+
51
+ def on_error!(response)
52
+ if @on_error.respond_to?(:call)
53
+ @on_error.call response
54
+ end
55
+ end
56
+
57
+ def on_success!(response)
58
+ if @on_success.respond_to?(:call)
59
+ @on_success.call response
60
+ end
61
+ end
62
+
63
+ def on_complete!(response)
64
+ if @on_complete.respond_to?(:call)
65
+ @on_complete.call response
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,56 @@
1
+ module F00px
2
+ module Request
3
+ class Runner
4
+ attr_accessor :user_id, :consumer_key
5
+
6
+ def initialize(conn)
7
+ @queued_requests = []
8
+ @connection = conn
9
+ end
10
+
11
+ def get(url, params={})
12
+ request(:get, url, params)
13
+ end
14
+
15
+ # Queues a POST request
16
+ def post(url, params={})
17
+ request(:post, url, params)
18
+ end
19
+
20
+ def request(method, url, params = {})
21
+ params = params.dup
22
+ params[:consumer_key] = consumer_key
23
+
24
+ Callback.new(method, url, params).tap do |r|
25
+ @queued_requests << r
26
+ end
27
+ end
28
+
29
+ # Runs all queued requests. This method will block until all requests are complete.
30
+ # As requests complete their callbacks will be executed.
31
+ def run!
32
+ conn = @connection
33
+
34
+ responses = {}
35
+ conn.in_parallel do
36
+ @queued_requests.each do |callback|
37
+ method, url, params = callback.info
38
+ params ||= {}
39
+ params[:auth_user_id] = user_id if user_id
40
+
41
+ response = conn.run_request(method, url, params, {})
42
+
43
+ response.on_complete do
44
+ callback.perform(response)
45
+ end
46
+
47
+ end
48
+ end
49
+
50
+ ensure
51
+ @queued_requests = []
52
+ end
53
+
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,3 @@
1
+ module F00px
2
+ VERSION = "0.3.0"
3
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: f00px
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Arthur Neves
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: faraday_middleware
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.9.0
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.9.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: typhoeus
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.5.4
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.5.4
46
+ - !ruby/object:Gem::Dependency
47
+ name: simple_oauth
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 0.2.0
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.2.0
62
+ description: ''
63
+ email:
64
+ - arthurnn@gmail.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - lib/f00px/authentication.rb
70
+ - lib/f00px/client.rb
71
+ - lib/f00px/configuration/options.rb
72
+ - lib/f00px/configuration.rb
73
+ - lib/f00px/connection.rb
74
+ - lib/f00px/error/forbidden.rb
75
+ - lib/f00px/error/unauthorized.rb
76
+ - lib/f00px/error.rb
77
+ - lib/f00px/request/callback.rb
78
+ - lib/f00px/request/runner.rb
79
+ - lib/f00px/request.rb
80
+ - lib/f00px/version.rb
81
+ - lib/f00px.rb
82
+ - LICENSE
83
+ - README.md
84
+ - Rakefile
85
+ homepage: ''
86
+ licenses: []
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '1.9'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: 1.3.6
103
+ requirements: []
104
+ rubyforge_project: f00px
105
+ rubygems_version: 1.8.24
106
+ signing_key:
107
+ specification_version: 3
108
+ summary: 500px api rubygem
109
+ test_files: []