f00px 0.3.0

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/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: []