thumbnail 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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>