RAA - ruby-aws

ruby-aws / 0.8.1

Short description: Interface to Amazon Associates Product Advertising API v4.
Category: Library/WWW
Status: beta
Created: 2008-03-24 18:55:24 GMT
Last update: 2010-03-20 12:38:14 GMT
Owner: Ian Macdonald (Projects of this owner)
Homepage: http://caliban.org/ruby/ruby-aws/
Download: http://caliban.org/files/ruby/ruby-aws-0.8.1.tar.gz
License: GPL
Dependency:
None
Description:

This library is the sequel to Ruby/Amazon, which worked with the AWS v3 API. See the README file in the archive for more information on the history.

Ruby/AWS is a Ruby language library that allows the programmer to retrieve information from the popular Amazon Web site via the Product Advertising API. In addition to the original amazon.com site, the local sites amazon.co.uk, amazon.de, amazon.fr, amazon.ca and amazon.co.jp are also supported.

AWS v4 API is supported almost in its entirety, with just a few gaps in the implementation of a couple of operations.

Currently implemented operations are:

BrowseNodeLookup
CustomerContentLookup
CustomerContentSearch
Help
ItemLookup
ItemSearch
ListLookup
ListSearch
SellerListingLookup
SellerListingSearch
SellerLookup
SimilarityLookup
TagLookup
TransactionLookup
VehiclePartLookup
VehiclePartSearch
VehicleSearch

Multiple operations and batch requests are also supported.

In addition, remote shopping-cart functionality is implemented. This adds the following operations:

CartCreate
CartAdd
CartModify
CartClear
CartGet


Changes in 0.8.1:

1. Operation#query_parameters was faulty, because it had accidentally been
defined outside the Operation class.

This meant that it wasn't in the correct namespace, causing libraries that
included Ruby/AWS to place that method in a namespace unreachable by
Ruby/AWS itself. Scripts that used Ruby/AWS without defining other modules
and classes were unaffected.

2. In determining the home directory location of the .amazonrc file, we were
mistakenly concatenating ENV['HOMEDRIVE'] + ENV['HOMEPATH'] without first
checking that both were defined.

3. The version of the AWS API used is now 2009-11-01, the latest at the time
of writing.


Changes in 0.8.0:

1. There is a new exception class, ObsolescenceError, which is raised when
an obsolete (i.e. no longer available) feature is used.

2. The batching and multiple operation code was basically unmaintainable. I
could no longer comprehend it, so I removed and rewrote it from scratch.

3. The implementation of MultipleOperation had a bug, whereby, if the second
operation was a batched operation, its parameters would overwrite those of
the first operation, leading to too few results returned.

This meant that the maximum number of operations that could be encapsulated
in a MultipleOperation was 3, not the proper 4, and, even then, only when
the batched operation was supplied as the first parameter, not the second.

4. There's a new ResponseGroup#response_group= method, the use of which is
transparent to the user. This makes it possible to assign response groups
to any kind of operation, even those encapsulated in batched and multiple
operations.

5. MultipleOperation.new can now accept an arbitrary number of operations in
its parameter list. This list may also be supplied in the form of an array.

Amazon still impose a maximum of 2 operations encapsulated in a multiple
operation, but there's no reason for Ruby/AWS to mirror this. If Amazon
later raise the limit, Ruby/AWS will require no modification to take
advantage of the new situation.

6. It's now possible to pass two batched operations to MultipleOperation.new,
allowing 4 base operations to be sent to AWS in a single request.

Note that Amazon still impose a limit of no more than 2 operations of the
same class in a single request, which means that to achieve the maximum of
4 base operations in a MultipleOperation, one must encapsulate two batched
operations of different classes.

7. A MultipleOperation that encapsulates only operations of the same class
will be commuted to a batch operation, resulting in the appropriate
response from Amazon.

For example, a MultipleOperation encapsulating two ItemSearch operations
will return an item_search_response, not a multiple_operation_response. A
MultipleOperation encapsulating an ItemSearch and an ItemLookup, on the
other hand, will still return a multiple_operation_response.

Previously, all multiple operations returned a multiple_operation_response.

8. It's no longer possible to pass a list of response groups as the second
parameter to Search::Request#search. This facility was deprecated in
Ruby/AWS 0.7.0 and has been removed altogether in 0.8.0 (shunting nr_pages
into place as the second and final parameter).

You must now directly assign to the operation's @response_group attribute.

In the case of a batched operation or a MultipleOperation, the response
groups will automatically propagate to the encapsulated operations.

An attempt to pass response groups as the second parameter to
Search::Request#search will now yield an ObsolescenceError exception.

9. Attempting to retrieve ALL_PAGES of a multiple page list, such as a
WishList, didn't work. Only the first page was retrieved. This is because
TotalPages is nested one level deeper in the XML response yielded by this
type of operation. The same is true of MultipleOperation responses.
10. Geolocation now associates Belgian clients with amazon.fr, rather than
amazon.co.uk. A Belgian client may not necessarily be a Francophone, but
this is probably still an improvement.

11. The version of the AWS API used is now 2009-10-01, the latest at the time
of writing. ItemSearch::SEARCH_INDICES has been updated with the latest
additions, Lighting and Outlet.

12. Ruby/AWS now depends on Ruby 1.8.6, not 1.8.7. This should make life
easier for some people, as many Linux distributions still come with 1.8.6.


Changes in 0.7.0:

1. This release introduces a shorthand module method for each of the AWS operations. These can be used to create less verbose code at the expense of flexibility.

For example, we might normally write the following code:

is = ItemSearch.new( 'Books', { 'Title' => 'Ruby' } )
rg = ResponseGroup.new( :Large )
req = Request.new
response = req.search( is, rg )

but we could instead use ItemSearch's associated module method as follows:

response = Amazon::AWS.item_search( 'Books', { 'Title' => 'Ruby' } )

There are some important restrictions when compared to the standard way of doing things:

a. Astute readers will note that there's no way to specify to the module methods which response group(s) to use. Instead, a reasonable default set for each type of operation will be used, as per the new ResponseGroup::DEFAULT hash.

The exception to this is Amazon::AWS.multiple_operation, which has no response groups of its own, instead applying those of the operations it combines.

Because no access is provided to the Request object used by the module method, it's also not possible to batch operations with Operation#batch when using this form of the search.

On the other hand, you can use the Amazon::AWS.multiple_operation module method to achieve more or less the same thing:

Amazon::AWS.multiple_operation( op1, op2 )

When op1 and op2 are of the same class, the effect is similar to batching two operations. The main difference is in the structure of the XML document returned by AWS.

b. Similarly, one can't influence the key ID, associate tag, locale, cache or user agent used for the request. These are all set as per ~/.amazonrc.

Likewise, the number of results pages to fetch will always be 1.

c. The module methods have no RDoc documentation, because they are dynamically generated.

Basically, the short form module methods are there as a convenience, but that convenience comes at the expense of flexibility. If they don't meet your needs, you will have to resort to the standard longhand form.

2. There's now an alternative to passing the list of desired response groups as the second parameter to Request#search.

The second parameter of that method is now optional and *nil* by default. Instead, you may assign to the response_group attribute of your operation object.

For example:

is = ItemSearch.new( 'Books', { 'Title' => 'Ruby' } )
is.response_group = ResponseGroup.new( :Large )
req = Request.new
response = req.search( is )

Note that the @response_group variable will be initialised at the time the operation object is instantiated. It will be assigned the same reasonable default as used by the equivalent module method, namely that specified by the new ResponseGroup::DEFAULT hash.

Specifying the desired response groups inside your operation object has at least two advantages over passing the list to Request#search:

a. You can maintain a separate response group set per operation, rather than having to pass a differen set to Request#search for each operation.

b. A reasonable default response group set can be used for any given operation if you don't supply one.

3. More and more people are moving to Ruby 1.9, so this release of Ruby/AWS has been tested to work with Ruby 1.9.1p129, the latest version at the time of writing. Attaining ompatibility with 1.9 is a little tricky, because of the way in which strings are no longer treated as sequences of bytes in that version. Instead, they have knowledge of their encoding.

There may be one or two obscure 1.9-related bugs remaining, but all of the unit tests pass, at least.

4. The signing of requests, introduced in Ruby/AWS 0.6.0, produced problems for people with a version of OpenSSL earlier than 0.9.8.

The code will now check whether there is OpenSSL support for the SHA-256 Secure Hash Algorithm before attempting to use it. If not, each attempt to sign a request will result in a warning if $DEBUG is used.

Once again, I remind you that Amazon intends to make request authentication compulsory on 15th August 2009, so this change to Ruby/AWS only lets users with an ancient OpenSSL library off the hook until then.

5. A second bug with the signing of requests occurred on Windows platforms. Requests were not properly timestamped. This was due to deficiencies in the underlying strftime(3) library function, but has now been fixed.

6. Finally, knowledge of a handful of relatively new search indices, such as UnboxVideo, was missing. This has now been added. The AWS documentation is terribly inconsistent in this regard, providing several different, yet supposedly complete lists of valid search indices at various points throughout the document.


Changes in 0.6.0:

1. Requests to AWS can now be signed in order to authenticate them. Amazon plans to make the signing of requests mandatory as of 15th August 2009, so it is recommended to start doing so now.

To have your requests automatically signed by Ruby/AWS, simply add the 'secret_key_id' parameter to your ~/.amazonrc configuration file. Its value should, rather predictably, be your secret access key, which can be retrieved here:

https://aws-portal.amazon.com/gp/aws/developer/account/index.html?ie=UTF8&action=access-key

You needn't be concerned about Amazon's warnings not to show your secret key to anyone else, because it will be used only for signing requests, prior to sending them. The key itself will not be sent over the network to Amazon, even in encrypted form.

In order to incorporate the new functionality, minor changes had to be made to the way the AWS request URLs are encoded. This change means that previous requests cached by earlier versions of Ruby/AWS will not be found in the cache. This is a minor, one-time inconvenience, and it just means that the requests will be performed and cached again.

2. When Amazon's AWS servers check whether the correct signature has been applied to a request, they recalculate the signature based on the data in the request and check for a match with the signature supplied by Ruby/AWS.

This introduces a complicating factor, namely the treatment of non-ASCII characters in the request, such as accented letters. When recalculating the signature, Amazon will use the UTF-8 representation of any such characters. This will cause a signature mismatch if you used a different encoding, such as ISO-8859-1 (a.k.a. Latin-1), when you supplied values for your request parameters.

Ruby/AWS can't (reliably) dynamically determine which character encoding your strings use, so this information can now be supplied via the ~/.amazonrc configuration file, using the 'encoding' parameter. This should be set to whichever encoding you use. If left unset, it defaults to UTF-8. An exception will be raised if you attempt to use an invalid (i.e. unknown) encoding.

Currently, the encoding you use makes no difference unless your requests are being signed, but because signing will soon be mandatory, I recommend you explicitly state which encoding you intend to use.

You may also change the encoding in use at any time by assigning to the @encoding instance variable of your Request object.

3. The robustness of the software has been improved by handling the following additional exceptions while communicating with the AWS servers: Errno::ECONNREFUSED, Errno::ECONNABORTED, Errno::ETIMEDOUT and Timeout::Error. Users have reported that all of these occur from time to time, although only Windows platforms seem to suffer from Errno::ECONNABORTED.

4. The version of the AWS API used is now 2009-03-31, the latest at the time of writing.


Changes in 0.5.1:

1. Catch Errno::EPIPE on server connections (Errno::ECONNRESET was already caught). This can occur when the connection times out due to lack of use. Running Ruby in debug mode will print the error message text when such an exception is caught.

2. The version of the AWS API used is now 2009-02-01, the latest at the time of writing.

3. The sequence numbering of shopping cart items incorrectly started from 2 instead of 1, but didn't cause a problem in practice.


Changes in 0.5.0:

1. The configuration files (/etc/amazonrc and typically ~/.amazonrc) are now locale-specific. Global and locale-specific settings can now be placed in their own sections.

For example:

Old style .amazonrc:

associate = 'caliban-21'
locale = 'uk'
cache = false
key_id = '0Y44V8FAFNM119C6XYZ2'

New style .amazonrc:

[global]
locale = 'uk'
cache = false
key_id = '0Y44V8FAFNM119C6XYZ2'

[uk]
associate = 'calibanorg-21'

[us]
associate = 'calibanorg-20'


The old style of configuration is still supported.

2. ItemLookup.new and SellerListingLookup.new no longer take a third parameter, b_parameters. Instead, the new Operation#batch method can be used to create batch operations.

Operation#batch can batch multiple operations of any class, not just ItemLookup and SellerListingLookup. The only requirement if that all batched operations must be of the same class.

If you want to send multiple operations of different classes as a single request, you must still use the MultipleOperation class.

3. VehiclePartLookup, VehiclePartSearch and VehicleSearch operations (which were added in the 2008-08-19 revision of the AWS API, are now supported. However, VehiclePartLookup is the only one of these that currently supports pagination.

4. The list of allowable search indices for ItemSearch operations has been updated in accordance with the latest AWS documentation.

5. Parameter checking for ItemSearch operations no longer occurs. It was impractical to keep the list of valid parameters concurrent with AWS. Related constants have therefore also been removed.

6. The version of the AWS API used is now 2009-01-06, the latest at the time of writing.

The configuration file now supports a new global parameter for requesting a different version of the API.

For example:

api = '2008-08-19'

7. While testing the ability to request a specific version of the AWS API, I encountered a new kind of AWS error, the internal error, which is reported using a different XML construct to that used for all other error conditions.

I triggered one of these internal errors when I attempted an operation, a VehicleSearch, that did not yet exist in the older version of the API that I requested.

This type of error now throws a generic Amazon::AWS::Error::AWSError exception.

It's reasonable to assume that there are other conditions that would cause an internal AWS error to occur. These, too, will be raised as an exception.

Unfortunately, AWS supplies no information on the cause of such internal errors, so Ruby/AWS is unable to pass on any clues to the user.


Changes in 0.4.4:

It's now possible to have Ruby/AWS use a user configuration file with a name other than .amazonrc. This is achieved by defining $AMAZONRCFILE. If left undefined, the default of .amazonrc is used.

Locations other than $HOME were not being checked for .amazonrc. This bug has now been fixed.


Changes in 0.4.3:

$AMAZONRCDIR is now searched for .amazonrc before $HOME and the other directories. This allows a user-defined location to be used for the user configuration file.

There is a new top-level class of exception for Ruby/AWS, Amazon::AmazonError.

Most non-operational exceptions, such as Amazon::AWS::HTTPError, Amazon::Config::ConfigError, Amazon::AWS::Search::Request::AccessKeyIdError, Amazon::AWS::Search::Request::LocaleError and Amazon::AWS::ShoppingCart::CartError are now immediate subclasses of AmazonError. Previously, they were subclasses of StandardError.

Amazon::AWS::Error::AWSError was previously a class that generated exceptions, but it's now simply a container class derived from AmazonError. All operational exceptions -- the ones whose class is dynamically created when AWS returns an error -- are now subclasses of AWSError. Previously, they were immediate subclasses of StandardError.

This has the advantage of allowing all of the exceptions resulting from operational errors to be caught by rescuing just the container class, AWSError.


Changes in 0.4.2:

The version of the Amazon AWS API requested when performing operations is now 2008-08-19. This is the latest at the time of writing.

The exception class Amazon::Config::ConfigError was mysteriously not defined.

Amazon::Config.new now accepts an optional argument, config_str, which may contain the string equivalent of a config file's contents. When config_str is not nil (nil is the default), this string is read instead of /etc/amazonrc and ~/.amazonrc. This addition is really just to aid unit-testing of the Amazon::Config class, as Amazon::Config.new never needs to be called by user code.

Config file lines may now contain leading whitespace.

The Amazon::AWS::MAX_PAGES constant has gone, replaced by the PAGINATION hash. Only ItemSearch should use ItemPage to page through results up to MAX_PAGES when ALL_PAGES has been requested, but the same approach was attempted for all types of operation.

Each operation has its own pagination parameter and its own maximum number of pages that can be fetched. This is now stored in the Amazon::AWS::PAGINATION hash.

Note that ItemLookup has three possible pagination parameters: OfferPage, VariationPage and ReviewPage. Ruby/AWS uses OfferPage for the purposes of ALL_PAGES.

Operations that do not explicitly provide a pagination parameter (or, at least, those for which there isn't one listed in the AWS Developer's Guide) use ItemPage and pagination up to page 400. This is likely to throw an exception, as such operations almost certainly don't support multiple results pages.


Changes in 0.4.1:

The exception class Amazon::AWS::HTTPError was not defined.

Extra locations besides $HOME are now scanned for .amazonrc (to assist Windows users). The full order is:

%HOME%
%HOMEDRIVE% + %HOMEPATH%
%USERPROFILE%


Changes in 0.4.0:

A new method, Amazon::AWS::ShoppingCart::Cart#cart_get, has been added, to allow the retrieval of an existing shopping-cart from AWS. This is necessary when the original Cart object no longer exists.

The version of the Amazon AWS API requested when performing operations is now 2008-06-26. This is the latest at the time of writing.

Minor bug fixes.


Changes in 0.3.3:

YAML.aws_load has been removed. Its functionality is available directly from Amazon::AWS::AWSObject.yaml_load and it wasn't logical or necessary to duplicate that in the YAML class itself. There was no corresponding Marshal.aws_load method, but if there had been, that, too, would have been removed.

Ruby/AWS is now finally available as a RubyGems package.The current release can be found here::

http://www.caliban.org/files/ruby/ruby-aws-x.x.x.gem


Changes in 0.3.2:

Serialisation, e.g. with Marshal and YAML, has been a problem until now.

This is because subclasses of Amazon::AWS::AWSObject are created as needed when XML responses from AWS are parsed. Whilst there is no problem dumping objects instantiated from such classes, the difficulty arises when later loading and attempting to reinstantiate them in a new process, because the dynamic classes from which they were spawned no longer exist.

The solution to the problem comes in the form of the new methods Amazon::AWS::AWSObject.load and Amazon::AWS::AWSObject.yaml_load. Use these as
alternatives to Marshal.load and YAML.load, respectively.


Changes in 0.3.1:

This release mostly features refinements to the support for remote shopping-carts.

The 'Save For Later' area of remote shopping-carts is now implemented.

Cart#cart_modify now takes an extra parameter, save_for_later. If true, items are moved from the active to the Save For Later area of the cart. If false, they are moved in the opposite direction.

In both cases, the quantity parameter is ignored, because attempting to pass it through to AWS results in an error, even though the AWS documentation claims this can be done to move partial quantities from one area of the cart to the other.

Cart#include? now also returns true if the item being queried is in the Save For Later area of the cart. Previously, only the active area was inspected.

New methods, Cart#active? and Cart#saved_for_later? (alias Cart#saved?), return whether or not an item is present in a particular area of the cart. If the item is present, its CartItemId is returned; otherwise 'false'.

A bug that caused shopping-cart transactions to use the cache if one was requested has been fixed. Shopping-carts should never use the cache under any circumstances.

Request objects can now have their @cache attribute assigned to. A Cache object may be directly assigned to it, or you may assign the value 'true'. If @cache is set to 'true', a Cache object will automatically be assigned to it the next time @cache is referenced. This is most useful when one wishes to switch from using no cache to using one, or vice versa.

Cache#flush_expired invariably threw an exception. This bug has been fixed.

Geolocation of users by host and IP address now raises an Amazon::Locale::GeoError exception if the host or IP address is unresolvable.

There's a new Ruby/AWS mailing-list for discussion of the development and usage of this library:

http://www.caliban.org/mailman/listinfo/ruby-aws


Changes in 0.3.0:

Remote shopping carts are now implemented. See the Amazon::AWS::ShoppingCart module and the Amazon::AWS::ShoppingCart::Cart class.

Basically, this adds Cart.new, Cart#cart_create, Cart#cart_add, Cart#cart_modify and Cart#cart_clear. There's also Cart#each for iterating over the items in a cart.

The version of the Amazon AWS API requested when performing operations is now 2008-04-07. This is the latest at the time of writing.

A new iterator method, AWSObject#each, yields each |property, value| of the AWSObject.

The AWSObject and AWSArray classes have received a few new helper methods that should make AWSObject and single element AWSArray objects behave more akin to strings when they are being compared with strings, matched against regexes, etc.

When searches are performed, greater efforts are now made to determine whether Amazon returned any errors. In particular, batch operations and MultipleOperations may return errors at different locations in the XML tree than normal operations.

A bug that materialised only when using an HTTP proxy has been fixed.


Changes in 0.2.0:

Many more types of operation are now supported. In fact, everything except shopping cart operations is now supported.

Symbols can now be used instead of Strings as parameters when instantiating operation and response group objects.

Image objects can now retrieve their images and optionally overlay them with percentage discount icons.

Compatibility fixes for Ruby 1.9.

Dozens of other fixes and minor improvements.


Changes in 0.1.0:

This version features a completely rewritten XML parser, which dynamically creates classes based on XML returned by AWS. This makes Ruby/AWS highly future-proof.

Multiple operations are now implemented.

Numerous fixes and small improvements have been made.

Large scale code clean-up has been performed.

Much more documentation has been added.

Versions: [0.8.1 (2010-03-20)] [0.8.0 (2010-02-21)] [0.7.0 (2009-06-16)] [0.6.0 (2009-05-26)] [0.5.1 (2009-05-26)] [0.5.0 (2009-02-20)] [0.4.4 (2008-10-03)] [0.4.3 (2008-09-22)] [0.4.2 (2008-09-10)] [0.4.1 (2008-08-18)] [0.4.0 (2008-07-05)] [0.3.3 (2008-06-23)] [0.3.2 (2008-06-17)] [0.3.1 (2008-06-10)] [0.3.0 (2008-05-19)] [0.2.0 (2008-04-28)] [0.1.0 (2008-04-12)] [0.0.1 (2008-03-24)]

Edit this project (for project owner)

back to RAA top