ebayr 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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