peddler 0.7.5 → 0.7.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -5
- data/lib/mws/fulfillment_inbound_shipment.rb +84 -0
- data/lib/mws/fulfillment_inventory.rb +20 -0
- data/lib/mws/fulfillment_outbound_shipment.rb +53 -0
- data/lib/mws/off_amazon_payments.rb +1 -1
- data/lib/peddler/client.rb +3 -1
- data/lib/peddler/flat_file_parser.rb +53 -0
- data/lib/peddler/parser.rb +15 -11
- data/lib/peddler/version.rb +1 -1
- data/test/integration/test_fulfillment_inbound_shipment.rb +11 -0
- data/test/integration/test_fulfillment_inventory.rb +11 -0
- data/test/integration/test_fulfillment_outbound_shipment.rb +11 -0
- data/test/unit/peddler/test_client.rb +1 -1
- data/test/unit/peddler/{test_csv_parser.rb → test_flat_file_parser.rb} +21 -3
- data/test/unit/peddler/test_xml_parser.rb +2 -2
- data/test/vcr_cassettes/FulfillmentInboundShipment.yml +369 -0
- data/test/vcr_cassettes/FulfillmentInventory.yml +369 -0
- data/test/vcr_cassettes/FulfillmentOutboundShipment.yml +370 -0
- data/test/vcr_cassettes/Reports.yml +6563 -0
- metadata +17 -5
- data/lib/peddler/csv_parser.rb +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f9b31544fe3d9183ca13cfaf52fc46b17b63bd7c
|
4
|
+
data.tar.gz: 812917ae3a325ea06882348325ac001057bc3335
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2cd7197ad9e27655e0f6c0554c12e2e703a9687e90d086d3330b76886bb30ac017e025e9f3ab328b2eb2098e2a0abb42492c35c9a4937f9174d92a3f93bc6cd6
|
7
|
+
data.tar.gz: 140a6b3e7091da63b3a42507749841803b10f1e215c956a9003f2f305126ff1335d60c107de305e15931b167a2fd5448bb444106d60b1bcb920db0a4f5b2615f
|
data/README.md
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
[![Build Status][1]][2]
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
**Peddler** is a Ruby interface to the [Amazon MWS API][4], a collection of web services that help Amazon sellers programmatically exchange data on their listings, orders, payments, reports, and more.
|
5
|
+
**Peddler** is a Ruby interface to the [Amazon MWS API][3], a collection of web services that help Amazon sellers programmatically exchange data on their listings, orders, payments, reports, and more.
|
8
6
|
|
9
7
|
To use Amazon MWS, you must have an eligible seller account.
|
10
8
|
|
9
|
+
![Peddler][4]
|
10
|
+
|
11
11
|
## Configuration
|
12
12
|
|
13
13
|
Require the entire library or a particular API section.
|
@@ -131,5 +131,5 @@ The Amazon MWS Subscriptions API section enables you to subscribe to receive not
|
|
131
131
|
|
132
132
|
[1]: https://travis-ci.org/hakanensari/peddler.png
|
133
133
|
[2]:https://travis-ci.org/hakanensari/peddler
|
134
|
-
[3]:
|
135
|
-
[4]:
|
134
|
+
[3]: https://developer.amazonservices.com/
|
135
|
+
[4]: http://f.cl.ly/items/231z2m0r1Q2o2q1n0w1N/peddler.jpg
|
@@ -9,5 +9,89 @@ module MWS
|
|
9
9
|
# @todo Not implemented
|
10
10
|
class FulfillmentInboundShipment < ::Peddler::Client
|
11
11
|
path '/FulfillmentInboundShipment/2010-10-01'
|
12
|
+
|
13
|
+
# Returns the information required to create an inbound shipment
|
14
|
+
def create_inbound_shipment_plan
|
15
|
+
raise NotImplementedError
|
16
|
+
end
|
17
|
+
|
18
|
+
# Creates an inbound shipment
|
19
|
+
def create_inbound_shipment
|
20
|
+
raise NotImplementedError
|
21
|
+
end
|
22
|
+
|
23
|
+
# Updates an existing inbound shipment
|
24
|
+
def update_inbound_shipment
|
25
|
+
raise NotImplementedError
|
26
|
+
end
|
27
|
+
|
28
|
+
# Sends transportation information to Amazon about an inbound shipment
|
29
|
+
def put_transport_content
|
30
|
+
raise NotImplementedError
|
31
|
+
end
|
32
|
+
|
33
|
+
# Requests an estimate of the shipping cost for an inbound shipment
|
34
|
+
def estimate_transport_request
|
35
|
+
raise NotImplementedError
|
36
|
+
end
|
37
|
+
|
38
|
+
# Confirms that you accept the Amazon-partnered shipping estimate and you
|
39
|
+
# request that the Amazon-partnered carrier ship your inbound shipment
|
40
|
+
def confirm_transport_request
|
41
|
+
raise NotImplementedError
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns current transportation information about an inbound shipment
|
45
|
+
def get_transport_content
|
46
|
+
raise NotImplementedError
|
47
|
+
end
|
48
|
+
|
49
|
+
# Voids a previously-confirmed request to ship your inbound shipment using
|
50
|
+
# an Amazon-partnered carrier
|
51
|
+
def void_transport_request
|
52
|
+
raise NotImplementedError
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns PDF document data for printing package labels for an inbound
|
56
|
+
# shipment
|
57
|
+
def get_package_labels
|
58
|
+
raise NotImplementedError
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns PDF document data for printing a bill of lading for an inbound
|
62
|
+
# shipment
|
63
|
+
def get_bill_of_lading
|
64
|
+
raise NotImplementedError
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns a list of inbound shipments based on criteria that you specify
|
68
|
+
def list_inbound_shipments
|
69
|
+
raise NotImplementedError
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns the next page of inbound shipments
|
73
|
+
def list_inbound_shipments_by_next_token
|
74
|
+
raise NotImplementedError
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns a list of items in a specified inbound shipment, or a list of
|
78
|
+
# items that were updated within a specified time frame
|
79
|
+
def list_inbound_shipment_items
|
80
|
+
raise NotImplementedError
|
81
|
+
end
|
82
|
+
|
83
|
+
# Returns the next page of inbound shipment items
|
84
|
+
def list_inbound_shipment_items_by_next_token
|
85
|
+
raise NotImplementedError
|
86
|
+
end
|
87
|
+
|
88
|
+
# Gets the operational status of the API
|
89
|
+
#
|
90
|
+
# @see http://docs.developer.amazonservices.com/en_US/fba_inbound/MWS_GetServiceStatus.html
|
91
|
+
# @return [Peddler::XMLParser]
|
92
|
+
def get_service_status
|
93
|
+
operation('GetServiceStatus')
|
94
|
+
run
|
95
|
+
end
|
12
96
|
end
|
13
97
|
end
|
@@ -11,5 +11,25 @@ module MWS
|
|
11
11
|
# @todo Not implemented
|
12
12
|
class FulfillmentInventory < ::Peddler::Client
|
13
13
|
path '/FulfillmentInventory/2010-10-01'
|
14
|
+
|
15
|
+
# Returns information about the availability of a seller's inventory
|
16
|
+
def list_inventory_supply
|
17
|
+
raise NotImplementedError
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns the next page of information about the availability of a seller's
|
21
|
+
# inventory
|
22
|
+
def list_inventory_supply_by_next_token
|
23
|
+
raise NotImplementedError
|
24
|
+
end
|
25
|
+
|
26
|
+
# Gets the operational status of the API
|
27
|
+
#
|
28
|
+
# @see http://docs.developer.amazonservices.com/en_US/fba_inventory/MWS_GetServiceStatus.html
|
29
|
+
# @return [Peddler::XMLParser]
|
30
|
+
def get_service_status
|
31
|
+
operation('GetServiceStatus')
|
32
|
+
run
|
33
|
+
end
|
14
34
|
end
|
15
35
|
end
|
@@ -13,5 +13,58 @@ module MWS
|
|
13
13
|
# @todo Not implemented
|
14
14
|
class FulfillmentOutboundShipment < ::Peddler::Client
|
15
15
|
path '/FulfillmentOutboundShipment/2010-10-01'
|
16
|
+
|
17
|
+
# Lists fulfillment order previews
|
18
|
+
def get_fulfillment_preview
|
19
|
+
raise NotImplementedError
|
20
|
+
end
|
21
|
+
|
22
|
+
# Requests that Amazon ship items from the seller's Amazon Fulfillment
|
23
|
+
# Network inventory to a destination address
|
24
|
+
def create_fulfillment_order
|
25
|
+
raise NotImplementedError
|
26
|
+
end
|
27
|
+
|
28
|
+
# Updates and/or requests shipment for a fulfillment order with an order
|
29
|
+
# hold on it
|
30
|
+
def update_fulfillment_order
|
31
|
+
raise NotImplementedError
|
32
|
+
end
|
33
|
+
|
34
|
+
# Gets a fulfillment order
|
35
|
+
def get_fulfillment_order
|
36
|
+
raise NotImplementedError
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns a list of fulfillment orders fulfilled on or after a date
|
40
|
+
def list_all_fulfillment_orders
|
41
|
+
raise NotImplementedError
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns the next page of fulfillment orders
|
45
|
+
def list_all_fulfillment_orders_by_next_token
|
46
|
+
raise NotImplementedError
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns delivery tracking information for a package in an outbound
|
50
|
+
# shipment for a Multi-Channel Fulfillment order
|
51
|
+
def get_package_tracking_details
|
52
|
+
raise NotImplementedError
|
53
|
+
end
|
54
|
+
|
55
|
+
# Requests that Amazon stop attempting to fulfill an existing fulfillment
|
56
|
+
# order
|
57
|
+
def cancel_fulfillment_order
|
58
|
+
raise NotImplementedError
|
59
|
+
end
|
60
|
+
|
61
|
+
# Gets the operational status of the API
|
62
|
+
#
|
63
|
+
# @see http://docs.developer.amazonservices.com/en_US/fba_outbound/MWS_GetServiceStatus.html
|
64
|
+
# @return [Peddler::XMLParser]
|
65
|
+
def get_service_status
|
66
|
+
operation('GetServiceStatus')
|
67
|
+
run
|
68
|
+
end
|
16
69
|
end
|
17
70
|
end
|
@@ -211,7 +211,7 @@ module MWS
|
|
211
211
|
run
|
212
212
|
end
|
213
213
|
|
214
|
-
#
|
214
|
+
# Gets the operational status of the API
|
215
215
|
#
|
216
216
|
# @see http://docs.developer.amazonservices.com/en_US/off_amazon_payments/OffAmazonPayments_GetServiceStatus.html
|
217
217
|
# @return [Peddler::XMLParser]
|
data/lib/peddler/client.rb
CHANGED
@@ -68,7 +68,7 @@ module Peddler
|
|
68
68
|
opts.store(:response_block, blk) if block_given?
|
69
69
|
res = post(opts)
|
70
70
|
|
71
|
-
parser.parse(res)
|
71
|
+
parser.parse(res, host_encoding)
|
72
72
|
end
|
73
73
|
|
74
74
|
private
|
@@ -83,6 +83,8 @@ module Peddler
|
|
83
83
|
|
84
84
|
def host_encoding
|
85
85
|
if host.end_with?('jp')
|
86
|
+
# Caveat: I've had one instance in the past where Shift_JIS didn't
|
87
|
+
# work but Windows-31J did when parsing a report.
|
86
88
|
'Shift_JIS'
|
87
89
|
elsif host.end_with?('cn')
|
88
90
|
'UTF-16'
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
require 'csv'
|
3
|
+
require 'digest/md5'
|
4
|
+
|
5
|
+
module Peddler
|
6
|
+
# @api private
|
7
|
+
class FlatFileParser < SimpleDelegator
|
8
|
+
# http://stackoverflow.com/questions/8073920/importing-csv-quoting-error-is-driving-me-nuts
|
9
|
+
OPTIONS = { col_sep: "\t", quote_char: "\x00", headers: true }
|
10
|
+
|
11
|
+
attr_reader :content, :summary, :encoding
|
12
|
+
|
13
|
+
def initialize(res, encoding)
|
14
|
+
super(res)
|
15
|
+
@encoding = encoding
|
16
|
+
extract_content
|
17
|
+
end
|
18
|
+
|
19
|
+
def parse
|
20
|
+
CSV.parse(scrub_content, OPTIONS) if content
|
21
|
+
end
|
22
|
+
|
23
|
+
def records_count
|
24
|
+
summarize if summary
|
25
|
+
end
|
26
|
+
|
27
|
+
def valid?
|
28
|
+
headers['Content-MD5'] == Digest::MD5.base64digest(body)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def extract_content
|
34
|
+
if has_summary?
|
35
|
+
@summary, @content = body.split("\n\n")
|
36
|
+
else
|
37
|
+
@content = body.dup
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def scrub_content
|
42
|
+
content.force_encoding(encoding).encode('UTF-8')
|
43
|
+
end
|
44
|
+
|
45
|
+
def has_summary?
|
46
|
+
body.start_with?('Feed Processing Summary')
|
47
|
+
end
|
48
|
+
|
49
|
+
def summarize
|
50
|
+
Hash[summary.split("\n\t")[1, 2].map { |line| line.split("\t\t") }]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/peddler/parser.rb
CHANGED
@@ -1,20 +1,24 @@
|
|
1
|
-
require 'peddler/
|
1
|
+
require 'peddler/flat_file_parser'
|
2
2
|
require 'peddler/xml_parser'
|
3
3
|
|
4
4
|
module Peddler
|
5
5
|
# @api private
|
6
6
|
module Parser
|
7
|
-
|
8
|
-
#
|
9
|
-
|
7
|
+
class << self
|
8
|
+
# The inevitable messiness of massaging data produced by a motley army of
|
9
|
+
# Amazon developers
|
10
|
+
def parse(res, encoding = 'ISO-8859-1')
|
11
|
+
# Don't parse if there's no body
|
12
|
+
return res unless res.body
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
case res.headers['Content-Type']
|
15
|
+
when 'text/xml'
|
16
|
+
XMLParser.new(res)
|
17
|
+
when 'application/octet-stream'
|
18
|
+
FlatFileParser.new(res, encoding)
|
19
|
+
else
|
20
|
+
raise NotImplementedError
|
21
|
+
end
|
18
22
|
end
|
19
23
|
end
|
20
24
|
end
|
data/lib/peddler/version.rb
CHANGED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'integration_helper'
|
2
|
+
require 'mws/fulfillment_inbound_shipment'
|
3
|
+
|
4
|
+
class FulfillmentInboundShipmentTest < IntegrationTest
|
5
|
+
def test_gets_service_status
|
6
|
+
clients.each do |client|
|
7
|
+
res = client.get_service_status
|
8
|
+
refute_empty res.parse
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'integration_helper'
|
2
|
+
require 'mws/fulfillment_outbound_shipment'
|
3
|
+
|
4
|
+
class FulfillmentOutboundShipmentTest < IntegrationTest
|
5
|
+
def test_gets_service_status
|
6
|
+
clients.each do |client|
|
7
|
+
res = client.get_service_status
|
8
|
+
refute_empty res.parse
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -1,13 +1,14 @@
|
|
1
1
|
require 'helper'
|
2
|
-
require 'peddler/
|
2
|
+
require 'peddler/flat_file_parser'
|
3
3
|
|
4
|
-
class
|
4
|
+
class FlatFileParserTest < MiniTest::Test
|
5
5
|
def setup
|
6
6
|
body = "Feed Processing Summary:\n\tNumber of records processed\t\t11006\n\tNumber of records successful\t\t11006\n\noriginal-record-number\tsku\terror-code\terror-type\terror-message\n1822\t85da472e-ba6c-11e3-95af-002590a74356\t5000\tWarning\tThe update for Sku '85da472e-ba6c-11e3-95af-002590a74356' was skipped because it is identical to the update in feed '9518995390'.\n"
|
7
|
+
body.encode!('ASCII-8BIT')
|
7
8
|
headers = { 'Content-Type' => 'application/octet-stream', 'Content-MD5' => 'SmZIMTs2mCO8u8QzR5LE7Q==' }
|
8
9
|
res = OpenStruct.new(body: body, headers: headers)
|
9
10
|
|
10
|
-
@parser = Peddler::
|
11
|
+
@parser = Peddler::FlatFileParser.new(res, 'ISO-8859-1')
|
11
12
|
end
|
12
13
|
|
13
14
|
def test_parses_data
|
@@ -21,4 +22,21 @@ class CSVParserTest < MiniTest::Test
|
|
21
22
|
def test_validates
|
22
23
|
assert @parser.valid?
|
23
24
|
end
|
25
|
+
|
26
|
+
def test_handles_reports_without_a_summary
|
27
|
+
res = OpenStruct.new(body: "Foo\nBar\n")
|
28
|
+
parser = Peddler::FlatFileParser.new(res, 'ISO-8859-1')
|
29
|
+
|
30
|
+
refute_empty parser.content
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_handles_japanese_flat_files
|
34
|
+
body = "Foo\nこんにちは\n"
|
35
|
+
body.encode!('SHIFT_JIS')
|
36
|
+
body.force_encoding('ASCII-8BIT')
|
37
|
+
res = OpenStruct.new(body: body)
|
38
|
+
parser = Peddler::FlatFileParser.new(res, 'SHIFT_JIS')
|
39
|
+
|
40
|
+
assert_equal 'こんにちは', parser.parse[0]['Foo']
|
41
|
+
end
|
24
42
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'helper'
|
2
|
-
require 'peddler/
|
2
|
+
require 'peddler/xml_parser'
|
3
3
|
|
4
4
|
class XMLParserTest < MiniTest::Test
|
5
5
|
def setup
|
6
6
|
body = '<Response><Result><NextToken>123</NextToken><Foo>Bar</Foo></Result></Response>'
|
7
7
|
res = OpenStruct.new(body: body, headers: { 'Content-Type' => 'text/xml'})
|
8
8
|
|
9
|
-
@parser = Peddler::
|
9
|
+
@parser = Peddler::XMLParser.new(res)
|
10
10
|
end
|
11
11
|
|
12
12
|
def test_parses_data
|