alandipert-ruby-aaws 0.7.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/INSTALL +260 -0
- data/NEWS +710 -0
- data/README +653 -0
- data/README.rdoc +145 -0
- data/Rakefile +35 -0
- data/VERSION +1 -0
- data/example/batch_operation +27 -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 +56 -0
- data/example/item_lookup2 +56 -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 +68 -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/example/vehicle_search +22 -0
- data/lib/amazon/aws/cache.rb +141 -0
- data/lib/amazon/aws/search.rb +342 -0
- data/lib/amazon/aws/shoppingcart.rb +504 -0
- data/lib/amazon/aws.rb +1217 -0
- data/lib/amazon/locale.rb +102 -0
- data/lib/amazon.rb +145 -0
- data/ruby-aaws.gemspec +117 -0
- data/setup.rb +1306 -0
- data/test/setup.rb +34 -0
- data/test/tc_amazon.rb +20 -0
- data/test/tc_aws.rb +151 -0
- 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 +106 -0
- data/test/tc_list_lookup.rb +55 -0
- data/test/tc_list_search.rb +55 -0
- data/test/tc_multiple_operation.rb +265 -0
- data/test/tc_operation_request.rb +58 -0
- 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_serialisation.rb +103 -0
- data/test/tc_shopping_cart.rb +214 -0
- 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 +24 -0
- metadata +135 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
#
|
|
3
|
+
# $Id: multiple_operation1,v 1.2 2009/02/20 00:25:59 ianmacd Exp $
|
|
4
|
+
|
|
5
|
+
require 'amazon/aws/search'
|
|
6
|
+
|
|
7
|
+
include Amazon::AWS
|
|
8
|
+
include Amazon::AWS::Search
|
|
9
|
+
|
|
10
|
+
# Example of a batch operation, using the ASIN as the shared ID.
|
|
11
|
+
#
|
|
12
|
+
# The MerchantId restriction is to ensure that we retrieve only items that
|
|
13
|
+
# are for sale by Amazon. This is important when we later want to retrieve the
|
|
14
|
+
# availability status.
|
|
15
|
+
#
|
|
16
|
+
il = ItemLookup.new( 'ASIN', { 'ItemId' => 'B000AE4QEC',
|
|
17
|
+
'MerchantId' => 'Amazon' } )
|
|
18
|
+
il2 = ItemLookup.new( 'ASIN', { 'ItemId' => 'B000051WBE',
|
|
19
|
+
'MerchantId' => 'Amazon' } )
|
|
20
|
+
il.batch( il2 )
|
|
21
|
+
is = ItemSearch.new( 'Books', { 'Title' => 'Ruby' } )
|
|
22
|
+
|
|
23
|
+
mo = MultipleOperation.new( is, il )
|
|
24
|
+
|
|
25
|
+
# You can have multiple response groups.
|
|
26
|
+
#
|
|
27
|
+
rg = ResponseGroup.new( 'Medium', 'Offers', 'Reviews' )
|
|
28
|
+
|
|
29
|
+
req = Request.new
|
|
30
|
+
req.locale = 'uk'
|
|
31
|
+
resp = req.search( mo, rg )
|
|
32
|
+
|
|
33
|
+
# Items returned by the ItemSearch.
|
|
34
|
+
#
|
|
35
|
+
is_item_sets = resp.multi_operation_response.item_search_response[0].items
|
|
36
|
+
|
|
37
|
+
# Items returned by the ItemLookup.
|
|
38
|
+
#
|
|
39
|
+
il_item_sets = resp.multi_operation_response.item_lookup_response[0].items
|
|
40
|
+
|
|
41
|
+
item_sets = is_item_sets + il_item_sets
|
|
42
|
+
|
|
43
|
+
item_sets.each do |item_set|
|
|
44
|
+
item_set.item.each do |item|
|
|
45
|
+
attribs = item.item_attributes[0]
|
|
46
|
+
puts attribs.label
|
|
47
|
+
if attribs.list_price
|
|
48
|
+
puts attribs.title, attribs.list_price[0].formatted_price
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Availability has become a cumbersome thing to retrieve in AWSv4.
|
|
52
|
+
#
|
|
53
|
+
puts 'Availability: %s' %
|
|
54
|
+
[ item.offers[0].offer[0].offer_listing[0].availability ]
|
|
55
|
+
|
|
56
|
+
if item.customer_reviews
|
|
57
|
+
puts 'Average rating: %s' % [ item.customer_reviews[0].average_rating ]
|
|
58
|
+
puts 'Reviewed by %s customers.' %
|
|
59
|
+
[ item.customer_reviews[0].total_reviews ]
|
|
60
|
+
puts 'Customers said:'
|
|
61
|
+
item.customer_reviews[0].review.each do |review|
|
|
62
|
+
puts ' %s (%s votes)' % [ review.summary, review.total_votes ]
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
puts
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
#
|
|
3
|
+
# $Id: seller_listing_lookup1,v 1.1 2008/04/27 10:49:38 ianmacd Exp $
|
|
4
|
+
|
|
5
|
+
require 'amazon/aws/search'
|
|
6
|
+
|
|
7
|
+
include Amazon::AWS
|
|
8
|
+
include Amazon::AWS::Search
|
|
9
|
+
|
|
10
|
+
seller_id = 'AP8U6Y3PYQ9VO'
|
|
11
|
+
artist = 'Killing Joke'
|
|
12
|
+
sll = SellerListingLookup.new( seller_id, 'ASIN',
|
|
13
|
+
{ 'Id' => 'B0009RRRC8' } )
|
|
14
|
+
sll_rg = ResponseGroup.new( 'SellerListing' )
|
|
15
|
+
|
|
16
|
+
req = Request.new
|
|
17
|
+
req.locale = 'uk'
|
|
18
|
+
|
|
19
|
+
resp = req.search( sll, sll_rg )
|
|
20
|
+
|
|
21
|
+
# Yawn. This is verbose.
|
|
22
|
+
#
|
|
23
|
+
|
|
24
|
+
seller_id = resp.seller_listing_lookup_response[0].seller_listings[0].
|
|
25
|
+
request[0].seller_listing_lookup_request[0].seller_id
|
|
26
|
+
item = resp.seller_listing_lookup_response[0].seller_listings[0].
|
|
27
|
+
seller_listing[0]
|
|
28
|
+
|
|
29
|
+
puts 'Seller %s is selling the following item by %s:' % [ seller_id, artist ]
|
|
30
|
+
puts item
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
#
|
|
3
|
+
# $Id: seller_listing_search1,v 1.4 2008/04/28 10:00:28 ianmacd Exp $
|
|
4
|
+
|
|
5
|
+
require 'amazon/aws/search'
|
|
6
|
+
|
|
7
|
+
include Amazon::AWS
|
|
8
|
+
include Amazon::AWS::Search
|
|
9
|
+
|
|
10
|
+
seller_id = 'AP8U6Y3PYQ9VO'
|
|
11
|
+
artist = 'Killing Joke'
|
|
12
|
+
sls = SellerListingSearch.new( seller_id, { 'Keywords' => artist } )
|
|
13
|
+
sls_rg = ResponseGroup.new( 'SellerListing' )
|
|
14
|
+
|
|
15
|
+
req = Request.new
|
|
16
|
+
req.locale = 'uk'
|
|
17
|
+
|
|
18
|
+
resp = req.search( sls, sls_rg )
|
|
19
|
+
|
|
20
|
+
# Yawn. This is verbose.
|
|
21
|
+
#
|
|
22
|
+
seller_id = resp.seller_listing_search_response[0].seller_listings[0].
|
|
23
|
+
request[0].seller_listing_search_request[0].seller_id
|
|
24
|
+
items = resp.seller_listing_search_response[0].seller_listings[0].
|
|
25
|
+
seller_listing
|
|
26
|
+
|
|
27
|
+
puts 'Seller %s is selling the following items by %s:' % [ seller_id, artist ]
|
|
28
|
+
items.each { |item| puts item, '-' * 80 }
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
#
|
|
3
|
+
# $Id: seller_lookup1,v 1.1 2008/04/27 10:10:07 ianmacd Exp $
|
|
4
|
+
|
|
5
|
+
require 'amazon/aws/search'
|
|
6
|
+
|
|
7
|
+
include Amazon::AWS
|
|
8
|
+
include Amazon::AWS::Search
|
|
9
|
+
|
|
10
|
+
def display_properties(root, indent=0)
|
|
11
|
+
if root[0].respond_to? :properties
|
|
12
|
+
printf( 'Property %s =', root[0] )
|
|
13
|
+
root[0].properties.each do |pr|
|
|
14
|
+
display_properties( pr, indent + 2 )
|
|
15
|
+
end
|
|
16
|
+
else
|
|
17
|
+
printf( "Property %s = %s.\n", root, root.to_h[root] )
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
sl = SellerLookup.new( 'A3QFR0K2KCB7EG' )
|
|
22
|
+
sl_rg = ResponseGroup.new( 'Seller' )
|
|
23
|
+
|
|
24
|
+
req = Request.new
|
|
25
|
+
req.locale = 'us'
|
|
26
|
+
|
|
27
|
+
resp = req.search( sl, sl_rg ).seller_lookup_response
|
|
28
|
+
|
|
29
|
+
seller = resp.sellers.seller
|
|
30
|
+
|
|
31
|
+
seller.properties.each do |pr|
|
|
32
|
+
if seller[0][pr][0].properties.empty?
|
|
33
|
+
printf( "%s = %s.\n", pr, seller[0][pr] )
|
|
34
|
+
else
|
|
35
|
+
seller[0][pr][0].properties.each do |nest1|
|
|
36
|
+
if seller[0][pr][0][nest1][0].properties.empty?
|
|
37
|
+
printf( "%s = %s.\n", nest1, seller[0][pr][0][nest1][0] )
|
|
38
|
+
else
|
|
39
|
+
seller[0][pr][0][nest1][0].properties.each do |nest2|
|
|
40
|
+
printf( "%s = %s.\n", nest2, seller[0][pr][0][nest1][0][nest2] )
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
#
|
|
3
|
+
# $Id: shopping_cart1,v 1.2 2008/06/06 13:31:40 ianmacd Exp $
|
|
4
|
+
|
|
5
|
+
require 'amazon/aws/search'
|
|
6
|
+
require 'amazon/aws/shoppingcart'
|
|
7
|
+
|
|
8
|
+
include Amazon::AWS
|
|
9
|
+
#include Amazon::AWS::Search
|
|
10
|
+
include Amazon::AWS::ShoppingCart
|
|
11
|
+
|
|
12
|
+
cart = Cart.new
|
|
13
|
+
cart.locale = 'uk'
|
|
14
|
+
|
|
15
|
+
cart.cart_create( :ASIN, 'B00151HZA6', 3, false,
|
|
16
|
+
{ 'B000WC4AH0' => 2 ,
|
|
17
|
+
'B000PY32OM' => 8 } )
|
|
18
|
+
|
|
19
|
+
puts cart.cart_id
|
|
20
|
+
puts cart.hmac
|
|
21
|
+
puts cart.purchase_url
|
|
22
|
+
puts
|
|
23
|
+
|
|
24
|
+
cart.cart_add( :ASIN, 'B0014C2BL4', 1,
|
|
25
|
+
{ 'B00006BCKL' => 5 },
|
|
26
|
+
{ 'B000VVE2UW' => 4 } )
|
|
27
|
+
cart.cart_add( :ASIN, 'B0013F2M52', 3 )
|
|
28
|
+
cart.cart_add( :ASIN, 'B000HCPSR6', 5 )
|
|
29
|
+
cart.cart_modify( :ASIN, 'B00151HZA6', 2, true,
|
|
30
|
+
{ 'B0013F2M52' => 1 },
|
|
31
|
+
{ 'B000HCPSR6' => 3 } )
|
|
32
|
+
|
|
33
|
+
puts 'Cart contents:'
|
|
34
|
+
cart.each do |it|
|
|
35
|
+
puts "ASIN: %s, item Id: %-14s, quantity: %d" %
|
|
36
|
+
[ it.asin, it.cart_item_id, it.quantity ]
|
|
37
|
+
end
|
|
38
|
+
puts
|
|
39
|
+
|
|
40
|
+
puts cart.items
|
|
41
|
+
|
|
42
|
+
cart.cart_clear
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
#
|
|
3
|
+
# $Id: similarity_lookup1,v 1.1 2008/04/27 06:03:54 ianmacd Exp $
|
|
4
|
+
|
|
5
|
+
require 'amazon/aws'
|
|
6
|
+
require 'amazon/aws/search'
|
|
7
|
+
|
|
8
|
+
include Amazon::AWS
|
|
9
|
+
include Amazon::AWS::Search
|
|
10
|
+
|
|
11
|
+
# Example of a batch operation, using the ASIN as the shared ID.
|
|
12
|
+
#
|
|
13
|
+
sl = SimilarityLookup.new( [ 'B000AE4QEC', 'B000051WBE' ] )
|
|
14
|
+
|
|
15
|
+
# You can have multiple response groups.
|
|
16
|
+
#
|
|
17
|
+
rg = ResponseGroup.new( 'Medium', 'Offers', 'Reviews' )
|
|
18
|
+
|
|
19
|
+
req = Request.new
|
|
20
|
+
req.locale = 'uk'
|
|
21
|
+
|
|
22
|
+
resp = req.search( sl, rg )
|
|
23
|
+
item_sets = resp.similarity_lookup_response[0].items
|
|
24
|
+
|
|
25
|
+
item_sets.each do |item_set|
|
|
26
|
+
item_set.item.each do |item|
|
|
27
|
+
attribs = item.item_attributes[0]
|
|
28
|
+
puts attribs.label
|
|
29
|
+
if attribs.list_price
|
|
30
|
+
puts attribs.title, attribs.list_price[0].formatted_price
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Availability has become a cumbersome thing to retrieve in AWSv4.
|
|
34
|
+
#
|
|
35
|
+
puts 'Availability: %s' %
|
|
36
|
+
[ item.offers[0].offer[0].offer_listing[0].availability ]
|
|
37
|
+
puts 'Average rating: %s' % [ item.customer_reviews[0].average_rating ]
|
|
38
|
+
puts 'Reviewed by %s customers.' %
|
|
39
|
+
[ item.customer_reviews[0].total_reviews ]
|
|
40
|
+
|
|
41
|
+
puts 'Customers said:'
|
|
42
|
+
item.customer_reviews[0].review.each do |review|
|
|
43
|
+
puts ' %s (%s votes)' % [ review.summary, review.total_votes ]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
puts
|
|
47
|
+
end
|
|
48
|
+
end
|
data/example/tag_lookup1
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
#
|
|
3
|
+
# $Id: tag_lookup1,v 1.1 2008/04/27 19:46:43 ianmacd Exp $
|
|
4
|
+
|
|
5
|
+
require 'amazon/aws'
|
|
6
|
+
require 'amazon/aws/search'
|
|
7
|
+
|
|
8
|
+
include Amazon::AWS
|
|
9
|
+
include Amazon::AWS::Search
|
|
10
|
+
|
|
11
|
+
tag_str = 'Awful'
|
|
12
|
+
tl = TagLookup.new( tag_str )
|
|
13
|
+
|
|
14
|
+
# You can have multiple response groups.
|
|
15
|
+
#
|
|
16
|
+
rg = ResponseGroup.new( 'Tags', 'TagsSummary' )
|
|
17
|
+
|
|
18
|
+
req = Request.new
|
|
19
|
+
req.locale = 'us'
|
|
20
|
+
|
|
21
|
+
resp = req.search( tl, rg )
|
|
22
|
+
tag = resp.tag_lookup_response.tags.tag
|
|
23
|
+
|
|
24
|
+
printf( "Tag name '%s' has %d distinct items.\n", tag_str, tag.distinct_items )
|
|
25
|
+
printf( "Tag has %d distinct items.\n", tag.distinct_users )
|
|
26
|
+
printf( "Tag has %d total usages.\n", tag.total_usages )
|
|
27
|
+
printf( "Tagged for the first time in entity %s on %s\nby %s..\n",
|
|
28
|
+
tag.first_tagging.entity_id,
|
|
29
|
+
tag.first_tagging.time,
|
|
30
|
+
tag.first_tagging.user_id )
|
|
31
|
+
printf( "Tagged for the last time in entity %s on %s\nby %s..\n",
|
|
32
|
+
tag.last_tagging.entity_id,
|
|
33
|
+
tag.last_tagging.time,
|
|
34
|
+
tag.last_tagging.user_id )
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
#
|
|
3
|
+
# $Id: transaction_lookup1,v 1.1 2008/04/27 21:24:21 ianmacd Exp $
|
|
4
|
+
|
|
5
|
+
require 'amazon/aws'
|
|
6
|
+
require 'amazon/aws/search'
|
|
7
|
+
|
|
8
|
+
include Amazon::AWS
|
|
9
|
+
include Amazon::AWS::Search
|
|
10
|
+
|
|
11
|
+
tl = TransactionLookup.new( '103-5663398-5028241' )
|
|
12
|
+
|
|
13
|
+
rg = ResponseGroup.new( 'TransactionDetails' )
|
|
14
|
+
|
|
15
|
+
req = Request.new
|
|
16
|
+
req.locale = 'us'
|
|
17
|
+
|
|
18
|
+
resp = req.search( tl, rg )
|
|
19
|
+
trans = resp.transaction_lookup_response.transactions.transaction
|
|
20
|
+
|
|
21
|
+
printf( "Transaction date was %s.\n", trans.transaction_date )
|
|
22
|
+
printf( "It was in the amount of %s and the seller was %s.\n",
|
|
23
|
+
trans.totals.total.formatted_price, trans.seller_name )
|
|
24
|
+
printf( "The shipping charge was %s and the package was sent by %s.\n",
|
|
25
|
+
trans.totals.shipping_charge.formatted_price,
|
|
26
|
+
trans.shipments.shipment.delivery_method )
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
#
|
|
3
|
+
# $Id: vehicle_search,v 1.1 2009/02/19 15:48:57 ianmacd Exp $
|
|
4
|
+
|
|
5
|
+
require 'amazon/aws/search'
|
|
6
|
+
|
|
7
|
+
include Amazon::AWS
|
|
8
|
+
include Amazon::AWS::Search
|
|
9
|
+
|
|
10
|
+
is = VehicleSearch.new( { 'Year' => 2008 } )
|
|
11
|
+
rg = ResponseGroup.new( 'VehicleMakes' )
|
|
12
|
+
|
|
13
|
+
req = Request.new
|
|
14
|
+
req.locale = 'us'
|
|
15
|
+
|
|
16
|
+
resp = req.search( is, rg )
|
|
17
|
+
makes = resp.vehicle_search_response[0].vehicle_years[0].vehicle_year[0].
|
|
18
|
+
vehicle_makes[0].vehicle_make
|
|
19
|
+
|
|
20
|
+
printf( "Search returned %d makes of vehicle for 2008.\n\n", makes.size )
|
|
21
|
+
|
|
22
|
+
makes.each { |make| puts make, '' }
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# $Id: cache.rb,v 1.8 2008/06/10 06:33:46 ianmacd Exp $
|
|
2
|
+
#
|
|
3
|
+
|
|
4
|
+
module Amazon
|
|
5
|
+
|
|
6
|
+
module AWS
|
|
7
|
+
|
|
8
|
+
# This class provides a simple results caching system for operations
|
|
9
|
+
# performed by AWS.
|
|
10
|
+
#
|
|
11
|
+
# To use it, set _cache_ to *true* in either <tt>/etc/amazonrc</tt> or
|
|
12
|
+
# <tt>~/.amazonrc</tt>.
|
|
13
|
+
#
|
|
14
|
+
# By default, the cache directory used is <tt>/tmp/amazon</tt>, but this
|
|
15
|
+
# can be changed by defining _cache_dir_ in either <tt>/etc/amazonrc</tt>
|
|
16
|
+
# or <tt>~/.amazonrc</tt>.
|
|
17
|
+
#
|
|
18
|
+
# When a cache is used, Ruby/AWS will check the cache directory for a
|
|
19
|
+
# recent copy of a response to the exact operation that you are
|
|
20
|
+
# performing. If found, the cached response will be returned instead of
|
|
21
|
+
# the request being forwarded to the AWS servers for processing. If no
|
|
22
|
+
# (recent) copy is found, the request will be forwarded to the AWS servers
|
|
23
|
+
# as usual. Recency is defined here as less than 24 hours old.
|
|
24
|
+
#
|
|
25
|
+
class Cache
|
|
26
|
+
|
|
27
|
+
require 'fileutils'
|
|
28
|
+
|
|
29
|
+
begin
|
|
30
|
+
require 'md5'
|
|
31
|
+
rescue LoadError
|
|
32
|
+
# Ruby 1.9 has moved MD5.
|
|
33
|
+
#
|
|
34
|
+
require 'digest/md5'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Exception class for bad cache paths.
|
|
38
|
+
#
|
|
39
|
+
class PathError < StandardError; end
|
|
40
|
+
|
|
41
|
+
# Length of one day in seconds
|
|
42
|
+
#
|
|
43
|
+
ONE_DAY = 86400 # :nodoc:
|
|
44
|
+
|
|
45
|
+
# Age in days below which to consider cache files valid.
|
|
46
|
+
#
|
|
47
|
+
MAX_AGE = 1.0
|
|
48
|
+
|
|
49
|
+
# Default cache location.
|
|
50
|
+
#
|
|
51
|
+
DEFAULT_CACHE_DIR = '/tmp/amazon'
|
|
52
|
+
|
|
53
|
+
attr_reader :path
|
|
54
|
+
|
|
55
|
+
def initialize(path=DEFAULT_CACHE_DIR)
|
|
56
|
+
path ||= DEFAULT_CACHE_DIR
|
|
57
|
+
|
|
58
|
+
::FileUtils::mkdir_p( path ) unless File.exists? path
|
|
59
|
+
|
|
60
|
+
unless File.directory? path
|
|
61
|
+
raise PathError, "cache path #{path} is not a directory"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
unless File.readable? path
|
|
65
|
+
raise PathError, "cache path #{path} is not readable"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
unless File.writable? path
|
|
69
|
+
raise PathError, "cache path #{path} is not writable"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
@path = path
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# Determine whether or not the the response to a given URL is cached.
|
|
77
|
+
# Returns *true* or *false*.
|
|
78
|
+
#
|
|
79
|
+
def cached?(url)
|
|
80
|
+
digest = Digest::MD5.hexdigest( url )
|
|
81
|
+
|
|
82
|
+
cache_files = Dir.glob( File.join( @path, '*' ) ).map do |d|
|
|
83
|
+
File.basename( d )
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
return cache_files.include?( digest ) &&
|
|
87
|
+
( Time.now - File.mtime( File.join( @path, digest ) ) ) /
|
|
88
|
+
ONE_DAY <= MAX_AGE
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
# Retrieve the cached response associated with _url_.
|
|
93
|
+
#
|
|
94
|
+
def fetch(url)
|
|
95
|
+
digest = Digest::MD5.hexdigest( url )
|
|
96
|
+
cache_file = File.join( @path, digest )
|
|
97
|
+
|
|
98
|
+
return nil unless File.exist? cache_file
|
|
99
|
+
|
|
100
|
+
Amazon.dprintf( 'Fetching %s from cache...', digest )
|
|
101
|
+
File.open( File.join( cache_file ) ).readlines.to_s
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# Cache the data from _contents_ and associate it with _url_.
|
|
106
|
+
#
|
|
107
|
+
def store(url, contents)
|
|
108
|
+
digest = Digest::MD5.hexdigest( url )
|
|
109
|
+
cache_file = File.join( @path, digest )
|
|
110
|
+
|
|
111
|
+
Amazon.dprintf( 'Caching %s...', digest )
|
|
112
|
+
File.open( cache_file, 'w' ) { |f| f.puts contents }
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
# This method flushes all files from the cache directory specified
|
|
117
|
+
# in the object's <i>@path</i> variable.
|
|
118
|
+
#
|
|
119
|
+
def flush_all
|
|
120
|
+
FileUtils.rm Dir.glob( File.join( @path, '*' ) )
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
# This method flushes expired files from the cache directory specified
|
|
125
|
+
# in the object's <i>@path</i> variable.
|
|
126
|
+
#
|
|
127
|
+
def flush_expired
|
|
128
|
+
now = Time.now
|
|
129
|
+
|
|
130
|
+
expired_files = Dir.glob( File.join( @path, '*' ) ).find_all do |f|
|
|
131
|
+
( now - File.mtime( f ) ) / ONE_DAY > MAX_AGE
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
FileUtils.rm expired_files
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
end
|