ruby-aaws 0.4.1
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.
- data/COPYING +340 -0
- data/NEWS +304 -0
- data/README +558 -0
- data/README.rdoc +136 -0
- data/example/browse_node_lookup1 +46 -0
- data/example/customer_content_lookup1 +27 -0
- data/example/customer_content_search1 +21 -0
- data/example/example1 +87 -0
- data/example/help1 +25 -0
- data/example/item_lookup1 +55 -0
- data/example/item_lookup2 +55 -0
- data/example/item_search1 +30 -0
- data/example/item_search2 +37 -0
- data/example/item_search3 +23 -0
- data/example/list_lookup1 +29 -0
- data/example/list_search1 +30 -0
- data/example/multiple_operation1 +67 -0
- data/example/seller_listing_lookup1 +30 -0
- data/example/seller_listing_search1 +28 -0
- data/example/seller_lookup1 +45 -0
- data/example/shopping_cart1 +42 -0
- data/example/similarity_lookup1 +48 -0
- data/example/tag_lookup1 +34 -0
- data/example/transaction_lookup1 +26 -0
- data/lib/amazon/aws/cache.rb +141 -0
- data/lib/amazon/aws/search.rb +317 -0
- data/lib/amazon/aws/shoppingcart.rb +504 -0
- data/lib/amazon/aws.rb +1156 -0
- data/lib/amazon/locale.rb +102 -0
- data/lib/amazon.rb +99 -0
- data/test/setup.rb +31 -0
- data/test/tc_amazon.rb +20 -0
- data/test/tc_aws.rb +118 -0
- data/test/tc_item_search.rb +21 -0
- data/test/tc_multiple_operation.rb +58 -0
- data/test/tc_operation_request.rb +58 -0
- data/test/tc_serialisation.rb +103 -0
- data/test/tc_shopping_cart.rb +214 -0
- data/test/ts_aws.rb +12 -0
- metadata +95 -0
data/README
ADDED
@@ -0,0 +1,558 @@
|
|
1
|
+
$Id: README,v 1.14 2008/08/17 11:59:27 ianmacd Exp $
|
2
|
+
|
3
|
+
|
4
|
+
Introduction
|
5
|
+
------------
|
6
|
+
|
7
|
+
Ruby/AWS is a Ruby language library that makes it relatively easy for the
|
8
|
+
programmer to retrieve information from the popular Amazon Web site via
|
9
|
+
Amazon's Associates Web Services (AWS). In addition to the original amazon.com
|
10
|
+
site, the local sites amazon.co.uk, amazon.de, amazon.fr, amazon.ca and
|
11
|
+
amazon.co.jp are also supported.
|
12
|
+
|
13
|
+
Development of Ruby/AWS has been quite swift since the appearance of the first
|
14
|
+
alpha version, 0.0.1, in late March 2008. Although Ruby/AWS shares almost no
|
15
|
+
code with its now obsolete predecessor, Ruby/Amazon, many lessons were learnt
|
16
|
+
whilst developing that library, and the experience gained has been rolled into
|
17
|
+
Ruby/AWS.
|
18
|
+
|
19
|
+
As of version 0.3.0, I believe that Ruby/AWS has attained its goal of being
|
20
|
+
superior to the final version of Ruby/Amazon, 0.9.2, which was released in
|
21
|
+
August 2006.
|
22
|
+
|
23
|
+
|
24
|
+
History and compatibility with Ruby/Amazon
|
25
|
+
------------------------------------------
|
26
|
+
|
27
|
+
In the beginning, there was Ruby/Amazon. This library was built around version
|
28
|
+
3.x of the Amazon Web Service API and first saw the light of day in 2004. That
|
29
|
+
version of the Amazon API was known at the time as AWS 3.x.
|
30
|
+
|
31
|
+
Amazon later renamed AWS to ECS, or E-Commerce Service, for the launch of
|
32
|
+
version 4 of the API, a complete overhaul that provided no backward
|
33
|
+
compatibility with previous versions. The previous version of the API was
|
34
|
+
thenceforth sometimes referred to as ECS 3.
|
35
|
+
|
36
|
+
Demonstrating the wisdom and consistency for which large companies are
|
37
|
+
globally revered, Amazon changed its mind once again in late 2007, reverting
|
38
|
+
to the familiar name of AWS. This time, however, it was said to stand for
|
39
|
+
Associates Web Service.
|
40
|
+
|
41
|
+
Since Amazon started offering AWS, the number of Amazon Web APIs has grown.
|
42
|
+
AWS is now just one of many. It is therefore no longer appropriate to call
|
43
|
+
this library by a name so general as Ruby/Amazon, because it interfaces only
|
44
|
+
with AWS. Therefore, the library will be known henceforth as Ruby/AWS.
|
45
|
+
|
46
|
+
Ruby/AWS is built around version 4 of the Amazon AWS API, which is
|
47
|
+
fundamentally different to version 3, both in terms of how requests are made
|
48
|
+
and data returned. The underlying structure of the XML response is radically
|
49
|
+
changed from previous versions.
|
50
|
+
|
51
|
+
It has therefore not been possible in Ruby/AWS to retain any level of API
|
52
|
+
compatibility with Ruby/Amazon. Unfortunately, this means that any code
|
53
|
+
written for Ruby/Amazon will need to be rewritten to work with Ruby/AWS.
|
54
|
+
|
55
|
+
One small piece of good news is that the /etc/amazonrc and ~/.amazonrc files
|
56
|
+
used with Ruby/Amazon _are_ compatible with Ruby/AWS. The only change required
|
57
|
+
for Ruby/AWS is the addition of a 'key_id' parameter, which should contain
|
58
|
+
your AWS Access Key ID.
|
59
|
+
|
60
|
+
Amazon finally decomissioned v3 of the AWS API on 2008-03-31. As a result, the
|
61
|
+
original Ruby/Amazon library no longer functions.
|
62
|
+
|
63
|
+
|
64
|
+
AWS Access Key ID
|
65
|
+
-----------------
|
66
|
+
|
67
|
+
You can obtain an AWS Access Key ID here:
|
68
|
+
|
69
|
+
https://aws-portal.amazon.com/gp/aws/developer/registration/index.html
|
70
|
+
|
71
|
+
Subscription IDs are deprecated by Amazon and, in any case, not supported by
|
72
|
+
Ruby/AWS. Please obtain and use an AWS Access Key ID instead.
|
73
|
+
|
74
|
+
|
75
|
+
API version
|
76
|
+
-----------
|
77
|
+
|
78
|
+
Ruby/AWS currently requests the 2008-06-26 revision of the AWS API when
|
79
|
+
performing its operations:
|
80
|
+
|
81
|
+
http://docs.amazonwebservices.com/AWSECommerceService/2008-03-03/DG/
|
82
|
+
|
83
|
+
|
84
|
+
Status and functionality
|
85
|
+
------------------------
|
86
|
+
|
87
|
+
Ruby/AWS is currently alpha code. Amongst other things, this means:
|
88
|
+
|
89
|
+
- You will probably encounter _many_ bugs. You will certainly encounter a few.
|
90
|
+
If you tell me about them, I will endeavour to fix them.
|
91
|
+
|
92
|
+
- The documentation is incomplete, but steadily getting better. Version 0.0.1
|
93
|
+
had virtually none, so consider yourself lucky.
|
94
|
+
|
95
|
+
- Not all features are currently implemented. Others may not be _fully_
|
96
|
+
implemented. Yet others may not be _properly_ implemented.
|
97
|
+
|
98
|
+
Nevertheless, the AWS v4 API is now more or less fully supported, with only
|
99
|
+
tiny gaps in the functionality of some operations.
|
100
|
+
|
101
|
+
Currently implemented operations are:
|
102
|
+
|
103
|
+
BrowseNodeLookup
|
104
|
+
CustomerContentLookup
|
105
|
+
CustomerContentSearch
|
106
|
+
Help
|
107
|
+
ItemLookup
|
108
|
+
ItemSearch
|
109
|
+
ListLookup
|
110
|
+
ListSearch
|
111
|
+
SellerListingLookup
|
112
|
+
SellerListingSearch
|
113
|
+
SellerLookup
|
114
|
+
SimilarityLookup
|
115
|
+
TagLookup
|
116
|
+
TransactionLookup
|
117
|
+
|
118
|
+
Remote shopping-carts are also implemented as of version 0.3.0. The
|
119
|
+
following remote shopping-cart operations are supported:
|
120
|
+
|
121
|
+
CartCreate
|
122
|
+
CartAdd
|
123
|
+
CartModify
|
124
|
+
CartClear
|
125
|
+
|
126
|
+
Version 0.4.0 also adds:
|
127
|
+
|
128
|
+
CartGet
|
129
|
+
|
130
|
+
Multiple operations and batch requests are also supported, but not well
|
131
|
+
tested. Beware of bugs. There appear to also be (undocumented)
|
132
|
+
Amazon-imposed restrictions on the use of multiple operations and batch
|
133
|
+
requests, so some experimentation on your part will probably be required to
|
134
|
+
determine what works and what doesn't.
|
135
|
+
|
136
|
+
- Classes, methods, constants and instance variables may change name in the
|
137
|
+
future. These various objects may appear from nowhere, change shape, grow,
|
138
|
+
shrink or disappear entirely. Indeed, this has already happened once in the
|
139
|
+
evolution from version 0.0.2 to version 0.1.0, breaking existing code in the
|
140
|
+
process.
|
141
|
+
|
142
|
+
In short, code written to work with this release of Ruby/AWS may stop working
|
143
|
+
when you upgrade to the next release. In fact, it may even stop working
|
144
|
+
_during_ this release, because it's possible there are circumstances that
|
145
|
+
would cause an exception to be raised, that I haven't come across in my
|
146
|
+
limited testing of the code.
|
147
|
+
|
148
|
+
That said, the Ruby/AWS's API is pretty stable at this point in time. I won't
|
149
|
+
break any of the method interfaces without seriously considering the merits of
|
150
|
+
doing so.
|
151
|
+
|
152
|
+
|
153
|
+
Installation
|
154
|
+
------------
|
155
|
+
|
156
|
+
Please see the INSTALL file for details of how to install Ruby/AWS. You can
|
157
|
+
choose between an installation script and a RubyGems installation.
|
158
|
+
|
159
|
+
|
160
|
+
Usage
|
161
|
+
-----
|
162
|
+
|
163
|
+
First of all, create either /etc/amazonrc or ~/.amazonrc. Its contents should
|
164
|
+
look something like this:
|
165
|
+
|
166
|
+
dev_token = 'D11XZ51ZUKJY66'
|
167
|
+
associate = 'fuzbarorg-21'
|
168
|
+
locale = 'uk'
|
169
|
+
email = 'foo@caliban.org'
|
170
|
+
password = 'xxxxxx'
|
171
|
+
cache = false
|
172
|
+
key_id = '0Y44V8G41KCQPGF6PTR2'
|
173
|
+
|
174
|
+
Because you're embedding a password and your key ID in the file, you should
|
175
|
+
protect it (on UNIX and similar systems) by making it mode 0600:
|
176
|
+
|
177
|
+
$ chmod 600 ~/.amazonrc
|
178
|
+
|
179
|
+
If you define cache to be true, you may also define cache_dir to point
|
180
|
+
somewhere other /tmp/amazon, which is the default.
|
181
|
+
|
182
|
+
If you're using Windows, the following locations are searched for the user
|
183
|
+
configuration file:
|
184
|
+
|
185
|
+
%HOME%
|
186
|
+
%HOMEDRIVE% + %HOMEPATH%
|
187
|
+
%USERPROFILE%
|
188
|
+
|
189
|
+
Choose one of these at your convenience.
|
190
|
+
|
191
|
+
Once you have your configuration file, you can get started on your code.
|
192
|
+
|
193
|
+
Here's some basic code, indicating how to perform an ItemSearch, probably the
|
194
|
+
most common type of AWS operation. Please see the ./examples subdirectory for
|
195
|
+
more examples of working code.
|
196
|
+
|
197
|
+
--
|
198
|
+
|
199
|
+
require 'amazon/aws/search'
|
200
|
+
|
201
|
+
# Avoid having to fully qualify our methods.
|
202
|
+
#
|
203
|
+
include Amazon::AWS
|
204
|
+
include Amazon::AWS::Search
|
205
|
+
|
206
|
+
is = ItemSearch.new( 'Books', { 'Title' => 'Ruby' } )
|
207
|
+
|
208
|
+
# I want to receive just a small amount of data for the items found.
|
209
|
+
#
|
210
|
+
rg = ResponseGroup.new( 'Small' )
|
211
|
+
|
212
|
+
req = Request.new
|
213
|
+
|
214
|
+
# Make sure I'm talking to amazon.co.uk.
|
215
|
+
#
|
216
|
+
req.locale = 'uk'
|
217
|
+
|
218
|
+
# Actually talk to AWS.
|
219
|
+
#
|
220
|
+
resp = req.search( is, rg )
|
221
|
+
|
222
|
+
# Drill down to the meat: the array of items returned.
|
223
|
+
#
|
224
|
+
items = resp.item_search_response[0].items[0].item
|
225
|
+
|
226
|
+
# The following alternative shorthand would also have worked:
|
227
|
+
#
|
228
|
+
# items = resp.item_search_response.items.item
|
229
|
+
|
230
|
+
# Available properties for first item:
|
231
|
+
#
|
232
|
+
puts items[0].properties
|
233
|
+
|
234
|
+
items.each do |item|
|
235
|
+
attribs = item.item_attributes[0]
|
236
|
+
puts attribs.label
|
237
|
+
if attribs.list_price
|
238
|
+
puts attribs.title, attribs.list_price[0].formatted_price, ''
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
|
243
|
+
XML to Ruby mapping
|
244
|
+
-------------------
|
245
|
+
|
246
|
+
Here, I will discuss the mapping of the XML returned from AWS to native Ruby
|
247
|
+
objects and data.
|
248
|
+
|
249
|
+
When the following code:
|
250
|
+
|
251
|
+
resp = req.search( is, rg )
|
252
|
+
|
253
|
+
was called in the previous section, the following URL was composed and sent to
|
254
|
+
AWS as an HTTP GET operation:
|
255
|
+
|
256
|
+
http://ecs.amazonaws.co.uk/onca/xml?AWSAccessKeyId=01234567890123456789&AssociateTag=calibanorg-21&Operation=ItemSearch&ResponseGroup=Small&SearchIndex=Books&Service=AWSECommerceService&Title=Ruby&Version=2008-03-03
|
257
|
+
|
258
|
+
The following (truncated) AWS XML response was received:
|
259
|
+
|
260
|
+
<ItemSearchResponse>
|
261
|
+
<OperationRequest>
|
262
|
+
<HTTPHeaders>
|
263
|
+
<Header Name="UserAgent" Value="Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.13) Gecko/20080325 Fedora/2.0.0.13-1.fc7 Firefox/2.0.0.13"/>
|
264
|
+
</HTTPHeaders>
|
265
|
+
<RequestId>1TBGEZ48MF8KZ8TGXH65</RequestId>
|
266
|
+
<Arguments>
|
267
|
+
<Argument Name="SearchIndex" Value="Books"/>
|
268
|
+
<Argument Name="Service" Value="AWSECommerceService"/>
|
269
|
+
<Argument Name="ResponseGroup" Value="Small"/>
|
270
|
+
<Argument Name="Operation" Value="ItemSearch"/>
|
271
|
+
<Argument Name="Version" Value="2008-03-03"/>
|
272
|
+
<Argument Name="AssociateTag" Value="calibanorg-21"/>
|
273
|
+
<Argument Name="Title" Value="Ruby"/>
|
274
|
+
<Argument Name="AWSAccessKeyId" Value="01234567890123456789"/>
|
275
|
+
</Arguments>
|
276
|
+
<RequestProcessingTime>0.0671439170837402</RequestProcessingTime>
|
277
|
+
</OperationRequest>
|
278
|
+
<Items>
|
279
|
+
<Request>
|
280
|
+
<IsValid>True</IsValid>
|
281
|
+
<ItemSearchRequest>
|
282
|
+
<ResponseGroup>Small</ResponseGroup>
|
283
|
+
<SearchIndex>Books</SearchIndex>
|
284
|
+
<Title>Ruby</Title>
|
285
|
+
</ItemSearchRequest>
|
286
|
+
</Request>
|
287
|
+
<TotalResults>1804</TotalResults>
|
288
|
+
<TotalPages>181</TotalPages>
|
289
|
+
<Item>
|
290
|
+
<ASIN>0439943663</ASIN>
|
291
|
+
<DetailPageURL>
|
292
|
+
http://www.amazon.co.uk/gp/redirect.html%3FASIN=0439943663%26tag=calibanorg-21%26lcode=xm2%26cID=2025%26ccmID=165953%26location=/o/ASIN/0439943663%253FSubscriptionId=0Y44V8FAFNM119C6PTR2
|
293
|
+
</DetailPageURL>
|
294
|
+
<ItemAttributes>
|
295
|
+
<Author>Philip Pullman</Author>
|
296
|
+
<Manufacturer>Scholastic</Manufacturer>
|
297
|
+
<ProductGroup>Book</ProductGroup>
|
298
|
+
<Title>The Ruby in the Smoke (Sally Lockhart Quartet)</Title>
|
299
|
+
</ItemAttributes>
|
300
|
+
</Item>
|
301
|
+
<Item>
|
302
|
+
<ASIN>0596516177</ASIN>
|
303
|
+
...
|
304
|
+
|
305
|
+
In Ruby/AWS, each unique XML element name forms a class of the same name. All
|
306
|
+
such classes are subclasses of AWSObject. For example, OperationRequest is a
|
307
|
+
class, as is ItemAttributes.
|
308
|
+
|
309
|
+
As the XML tree is traversed, each element is converted to an instance of the
|
310
|
+
class of the same name. Every such object has instance variables, one per
|
311
|
+
unique child element name. The name of the instance variable is translated to
|
312
|
+
comply with Ruby convention by adding an underscore ('_') character at word
|
313
|
+
boundaries and converting the name to lower case.
|
314
|
+
|
315
|
+
For example, given the following XML:
|
316
|
+
|
317
|
+
<ItemAttributes>
|
318
|
+
<Author>Philip Pullman</Author>
|
319
|
+
<Manufacturer>Scholastic</Manufacturer>
|
320
|
+
<ProductGroup>Book</ProductGroup>
|
321
|
+
<Title>The Ruby in the Smoke (Sally Lockhart Quartet)</Title>
|
322
|
+
</ItemAttributes>
|
323
|
+
|
324
|
+
the following statements would all be true:
|
325
|
+
|
326
|
+
- ItemAttributes, Author, Manufacturer, ProductGroup and Title would all be
|
327
|
+
dynamically defined subclasses of AWSObject.
|
328
|
+
|
329
|
+
- An instance of the ItemAttributes class would be instantiated, with instance
|
330
|
+
variables @author, @manufacturer, @product_group and @title.
|
331
|
+
|
332
|
+
- To each of these instance variables would respectively be assigned an array
|
333
|
+
of Author objects, an array of Manufacturer objects, an array of
|
334
|
+
ProductGroup objects and an array of Title objects. In the above case, these
|
335
|
+
would all be single element arrays, because there's only one instance of
|
336
|
+
each kind of tag in the XML.
|
337
|
+
|
338
|
+
- These lowest level objects would have no instance variables, because the
|
339
|
+
corresponding XML elements contain no children, just a value. These objects
|
340
|
+
are therefore directly assigned the value of the corresponding XML element.
|
341
|
+
|
342
|
+
So, if resp is the top level AWSObject created and returned by calling
|
343
|
+
Amazon::AWS::Search::Request#search on the Request object, and we'd like to
|
344
|
+
know the ASIN of the first item found, we can refer to this as follows:
|
345
|
+
|
346
|
+
resp.item_search_response[0].items[0].item[0].asin
|
347
|
+
|
348
|
+
Looking at each component of this chain in turn:
|
349
|
+
|
350
|
+
- resp is an AWSObject with a single instance variable, @item_search_response.
|
351
|
+
This is because the entire XML response is contained within a single
|
352
|
+
<ItemSearchResponse> tag pair, so there's nothing else at the top level.
|
353
|
+
|
354
|
+
- resp.item_search_response is assigned an array of ItemSearchResponse
|
355
|
+
objects. Because there's only a single <ItemSearchResponse> tag pair in the
|
356
|
+
whole document (containing the rest of the XML), the array contains only a
|
357
|
+
single element.
|
358
|
+
|
359
|
+
- resp.item_search_response[0] has an instance variable, @items, which is
|
360
|
+
assigned an array of Items objects. Here again, only a single element is
|
361
|
+
created, because there's only one <Items> tag pair in the XML.
|
362
|
+
|
363
|
+
- resp.item_search_response[0].items[0] has an instance variable, @item, which
|
364
|
+
is an array containing the item(s) returned by the search. It is a
|
365
|
+
multi-element array, however, because more than one item was found, as
|
366
|
+
represented by the multiple <Item> elements in the XML.
|
367
|
+
|
368
|
+
The creation of so many single element arrays is unfortunate. It makes user
|
369
|
+
code verboser, uglier and consequently harder to read.
|
370
|
+
|
371
|
+
Some such arrays do, in fact, have the potential to be multi-element, because
|
372
|
+
the corresponding XML tag _can_ appear multiple times in the AWS response. A
|
373
|
+
book, for example, _may_ have more than one <Author>. Many other types of
|
374
|
+
array, however, are necessarily single element arrays. The same book, for
|
375
|
+
example, is unlikely to have more than one <Title>.
|
376
|
+
|
377
|
+
As another concrete example, an ItemSearch will probably return many <Item>
|
378
|
+
elements in the <ItemSearchResponse>, but these will invariably be nested in a
|
379
|
+
single <Items> tag. The @items instance variable of the ItemSearchResponse
|
380
|
+
object will therefore always have a size of 1.
|
381
|
+
|
382
|
+
In other words, the following statements are always true when an ItemSearch
|
383
|
+
successfully finds items:
|
384
|
+
|
385
|
+
- resp.item_search_response[0].items.size == 1
|
386
|
+
|
387
|
+
- resp.item_search_response[0].items[0].item.size >= 1
|
388
|
+
|
389
|
+
The awkwardness of using such single element arrays is alleviated in Ruby/AWS
|
390
|
+
by the use of the AWSArray subclass. This ever-so-slightly magic class of
|
391
|
+
array allows element 0 of single-element arrays to be dereferenced using the
|
392
|
+
base array name, i.e. without a subscript.
|
393
|
+
|
394
|
+
In other words, a reference to foo.bar will actually return foo[0].bar, so
|
395
|
+
long as foo.size == 1. Note that this only works because the array instance
|
396
|
+
itself, foo, has no bar method, so the intention is unambiguous and foo can
|
397
|
+
pass the call of bar down to foo[0]. foo.size, on the other hand, will
|
398
|
+
_always_ refer to foo and never to foo[0], because Array#size _is_ an existing
|
399
|
+
method.
|
400
|
+
|
401
|
+
This allows the ASIN of the first item returned in the above XML to be
|
402
|
+
referred to using the following shorthand:
|
403
|
+
|
404
|
+
resp.item_search_response.items.item[0].asin
|
405
|
+
|
406
|
+
It's worth reiterating that it's still necessary to refer to item[0] using a
|
407
|
+
subscript in this example, because the <Items> tag in the XML contains
|
408
|
+
multiple <Item> tags, making item.size > 1.
|
409
|
+
|
410
|
+
Use this syntactic shorthand to your advantage, but understand when you're
|
411
|
+
likely to be dealing with a single element array and when a multiple. This
|
412
|
+
will become apparent as you gain familiarity with AWS v4.
|
413
|
+
|
414
|
+
An exception will be thrown if an unknown method is called on a multi-element
|
415
|
+
array, as it can't be known which element the method invocation should be
|
416
|
+
passed to. This will almost certainly be the result of an incorrect assumption
|
417
|
+
that an array contains only a single element when it actually contains
|
418
|
+
multiple.
|
419
|
+
|
420
|
+
A further important detail to note is that not all AWS operations in the same
|
421
|
+
class return the same data. For example, an ItemSearch using the Books search
|
422
|
+
index will return items that, amongst other things, create an ItemAttributes
|
423
|
+
object containing further objects of class Author, ISBN, etc. An ItemSearch
|
424
|
+
using the DVD search index, however, will have no Author or ISBN, but _will_
|
425
|
+
have a Director and probably one or more Actor objects.
|
426
|
+
|
427
|
+
Because of the disparity in same-class object attributes, Ruby/AWS returns
|
428
|
+
*nil* when an attempt is made to dereference a non-existent instance variable.
|
429
|
+
This approach was chosen, because it often cannot be known in advance
|
430
|
+
precisely which data will be returned by a given search. Returning *nil* for
|
431
|
+
non-existent attributes means that the user does not have to pepper their code
|
432
|
+
with exception-handling clauses.
|
433
|
+
|
434
|
+
For example:
|
435
|
+
|
436
|
+
resp.item_search_response[0].items[0].item[0].item_attributes.director
|
437
|
+
|
438
|
+
will return *nil* for a book, because there was no corresponding Director
|
439
|
+
element in the XML returned by AWS.
|
440
|
+
|
441
|
+
Similarly:
|
442
|
+
|
443
|
+
resp.item_search_response[0].items[0].item[0].item_attributes.foo_bar
|
444
|
+
|
445
|
+
will _always_ return *nil* for any item, because no kind of ItemSearch will
|
446
|
+
ever yield an item with a FooBar attribute.
|
447
|
+
|
448
|
+
|
449
|
+
Parameter checking
|
450
|
+
------------------
|
451
|
+
|
452
|
+
There are many combinations of parameters and values that are legal for a
|
453
|
+
particular type of search. For example, an ItemSearch can use a Sort parameter
|
454
|
+
with a value of 'titlerank' if the SearchIndex is 'Books'. However, this value
|
455
|
+
wouldn't make much sense in the 'Automotive' SearchIndex.
|
456
|
+
|
457
|
+
The very presence of a certain parameter can be illegal in a certain contexts.
|
458
|
+
For example, specifying the parameter 'Author' with any value would be
|
459
|
+
nonsensical in the 'PetSupplies' SearchIndex.
|
460
|
+
|
461
|
+
To complicate things further, the validity of parameters and their values
|
462
|
+
differs not only by search type, but also by Amazon locale (amazon.com,
|
463
|
+
amazon.co.uk, amazon.de, etc.) and is prone to change with each minor revision
|
464
|
+
of the Amazon AWS API.
|
465
|
+
|
466
|
+
Even worse, even the operations themselves can be illegal in some locales.
|
467
|
+
TransactionLookup operations, for example, don't currently work in the UK
|
468
|
+
locale, but do work in the US locale.
|
469
|
+
|
470
|
+
Ruby/Amazon attempted to track these complex and dynamic relationships to
|
471
|
+
prevent illegal or ineffective operations from being attempted. It was a
|
472
|
+
time-consuming and tedious task to track the evolving API (which often changed
|
473
|
+
in subtle ways without prior [or even belated] notice from Amazon), find all
|
474
|
+
of the corner cases and handle undocumented quirks.
|
475
|
+
|
476
|
+
With the highly dynamic nature of the Amazon environment, plus the sheer
|
477
|
+
number of operations, parameters, possible legal values and locales in the AWS
|
478
|
+
v4 API, this strict approach must track too many combinations and permutations
|
479
|
+
to be practical. Ruby/AWS therefore no longer tries.
|
480
|
+
|
481
|
+
Instead, it's now up to you to ensure that you perform legal operations and
|
482
|
+
pass in sensible parameters and values for the locale in which you're working.
|
483
|
+
|
484
|
+
Parameter name checking, however, _is_ still performed. For example,
|
485
|
+
performing an ItemSearch and passing in a 'Keywrds' parameter would generate
|
486
|
+
an exception, because 'Keywrds' doesn't exist as a parameter in any context.
|
487
|
+
Here, 'Keywords' was obviously what was intended and a simple typo was made by
|
488
|
+
the user.
|
489
|
+
|
490
|
+
Similarly, the SearchIndex must also actually exist, so 'Music' or 'Beauty'
|
491
|
+
would be valid, but 'Furniture' or 'MobilePhones' would not, because Amazon
|
492
|
+
does not (currently) offer such indices.
|
493
|
+
|
494
|
+
In conclusion, we can say that broad checks are performed to determine whether
|
495
|
+
a search _could_ conceivably be valid in any context, but it's up to you to
|
496
|
+
determine whether the search actually _is_ valid in your particular context.
|
497
|
+
|
498
|
+
Thankfully, with the AWS Developer Guide at your side, it's largely common
|
499
|
+
sense which parameters and values can be used with each type of search. It's
|
500
|
+
less obvious when these differ by locale, such as 'Beauty' being a valid
|
501
|
+
SearchIndex in the 'us' locale, bot not in the 'uk'. AWS unfortunately abounds
|
502
|
+
with such inconsistencies.
|
503
|
+
|
504
|
+
The only way to apprise yourself of such quirks is to read Amazon's latest
|
505
|
+
developer documentation (and closely follow the release notes of each minor
|
506
|
+
API revision to make sure things haven't changed).
|
507
|
+
|
508
|
+
The AWS Developer Connection pages may also be of use to you. In particular,
|
509
|
+
the forum for discussing AWS has proved useful to me over the years:
|
510
|
+
|
511
|
+
http://developer.amazonwebservices.com/connect/forum.jspa?forumID=9
|
512
|
+
|
513
|
+
For those illegal operations that make it through and are passed to the Amazon
|
514
|
+
servers, the good news is that Amazon carries out extensive request-time
|
515
|
+
parameter checking in AWS v4 (much better than in v3) and will generate an
|
516
|
+
error when an illegal set of parameters and values is given. Ruby/AWS will
|
517
|
+
dynamically generate an exception class for the reported type of error and
|
518
|
+
raise an exception of that class.
|
519
|
+
|
520
|
+
Using this approach, Ruby/AWS doesn't have to perform checks that Amazon will
|
521
|
+
perform later anyway. This helps keep the code base leaner, the library
|
522
|
+
faster, and reduces the chances of Ruby/AWS disallowing operations that will
|
523
|
+
one day be allowed in a minor revision of AWS.
|
524
|
+
|
525
|
+
|
526
|
+
Documentation
|
527
|
+
-------------
|
528
|
+
|
529
|
+
You can generate HTML documentation for the library with the following
|
530
|
+
command, executed from the directory created when you unpacked the archive:
|
531
|
+
|
532
|
+
rdoc -SUx CVS lib
|
533
|
+
|
534
|
+
The documentation on how to use this library is currently incomplete, but that
|
535
|
+
is steadily being remedied.
|
536
|
+
|
537
|
+
You can also use the Ruby/AWS mailing-list:
|
538
|
+
|
539
|
+
http://www.caliban.org/mailman/listinfo/ruby-aws
|
540
|
+
|
541
|
+
to discuss all Ruby/AWS-related subjects and issues.
|
542
|
+
|
543
|
+
|
544
|
+
Examples
|
545
|
+
--------
|
546
|
+
|
547
|
+
The ./examples subdirectory contains working examples of code.
|
548
|
+
|
549
|
+
|
550
|
+
Licence
|
551
|
+
-------
|
552
|
+
|
553
|
+
This software is copyright (C) 2008 Ian Macdonald and distributed under the
|
554
|
+
terms of the GNU GENERAL PUBLIC LICENSE, a copy of which is included.
|
555
|
+
|
556
|
+
--
|
557
|
+
Ian Macdonald
|
558
|
+
<ian@caliban.org>
|
data/README.rdoc
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
#--
|
2
|
+
# $Id: README.rdoc,v 1.14 2008/07/05 16:10:04 ianmacd Exp $
|
3
|
+
#++
|
4
|
+
#
|
5
|
+
#
|
6
|
+
# = Ruby/AWS - A Ruby interface to the Amazon Associates Web Services API.
|
7
|
+
#
|
8
|
+
# == Introduction
|
9
|
+
#
|
10
|
+
# Ruby/AWS is a Ruby language library that allows programmatic access to
|
11
|
+
# the popular Amazon Web sites via the AWS v4 API. It is the successor to the
|
12
|
+
# now obsolete Ruby/Amazon.
|
13
|
+
#
|
14
|
+
# In addition to the original
|
15
|
+
# amazon.com[http://www.amazon.com/exec/obidos/redirect-home/calibanorg-20]
|
16
|
+
# site, the local sites
|
17
|
+
# amazon.co.uk[http://www.amazon.co.uk/exec/obidos/redirect-home/caliban-21],
|
18
|
+
# amazon.de[http://www.amazon.de/exec/obidos/redirect-home/calibanorg0a-21],
|
19
|
+
# amazon.fr[http://www.amazon.fr/exec/obidos/redirect-home/caliban08-21],
|
20
|
+
# amazon.ca[http://www.amazon.ca/exec/obidos/redirect-home/caliban-20] and
|
21
|
+
# amazon.co.jp[http://www.amazon.co.jp/exec/obidos/redirect-home/calibanorg-20]
|
22
|
+
# are also supported.
|
23
|
+
#
|
24
|
+
# Although the library is still in development, the AWS v4 API is now more or
|
25
|
+
# less fully supported, with only tiny gaps in the functionality of some
|
26
|
+
# operations.
|
27
|
+
#
|
28
|
+
# The following operations are supported:
|
29
|
+
#
|
30
|
+
# BrowseNodeLookup
|
31
|
+
# CustomerContentLookup
|
32
|
+
# CustomerContentSearch
|
33
|
+
# Help
|
34
|
+
# ItemLookup
|
35
|
+
# ItemSearch
|
36
|
+
# ListLookup
|
37
|
+
# ListSearch
|
38
|
+
# SellerListingLookup
|
39
|
+
# SellerListingSearch
|
40
|
+
# SellerLookup
|
41
|
+
# SimilarityLookup
|
42
|
+
# TagLookup
|
43
|
+
# TransactionLookup
|
44
|
+
#
|
45
|
+
# Remote shopping-carts are also supported. This adds the following operations:
|
46
|
+
#
|
47
|
+
# CartCreate
|
48
|
+
# CartAdd
|
49
|
+
# CartModify
|
50
|
+
# CartClear
|
51
|
+
# CartGet
|
52
|
+
#
|
53
|
+
# In addition, multiple operations and batch requests are also supported.
|
54
|
+
#
|
55
|
+
# Ruby/AWS also offers advanced features not directly available in the AWS
|
56
|
+
# API, such as the ability to retrieve *all* results pages for a particular
|
57
|
+
# search, rather than having to manually deal with AWS responses of 10 results
|
58
|
+
# per page.
|
59
|
+
#
|
60
|
+
# You can also retrieve product images and optionally overlay them with
|
61
|
+
# percentage discount icons.
|
62
|
+
#
|
63
|
+
# Another advanced feature is the ability to cache responses returned by AWS.
|
64
|
+
# If the cache is used (as it is by default), the results of each unique
|
65
|
+
# query will be cached and used for 24 hours. The cache can be manually
|
66
|
+
# flushed of all or just the expired entries.
|
67
|
+
#
|
68
|
+
# One other useful advanced feature is the ability to determine the
|
69
|
+
# appropriate Amazon locale for a given client, based on its IP address or
|
70
|
+
# host name. This allows you to perform AWS operations using the correct
|
71
|
+
# geographical Amazon site for any given client. German and Austrian clients
|
72
|
+
# can be made to interact with amazon.de, British and Irish clients with
|
73
|
+
# amazon.co.uk, etc.
|
74
|
+
#
|
75
|
+
#
|
76
|
+
# == Installation
|
77
|
+
#
|
78
|
+
# Please see the +INSTALL+ file supplied with the software for details of how
|
79
|
+
# to install Ruby/AWS. You can choose between an installation script and a
|
80
|
+
# RubyGems[http://www.rubygems.org/] installation.
|
81
|
+
#
|
82
|
+
# Note, however, if choosing the gem installation, that whilst Ruby/AWS's
|
83
|
+
# RubyForge UNIX name is ruby-aws, that name is already claimed by an {earlier
|
84
|
+
# project}[http://rubyforge.org/projects/ruby-aws/]. For that reason, it's
|
85
|
+
# necessary to download the gem to a local file before installing, because
|
86
|
+
# RubyForge's gem repository will always find the other ruby-aws project when
|
87
|
+
# queried for this name.
|
88
|
+
#
|
89
|
+
#
|
90
|
+
# == Prerequisites
|
91
|
+
#
|
92
|
+
# Before you can use this library, you need to obtain an Amazon Web Services
|
93
|
+
# {access key
|
94
|
+
# ID}[https://aws-portal.amazon.com/gp/aws/developer/registration/index.html].
|
95
|
+
#
|
96
|
+
# You should also apply for an {Associates
|
97
|
+
# account}[http://docs.amazonwebservices.com/AWSECommerceService/2008-04-07/GSG/BecominganAssociate.html],
|
98
|
+
# although this isn't strictly necessary. If you do not explicitly provide an
|
99
|
+
# Associates tag in your calls through Ruby/AWS, the tag of the Ruby/AWS
|
100
|
+
# author will be used by default.
|
101
|
+
#
|
102
|
+
#
|
103
|
+
# == See Also
|
104
|
+
#
|
105
|
+
# Ultimately, the way to get the most from this library is to read the AWS
|
106
|
+
# documentation to get a feel for what is possible, and then experiment with
|
107
|
+
# this library to see how the AWS calls are mapped into the Ruby world. You
|
108
|
+
# should also review this library's
|
109
|
+
# RDoc[http://www.ruby-doc.org/core/classes/RDoc.html]
|
110
|
+
# documentation[http://www.caliban.org/ruby/ruby-aws/] as well as the
|
111
|
+
# plain-text +README+ file that came with the archive.
|
112
|
+
#
|
113
|
+
# Additionally, there's a
|
114
|
+
# {mailing-list}[http://www.caliban.org/mailman/listinfo/ruby-aws] available,
|
115
|
+
# where you can discuss all Ruby/AWS-related subjects and issues.
|
116
|
+
#
|
117
|
+
# Please see the Amazon Web Services
|
118
|
+
# documentation[http://www.amazon.com/E-Commerce-Service-AWS-home-page/b/ref=sc_fe_c_0_15763381_1?node=12738641]
|
119
|
+
# for definitive information on the capabilities and inner workings of the AWS
|
120
|
+
# API.
|
121
|
+
#
|
122
|
+
#
|
123
|
+
# == Download
|
124
|
+
#
|
125
|
+
# Version 0.4.1
|
126
|
+
# === {gzip'ed tar archive}[http://www.caliban.org/files/ruby/ruby-aws-0.4.1.tar.gz]
|
127
|
+
# === {Ruby Gem}[http://www.caliban.org/files/ruby/ruby-aaws-0.4.1.gem]
|
128
|
+
# === {Fedora 7 RPM}[http://www.caliban.org/files/redhat/RPMS/noarch/ruby-aaws-0.4.1-1.fc7.noarch.rpm]
|
129
|
+
# === {Fedora 7 doc RPM}[http://www.caliban.org/files/redhat/RPMS/noarch/ruby-aws-doc-0.4.1-1.fc7.noarch.rpm]
|
130
|
+
# === {Fedora 7 source RPM}[http://www.caliban.org/files/redhat/SRPMS/ruby-aws-0.4.1-1.fc7.src.rpm]
|
131
|
+
#
|
132
|
+
#
|
133
|
+
# ---
|
134
|
+
# Author:: Ian Macdonald <mailto:ian@caliban.org>
|
135
|
+
# Version:: 0.4.1
|
136
|
+
# Licence:: GPL[http://www.gnu.org/copyleft/gpl.html]
|