amazon-mws-plus 0.1.3

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.
Files changed (151) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.project +12 -0
  4. data/Gemfile +13 -0
  5. data/README.markdown +30 -0
  6. data/Rakefile +50 -0
  7. data/amazon-mws-plus.gemspec +23 -0
  8. data/amazon-mws.tmproj +27 -0
  9. data/examples/xml/cancel_feed_submissions.xml +16 -0
  10. data/examples/xml/cancel_fulfillment_order.xml +6 -0
  11. data/examples/xml/cancel_report_requests.xml +18 -0
  12. data/examples/xml/create_fulfillment_order.xml +6 -0
  13. data/examples/xml/error.xml +10 -0
  14. data/examples/xml/get_feed_submission_count.xml +10 -0
  15. data/examples/xml/get_feed_submission_list.xml +18 -0
  16. data/examples/xml/get_feed_submission_list_by_next_token.xml +16 -0
  17. data/examples/xml/get_feed_submission_result.xml +30 -0
  18. data/examples/xml/get_fulfillment_order.xml +113 -0
  19. data/examples/xml/get_fulfillment_preview.xml +148 -0
  20. data/examples/xml/get_matching_product.xml +115 -0
  21. data/examples/xml/get_matching_product_for_id.xml +119 -0
  22. data/examples/xml/get_report.xml +237 -0
  23. data/examples/xml/get_report_count.xml +9 -0
  24. data/examples/xml/get_report_list.xml +17 -0
  25. data/examples/xml/get_report_request_count.xml +8 -0
  26. data/examples/xml/get_report_request_list.xml +120 -0
  27. data/examples/xml/get_report_request_list_by_next_token.xml +20 -0
  28. data/examples/xml/get_report_schedule_count.xml +10 -0
  29. data/examples/xml/get_report_schedule_list.xml +15 -0
  30. data/examples/xml/get_report_schedule_list_by_next_token.xml +15 -0
  31. data/examples/xml/list_all_fulfillment_orders.xml +69 -0
  32. data/examples/xml/list_all_fulfillment_orders_by_next_token.xml +61 -0
  33. data/examples/xml/manage_report_schedule.xml +14 -0
  34. data/examples/xml/orders_request.xml +39 -0
  35. data/examples/xml/request_order_items.xml +51 -0
  36. data/examples/xml/request_order_items_by_next_token.xml +51 -0
  37. data/examples/xml/request_orders.xml +43 -0
  38. data/examples/xml/request_orders_by_next_token.xml +69 -0
  39. data/examples/xml/request_report.xml +17 -0
  40. data/examples/xml/submit_feed.xml +14 -0
  41. data/examples/xml/update_report_acknowledgements.xml +18 -0
  42. data/examples/xsd/Inventory.xsd +49 -0
  43. data/examples/xsd/Item.xsd +285 -0
  44. data/examples/xsd/Listings.xsd +32 -0
  45. data/examples/xsd/OrderAcknowledgement.xsd +55 -0
  46. data/examples/xsd/OrderAdjustment.xsd +94 -0
  47. data/examples/xsd/OrderFulfillment.xsd +57 -0
  48. data/examples/xsd/Override.xsd +48 -0
  49. data/examples/xsd/Price.xsd +59 -0
  50. data/examples/xsd/ProcessingReport.xsd +87 -0
  51. data/examples/xsd/Product.xsd +220 -0
  52. data/examples/xsd/Product/AutoAccessory.xsd +807 -0
  53. data/examples/xsd/Product/Beauty.xsd +114 -0
  54. data/examples/xsd/Product/CE.xsd +544 -0
  55. data/examples/xsd/Product/CameraPhoto.xsd +2410 -0
  56. data/examples/xsd/Product/FoodAndBeverages.xsd +270 -0
  57. data/examples/xsd/Product/Gourmet.xsd +85 -0
  58. data/examples/xsd/Product/Health.xsd +189 -0
  59. data/examples/xsd/Product/Home.xsd +654 -0
  60. data/examples/xsd/Product/Jewelry.xsd +603 -0
  61. data/examples/xsd/Product/Miscellaneous.xsd +157 -0
  62. data/examples/xsd/Product/MusicalInstruments.xsd +853 -0
  63. data/examples/xsd/Product/Office.xsd +550 -0
  64. data/examples/xsd/Product/PetSupplies.xsd +40 -0
  65. data/examples/xsd/Product/ProductClothing.xsd +197 -0
  66. data/examples/xsd/Product/SWVG.xsd +238 -0
  67. data/examples/xsd/Product/Sports.xsd +308 -0
  68. data/examples/xsd/Product/TiresAndWheels.xsd +159 -0
  69. data/examples/xsd/Product/Tools.xsd +62 -0
  70. data/examples/xsd/Product/ToysBaby.xsd +241 -0
  71. data/examples/xsd/Product/Wireless.xsd +77 -0
  72. data/examples/xsd/ProductImage.xsd +39 -0
  73. data/examples/xsd/Relationship.xsd +47 -0
  74. data/examples/xsd/SettlementReport.xsd +158 -0
  75. data/examples/xsd/amzn-base.xsd +1600 -0
  76. data/examples/xsd/amzn-envelope.xsd +98 -0
  77. data/examples/xsd/amzn-header.xsd +45 -0
  78. data/lib/amazon-mws.rb +6 -0
  79. data/lib/amazon/mws.rb +69 -0
  80. data/lib/amazon/mws/authentication.rb +10 -0
  81. data/lib/amazon/mws/authentication/query_string.rb +36 -0
  82. data/lib/amazon/mws/authentication/signature.rb +43 -0
  83. data/lib/amazon/mws/base.rb +74 -0
  84. data/lib/amazon/mws/connection.rb +107 -0
  85. data/lib/amazon/mws/connection/management.rb +95 -0
  86. data/lib/amazon/mws/connection/request_builder.rb +67 -0
  87. data/lib/amazon/mws/exceptions.rb +55 -0
  88. data/lib/amazon/mws/lib/extensions.rb +178 -0
  89. data/lib/amazon/mws/lib/memoizable.rb +10 -0
  90. data/lib/amazon/mws/request/feed.rb +276 -0
  91. data/lib/amazon/mws/request/feed_builder.rb +83 -0
  92. data/lib/amazon/mws/request/fulfillment.rb +50 -0
  93. data/lib/amazon/mws/request/orders.rb +107 -0
  94. data/lib/amazon/mws/request/products.rb +38 -0
  95. data/lib/amazon/mws/request/report.rb +330 -0
  96. data/lib/amazon/mws/response.rb +43 -0
  97. data/lib/amazon/mws/response/feed/cancel_feed_submissions_response.rb +15 -0
  98. data/lib/amazon/mws/response/feed/get_feed_submission_count_response.rb +13 -0
  99. data/lib/amazon/mws/response/feed/get_feed_submission_list_by_next_token_response.rb +17 -0
  100. data/lib/amazon/mws/response/feed/get_feed_submission_list_response.rb +16 -0
  101. data/lib/amazon/mws/response/feed/get_feed_submission_result_response.rb +54 -0
  102. data/lib/amazon/mws/response/feed/models/feed_submission.rb +16 -0
  103. data/lib/amazon/mws/response/feed/submit_feed_response.rb +15 -0
  104. data/lib/amazon/mws/response/fulfillment_order/cancel_fulfillment_order_response.rb +11 -0
  105. data/lib/amazon/mws/response/fulfillment_order/create_fulfillment_order_response.rb +12 -0
  106. data/lib/amazon/mws/response/fulfillment_order/get_fulfillment_order_response.rb +19 -0
  107. data/lib/amazon/mws/response/fulfillment_order/list_all_fulfillment_orders_by_next_token_response.rb +16 -0
  108. data/lib/amazon/mws/response/fulfillment_order/list_all_fulfillment_orders_response.rb +15 -0
  109. data/lib/amazon/mws/response/fulfillment_order/models/fulfillment_address.rb +18 -0
  110. data/lib/amazon/mws/response/fulfillment_order/models/fulfillment_order.rb +24 -0
  111. data/lib/amazon/mws/response/fulfillment_order/models/fulfillment_order_item.rb +20 -0
  112. data/lib/amazon/mws/response/fulfillment_order/models/fulfillment_shipment.rb +18 -0
  113. data/lib/amazon/mws/response/fulfillment_order/models/fulfillment_shipment_item.rb +14 -0
  114. data/lib/amazon/mws/response/order/models/order.rb +43 -0
  115. data/lib/amazon/mws/response/order/models/order_item.rb +48 -0
  116. data/lib/amazon/mws/response/order/models/promotion_id.rb +9 -0
  117. data/lib/amazon/mws/response/order/request_get_order_response.rb +15 -0
  118. data/lib/amazon/mws/response/order/request_order_items_response.rb +25 -0
  119. data/lib/amazon/mws/response/order/request_orders_response.rb +28 -0
  120. data/lib/amazon/mws/response/product/get_matching_proudct.rb +31 -0
  121. data/lib/amazon/mws/response/product/models/product.rb +36 -0
  122. data/lib/amazon/mws/response/report/cancel_report_requests_response.rb +16 -0
  123. data/lib/amazon/mws/response/report/get_report_count_response.rb +13 -0
  124. data/lib/amazon/mws/response/report/get_report_list_response.rb +17 -0
  125. data/lib/amazon/mws/response/report/get_report_request_count_response.rb +13 -0
  126. data/lib/amazon/mws/response/report/get_report_request_list_by_next_token_response.rb +17 -0
  127. data/lib/amazon/mws/response/report/get_report_request_list_response.rb +17 -0
  128. data/lib/amazon/mws/response/report/get_report_schedule_count_response.rb +13 -0
  129. data/lib/amazon/mws/response/report/get_report_schedule_list_by_next_token_response.rb +17 -0
  130. data/lib/amazon/mws/response/report/get_report_schedule_list_response.rb +17 -0
  131. data/lib/amazon/mws/response/report/manage_report_schedule_response.rb +16 -0
  132. data/lib/amazon/mws/response/report/models/report_info.rb +16 -0
  133. data/lib/amazon/mws/response/report/models/report_request.rb +20 -0
  134. data/lib/amazon/mws/response/report/models/report_schedule.rb +13 -0
  135. data/lib/amazon/mws/response/report/request_report_response.rb +15 -0
  136. data/lib/amazon/mws/response/report/update_reports_acknowledgements_response.rb +16 -0
  137. data/lib/amazon/mws/response/response.rb +43 -0
  138. data/lib/amazon/mws/response/response_error.rb +21 -0
  139. data/test/connection_test.rb +14 -0
  140. data/test/feed_builder_test.rb +74 -0
  141. data/test/feed_test.rb +144 -0
  142. data/test/fulfillment_order.rb +49 -0
  143. data/test/orders_test.rb +78 -0
  144. data/test/products_test.rb +28 -0
  145. data/test/query_string_test.rb +18 -0
  146. data/test/report_test.rb +88 -0
  147. data/test/response_test.rb +172 -0
  148. data/test/signature_test.rb +32 -0
  149. data/test/test_config.yml +6 -0
  150. data/test/test_helper.rb +33 -0
  151. metadata +335 -0
@@ -0,0 +1,98 @@
1
+ <?xml version="1.0"?>
2
+ <!-- Revision="$Revision: #6 $" -->
3
+ <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
4
+ <!--
5
+ $Date: 2007/01/18 $
6
+
7
+ AMAZON.COM CONFIDENTIAL. This document and the information contained in it are
8
+ confidential and proprietary information of Amazon.com and may not be reproduced,
9
+ distributed or used, in whole or in part, for any purpose other than as necessary
10
+ to list products for sale on the www.amazon.com web site pursuant to an agreement
11
+ with Amazon.com.
12
+ -->
13
+ <xsd:include schemaLocation="amzn-base.xsd"/>
14
+ <xsd:include schemaLocation="amzn-header.xsd"/>
15
+ <xsd:include schemaLocation="FulfillmentCenter.xsd"/>
16
+ <xsd:include schemaLocation="Inventory.xsd"/>
17
+ <xsd:include schemaLocation="Listings.xsd"/>
18
+ <xsd:include schemaLocation="OrderAcknowledgement.xsd"/>
19
+ <xsd:include schemaLocation="OrderAdjustment.xsd"/>
20
+ <xsd:include schemaLocation="OrderFulfillment.xsd"/>
21
+
22
+ <xsd:include schemaLocation="Override.xsd"/>
23
+ <xsd:include schemaLocation="Price.xsd"/>
24
+ <xsd:include schemaLocation="ProcessingReport.xsd"/>
25
+ <xsd:include schemaLocation="ProductImage.xsd"/>
26
+ <xsd:include schemaLocation="Product.xsd"/>
27
+ <xsd:include schemaLocation="Relationship.xsd"/>
28
+ <xsd:include schemaLocation="SettlementReport.xsd"/>
29
+ <xsd:element name="AmazonEnvelope">
30
+ <xsd:complexType>
31
+ <xsd:sequence>
32
+ <xsd:element ref="Header"/>
33
+ <xsd:element name="MessageType">
34
+ <xsd:simpleType>
35
+ <xsd:restriction base="xsd:string">
36
+ <xsd:enumeration value="FulfillmentCenter"/>
37
+ <xsd:enumeration value="Inventory"/>
38
+ <xsd:enumeration value="Listings"/>
39
+ <xsd:enumeration value="OrderAcknowledgement"/>
40
+ <xsd:enumeration value="OrderAdjustment"/>
41
+ <xsd:enumeration value="OrderFulfillment"/>
42
+ <xsd:enumeration value="Override"/>
43
+ <xsd:enumeration value="Price"/>
44
+ <xsd:enumeration value="ProcessingReport"/>
45
+ <xsd:enumeration value="Product"/>
46
+ <xsd:enumeration value="ProductImage"/>
47
+ <xsd:enumeration value="Relationship"/>
48
+ <xsd:enumeration value="SettlementReport"/>
49
+ </xsd:restriction>
50
+ </xsd:simpleType>
51
+ </xsd:element>
52
+ <xsd:element ref="MarketplaceName" minOccurs="0">
53
+ <xsd:annotation>
54
+ <xsd:documentation>
55
+ The MarketplaceName is only supported for
56
+ Override feeds.
57
+ If included here, the MarketplaceName will
58
+ apply to all messages in the feed.
59
+ </xsd:documentation>
60
+ </xsd:annotation>
61
+ </xsd:element>
62
+ <xsd:element name="PurgeAndReplace" type="xsd:boolean" minOccurs="0"/>
63
+ <xsd:element name="EffectiveDate" type="xsd:dateTime" minOccurs="0"/>
64
+ <xsd:element name="Message" maxOccurs="unbounded">
65
+ <xsd:complexType>
66
+ <xsd:sequence>
67
+ <xsd:element name="MessageID" type="IDNumber"/>
68
+ <xsd:element name="OperationType" minOccurs="0">
69
+ <xsd:simpleType>
70
+ <xsd:restriction base="xsd:string">
71
+ <xsd:enumeration value="Update"/>
72
+ <xsd:enumeration value="Delete"/>
73
+ <xsd:enumeration value="PartialUpdate"/>
74
+ </xsd:restriction>
75
+ </xsd:simpleType>
76
+ </xsd:element>
77
+ <xsd:choice>
78
+ <xsd:element ref="FulfillmentCenter"/>
79
+ <xsd:element ref="Inventory"/>
80
+ <xsd:element ref="Listings"/>
81
+ <xsd:element ref="OrderAcknowledgement"/>
82
+ <xsd:element ref="OrderAdjustment"/>
83
+ <xsd:element ref="OrderFulfillment"/>
84
+ <xsd:element ref="Override"/>
85
+ <xsd:element ref="Price"/>
86
+ <xsd:element ref="ProcessingReport"/>
87
+ <xsd:element ref="Product"/>
88
+ <xsd:element ref="ProductImage"/>
89
+ <xsd:element ref="Relationship"/>
90
+ <xsd:element ref="SettlementReport"/>
91
+ </xsd:choice>
92
+ </xsd:sequence>
93
+ </xsd:complexType>
94
+ </xsd:element>
95
+ </xsd:sequence>
96
+ </xsd:complexType>
97
+ </xsd:element>
98
+ </xsd:schema>
@@ -0,0 +1,45 @@
1
+ <?xml version="1.0"?>
2
+ <!-- "$Revision: #3 $" -->
3
+ <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
4
+
5
+ <!--
6
+ $Date: 2005/04/01 $
7
+
8
+ AMAZON.COM CONFIDENTIAL. This document and the information contained in it are
9
+ confidential and proprietary information of Amazon.com and may not be reproduced,
10
+ distributed or used, in whole or in part, for any purpose other than as necessary
11
+ to list products for sale on the www.amazon.com web site pursuant to an agreement
12
+ with Amazon.com.
13
+ -->
14
+
15
+ <xsd:include schemaLocation="amzn-base.xsd"/>
16
+
17
+ <xsd:element name="Header">
18
+ <xsd:complexType>
19
+ <xsd:sequence>
20
+
21
+ <xsd:element name="DocumentVersion">
22
+ <xsd:simpleType>
23
+ <xsd:restriction base="xsd:string">
24
+ <xsd:pattern value="\d{1,2}\.\d{1,2}"/>
25
+ </xsd:restriction>
26
+ </xsd:simpleType>
27
+ </xsd:element>
28
+
29
+ <xsd:element name="MerchantIdentifier" type="String"/>
30
+
31
+ <xsd:element name="OverrideReleaseId" minOccurs="0">
32
+ <xsd:simpleType>
33
+ <xsd:restriction base="xsd:string">
34
+ <xsd:pattern value="\d{1,4}\.\d{1,4}"/>
35
+ </xsd:restriction>
36
+ </xsd:simpleType>
37
+ </xsd:element>
38
+
39
+ </xsd:sequence>
40
+ </xsd:complexType>
41
+ </xsd:element>
42
+
43
+ </xsd:schema>
44
+
45
+
@@ -0,0 +1,6 @@
1
+ require 'amazon/mws'
2
+
3
+ module Amazon
4
+ module MWS
5
+ end
6
+ end
@@ -0,0 +1,69 @@
1
+ #require 'rubygems'
2
+ require 'cgi'
3
+ require 'uri'
4
+ require 'openssl'
5
+ require 'net/https'
6
+ require 'time'
7
+ require 'date'
8
+ require 'hmac'
9
+ require 'hmac-sha2'
10
+ require 'base64'
11
+ require 'builder'
12
+ require "rexml/document"
13
+ require 'roxml'
14
+
15
+ $:.unshift(File.dirname(__FILE__))
16
+ require 'mws/lib/extensions'
17
+ require 'builder'
18
+ #require_library_or_gem 'mime/types', 'mime-types' unless defined? MIME::Types
19
+
20
+ require 'mws/lib/memoizable'
21
+
22
+ require 'mws/request/feed_builder'
23
+ require 'mws/request/feed'
24
+ require 'mws/request/report'
25
+ require 'mws/request/products'
26
+ require 'mws/request/fulfillment'
27
+ require 'mws/request/orders'
28
+
29
+ require 'mws/response/response'
30
+ Dir.glob(File.join(File.dirname(__FILE__), 'mws/response/**/*.rb')).each {|f| require f }
31
+
32
+ require 'mws/base'
33
+ require 'mws/exceptions'
34
+ require 'mws/connection'
35
+ require 'mws/connection/request_builder'
36
+ require 'mws/authentication'
37
+ require 'mws/authentication/query_string'
38
+ require 'mws/authentication/signature'
39
+
40
+ Amazon::MWS::Base.class_eval do
41
+ include Amazon::MWS::Feed
42
+ include Amazon::MWS::Report
43
+ include Amazon::MWS::Orders
44
+ include Amazon::MWS::Products
45
+ include Amazon::MWS::Fulfillment
46
+ end
47
+
48
+ #AWS = Amazon
49
+
50
+ #require_library_or_gem 'xmlsimple', 'xml-simple' unless defined? XmlSimple
51
+ gem 'xml-simple'
52
+
53
+ =begin
54
+ # If libxml is installed, we use the FasterXmlSimple library, that provides most of the functionality of XmlSimple
55
+ # except it uses the xml/libxml library for xml parsing (rather than REXML). If libxml isn't installed, we just fall back on
56
+ # XmlSimple.
57
+ AWS::S3::Parsing.parser =
58
+ begin
59
+ require_library_or_gem 'xml/libxml'
60
+ # Older version of libxml aren't stable (bus error when requesting attributes that don't exist) so we
61
+ # have to use a version greater than '0.3.8.2'.
62
+ raise LoadError unless XML::Parser::VERSION > '0.3.8.2'
63
+ $:.push(File.join(File.dirname(__FILE__), '..', '..', 'support', 'faster-xml-simple', 'lib'))
64
+ require_library_or_gem 'faster_xml_simple'
65
+ FasterXmlSimple
66
+ rescue LoadError
67
+ XmlSimple
68
+ end
69
+ =end
@@ -0,0 +1,10 @@
1
+ module Amazon
2
+ module MWS
3
+ class Authentication
4
+ VERSION = '2009-01-01'
5
+ ORDERS_VERSION = '2011-01-01'
6
+ PRODUCTS_VERSION = '2011-10-01'
7
+ FULFILLMENT_VERSION = '2010-10-01'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,36 @@
1
+ class Amazon::MWS::Authentication
2
+
3
+ class QueryString < String
4
+ def initialize(params = {})
5
+ query_params = {
6
+ 'AWSAccessKeyId' => params[:access_key],
7
+ 'SignatureMethod' => Signature::METHOD,
8
+ 'SignatureVersion' => Signature::VERSION,
9
+ 'Timestamp' => Time.now.iso8601
10
+ }
11
+
12
+ if params[:path].include? 'Orders'
13
+ query_params['SellerId'] = params[:merchant_id]
14
+ query_params['Version'] = Amazon::MWS::Authentication::ORDERS_VERSION
15
+ elsif params[:path].include? 'Products'
16
+ query_params['SellerId'] = params[:merchant_id]
17
+ query_params['Version'] = Amazon::MWS::Authentication::PRODUCTS_VERSION
18
+ else
19
+ query_params['Merchant'] = params[:merchant_id]
20
+ query_params['Version'] = Amazon::MWS::Authentication::VERSION
21
+ end
22
+
23
+ # Add any params that are passed in via uri before calculating the signature
24
+ query_params = query_params.merge(params[:query_params] || {})
25
+ # Calculate the signature
26
+ query_params['Signature'] = Signature.new(query_params, params)
27
+
28
+ self << formatted_querystring(query_params)
29
+ end
30
+
31
+ def formatted_querystring(query_params)
32
+ query_params.collect { |key, value| [CGI.escape(key.to_s), CGI.escape(value.to_s)].join('=') }.join('&') # order doesn't matter for the actual request
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,43 @@
1
+ class Amazon::MWS::Authentication
2
+
3
+ class Signature < String#:nodoc:
4
+ extend Memoizable
5
+
6
+ VERSION = '2'
7
+ METHOD = 'HmacSHA256'
8
+
9
+ def initialize(queryparams = {}, params = {})
10
+ verb = params[:verb]
11
+ secret = params[:secret_access_key]
12
+ # Create the string to sign
13
+ string = string_to_sign(verb, canonical_querystring(queryparams), params[:server], params[:path])
14
+ self << sign(string, secret)
15
+ end
16
+
17
+ # Returns a signed string
18
+ def sign(string, secret_access_key)
19
+ hmac = HMAC::SHA256.new(secret_access_key)
20
+ hmac.update(string)
21
+ # chomp is important! the base64 encoded version will have a newline at the end
22
+ Base64.encode64(hmac.digest).chomp
23
+ end
24
+
25
+ memoize :sign
26
+
27
+ def string_to_sign(verb, querystring, server, path)
28
+ verb = verb.to_s.upcase
29
+ string = "#{verb}\n#{server}\n#{path}\n#{querystring}"
30
+ end
31
+
32
+ memoize :string_to_sign
33
+
34
+ def canonical_querystring(params)
35
+ # Make sure we have string keys, otherwise the sort does not work
36
+ params = Hash.keys_to_s(params)
37
+ params.sort.collect { |key, value| [CGI.escape(key.to_s), CGI.escape(value.to_s)].join('=') }.join('&')
38
+ end
39
+
40
+ memoize :canonical_querystring
41
+ end
42
+
43
+ end
@@ -0,0 +1,74 @@
1
+ module Amazon
2
+ module MWS
3
+ HOSTS = {
4
+ :ca => "mws.amazonservices.ca",
5
+ :cn => "mws.amazonservices.com.cn",
6
+ :de => "mws-eu.amazonservices.com",
7
+ :es => "mws-eu.amazonservices.com",
8
+ :fr => "mws-eu.amazonservices.com",
9
+ :in => "mws.amazonservices.in",
10
+ :it => "mws-eu.amazonservices.com",
11
+ :jp => "mws.amazonservices.jp",
12
+ :uk => "mws-eu.amazonservices.com",
13
+ :us => "mws.amazonservices.com"
14
+ }
15
+
16
+ class Base
17
+ attr_accessor :connection
18
+
19
+ def self.debug; @@debug ||= false end
20
+ def self.debug=(bool); @@debug = bool end
21
+
22
+ def initialize(options ={})
23
+ @merchant_id = options['merchant_id']
24
+ raise "Must supply merchant_id" unless @merchant_id
25
+ @connection = Amazon::MWS::Connection.connect(options)
26
+ end
27
+
28
+ def connection
29
+ raise Amazon::MWS::NoConnectionEstablished.new if !connected?
30
+ @connection
31
+ end
32
+
33
+ def connected?
34
+ !@connection.nil?
35
+ end
36
+
37
+ #def disconnect
38
+ # @connection.http.finish if @connection.persistent?
39
+ # @connection = nil
40
+ #end
41
+
42
+ # Wraps the current connection's request method and picks the appropriate response class to wrap the response in.
43
+ # If the response is an error, it will raise that error as an exception. All such exceptions can be caught by rescuing
44
+ # their superclass, the ResponseError exception class.
45
+ #
46
+ # It is unlikely that you would call this method directly. Subclasses of Base have convenience methods for each http request verb
47
+ # that wrap calls to request.
48
+ def request(verb, path, query_params = {}, body = nil, attempts = 0, &block)
49
+ # Find the connection method in connection/management.rb which is evaled into Amazon::MWS::Base
50
+ response = @connection.request(verb, path, query_params, body, attempts, &block)
51
+
52
+ # Each calling class is responsible for formatting the result
53
+ return response
54
+ rescue InternalError, RequestTimeout
55
+ if attempts == 3
56
+ raise
57
+ else
58
+ attempts += 1
59
+ retry
60
+ end
61
+ end
62
+
63
+ # Make some convenience methods
64
+ [:get, :post, :put, :delete, :head].each do |verb|
65
+ class_eval(<<-EVAL, __FILE__, __LINE__)
66
+ def #{verb}(path, query_params = {}, body = nil, &block)
67
+ request(:#{verb}, path, query_params, body, &block)
68
+ end
69
+ EVAL
70
+ end
71
+ end
72
+
73
+ end
74
+ end
@@ -0,0 +1,107 @@
1
+ module Amazon
2
+ module MWS
3
+
4
+ class Connection
5
+
6
+ attr_reader :server, :access_key, :merchant_id, :marketplace_id, :locale
7
+
8
+ # Static/Class methods
9
+ class << self
10
+ def connect(options = {})
11
+ new(options)
12
+ end
13
+ end
14
+
15
+ def initialize(params = {})
16
+ # These values are essential to establishing a connection
17
+ @locale = (params['locale'] || "us").downcase.to_sym
18
+ @server = HOSTS[locale]
19
+ #@persistent = params['persistent'] || false
20
+ # These values are essential to signing requests
21
+ @access_key = params['access_key']
22
+ @secret_access_key = params['secret_access_key']
23
+ @merchant_id = params['merchant_id']
24
+ @marketplace_id = params['marketplace_id']
25
+ @path = '/'
26
+
27
+ raise MissingConnectionOptions if [@access_key, @secret_access_key, @merchant_id, @marketplace_id].any? {|option| option.nil?}
28
+
29
+ @http = connect
30
+ end
31
+
32
+ # Create the Net::HTTP object to use for this connection
33
+ def connect
34
+ http = Net::HTTP.new(@server, 443)
35
+ http.use_ssl = true
36
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
37
+ return http
38
+ end
39
+
40
+ # Make the request, based on the appropriate request object
41
+ # Called from Amazon::MWS::Base
42
+ def request(verb, path, query_params, body = nil, attempts = 0, &block)
43
+ @path = path
44
+ # presumably this is for files
45
+ body.rewind if body.respond_to?(:rewind) unless attempts.zero?
46
+ # Prepare the Proc to be called by Net::HTTP
47
+ proc = requester(verb, path, query_params, body)
48
+
49
+ #if @persistent
50
+ # @http.start unless @http.started?
51
+ # proc.call
52
+ #else
53
+ @http.start(&proc)
54
+ #end
55
+ rescue Errno::EPIPE, Timeout::Error, Errno::EINVAL, EOFError
56
+ @http = connect
57
+ attempts == 3 ? raise : (attempts += 1; retry)
58
+ end
59
+
60
+ # A Proc used by the request method
61
+ def requester(verb, path, query_params, body)
62
+ Proc.new do |http|
63
+ path = prepare_path(verb, path, query_params)
64
+ puts "#{path}\n\n" if Amazon::MWS::Base.debug
65
+ request = build_request(verb, path, body)
66
+
67
+ @http.request(request)
68
+ end
69
+ end
70
+
71
+ # Create the signed authentication query string.
72
+ # Add this query string to the path WITHOUT prepending the server address.
73
+ def prepare_path(verb, path, query_params)
74
+ query_string = authenticate_query_string(verb, query_params)
75
+ return "#{path}?#{query_string}"
76
+ end
77
+
78
+ # Generates the authentication query string used by Amazon.
79
+ # Takes the http method and the query string of the request and returns the authenticated query string
80
+ def authenticate_query_string(verb, query_params = {})
81
+ Authentication::QueryString.new(
82
+ :verb => verb,
83
+ :query_params => query_params,
84
+ :access_key => @access_key,
85
+ :secret_access_key => @secret_access_key,
86
+ :merchant_id => @merchant_id,
87
+ :marketplace_id => @marketplace_id,
88
+ :server => @server,
89
+ :path => @path
90
+ )
91
+ end
92
+
93
+ # Builds up a Net::HTTP request object
94
+ def build_request(verb, path, body = nil)
95
+ builder = RequestBuilder.new(verb, path, body)
96
+ builder.add_user_agent
97
+ builder.add_content_type
98
+ builder.add_content_md5(body) unless body.nil?
99
+
100
+ return builder.request
101
+ end
102
+ end
103
+ # Connection
104
+
105
+ end
106
+ end
107
+