thumbnail 0.2.0

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.
@@ -0,0 +1,284 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+ require File.dirname(__FILE__) + '/../lib/thumbnail.rb'
3
+
4
+ module SetupOpts
5
+ def auth_opts
6
+ {:access_key_id => "asdfsdfasdf", :secret_access_key => "asdfsadfasf"}
7
+ end
8
+ end
9
+
10
+ module NoGo
11
+ def stub_request
12
+ Net::HTTP.stub!(:get)
13
+ end
14
+ end
15
+
16
+ describe "Thumbnail::Client#new" do
17
+ include SetupOpts
18
+
19
+ it "should default to the thumbnail action" do
20
+ t = Thumbnail::Client.new(auth_opts)
21
+ t.action.should == :thumbnail
22
+ end
23
+
24
+ it "should set the action as redirect if specified" do
25
+ t = Thumbnail::Client.new( auth_opts.merge(:action => :redirect) )
26
+ t.action.should == :redirect
27
+ end
28
+
29
+ it "should raise an error if the action is neither redirect nor thumbnail" do
30
+ lambda{ Thumbnail::Client.new(auth_opts.merge(:action => :dogs) ) }.should raise_error(ArgumentError)
31
+ end
32
+
33
+ it "should raise an error if the access_key_id is not specified" do
34
+ lambda{ Thumbnail::Client.new(:secret_access_key => "asdfsadfasf")}.should raise_error(ArgumentError)
35
+ end
36
+
37
+ it "should raise an error if the secret_access_key is not specified" do
38
+ lambda{ Thumbnail::Client.new(:access_key_id => "asdfsadfasf")}.should raise_error(ArgumentError)
39
+ end
40
+
41
+ it "should default the size to large" do
42
+ t = Thumbnail::Client.new(auth_opts)
43
+ t.size.should == :large
44
+ end
45
+ it "should set the size to small if specified" do
46
+ t = Thumbnail::Client.new( auth_opts.merge(:size => :small) )
47
+ t.size.should == :small
48
+ end
49
+
50
+ it "should raise an error if the size is neither large nor small" do
51
+ lambda{ Thumbnail::Client.new(auth_opts.merge(:size => :largest) ) }.should raise_error(ArgumentError)
52
+ end
53
+
54
+ it "should raise an error if a default_image is specified for a Thumbnail action" do
55
+ lambda{ Thumbnail::Client.new(auth_opts.merge(:default_image => "http://somewhere.com/my_pict.jpg")) }.should raise_error(ArgumentError)
56
+ end
57
+ end
58
+
59
+ describe "Thumbnail::Client#new for a redirect" do
60
+ include SetupOpts
61
+
62
+ it "should set the default_image if specified" do
63
+ t = Thumbnail::Client.new(auth_opts.merge(:action => :redirect, :default_image => "http://somewhere.com/my_pict.jpg"))
64
+ t.instance_variable_get("@default_image").should == "http://somewhere.com/my_pict.jpg"
65
+ end
66
+
67
+ end
68
+
69
+ describe "Thumbnail#query" do
70
+ include SetupOpts
71
+
72
+ it "should calculate the signature and timestamp" do
73
+ t = Thumbnail::Client.new(auth_opts)
74
+ t.should_receive(:calculate_signature_and_timestamp)
75
+ t.send(:query)
76
+ end
77
+ end
78
+
79
+ describe "Thumbnail#calculate_signature_and_timestamp" do
80
+ include SetupOpts
81
+
82
+ before do
83
+ @t = Thumbnail::Client.new(auth_opts)
84
+ end
85
+
86
+ it "should calculate the signature" do
87
+ Base64.should_receive(:encode64).and_return("se5wwsefaw435rawef=")
88
+ @t.send(:calculate_signature_and_timestamp)
89
+ end
90
+
91
+ it "should set the (correctly formatted) timestamp" do
92
+ Time.stub!(:now).and_return(Time.mktime(2007,7,1,12))
93
+ @t.send(:calculate_signature_and_timestamp)
94
+ @t.instance_variable_get("@timestamp").should == "2007-07-01T19:00:00.000Z"
95
+ end
96
+ end
97
+
98
+ describe "Thumbnail#query with thumbnail action and a single url" do
99
+ include SetupOpts
100
+
101
+ before do
102
+ @t = Thumbnail::Client.new(auth_opts)
103
+ @t.instance_variable_set("@url", "www.boingboing.net")
104
+ end
105
+
106
+ it "should compose a thumbnail single query" do
107
+ @t.should_receive(:thumbnail_query_single)
108
+ @t.send(:query)
109
+ end
110
+ end
111
+
112
+ describe "Thumbnail::Client#query with thumbnail action and an array of urls" do
113
+ include SetupOpts
114
+
115
+ before do
116
+ @t = Thumbnail::Client.new(auth_opts)
117
+ @t.instance_variable_set("@url", ["www.boingboing.net", "www.craphound.com"])
118
+
119
+ end
120
+
121
+ it "should compose a thumbnail batch query" do
122
+ @t.should_receive(:thumbnail_query_batch)
123
+ @t.send(:query)
124
+ end
125
+ end
126
+
127
+ describe "Thumbnail::Client#query with redirect action" do
128
+ include SetupOpts
129
+
130
+ before do
131
+ @t = Thumbnail::Client.new( auth_opts.merge(:action => :redirect) )
132
+ @t.instance_variable_set("@url", "www.boingboing.net")
133
+ end
134
+
135
+ it "should compose a redirect query" do
136
+ @t.should_receive(:redirect_query)
137
+ @t.send(:query)
138
+ end
139
+ end
140
+
141
+ describe "Thumbnail::Client#thumbnail_query_single" do
142
+ include SetupOpts
143
+
144
+ before do
145
+ Time.stub!(:now).and_return(Time.mktime(2007,7,1,15))
146
+ @t = Thumbnail::Client.new( auth_opts )
147
+ @t.send(:calculate_signature_and_timestamp)
148
+ end
149
+
150
+ it "should compose the query url correctly" do
151
+ @t.instance_variable_set("@url", "www.boingboing.net")
152
+ @t.send(:thumbnail_query_single).should == "http://ast.amazonaws.com/?Action=Thumbnail&AWSAccessKeyId=#{auth_opts[:access_key_id]}&Signature=f2g%2BLOp8T1ZfWLEip7l4RXiPQkI%3D&Timestamp=2007-07-01T22:00:00.000Z&Url=www.boingboing.net&Size=Large"
153
+ end
154
+ end
155
+
156
+ describe "Thumbnail::Client#thumbnail_query_batch" do
157
+ include SetupOpts
158
+
159
+ before do
160
+ Time.stub!(:now).and_return(Time.mktime(2007,7,1,15))
161
+ @t = Thumbnail::Client.new( auth_opts )
162
+ @t.send(:calculate_signature_and_timestamp)
163
+ end
164
+
165
+ it "should compose the query url correctly" do
166
+ @t.instance_variable_set("@url", ["www.boingboing.net", "www.craphound.com"])
167
+ @t.send(:thumbnail_query_batch).should ==
168
+ "http://ast.amazonaws.com/?Action=Thumbnail&AWSAccessKeyId=#{auth_opts[:access_key_id]}&Signature=f2g%2BLOp8T1ZfWLEip7l4RXiPQkI%3D&Timestamp=2007-07-01T22:00:00.000Z&Shared.Size=Large&Thumbnail.1.Url=www.boingboing.net&Thumbnail.2.Url=www.craphound.com"
169
+ end
170
+ end
171
+
172
+ describe "Thumbnail::Client#redirect_query with a default_image" do
173
+ include SetupOpts
174
+
175
+ before do
176
+ Time.stub!(:now).and_return(Time.mktime(2007,7,1,15))
177
+ @t = Thumbnail::Client.new( auth_opts.merge(:action => :redirect, :default_image => "http://somewhere.com/my_pict.jpg") )
178
+ @t.send(:calculate_signature_and_timestamp)
179
+ end
180
+
181
+ it "should compose the query url correctly" do
182
+ @t.instance_variable_set("@url", "www.boingboing.net")
183
+
184
+ @t.send(:redirect_query).should ==
185
+ "http://ast.amazonaws.com/?Action=Redirect&AWSAccessKeyId=#{auth_opts[:access_key_id]}&Signature=%2FceiRH2lULi0rTvaY0mmJhxIwa4%3D&Timestamp=2007-07-01T22:00:00.000Z&Url=www.boingboing.net&Size=Large&DefaultImage=http://somewhere.com/my_pict.jpg"
186
+ end
187
+ end
188
+
189
+ describe "Thumbnail::Client#redirect_query without a default_image" do
190
+ include SetupOpts
191
+
192
+ before do
193
+ Time.stub!(:now).and_return(Time.mktime(2007,7,1,15))
194
+ @t = Thumbnail::Client.new( auth_opts.merge(:action => :redirect) )
195
+ @t.send(:calculate_signature_and_timestamp)
196
+ end
197
+
198
+ it "should compose the query url correctly" do
199
+ @t.instance_variable_set("@url", "www.boingboing.net")
200
+ @t.send(:redirect_query).should ==
201
+ "http://ast.amazonaws.com/?Action=Redirect&AWSAccessKeyId=#{auth_opts[:access_key_id]}&Signature=%2FceiRH2lULi0rTvaY0mmJhxIwa4%3D&Timestamp=2007-07-01T22:00:00.000Z&Url=www.boingboing.net&Size=Large"
202
+ end
203
+ end
204
+
205
+ describe "Thumbnail::Client#get with a thumbnail action" do
206
+ include SetupOpts
207
+ include NoGo
208
+
209
+ before do
210
+ stub_request
211
+ Thumbnail::Response.stub!(:build)
212
+ @t = Thumbnail::Client.new(auth_opts)
213
+ @t.stub!(:query).and_return(@q = "http://aws.com")
214
+ @pq = mock('URI::HTTP')
215
+ @pq.stub!(:host).and_return('aws.com')
216
+ URI.stub!(:parse).and_return(@pq)
217
+ Net::HTTP.stub!(:get).and_return(@xml = mock('xmldoc'))
218
+ end
219
+
220
+ it "should set the url string if given a single url" do
221
+ @t.get("www.boingboing.net")
222
+ @t.instance_variable_get("@url").should == "www.boingboing.net"
223
+ end
224
+
225
+ it "should set the url array if given an array of urls" do
226
+ @t.get(["www.boingboing.net", "www.craphound.com"])
227
+ @t.instance_variable_get("@url").should == ["www.boingboing.net", "www.craphound.com"]
228
+ end
229
+
230
+ it "should parse the url before conducting the query" do
231
+ URI.should_receive(:parse).with(@q).and_return(@pq)
232
+ @t.get("www.craphound.com")
233
+ end
234
+
235
+ it "should use net/https to conduct the query" do
236
+ Net::HTTP.should_receive(:get).with(@pq)
237
+ @t.get("www.craphound.com")
238
+ end
239
+
240
+ it "should build a response object from the xml" do
241
+ Thumbnail::Response.should_receive(:build).with(@xml)
242
+ @t.get("www.craphound.com")
243
+ end
244
+ end
245
+
246
+ describe "Thumbnail::Client#get with one or more invalid urls" do
247
+ include SetupOpts
248
+
249
+ before do
250
+ @t = Thumbnail::Client.new(auth_opts)
251
+ end
252
+
253
+ it "should raise an error with one url that is invalid" do
254
+ lambda{ @t.get("89u--=sdf-://as-df-") }.should raise_error(URI::InvalidURIError)
255
+ end
256
+
257
+ it "should raise an error if any of the urls in its give array are invalid" do
258
+ lambda{ @t.get(["89u--=s:?df-as-df-", "www.google.com"]) }.should raise_error(URI::InvalidURIError)
259
+ end
260
+
261
+ end
262
+
263
+ describe "Thumbnail::Client#get with a redirect action" do
264
+ include SetupOpts
265
+ include NoGo
266
+
267
+ before do
268
+ stub_request
269
+ @t = Thumbnail::Client.new(auth_opts.merge(:action => :redirect))
270
+ end
271
+
272
+ it "should raise an error if given an array of urls" do
273
+ lambda{ @t.get(["www.boingboing.net", "www.craphound.com"]) }.should raise_error(ArgumentError)
274
+ end
275
+
276
+ it "should calculate the query url" do
277
+ @t.should_receive(:query)
278
+ @t.get("www.boingboing.net")
279
+ end
280
+
281
+ it "should return the redirect query" do
282
+ @t.get("www.boingboing.net").should == @t.send(:redirect_query)
283
+ end
284
+ end
@@ -0,0 +1,64 @@
1
+ <?xml version="1.0"?>
2
+ <aws:ThumbnailResponse
3
+ xmlns:aws="http://ast.amazonaws.com/doc/2005-10-05/">
4
+ <aws:Response>
5
+ <aws:OperationRequest>
6
+ <aws:RequestId>
7
+ xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
8
+ </aws:RequestId>
9
+ </aws:OperationRequest>
10
+ <aws:ThumbnailResult>
11
+ <aws:Thumbnail Exists="true">
12
+ http://location_to_thumbnail_for_alexa.com
13
+ </aws:Thumbnail>
14
+ <aws:RequestUrl>
15
+ alexa.com
16
+ </aws:RequestUrl>
17
+ </aws:ThumbnailResult>
18
+ <aws:ResponseStatus>
19
+ <aws:StatusCode>
20
+ Success
21
+ </aws:StatusCode>
22
+ </aws:ResponseStatus>
23
+ </aws:Response>
24
+ <aws:Response>
25
+ <aws:OperationRequest>
26
+ <aws:RequestId>
27
+ xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
28
+ </aws:RequestId>
29
+ </aws:OperationRequest>
30
+ <aws:ThumbnailResult>
31
+ <aws:Thumbnail Exists="true">
32
+ http://location_to_thumbnail_for_amazon.com
33
+ </aws:Thumbnail>
34
+ <aws:RequestUrl>
35
+ amazon.com
36
+ </aws:RequestUrl>
37
+ </aws:ThumbnailResult>
38
+ <aws:ResponseStatus>
39
+ <aws:StatusCode>
40
+ Success
41
+ </aws:StatusCode>
42
+ </aws:ResponseStatus>
43
+ </aws:Response>
44
+ <aws:Response>
45
+ <aws:OperationRequest>
46
+ <aws:RequestId>
47
+ xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
48
+ </aws:RequestId>
49
+ </aws:OperationRequest>
50
+ <aws:ThumbnailResult>
51
+ <aws:Thumbnail Exists="true">
52
+ http://location_to_thumbnail_for_a9.com
53
+ </aws:Thumbnail>
54
+ <aws:RequestUrl>
55
+ a9.com
56
+ </aws:RequestUrl>
57
+ </aws:ThumbnailResult>
58
+ <aws:ResponseStatus>
59
+ <aws:StatusCode>
60
+ Success
61
+ </aws:StatusCode>
62
+ </aws:ResponseStatus>
63
+ </aws:Response>
64
+ </aws:ThumbnailResponse>
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0"?>
2
+ <Response>
3
+ <Errors>
4
+ <Error>
5
+ <Code>AuthFailure</Code>
6
+ <Message>AWS was not able to validate the provided access credentials</Message>
7
+ </Error>
8
+ </Errors>
9
+ <RequestID>5bb2ed01-8ff3-4622-a359-af9b9dcb80b2</RequestID>
10
+ </Response>
@@ -0,0 +1,15 @@
1
+ <?xml version="1.0"?>
2
+ <aws:ThumbnailResponse xmlns:aws="http://ast.amazonaws.com/doc/2005-10-05/">
3
+ <aws:Response>
4
+ <aws:OperationRequest>
5
+ <aws:RequestId>429d5fa3-e7b3-43d7-98ee-35ec9b01750f</aws:RequestId>
6
+ </aws:OperationRequest>
7
+ <aws:ThumbnailResult>
8
+ <aws:Thumbnail Exists="true">http://s3-external-1.amazonaws.com/alexa-thumbnails/421922F1CA73EF1FB344425517D124FA5F84E8DDl?Signature=sL4Ldjh336C2KJ8RMaWoswMah9k%3D&amp;Expires=1181512094&amp;AWSAccessKeyId=1FVZ0JNEJDA5TK457CR2</aws:Thumbnail>
9
+ <aws:RequestUrl>www.boingboing.net</aws:RequestUrl>
10
+ </aws:ThumbnailResult>
11
+ <aws:ResponseStatus>
12
+ <aws:StatusCode>Success</aws:StatusCode>
13
+ </aws:ResponseStatus>
14
+ </aws:Response>
15
+ </aws:ThumbnailResponse>
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0"?>
2
+ <aws:ThumbnailResponse xmlns:aws="http://ast.amazonaws.com/doc/2005-10-05/"><aws:Response><aws:OperationRequest><aws:RequestId>c4ab78dc-77f1-4534-9458-45436f689c1b</aws:RequestId></aws:OperationRequest><aws:ThumbnailResult><aws:Thumbnail Exists="false">http://s3-external-1.amazonaws.com/alexa-thumbnails/noimagel?Signature=ZEDPUK7B%2FpLsNwufU%2FafuHPrIR0%3D&amp;Expires=1181687213&amp;AWSAccessKeyId=1FVZ0JNEJDA5TK457CR2</aws:Thumbnail><aws:RequestUrl>www.thenytimesexplainstheratings.com</aws:RequestUrl></aws:ThumbnailResult><aws:ResponseStatus><aws:StatusCode>Success</aws:StatusCode></aws:ResponseStatus></aws:Response></aws:ThumbnailResponse>
@@ -0,0 +1,40 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+ require File.dirname(__FILE__) + '/../lib/thumbnail.rb'
3
+
4
+ describe "Thumbnail::Response#build with a successful single response" do
5
+ before do
6
+ @xml = parse_fixture("single")
7
+ end
8
+
9
+ it "should create a Thumbnail::Response::Success object" do
10
+ Thumbnail::Response::Success.should_receive(:new)
11
+ Thumbnail::Response.build(@xml)
12
+ end
13
+ end
14
+
15
+ describe "Thumbnail::Response#build with a successful batch response" do
16
+ before do
17
+ @xml = parse_fixture("batch")
18
+ end
19
+
20
+ it "should create a Thumbnail::Response::Success object" do
21
+ Thumbnail::Response::Success.should_receive(:new)
22
+ Thumbnail::Response.build(@xml)
23
+ end
24
+ end
25
+
26
+ describe "Thumbnail::Response#build with an invalid credentails response" do
27
+ before do
28
+ @xml = parse_fixture("invalid_credentials")
29
+ end
30
+
31
+ it "should create a Thumbnail::Response::Failure object" do
32
+ Thumbnail::Response::Failure.should_receive(:new)
33
+ Thumbnail::Response.build(@xml)
34
+ end
35
+
36
+ it "should correctly parse out and format the error message" do
37
+ r = Thumbnail::Response.build(@xml)
38
+ r.to_s.should == "AuthFailure: AWS was not able to validate the provided access credentials"
39
+ end
40
+ end
@@ -0,0 +1 @@
1
+ --colour
Binary file
Binary file
@@ -0,0 +1,147 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <link rel="stylesheet" href="stylesheets/screen.css" type="text/css" media="screen" />
6
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
+ <title>
8
+ THUMBNAIL: website pix courtesy of ruby, amazon, and alexa
9
+ </title>
10
+ <script src="javascripts/rounded_corners_lite.inc.js" type="text/javascript"></script>
11
+ <style>
12
+
13
+ </style>
14
+ <script type="text/javascript">
15
+ window.onload = function() {
16
+ settings = {
17
+ tl: { radius: 10 },
18
+ tr: { radius: 10 },
19
+ bl: { radius: 10 },
20
+ br: { radius: 10 },
21
+ antiAlias: true,
22
+ autoPad: true,
23
+ validTags: ["div"]
24
+ }
25
+ var versionBox = new curvyCorners(settings, document.getElementById("version"));
26
+ versionBox.applyCornersToAll();
27
+ }
28
+ </script>
29
+ </head>
30
+ <body>
31
+ <div id="main">
32
+ <img src="logo.png" id="logo">
33
+ <div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/thumbnail"; return false'>
34
+ <p>Get Version</p>
35
+ <a href="http://rubyforge.org/projects/thumbnail" class="numbers">0.2.0</a>
36
+ </div>
37
+
38
+
39
+ <h2>What</h2>
40
+ <p>A Ruby wrapper for the <a href="http://www.amazon.com/b/ref=sc_fe_c_0_239513011_4/102-1130464-8229719?ie=UTF8&node=236156011&no=239513011&me=A36L942TSJ2AJA">Amazon Web Services Alexa Site Thumbnail Service</a> REST API, which provides website thumbnail images on demand for a small fee ($0.20/1000).</p>
41
+
42
+ <h2>Installing</h2>
43
+
44
+
45
+ <pre syntax="ruby">$ sudo gem install thumbnail</pre>
46
+
47
+ <p>Thumbnail depends on the terrific <a href="http://code.whytheluckystiff.net/hpricot/">Hpricot</a> XHTML parsing and manipulation library by <a href="whytheluckystiff.net">why the lucky stiff</a>; version 0.5 or better has the necessary powers.</p>
48
+
49
+ <h2>Registering with Amazon</h2>
50
+ <p>
51
+ In order to use the AWS-AST api, you must first complete the following series of bureaucratic tasks:
52
+ <ol>
53
+ <li><a href="http://aws.amazon.com">Signup for an Amazon Web Services account</a> (if you don't yet have one). You can use your existing Amazon user account for this or create a new one.</li>
54
+ <li><a href="http://www.amazon.com/b/ref=sc_fe_c_0_239513011_4/102-1130464-8229719?ie=UTF8&node=236156011&no=239513011&me=A36L942TSJ2AJA">Signup for the Alexa Site Thumbnail Service</a>.</li>
55
+ <li>Find and note your AWS Access Key Id and your Secret Access Key. You'll need to tell Thumbnail about these for authentication's sake; you should be given them at the end of the signup process.</li>
56
+ </ol>
57
+ </p>
58
+ <p>
59
+ Registering for both of these accounts is free, payment for the Site Thumbnail Service is based entirely on usage, with no charges for requests for unavailable thumbnails.
60
+ </p>
61
+ <h2>Demonstration of usage</h2>
62
+ <p>The API provides two actions for accessing site thumbnails: Thumbnail and Redirect and the Thumbnail::Client supports 'em both.
63
+ </p>
64
+ <h3>Thumbnail Action</h3>
65
+ When conducting a thumbnail action (the default), the Client will conduct an api call to fetch the image url(s) from Amazon for immediate download of your thumbnail(s) as follows:
66
+
67
+ <pre>
68
+ require 'thumbnail'
69
+ require 'open-uri'
70
+
71
+ t = Thumbnail::Client.new :access_key_id =&gt; YOUR_ACCESS_KEY_ID,
72
+ :secret_access_key =&gt; YOUR_SECRET_ACCESS_KEY
73
+ url = t.get(&quot;www.craphound.com&quot;)[:thumbnail][:url]
74
+ File.open(&quot;craphound.jpg&quot;, &quot;w&quot;) { |f| f.write open(url).read }
75
+ </pre>
76
+ The result will look something like this:<br />
77
+ <img src="craphound.jpg">
78
+ </p>
79
+ <p>You can also request thumbnails for multiple images simultaneously by passing an array of urls to <code>get</code>. If you do that, you'll have to access the response object differently (see below).</p>
80
+ <p><em>Note: Once you make the <code>get</code> call, and the request to AST goes out, you only have fifteen seconds to use the resulting image url before it expires. This can play havoc with by-hand testing. I recommend that you run something very much like the final line in the example immediately.</em></p>
81
+ <h3>The Response Object</h3>
82
+ <p>
83
+ Thumbnail action requests will return either a Thumbnail::Response::Success or Thumbnail::Response::Failure object depending on their outcome. Each of these objects offer access to the raw xml response and the Hpricot::Doc object built from parsing it in addtion to the parsed results hash. Further, the <code>[]</code> method has been defined to provide easy access to the parsed results as seen in the example above. Calling <code>to_s</code> on a Failure object will provide a helpful concatenation of the error messages returned by Amazon.
84
+ </p>
85
+ <h3>Redirect Action</h3>
86
+ <p>
87
+ For a redirect action, the Thumbnail::Client will simply compose and return the image url like so:
88
+ <pre>
89
+ require 'thumbnail'
90
+
91
+ t = Thumbnail::Client.new :access_key_id =&gt; YOUR_ACCESS_KEY_ID,
92
+ :secret_access_key =&gt; YOUR_SECRET_ACCESS_KEY,
93
+ :action =&gt; :redirect
94
+ url = t.get(&quot;www.twitter.com&quot;)
95
+
96
+ #=&gt; http://ast.amazonaws.com/?Action=Redirect&amp;AWSAccessKeyId=YOUR_ACCESS_KEY_ID
97
+ &amp;Signature=sdhfiawrkjw3h9bncoa8ue&amp;Timestamp=2007-06-14T09:09:18.000Z&amp;Url=www.tw
98
+ itter.com&amp;Size=Large
99
+ </pre>
100
+ The resulting url will redirect to the thumbnail image hosted on s3. This action is perfect for dynamic inclusion of AWS-AST-generated thumbnails in live web pages. <em>Note: this usage of the Thumbnail::Client does not go out over the wire and will not count as a paid api call until you actually request the resulting url with a browser or other user agent.</em>
101
+ </p>
102
+ <h3>Default Images</h3>
103
+ <p>
104
+ In either action, if you request a thumbnail that is not available, it will be queued for creation within 24 hours and you will not be charged for the request. In the redirect action, you can indicate a Default Image to be returned in this eventuality by including <code>:default_image => 'http://me.com/path/to/my_image.jpg'</code> in the options hash when initializing your Thumbnail::Client. If you don't indicate a default image (or if you're doing a thumbnail action), you'll get the following Alexa "coming soon" default image:<br />
105
+ <img src="soon.jpg">
106
+ </p>
107
+ <h3>Image Size Options</h3>
108
+
109
+ <p>In both actions, you have a choice between large (201x147 pixels, ~8k) and small (111x82 pixels, ~3k) thumbnails. The Thumbnail::Client defaults to the large size, so if you want the smaller images, you should include <code>:size => :small</code> in your options hash when calling <code>Thumbnail::Client.new</code> (<em>note: there's also an attribute accessor for doing this after initialization</em>). Here are both sizes next to each other for comparison:<br />
110
+ <img src="craphound.jpg">
111
+ <img src="small_crap.jpg" />
112
+ </p>
113
+
114
+ <h2>Documentation</h2>
115
+ <p>
116
+ For more details about using Thumbnail, see <a href="http://thumbnail.rubyforge.org/rdoc">the RDoc documentation</a>. To learn more about AWS-AST, see <a href="http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=51">the Alexa Site Thumbnail Service Resource Center</a>.
117
+ </p>
118
+
119
+ <h2>How to submit patches</h2>
120
+
121
+
122
+ <p>Read the <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/">8 steps for fixing other people&#8217;s code</a> and then <a href="mailto:greg@mfdz.com">email me</a>.
123
+
124
+
125
+ <p>The trunk repository is <code>svn://rubyforge.org/var/svn/thumbnail/trunk</code> for anonymous access.</p>
126
+
127
+
128
+ <h2>License</h2>
129
+
130
+
131
+ <p>This code is free to use under the terms of the <span class="caps">MIT</span> license.</p>
132
+
133
+
134
+ <h2>Contact</h2>
135
+
136
+
137
+ <p>Comments are welcome. Send email to <a href="mailto:greg@mfdz.com">Greg Borenstein</a>. Visit my blog: <a href=http://www.urbanhonking.com/ideasfordozens>Ideas For Dozens</a>.</p>
138
+ <p class="coda">
139
+ This gem was packaged and released with the help of <a href="http://newgem.rubyforge.org/">newgem</a> by <a href="http://drnicwilliams.com/">Dr Nic</a>.<br />
140
+ Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
141
+ </p>
142
+ </div>
143
+
144
+ <!-- insert site tracking codes here, like Google Urchin -->
145
+
146
+ </body>
147
+ </html>