amazon-ecs 2.3.2 → 2.4.0
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 +4 -4
- data/CHANGELOG +6 -0
- data/README.md +28 -15
- data/lib/amazon/ecs.rb +33 -5
- data/test/amazon/ecs_test.rb +63 -48
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e39d8758a1f2aa22fcfe7f304ea30d1198d020b
|
4
|
+
data.tar.gz: 001438e4be846c70cd283d2f8f8d260eea37bef4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 736d9a9a30ab25fa2d5dc0201374fd2cc5f34244fb78ad5579745718b7e6f24414cb52c1f17d4a685641d1890e55adace4727d8ce56528794c4a57bf0194838e
|
7
|
+
data.tar.gz: cf3064f04d981f34aa08beffc9bb41a70c562a063424477f88830d5fdbb7aabb2b017a56cd817a563d8564ee81607c399679fc813aae2b8fa9fb136b83bce241
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
2.4.0 2016-01-05
|
2
|
+
----------------
|
3
|
+
* Upgrade API version to 2013-08-01
|
4
|
+
* Add browse_node_lookup and similarity_lookup methods on Amaon::Ecs
|
5
|
+
* Add /, get_elements, and get_element methods on Amazon::Ecs::Response
|
6
|
+
|
1
7
|
2.3.2 2015-01-04
|
2
8
|
----------------
|
3
9
|
* Add support for Amazon MX
|
data/README.md
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
`amazon-ecs` is a generic Ruby wrapper to access Amazon Product Advertising API.
|
4
4
|
|
5
|
-
You can easily extend the library to support any of the operations supported by the API.
|
5
|
+
You can easily extend the library to support any of the operations supported by the API.
|
6
6
|
|
7
|
-
The library wraps around Nokogiri element object. It provides an easy access to the XML response
|
7
|
+
The library wraps around Nokogiri element object. It provides an easy access to the XML response
|
8
8
|
structure through an XML path instead of an object attribute. The idea is the API evolves,
|
9
9
|
there will be changes to the XML schema. With `amazon-ecs`, your code will still work, only
|
10
10
|
the XML path needs to be updated.
|
@@ -21,9 +21,9 @@ gem install amazon-ecs
|
|
21
21
|
require 'amazon/ecs'
|
22
22
|
|
23
23
|
# Configure your access key, secret key and other options such as the associate tag.
|
24
|
-
# Options set in the configure block will be merged with the pre-configured default
|
24
|
+
# Options set in the configure block will be merged with the pre-configured default
|
25
25
|
# options, i.e.
|
26
|
-
# options[:version] => "
|
26
|
+
# options[:version] => "2013-08-01"
|
27
27
|
# options[:service] => "AWSECommerceService"
|
28
28
|
Amazon::Ecs.configure do |options|
|
29
29
|
options[:AWS_access_key_id] = '[your access key]'
|
@@ -76,10 +76,10 @@ res.items.each do |item|
|
|
76
76
|
|
77
77
|
# return the first matching path as Amazon::Element
|
78
78
|
item_height = item.get_element('ItemDimensions/Height')
|
79
|
-
|
79
|
+
|
80
80
|
# retrieve attributes from Amazon::Element
|
81
81
|
item_height.attributes['Units'] # 'hundredths-inches'
|
82
|
-
|
82
|
+
|
83
83
|
# return an array of Amazon::Element
|
84
84
|
authors = item.get_elements('Author')
|
85
85
|
|
@@ -94,7 +94,7 @@ res.items.each do |item|
|
|
94
94
|
# Or to get unescaped HTML values
|
95
95
|
Amazon::Element.get_unescaped(review, 'Source')
|
96
96
|
Amazon::Element.get_unescaped(review, 'Content')
|
97
|
-
|
97
|
+
|
98
98
|
# Or this way
|
99
99
|
el = Amazon::Element.new(review)
|
100
100
|
el.get_unescaped('Source')
|
@@ -103,26 +103,39 @@ res.items.each do |item|
|
|
103
103
|
end
|
104
104
|
```
|
105
105
|
|
106
|
-
|
106
|
+
Other Operations
|
107
|
+
|
107
108
|
```ruby
|
108
|
-
|
109
|
-
Amazon::
|
109
|
+
# Browse node lookup
|
110
|
+
resp = Amazon::ECS.browse_node_lookup("17")
|
111
|
+
|
112
|
+
nodes = resp.get_elements("BrowseNode")
|
113
|
+
nodes.each do |node|
|
114
|
+
puts node.get_unescaped('BrowseNodeId')
|
115
|
+
puts node.get_unescaped('Name')
|
116
|
+
end
|
117
|
+
|
118
|
+
# Similarity lookup
|
119
|
+
Amazon::ECS.similarity_lookup("0974514055")
|
120
|
+
|
121
|
+
# Other operation
|
122
|
+
Amazon::Ecs.send_request(:operation => '[OperationName]', :id => 123)
|
110
123
|
```
|
111
124
|
|
112
125
|
Or you could extend `Amazon::Ecs`:
|
113
126
|
```ruby
|
114
127
|
module Amazon
|
115
128
|
class Ecs
|
116
|
-
def self.
|
117
|
-
opts[:operation] = '
|
118
|
-
opts[:
|
119
|
-
|
129
|
+
def self.custom_method(id, opts={})
|
130
|
+
opts[:operation] = '[OperationName]'
|
131
|
+
opts[:id] = id
|
132
|
+
|
120
133
|
self.send_request(opts)
|
121
134
|
end
|
122
135
|
end
|
123
136
|
end
|
124
137
|
|
125
|
-
Amazon::Ecs.
|
138
|
+
Amazon::Ecs.custom_method(123, :param1 => 'abc', :param2 => 'xyz')
|
126
139
|
```
|
127
140
|
|
128
141
|
Refer to [Amazon Product Advertising API](https://affiliate-program.amazon.com/gp/advertising/api/detail/main.html) documentation for more information on the operations and request parameters supported.
|
data/lib/amazon/ecs.rb
CHANGED
@@ -32,7 +32,7 @@ module Amazon
|
|
32
32
|
class RequestError < StandardError; end
|
33
33
|
|
34
34
|
class Ecs
|
35
|
-
VERSION = '2.
|
35
|
+
VERSION = '2.4.0'
|
36
36
|
|
37
37
|
SERVICE_URLS = {
|
38
38
|
:us => 'http://webservices.amazon.com/onca/xml',
|
@@ -55,7 +55,7 @@ module Amazon
|
|
55
55
|
OPENSSL_DIGEST = OpenSSL::Digest.new( 'sha256' ) if OPENSSL_DIGEST_SUPPORT
|
56
56
|
|
57
57
|
@@options = {
|
58
|
-
:version => "
|
58
|
+
:version => "2013-08-01",
|
59
59
|
:service => "AWSECommerceService"
|
60
60
|
}
|
61
61
|
|
@@ -110,7 +110,7 @@ module Amazon
|
|
110
110
|
self.send_request(opts)
|
111
111
|
end
|
112
112
|
|
113
|
-
#
|
113
|
+
# Browse node lookup by node ID.
|
114
114
|
def self.browse_node_lookup(browse_node_id, opts = {})
|
115
115
|
opts[:operation] = 'BrowseNodeLookup'
|
116
116
|
opts[:browse_node_id] = browse_node_id
|
@@ -118,6 +118,14 @@ module Amazon
|
|
118
118
|
self.send_request(opts)
|
119
119
|
end
|
120
120
|
|
121
|
+
# Similarity lookup by item ID.
|
122
|
+
def self.similarity_lookup(item_id, opts = {})
|
123
|
+
opts[:operation] = 'SimilarityLookup'
|
124
|
+
opts[:item_id] = item_id
|
125
|
+
|
126
|
+
self.send_request(opts)
|
127
|
+
end
|
128
|
+
|
121
129
|
# Generic send request to ECS REST service. You have to specify the :operation parameter.
|
122
130
|
def self.send_request(opts)
|
123
131
|
opts = self.options.merge(opts) if self.options
|
@@ -155,6 +163,26 @@ module Amazon
|
|
155
163
|
@doc
|
156
164
|
end
|
157
165
|
|
166
|
+
# Return a Nokogiri::XML::NodeSet of elements matching the given path.
|
167
|
+
def /(path)
|
168
|
+
elements = @doc/path
|
169
|
+
return nil if elements.size == 0
|
170
|
+
elements
|
171
|
+
end
|
172
|
+
|
173
|
+
# Return an array of Amazon::Element matching the given path
|
174
|
+
def get_elements(path)
|
175
|
+
elements = self./(path)
|
176
|
+
return unless elements
|
177
|
+
elements = elements.map{|element| Element.new(element)}
|
178
|
+
end
|
179
|
+
|
180
|
+
# Return the first element found
|
181
|
+
def get_element(path)
|
182
|
+
elements = get_elements(path)
|
183
|
+
elements[0] if elements
|
184
|
+
end
|
185
|
+
|
158
186
|
# Return true if request is valid.
|
159
187
|
def is_valid_request?
|
160
188
|
Element.get(@doc, "//IsValid") == "True"
|
@@ -334,12 +362,12 @@ module Amazon
|
|
334
362
|
@element = element
|
335
363
|
end
|
336
364
|
|
337
|
-
#
|
365
|
+
# Return Nokogiri::XML::Element object
|
338
366
|
def elem
|
339
367
|
@element
|
340
368
|
end
|
341
369
|
|
342
|
-
#
|
370
|
+
# Return a Nokogiri::XML::NodeSet of elements matching the given path. Example: element/"author".
|
343
371
|
def /(path)
|
344
372
|
elements = @element/path
|
345
373
|
return nil if elements.size == 0
|
data/test/amazon/ecs_test.rb
CHANGED
@@ -9,23 +9,22 @@ class Amazon::EcsTest < Test::Unit::TestCase
|
|
9
9
|
|
10
10
|
AWS_ACCESS_KEY_ID = ENV['AWS_ACCESS_KEY_ID'] || ''
|
11
11
|
AWS_SECRET_KEY = ENV['AWS_SECRET_KEY'] || ''
|
12
|
-
|
13
|
-
raise "
|
14
|
-
raise "
|
15
|
-
|
12
|
+
|
13
|
+
raise "AWS_ACCESS_KEY_ID env variable is not set" if AWS_ACCESS_KEY_ID.empty?
|
14
|
+
raise "AWS_SECRET_KEY env variable is not set" if AWS_SECRET_KEY.empty?
|
15
|
+
|
16
16
|
Amazon::Ecs.configure do |options|
|
17
|
-
options[:response_group] = 'Large'
|
18
17
|
options[:AWS_access_key_id] = AWS_ACCESS_KEY_ID
|
19
18
|
options[:AWS_secret_key] = AWS_SECRET_KEY
|
20
19
|
options[:associate_tag] = 'bookjetty-20'
|
21
20
|
end
|
22
|
-
|
21
|
+
|
23
22
|
# To print debug information
|
24
23
|
# Amazon::Ecs.debug = true
|
25
24
|
|
26
25
|
# Test item_search
|
27
26
|
def test_item_search
|
28
|
-
resp = Amazon::Ecs.item_search('ruby')
|
27
|
+
resp = Amazon::Ecs.item_search('ruby')
|
29
28
|
assert resp.is_valid_request?,
|
30
29
|
"Not a valid request"
|
31
30
|
assert (resp.total_results >= 3600),
|
@@ -33,67 +32,67 @@ class Amazon::EcsTest < Test::Unit::TestCase
|
|
33
32
|
assert (resp.total_pages >= 360),
|
34
33
|
"Pages returned (#{resp.total_pages}) were < 360"
|
35
34
|
end
|
36
|
-
|
35
|
+
|
37
36
|
def test_item_search_with_special_characters
|
38
37
|
resp = Amazon::Ecs.item_search('()*&^%$')
|
39
38
|
assert resp.is_valid_request?,
|
40
39
|
"Not a valid request"
|
41
40
|
end
|
42
|
-
|
41
|
+
|
43
42
|
def test_item_search_with_paging
|
44
43
|
resp = Amazon::Ecs.item_search('ruby', :item_page => 2)
|
45
|
-
assert resp.is_valid_request?,
|
44
|
+
assert resp.is_valid_request?,
|
46
45
|
"Not a valid request"
|
47
46
|
assert_equal 2, resp.item_page,
|
48
47
|
"Page returned (#{resp.item_page}) different from expected (2)"
|
49
48
|
end
|
50
|
-
|
49
|
+
|
51
50
|
def test_item_search_with_invalid_request
|
52
51
|
resp = Amazon::Ecs.item_search(nil)
|
53
|
-
assert !resp.is_valid_request?,
|
52
|
+
assert !resp.is_valid_request?,
|
54
53
|
"Expected invalid request error"
|
55
54
|
end
|
56
|
-
|
55
|
+
|
57
56
|
def test_item_search_with_no_result
|
58
|
-
resp = Amazon::Ecs.item_search('afdsafds')
|
59
|
-
assert resp.is_valid_request?,
|
57
|
+
resp = Amazon::Ecs.item_search('afdsafds')
|
58
|
+
assert resp.is_valid_request?,
|
60
59
|
"Not a valid request"
|
61
|
-
assert_equal "We did not find any matches for your request.", resp.error,
|
60
|
+
assert_equal "We did not find any matches for your request.", resp.error,
|
62
61
|
"Error string different from expected"
|
63
62
|
end
|
64
|
-
|
63
|
+
|
65
64
|
def test_utf8_encoding
|
66
65
|
resp = Amazon::Ecs.item_search('ruby', :country => :uk)
|
67
|
-
assert resp.is_valid_request?,
|
66
|
+
assert resp.is_valid_request?,
|
68
67
|
"Not a valid request"
|
69
68
|
item = resp.first_item
|
70
69
|
assert_no_match /\A&#x.*/, item.get_unescaped("//FormattedPrice"),
|
71
70
|
"£ sign converted to ASCII from UTF-8"
|
72
71
|
end
|
73
|
-
|
72
|
+
|
74
73
|
def test_item_search_by_author
|
75
74
|
resp = Amazon::Ecs.item_search('dave', :type => :author)
|
76
|
-
assert resp.is_valid_request?,
|
75
|
+
assert resp.is_valid_request?,
|
77
76
|
"Not a valid request"
|
78
77
|
end
|
79
|
-
|
78
|
+
|
80
79
|
def test_item_get
|
81
|
-
resp = Amazon::Ecs.item_search("0974514055")
|
80
|
+
resp = Amazon::Ecs.item_search("0974514055", :response_group => 'Large')
|
82
81
|
item = resp.first_item
|
83
|
-
|
82
|
+
|
84
83
|
# test get
|
85
|
-
assert_equal "Programming Ruby: The Pragmatic Programmers' Guide, Second Edition",
|
86
|
-
item.get("ItemAttributes/Title"),
|
84
|
+
assert_equal "Programming Ruby: The Pragmatic Programmers' Guide, Second Edition",
|
85
|
+
item.get("ItemAttributes/Title"),
|
87
86
|
"Title different from expected"
|
88
|
-
|
87
|
+
|
89
88
|
# test get_array
|
90
|
-
assert_equal ['Dave Thomas', 'Chad Fowler', 'Andy Hunt'],
|
91
|
-
item.get_array("Author"),
|
89
|
+
assert_equal ['Dave Thomas', 'Chad Fowler', 'Andy Hunt'],
|
90
|
+
item.get_array("Author"),
|
92
91
|
"Authors Array different from expected"
|
93
|
-
|
92
|
+
|
94
93
|
# test get_hash
|
95
94
|
small_image = item.get_hash("SmallImage")
|
96
|
-
|
95
|
+
|
97
96
|
assert_equal 3, small_image.keys.size,
|
98
97
|
"Image hash key count (#{small_image.keys.size}) different from expected (3)"
|
99
98
|
assert_match ".jpg", small_image['URL'],
|
@@ -102,7 +101,7 @@ class Amazon::EcsTest < Test::Unit::TestCase
|
|
102
101
|
"Image height (#{small_image['Height']}) different from expected (75)"
|
103
102
|
assert_equal "59", small_image['Width'],
|
104
103
|
"Image width (#{small_image['Width']}) different from expected (59)"
|
105
|
-
|
104
|
+
|
106
105
|
# test /
|
107
106
|
reviews = item/"EditorialReview"
|
108
107
|
reviews.each do |review|
|
@@ -113,15 +112,15 @@ class Amazon::EcsTest < Test::Unit::TestCase
|
|
113
112
|
"XPath editorialreview failed to get content"
|
114
113
|
end
|
115
114
|
end
|
116
|
-
|
115
|
+
|
117
116
|
## Test item_lookup
|
118
117
|
def test_item_lookup
|
119
118
|
resp = Amazon::Ecs.item_lookup('0974514055')
|
120
|
-
assert_equal "Programming Ruby: The Pragmatic Programmers' Guide, Second Edition",
|
119
|
+
assert_equal "Programming Ruby: The Pragmatic Programmers' Guide, Second Edition",
|
121
120
|
resp.first_item.get("ItemAttributes/Title"),
|
122
121
|
"Title different from expected"
|
123
122
|
end
|
124
|
-
|
123
|
+
|
125
124
|
def test_item_lookup_with_invalid_request
|
126
125
|
resp = Amazon::Ecs.item_lookup(nil)
|
127
126
|
assert resp.has_error?,
|
@@ -129,19 +128,19 @@ class Amazon::EcsTest < Test::Unit::TestCase
|
|
129
128
|
assert resp.error,
|
130
129
|
"Response should have contained an error"
|
131
130
|
end
|
132
|
-
|
131
|
+
|
133
132
|
def test_item_lookup_with_no_result
|
134
|
-
resp = Amazon::Ecs.item_lookup('abc')
|
133
|
+
resp = Amazon::Ecs.item_lookup('abc')
|
135
134
|
assert resp.is_valid_request?,
|
136
135
|
"Not a valid request"
|
137
|
-
assert_match /ABC is not a valid value for ItemId/, resp.error,
|
136
|
+
assert_match /ABC is not a valid value for ItemId/, resp.error,
|
138
137
|
"Error Message for lookup of ASIN = ABC different from expected"
|
139
138
|
end
|
140
|
-
|
139
|
+
|
141
140
|
def test_get_elements
|
142
141
|
resp = Amazon::Ecs.item_lookup('0974514055')
|
143
142
|
item = resp.first_item
|
144
|
-
|
143
|
+
|
145
144
|
authors = item.get_elements("Author")
|
146
145
|
assert_instance_of Array, authors,
|
147
146
|
"Authors should be an Array"
|
@@ -151,24 +150,24 @@ class Amazon::EcsTest < Test::Unit::TestCase
|
|
151
150
|
"Authors array first element (#{authors.first.class}) should be an Amazon::Element"
|
152
151
|
assert_equal "Dave Thomas", authors.first.get,
|
153
152
|
"First Author (#{authors.first.get}) different from expected (Dave Thomas)"
|
154
|
-
|
153
|
+
|
155
154
|
asin = item.get_elements("./ASIN")
|
156
155
|
assert_instance_of Array, asin,
|
157
156
|
"ASIN should be an Array"
|
158
157
|
assert_equal 1, asin.size,
|
159
158
|
"ASIN array size (#{asin.size}) different from expected (1)"
|
160
159
|
end
|
161
|
-
|
160
|
+
|
162
161
|
def test_get_element_and_attributes
|
163
|
-
resp = Amazon::Ecs.item_lookup('0974514055')
|
162
|
+
resp = Amazon::Ecs.item_lookup('0974514055', :response_group => 'Large')
|
164
163
|
item = resp.first_item
|
165
|
-
|
164
|
+
|
166
165
|
first_author = item.get_element("Author")
|
167
166
|
assert_equal "Dave Thomas", first_author.get,
|
168
167
|
"First Author (#{first_author.get}) different from expected (Dave Thomas)"
|
169
168
|
assert_nil first_author.attributes['unknown'],
|
170
169
|
"First Author 'unknown' attributes should be nil"
|
171
|
-
|
170
|
+
|
172
171
|
item_height = item.get_element("ItemDimensions/Height")
|
173
172
|
units = item_height.attributes['Units'].inner_html if item_height
|
174
173
|
assert_equal "hundredths-inches", units,
|
@@ -180,22 +179,38 @@ class Amazon::EcsTest < Test::Unit::TestCase
|
|
180
179
|
assert resp.is_valid_request?,
|
181
180
|
"Not a valid request"
|
182
181
|
end
|
183
|
-
|
182
|
+
|
184
183
|
def test_marshal_dump_and_load
|
185
184
|
resp = Amazon::Ecs::Response.new(File.read(File.expand_path('../../fixtures/item_search.xml', __FILE__)))
|
186
185
|
dumped_resp = Marshal.load(Marshal.dump(resp))
|
187
|
-
|
186
|
+
|
188
187
|
assert_equal resp.doc.to_s, dumped_resp.doc.to_s
|
189
188
|
assert_equal resp.items.size, dumped_resp.items.size
|
190
189
|
assert_equal resp.item_page, dumped_resp.item_page
|
191
190
|
assert_equal resp.total_results, dumped_resp.total_results
|
192
191
|
assert_equal resp.total_pages, dumped_resp.total_pages
|
193
192
|
end
|
194
|
-
|
193
|
+
|
194
|
+
def test_browse_node_lookup
|
195
|
+
resp = Amazon::Ecs.browse_node_lookup("17")
|
196
|
+
assert resp.is_valid_request?, "Not a valid request"
|
197
|
+
|
198
|
+
items = resp.get_elements("BrowseNode")
|
199
|
+
assert_equal 24, items.size
|
200
|
+
end
|
201
|
+
|
202
|
+
def test_similarity_lookup
|
203
|
+
resp = Amazon::Ecs.similarity_lookup("0974514055")
|
204
|
+
assert resp.is_valid_request?, "Not a valid request"
|
205
|
+
|
206
|
+
items = resp.get_elements("Item")
|
207
|
+
assert_equal 10, items.size
|
208
|
+
end
|
209
|
+
|
195
210
|
def test_other_service_urls
|
196
211
|
Amazon::Ecs::SERVICE_URLS.each do |key, value|
|
197
212
|
next if key == :us
|
198
|
-
|
213
|
+
|
199
214
|
begin
|
200
215
|
resp = Amazon::Ecs.item_search('ruby', :country => key)
|
201
216
|
assert resp, "#{key} service url (#{value}) is invalid"
|