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.
@@ -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
@@ -0,0 +1,10 @@
1
+ /.idea/
2
+ /.env
3
+ /.bundle/
4
+ /.yardoc
5
+ /Gemfile.lock
6
+ /_yardoc/
7
+ /coverage/
8
+ /doc/
9
+ /pkg/
10
+ /spec/reports/
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.5
4
+ before_install: gem install bundler -v 1.10.4
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ebay_trader.gemspec
4
+ gemspec
@@ -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.
@@ -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
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -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
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -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