ruby-aaws 0.6.0 → 0.7.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.
@@ -1,4 +1,4 @@
1
- # $Id: search.rb,v 1.35 2009/05/26 16:27:12 ianmacd Exp $
1
+ # $Id: search.rb,v 1.43 2009/06/14 22:28:27 ianmacd Exp $
2
2
  #
3
3
 
4
4
  module Amazon
@@ -28,10 +28,17 @@ module Amazon
28
28
  #
29
29
  class LocaleError < Amazon::AWS::Error::AWSError; end
30
30
 
31
- # Requests can be authenticated using the SHA-256 Secure Hash
32
- # Algorithm.
31
+ # Do we have support for the SHA-256 Secure Hash Algorithm?
33
32
  #
34
- DIGEST = OpenSSL::Digest::Digest.new( 'sha256' )
33
+ # Note that Module#constants returns Strings in Ruby 1.8 and Symbols
34
+ # in 1.9.
35
+ #
36
+ DIGEST_SUPPORT = OpenSSL::Digest.constants.include?( 'SHA256' ) ||
37
+ OpenSSL::Digest.constants.include?( :SHA256 )
38
+
39
+ # Requests are authenticated using the SHA-256 Secure Hash Algorithm.
40
+ #
41
+ DIGEST = OpenSSL::Digest::Digest.new( 'sha256' ) if DIGEST_SUPPORT
35
42
 
36
43
  attr_reader :conn, :config, :locale, :query, :user_agent
37
44
  attr_writer :cache
@@ -40,9 +47,12 @@ module Amazon
40
47
  # This method is used to generate an AWS search request object.
41
48
  #
42
49
  # _key_id_ is your AWS {access key
43
- # ID}[https://aws-portal.amazon.com/gp/aws/developer/registration/index.html],
50
+ # ID}[https://aws-portal.amazon.com/gp/aws/developer/registration/index.html].
51
+ # Note that your secret key, used for signing requests, can be
52
+ # specified only in your <tt>~/.amazonrc</tt> configuration file.
53
+ #
44
54
  # _associate_ is your
45
- # Associates[http://docs.amazonwebservices.com/AWSECommerceService/2009-01-06/GSG/BecominganAssociate.html]
55
+ # Associates[http://docs.amazonwebservices.com/AWSECommerceService/2009-03-31/GSG/BecominganAssociate.html]
46
56
  # tag (if any), _locale_ is the locale in which you which to work
47
57
  # (*us* for amazon.com[http://www.amazon.com/], *uk* for
48
58
  # amazon.co.uk[http://www.amazon.co.uk], etc.), _cache_ is whether or
@@ -184,7 +194,7 @@ module Amazon
184
194
  # _xml_ is the XML node below which to search.
185
195
  #
186
196
  def error_check(xml)
187
- if xml = xml.elements['Errors/Error']
197
+ if ! xml.nil? && xml = xml.elements['Errors/Error']
188
198
  raise Amazon::AWS::Error.exception( xml )
189
199
  end
190
200
  end
@@ -195,7 +205,8 @@ module Amazon
195
205
  #
196
206
  def timestamp
197
207
  @query << '&Timestamp=%s' %
198
- [ Amazon.url_encode( Time.now.utc.strftime( '%FT%TZ' ) ) ]
208
+ [ Amazon.url_encode(
209
+ Time.now.utc.strftime( '%Y-%m-%dT%H:%M:%SZ' ) ) ]
199
210
  end
200
211
  private :timestamp
201
212
 
@@ -204,6 +215,8 @@ module Amazon
204
215
  # also adds a timestamp.
205
216
  #
206
217
  def sign
218
+ return false unless DIGEST_SUPPORT
219
+
207
220
  timestamp
208
221
  params = @query[1..-1].split( '&' ).sort.join( '&' )
209
222
 
@@ -225,15 +238,32 @@ module Amazon
225
238
 
226
239
  params << '&Signature=%s' % [ signature ]
227
240
  @query = '?' + params
241
+
242
+ true
228
243
  end
229
244
 
230
245
 
231
- # Perform a search of the AWS database. _operation_ is one of the
232
- # objects subclassed from _Operation_, such as _ItemSearch_,
233
- # _ItemLookup_, etc. It may also be a _MultipleOperation_ object.
246
+ # Perform a search of the AWS database, returning an AWSObject.
247
+ #
248
+ # _operation_ is an object of a subclass of _Operation_, such as
249
+ # _ItemSearch_, _ItemLookup_, etc. It may also be a _MultipleOperation_
250
+ # object.
251
+ #
252
+ # _response_group_, if supplied, is a set of one or more response
253
+ # groups to use in combination with _operation_ for the purpose of
254
+ # determining which data sets AWS should return.
255
+ #
256
+ # If _response_group_ is *nil*, Ruby/AWS will instead use the response
257
+ # groups specified by the _@response_group_ attribute of _operation_.
258
+ # That is now the preferred way of specifying response groups to use
259
+ # with a given operation. The _response_group_ parameter may later be
260
+ # removed from this method altogether.
234
261
  #
235
- # _response_group_ will apply to all both operations contained in
236
- # _operation_, if _operation_ is a _MultipleOperation_ object.
262
+ # If _response_group_ is given, it will apply to all sub-operations of
263
+ # _operation_, if _operation_ is of class MultipleOperation. To use a
264
+ # different set of response groups for each sub-operation, you should
265
+ # assign to the _@response_group_ attribute of each of them before
266
+ # instantiating a MultipleOperation to combine them.
237
267
  #
238
268
  # _nr_pages_ is the number of results pages to return. It defaults to
239
269
  # <b>1</b>. If a higher number is given, pages 1 to _nr_pages_ will be
@@ -243,17 +273,23 @@ module Amazon
243
273
  # The maximum page number that can be returned for each type of
244
274
  # operation is documented in the AWS Developer's Guide:
245
275
  #
246
- # http://docs.amazonwebservices.com/AWSECommerceService/2009-01-06/DG/index.html?MaximumNumberofPages.html
276
+ # http://docs.amazonwebservices.com/AWSECommerceService/2009-03-31/DG/index.html?MaximumNumberofPages.html
247
277
  #
248
278
  # Note that _ItemLookup_ operations can use three separate pagination
249
279
  # parameters. Ruby/AWS, however, uses _OfferPage_ for the purposes of
250
280
  # returning multiple pages.
251
281
  #
252
282
  # If operation is of class _MultipleOperation_, the operations
253
- # combined within will return only the first page, regardless of
283
+ # specified within will return only the first page, regardless of
254
284
  # whether a higher number of pages is requested.
255
285
  #
256
- def search(operation, response_group, nr_pages=1)
286
+ # If a block is passed to this method, each successive page of results
287
+ # will be yielded to the block.
288
+ #
289
+ def search(operation, response_group=nil, nr_pages=1)
290
+ response_group ||=
291
+ operation.response_group || ResponseGroup.new( :Large )
292
+
257
293
  parameters = Amazon::AWS::SERVICE.
258
294
  merge( { 'AWSAccessKeyId' => @key_id,
259
295
  'AssociateTag' => @tag } ).
@@ -267,6 +303,11 @@ module Amazon
267
303
 
268
304
  @query = Amazon::AWS.assemble_query( parameters, @encoding )
269
305
  page = Amazon::AWS.get_page( self )
306
+
307
+ # Ruby 1.9 needs to know that the page is UTF-8, not ASCII-8BIT.
308
+ #
309
+ page.force_encoding( 'utf-8' ) if RUBY_VERSION >= '1.9.0'
310
+
270
311
  doc = Document.new( page )
271
312
 
272
313
  # Some errors occur at the very top level of the XML. For example,
@@ -369,6 +410,11 @@ module Amazon
369
410
  parameters.merge( { page_parameter => page_nr } ),
370
411
  @encoding)
371
412
  page = Amazon::AWS.get_page( self )
413
+
414
+ # Ruby 1.9 needs to know that the page is UTF-8, not ASCII-8BIT.
415
+ #
416
+ page.force_encoding( 'utf-8' ) if RUBY_VERSION >= '1.9.0'
417
+
372
418
  doc = Document.new( page )
373
419
 
374
420
  # Check for errors.
@@ -1,4 +1,4 @@
1
- # $Id: setup.rb,v 1.4 2009/05/25 23:35:54 ianmacd Exp $
1
+ # $Id: setup.rb,v 1.5 2009/06/14 00:28:48 ianmacd Exp $
2
2
  #
3
3
 
4
4
  # Attempt to load Ruby/AWS using RubyGems.
@@ -27,6 +27,8 @@ class AWSTest < Test::Unit::TestCase
27
27
  @req.encoding = 'utf-8'
28
28
  end
29
29
 
30
- undef_method :default_test
30
+ # The default_test method needs to be removed before Ruby 1.9.0.
31
+ #
32
+ undef_method :default_test if method_defined? :default_test
31
33
 
32
34
  end
@@ -1,4 +1,4 @@
1
- # $Id: tc_aws.rb,v 1.11 2008/10/02 21:33:58 ianmacd Exp $
1
+ # $Id: tc_aws.rb,v 1.12 2009/06/14 00:29:28 ianmacd Exp $
2
2
  #
3
3
 
4
4
  require 'test/unit'
@@ -13,7 +13,7 @@ class TestAWSBasics < AWSTest
13
13
  CACHE_PATH = File.join( Dir.tmpdir, 'aws_cache' )
14
14
 
15
15
  def test_version
16
- v = '1.8.6'
16
+ v = '1.8.7'
17
17
  assert( RUBY_VERSION >= v, "Ruby version is lower than #{v}." )
18
18
  end
19
19
 
@@ -0,0 +1,62 @@
1
+ # $Id: tc_browse_node_lookup.rb,v 1.2 2009/06/02 00:39:43 ianmacd Exp $
2
+ #
3
+
4
+ require 'test/unit'
5
+ require './setup'
6
+
7
+ class TestBrowseNodeLookup < AWSTest
8
+
9
+ def test_browse_node_lookup
10
+
11
+ bnl = BrowseNodeLookup.new( 694212 )
12
+ rg = ResponseGroup.new( :BrowseNodeInfo )
13
+
14
+ response = @req.search( bnl, rg )
15
+
16
+ results = response.kernel
17
+
18
+ # Ensure we got some actual results back.
19
+ #
20
+ assert( results.size > 0 )
21
+
22
+ end
23
+
24
+ def test_browse_node_lookup_no_response_group
25
+
26
+ bnl = BrowseNodeLookup.new( 694212 )
27
+ bnl.response_group = ResponseGroup.new( :BrowseNodeInfo )
28
+ response = @req.search( bnl, nil )
29
+
30
+ results = response.kernel
31
+
32
+ # Ensure we got more than 10 results back.
33
+ #
34
+ assert( results.size > 0 )
35
+
36
+ end
37
+
38
+ def test_browse_node_lookup_class_method
39
+
40
+ response = Amazon::AWS.browse_node_lookup( 694212 )
41
+
42
+ results = response.kernel
43
+
44
+ # Ensure we got some actual results back.
45
+ #
46
+ assert( results.size > 0 )
47
+
48
+ end
49
+
50
+ def test_browse_node_lookup_class_method_block
51
+
52
+ Amazon::AWS.browse_node_lookup( '694212' ) do |r|
53
+
54
+ results = r.kernel
55
+
56
+ # Ensure we got some actual results back.
57
+ #
58
+ assert( results.size > 0 )
59
+ end
60
+ end
61
+
62
+ end
@@ -0,0 +1,64 @@
1
+ # $Id: tc_customer_content_lookup.rb,v 1.1 2009/06/02 00:29:18 ianmacd Exp $
2
+ #
3
+
4
+ require 'test/unit'
5
+ require './setup'
6
+
7
+ class TestCustomerContentLookup < AWSTest
8
+
9
+ def test_customer_content_lookup
10
+
11
+ @req.locale = 'us'
12
+ ccl = CustomerContentLookup.new( 'AJDWXANG1SYZP' )
13
+ rg = ResponseGroup.new( :CustomerReviews )
14
+
15
+ response = @req.search( ccl, rg )
16
+
17
+ review = response.customer_content_lookup_response.customers.customer.
18
+ customer_reviews.review[0]
19
+
20
+ # Ensure we got the right review.
21
+ #
22
+ assert_equal( 3746, review.content[0].size )
23
+
24
+ end
25
+
26
+ def test_customer_content_lookup_no_response_group
27
+
28
+ @req.locale = 'us'
29
+ ccl = CustomerContentLookup.new( 'AJDWXANG1SYZP' )
30
+ ccl.response_group = ResponseGroup.new( :CustomerReviews )
31
+ response = @req.search( ccl, nil )
32
+
33
+ review = response.customer_content_lookup_response.customers.customer.
34
+ customer_reviews.review[0]
35
+
36
+ # Ensure we got the right review.
37
+ #
38
+ assert_equal( 3746, review.content[0].size )
39
+
40
+ end
41
+
42
+ def test_customer_content_lookup_class_method
43
+
44
+ response = Amazon::AWS.customer_content_lookup( 'AA5QZU6TJQXEN' )
45
+
46
+ nickname = response.customer_content_lookup_response.customers.customer.
47
+ nickname
48
+
49
+ assert_equal( 'jimwood43', nickname )
50
+
51
+ end
52
+
53
+ def test_item_search_class_method_block
54
+
55
+ Amazon::AWS.customer_content_lookup( 'AA5QZU6TJQXEN' ) do |r|
56
+
57
+ nickname = r.customer_content_lookup_response.customers.customer.nickname
58
+
59
+ assert_equal( 'jimwood43', nickname )
60
+
61
+ end
62
+ end
63
+
64
+ end
@@ -0,0 +1,60 @@
1
+ # $Id: tc_help.rb,v 1.2 2009/06/02 00:39:23 ianmacd Exp $
2
+ #
3
+
4
+ require 'test/unit'
5
+ require './setup'
6
+
7
+ class TestHelp < AWSTest
8
+
9
+ def test_help
10
+
11
+ h = Help.new( 'ResponseGroup', 'Large' )
12
+ rg = ResponseGroup.new( 'Help' )
13
+ response = @req.search( h, rg )
14
+
15
+ # Get a list of valid operations for the Large response group.
16
+ #
17
+ results = response.help_response[0].information.response_group_information.
18
+ valid_operations.operation
19
+
20
+ # Ensure we got some actual results back.
21
+ #
22
+ assert( results.size > 0 )
23
+
24
+ end
25
+
26
+ def test_help_no_response_group
27
+
28
+ h = Help.new( 'ResponseGroup', 'Large' )
29
+ h.response_group = ResponseGroup.new( 'Help' )
30
+ response = @req.search( h, nil )
31
+
32
+ # Get a list of valid operations for the Large response group.
33
+ #
34
+ results = response.help_response[0].information.response_group_information.
35
+ valid_operations.operation
36
+
37
+ # Ensure we got some actual results back.
38
+ #
39
+ assert( results.size > 0 )
40
+
41
+ end
42
+
43
+ def test_help_class_method
44
+
45
+ response = Amazon::AWS.help( 'ResponseGroup', 'Large' )
46
+
47
+ # With no response group, Large will be tried. The resulting exception
48
+ # will be rescued and the text of the message returned by AWS will be used
49
+ # to determine a response group that will work.
50
+ #
51
+ results = response.help_response[0].information.response_group_information.
52
+ valid_operations.operation
53
+
54
+ # Ensure we got some actual results back.
55
+ #
56
+ assert( results.size > 0 )
57
+
58
+ end
59
+
60
+ end
@@ -0,0 +1,60 @@
1
+ # $Id: tc_item_lookup.rb,v 1.2 2009/05/30 11:11:27 ianmacd Exp $
2
+ #
3
+
4
+ require 'test/unit'
5
+ require './setup'
6
+
7
+ class TestItemLookup < AWSTest
8
+
9
+ def test_item_lookup
10
+
11
+ is = ItemLookup.new( 'ASIN', { 'ItemId' => 'B000AE4QEC' } )
12
+ response = @req.search( is, @rg )
13
+
14
+ results = response.kernel
15
+
16
+ # Ensure we got some actual results back.
17
+ #
18
+ assert( results.size > 0 )
19
+
20
+ end
21
+
22
+ def test_item_lookup_no_response_group
23
+
24
+ is = ItemLookup.new( 'ASIN', { 'ItemId' => 'B000AE4QEC' } )
25
+ is.response_group = ResponseGroup.new( :Small )
26
+ response = @req.search( is, nil )
27
+
28
+ results = response.kernel
29
+
30
+ # Ensure we got more than 10 results back.
31
+ #
32
+ assert( results.size > 0 )
33
+
34
+ end
35
+
36
+ def test_item_lookup_class_method
37
+
38
+ response = Amazon::AWS.item_lookup( 'ASIN', { 'ItemId' => 'B000AE4QEC' } )
39
+
40
+ results = response.kernel
41
+
42
+ # Ensure we got some actual results back.
43
+ #
44
+ assert( results.size > 0 )
45
+
46
+ end
47
+
48
+ def test_item_search_class_method_block
49
+
50
+ Amazon::AWS.item_lookup( 'ASIN', { 'ItemId' => 'B000AE4QEC' } ) do |r|
51
+
52
+ results = r.kernel
53
+
54
+ # Ensure we got some actual results back.
55
+ #
56
+ assert( results.size > 0 )
57
+ end
58
+ end
59
+
60
+ end
@@ -1,5 +1,10 @@
1
- # $Id: tc_item_search.rb,v 1.3 2009/05/26 16:18:14 ianmacd Exp $
1
+ # encoding: ASCII-8BIT
2
2
  #
3
+ # $Id: tc_item_search.rb,v 1.6 2009/06/15 10:18:07 ianmacd Exp $
4
+ #
5
+ # The encoding at the top of this file is necessary for Ruby 1.9, which will
6
+ # otherwise choke with 'invalid multibyte char (US-ASCII)' when it reads the
7
+ # ISO-8859-1 encoded accented 'e' in the test_item_search_iso_8859_15 method.
3
8
 
4
9
  require 'test/unit'
5
10
  require './setup'
@@ -12,7 +17,9 @@ class TestItemSearch < AWSTest
12
17
  # ISO-8859-15, a.k.a. Latin-15.
13
18
  #
14
19
  @req.encoding = 'iso-8859-15'
15
- is = ItemSearch.new( 'Books', { 'Title' => 'Caf�' } )
20
+
21
+ str = 'Caf�'
22
+ is = ItemSearch.new( 'Books', { 'Title' => str } )
16
23
  response = @req.search( is, @rg )
17
24
 
18
25
  results = response.kernel
@@ -28,7 +35,9 @@ class TestItemSearch < AWSTest
28
35
  # Manually set UTF-8 encoding.
29
36
  #
30
37
  @req.encoding = 'utf-8'
31
- is = ItemSearch.new( 'Books', { 'Title' => 'Café' } )
38
+
39
+ str = 'Café'
40
+ is = ItemSearch.new( 'Books', { 'Title' => str } )
32
41
  response = @req.search( is, @rg )
33
42
 
34
43
  results = response.kernel
@@ -41,13 +50,28 @@ class TestItemSearch < AWSTest
41
50
 
42
51
  def test_item_search_multiple_pages
43
52
 
53
+ @req.encoding = 'utf-8'
44
54
  is = ItemSearch.new( 'Books', { 'Title' => 'programming' } )
45
55
  responses = @req.search( is, @rg, 5 )
46
56
 
47
57
  results = []
48
- responses.each do |response|
49
- results += response.kernel
50
- end
58
+ responses.each { |response| results += response.kernel }
59
+
60
+ # Ensure we got more than 10 results back.
61
+ #
62
+ assert( results.size > 10 )
63
+
64
+ end
65
+
66
+ def test_item_search_no_response_group
67
+
68
+ @req.encoding = 'utf-8'
69
+ is = ItemSearch.new( 'Books', { 'Title' => 'programming' } )
70
+ is.response_group = ResponseGroup.new( :Small )
71
+ responses = @req.search( is, nil, 5 )
72
+
73
+ results = []
74
+ responses.each { |response| results += response.kernel }
51
75
 
52
76
  # Ensure we got more than 10 results back.
53
77
  #
@@ -55,4 +79,28 @@ class TestItemSearch < AWSTest
55
79
 
56
80
  end
57
81
 
82
+ def test_item_search_class_method
83
+
84
+ response = Amazon::AWS.item_search( 'Books', { 'Title' => 'programming' } )
85
+
86
+ results = response.kernel
87
+
88
+ # Ensure we got some actual results back.
89
+ #
90
+ assert( results.size > 0 )
91
+
92
+ end
93
+
94
+ def test_item_search_class_method_block
95
+
96
+ Amazon::AWS.item_search( 'Books', { 'Title' => 'programming' } ) do |r|
97
+
98
+ results = r.kernel
99
+
100
+ # Ensure we got some actual results back.
101
+ #
102
+ assert( results.size > 0 )
103
+ end
104
+ end
105
+
58
106
  end