ebay-trader 0.9.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 +7 -0
- data/.gitignore +10 -0
- data/.rspec +3 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +325 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/ebay_trader.gemspec +34 -0
- data/examples/get_categories.rb +39 -0
- data/examples/more_examples.rb +5 -0
- data/lib/ebay_trader.rb +45 -0
- data/lib/ebay_trader/configuration.rb +242 -0
- data/lib/ebay_trader/fetch_token.rb +45 -0
- data/lib/ebay_trader/request.rb +354 -0
- data/lib/ebay_trader/sax_handler.rb +151 -0
- data/lib/ebay_trader/session_id.rb +71 -0
- data/lib/ebay_trader/version.rb +3 -0
- data/lib/ebay_trader/xml_builder.rb +113 -0
- data/lib/hash_with_indifferent_access.rb +23 -0
- metadata +138 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2d002fbf649178cd5dd0b7df4c17cbe95c81965a
|
4
|
+
data.tar.gz: 8361565674b5d6d21d1e48c00a43a217f3edf06a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 37533e2f16c1e612e5401203be672da3bd859e3a12dbcd017885e9df3ebc31708b92afd344efef394cfa0a25999da327307cbc714ae9a6cca266b450619ec955
|
7
|
+
data.tar.gz: 2358280eda7a23c0a67610d88918340dc34285eac36b325bcc1a0e1b0495ca012a32898695d7fea4fd1951013d2800552ed19402da88b665efac9bc4031e715a
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Rob Graham
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,325 @@
|
|
1
|
+
# EbayTrader
|
2
|
+
|
3
|
+
**EbayTrader** is a lightweight easy to use Ruby gem for interacting with [eBay's Trading API](http://developer.ebay.com/DevZone/XML/docs/Reference/eBay/index.html).
|
4
|
+
Leveraging Ruby's missing_method meta-programming DSL techniques, EbayTrader allows you to quickly and intuitively post XML requests
|
5
|
+
to eBay and parses the response. The response data is available in the form of a Hash, actually a
|
6
|
+
[HashWithIndifferentAccess](http://api.rubyonrails.org/classes/ActiveSupport/HashWithIndifferentAccess.html) so keys `:key_name` and `"key_name"` are treated equally,
|
7
|
+
and values are auto-type-cast to String, Fixnum, Float, Boolean, BigDecimal or [Money](https://github.com/RubyMoney/money).
|
8
|
+
|
9
|
+
## Simple example
|
10
|
+
|
11
|
+
Let's start with a simple example. Here we will request a list of [categories](http://www.ebay.com/sch/allcategories/all-categories)
|
12
|
+
from eBay via a [GetCategories](http://developer.ebay.com/DevZone/XML/docs/Reference/eBay/GetCategories.html) API call.
|
13
|
+
Assuming there are no errors or warnings a list of all eBay category names will be printed.
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
require 'ebay_trader'
|
17
|
+
require 'ebay_trader/request'
|
18
|
+
|
19
|
+
EbayTrader.configure do |config|
|
20
|
+
# Configuration is described in the section below...
|
21
|
+
end
|
22
|
+
|
23
|
+
request = EbayTrader::Request.new('GetCategories') do
|
24
|
+
CategorySiteID 0
|
25
|
+
CategoryParent ARGV.first unless ARGV.empty?
|
26
|
+
DetailLevel 'ReturnAll'
|
27
|
+
LevelLimit 5
|
28
|
+
ViewAllNodes true
|
29
|
+
end
|
30
|
+
request.errors_and_warnings.each { |error| puts error.long_message } if request.has_errors_or_warnings?
|
31
|
+
|
32
|
+
if request.success?
|
33
|
+
category_names = request.response_hash[:category_array][:category].map { |c| c[:category_name] }
|
34
|
+
category_names.each { |name| puts name }
|
35
|
+
end
|
36
|
+
```
|
37
|
+
|
38
|
+
Notice that in the above example if `ARGV` is an empty array `CategoryParent` node will be excluded from the XML document.
|
39
|
+
|
40
|
+
### CamelCase method names?!
|
41
|
+
|
42
|
+
Before you start screaming that this goes against the conventions of the [Ruby style guide](https://github.com/bbatsov/ruby-style-guide),
|
43
|
+
let me justify it by reminding you that the [eBay XML schema](http://developer.ebay.com/webservices/latest/ebaySvc.xsd)
|
44
|
+
uses **CamelCase**. It is thus rather counter productive to copy an paste key names from eBay's documentation,
|
45
|
+
manually adapt them to **snake_case** for the sake of etiquette, then write a method to convert these snake_case
|
46
|
+
key names back into CamelCase.
|
47
|
+
|
48
|
+
## Nested data example
|
49
|
+
|
50
|
+
As shown above the `EbayTrader::Request` constructor accepts a block with a DSL describing the structure of the XML
|
51
|
+
document to be posted to the eBay Trading API. Additional hierarchy in the XML can be described by nesting more blocks
|
52
|
+
within this DSL. The following example show a call to [GetMyeBaySelling](http://developer.ebay.com/DevZone/XML/docs/Reference/ebay/GetMyeBaySelling.html)
|
53
|
+
to retrieve a list of **unsold** items.
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
duration = 30 # days
|
57
|
+
per_page = 100
|
58
|
+
page_number = 2
|
59
|
+
|
60
|
+
request = EbayTrader::Request.new('GetMyeBaySelling') do
|
61
|
+
ErrorLanguage 'en_GB'
|
62
|
+
WarningLevel 'High'
|
63
|
+
DetailLevel 'ReturnAll'
|
64
|
+
|
65
|
+
UnsoldList do
|
66
|
+
Include 'true'
|
67
|
+
DurationInDays duration # 0..60
|
68
|
+
Pagination do
|
69
|
+
EntriesPerPage per_page
|
70
|
+
PageNumber page_number
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
ActiveList do
|
75
|
+
Include false
|
76
|
+
end
|
77
|
+
|
78
|
+
BidList do
|
79
|
+
Include false
|
80
|
+
end
|
81
|
+
|
82
|
+
DeletedFromSoldList do
|
83
|
+
Include false
|
84
|
+
end
|
85
|
+
|
86
|
+
DeletedFromUnsoldList do
|
87
|
+
Include false
|
88
|
+
end
|
89
|
+
|
90
|
+
ScheduledList do
|
91
|
+
Include false
|
92
|
+
end
|
93
|
+
|
94
|
+
SoldList do
|
95
|
+
Include false
|
96
|
+
end
|
97
|
+
end
|
98
|
+
```
|
99
|
+
|
100
|
+
For a list of more comprehensive examples please feel free to check out my [ebay_trader_support](https://github.com/altabyte/ebay_trader_support)
|
101
|
+
gem. This gem hosts some of the classes and command line tools from my production environment.
|
102
|
+
|
103
|
+
### Response data
|
104
|
+
|
105
|
+
The data tree returned by eBay is accessible through `request.response_hash`. Response hash is a [HashWithIndifferentAccess](http://api.rubyonrails.org/classes/ActiveSupport/HashWithIndifferentAccess.html)
|
106
|
+
which has been monkey patched to include a `deep_find` method. This `deep_find` method expects an array of key names and
|
107
|
+
performs a depth-first search on response_hash, returning the *first* value matching the path.
|
108
|
+
|
109
|
+
If for example I made a [GetItem](http://developer.ebay.com/DevZone/XML/docs/Reference/ebay/GetItem.html) API call I could
|
110
|
+
determine the [current price](http://developer.ebay.com/DevZone/XML/docs/Reference/ebay/GetItem.html#Response.Item.SellingStatus.CurrentPrice) as follows:
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
request.response_hash.deep_find([:item, :selling_status, :current_price])
|
114
|
+
```
|
115
|
+
|
116
|
+
If any of the nodes in the path are absent a value of `nil` will be returned.
|
117
|
+
`deep_find` can be instructed return a default should there be no value at the specified path.
|
118
|
+
In the following example $0.00 USD will be returned instead of `nil` if there is no value at
|
119
|
+
`response_hash[:item][:selling_status][:current_price]` or the path does not exist.
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
request.response_hash.deep_find([:item, :selling_status, :current_price], Money.new(0_00, 'USD'))
|
123
|
+
```
|
124
|
+
|
125
|
+
## Configuration
|
126
|
+
|
127
|
+
Before using this gem you must configure it with your [eBay Developer](https://go.developer.ebay.com/) credentials.
|
128
|
+
Shown below is an example configuration.
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
EbayTrader.configure do |config|
|
132
|
+
|
133
|
+
config.ebay_api_version = 935
|
134
|
+
|
135
|
+
# Environment can be :sandbox or :production
|
136
|
+
config.environment = :sandbox
|
137
|
+
|
138
|
+
# Optional as ebay_site_id can also be specified for each request.
|
139
|
+
# 0 for ebay.com [Default]
|
140
|
+
# 3 for ebay.co.uk
|
141
|
+
config.ebay_site_id = 0
|
142
|
+
|
143
|
+
# If you are getting error messages regarding SSL Certificates
|
144
|
+
# you can [temporarily] disable SSL verification.
|
145
|
+
# Caution! setting this to false will make you vulnerable to man-in-the-middle attacks.
|
146
|
+
# The default value is true
|
147
|
+
config.ssl_verify = false # because I like to live dangerously
|
148
|
+
|
149
|
+
# Optional as auth_token can also be specified for each request.
|
150
|
+
config.auth_token = ENV['EBAY_API_AUTH_TOKEN']
|
151
|
+
|
152
|
+
config.dev_id = ENV['EBAY_API_DEV_ID']
|
153
|
+
config.app_id = ENV['EBAY_API_APP_ID']
|
154
|
+
config.cert_id = ENV['EBAY_API_CERT_ID']
|
155
|
+
|
156
|
+
config.ru_name = ENV['EBAY_API_RU_NAME']
|
157
|
+
|
158
|
+
# By default price values are represented as BigDecimal
|
159
|
+
# This can be changed to any of the following
|
160
|
+
# :big_decimal, :fixnum, :integer, :float or :money
|
161
|
+
# :money can only be specified if the Money gem is available to your application.
|
162
|
+
config.price_type = :big_decimal
|
163
|
+
end
|
164
|
+
```
|
165
|
+
|
166
|
+
The latest eBay API version number can be found in the [Trading API Release Notes](http://developer.ebay.com/DevZone/XML/docs/ReleaseNotes.html).
|
167
|
+
|
168
|
+
### Counting calls
|
169
|
+
|
170
|
+
As eBay [limits the number](https://go.developer.ebay.com/api-call-limits) of API calls
|
171
|
+
that can be made each day, you may wish to keep track of your usage. You can provide an optional counter callback
|
172
|
+
that will be called during each post.
|
173
|
+
|
174
|
+
Here is an example of how to use a [Redis](http://redis.io/) database to keep track of daily API calls.
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
config.counter = lambda {
|
178
|
+
begin
|
179
|
+
redis = Redis.new(host: 'localhost')
|
180
|
+
key = "ebay_trader:production:call_count:#{Time.now.utc.strftime('%Y-%m-%d')}"
|
181
|
+
redis.incr(key)
|
182
|
+
rescue SocketError
|
183
|
+
puts 'Failed to increment Redis call counter!'
|
184
|
+
end
|
185
|
+
}
|
186
|
+
```
|
187
|
+
|
188
|
+
|
189
|
+
## Customizing request calls
|
190
|
+
|
191
|
+
`EbayTrader::Request.new` method accepts a Hash of options. Listed below are some of the common options.
|
192
|
+
|
193
|
+
### Authentication token and site ID
|
194
|
+
|
195
|
+
An `:auth_token` and/or `:ebay_site_id` can be passed to each request, overriding any
|
196
|
+
value defined in the module configuration.
|
197
|
+
|
198
|
+
```ruby
|
199
|
+
request = EbayTrader::Request.new('GetItem', auth_token: ENV[EBAY_AUTH_TOKEN], ebay_site_id: 3) do
|
200
|
+
CategorySpecific {
|
201
|
+
CategoryID category_id_number
|
202
|
+
}
|
203
|
+
end
|
204
|
+
```
|
205
|
+
|
206
|
+
### Extending timeout
|
207
|
+
|
208
|
+
By default each request will allow up to 30 seconds (although this can be changed in the module
|
209
|
+
configuration) before raising a timeout error. However some calls such as [UploadSiteHostedPictures](http://developer.ebay.com/DevZone/XML/docs/Reference/eBay/UploadSiteHostedPictures.html)
|
210
|
+
may require more time, especially if uploading large images.
|
211
|
+
This timeout can be extended with the following option `http_timeout: 60`
|
212
|
+
|
213
|
+
### Automatic type-casting
|
214
|
+
|
215
|
+
By default this gem tries to guess and auto-cast values to their appropriate types. As this is based on simple pattern
|
216
|
+
recognition it does not always get it right. Take for example a call to [GetUser](http://developer.ebay.com/DevZone/XML/docs/Reference/ebay/GetUser.html).
|
217
|
+
If an eBay user has the username ID '123456' this gem will type-cast the value to a `Fixnum`. This can be prevented by passing
|
218
|
+
an array of keys to be excluded from type-casting to the `Request` constructor.
|
219
|
+
|
220
|
+
```ruby
|
221
|
+
SKIP_TYPE_CASTING = [
|
222
|
+
:charity_id,
|
223
|
+
:city_name,
|
224
|
+
:international_street,
|
225
|
+
:phone,
|
226
|
+
:postal_code,
|
227
|
+
:name,
|
228
|
+
:skype_id,
|
229
|
+
:street,
|
230
|
+
:street1,
|
231
|
+
:street2,
|
232
|
+
:user_id,
|
233
|
+
:vat_id
|
234
|
+
]
|
235
|
+
|
236
|
+
request = EbayTrader::Request.new('GetUser', skip_type_casting: SKIP_TYPE_CASTING) do
|
237
|
+
UserID user_id unless user_id.nil?
|
238
|
+
ItemID item_id.to_s unless item_id.nil?
|
239
|
+
end
|
240
|
+
```
|
241
|
+
|
242
|
+
### Known arrays
|
243
|
+
|
244
|
+
One of the limitations of XML is that it is not possible to explicitly define arrays. This means that when a response
|
245
|
+
contains a list with only one element a parser cannot intrinsically determine that it should be an array.
|
246
|
+
To overcome this limitation you can provide a list of known arrays to the request.
|
247
|
+
|
248
|
+
```ruby
|
249
|
+
KNOWN_ARRAYS = [
|
250
|
+
:compatibility,
|
251
|
+
:copyright,
|
252
|
+
:cross_border_trade,
|
253
|
+
:discount_profile,
|
254
|
+
:ebay_picture_url,
|
255
|
+
:exclude_ship_to_location,
|
256
|
+
:external_picture_url,
|
257
|
+
:gift_services,
|
258
|
+
:international_shipping_service_option,
|
259
|
+
:item_specifics,
|
260
|
+
:listing_enhancement,
|
261
|
+
:name_value_list,
|
262
|
+
:payment_allowed_site,
|
263
|
+
:payment_methods,
|
264
|
+
:promoted_item,
|
265
|
+
:picture_url,
|
266
|
+
:shipping_service_options,
|
267
|
+
:ship_to_location,
|
268
|
+
:ship_to_locations,
|
269
|
+
:skype_contact_option,
|
270
|
+
:tax_jurisdiction,
|
271
|
+
:value,
|
272
|
+
:variation,
|
273
|
+
:variation_specific_picture_set,
|
274
|
+
:variation_specifics,
|
275
|
+
:variation_specifics_set
|
276
|
+
]
|
277
|
+
|
278
|
+
request = EbayTrader::Request.new('GetItem', known_arrays: KNOWN_ARRAYS) do
|
279
|
+
ItemID item_id
|
280
|
+
IncludeWatchCount true
|
281
|
+
IncludeItemSpecifics true
|
282
|
+
DetailLevel 'ItemReturnDescription' if include_description?
|
283
|
+
end
|
284
|
+
```
|
285
|
+
|
286
|
+
Subsequently you can simply iterate over the data without having to first check if it is an array. This can also eliminate
|
287
|
+
a post-processing step should you wish to dump the response hashes into [mongoDB](https://www.mongodb.org/) for analysis.
|
288
|
+
|
289
|
+
### Cached responses
|
290
|
+
|
291
|
+
For testing and debugging you can inject a String containing the expected eBay response XML
|
292
|
+
with the `xml_response: xml_string` option. If given this string will be parsed and no data will be posted
|
293
|
+
to the eBay API.
|
294
|
+
|
295
|
+
## Installation
|
296
|
+
|
297
|
+
Add this line to your application's Gemfile:
|
298
|
+
|
299
|
+
```ruby
|
300
|
+
gem 'ebay_trader'
|
301
|
+
```
|
302
|
+
|
303
|
+
And then execute:
|
304
|
+
|
305
|
+
$ bundle
|
306
|
+
|
307
|
+
Or install it yourself as:
|
308
|
+
|
309
|
+
$ gem install ebay_trader
|
310
|
+
|
311
|
+
## Development
|
312
|
+
|
313
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
314
|
+
|
315
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
316
|
+
|
317
|
+
## Contributing
|
318
|
+
|
319
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/altabyte/ebay_trading.
|
320
|
+
|
321
|
+
|
322
|
+
## License
|
323
|
+
|
324
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
325
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "ebay_trader"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/ebay_trader.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'ebay_trader/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'ebay-trader'
|
8
|
+
spec.version = EbayTrader::VERSION
|
9
|
+
spec.authors = ['Rob Graham']
|
10
|
+
spec.email = ['rob@altabyte.com']
|
11
|
+
|
12
|
+
spec.summary = %q{A DSL to interact with eBay's Trading API using Ruby}
|
13
|
+
spec.description = <<-DESC
|
14
|
+
EbayTrader is a lightweight easy to use Ruby gem for interacting with eBay's Trading API.
|
15
|
+
Using its simple DSL you can quickly and intuitively post XML requests to eBay and rapidly interpret the responses.
|
16
|
+
DESC
|
17
|
+
spec.homepage = 'https://github.com/altabyte/ebay_trader'
|
18
|
+
spec.license = 'MIT'
|
19
|
+
|
20
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
21
|
+
spec.bindir = 'exe'
|
22
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
|
+
spec.require_paths = ['lib']
|
24
|
+
|
25
|
+
spec.add_development_dependency 'bundler', '~> 1.10'
|
26
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
27
|
+
spec.add_development_dependency 'rspec'
|
28
|
+
|
29
|
+
spec.add_runtime_dependency 'activesupport', '~> 4.0'
|
30
|
+
spec.add_runtime_dependency 'ox', '~> 2.2'
|
31
|
+
|
32
|
+
# Uncomment the following line to have monetary values cast to Money types...
|
33
|
+
# spec.add_runtime_dependency 'money'
|
34
|
+
end
|