Class: Amazon::AWS::Search::Request

Inherits:
Object
  • Object
show all
Includes:
REXML
Defined in:
lib/amazon/aws/search.rb

Direct Known Subclasses

Amazon::AWS::ShoppingCart::Cart

Defined Under Namespace

Classes: AccessKeyIdError, LocaleError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(key_id = nil, secret_id = nil, associate = nil, locale = nil, cache = nil, cache_dir = nil, user_agent = USER_AGENT) ⇒ Request

associate is your Associates tag (if any), locale is the locale in which you which to work (us for amazon.com, uk for amazon.co.uk, etc.), cache is whether or not you wish to utilise a response cache, and user_agent is the client name to pass when performing calls to AWS. By default, user_agent will be set to a string identifying the Ruby/AWS library and its version number.

locale and cache can also be set later, if you wish to change the current behaviour.

Example:

req = Request.new( '0Y44V8FAFNM119CX4TR2', 'yoursecret_id', 'calibanorg-20' )


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/amazon/aws/search.rb', line 55

def initialize(key_id=nil, secret_id=nil, associate=nil, locale=nil, cache=nil, cache_dir=nil, user_agent=USER_AGENT)
        
  @config ||= Amazon::Config.new
  
  def_locale = locale
  locale = 'us' unless locale
  locale.downcase!
  
  key_id ||= @config['key_id']
  secret_id ||= @config['secret_id']
  cache = @config['cache'] if cache.nil?
  cache_dir ||= @config['cache_dir']
  
  # Take locale from config file if no locale was passed to method.
  #
  if @config.key?( 'locale' ) && ! def_locale
    locale = @config['locale']
  end
  validate_locale( locale )
  
  if key_id.nil?
    raise AccessKeyIdError, 'key_id may not be nil'
  end
  
  if secret_id.nil?
    raise AccessKeyIdError, 'secrret_id may not be nil'
  end
  
  @key_id = key_id
  @secret_id = secret_id
  @tag = associate || @config['associate'] || DEF_ASSOC[locale]
  @user_agent = user_agent
  @cache = unless cache == 'false' || cache == false
    Amazon::AWS::Cache.new( cache_dir )
  else
    nil
  end
  self.locale = locale
end

Instance Attribute Details

#cacheObject

If @cache has simply been assigned true at some point in time, assign a proper cache object to it when it is referenced. Otherwise, just return its value.



126
127
128
129
130
131
132
# File 'lib/amazon/aws/search.rb', line 126

def cache  # :nodoc:
  if @cache == true
    @cache = Amazon::AWS::Cache.new( @config['cache_dir'] )
  else
    @cache
  end
end

#connObject (readonly)

Returns the value of attribute conn.



30
31
32
# File 'lib/amazon/aws/search.rb', line 30

def conn
  @conn
end

#localeObject

Returns the value of attribute locale.



30
31
32
# File 'lib/amazon/aws/search.rb', line 30

def locale
  @locale
end

#secret_idObject (readonly)

Returns the value of attribute secret_id.



30
31
32
# File 'lib/amazon/aws/search.rb', line 30

def secret_id
  @secret_id
end

#user_agentObject (readonly)

Returns the value of attribute user_agent.



30
31
32
# File 'lib/amazon/aws/search.rb', line 30

def user_agent
  @user_agent
end

Instance Method Details

#reconnectObject

Reconnect to the server if our connection has been lost (due to a time-out, etc.).



166
167
168
169
# File 'lib/amazon/aws/search.rb', line 166

def reconnect  # :nodoc:
  connect( self.locale )
  self
end

#search(operation, response_group, nr_pages = 1) ⇒ Object

Perform a search of the AWS database. operation is one of the objects subclassed from Operation, such as ItemSearch, ItemLookup, etc. It may also be a MultipleOperation object.

response_group will apply to all both operations contained in operation, if operation is a MultipleOperation object.

nr_pages is the number of results pages to return. It defaults to 1. If a higher number is given, pages 1 to nr_pages will be returned. If the special value :ALL_PAGES is given, all results pages will be returned.

The maximum page number that can be returned for each type of operation is documented in the AWS Developer’s Guide:

docs.amazonwebservices.com/AWSECommerceService/2008-08-19/DG/index.html?CHAP_MakingRequestsandUnderstandingResponses.html#PagingThroughResults

Note that ItemLookup operations can use three separate pagination parameters. Ruby/AWS, however, uses OfferPage for the purposes of returning multiple pages.

If operation is of class MultipleOperation, the operations combined within will return only the first page, regardless of whether a higher number of pages is requested.



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
# File 'lib/amazon/aws/search.rb', line 208

def search(operation, response_group, nr_pages=1)
  q_params = Amazon::AWS::SERVICE.
	       merge( { 'AWSAccessKeyId' => @key_id,
			'AssociateTag'   => @tag } ).
	       merge( operation.params ).
	       merge( response_group.params )

  query = Amazon::AWS.assemble_query( q_params )
   
   
  page = Amazon::AWS.get_page( self, query )
  doc = Document.new( page )

  # Some errors occur at the very top level of the XML. For example,
  # when no Operation parameter is given. This should not be possible
  # with user code, but occurred during debugging of this library.
  #
  error_check( doc )

  # Fundamental errors happen at the OperationRequest level. For
  # example, if an invalid AWSAccessKeyId is used.
  #
  error_check( doc.elements['*/OperationRequest'] )

  # Check for parameter and value errors deeper down, inside Request.
  #
  if operation.kind == 'MultipleOperation'

    # Everything is a level deeper, because of the
    # <MultiOperationResponse> container.
    #
    # Check for errors in the first operation.
    #
    error_check( doc.elements['*/*/*/Request'] )

    # Check for errors in the second operation.
    #
    error_check( doc.elements['*/*[3]/*/Request'] )

    # If second operation is batched, check for errors in its 2nd set
    # of results.
    #
    if batched = doc.elements['*/*[3]/*[2]/Request']
      error_check( batched )
    end
  else
    error_check( doc.elements['*/*/Request'] )

    # If operation is batched, check for errors in its 2nd set of
    # results.
    #
    if batched = doc.elements['*/*[3]/Request']
      error_check( batched )
    end
  end

  # FIXME: This doesn't work if a MultipleOperation was used, because
  # <TotalPages> will be nested one level deeper. It's therefore
  # currently only possible to return the first page of results
  # for operations combined in a MultipleOperation.
  #
  if doc.elements['*/*[2]/TotalPages']
    total_pages = doc.elements['*/*[2]/TotalPages'].text.to_i
  else
    total_pages = 1
  end

  # Create a root AWS object and walk the XML response tree.
  #
  aws = AWS::AWSObject.new( operation )
  aws.walk( doc )
  result = aws

  # If only one page has been requested or only one page is available,
  # we can stop here. First yield to the block, if given.
  #
  if nr_pages == 1 || ( tp = total_pages ) == 1
     yield result if block_given?
     return result
  end

  # Limit the number of pages to the maximum number available.
  #
  nr_pages = tp.to_i if nr_pages == :ALL_PAGES || nr_pages > tp.to_i

  if PAGINATION.key? operation.kind
    page_parameter = PAGINATION[operation.kind]['parameter']
    max_pages = PAGINATION[operation.kind]['max_page']
  else
    page_parameter = 'ItemPage'
    max_pages = 400
  end

  # Iterate over pages 2 and higher, but go no higher than MAX_PAGES.
  #
  2.upto( nr_pages < max_pages ? nr_pages : max_pages ) do |page_nr|
    query = Amazon::AWS.assemble_query(
	      q_params.merge( { page_parameter => page_nr } ) )
    page = Amazon::AWS.get_page( self, query )
    doc = Document.new( page )

    # Check for errors.
    #
    error_check( doc.elements['*/OperationRequest'] )
    error_check( doc.elements['*/*/Request'] )

    # Create a new AWS object and walk the XML response tree.
    #
    aws = AWS::AWSObject.new
    aws.walk( doc )

    # When dealing with multiple pages, we return not just an
    # AWSObject, but an array of them.
    #
    result = [ result ] unless result.is_a? Array

    # Append the new object to the array.
    #
    result << aws
  end

  # Yield each object to the block, if given.
  #
  result.each { |r| yield r } if block_given?

  result
end