amazon-ecs 2.5.0 → 2.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 90f10db26290415039bd4ab1d9251cebfd3fa27e
4
- data.tar.gz: 563deba5317a1bd94dfa641f5ed216cb8463654e
2
+ SHA256:
3
+ metadata.gz: 293020f2c842d45f159daf0c0479a7acc50c00e513baf60523e1c64ba6f4194a
4
+ data.tar.gz: 7006f32167b832f9d13ad87825779a0e9b34b5efe17cace5d675addbeeddf169
5
5
  SHA512:
6
- metadata.gz: 522f2e3a0ff2ea59cd61048e0c7275f5ff89d3daaeed71507570d41a119486ac4f9387dc9188d595fc490ed9f59ad1499e9e9bb8cd4f9adc7b9da7cecc14c495
7
- data.tar.gz: f8d41a6bc7e22037647066797ebb2786516ad3a35e05cf27dc3b80b468ed7b87d447315bf70d8860a6ef32b2b4f0cb42cc27cc433701fe4c9c433ae6037fa9bb
6
+ metadata.gz: e7b7c409eba77b66b8b99bf58dc711a05ea2246564dc17ea82c80875cefd28a3989639b56271a1215aef8aaabf348e77e7acd22737b97830fbb36bd9fa063dbb
7
+ data.tar.gz: bb6dc4f05976990f9ab19e51817355b55ad0596622fcecacac1129d431b4b069e399ef245359ba4b50307ed9ad065c4857b69cdfbe27e989e98e664db714241c
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1
4
+ - 2.2
5
+ - 2.3.3
6
+ - 2.4.0
7
+ script: rake test
data/CHANGELOG CHANGED
@@ -1,3 +1,8 @@
1
+ 2.6.0 2019-05-20
2
+ ----------------
3
+ * Upgrade nokogiri dependency
4
+ * Remove ruby-hmac support
5
+
1
6
  2.5.0 2016-07-09
2
7
  ----------------
3
8
  * Turn on debug mode with DEBUG_AMAZON_ECS=1
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # amazon-ecs
2
2
 
3
+ [![Travis CI](https://travis-ci.org/jugend/amazon-ecs.svg?branch=master)](https://travis-ci.org/jugend/amazon-ecs)
4
+
3
5
  `amazon-ecs` is a generic Ruby wrapper to access Amazon Product Advertising API.
4
6
 
5
7
  The library wraps around [Nokogiri](http://www.nokogiri.org/) element object. It provides an easy access to the XML response elements and attributes.
@@ -18,7 +20,7 @@ gem install amazon-ecs
18
20
  ```ruby
19
21
  require 'amazon/ecs'
20
22
 
21
- # default options:
23
+ # Default options:
22
24
  # options[:version] => "2013-08-01"
23
25
  # options[:service] => "AWSECommerceService"
24
26
  Amazon::Ecs.configure do |options|
@@ -27,16 +29,16 @@ Amazon::Ecs.configure do |options|
27
29
  options[:associate_tag] = '[your associate tag]'
28
30
  end
29
31
 
30
- # to overwrite the whole options
32
+ # To replace default options
31
33
  # Amazon::Ecs.options = { ... }
32
34
 
33
- # options will be merged with the default options
35
+ # To override default options
34
36
  res = Amazon::Ecs.item_search('ruby', {:response_group => 'Medium', :sort => 'salesrank'})
35
37
 
36
- # search amazon uk
38
+ # Search Amazon UK
37
39
  res = Amazon::Ecs.item_search('ruby', :country => 'uk')
38
40
 
39
- # search all items, default search index: Books
41
+ # Search all items, default search index: Books
40
42
  res = Amazon::Ecs.item_search('ruby', :search_index => 'All')
41
43
 
42
44
  res.is_valid_request?
@@ -46,13 +48,13 @@ res.total_pages
46
48
  res.total_results
47
49
  res.item_page # current page no if :item_page option is provided
48
50
 
49
- # find elements matching 'Item' in response object
51
+ # Find elements matching 'Item' in response object
50
52
  res.items.each do |item|
51
- # retrieve string value using XML path
53
+ # Retrieve string value using XML path
52
54
  item.get('ASIN')
53
55
  item.get('ItemAttributes/Title')
54
56
 
55
- # return Amazon::Element instance
57
+ # Return Amazon::Element instance
56
58
  item_attributes = item.get_element('ItemAttributes')
57
59
  item_attributes.get('Title')
58
60
 
@@ -60,14 +62,14 @@ res.items.each do |item|
60
62
  item_attributes.get_array('Author') # ['Author 1', 'Author 2', ...]
61
63
  item_attributes.get('Author') # 'Author 1'
62
64
 
63
- # return a hash object with the element names as the keys
65
+ # Return a hash object with the element names as the keys
64
66
  item.get_hash('SmallImage') # {:url => ..., :width => ..., :height => ...}
65
67
 
66
- # return the first matching path
68
+ # Return the first matching path
67
69
  item_height = item.get_element('ItemDimensions/Height')
68
70
  item_height.attributes['Units'] # 'hundredths-inches'
69
71
 
70
- # there are two ways to find elements:
72
+ # There are two ways to find elements:
71
73
  # 1) return an array of Amazon::Element
72
74
  reviews = item.get_elements('EditorialReview')
73
75
  reviews.each do |review|
@@ -88,7 +90,7 @@ end
88
90
  ```ruby
89
91
  # Item lookup
90
92
  res = Amazon::Ecs.item_lookup("0974514055")
91
- item = resp.get_element("Item")
93
+ item = res.get_element("Item")
92
94
 
93
95
  # Browse node lookup
94
96
  res = Amazon::Ecs.browse_node_lookup("17")
@@ -11,24 +11,9 @@ Gem::Specification.new do |gem|
11
11
  gem.homepage = %q{https://github.com/jugend/amazon-ecs}
12
12
  gem.summary = %q{Generic Amazon Product Advertising Ruby API.}
13
13
  gem.description = %q{Generic Amazon Product Advertising Ruby API.}
14
-
14
+ gem.required_ruby_version = '>= 2.3'
15
15
  gem.files = `git ls-files`.split("\n")
16
16
  gem.test_files = `git ls-files -- test/*`.split("\n")
17
17
  gem.require_paths = ["lib"]
18
-
19
- if gem.respond_to? :specification_version then
20
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
21
- gem.specification_version = 2
22
-
23
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
24
- gem.add_runtime_dependency("nokogiri", "~> 1.4")
25
- gem.add_runtime_dependency("ruby-hmac", "~> 0.3")
26
- else
27
- gem.add_dependency("nokogiri", "~> 1.4")
28
- gem.add_dependency("ruby-hmac", "~> 0.3")
29
- end
30
- else
31
- gem.add_dependency("nokogiri", "~> 1.4")
32
- gem.add_dependency("ruby-hmac", "~> 0.3")
33
- end
34
- end
18
+ gem.add_runtime_dependency("nokogiri", "~> 1.10")
19
+ end
@@ -24,7 +24,6 @@
24
24
  require 'net/http'
25
25
  require 'nokogiri'
26
26
  require 'cgi'
27
- require 'hmac-sha2'
28
27
  require 'base64'
29
28
  require 'openssl'
30
29
 
@@ -32,7 +31,7 @@ module Amazon
32
31
  class RequestError < StandardError; end
33
32
 
34
33
  class Ecs
35
- VERSION = '2.5.0'
34
+ VERSION = '2.6.0'
36
35
 
37
36
  SERVICE_URLS = {
38
37
  :us => 'http://webservices.amazon.com/onca/xml',
@@ -46,14 +45,10 @@ module Amazon
46
45
  :es => 'http://webservices.amazon.es/onca/xml',
47
46
  :in => 'http://webservices.amazon.in/onca/xml',
48
47
  :br => 'http://webservices.amazon.com.br/onca/xml',
49
- :mx => 'http://webservices.amazon.com.mx/onca/xml'
48
+ :mx => 'http://webservices.amazon.com.mx/onca/xml',
49
+ :au => 'http://webservices.amazon.com.au/onca/xml'
50
50
  }
51
51
 
52
- OPENSSL_DIGEST_SUPPORT = OpenSSL::Digest.constants.include?( 'SHA256' ) ||
53
- OpenSSL::Digest.constants.include?( :SHA256 )
54
-
55
- OPENSSL_DIGEST = OpenSSL::Digest.new( 'sha256' ) if OPENSSL_DIGEST_SUPPORT
56
-
57
52
  @@options = {
58
53
  :version => "2013-08-01",
59
54
  :service => "AWSECommerceService"
@@ -61,6 +56,9 @@ module Amazon
61
56
 
62
57
  @@debug = ENV['DEBUG_AMAZON_ECS'] || false
63
58
 
59
+ # Error response from Amazon API may contain Access key ID
60
+ @@hideAPIError = ENV['HIDE_AMAZON_ECS_API_ERROR'] || false
61
+
64
62
  # Default search options
65
63
  def self.options
66
64
  @@options
@@ -142,7 +140,7 @@ module Amazon
142
140
  ecs_res = Response.new(res.body)
143
141
  unless res.kind_of? Net::HTTPSuccess
144
142
  err_msg = "HTTP Response: #{res.code} #{res.message}"
145
- err_msg += " - #{ecs_res.error}" if ecs_res.error
143
+ err_msg += " - #{ecs_res.error}" if ecs_res.error && !@@hideAPIError
146
144
  raise Amazon::RequestError, err_msg
147
145
  end
148
146
  ecs_res
@@ -305,15 +303,7 @@ module Amazon
305
303
 
306
304
  def self.sign_request(url, key)
307
305
  return nil if key.nil?
308
-
309
- if OPENSSL_DIGEST_SUPPORT
310
- signature = OpenSSL::HMAC.digest(OPENSSL_DIGEST, key, url)
311
- signature = [signature].pack('m').chomp
312
- else
313
- signature = Base64.encode64(HMAC::SHA256.digest(key, url)).strip
314
- end
315
- signature = CGI.escape(signature)
316
- return signature
306
+ return CGI.escape(Base64.strict_encode64(OpenSSL::HMAC.digest("SHA256", key, url)))
317
307
  end
318
308
  end
319
309
 
@@ -19,52 +19,54 @@ class Amazon::EcsTest < Test::Unit::TestCase
19
19
  options[:associate_tag] = 'bookjetty-20'
20
20
  end
21
21
 
22
+ # Amazon throwing an error if requests are submitted too quickly
23
+ AMAZON_ECS_REQUEST_DELAY = ENV['AMAZON_ECS_REQUEST_DELAY'] || 0
24
+
25
+ def throttle_request(delay = AMAZON_ECS_REQUEST_DELAY.to_i)
26
+ sleep(delay) if delay > 0
27
+ end
28
+
22
29
  # To print debug information
23
30
  # Amazon::Ecs.debug = true
24
31
 
32
+ def setup
33
+ throttle_request
34
+ end
35
+
25
36
  # Test item_search
26
37
  def test_item_search
27
38
  resp = Amazon::Ecs.item_search('ruby')
28
- assert resp.is_valid_request?,
29
- "Not a valid request"
30
- assert (resp.total_results >= 3600),
31
- "Results returned (#{resp.total_results}) were < 3600"
32
- assert (resp.total_pages >= 360),
33
- "Pages returned (#{resp.total_pages}) were < 360"
39
+ assert resp.is_valid_request?, "Not a valid request"
40
+ assert (resp.total_results >= 3600), "Results returned (#{resp.total_results}) were < 3600"
41
+ assert (resp.total_pages >= 360), "Pages returned (#{resp.total_pages}) were < 360"
34
42
  end
35
43
 
36
44
  def test_item_search_with_special_characters
37
45
  resp = Amazon::Ecs.item_search('()*&^%$')
38
- assert resp.is_valid_request?,
39
- "Not a valid request"
46
+ assert resp.is_valid_request?, "Not a valid request"
40
47
  end
41
48
 
42
49
  def test_item_search_with_paging
43
50
  resp = Amazon::Ecs.item_search('ruby', :item_page => 2)
44
- assert resp.is_valid_request?,
45
- "Not a valid request"
46
- assert_equal 2, resp.item_page,
47
- "Page returned (#{resp.item_page}) different from expected (2)"
51
+ assert resp.is_valid_request?, "Not a valid request"
52
+ assert_equal 2, resp.item_page, "Page returned (#{resp.item_page}) different from expected (2)"
48
53
  end
49
54
 
50
55
  def test_item_search_with_invalid_request
51
56
  resp = Amazon::Ecs.item_search(nil)
52
- assert !resp.is_valid_request?,
53
- "Expected invalid request error"
57
+ assert !resp.is_valid_request?, "Expected invalid request error"
54
58
  end
55
59
 
56
60
  def test_item_search_with_no_result
57
61
  resp = Amazon::Ecs.item_search('afdsafds')
58
- assert resp.is_valid_request?,
59
- "Not a valid request"
62
+ assert resp.is_valid_request?, "Not a valid request"
60
63
  assert_equal "We did not find any matches for your request.", resp.error,
61
64
  "Error string different from expected"
62
65
  end
63
66
 
64
67
  def test_utf8_encoding
65
68
  resp = Amazon::Ecs.item_search('ruby', :country => :uk)
66
- assert resp.is_valid_request?,
67
- "Not a valid request"
69
+ assert resp.is_valid_request?, "Not a valid request"
68
70
  item = resp.first_item
69
71
  assert_no_match(/\A&#x.*/, item.get_unescaped("//FormattedPrice"),
70
72
  "£ sign converted to ASCII from UTF-8")
@@ -72,8 +74,7 @@ class Amazon::EcsTest < Test::Unit::TestCase
72
74
 
73
75
  def test_item_search_by_author
74
76
  resp = Amazon::Ecs.item_search('dave', :type => :author)
75
- assert resp.is_valid_request?,
76
- "Not a valid request"
77
+ assert resp.is_valid_request?, "Not a valid request"
77
78
  end
78
79
 
79
80
  def test_item_get
@@ -82,13 +83,11 @@ class Amazon::EcsTest < Test::Unit::TestCase
82
83
 
83
84
  # test get
84
85
  assert_equal "Programming Ruby: The Pragmatic Programmers' Guide, Second Edition",
85
- item.get("ItemAttributes/Title"),
86
- "Title different from expected"
86
+ item.get("ItemAttributes/Title"), "Title different from expected"
87
87
 
88
88
  # test get_array
89
89
  assert_equal ['Dave Thomas', 'Chad Fowler', 'Andy Hunt'],
90
- item.get_array("Author"),
91
- "Authors Array different from expected"
90
+ item.get_array("Author"), "Authors Array different from expected"
92
91
 
93
92
  # test get_hash
94
93
  small_image = item.get_hash("SmallImage")
@@ -117,22 +116,18 @@ class Amazon::EcsTest < Test::Unit::TestCase
117
116
  def test_item_lookup
118
117
  resp = Amazon::Ecs.item_lookup('0974514055')
119
118
  assert_equal "Programming Ruby: The Pragmatic Programmers' Guide, Second Edition",
120
- resp.first_item.get("ItemAttributes/Title"),
121
- "Title different from expected"
119
+ resp.first_item.get("ItemAttributes/Title"), "Title different from expected"
122
120
  end
123
121
 
124
122
  def test_item_lookup_with_invalid_request
125
123
  resp = Amazon::Ecs.item_lookup(nil)
126
- assert resp.has_error?,
127
- "Response should have been invalid"
128
- assert resp.error,
129
- "Response should have contained an error"
124
+ assert resp.has_error?, "Response should have been invalid"
125
+ assert resp.error, "Response should have contained an error"
130
126
  end
131
127
 
132
128
  def test_item_lookup_with_no_result
133
129
  resp = Amazon::Ecs.item_lookup('abc')
134
- assert resp.is_valid_request?,
135
- "Not a valid request"
130
+ assert resp.is_valid_request?, "Not a valid request"
136
131
  assert_match(/ABC is not a valid value for ItemId/, resp.error,
137
132
  "Error Message for lookup of ASIN = ABC different from expected")
138
133
  end
@@ -142,20 +137,16 @@ class Amazon::EcsTest < Test::Unit::TestCase
142
137
  item = resp.first_item
143
138
 
144
139
  authors = item.get_elements("Author")
145
- assert_instance_of Array, authors,
146
- "Authors should be an Array"
147
- assert_equal 3, authors.size,
148
- "Author array size (#{authors.size}) different from expected (3)"
140
+ assert_instance_of Array, authors, "Authors should be an Array"
141
+ assert_equal 3, authors.size, "Author array size (#{authors.size}) different from expected (3)"
149
142
  assert_instance_of Amazon::Element, authors.first,
150
143
  "Authors array first element (#{authors.first.class}) should be an Amazon::Element"
151
144
  assert_equal "Dave Thomas", authors.first.get,
152
145
  "First Author (#{authors.first.get}) different from expected (Dave Thomas)"
153
146
 
154
147
  asin = item.get_elements("./ASIN")
155
- assert_instance_of Array, asin,
156
- "ASIN should be an Array"
157
- assert_equal 1, asin.size,
158
- "ASIN array size (#{asin.size}) different from expected (1)"
148
+ assert_instance_of Array, asin, "ASIN should be an Array"
149
+ assert_equal 1, asin.size, "ASIN array size (#{asin.size}) different from expected (1)"
159
150
  end
160
151
 
161
152
  def test_get_element_and_attributes
@@ -176,8 +167,7 @@ class Amazon::EcsTest < Test::Unit::TestCase
176
167
 
177
168
  def test_multibyte_search
178
169
  resp = Amazon::Ecs.item_search("パソコン")
179
- assert resp.is_valid_request?,
180
- "Not a valid request"
170
+ assert resp.is_valid_request?, "Not a valid request"
181
171
  end
182
172
 
183
173
  def test_marshal_dump_and_load
@@ -192,11 +182,11 @@ class Amazon::EcsTest < Test::Unit::TestCase
192
182
  end
193
183
 
194
184
  def test_browse_node_lookup
195
- resp = Amazon::Ecs.browse_node_lookup("17")
185
+ resp = Amazon::Ecs.browse_node_lookup('17')
196
186
  assert resp.is_valid_request?, "Not a valid request"
197
187
 
198
188
  items = resp.get_elements("BrowseNode")
199
- assert_equal 24, items.size
189
+ assert items.size.between?(15, 25)
200
190
  end
201
191
 
202
192
  def test_similarity_lookup
@@ -204,19 +194,25 @@ class Amazon::EcsTest < Test::Unit::TestCase
204
194
  assert resp.is_valid_request?, "Not a valid request"
205
195
 
206
196
  items = resp.get_elements("Item")
207
- assert_equal 10, items.size
197
+ assert items.size.between?(5, 15)
208
198
  end
209
199
 
210
200
  def test_other_service_urls
201
+ test_regions = ENV['AWS_REGIONS']&.split&.collect(&:to_sym) || Amazon::Ecs::SERVICE_URLS.keys
202
+
211
203
  Amazon::Ecs::SERVICE_URLS.each do |key, value|
212
- next if key == :us
204
+ next unless test_regions.include?(key)
213
205
 
214
206
  begin
207
+ throttle_request
215
208
  resp = Amazon::Ecs.item_search('ruby', :country => key)
216
209
  assert resp, "#{key} service url (#{value}) is invalid"
217
210
  rescue => e
218
- assert false, "'#{key}' service url (#{value}) is invalid. Error: #{e}"
219
- puts e.backtrace
211
+ if e.message.match(/503 Service Unavailable/)
212
+ puts "Unable to test '#{key}' service url (#{value}) is unavailable: #{e}"
213
+ else
214
+ assert false, "'#{key}' service url (#{value}) is invalid. Error: #{e}"
215
+ end
220
216
  end
221
217
  end
222
218
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: amazon-ecs
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 2.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Herryanto Siatono
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-09 00:00:00.000000000 Z
11
+ date: 2019-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -16,28 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.4'
19
+ version: '1.10'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.4'
27
- - !ruby/object:Gem::Dependency
28
- name: ruby-hmac
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '0.3'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '0.3'
26
+ version: '1.10'
41
27
  description: Generic Amazon Product Advertising Ruby API.
42
28
  email: herryanto@gmail.com
43
29
  executables: []
@@ -45,6 +31,7 @@ extensions: []
45
31
  extra_rdoc_files: []
46
32
  files:
47
33
  - ".gitignore"
34
+ - ".travis.yml"
48
35
  - CHANGELOG
49
36
  - Gemfile
50
37
  - MIT-LICENSE
@@ -65,17 +52,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
65
52
  requirements:
66
53
  - - ">="
67
54
  - !ruby/object:Gem::Version
68
- version: '0'
55
+ version: '2.3'
69
56
  required_rubygems_version: !ruby/object:Gem::Requirement
70
57
  requirements:
71
58
  - - ">="
72
59
  - !ruby/object:Gem::Version
73
60
  version: '0'
74
61
  requirements: []
75
- rubyforge_project:
76
- rubygems_version: 2.4.6
62
+ rubygems_version: 3.0.1
77
63
  signing_key:
78
- specification_version: 2
64
+ specification_version: 4
79
65
  summary: Generic Amazon Product Advertising Ruby API.
80
66
  test_files:
81
67
  - test/amazon/ecs_test.rb