bare-ruby-aws 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,580 @@
1
+ This is a fork of the Ruby/AWS library. It allows for any config file to be
2
+ used, not just one stored in your home directory (since a deployed web app may
3
+ not _have_ a home directory, nor the ability to alias it through an environemnt
4
+ variable.) and has had most functionality other than ItemSearch stripped out.
5
+
6
+ Introduction
7
+ ------------
8
+
9
+ Ruby/AWS is a Ruby language library that aims to make it relatively easy for
10
+ the programmer to retrieve information from the popular Amazon Web site via
11
+ Amazon's Associates Web Services (AWS). In addition to the original amazon.com
12
+ site, the local sites amazon.co.uk, amazon.de, amazon.fr, amazon.ca and
13
+ amazon.co.jp are also supported.
14
+
15
+ Development of Ruby/AWS has been quite swift since the appearance of the first
16
+ alpha version, 0.0.1, in late March of 2008. Although Ruby/AWS shares almost no
17
+ code with its now obsolete predecessor, Ruby/Amazon, many lessons were learnt
18
+ whilst developing that library, and the experience gained has been rolled into
19
+ Ruby/AWS.
20
+
21
+ As of version 0.3.0, I believe that Ruby/AWS has attained its goal of being
22
+ superior to the final version of Ruby/Amazon, 0.9.2, which was released in
23
+ August 2006.
24
+
25
+ This fork was created in July 2010.
26
+
27
+
28
+ History and compatibility with Ruby/Amazon
29
+ ------------------------------------------
30
+
31
+ In the beginning, there was Ruby/Amazon. This library was built around version
32
+ 3.x of the Amazon Web Service API and first saw the light of day in January
33
+ 2004. The version of the Amazon API in use at the time was known as AWS 3.x.
34
+
35
+ Amazon later renamed AWS to ECS, or E-Commerce Service, for the launch of
36
+ version 4 of their API, a complete overhaul that provided no backward
37
+ compatibility with previous versions. The previous version of the API was
38
+ thenceforth sometimes referred to as ECS 3.
39
+
40
+ Demonstrating the wisdom and consistency for which large companies are
41
+ renowned, Amazon changed their mind once again in late 2007, reverting to the
42
+ familiar name of AWS. This time, however, it was said to stand for Associates
43
+ Web Service, rather than Amazon Web Service.
44
+
45
+ Since Amazon first made AWS available, the number of Amazon Web APIs has
46
+ grown and AWS is now just one of many. It is therefore no longer appropriate
47
+ to call this library by a name so general as Ruby/Amazon, because it
48
+ provides an interface to just one of the Amazon Web APIs. Therefore, the
49
+ monicker for this library is Ruby/AWS.
50
+
51
+ Unfortunately for Ruby/AWS, Amazon changed the name once again in May 2009,
52
+ referring to it now as the Product Advertising API. Changing Ruby/AWS's name
53
+ would create more confusion than it would mitigate, however, so I'm not about
54
+ to do so. Similarly, I will continue to refer to the Amazon API in question as
55
+ AWS.
56
+
57
+ Ruby/AWS is built around version 4 of the Amazon AWS API, which is
58
+ fundamentally different to version 3, both in terms of how requests are made
59
+ and the data returned. The underlying structure of the XML response has
60
+ radically changed from previous versions.
61
+
62
+ It has therefore not been practical for Ruby/AWS to retain any level of API
63
+ compatibility with Ruby/Amazon. Unfortunately, this means that any code
64
+ written for Ruby/Amazon will need to be rewritten to work with Ruby/AWS. The
65
+ good news is that, in most cases, this isn't as much work as it might sound.
66
+
67
+ Another bit of good news is that the /etc/amazonrc and ~/.amazonrc files used
68
+ by Ruby/Amazon _are_ compatible with Ruby/AWS. The only change required for
69
+ Ruby/AWS is the addition of the 'key_id' and 'secret_key_id' parameters, which
70
+ should contain your AWS Access Key ID and its secret counterpart. That fact
71
+ notwithstanding, as of version 0.5.0, Ruby/AWS also supports a more flexible,
72
+ locale-specific configuration syntax.
73
+
74
+ Amazon finally decomissioned v3 of the AWS API on 2008-03-31. As a result, the
75
+ original Ruby/Amazon library no longer functions and is therefore obsolete.
76
+
77
+
78
+ AWS Access Key ID
79
+ -----------------
80
+
81
+ You can obtain an AWS Access Key ID here:
82
+
83
+ https://aws-portal.amazon.com/gp/aws/developer/registration/index.html
84
+
85
+ You may see mention of Subscription IDs at the above location. Subscription
86
+ IDs are not supported by Ruby/AWS and, in any case, are no longer supported by
87
+ Amazon since the introduction of authenticated requests. Please obtain and use
88
+ an AWS Access Key ID instead.
89
+
90
+
91
+ API version
92
+ -----------
93
+
94
+ Ruby/AWS currently requests the 2009-11-01 revision of the AWS API when
95
+ performing its operations:
96
+
97
+ http://docs.amazonwebservices.com/AWSECommerceService/2009-11-01/DG/
98
+
99
+ However, a different version can be requested via the 'api' parameter in the
100
+ user configuration file.
101
+
102
+
103
+ Status and functionality
104
+ ------------------------
105
+
106
+ Bare Ruby/AWS is currently beta software. Amongst other things, this means:
107
+
108
+ - You will encounter bugs, but hopefully not too many and none too serious.
109
+ Tell me about them and I will endeavour to fix them.
110
+
111
+ - The documentation isn't what it could be, but it's hopefully enough to get
112
+ you up and running.
113
+
114
+ - Not all features are currently implemented. Others may not yet be _fully_
115
+ implemented. Some, I probably haven't even thought of yet. Again, if
116
+ something's missing, tell me, and if it makes sense, I'll add it.
117
+
118
+ In spite of this shortcomings, the AWS v4 API is more or less fully
119
+ supported, with only small gaps in the functionality of some operations.
120
+
121
+ Currently implemented operations are:
122
+
123
+ ItemSearch
124
+
125
+ - Classes, methods, constants and instance variables may change name in the
126
+ future. New ones may appear from nowhere and existing ones may change shape,
127
+ grow, shrink or disappear without trace. Such fundamental changes will break
128
+ existing code, so I will endeavour to keep them to a minimum.
129
+
130
+ In short, code written to work with this release of Bare Ruby/AWS may stop working
131
+ when you upgrade to the next. In fact, it may even stop working _during_ this
132
+ release cycle, because it's possible there are fatal conditions that I didn't
133
+ encounter in my limited testing of the code. It's also possible that future
134
+ (possibly unannounced) changes made by Amazon will affect Bare Ruby/AWS in
135
+ ways I can't anticipate.
136
+
137
+ That said, the Bare Ruby/AWS API is pretty stable at this point in time. I won't
138
+ break any of the method interfaces without seriously considering the merits of
139
+ doing so.
140
+
141
+
142
+ Installation
143
+ ------------
144
+
145
+ Bare Ruby/AWS is installed by gem:
146
+
147
+ > sudo gem install bare-ruby-aws
148
+
149
+ If used as part of a Rails app, add the following line to the bottom of your
150
+ app's config/environment.rb file:
151
+
152
+ require 'amazon/aws/search'
153
+
154
+ Usage
155
+ -----
156
+
157
+ First of all, create a text file to use as a config file.
158
+ Its contents should look something like this:
159
+
160
+ # Any line that starts with a hash character is a comment.
161
+ key_id = '0Y44V8G41KCQPGF6XYZ2'
162
+ secret_key_id = 'k+kuddeoQJzUnImC0Hyy21J4xLWQc1hbvfQ+7F1G
163
+ associate = 'fuzbarorg-21'
164
+ cache = false
165
+ locale = 'uk'
166
+ encoding = 'iso-8859-15'
167
+
168
+ When Amazon checks for a valid signature, it does so by comparing its
169
+ computation of the signature with the one supplied by the user. In doing this,
170
+ Amazon uses the UTF-8 representation of parameter values that you supply, even
171
+ if you use a different encoding.
172
+
173
+ In order to have Bare Ruby/AWS properly reencode your strings as UTF-8, you need
174
+ to tell it which encoding you are using. The 'encoding' parameter can be used
175
+ for this, but you can omit it if your strings are already UTF-8, because this
176
+ is the default.
177
+
178
+ --
179
+
180
+ require 'amazon/aws/search'
181
+
182
+ # Avoid having to fully qualify our methods.
183
+ #
184
+ include Amazon::AWS
185
+ include Amazon::AWS::Search
186
+
187
+ is = ItemSearch.new( 'Books', { 'Title' => 'Ruby' } )
188
+
189
+ # I want to receive just a small amount of data for the items found.
190
+ #
191
+ is.response_group = ResponseGroup.new( :Small )
192
+
193
+ req = Request.new
194
+
195
+ # Make sure I'm talking to amazon.co.uk.
196
+ #
197
+ req.locale = 'uk'
198
+
199
+ # Actually talk to AWS.
200
+ #
201
+ resp = req.search( is )
202
+
203
+ # Drill down to the meat: the array of items returned.
204
+ #
205
+ items = resp.item_search_response[0].items[0].item
206
+
207
+ # The following alternative shorthand would also have worked:
208
+ #
209
+ # items = resp.item_search_response.items.item
210
+
211
+ # Available properties for first item:
212
+ #
213
+ puts items[0].properties
214
+
215
+ items.each do |item|
216
+ attribs = item.item_attributes[0]
217
+ puts attribs.label
218
+ if attribs.list_price
219
+ puts attribs.title, attribs.list_price[0].formatted_price, ''
220
+ end
221
+ end
222
+
223
+
224
+ Troubleshooting
225
+ ---------------
226
+
227
+ HTTP 400 is the main bane of people's life since Amazon started authenticating
228
+ requests to AWS. If you're trying to get Bare Ruby/AWS to work, but are plagued by
229
+ HTTP 400 responses, here are some possible causes:
230
+
231
+ - Your ~/.amazonrc file doesn't contain a secret_key_id parameter. Add one.
232
+
233
+ - Your computer's system clock is running more than 15 minutes slow. Amazon
234
+ consider a request timestamped more than 15 minutes in the past invalid.
235
+ Synchronise your system clock with a reliable time source.
236
+
237
+ Incidentally, Amazon don't object to requests timestamped in the future, but
238
+ that's something that may change at any time and therefore shouldn't be
239
+ relied upon.
240
+
241
+
242
+ XML to Ruby mapping
243
+ -------------------
244
+
245
+ Here, I will discuss the mapping of the XML returned from AWS to native Ruby
246
+ objects and data. Note that the XML shown below was that returned at the time
247
+ of writing and may look different to what you would see today if you were to
248
+ execute the same request.
249
+
250
+ When this code:
251
+
252
+ resp = req.search( is )
253
+
254
+ was called in the previous section, the following URL was composed and sent to
255
+ AWS as an HTTP GET operation:
256
+
257
+ 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
258
+
259
+ The following (abbreviated) AWS XML response was received:
260
+
261
+ <ItemSearchResponse>
262
+ <OperationRequest>
263
+ <HTTPHeaders>
264
+ <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"/>
265
+ </HTTPHeaders>
266
+ <RequestId>1TBGEZ48MF8KZ8TGXH65</RequestId>
267
+ <Arguments>
268
+ <Argument Name="SearchIndex" Value="Books"/>
269
+ <Argument Name="Service" Value="AWSECommerceService"/>
270
+ <Argument Name="ResponseGroup" Value="Small"/>
271
+ <Argument Name="Operation" Value="ItemSearch"/>
272
+ <Argument Name="Version" Value="2008-03-03"/>
273
+ <Argument Name="AssociateTag" Value="calibanorg-21"/>
274
+ <Argument Name="Title" Value="Ruby"/>
275
+ <Argument Name="AWSAccessKeyId" Value="01234567890123456789"/>
276
+ </Arguments>
277
+ <RequestProcessingTime>0.0671439170837402</RequestProcessingTime>
278
+ </OperationRequest>
279
+ <Items>
280
+ <Request>
281
+ <IsValid>True</IsValid>
282
+ <ItemSearchRequest>
283
+ <ResponseGroup>Small</ResponseGroup>
284
+ <SearchIndex>Books</SearchIndex>
285
+ <Title>Ruby</Title>
286
+ </ItemSearchRequest>
287
+ </Request>
288
+ <TotalResults>1804</TotalResults>
289
+ <TotalPages>181</TotalPages>
290
+ <Item>
291
+ <ASIN>0439943663</ASIN>
292
+ <DetailPageURL>
293
+ 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
294
+ </DetailPageURL>
295
+ <ItemAttributes>
296
+ <Author>Philip Pullman</Author>
297
+ <Manufacturer>Scholastic</Manufacturer>
298
+ <ProductGroup>Book</ProductGroup>
299
+ <Title>The Ruby in the Smoke (Sally Lockhart Quartet)</Title>
300
+ </ItemAttributes>
301
+ </Item>
302
+ <Item>
303
+ <ASIN>0596516177</ASIN>
304
+ ...
305
+
306
+ In Bare Ruby/AWS, each unique XML element name forms a class of the same name. All
307
+ such classes are subclasses of AWSObject. For example, OperationRequest is a
308
+ class, as is ItemAttributes.
309
+
310
+ As the XML tree is traversed, each element is converted to an instance of the
311
+ class of the same name. Every such object has instance variables, one per
312
+ unique child element name. The name of the instance variable is translated to
313
+ comply with Ruby convention by adding an underscore ('_') character at word
314
+ boundaries and converting the name to lower case.
315
+
316
+ For example, given the following XML:
317
+
318
+ <ItemAttributes>
319
+ <Author>Philip Pullman</Author>
320
+ <Manufacturer>Scholastic</Manufacturer>
321
+ <ProductGroup>Book</ProductGroup>
322
+ <Title>The Ruby in the Smoke (Sally Lockhart Quartet)</Title>
323
+ </ItemAttributes>
324
+
325
+ the following statements would all be true:
326
+
327
+ - ItemAttributes, Author, Manufacturer, ProductGroup and Title would all be
328
+ dynamically defined subclasses of AWSObject.
329
+
330
+ - An instance of the ItemAttributes class would be created, with instance
331
+ variables @author, @manufacturer, @product_group and @title.
332
+
333
+ - To each of these instance variables would respectively be assigned an array
334
+ of Author objects, an array of Manufacturer objects, an array of
335
+ ProductGroup objects and an array of Title objects. In the above case, these
336
+ would all be single element arrays, because there's only one instance of
337
+ each kind of tag in the XML.
338
+
339
+ - The Author, Manufacturer, ProductGroup and Title objects would have no
340
+ instance variables of their own, because the corresponding XML elements
341
+ have no children, just a value. These objects are therefore directly
342
+ assigned the value in question.
343
+
344
+ So, if resp is the top level AWSObject created and returned by calling the
345
+ Amazon::AWS::Search::Request#search method of the Request object, and we'd
346
+ like to know the ASIN of the first item found, we can refer to this as
347
+ follows:
348
+
349
+ resp.item_search_response[0].items[0].item[0].asin
350
+
351
+ Looking at each component of this chain in turn:
352
+
353
+ - resp is an AWSObject with a single instance variable, @item_search_response.
354
+ This is because the entire XML response is contained within a single
355
+ <ItemSearchResponse> element, so there's nothing else at the top level.
356
+
357
+ - resp.item_search_response is assigned an array of ItemSearchResponse
358
+ objects. Because there's only a single <ItemSearchResponse> element in the
359
+ whole document (containing the rest of the XML), the array contains only a
360
+ single element.
361
+
362
+ - resp.item_search_response[0] has an instance variable, @items, which is
363
+ assigned an array of Items objects. Here again, only a single element is
364
+ created, because there's only one corresponding <Items> element in the XML.
365
+
366
+ - resp.item_search_response[0].items[0] has an instance variable, @item, which
367
+ is an array containing the actual item(s) located by the search. It is a
368
+ multi-element array, however, because more than one item was found, as
369
+ represented by the multiple <Item> elements in the XML.
370
+
371
+ The creation of so many single element arrays is unfortunate. It makes user
372
+ code verboser, uglier and consequently harder to read.
373
+
374
+ You might wonder why Ruby/AWS doesn't just assign the single element itself,
375
+ rather than the array that contains it.
376
+
377
+ The answer is that most of these single-element arrays actually do have the
378
+ potential to be multi-element, because the corresponding XML tag _can_ appear
379
+ multiple times in an AWS response. A book, for example, _may_ have more than
380
+ one <Author>. Many other types of array, however, are necessarily single
381
+ element arrays. That same book, for example, is unlikely to have more than one
382
+ <Title>. This is context-dependent and difficult to define programatically.
383
+
384
+ As another concrete example, an ItemSearch will probably yield many <Item>
385
+ elements in the <ItemSearchResponse>, but these will invariably be nested in a
386
+ single <Items> element. The @items instance variable of the ItemSearchResponse
387
+ object will therefore always be a single-element array.
388
+
389
+ In other words, the following statements are both invariably true when an
390
+ ItemSearch successfully locates items:
391
+
392
+ - resp.item_search_response[0].items.size == 1
393
+
394
+ - resp.item_search_response[0].items[0].item.size >= 1
395
+
396
+ The awkwardness of using such single element arrays is alleviated in Ruby/AWS
397
+ by the use of the AWSArray subclass. An instance of this class differs from a
398
+ standard array by allowing element 0 of a single-element array to be
399
+ dereferenced using just the array name, i.e. without a subscript.
400
+
401
+ In other words, a reference to foo.bar will actually return foo[0].bar when
402
+ foo.size == 1. Note that this can only work because the array itself, foo, has
403
+ no bar method, so the intention is unambiguous and foo can delegate the
404
+ invocation of the method to foo[0]. foo.size, on the other hand, will _always_
405
+ invoke foo's bar method, never delegating to foo[0], because of the existence
406
+ of the Array#size method.
407
+
408
+ This allows the ASIN of the first item returned in the above XML to be
409
+ referred to using the following shorthand:
410
+
411
+ resp.item_search_response.items.item[0].asin
412
+
413
+ It's worth reiterating that it's still necessary in this example to refer to
414
+ item[0] using a subscript, because the <Items> element in the XML contains
415
+ multiple <Item> elements, making item.size > 1.
416
+
417
+ Use this syntactic shorthand to your advantage, but understand when you're
418
+ likely to be dealing with a single element array vs. a multiple. This will
419
+ become apparent as you gain familiarity with AWS v4.
420
+
421
+ An exception will be raised if an unknown method is called on a multi-element
422
+ array, as it can't be known to which array element the method invocation
423
+ should be delegated. This will almost certainly stem from an incorrect
424
+ assumption that an array contains only a single element when, in actual fact,
425
+ it contains multiple elements.
426
+
427
+ A further important detail to note is that not all AWS operations of the same
428
+ class return the same data. For example, an ItemSearch using the Books search
429
+ index will return items that, amongst other things, have an ItemAttributes
430
+ object containing further objects of class Author, ISBN, etc. An ItemSearch
431
+ using the DVD search index, by contrast, will have no Author or ISBN, but
432
+ will likely have a Director and probably one or more Actor objects.
433
+
434
+ Because of the disparity in same-class object attributes, Ruby/AWS returns
435
+ *nil* when an attempt is made to dereference a non-existent instance variable.
436
+ This approach was chosen because, more often than not, it cannot be known in
437
+ advance precisely which data will be returned by a given search operation.
438
+ Returning *nil* for non-existent attributes saves the user from having to
439
+ pepper their code with exception-handling clauses.
440
+
441
+ For example:
442
+
443
+ resp.item_search_response[0].items[0].item[0].item_attributes.director
444
+
445
+ will return *nil* for a book, because there was no corresponding Director
446
+ element in the XML returned by AWS.
447
+
448
+ Similarly:
449
+
450
+ resp.item_search_response[0].items[0].item[0].item_attributes.foo_bar
451
+
452
+ will _always_ return *nil* for _any_ item, because no kind of ItemSearch will
453
+ ever yield an item with a FooBar element.
454
+
455
+
456
+ Parameter checking
457
+ ------------------
458
+
459
+ There are many combinations of parameters and values that are legal for a
460
+ particular type of search. For example, an ItemSearch can use a Sort parameter
461
+ with a value of 'titlerank' if the SearchIndex is 'Books'. However, this value
462
+ wouldn't make much sense in the 'Automotive' SearchIndex.
463
+
464
+ The very presence of a certain parameter can be illegal in certain contexts.
465
+ For example, specifying the parameter 'Author' with _any_ value would be
466
+ nonsensical in the 'PetSupplies' SearchIndex.
467
+
468
+ To complicate things further, the validity of parameters and their values
469
+ differs not only by search type, but also by Amazon locale (amazon.com,
470
+ amazon.co.uk, amazon.de, etc.) and is prone to change with minor revisions of
471
+ the Amazon AWS API.
472
+
473
+ Even worse, the operations themselves can be illegal in certain locales.
474
+ TransactionLookup operations, for example, don't work in the UK locale at the
475
+ time of writing, but do work in the US locale. As a rule of thumb, we can say
476
+ that almost everything works in the US locale and _may_ work in others.
477
+
478
+ Ruby/Amazon attempted to track these complex and dynamic relationships to
479
+ prevent illegal or ineffective operations from being attempted. It was a
480
+ time-consuming and tedious task to track the evolving API (which often changed
481
+ in subtle ways without prior [or even belated] notice from Amazon), find all
482
+ of the corner cases and handle undocumented quirks.
483
+
484
+ With the highly dynamic nature of the Amazon environment and its many locales,
485
+ plus the sheer number of operations, parameters and their possibly legal
486
+ values in the AWS v4 API, this strict approach would be completely
487
+ impractical for Ruby/AWS. It therefore doesn't even try.
488
+
489
+ Instead, it's now up to you to ensure that you perform legal operations and
490
+ pass sensible parameters and values for the locale in which you're working.
491
+ The context is now your responsibility.
492
+
493
+ The one exception to this rule is search index checking for ItemSearch
494
+ operations. Code that attempts to use an invalid SearchIndex will raise an
495
+ exception. The list of allowable search indices can be found in the
496
+ Amazon::AWS::Operation::ItemSearch::SEARCH_INDICES array.
497
+
498
+ Of course, even this check exposes the user to the risk that Amazon may later
499
+ add new search indices, which would continue to be unrecognised and ruled
500
+ invalid by Ruby/AWS until an update was issued. Whilst I have chosen to
501
+ implement this very basic level of checking, it may be removed in the future
502
+ if it becomes impractical to keep it current.
503
+
504
+ In short, the validity of what goes into a search operation is your own
505
+ responsibility: garbage in, garbage out.
506
+
507
+ Thankfully, with the AWS Developer Guide at your side, it's largely common
508
+ sense which parameters and values can be used with each type of search. It's
509
+ less obvious when these differ by locale. For example, the 'Beauty'
510
+ SearchIndex was valid in the 'us' locale, but not in the 'uk' locale until the
511
+ 2009-01-06 revision of the AWS API.
512
+
513
+ Unfortunately, AWS abounds with such inconsistencies and they are prone to
514
+ change at any time. Amazon, themselves, seem to struggle to document all of
515
+ these quirks, a situation probably aggravated by the US focus of the AWS
516
+ staff.
517
+
518
+ The only way to apprise yourself of such peculiarities is to read Amazon's
519
+ latest developer documentation (and closely follow the release notes of each
520
+ minor API revision to make sure things haven't changed). If you don't want to
521
+ be exposed to such API changes, use the 'api' parameter in the user
522
+ configuration file to request a particular version of the API.
523
+
524
+ The AWS Developer Connection pages may also be of use to you. In particular,
525
+ the forum for discussing AWS has proved useful to me over the years:
526
+
527
+ http://developer.amazonwebservices.com/connect/forum.jspa?forumID=9
528
+
529
+ For those illegal operations that make it through to the Amazon servers, the
530
+ good news is that Amazon carries out extensive run-time parameter checking in
531
+ AWS v4 (much better than in v3) and will generate an error when an illegal set
532
+ of parameters and/or values is given. Ruby/AWS will dynamically generate a
533
+ class for the type of error reported and raise an exception of that class.
534
+
535
+ Using this approach, Ruby/AWS doesn't have to perform checks that Amazon will
536
+ perform, anyway. This helps keep the code base leaner, the library faster, and
537
+ reduces the chance that Ruby/AWS will disallow an operation that becomes valid
538
+ following a minor revision of AWS.
539
+
540
+
541
+ Documentation
542
+ -------------
543
+
544
+ You can generate HTML documentation for the library with the following
545
+ command, executed from the directory created when you unpacked the archive:
546
+
547
+ rdoc -SUx CVS lib
548
+
549
+ The documentation on how to use this library is currently incomplete, but it
550
+ should be enough to get you started.
551
+
552
+ You can also use the Ruby/AWS mailing-list:
553
+
554
+ http://caliban.org/mailman/listinfo/ruby-aws
555
+
556
+ to discuss any Ruby/AWS-related subjects and issues.
557
+
558
+
559
+ Examples
560
+ --------
561
+
562
+ The ./examples subdirectory contains working examples of code.
563
+
564
+
565
+ Licence
566
+ -------
567
+
568
+ This software is copyright (C) 2008-2010 Ian Macdonald and distributed under
569
+ the terms of the GNU GENERAL PUBLIC LICENSE, a copy of which is included.
570
+
571
+ --
572
+ Ian Macdonald
573
+ <ian@caliban.org>
574
+
575
+ The fork is copyright (C) 2010 Scott Williams and distributed under
576
+ the terms of the GNU GENERAL PUBLIC LICENSE, a copy of which is included.
577
+
578
+ --
579
+ Scott Williams
580
+ <scott@krazyyak.com>