kernow-ruby-aaws 0.5.4 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- data/INSTALL +7 -6
- data/NEWS +600 -272
- data/README +250 -163
- data/README.rdoc +145 -129
- data/Rakefile +13 -32
- data/VERSION +1 -0
- data/example/batch_operation +27 -0
- data/example/example1 +3 -3
- data/example/item_lookup1 +5 -4
- data/example/item_lookup2 +5 -4
- data/example/multiple_operation1 +4 -3
- data/example/vehicle_search +22 -0
- data/lib/amazon.rb +34 -16
- data/lib/amazon/aws.rb +496 -161
- data/lib/amazon/aws/search.rb +148 -28
- data/ruby-aaws.gemspec +117 -0
- data/test/setup.rb +5 -2
- data/test/tc_aws.rb +2 -2
- data/test/tc_browse_node_lookup.rb +62 -0
- data/test/tc_customer_content_lookup.rb +64 -0
- data/test/tc_help.rb +60 -0
- data/test/tc_item_lookup.rb +60 -0
- data/test/tc_item_search.rb +88 -3
- data/test/tc_list_lookup.rb +55 -0
- data/test/tc_list_search.rb +55 -0
- data/test/tc_multiple_operation.rb +211 -4
- data/test/tc_seller_listing_lookup.rb +58 -0
- data/test/tc_seller_listing_search.rb +70 -0
- data/test/tc_seller_lookup.rb +54 -0
- data/test/tc_shopping_cart.rb +9 -9
- data/test/tc_similarity_lookup.rb +59 -0
- data/test/tc_tag_lookup.rb +35 -0
- data/test/tc_transaction_lookup.rb +35 -0
- data/test/tc_vehicle_operations.rb +106 -0
- data/test/ts_aws.rb +16 -4
- metadata +85 -49
- data/ruby-aws.gemspec +0 -57
- data/ruby-aws.spec +0 -177
data/INSTALL
CHANGED
@@ -1,11 +1,14 @@
|
|
1
|
-
$Id: INSTALL,v 1.
|
1
|
+
$Id: INSTALL,v 1.9 2009/06/15 12:17:56 ianmacd Exp $
|
2
2
|
|
3
3
|
Requirements
|
4
4
|
------------
|
5
5
|
|
6
|
-
Ruby/AWS depends on Ruby 1.8.
|
7
|
-
|
8
|
-
|
6
|
+
Ruby/AWS depends on Ruby 1.8.7 or later in the 1.8 series. It has also been
|
7
|
+
tested to work with Ruby 1.9.1p129, the latest in the 1.9 series at the time
|
8
|
+
of writing.
|
9
|
+
|
10
|
+
You will also need at least version 0.9.8 of the OpenSSL libraries in order to
|
11
|
+
use the the signature authentication code.
|
9
12
|
|
10
13
|
|
11
14
|
Installation
|
@@ -44,8 +47,6 @@ See http://www.rubygems.org/ for more information on using RubyGems.
|
|
44
47
|
Documentation
|
45
48
|
-------------
|
46
49
|
|
47
|
-
Documentation is minimal in this alpha version of Ruby/AWS.
|
48
|
-
|
49
50
|
To create HTML documentation for Ruby/AWS, use rdoc as follows:
|
50
51
|
|
51
52
|
$ rdoc -SUx CVS lib
|
data/NEWS
CHANGED
@@ -1,382 +1,710 @@
|
|
1
|
-
$Id: NEWS,v 1.
|
1
|
+
$Id: NEWS,v 1.19 2009/06/15 23:48:49 ianmacd Exp $
|
2
2
|
|
3
3
|
|
4
|
-
0.
|
5
|
-
|
4
|
+
0.7.0 - 2009-06-16
|
5
|
+
------------------
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
1. This release introduces a shorthand module method for each of the AWS
|
8
|
+
operations. These can be used to create less verbose code at the expense of
|
9
|
+
flexibility.
|
10
10
|
|
11
|
-
|
12
|
-
now been fixed.
|
11
|
+
For example, we might normally write the following code:
|
13
12
|
|
13
|
+
is = ItemSearch.new( 'Books', { 'Title' => 'Ruby' } )
|
14
|
+
rg = ResponseGroup.new( :Large )
|
15
|
+
req = Request.new
|
16
|
+
response = req.search( is, rg )
|
17
|
+
|
18
|
+
but we could instead use ItemSearch's associated module method as follows:
|
14
19
|
|
15
|
-
|
16
|
-
-----
|
20
|
+
response = Amazon::AWS.item_search( 'Books', { 'Title' => 'Ruby' } )
|
17
21
|
|
18
|
-
|
19
|
-
|
20
|
-
configuration file.
|
22
|
+
There are some important restrictions when compared to the standard way of
|
23
|
+
doing things:
|
21
24
|
|
22
|
-
|
25
|
+
a. Astute readers will note that there's no way to specify to the module
|
26
|
+
methods which response group(s) to use. Instead, a reasonable default
|
27
|
+
set for each type of operation will be used, as per the new
|
28
|
+
ResponseGroup::DEFAULT hash.
|
23
29
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
Amazon::AWS::ShoppingCart::CartError are now immediate subclasses of
|
28
|
-
AmazonError. Previously, they were subclasses of StandardError.
|
30
|
+
The exception to this is Amazon::AWS.multiple_operation, which has no
|
31
|
+
response groups of its own, instead applying those of the operations it
|
32
|
+
combines.
|
29
33
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
returns an error -- are now subclasses of AWSError. Previously, they were
|
34
|
-
immediate subclasses of StandardError.
|
34
|
+
Because no access is provided to the Request object used by the module
|
35
|
+
method, it's also not possible to batch operations with Operation#batch
|
36
|
+
when using this form of the search.
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
-
AWSError.
|
39
|
-
|
38
|
+
On the other hand, you can use the Amazon::AWS.multiple_operation module
|
39
|
+
method to achieve more or less the same thing:
|
40
40
|
|
41
|
-
|
42
|
-
-----
|
41
|
+
Amazon::AWS.multiple_operation( op1, op2 )
|
43
42
|
|
44
|
-
|
45
|
-
|
43
|
+
When op1 and op2 are of the same class, the effect is similar to
|
44
|
+
batching two operations. The main difference is in the structure of the
|
45
|
+
XML document returned by AWS.
|
46
46
|
|
47
|
-
|
47
|
+
b. Similarly, one can't influence the key ID, associate tag, locale, cache
|
48
|
+
or user agent used for the request. These are all set as per
|
49
|
+
~/.amazonrc.
|
50
|
+
|
51
|
+
Likewise, the number of results pages to fetch will always be 1.
|
48
52
|
|
49
|
-
|
50
|
-
|
51
|
-
not nil (nil is the default), this string is read instead of /etc/amazonrc and
|
52
|
-
~/.amazonrc. This addition is really just to aid unit-testing of the
|
53
|
-
Amazon::Config class, as Amazon::Config.new never needs to be called by user
|
54
|
-
code.
|
53
|
+
c. The module methods have no RDoc documentation, because they are
|
54
|
+
dynamically generated.
|
55
55
|
|
56
|
-
|
56
|
+
Basically, the short form module methods are there as a convenience, but
|
57
|
+
that convenience comes at the expense of flexibility. If they don't meet
|
58
|
+
your needs, you will have to resort to the standard longhand form.
|
59
|
+
|
60
|
+
2. There's now an alternative to passing the list of desired response groups
|
61
|
+
as the second parameter to Request#search.
|
62
|
+
|
63
|
+
The second parameter of that method is now optional and *nil* by default.
|
64
|
+
Instead, you may assign to the response_group attribute of your operation
|
65
|
+
object.
|
66
|
+
|
67
|
+
For example:
|
57
68
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
69
|
+
is = ItemSearch.new( 'Books', { 'Title' => 'Ruby' } )
|
70
|
+
is.response_group = ResponseGroup.new( :Large )
|
71
|
+
req = Request.new
|
72
|
+
response = req.search( is )
|
73
|
+
|
74
|
+
Note that the @response_group variable will be initialised at the
|
75
|
+
time the operation object is instantiated. It will be assigned the same
|
76
|
+
reasonable default as used by the equivalent module method, namely
|
77
|
+
that specified by the new ResponseGroup::DEFAULT hash.
|
78
|
+
|
79
|
+
Specifying the desired response groups inside your operation object has at
|
80
|
+
least two advantages over passing the list to Request#search:
|
81
|
+
|
82
|
+
a. You can maintain a separate response group set per operation, rather
|
83
|
+
than having to pass a differen set to Request#search for each operation.
|
84
|
+
|
85
|
+
b. A reasonable default response group set can be used for any given
|
86
|
+
operation if you don't supply one.
|
87
|
+
|
88
|
+
3. More and more people are moving to Ruby 1.9, so this release of Ruby/AWS
|
89
|
+
has been tested to work with Ruby 1.9.1p129, the latest version at the time
|
90
|
+
of writing. Attaining ompatibility with 1.9 is a little tricky, because of
|
91
|
+
the way in which strings are no longer treated as sequences of bytes in
|
92
|
+
that version. Instead, they have knowledge of their encoding.
|
93
|
+
|
94
|
+
There may be one or two obscure 1.9-related bugs remaining, but all of the
|
95
|
+
unit tests pass, at least.
|
96
|
+
|
97
|
+
4. The signing of requests, introduced in Ruby/AWS 0.6.0, produced problems
|
98
|
+
for people with a version of OpenSSL earlier than 0.9.8.
|
99
|
+
|
100
|
+
The code will now check whether there is OpenSSL support for the SHA-256
|
101
|
+
Secure Hash Algorithm before attempting to use it. If not, each attempt to
|
102
|
+
sign a request will result in a warning if $DEBUG is used.
|
103
|
+
|
104
|
+
Once again, I remind you that Amazon intends to make request authentication
|
105
|
+
compulsory on 15th August 2009, so this change to Ruby/AWS only lets users
|
106
|
+
with an ancient OpenSSL library off the hook until then.
|
107
|
+
|
108
|
+
5. A second bug with the signing of requests occurred on Windows platforms.
|
109
|
+
Requests were not properly timestamped. This was due to deficiencies in the
|
110
|
+
underlying strftime(3) library function, but has now been fixed.
|
111
|
+
|
112
|
+
6. Finally, knowledge of a handful of relatively new search indices, such as
|
113
|
+
UnboxVideo, was missing. This has now been added. The AWS documentation is
|
114
|
+
terribly inconsistent in this regard, providing several different, yet
|
115
|
+
supposedly complete lists of valid search indices at various points
|
116
|
+
throughout the document.
|
117
|
+
|
118
|
+
|
119
|
+
0.6.0 - 2009-05-26
|
120
|
+
------------------
|
121
|
+
|
122
|
+
1. Requests to AWS can now be signed in order to authenticate them. Amazon
|
123
|
+
plans to make the signing of requests mandatory as of 15th August 2009, so
|
124
|
+
it is recommended to start doing so now.
|
125
|
+
|
126
|
+
To have your requests automatically signed by Ruby/AWS, simply add the
|
127
|
+
'secret_key_id' parameter to your ~/.amazonrc configuration file. Its value
|
128
|
+
should, rather predictably, be your secret access key, which can be
|
129
|
+
retrieved here:
|
130
|
+
|
131
|
+
https://aws-portal.amazon.com/gp/aws/developer/account/index.html?ie=UTF8&action=access-key
|
132
|
+
|
133
|
+
You needn't be concerned about Amazon's warnings not to show your secret
|
134
|
+
key to anyone else, because it will be used only for signing requests,
|
135
|
+
prior to sending them. The key itself will not be sent over the network to
|
136
|
+
Amazon, even in encrypted form.
|
137
|
+
|
138
|
+
In order to incorporate the new functionality, minor changes had to be made
|
139
|
+
to the way the AWS request URLs are encoded. This change means that
|
140
|
+
previous requests cached by earlier versions of Ruby/AWS will not be found
|
141
|
+
in the cache. This is a minor, one-time inconvenience, and it just means
|
142
|
+
that the requests will be performed and cached again.
|
143
|
+
|
144
|
+
2. When Amazon's AWS servers check whether the correct signature has been
|
145
|
+
applied to a request, they recalculate the signature based on the data in
|
146
|
+
the request and check for a match with the signature supplied by Ruby/AWS.
|
147
|
+
|
148
|
+
This introduces a complicating factor, namely the treatment of non-ASCII
|
149
|
+
characters in the request, such as accented letters. When recalculating the
|
150
|
+
signature, Amazon will use the UTF-8 representation of any such characters.
|
151
|
+
This will cause a signature mismatch if you used a different encoding, such
|
152
|
+
as ISO-8859-1 (a.k.a. Latin-1), when you supplied values for your request
|
153
|
+
parameters.
|
154
|
+
|
155
|
+
Ruby/AWS can't (reliably) dynamically determine which character encoding
|
156
|
+
your strings use, so this information can now be supplied via the
|
157
|
+
~/.amazonrc configuration file, using the 'encoding' parameter. This should
|
158
|
+
be set to whichever encoding you use. If left unset, it defaults to UTF-8.
|
159
|
+
An exception will be raised if you attempt to use an invalid (i.e. unknown)
|
160
|
+
encoding.
|
161
|
+
|
162
|
+
Currently, the encoding you use makes no difference unless your requests
|
163
|
+
are being signed, but because signing will soon be mandatory, I recommend
|
164
|
+
you explicitly state which encoding you intend to use.
|
165
|
+
|
166
|
+
You may also change the encoding in use at any time by assigning to the
|
167
|
+
@encoding instance variable of your Request object.
|
168
|
+
|
169
|
+
3. The robustness of the software has been improved by handling the following
|
170
|
+
additional exceptions while communicating with the AWS servers:
|
171
|
+
Errno::ECONNREFUSED, Errno::ECONNABORTED, Errno::ETIMEDOUT and
|
172
|
+
Timeout::Error. Users have reported that all of these occur from time to
|
173
|
+
time, although only Windows platforms seem to suffer from
|
174
|
+
Errno::ECONNABORTED.
|
175
|
+
|
176
|
+
4. The version of the AWS API used is now 2009-03-31, the latest at the time
|
177
|
+
of writing.
|
178
|
+
|
179
|
+
5. <RANT>
|
180
|
+
Amazon must have appointed a new interim Senior Vice-President of
|
181
|
+
Outward-Facing Moniker Reconciliation or something, because earlier this
|
182
|
+
month, on 8th May, I received an e-mail from Amazon, informing me that the
|
183
|
+
Web service formerly known as Amazon Web Services, latterly the E-Commerce
|
184
|
+
Service, and then, until this month, the Amazon Associates Web Service, is
|
185
|
+
to undergo yet another name change.
|
186
|
+
|
187
|
+
Once again, the reason for the new moniker is that it ostensibly "more
|
188
|
+
accurately reflects the purpose of the API". The new sobriquet is the
|
189
|
+
highly reflective 'Product Advertising API'.
|
190
|
+
|
191
|
+
It never ceases to amaze me that the collective intellectual might of a
|
192
|
+
company as large and resourceful as Amazon cannot, over a period of five
|
193
|
+
years, converge to decisively name an API.
|
194
|
+
|
195
|
+
How long until the reins of responsibility for this offering change hands
|
196
|
+
once again and the next in a growing line of misguided middle managers
|
197
|
+
decides that he can best raise his profile with his superiors by changing
|
198
|
+
the name of the API to "better reflect its purpose"?
|
199
|
+
|
200
|
+
Well, I'm resistant to change, especially stupid, time-wasting changes, so
|
201
|
+
I'll be continuing to refer to AWS as AWS for the foreseeable future. When
|
202
|
+
I say AWS, you'll know I mean the product whose name is woefully subject to
|
203
|
+
Amazon's whimsy.
|
204
|
+
|
205
|
+
The same e-mail informed me that Amazon would soon be introducing mandatory
|
206
|
+
authentication of AWS requests.
|
207
|
+
|
208
|
+
I downloaded the latest developer guide, wrote some code to implement
|
209
|
+
request signatures, and then spent a good couple of hours trying to make my
|
210
|
+
code produce the sample results shown in the developer guide.
|
211
|
+
|
212
|
+
Ultimately, I realised that the sample requests in the developer guide
|
213
|
+
could not have produced the output claimed by the documentation.
|
214
|
+
|
215
|
+
Not only that, but 3 of the 10 steps in the developer guide, in the section
|
216
|
+
detailing how to sign AWS requests, contain critical errors. This means
|
217
|
+
that Amazon didn't once follow their own documentation to verify its
|
218
|
+
correctness.
|
219
|
+
|
220
|
+
Most of the mistakes have since been silently rectified by Amazon, without
|
221
|
+
any mention on the AWS forum or revising the document version. Who knows
|
222
|
+
how often the developer guide changes on a day to day basis. I had thought
|
223
|
+
each dated version to be a static, completed work, but this is apparently
|
224
|
+
not the case.
|
225
|
+
</RANT>
|
226
|
+
|
227
|
+
|
228
|
+
0.5.1 - 2009-03-29
|
229
|
+
------------------
|
230
|
+
|
231
|
+
1. Catch Errno::EPIPE on server connections (Errno::ECONNRESET was already
|
232
|
+
caught). This can occur when the connection times out due to lack of use.
|
233
|
+
Running Ruby in debug mode will print the error message text when such an
|
234
|
+
exception is caught.
|
235
|
+
|
236
|
+
2. The version of the AWS API used is now 2009-02-01, the latest at the time
|
237
|
+
of writing.
|
238
|
+
|
239
|
+
3. The sequence numbering of shopping cart items incorrectly started from 2
|
240
|
+
instead of 1, but didn't cause a problem in practice.
|
241
|
+
|
242
|
+
|
243
|
+
0.5.0 - 2009-02-20
|
244
|
+
------------------
|
245
|
+
|
246
|
+
1. The configuration files (/etc/amazonrc and typically ~/.amazonrc) are now
|
247
|
+
locale-specific. Global and locale-specific settings can now be placed in
|
248
|
+
their own sections. For example:
|
249
|
+
|
250
|
+
Old style .amazonrc:
|
251
|
+
|
252
|
+
associate = 'caliban-21'
|
253
|
+
locale = 'uk'
|
254
|
+
cache = false
|
255
|
+
key_id = '0Y44V8FAFNM119C6XYZ2'
|
256
|
+
|
257
|
+
New style .amazonrc:
|
258
|
+
|
259
|
+
[global]
|
260
|
+
locale = 'uk'
|
261
|
+
cache = false
|
262
|
+
key_id = '0Y44V8FAFNM119C6XYZ2'
|
62
263
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
Operations that do not explicitly provide a pagination parameter (or, at
|
72
|
-
least, those for which there isn't one listed in the AWS Developer's Guide)
|
73
|
-
use ItemPage and pagination up to page 400. This is likely to throw an
|
74
|
-
exception, as such operations almost certainly don't support multiple results
|
75
|
-
pages.
|
264
|
+
[uk]
|
265
|
+
associate = 'calibanorg-21'
|
266
|
+
|
267
|
+
[us]
|
268
|
+
associate = 'calibanorg-20'
|
269
|
+
|
270
|
+
|
271
|
+
The old style of configuration is still supported.
|
76
272
|
|
273
|
+
2. ItemLookup.new and SellerListingLookup.new no longer take a third
|
274
|
+
parameter, b_parameters. Instead, the new Operation#batch method can be
|
275
|
+
used to create batch operations.
|
77
276
|
|
78
|
-
|
79
|
-
|
277
|
+
Operation#batch can batch multiple operations of any class, not just
|
278
|
+
ItemLookup and SellerListingLookup. The only requirement if that all
|
279
|
+
batched operations must be of the same class.
|
80
280
|
|
81
|
-
|
82
|
-
|
281
|
+
If you want to send multiple operations of different classes as a single
|
282
|
+
request, you must still use the MultipleOperation class.
|
83
283
|
|
84
|
-
|
85
|
-
|
86
|
-
|
284
|
+
3. VehiclePartLookup, VehiclePartSearch and VehicleSearch operations (which
|
285
|
+
were added in the 2008-08-19 revision of the AWS API, are now supported.
|
286
|
+
However, VehiclePartLookup is the only one of these that currently supports
|
287
|
+
pagination.
|
87
288
|
|
88
|
-
|
89
|
-
|
90
|
-
%USERPROFILE%
|
289
|
+
4. The list of allowable search indices for ItemSearch operations has been
|
290
|
+
updated in accordance with the latest AWS documentation.
|
91
291
|
|
92
|
-
|
292
|
+
5. Parameter checking for ItemSearch operations no longer occurs. It was
|
293
|
+
impractical to keep the list of valid parameters concurrent with AWS.
|
294
|
+
Related constants have therefore also been removed.
|
93
295
|
|
94
|
-
The
|
95
|
-
|
96
|
-
of the gem.
|
296
|
+
6. The version of the AWS API used is now 2009-01-06, the latest at the time
|
297
|
+
of writing.
|
97
298
|
|
299
|
+
The configuration file now supports a new global parameter for requesting a
|
300
|
+
different version of the API. For example:
|
98
301
|
|
99
|
-
|
100
|
-
-----
|
302
|
+
api = '2008-08-19'
|
101
303
|
|
102
|
-
|
103
|
-
|
304
|
+
7. While testing the ability to request a specific version of the AWS API, I
|
305
|
+
encountered a new kind of AWS error, the internal error, which is reported
|
306
|
+
using a different XML construct to that used for all other error
|
307
|
+
conditions.
|
104
308
|
|
105
|
-
|
106
|
-
|
107
|
-
|
309
|
+
I triggered one of these internal errors when I attempted an operation, a
|
310
|
+
VehicleSearch, that did not yet exist in the older version of the API that
|
311
|
+
I requested.
|
108
312
|
|
109
|
-
|
110
|
-
|
313
|
+
This type of error now throws a generic Amazon::AWS::Error::AWSError
|
314
|
+
exception.
|
315
|
+
|
316
|
+
It's reasonable to assume that there are other conditions that would cause
|
317
|
+
an internal AWS error to occur. These, too, will be raised as an exception.
|
318
|
+
|
319
|
+
Unfortunately, AWS supplies no information on the cause of such internal
|
320
|
+
errors, so Ruby/AWS is unable to pass on any clues to the user.
|
111
321
|
|
112
322
|
|
113
|
-
0.
|
114
|
-
|
323
|
+
0.4.4 - 2008-10-03
|
324
|
+
------------------
|
115
325
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
Marshal.aws_load method, but if there had been, that, too, would have been
|
120
|
-
removed.
|
326
|
+
1. It's now possible to have Ruby/AWS use a user configuration file with a
|
327
|
+
name other than .amazonrc. This is achieved by defining $AMAZONRCFILE. If
|
328
|
+
left undefined, the default of .amazonrc is used.
|
121
329
|
|
122
|
-
|
330
|
+
2. Locations other than $HOME were not being checked for .amazonrc. This bug
|
331
|
+
has now been fixed.
|
123
332
|
|
124
|
-
http://www.caliban.org/files/ruby/ruby-aws-0.3.3.gem
|
125
333
|
|
126
|
-
|
127
|
-
|
128
|
-
top level directory of the archive. The gem will be generated and placed in
|
129
|
-
the ./pkg subdirectory, from where you can 'sudo gem install' it.
|
334
|
+
0.4.3 - 2008-09-22
|
335
|
+
------------------
|
130
336
|
|
131
|
-
|
132
|
-
|
133
|
-
|
337
|
+
1. $AMAZONRCDIR is now searched for .amazonrc before $HOME and the other
|
338
|
+
directories. This allows a user-defined location to be used for the user
|
339
|
+
configuration file.
|
134
340
|
|
135
|
-
|
341
|
+
2. There is a new top-level class of exception for Ruby/AWS,
|
342
|
+
Amazon::AmazonError.
|
136
343
|
|
137
|
-
|
344
|
+
Most non-operational exceptions, such as Amazon::AWS::HTTPError,
|
345
|
+
Amazon::Config::ConfigError,
|
346
|
+
Amazon::AWS::Search::Request::AccessKeyIdError,
|
347
|
+
Amazon::AWS::Search::Request::LocaleError and
|
348
|
+
Amazon::AWS::ShoppingCart::CartError are now immediate subclasses of
|
349
|
+
AmazonError. Previously, they were subclasses of StandardError.
|
138
350
|
|
351
|
+
3. Amazon::AWS::Error::AWSError was previously a class that generated
|
352
|
+
exceptions, but it's now simply a container class derived from AmazonError.
|
353
|
+
All operational exceptions -- the ones whose class is dynamically created
|
354
|
+
when AWS returns an error -- are now subclasses of AWSError. Previously,
|
355
|
+
they were immediate subclasses of StandardError.
|
139
356
|
|
140
|
-
|
141
|
-
|
357
|
+
This has the advantage of allowing all of the exceptions resulting from
|
358
|
+
operational errors to be caught by rescuing just the container class,
|
359
|
+
AWSError.
|
360
|
+
|
142
361
|
|
143
|
-
|
144
|
-
|
145
|
-
This is because subclasses of Amazon::AWS::AWSObject are created as needed
|
146
|
-
when XML responses from AWS are parsed. Whilst there is no problem dumping
|
147
|
-
objects instantiated from such classes, the difficulty arises when later
|
148
|
-
loading and attempting to reinstantiate them in a new process, because the
|
149
|
-
dynamic classes from which they were spawned no longer exist.
|
362
|
+
0.4.2 - 2008-09-11
|
363
|
+
------------------
|
150
364
|
|
151
|
-
The
|
152
|
-
|
153
|
-
alternatives to Marshal.load and YAML.load, respectively.
|
365
|
+
1. The version of the Amazon AWS API requested when performing operations is
|
366
|
+
now 2008-08-19. This is the latest at the time of writing.
|
154
367
|
|
368
|
+
2. The exception class Amazon::Config::ConfigError was mysteriously not
|
369
|
+
defined.
|
155
370
|
|
156
|
-
|
157
|
-
|
371
|
+
3. Amazon::Config.new now accepts an optional argument, config_str, which may
|
372
|
+
contain the string equivalent of a config file's contents. When config_str
|
373
|
+
is not nil (nil is the default), this string is read instead of
|
374
|
+
/etc/amazonrc and ~/.amazonrc. This addition is really just to aid
|
375
|
+
unit-testing of the Amazon::Config class, as Amazon::Config.new never needs
|
376
|
+
to be called by user code.
|
158
377
|
|
159
|
-
|
160
|
-
shopping-carts.
|
378
|
+
4. Config file lines may now contain leading whitespace.
|
161
379
|
|
162
|
-
The
|
380
|
+
5. The Amazon::AWS::MAX_PAGES constant has gone, replaced by the PAGINATION
|
381
|
+
hash. Only ItemSearch should use ItemPage to page through results up to
|
382
|
+
MAX_PAGES when ALL_PAGES has been requested, but the same approach was
|
383
|
+
attempted for all types of operation.
|
384
|
+
|
385
|
+
Each operation has its own pagination parameter and its own maximum number
|
386
|
+
of pages that can be fetched. This is now stored in the
|
387
|
+
Amazon::AWS::PAGINATION hash.
|
388
|
+
|
389
|
+
Note that ItemLookup has three possible pagination parameters: OfferPage,
|
390
|
+
VariationPage and ReviewPage. Ruby/AWS uses OfferPage for the purposes of
|
391
|
+
ALL_PAGES.
|
392
|
+
|
393
|
+
Operations that do not explicitly provide a pagination parameter (or, at
|
394
|
+
least, those for which there isn't one listed in the AWS Developer's Guide)
|
395
|
+
use ItemPage for pagination up to page 400. In practice, this is likely to
|
396
|
+
throw an exception, as such operations almost certainly don't support
|
397
|
+
multiple results pages.
|
163
398
|
|
164
|
-
Cart#cart_modify now takes an extra parameter, save_for_later. If true, items
|
165
|
-
are moved from the active to the Save For Later area of the cart. If false,
|
166
|
-
they are moved in the opposite direction.
|
167
399
|
|
168
|
-
|
169
|
-
|
170
|
-
claims this can be done to move partial quantities from one area of the cart
|
171
|
-
to the other.
|
400
|
+
0.4.1 - 2008-08-18
|
401
|
+
------------------
|
172
402
|
|
173
|
-
|
174
|
-
|
403
|
+
1. The exception class Amazon::AWS::HTTPError was not actually defined, which
|
404
|
+
caused an error when an attempt was made to raise an instance of it.
|
175
405
|
|
176
|
-
|
177
|
-
|
178
|
-
|
406
|
+
2. If you're using Windows, %HOME% typically isn't defined. Therefore, the
|
407
|
+
following sequence of paths is now searched for your .amazonrc
|
408
|
+
configuration file:
|
179
409
|
|
180
|
-
|
181
|
-
|
410
|
+
%HOME%
|
411
|
+
%HOMEDRIVE% + %HOMEPATH%
|
412
|
+
%USERPROFILE%
|
413
|
+
|
414
|
+
Choose one of these at your convenience.
|
182
415
|
|
183
|
-
|
184
|
-
|
185
|
-
|
416
|
+
3. The Ruby/AWS gem has been renamed ruby-aaws (from ruby-aws) to avoid a
|
417
|
+
namespace clash with another project. This clash prevented remote
|
418
|
+
installation of the gem.
|
186
419
|
|
187
|
-
A bug that caused shopping-cart transactions to use the cache if one was
|
188
|
-
requested has been fixed. Shopping-carts should never use the cache under any
|
189
|
-
circumstances.
|
190
420
|
|
191
|
-
|
192
|
-
|
193
|
-
@cache is set to 'true', a Cache object will automatically be assigned to it
|
194
|
-
the next time @cache is referenced. This is most useful when one wishes to
|
195
|
-
switch from using no cache to using one, or vice versa.
|
421
|
+
0.4.0 - 2008-07-05
|
422
|
+
------------------
|
196
423
|
|
197
|
-
|
424
|
+
1. The version of the Amazon AWS API requested when performing operations is
|
425
|
+
now 2008-06-26. This is the latest at the time of writing.
|
198
426
|
|
199
|
-
|
200
|
-
|
427
|
+
2. A new method, Amazon::AWS::ShoppingCart::Cart#cart_get, has been added, to
|
428
|
+
allow the retrieval of an existing shopping-cart from AWS. This is
|
429
|
+
necessary when the original Cart object no longer exists.
|
201
430
|
|
202
|
-
|
203
|
-
|
431
|
+
3. A bug in Amazon::AWS::ShoppingCart::Cart#cart_modify has been fixed, which
|
432
|
+
caused carts with no items in their active section to raise an exception.
|
204
433
|
|
205
|
-
http://www.caliban.org/mailman/listinfo/ruby-aws
|
206
434
|
|
435
|
+
0.3.3 - 2008-06-23
|
436
|
+
------------------
|
437
|
+
|
438
|
+
1. YAML.aws_load has been removed. Its functionality is available directly
|
439
|
+
from Amazon::AWS::AWSObject.yaml_load and it wasn't logical or necessary to
|
440
|
+
duplicate that in the YAML class itself. There was no corresponding
|
441
|
+
Marshal.aws_load method, but if there had been, that, too, would have been
|
442
|
+
removed.
|
443
|
+
|
444
|
+
2. Ruby/AWS is finally available as a RubyGems package and can be found here:
|
445
|
+
|
446
|
+
http://www.caliban.org/files/ruby/ruby-aws-0.3.3.gem
|
447
|
+
|
448
|
+
The enclosed Rakefile can be used to build the gem from scratch. First make
|
449
|
+
sure you have rake and rubygems installed, and then simply type 'rake' in
|
450
|
+
the top level directory of the archive. The gem will be generated and
|
451
|
+
placed in the ./pkg subdirectory, from where you can 'sudo gem install' it.
|
452
|
+
|
453
|
+
This is my first gem, so bear with me. It appears to work properly, but I
|
454
|
+
offer no guarantees. One thing that doesn't currently work is installing
|
455
|
+
the package with gem's -t option to run the supplied unit tests.
|
456
|
+
|
457
|
+
More information about RubyGems can be found here:
|
207
458
|
|
208
|
-
|
209
|
-
-----
|
459
|
+
http://www.rubygems.org/
|
210
460
|
|
211
|
-
The version of the Amazon AWS API requested when performing operations is now
|
212
|
-
2008-04-07. This is the latest at the time of writing.
|
213
461
|
|
214
|
-
|
215
|
-
|
216
|
-
./amazon/aws/shoppingcart.rb for more details.
|
462
|
+
0.3.2 - 2008-06-17
|
463
|
+
------------------
|
217
464
|
|
218
|
-
|
219
|
-
|
220
|
-
|
465
|
+
1. Serialisation, e.g. with Marshal and YAML, has been a problem until now.
|
466
|
+
|
467
|
+
This is because subclasses of Amazon::AWS::AWSObject are created as needed
|
468
|
+
when XML responses from AWS are parsed. Whilst there is no problem dumping
|
469
|
+
objects instantiated from such classes, the difficulty arises when later
|
470
|
+
loading and attempting to reinstantiate them in a new process, because the
|
471
|
+
dynamic classes from which they were spawned no longer exist.
|
221
472
|
|
222
|
-
|
473
|
+
The solution to the problem comes in the form of the new methods
|
474
|
+
Amazon::AWS::AWSObject.load and Amazon::AWS::AWSObject.yaml_load. Use these
|
475
|
+
as alternatives to Marshal.load and YAML.load, respectively.
|
223
476
|
|
224
|
-
CartCreate
|
225
|
-
CartAdd
|
226
|
-
CartModify
|
227
|
-
CartClear
|
228
477
|
|
229
|
-
|
230
|
-
|
478
|
+
0.3.1 - 2008-06-10
|
479
|
+
------------------
|
231
480
|
|
232
|
-
|
233
|
-
|
481
|
+
This release mostly features refinements to the support for remote
|
482
|
+
shopping-carts.
|
234
483
|
|
235
|
-
|
236
|
-
AWSObject.
|
484
|
+
1. The 'Save For Later' area of remote shopping-carts is now implemented.
|
237
485
|
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
etc.
|
486
|
+
Cart#cart_modify now takes an extra parameter, save_for_later. If true,
|
487
|
+
items are moved from the active to the Save For Later area of the cart. If
|
488
|
+
false, they are moved in the opposite direction.
|
242
489
|
|
243
|
-
|
244
|
-
|
245
|
-
|
490
|
+
In both cases, the quantity parameter is ignored, because attempting to
|
491
|
+
pass it through to AWS results in an error, even though the AWS
|
492
|
+
documentation claims this can be done to move partial quantities from one
|
493
|
+
area of the cart to the other.
|
246
494
|
|
247
|
-
|
248
|
-
|
249
|
-
this:
|
495
|
+
2. Cart objects now have a @saved_for_later_items attribute, aliased to
|
496
|
+
@saved_items and @saved for brevity. Take your pick.
|
250
497
|
|
251
|
-
|
498
|
+
3. @cart_items is now set to [] when Cart.new is called. Previously, it wasn't
|
499
|
+
set until Cart#cart_create was used, at which time it was set to nil.
|
500
|
+
@saved_for_later_items is also set to [] by Cart.new.
|
252
501
|
|
253
|
-
|
502
|
+
4. Cart#include? now also returns true if the item being queried is in the
|
503
|
+
Save For Later area of the cart. Previously, only the active area was
|
504
|
+
inspected.
|
254
505
|
|
255
|
-
|
506
|
+
5. New methods, Cart#active? and Cart#saved_for_later? (alias Cart#saved?),
|
507
|
+
return whether or not an item is present in a particular area of the cart.
|
508
|
+
If the item is present, its CartItemId is returned; otherwise 'false'.
|
256
509
|
|
257
|
-
|
258
|
-
|
259
|
-
|
510
|
+
6. A bug that caused shopping-cart transactions to use the cache if one was
|
511
|
+
requested has been fixed. Shopping-carts should never use the cache under
|
512
|
+
any circumstances.
|
260
513
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
514
|
+
7. Request objects can now have their @cache attribute assigned to. A Cache
|
515
|
+
object may be directly assigned to it, or you may assign the value 'true'.
|
516
|
+
If @cache is set to 'true', a Cache object will automatically be assigned
|
517
|
+
to it the next time @cache is referenced. This is most useful when one
|
518
|
+
wishes to switch from using no cache to using one, or vice versa.
|
265
519
|
|
266
|
-
|
520
|
+
8. Cache#flush_expired invariably threw an exception. This bug has been fixed.
|
267
521
|
|
522
|
+
9. Geolocation of users by host and IP address now raises an
|
523
|
+
Amazon::Locale::GeoError exception if the host or IP address is
|
524
|
+
unresolvable.
|
268
525
|
|
269
|
-
|
270
|
-
|
526
|
+
There's a new Ruby/AWS mailing-list for discussion of the development and
|
527
|
+
usage of this library:
|
528
|
+
|
529
|
+
http://www.caliban.org/mailman/listinfo/ruby-aws
|
271
530
|
|
272
|
-
In previous versions, only 5 types of operation were supported:
|
273
531
|
|
274
|
-
|
275
|
-
|
276
|
-
ItemSearch
|
277
|
-
ListSearch
|
278
|
-
SellerListingSearch
|
532
|
+
0.3.0 - 2008-05-19
|
533
|
+
------------------
|
279
534
|
|
280
|
-
|
535
|
+
1. The version of the Amazon AWS API requested when performing operations is
|
536
|
+
now 2008-04-07. This is the latest at the time of writing.
|
281
537
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
ListLookup
|
286
|
-
SellerListingSearch
|
287
|
-
SellerLookup
|
288
|
-
SimilarityLookup
|
289
|
-
TagLookup
|
290
|
-
TransactionLookup
|
538
|
+
2. Remote shopping-carts are now implemented. See the
|
539
|
+
Amazon::AWS::ShoppingCart module and the Amazon::AWS::ShoppingCart::Cart
|
540
|
+
class in ./amazon/aws/shoppingcart.rb for more details.
|
291
541
|
|
292
|
-
|
542
|
+
Basically, the new methods are Cart.new, Cart#cart_create, Cart#cart_add,
|
543
|
+
Cart#cart_modify and Cart#cart_clear. There's also Cart#each for iterating
|
544
|
+
over the items in a cart.
|
293
545
|
|
294
|
-
|
295
|
-
Ruby/AWS.
|
546
|
+
This adds the following AWS operations to the list of those supported:
|
296
547
|
|
297
|
-
|
298
|
-
|
548
|
+
CartCreate
|
549
|
+
CartAdd
|
550
|
+
CartModify
|
551
|
+
CartClear
|
299
552
|
|
300
|
-
|
553
|
+
It's currently not possible to update a wishlist at purchase time by
|
554
|
+
referring to the item's ListItemId when adding it to a cart.
|
301
555
|
|
302
|
-
|
303
|
-
|
556
|
+
It's also currently not possible to add items to the 'Saved For Later'
|
557
|
+
section of the cart.
|
304
558
|
|
305
|
-
|
559
|
+
3. A new iterator method, AWSObject#each, yields each |property, value| of the
|
560
|
+
AWSObject.
|
306
561
|
|
307
|
-
|
308
|
-
|
562
|
+
4. The AWSObject and AWSArray classes have received a few new helper methods
|
563
|
+
that should make AWSObject and single element AWSArray objects behave more
|
564
|
+
akin to strings when they are being compared with strings, matched against
|
565
|
+
regexes, etc.
|
309
566
|
|
310
|
-
|
567
|
+
5. An otherwise undocumented method, AWSObject#kernel, provides unnested (i.e.
|
568
|
+
top level) AWSObject objects with a shortcut reference to the data most
|
569
|
+
likely of interest to the user.
|
311
570
|
|
312
|
-
|
313
|
-
|
571
|
+
For example, if a top level AWSObject is formed as the result of an
|
572
|
+
ItemSearch, one might normally refer to the items returned with something
|
573
|
+
like this:
|
314
574
|
|
315
|
-
|
316
|
-
with the %d format specifier in formatted strings. It's up to you, though, to
|
317
|
-
know when an AWSObject can be expected to contain a String that's usable as an
|
318
|
-
Integer.
|
575
|
+
foo.item_search_response[0].items[0].item
|
319
576
|
|
320
|
-
|
321
|
-
attribute that points to the URL of the image in question. Such objects now
|
322
|
-
have a #get method, which can be used to retrieve the image in question. This
|
323
|
-
method takes a single parameter, an integer precentage, which causes the
|
324
|
-
retrieved image to be overlayed with a discount icon.
|
577
|
+
AWSObject#kernel allows the same data to be referred to as follows:
|
325
578
|
|
326
|
-
|
327
|
-
1.9. The use of Ruby/AWS with this version is still not recommended, however.
|
328
|
-
For one thing, Ruby 1.9 seems to use #inspect in places that Ruby 1.8 used
|
329
|
-
#to_s.
|
579
|
+
foo.kernel
|
330
580
|
|
581
|
+
The path to the data is programatically determined, so this method only
|
582
|
+
works for top level AWSObject objects created by a class of operation whose
|
583
|
+
name can be used to derive the path. This is why this method is not
|
584
|
+
mentioned in the RDoc documentation.
|
331
585
|
|
332
|
-
|
333
|
-
|
586
|
+
6. When searches are performed, greater efforts are now made to determine
|
587
|
+
whether Amazon returned any errors. In particular, batch operations and
|
588
|
+
MultipleOperations may return errors at different locations in the XML tree
|
589
|
+
than normal operations.
|
334
590
|
|
335
|
-
|
336
|
-
very crude versions, 0.0.1 and 0.0.2.
|
591
|
+
7. A bug that materialised only when using an HTTP proxy has been fixed.
|
337
592
|
|
338
|
-
For one thing, the AWS XML parser has been completely rewritten. In this new
|
339
|
-
version, classes are dynamically generated as required, based on the elements
|
340
|
-
present in the XML pages returned by AWS.
|
341
593
|
|
342
|
-
|
343
|
-
|
344
|
-
AWS XML reponses. This time-consuming, unwieldy and unnecessary approach was
|
345
|
-
largely the result of my own lack of aptitude with the Ruby REXML library.
|
594
|
+
0.2.0 - 2008-04-28
|
595
|
+
------------------
|
346
596
|
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
597
|
+
1. In previous versions, only 5 types of operation were supported:
|
598
|
+
|
599
|
+
BrowseNodeLookup
|
600
|
+
ItemLookup
|
601
|
+
ItemSearch
|
602
|
+
ListSearch
|
603
|
+
SellerListingSearch
|
604
|
+
|
605
|
+
This version supports all remaining non-shopping-cart operations:
|
606
|
+
|
607
|
+
CustomerContentLookup
|
608
|
+
CustomerContentSearch
|
609
|
+
Help
|
610
|
+
ListLookup
|
611
|
+
SellerListingSearch
|
612
|
+
SellerLookup
|
613
|
+
SimilarityLookup
|
614
|
+
TagLookup
|
615
|
+
TransactionLookup
|
616
|
+
|
617
|
+
Examples of each of these can be found in ./examples/
|
618
|
+
|
619
|
+
It is hoped that shopping-carts will make their debut in the next release
|
620
|
+
of Ruby/AWS.
|
354
621
|
|
355
|
-
|
356
|
-
|
357
|
-
class definitions have been removed and all classes are now defined at the
|
358
|
-
time they first need to be instantiated.
|
622
|
+
2. One can now use a Symbol for search indices and hash keys when
|
623
|
+
instantiating operation objects and response group objects.
|
359
624
|
|
360
|
-
|
625
|
+
For example:
|
361
626
|
|
362
|
-
|
363
|
-
|
364
|
-
of data that later disappears from AWS responses [and even this should not
|
365
|
-
happen, because AWS v4 has a versioned API]), but they will not break the
|
366
|
-
library. The library will always create whichever classes are needed to
|
367
|
-
represent any given XML structure returned by AWS.
|
627
|
+
is = ItemSearch.new( 'Books', { 'Title' => 'Ruby' } )
|
628
|
+
rg = ResponseGroup.new( 'Large' )
|
368
629
|
|
369
|
-
|
370
|
-
included in responses will automatically cause said data to be made
|
371
|
-
available via Ruby/AWS. If, for example, Amazon starts to return data about
|
372
|
-
the duration of each CD in their catalogue, perhaps using a <Duration> tag,
|
373
|
-
foo.duration would automatically start to return that property.
|
630
|
+
can now be written like this:
|
374
631
|
|
375
|
-
|
632
|
+
is = ItemSearch.new( :Books, { :Title => 'Ruby' } )
|
633
|
+
rg = ResponseGroup.new( :Large )
|
376
634
|
|
377
|
-
|
635
|
+
It's up to you which form you use. The Symbol form saves one character. :-)
|
378
636
|
|
379
|
-
|
637
|
+
3. AWSObject#to_s has been improved to provide something better looking.
|
638
|
+
There's still room for improvement, though.
|
639
|
+
|
640
|
+
4. AWSObject#to_i has been added. This allows, for example, AWSObjects to be
|
641
|
+
used with the %d format specifier in formatted strings. It's up to you,
|
642
|
+
though, to know when an AWSObject can be expected to contain a String
|
643
|
+
that's usable as an Integer.
|
380
644
|
|
381
|
-
|
382
|
-
|
645
|
+
5. Objects of a class whose name matches AWSObject::.*Image typically have a
|
646
|
+
@url attribute that points to the URL of the image in question. Such
|
647
|
+
objects now have a #get method, which can be used to retrieve the image in
|
648
|
+
question. This method takes a single parameter, an integer precentage,
|
649
|
+
which causes the retrieved image to be overlayed with a discount icon.
|
650
|
+
|
651
|
+
6. Various compatibility fixes were made to allow Ruby/AWS to work under Ruby
|
652
|
+
1.9. The use of Ruby/AWS with this version is still not recommended,
|
653
|
+
however. For one thing, Ruby 1.9 seems to use #inspect in places that Ruby
|
654
|
+
1.8 used #to_s.
|
655
|
+
|
656
|
+
|
657
|
+
0.1.0 - 2008-04-11
|
658
|
+
------------------
|
659
|
+
|
660
|
+
1. Version 0.1.0 of Ruby/AWS has undergone fundamental changes from the
|
661
|
+
previous, very crude versions, 0.0.1 and 0.0.2.
|
662
|
+
|
663
|
+
For one thing, the AWS XML parser has been completely rewritten. In this
|
664
|
+
new version, classes are dynamically generated as required, based on the
|
665
|
+
elements present in the XML pages returned by AWS.
|
666
|
+
|
667
|
+
Previous versions of Ruby/AWS (and also Ruby/Amazon), manually defined most
|
668
|
+
of these classes, based on Amazon's developer documentation and examination
|
669
|
+
of AWS XML reponses. This time-consuming, unwieldy and unnecessary approach
|
670
|
+
was largely the result of my own lack of aptitude with the Ruby REXML
|
671
|
+
library.
|
672
|
+
|
673
|
+
While these manually defined classes accounted for much of the data
|
674
|
+
returned by AWS, a smaller section of the data was, nevertheless,
|
675
|
+
dynamically converted to Ruby data structures. This mix of manually and
|
676
|
+
automatically treated objects led to inconsistencies in the Ruby
|
677
|
+
representation of the hierarchical XML structure. This meant that it was
|
678
|
+
not quite possible to look at an AWS XML response and reliably determine
|
679
|
+
how the resulting Ruby data structure would look.
|
680
|
+
|
681
|
+
That inconsistency has been ironed out in version 0.1.0. As of now,
|
682
|
+
_everything_ is dynamically generated from the AWS XML response. All manual
|
683
|
+
class definitions have been removed and all classes are now defined at the
|
684
|
+
time they first need to be instantiated.
|
685
|
+
|
686
|
+
This has the following advantages:
|
687
|
+
|
688
|
+
- Changes in the structure of AWS XML responses will not break Ruby/AWS.
|
689
|
+
They may break user code (if, for example, you depend on the presence
|
690
|
+
of a piece of data that later disappears from AWS responses [and even
|
691
|
+
this should not happen, because AWS v4 has a versioned API]), but they
|
692
|
+
will not break the library. The library will always create whichever
|
693
|
+
classes are needed to represent any given XML structure returned by
|
694
|
+
AWS.
|
695
|
+
|
696
|
+
- Changes in the structure of AWS XML that results in new data being
|
697
|
+
included in responses will automatically cause said data to be made
|
698
|
+
available via Ruby/AWS. If, for example, Amazon starts to return data
|
699
|
+
about the duration of each CD in their catalogue, perhaps using a
|
700
|
+
<Duration> tag, foo.duration would automatically start to return that
|
701
|
+
property.
|
702
|
+
|
703
|
+
- It should be faster, but I haven't verified this.
|
704
|
+
|
705
|
+
2. Multiple operations are now supported.
|
706
|
+
|
707
|
+
3. Geolocation of locale is now working.
|
708
|
+
|
709
|
+
4. Documentation in this version has been radically improved, but is still
|
710
|
+
lacking.
|