ebayr 0.0.4 → 0.0.5

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c6a8d014c48da465ef9813378975e782f1b64728
4
+ data.tar.gz: 1bcc92d6f405c47d8935a036f32a1023640a2aa6
5
+ SHA512:
6
+ metadata.gz: 35164d75bf6bcd6fc85e6d8754086bad689333df0489e9d613300f5fe7bda8cb8eaa72afcf0806db6fb8cc9762a645a8ae98dc53aa6e151d24f50f1cc1825aec
7
+ data.tar.gz: 7d92802f8b38331c70196e349c75b9f794533ba8451c4b58eba94fd37d4bb56d59a069a272e193546ae70ad4ea314dbccf4e1e305d2436b12992e6b301cded75
data/.gitignore CHANGED
@@ -15,4 +15,5 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ .ebayr.conf
18
19
  *.sw?
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 1.9.3
5
+ - 1.8.7
data/Guardfile ADDED
@@ -0,0 +1,8 @@
1
+ # -*- encoding : utf-8 -*-
2
+ guard :test do
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
4
+ watch(%r{^test/(.+)_test\.rb$}) { |m| "test/#{m[1]}_test.rb" }
5
+ watch('test/test_helper.rb') { "test" }
6
+ end
7
+
8
+ # vi:ft=ruby
data/README.md CHANGED
@@ -29,28 +29,28 @@ stuff - look at the [eBay developer docs][1] for details).
29
29
  ```ruby
30
30
  require 'ebayr'
31
31
 
32
- Ebay.dev_id = "my-dev-id"
32
+ Ebayr.dev_id = "my-dev-id"
33
33
 
34
34
  # This is only needed if you want to retrieve user tokens
35
- Ebay.authorization_callback_url = "https://my-site/callback-url"
35
+ Ebayr.authorization_callback_url = "https://my-site/callback-url"
36
36
 
37
- Ebay.auth_token = "myverylongebayauthtoken"
37
+ Ebayr.auth_token = "myverylongebayauthtoken"
38
38
 
39
- Ebay.app_id = "my-ebay-app-id"
39
+ Ebayr.app_id = "my-ebay-app-id"
40
40
 
41
- Ebay.cert_id = "my-ebay-cert-id"
41
+ Ebayr.cert_id = "my-ebay-cert-id"
42
42
 
43
- Ebay.ru_name = "my-ebay-ru-name"
43
+ Ebayr.ru_name = "my-ebay-ru-name"
44
44
 
45
45
  # Set this to true for testing in the eBay Sandbox (but remember to use the
46
46
  # appropriate keys!). It's true by default.
47
- Ebay.sandbox = false
47
+ Ebayr.sandbox = false
48
48
  ```
49
49
 
50
50
  Now you're ready to make calls
51
-
52
51
  ```ruby
53
52
  Ebayr.call(:GeteBayOfficialTime)
53
+ session = Ebayr.call(:GetSessionID, :RuName => Ebayr.ru_name)[:SessionID]
54
54
  ```
55
55
 
56
56
  To use an authorized user's key, pass in an `auth_token` parameter
@@ -58,6 +58,7 @@ To use an authorized user's key, pass in an `auth_token` parameter
58
58
  Ebayr.call(:GetOrders, :auth_token => "another-ebay-auth-token")
59
59
  ```
60
60
 
61
+
61
62
  ### Configuration
62
63
 
63
64
  Ebayr will look for the following Ruby files, and load them *once* in order (if
@@ -78,6 +79,8 @@ repository.
78
79
 
79
80
  ## Testing
80
81
 
82
+ [![Status](https://travis-ci.org/bjjb/ebayr.png?branch=master)](https://travis-ci.org/bjjb/ebayr)
83
+
81
84
  When running test, you generally won't want to use up your API call-limit too
82
85
  quickly, so it makes sense to stub out calls to the eBay API.
83
86
 
data/Rakefile CHANGED
@@ -1,10 +1,12 @@
1
1
  #!/usr/bin/env rake
2
+ # -*- encoding : utf-8 -*-
3
+
2
4
  require "bundler/gem_tasks"
3
5
  require "rake/testtask"
4
6
 
5
7
  Rake::TestTask.new do |t|
6
8
  t.libs << "test"
7
- t.test_files = FileList["test/test*.rb"]
9
+ t.test_files = FileList["test/**/*_test.rb"]
8
10
  end
9
11
 
10
12
  task :default => :test
data/ebayr.gemspec CHANGED
@@ -1,20 +1,30 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/ebayr/version', __FILE__)
1
+ # -*- encoding : utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
4
 
4
5
  Gem::Specification.new do |gem|
5
- gem.authors = ["JJ Buckley"]
6
- gem.email = ["jj@bjjb.org"]
7
- gem.description = %q{A tidy library for using the eBay Trading API with Ruby}
8
- gem.summary = %q{eBayR is a gem that makes it (relatively) easy to use the eBay Trading API from Ruby. Includes a self-contained XML parser, a flexible callback system, and easy integration into Rails.}
9
- gem.homepage = "http://jjbuckley.github.com/ebayr"
6
+ gem.authors = ["Bryan JJ Buckley"]
7
+ gem.email = ["jjbuckley@gmail.org"]
8
+ gem.description = "A tidy library for using the eBay Trading API with Ruby"
9
+ gem.summary = <<-DESCRIPTION
10
+ eBayR is a gem that makes it (relatively) easy to use the eBay Trading API from
11
+ Ruby. Includes a self-contained XML parser, a flexible callback system, and a
12
+ command-line client which aids integration into other projects.
13
+ DESCRIPTION
14
+ gem.homepage = "http://bjjb.github.com/ebayr"
10
15
 
11
16
  gem.files = `git ls-files`.split($\)
12
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^test/})
14
19
  gem.name = "ebayr"
15
20
  gem.require_paths = ["lib"]
16
- gem.version = Ebayr::VERSION
17
- gem.add_dependency 'activesupport'
21
+ gem.version = "0.0.5"
22
+ if RUBY_VERSION < "1.9"
23
+ gem.add_dependency 'activesupport', '~> 3.2'
24
+ gem.add_development_dependency 'minitest'
25
+ else
26
+ gem.add_dependency 'activesupport', '~> 4.0'
27
+ end
18
28
  gem.add_development_dependency 'rake'
19
29
  gem.add_development_dependency 'fakeweb'
20
30
  end
@@ -0,0 +1,49 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Ebayr
3
+ class Record < Hash
4
+ def initialize(initial = {})
5
+ super()
6
+ initial.each { |k, v| self[k] = v }
7
+ end
8
+
9
+ def <=>(another)
10
+ return false unless another.respond_to(:keys) and another.respond_to(:"[]")
11
+ another.keys.each do |k|
12
+ return false unless convert_value(another[k]) == self[k]
13
+ end
14
+ true
15
+ end
16
+
17
+ def [](key)
18
+ super(convert_key(key))
19
+ end
20
+
21
+ def []=(key, value)
22
+ key = convert_key(key)
23
+ value = convert_value(value)
24
+ (class << self; self; end).send(:define_method, key) { value }
25
+ super(key, value)
26
+ end
27
+
28
+ protected
29
+ def convert_key(k)
30
+ self.class.convert_key(k)
31
+ end
32
+
33
+ def self.convert_key(k)
34
+ k.to_s.underscore.gsub(/e_bay/, "ebay").to_sym
35
+ end
36
+
37
+ def convert_value(arg)
38
+ self.class.convert_value(arg)
39
+ end
40
+
41
+ def self.convert_value(arg)
42
+ case arg
43
+ when Hash then Record.new(arg)
44
+ when Array then arg.map { |a| convert_value(a) }
45
+ else arg
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,122 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Ebayr #:nodoc:
3
+ # Encapsulates a request which is sent to the eBay Trading API.
4
+ class Request
5
+ include Ebayr
6
+
7
+ attr_reader :command
8
+
9
+ # Make a new call. The URI used will be that of Ebayr::uri, unless
10
+ # overridden here (same for auth_token, site_id and compatability_level).
11
+ def initialize(command, options = {})
12
+ @command = self.class.camelize(command.to_s)
13
+ @uri = options.delete(:uri) || self.uri
14
+ @uri = URI.parse(@uri) unless @uri.is_a? URI
15
+ @auth_token = (options.delete(:auth_token) || self.auth_token).to_s
16
+ @site_id = (options.delete(:site_id) || self.site_id).to_s
17
+ @compatability_level = (options.delete(:compatability_level) || self.compatability_level).to_s
18
+ # Remaining options are converted and used as input to the call
19
+ @input = self.class.serialize_input(options)
20
+ end
21
+
22
+ # Gets the path to which this request will be posted
23
+ def path
24
+ @uri.path
25
+ end
26
+
27
+ # Gets the headers that will be sent with this request.
28
+ def headers
29
+ {
30
+ 'X-EBAY-API-COMPATIBILITY-LEVEL' => @compatability_level.to_s,
31
+ 'X-EBAY-API-DEV-NAME' => dev_id.to_s,
32
+ 'X-EBAY-API-APP-NAME' => app_id.to_s,
33
+ 'X-EBAY-API-CERT-NAME' => cert_id.to_s,
34
+ 'X-EBAY-API-CALL-NAME' => @command.to_s,
35
+ 'X-EBAY-API-SITEID' => @site_id.to_s,
36
+ 'Content-Type' => 'text/xml'
37
+ }
38
+ end
39
+
40
+ # Gets the body of this request (which is XML)
41
+ def body
42
+ <<-XML
43
+ <?xml version="1.0" encoding="utf-8"?>
44
+ <#{@command}Request xmlns="urn:ebay:apis:eBLBaseComponents">
45
+ <RequesterCredentials>
46
+ <eBayAuthToken>#{@auth_token}</eBayAuthToken>
47
+ </RequesterCredentials>
48
+ #{self.class.xml(@input)}
49
+ </#{@command}Request>
50
+ XML
51
+ end
52
+
53
+ # Makes a HTTP connection and sends the request, returning an
54
+ # Ebayr::Response
55
+ def send
56
+ http = Net::HTTP.new(@uri.host, @uri.port)
57
+
58
+ if @uri.port == 443
59
+ http.use_ssl = true
60
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
61
+ end
62
+
63
+ post = Net::HTTP::Post.new(@uri.path, headers)
64
+ post.body = body
65
+
66
+ response = http.start { |http| http.request(post) }
67
+
68
+ @response = Response.new(self, response)
69
+ end
70
+
71
+ def to_s
72
+ "#{@command}[#{@input}] <#{@uri}>"
73
+ end
74
+
75
+ # A very, very simple XML serializer.
76
+ #
77
+ # Ebayr.xml("Hello!") # => "Hello!"
78
+ # Ebayr.xml(:foo=>"Bar") # => <foo>Bar</foo>
79
+ # Ebayr.xml(:foo=>["Bar","Baz"]) # => <foo>Bar</foo>
80
+ def self.xml(*args)
81
+ args.map do |structure|
82
+ case structure
83
+ when Hash then structure.map { |k, v| "<#{k.to_s}>#{xml(v)}</#{k.to_s}>" }.join
84
+ when Array then structure.map { |v| xml(v) }.join
85
+ else structure.to_s
86
+ end
87
+ end.join
88
+ end
89
+
90
+ # Prepares a hash of arguments for input to an eBay Trading API XML call.
91
+ # * Times are converted to ISO 8601 format
92
+ def self.serialize_input(args)
93
+ result = {}
94
+ args.each do |k, v|
95
+ result[k] = case v
96
+ when Time then v.to_time.utc.iso8601
97
+ else v
98
+ end
99
+ end
100
+ result
101
+ end
102
+
103
+ # Converts a command like get_ebay_offical_time to GeteBayOfficialTime
104
+ def self.camelize(string)
105
+ string = string.to_s
106
+ return string unless string == string.downcase
107
+ string.split('_').map(&:capitalize).join.gsub('Ebay', 'eBay')
108
+ end
109
+
110
+ # Gets a HTTP connection for this request. If you pass in a block, it will
111
+ # be run on that HTTP connection.
112
+ def http(&block)
113
+ http = Net::HTTP.new(@uri.host, @uri.port)
114
+ if @uri.port == 443
115
+ http.use_ssl = true
116
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
117
+ end
118
+ return http.start(&block) if block_given?
119
+ http
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,15 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Ebayr #:nodoc:
3
+ # A response to an Ebayr::Request.
4
+ class Response < Record
5
+ def initialize(request, response)
6
+ @request = request
7
+ @command = @request.command if @request
8
+ @response = response
9
+ @body = response.body if @response
10
+ hash = self.class.from_xml(@body) if @body
11
+ response_data = hash["#{@command}Response"] if hash
12
+ super(response_data) if response_data
13
+ end
14
+ end
15
+ end
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  module Ebayr
2
3
  module TestHelper
3
4
  @@success = Ebayr.xml(:Ack => "Success")
@@ -17,7 +18,13 @@ module Ebayr
17
18
  # assert Ebayr.call(:GeteBayOfficialTime) # => stubbed call
18
19
  # end
19
20
  # end
21
+ #
22
+ # This method is deprecated, and will be removed in a future release.
20
23
  def stub_ebay_call!(call, content, &block)
24
+ puts <<DEPRECATION
25
+ stub_ebay_call! is deprecated, and will be removed in a future release. Please
26
+ use Ruby techniques to stub eBay calls your way. See the wiki for details.
27
+ DEPRECATION
21
28
  content = Ebayr.xml(content) unless content.is_a?(String)
22
29
  _allow_net_connect_ = FakeWeb.allow_net_connect?
23
30
  FakeWeb.allow_net_connect = false
@@ -27,11 +34,10 @@ module Ebayr
27
34
  #{content}
28
35
  </#{call}Response>
29
36
  XML
30
- FakeWeb.register_uri( :any, Ebayr.uri, :body => body)
37
+ FakeWeb.register_uri(:any, Ebayr.uri, :body => body)
31
38
  yield
32
39
  FakeWeb.clean_registry
33
40
  FakeWeb.allow_net_connect = _allow_net_connect_
34
41
  end
35
-
36
42
  end
37
43
  end
data/lib/ebayr/user.rb ADDED
@@ -0,0 +1,16 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Ebayr
3
+ module User
4
+ # Shorthand for call(call, arguments.merge(:auth_token => this.ebay_token))
5
+ # Allows objects which mix in this module to use their own token.
6
+ def ebay_call(call, arguments = {})
7
+ raise "#{self} has no eBay token" unless ebay_token
8
+ Ebayr.call(call, arguments.merge(:auth_token => ebay_token))
9
+ end
10
+
11
+ # Gets the user's data
12
+ def get_ebay_data
13
+ ebay_call(:GetUser)
14
+ end
15
+ end
16
+ end
data/lib/ebayr.rb CHANGED
@@ -1,52 +1,92 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require "ebayr/version"
2
+ require 'logger'
3
3
  require 'net/https'
4
4
  require 'active_support/core_ext/module/attribute_accessors'
5
5
  require 'active_support/core_ext/hash/conversions'
6
- require 'active_support/buffered_logger'
7
6
 
7
+ # A library to assist in using the eBay Trading API.
8
8
  module Ebayr
9
- mattr_accessor :dev_id,
10
- :app_id,
11
- :cert_id,
12
- :ru_name,
13
- :auth_token,
14
- :sandbox,
15
- :authorization_callback_url,
16
- :callbacks,
17
- :site_id,
18
- :compatability_level,
19
- :logger
20
-
21
- @@logger ||= if defined?(Rails)
22
- Rails.logger
23
- else
24
- ActiveSupport::BufferedLogger.new(STDOUT)
9
+ autoload :Record, File.expand_path('../ebayr/record', __FILE__)
10
+ autoload :Request, File.expand_path('../ebayr/request', __FILE__)
11
+ autoload :Response, File.expand_path('../ebayr/response', __FILE__)
12
+ autoload :User, File.expand_path('../ebayr/user', __FILE__)
13
+
14
+ # To make a call, you need to have a registered user and app. Then you must
15
+ # fill in the <code>dev_id</code>, <code>app_id</code>, <code>cert_id</code>
16
+ # and <code>ru_name</code>. You will also need an <code>auth_token</code>,
17
+ # though you may use any user's token here.
18
+ # See http://developer.ebay.com/DevZone/XML/docs/HowTo/index.html for more
19
+ # details.
20
+ mattr_accessor :dev_id
21
+ mattr_accessor :app_id
22
+ mattr_accessor :cert_id
23
+ mattr_accessor :ru_name
24
+ mattr_accessor :auth_token
25
+
26
+ # Determines whether to use the eBay sandbox or the real site.
27
+ mattr_accessor :sandbox
28
+ self.sandbox = true
29
+
30
+ # Set to true to generate fancier objects for responses (will decrease
31
+ # performance).
32
+ mattr_accessor :normalize_responses
33
+
34
+ def self.normalize_responses?
35
+ !!normalize_responses
25
36
  end
26
37
 
27
- %W(/etc/ebayrc.conf /usr/local/etc/ebayrc.conf ~/.ebayrc.conf ./.ebayrc.conf).each do |path|
28
- load path if File.exists?(path = File.expand_path(path))
29
- end
30
-
31
-
32
- @@site_id ||= 0 # US
33
- @@compatability_level ||= 745
34
-
35
- def self.sandbox?
38
+ def sandbox?
36
39
  !!sandbox
37
40
  end
38
41
 
42
+ # This URL is used to redirect the user back after a successful registration.
43
+ # For more details, see here:
44
+ # http://developer.ebay.com/DevZone/XML/docs/WebHelp/wwhelp/wwhimpl/js/html/wwhelp.htm?context=eBay_XML_API&topic=GettingATokenViaFetchToken
45
+ mattr_accessor :authorization_callback_url
46
+ self.authorization_callback_url = 'https://example.com/'
47
+
48
+ # This URL is used if the authorization process fails - usually because the user
49
+ # didn't click 'I agree'. If you leave it nil, the
50
+ # <code>authorization_callback_url</code> will be used (but the parameters will be
51
+ # different).
52
+ mattr_accessor :authorization_failure_url
53
+ self.authorization_failure_url = nil
54
+
55
+ # Callbacks which are invoked at various points throughout a request.
56
+ mattr_accessor :callbacks
57
+ self.callbacks = {
58
+ :before_request => [],
59
+ :after_request => [],
60
+ :before_response => [],
61
+ :after_response => [],
62
+ :on_error => []
63
+ }
64
+
65
+ # The eBay Site to use for calls. The full list of available sites can be
66
+ # retrieved with <code>GeteBayDetails(:DetailName => "SiteDetails")</code>
67
+ mattr_accessor :site_id
68
+ self.site_id = 0
69
+
70
+ # eBay Trading API version to use. For more details, see
71
+ # http://developer.ebay.com/devzone/xml/docs/HowTo/eBayWS/eBaySchemaVersioning.html
72
+ mattr_accessor :compatability_level
73
+ self.compatability_level = 745
74
+
75
+ mattr_accessor :logger
76
+ self.logger = Logger.new(STDOUT)
77
+ self.logger.level = Logger::INFO
78
+
39
79
  # Gets either ebay.com/ws or sandbox.ebay.com/ws, as appropriate, with
40
80
  # "service" prepended. E.g.
41
81
  #
42
82
  # Ebayr.uri_prefix("blah") # => https://blah.ebay.com/ws
43
83
  # Ebayr.uri_prefix # => https://api.ebay.com/ws
44
- def self.uri_prefix(service = "api")
84
+ def uri_prefix(service = "api")
45
85
  "https://#{service}#{sandbox ? ".sandbox" : ""}.ebay.com/ws"
46
86
  end
47
87
 
48
88
  # Gets the URI used for API calls (as a URI object)
49
- def self.uri(*args)
89
+ def uri(*args)
50
90
  URI::parse("#{uri_prefix(*args)}/api.dll")
51
91
  end
52
92
 
@@ -54,24 +94,12 @@ module Ebayr
54
94
  # via an API call to GetSessionID (be sure to use the right ru_name), and the
55
95
  # ru_params can contain anything (they will be passed back to your app in the
56
96
  # redirect from eBay upon successful login and authorization).
57
- def self.authorization_uri(session_id, ru_params = {})
97
+ def authorization_uri(session_id, ru_params = {})
58
98
  ruparams = CGI::escape(ru_params.map { |k, v| "#{k}=#{v}" }.join("&"))
59
99
  URI::parse("#{uri_prefix("signin")}/eBayISAPI.dll?SignIn&RuName=#{ru_name}&SessId=#{session_id}&ruparams=#{ruparams}")
60
100
  end
61
101
 
62
- # A very, very simple XML serializer.
63
- #
64
- # Ebayr.xml("Hello!") # => "Hello!"
65
- # Ebayr.xml({:foo=>"Bar"}) # => <foo>Bar</foo>
66
- def self.xml(structure)
67
- case structure
68
- when Hash then structure.map { |k, v| "<#{k.to_s}>#{xml(v)}</#{k.to_s}>" }.join
69
- when Array then structure.map { |v| xml(v) }
70
- else structure.to_s
71
- end
72
- end
73
-
74
- # Make an eBay call (symbol or string). You can pass in these arguments:
102
+ # Perform an eBay call (symbol or string). You can pass in these arguments:
75
103
  #
76
104
  # auth_token:: to use a user's token instead of the general token
77
105
  # site_id:: to use a specific eBay site (default is 0, which is US ebay.com)
@@ -79,111 +107,38 @@ module Ebayr
79
107
  #
80
108
  # All other arguments are passed into the API call, and may be nested.
81
109
  #
82
- # Remember, case matters.
110
+ # response = call(:GeteBayOfficialTime)
111
+ # response = call(:get_ebay_official_time)
83
112
  #
84
- # call(:GeteBayOfficialTime)
113
+ # See Ebayr::Request for details.
85
114
  #
86
- # The response is a Hash of the response, deserialized from the XML by
87
- # ActiveSupport's XML deserializer.
88
- def self.call(call, arguments = {})
89
- call = call.to_s
90
-
91
- auth_token = arguments.delete(:auth_token) || self.auth_token.to_s
92
- site_id = arguments.delete(:site_id) || self.site_id.to_s
93
- compatability_level = arguments.delete(:compatability_level) || self.compatability_level.to_s
94
-
95
- headers = {
96
- 'X-EBAY-API-COMPATIBILITY-LEVEL' => compatability_level.to_s,
97
- 'X-EBAY-API-DEV-NAME' => dev_id.to_s,
98
- 'X-EBAY-API-APP-NAME' => app_id.to_s,
99
- 'X-EBAY-API-CERT-NAME' => cert_id.to_s,
100
- 'X-EBAY-API-CALL-NAME' => call.to_s,
101
- 'X-EBAY-API-SITEID' => site_id.to_s,
102
- 'Content-Type' => 'text/xml'
103
- }
104
-
105
- xml = xml(arguments)
106
-
107
- xml = <<-XML
108
- <?xml version="1.0" encoding="utf-8"?>
109
- <#{call}Request xmlns="urn:ebay:apis:eBLBaseComponents">
110
- <RequesterCredentials>
111
- <eBayAuthToken>#{auth_token}</eBayAuthToken>
112
- </RequesterCredentials>
113
- #{xml}
114
- </#{call}Request>
115
- XML
116
-
117
- request = Net::HTTP::Post.new(uri.path, headers)
118
-
119
- request.body = xml.to_s
120
-
121
- http = Net::HTTP.new(uri.host, uri.port)
122
-
123
- if uri.port == 443
124
- http.use_ssl = true
125
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
126
- end
127
-
128
- response = http.start { |http| http.request(request) }
129
-
130
- if callbacks
131
- callbacks.each do |callback|
132
- if callback.is_a?(Symbol)
133
- send(callback, request, response)
134
- elsif callback.respond_to?(:call)
135
- callback.call(request, response)
136
- else
137
- throw Error.new("Invalid callback: #{callback.to_s}")
138
- end
139
- end
140
- end
141
-
142
- case response
143
- when Net::HTTPSuccess
144
- result = Hash.from_xml(response.body)["#{call}Response"]
145
- unless result
146
- raise Exception.new("No #{call}Response in response", request, response)
147
- end
148
- case result['Ack']
149
- when 'Success'
150
- return result
151
- when 'Warning'
152
- @@logger.warn(result['Errors'].inspect)
153
- return result
154
- else
155
- raise Error.new(result['Errors'], request, response)
156
- end
157
- return result
158
- else
159
- raise Exception.new("Unexpected response from server", request, response)
160
- end
115
+ # The response is a special Hash of the response, deserialized from the XML
116
+ #
117
+ # response.timestamp # => 2010-10-10 10:00:00 UTC
118
+ # response[:timestamp] # => 2010-10-10 10:00:00 UTC
119
+ # response['Timestamp'] # => "2012-10-10T10:00:00.000Z"
120
+ # response[:Timestamp] # => "2012-10-10T10:00:00.000Z"
121
+ # response.ack # "Success"
122
+ # response.success? # true
123
+ #
124
+ # See Ebayr::Response for details.
125
+ #
126
+ # To see a list of available calls, check out
127
+ # http://developer.ebay.com/DevZone/XML/docs/Reference/ebay/index.html
128
+ def call(command, arguments = {})
129
+ Request.new(command, arguments).send
161
130
  end
162
131
 
163
- # Shorthand for call(call, arguments.merge(:auth_token => this.ebay_token))
164
- # Allows objects which mix in this module to use their own token.
165
- def ebay_call(call, arguments = {})
166
- raise "#{self} has no eBay token" unless ebay_token
167
- Ebay.call(call, arguments.merge(:auth_token => ebay_token))
168
- end
169
132
 
170
- class Exception < ::Exception
171
- attr_reader :request, :response
172
- def initialize(message, request, response)
173
- super message
174
- @request, @response = request, response
175
- end
133
+ def self.included(mod)
134
+ mod.extend(self)
176
135
  end
177
136
 
178
- class Error < Exception
179
- attr_reader :request, :response, :errors
180
- def initialize(errors, request, response)
181
- @errors, @request, @response = errors, request, response
182
- super
183
- end
184
-
185
- def to_s
186
- [@errors].flatten.map { |e| "<#{e['LongMessage']}>" }.join(", ")
187
- end
188
- end
137
+ extend self
138
+ end
139
+
140
+ # Override defaults with values from a config file, if there is one.
141
+ %W(/etc/ebayr.conf /usr/local/etc/ebayr.conf ~/.ebayr.conf ./.ebayr.conf).each do |path|
142
+ load path if File.exists?(path = File.expand_path(path))
189
143
  end
144
+
@@ -0,0 +1,21 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'test_helper'
3
+ require 'ebayr/record'
4
+
5
+ module Ebayr
6
+ class RecordTest < MiniTest::Unit::TestCase
7
+ def test_lookup_is_case_insensitive
8
+ record = Record.new('Foo' => 'Bar')
9
+ assert_equal 'Bar', record['Foo']
10
+ end
11
+
12
+ def test_records_are_nested
13
+ record = Record.new(:Foo => { "Bar" => "Baz" })
14
+ assert_equal "Baz", record.foo.bar
15
+
16
+ record = Record.new('Foo' => { 'Bars' => [{ 'Value' => 1 }, { 'Value' => 2 }] })
17
+ assert_equal 1, record.foo.bars[0].value
18
+ assert_equal 2, record.foo.bars[1].value
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,45 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'test_helper'
3
+ require 'ebayr/request'
4
+
5
+ describe Ebayr::Request do
6
+ describe "serializing input" do
7
+ it "converts times" do
8
+ result = Ebayr::Request.serialize_input("Time" => Time.utc(2010, 'oct', 31, 03, 15))
9
+ result['Time'].must_equal "2010-10-31T03:15:00Z"
10
+ end
11
+ end
12
+
13
+ describe "uri" do
14
+ it "is the Ebayr one" do
15
+ Ebayr::Request.new(:Blah).uri.must_equal(Ebayr.uri)
16
+ end
17
+ end
18
+
19
+ describe "xml" do
20
+ def request(*args)
21
+ Ebayr::Request.xml(*args)
22
+ end
23
+
24
+ it "convets a hash" do
25
+ request(:a => { :b => 123 }).must_equal '<a><b>123</b></a>'
26
+ end
27
+
28
+ it "converts an array" do
29
+ request([{ :a => 1 }, { :a => 2 }]).must_equal "<a>1</a><a>2</a>"
30
+ end
31
+
32
+ it "converts a string" do
33
+ request('boo').must_equal 'boo'
34
+ end
35
+
36
+ it "converts a number" do
37
+ request(1234).must_equal '1234'
38
+ end
39
+
40
+ it "converts multiple arguments" do
41
+ args = [{ :a => 1 }, { :a => [{:b => 1 }, { :b => 2 }] }]
42
+ request(*args).must_equal '<a>1</a><a><b>1</b><b>2</b></a>'
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,50 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'test_helper'
3
+ require 'ostruct'
4
+ require 'ebayr/response'
5
+
6
+ describe Ebayr::Response do
7
+ it "builds objects from XML" do
8
+ xml = "<GetSomethingResponse><Foo>Bar</Foo></GetSomethingResponse>"
9
+ response = Ebayr::Response.new(
10
+ OpenStruct.new(:command => 'GetSomething'),
11
+ OpenStruct.new(:body => xml))
12
+ response['Foo'].must_equal 'Bar'
13
+ response.foo.must_equal 'Bar'
14
+ end
15
+
16
+ it "handes responses" do
17
+ xml = "<GeteBayResponse><eBayFoo>Bar</eBayFoo></GeteBayResponse>"
18
+ response = Ebayr::Response.new(
19
+ OpenStruct.new(:command => 'GeteBay'),
20
+ OpenStruct.new(:body => xml))
21
+ response.ebay_foo.must_equal 'Bar'
22
+ end
23
+
24
+ def test_response_nesting
25
+ xml = <<-XML
26
+ <GetOrdersResponse>
27
+ <OrdersArray>
28
+ <Order>
29
+ <OrderID>1</OrderID>
30
+ </Order>
31
+ <Order>
32
+ <OrderID>2</OrderID>
33
+ </Order>
34
+ <Order>
35
+ <OrderID>3</OrderID>
36
+ </Order>
37
+ </OrdersArray>
38
+ </GetOrdersResponse>
39
+ XML
40
+ response = Ebayr::Response.new(
41
+ OpenStruct.new(:command => 'GetOrders'),
42
+ OpenStruct.new(:body => xml)
43
+ )
44
+ assert_kind_of Hash, response.orders_array
45
+ response.orders_array.order[0].order_id.must_equal "1"
46
+ response.orders_array.order[1].order_id.must_equal "2"
47
+ response.orders_array.order[2].order_id.must_equal "3"
48
+ end
49
+
50
+ end
@@ -0,0 +1,87 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'test_helper'
3
+ require 'ebayr'
4
+ require 'fakeweb'
5
+
6
+ describe Ebayr do
7
+ before { Ebayr.sandbox = true }
8
+
9
+ def check_common_methods(mod = Ebayr)
10
+ assert_respond_to mod, :"dev_id"
11
+ assert_respond_to mod, :"dev_id="
12
+ assert_respond_to mod, :"cert_id"
13
+ assert_respond_to mod, :"cert_id="
14
+ assert_respond_to mod, :"ru_name"
15
+ assert_respond_to mod, :"ru_name="
16
+ assert_respond_to mod, :"auth_token"
17
+ assert_respond_to mod, :"auth_token="
18
+ assert_respond_to mod, :"compatability_level"
19
+ assert_respond_to mod, :"compatability_level="
20
+ assert_respond_to mod, :"site_id"
21
+ assert_respond_to mod, :"site_id="
22
+ assert_respond_to mod, :"sandbox"
23
+ assert_respond_to mod, :"sandbox="
24
+ assert_respond_to mod, :"sandbox?"
25
+ assert_respond_to mod, :"authorization_callback_url"
26
+ assert_respond_to mod, :"authorization_callback_url="
27
+ assert_respond_to mod, :"authorization_failure_url"
28
+ assert_respond_to mod, :"authorization_failure_url="
29
+ assert_respond_to mod, :"callbacks"
30
+ assert_respond_to mod, :"callbacks="
31
+ assert_respond_to mod, :"logger"
32
+ assert_respond_to mod, :"logger="
33
+ assert_respond_to mod, :"uri"
34
+ end
35
+
36
+ # If this passes without an exception, then we're ok.
37
+ describe "basic usage" do
38
+ before { FakeWeb.register_uri(:post, Ebayr.uri, :body => xml) }
39
+ let(:xml) { "<GeteBayOfficialTimeResponse><Ack>Succes</Ack><Timestamp>blah</Timestamp></GeteBayOfficialTimeResponse>" }
40
+
41
+ it "runs without exceptions" do
42
+ Ebayr.call(:GeteBayOfficialTime).timestamp.must_equal 'blah'
43
+ end
44
+ end
45
+
46
+ it "correctly reports its sandbox status" do
47
+ Ebayr.sandbox = false
48
+ Ebayr.wont_be :sandbox?
49
+ Ebayr.sandbox = true
50
+ Ebayr.must_be :sandbox?
51
+ end
52
+
53
+ it "has the right sandbox URIs" do
54
+ Ebayr.must_be :sandbox?
55
+ Ebayr.uri_prefix.must_equal "https://api.sandbox.ebay.com/ws"
56
+ Ebayr.uri_prefix("blah").must_equal "https://blah.sandbox.ebay.com/ws"
57
+ Ebayr.uri.to_s.must_equal "https://api.sandbox.ebay.com/ws/api.dll"
58
+ end
59
+
60
+ it "has the right real-world URIs" do
61
+ Ebayr.sandbox = false
62
+ Ebayr.uri_prefix.must_equal "https://api.ebay.com/ws"
63
+ Ebayr.uri_prefix("blah").must_equal "https://blah.ebay.com/ws"
64
+ Ebayr.uri.to_s.must_equal "https://api.ebay.com/ws/api.dll"
65
+ Ebayr.sandbox = true
66
+ end
67
+
68
+ it "works when as an extension" do
69
+ mod = Module.new { extend Ebayr }
70
+ check_common_methods(mod)
71
+ end
72
+
73
+ it "works as an inclusion" do
74
+ mod = Module.new { extend Ebayr }
75
+ check_common_methods(mod)
76
+ end
77
+
78
+ it "has the right methods" do
79
+ check_common_methods
80
+ end
81
+
82
+ it "has decent defaults" do
83
+ Ebayr.must_be :sandbox?
84
+ Ebayr.uri.to_s.must_equal "https://api.sandbox.ebay.com/ws/api.dll"
85
+ Ebayr.logger.must_be_kind_of Logger
86
+ end
87
+ end
@@ -0,0 +1,2 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'minitest/autorun'
metadata CHANGED
@@ -1,97 +1,111 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ebayr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
5
- prerelease:
4
+ version: 0.0.5
6
5
  platform: ruby
7
6
  authors:
8
- - JJ Buckley
7
+ - Bryan JJ Buckley
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-04-18 00:00:00.000000000Z
11
+ date: 2013-11-08 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: activesupport
16
- requirement: &81893100 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ! '>='
17
+ - - ~>
20
18
  - !ruby/object:Gem::Version
21
- version: '0'
19
+ version: '4.0'
22
20
  type: :runtime
23
21
  prerelease: false
24
- version_requirements: *81893100
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
25
27
  - !ruby/object:Gem::Dependency
26
28
  name: rake
27
- requirement: &81892860 !ruby/object:Gem::Requirement
28
- none: false
29
+ requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - ! '>='
31
+ - - '>='
31
32
  - !ruby/object:Gem::Version
32
33
  version: '0'
33
34
  type: :development
34
35
  prerelease: false
35
- version_requirements: *81892860
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
36
41
  - !ruby/object:Gem::Dependency
37
42
  name: fakeweb
38
- requirement: &81892620 !ruby/object:Gem::Requirement
39
- none: false
43
+ requirement: !ruby/object:Gem::Requirement
40
44
  requirements:
41
- - - ! '>='
45
+ - - '>='
42
46
  - !ruby/object:Gem::Version
43
47
  version: '0'
44
48
  type: :development
45
49
  prerelease: false
46
- version_requirements: *81892620
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
47
55
  description: A tidy library for using the eBay Trading API with Ruby
48
56
  email:
49
- - jj@bjjb.org
57
+ - jjbuckley@gmail.org
50
58
  executables: []
51
59
  extensions: []
52
60
  extra_rdoc_files: []
53
61
  files:
54
62
  - .gitignore
63
+ - .travis.yml
55
64
  - Gemfile
65
+ - Guardfile
56
66
  - LICENSE
57
67
  - README.md
58
68
  - Rakefile
59
69
  - ebayr.gemspec
60
70
  - lib/ebayr.rb
71
+ - lib/ebayr/record.rb
72
+ - lib/ebayr/request.rb
73
+ - lib/ebayr/response.rb
61
74
  - lib/ebayr/test_helper.rb
62
- - lib/ebayr/version.rb
63
- - test/test_ebayr.rb
64
- homepage: http://jjbuckley.github.com/ebayr
75
+ - lib/ebayr/user.rb
76
+ - test/ebayr/record_test.rb
77
+ - test/ebayr/request_test.rb
78
+ - test/ebayr/response_test.rb
79
+ - test/ebayr_test.rb
80
+ - test/test_helper.rb
81
+ homepage: http://bjjb.github.com/ebayr
65
82
  licenses: []
83
+ metadata: {}
66
84
  post_install_message:
67
85
  rdoc_options: []
68
86
  require_paths:
69
87
  - lib
70
88
  required_ruby_version: !ruby/object:Gem::Requirement
71
- none: false
72
89
  requirements:
73
- - - ! '>='
90
+ - - '>='
74
91
  - !ruby/object:Gem::Version
75
92
  version: '0'
76
- segments:
77
- - 0
78
- hash: -317667633
79
93
  required_rubygems_version: !ruby/object:Gem::Requirement
80
- none: false
81
94
  requirements:
82
- - - ! '>='
95
+ - - '>='
83
96
  - !ruby/object:Gem::Version
84
97
  version: '0'
85
- segments:
86
- - 0
87
- hash: -317667633
88
98
  requirements: []
89
99
  rubyforge_project:
90
- rubygems_version: 1.8.10
100
+ rubygems_version: 2.0.3
91
101
  signing_key:
92
- specification_version: 3
102
+ specification_version: 4
93
103
  summary: eBayR is a gem that makes it (relatively) easy to use the eBay Trading API
94
104
  from Ruby. Includes a self-contained XML parser, a flexible callback system, and
95
- easy integration into Rails.
105
+ a command-line client which aids integration into other projects.
96
106
  test_files:
97
- - test/test_ebayr.rb
107
+ - test/ebayr/record_test.rb
108
+ - test/ebayr/request_test.rb
109
+ - test/ebayr/response_test.rb
110
+ - test/ebayr_test.rb
111
+ - test/test_helper.rb
data/lib/ebayr/version.rb DELETED
@@ -1,3 +0,0 @@
1
- module Ebayr
2
- VERSION = "0.0.4"
3
- end
data/test/test_ebayr.rb DELETED
@@ -1,29 +0,0 @@
1
- require 'test/unit'
2
- require 'ebayr'
3
- require 'ebayr/test_helper'
4
-
5
- class TestEbayr < Test::Unit::TestCase
6
- include Ebayr::TestHelper
7
-
8
- # If this passes without an exception, then we're ok.
9
- def test_sanity
10
- t = Time.now.to_s
11
- stub_ebay_call!(:GeteBayOfficialTime, :Timestamp => t) do
12
- result = Ebayr.call(:GeteBayOfficialTime)
13
- assert_equal t, result['Timestamp']
14
- end
15
- end
16
-
17
- def test_sandbox_reports_accurately
18
- Ebayr.sandbox = false
19
- assert !Ebayr.sandbox?
20
- Ebayr.sandbox = true
21
- assert Ebayr.sandbox?
22
- end
23
-
24
- def test_ebayr_uris
25
- assert_equal "https://api.sandbox.ebay.com/ws", Ebayr.uri_prefix
26
- assert_equal "https://blah.sandbox.ebay.com/ws", Ebayr.uri_prefix("blah")
27
- assert_equal "https://api.sandbox.ebay.com/ws/api.dll", Ebayr.uri.to_s
28
- end
29
- end