amazon-hacks 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,5 @@
1
+ == 1.0.0 / 2006-12-04
2
+
3
+ * Initial Release
4
+ * Some URL hacks
5
+ * Image transformation tools
data/Manifest.txt ADDED
@@ -0,0 +1,6 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/amazon-hacks.rb
6
+ test/test_amazon-hacks.rb
data/README.txt ADDED
@@ -0,0 +1,105 @@
1
+ AmazonHacks
2
+ by Jacob Harris
3
+ harrisj@schizopolis.net
4
+ http://www.nimblecode.com/
5
+
6
+ NYC.rb
7
+ http://www.nycruby.org/
8
+
9
+ == DESCRIPTION:
10
+
11
+ Mainly the product of messing around, this gem comprises Ruby code for a few
12
+ useful "Amazon Hacks" -- common techniques for manipulating Amazon product URLs
13
+ and Images. This is mainly useful if you find yourself creating a site where you
14
+ might link to Amazon product pages and display images for them. Examples of this
15
+ might include:
16
+
17
+ * Social consumption sites like http://www.allconsuming.net/
18
+ * Blogs or tumbleblogs with book/music/etc. reviews
19
+ * Normalizing Amazon links or create associate IDs
20
+
21
+ This GEM is NOT related to using the Amazon Web Services and there is already an
22
+ excellent gem for that if you need more heavy-duty use of the Amazon website
23
+ (this gem does not even communicate with Amazon at all). Also, note this gem is
24
+ meant in the spirit of fun hackery. You can use it to create interesting images
25
+ from Amazon on demand, but if you are going to use it on a serious website,
26
+ please consider caching and attributing that image to Amazon (I also have no
27
+ idea what the official legal policy for using Amazon's book images is).
28
+
29
+ And of course, do not even consider using this for fraud. It is possible to
30
+ generate "20% off" or "Look Inside!" badges on Amazon images, but this gem does
31
+ not support that since I can not think of any reason why outside sites would use
32
+ that.
33
+
34
+ == FEATURES/PROBLEMS:
35
+
36
+ There are two main classes within the Amazon::Hacks namespace with the following
37
+ functionality:
38
+
39
+ === Link (product URL)
40
+
41
+ * Extract country of site
42
+ * Extract ASIN (Amazon identifier)
43
+ * Normalize (reduce to most basic URL for matching)
44
+ * Associate URL (create a normalized URL with your Amazon Associate ID)
45
+
46
+ === Image
47
+
48
+ - Derive a corresponding image URL from a product URL
49
+ - Sizes (small, medium, large)
50
+ - Shadow
51
+ - Border
52
+ - Crop
53
+ - Scale
54
+ - Tilt
55
+ - Blur
56
+ - Sharpen
57
+ - Highlight
58
+ - Text overlay
59
+
60
+ This is still a work in development, and while I have tested against some
61
+ generic Amazon rules, it is possible that certain countries might deviate from
62
+ Amazon's practices (for instance, China seems to not use the image generation
63
+ code and instead just links to static URLs). Let me know if you find any issues
64
+ for a given product link/image. Thank you.
65
+
66
+ == SYNOPSIS:
67
+
68
+ To use, simply +require 'amazon_hacks'+
69
+
70
+ === LINKS
71
+
72
+ This gem is inspired by the {Abusing Amazon Images}[http://aaugh.com/imageabuse.html] page.
73
+
74
+ == REQUIREMENTS:
75
+
76
+ * Requires the 'color-tools' gem
77
+
78
+ == INSTALL:
79
+
80
+ * sudo gem install amazon-hacks
81
+
82
+ == LICENSE:
83
+
84
+ (The MIT License)
85
+
86
+ Copyright (c) 2006 FIX
87
+
88
+ Permission is hereby granted, free of charge, to any person obtaining
89
+ a copy of this software and associated documentation files (the
90
+ 'Software'), to deal in the Software without restriction, including
91
+ without limitation the rights to use, copy, modify, merge, publish,
92
+ distribute, sublicense, and/or sell copies of the Software, and to
93
+ permit persons to whom the Software is furnished to do so, subject to
94
+ the following conditions:
95
+
96
+ The above copyright notice and this permission notice shall be
97
+ included in all copies or substantial portions of the Software.
98
+
99
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
100
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
101
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
102
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
103
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
104
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
105
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/amazon-hacks'
6
+
7
+ Hoe.new('amazon-hacks', AmazonHacks::VERSION) do |p|
8
+ p.rubyforge_name = 'amazon-hacks'
9
+ p.summary = 'A collection of useful snippets against the Amazon website'
10
+ p.author = 'Jacob Harris'
11
+ p.email = 'harrisj@schizopolis.net'
12
+ p.url = 'http://www.nimblecode.com/code/AmazonHacks'
13
+ p.description = p.paragraphs_of('README.txt', 2..6).join("\n\n")
14
+ # p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
15
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
16
+ p.extra_deps = "color-tools"
17
+ end
@@ -0,0 +1,411 @@
1
+ require 'rubygems'
2
+ require 'uri'
3
+ require 'color'
4
+
5
+ class AmazonHacks
6
+ VERSION = '0.1.0'
7
+ end
8
+
9
+ module Amazon
10
+ module Hacks
11
+ Country = Struct.new("Country", :country, :host, :img_code, :img_host)
12
+
13
+ ##
14
+ # COUNTRIES is nice generic structure for storing information specific to
15
+ # each country Amazon has a store for (China seems special though, so I have
16
+ # deferred supporting it for now)
17
+ COUNTRIES = {
18
+ :ca => Country.new(:ca, "www.amazon.ca", "01", "images.amazon.ca"),
19
+ # :cn => new Location("www.amazon.cn", )
20
+ :de => Country.new(:de, "www.amazon.de", "03", "images.amazon.de"),
21
+ :fr => Country.new(:fr, "www.amazon.fr", "08", "images.amazon.fr"),
22
+ :jp => Country.new(:jp, "www.amazon.co.jp", "09", "images.amazon.co.jp"),
23
+ :uk => Country.new(:uk, "www.amazon.co.uk", "02", "images.amazon.co.uk"),
24
+ :us => Country.new(:us, "www.amazon.com", "01", "images.amazon.com")
25
+ }
26
+
27
+ ##
28
+ # The countries module is a convenience mixin to retrieve the correct
29
+ # server, etc. for an Image or Link. This module requires the class to
30
+ # include a +@country+ instance variable.
31
+ module Countries
32
+
33
+ ##
34
+ # Returns a hostname for the Amazon store for that country
35
+ def country_host
36
+ COUNTRIES[@country].host
37
+ end
38
+
39
+ ##
40
+ # Each country in Amazon seems to use a different image code number in its
41
+ # images (eg, "01" for the US, "08" for France). This method returns the
42
+ # image code for the country
43
+ def country_imgcode
44
+ COUNTRIES[@country].img_code
45
+ end
46
+
47
+ ##
48
+ # Each country also has a different server for its images. This returns
49
+ # the correct server.
50
+ def country_imghost
51
+ COUNTRIES[@country].img_host
52
+ end
53
+ end
54
+
55
+ class Link
56
+ include Countries
57
+ attr_reader :asin, :country
58
+
59
+ def initialize(url=nil, country=nil, asin=nil)
60
+ if url.nil?
61
+ @url = @country = @asin = nil
62
+ else
63
+ @url = URI.parse(url)
64
+ @country = country ? country : Amazon::Hacks::Link.extract_country(url)
65
+ @asin = asin ? asin : Amazon::Hacks::Link.extract_asin(url)
66
+ end
67
+ end
68
+
69
+ ##
70
+ # Sets the internal url of the link to be +url+. Also parses the values of
71
+ # the +asin+ and +country+ from the URL
72
+ def url=(url)
73
+ @url = URI.parse(url)
74
+ @country = Amazon::Hacks::Link.extract_country(url)
75
+ @asin = Amazon::Hacks::Link.extract_asin(url)
76
+ end
77
+
78
+ ##
79
+ # Returns a normalized form of the Link's URL. This is the shortest valid
80
+ # URL that links to the product on Amazon
81
+ #
82
+ # For example, the normalized form of a URL like:
83
+ #
84
+ # http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672/sr=8-1/qid=1165273301/ref=pd_bbs_sr_1/002-2410048-1716806?ie=UTF8&s=books
85
+ #
86
+ # would be:
87
+ #
88
+ # http://www.amazon.com/o/asin/0201485672
89
+ #
90
+ # Since it removes the session and other variables from the URL,
91
+ # normalization is very useful for comparing two Amazon links directly.
92
+ # The Link== method does NOT normalize, but you might want to consider
93
+ # that if you need it.
94
+ def normalize
95
+ "http://#{country_host}/o/asin/#{asin}"
96
+ end
97
+
98
+ ##
99
+ # Extracts the Amazon Standard Identification Number (ASIN) from a string +url+.
100
+ # Each product on an Amazon store has a unique ASIN used to identify it.
101
+ # As Amazon's help documents describe it:
102
+ #
103
+ # "For books, the ASIN is the same as the ISBN number, but for all other
104
+ # products a new ASIN is created when the item is uploaded to our catalog"
105
+ #
106
+ # ASIN values are specific to the store they're applied to and can not be
107
+ # used against another store nor are they guaranteed to be globally unique.
108
+ # Put another way, the ASIN for the US edition of a book will not return
109
+ # the UK edition when used with the UK store and might return nothing or
110
+ # something completely different. Also, ASINs are alphanumeric strings, not
111
+ # numbers.
112
+ #
113
+ # Amazon has used several different major URL formats interchangeably and
114
+ # this function extracts the ASIN from the following URL paths:
115
+ #
116
+ # /o/asin/<ASIN VALUE>[/...]
117
+ #
118
+ # /exec/obidos/ASIN/<ASIN VALUE>[/...]
119
+ #
120
+ # /exec/obidos/tg/detail/-/<ASIN VALUE>[/...]
121
+ #
122
+ # /long-title-goes-here/dp/<ASIN VALUE>[/...]
123
+ #
124
+ # This is only an informally gathered list. If you find a case where
125
+ # +extract_asin+ fails, please send me the URL. If the ASIN is not matched,
126
+ # returns +nil+
127
+ def Link.extract_asin(url)
128
+ u = URI.parse(url)
129
+ asin = nil
130
+
131
+ asin_regexps = [ /^\/o\/asin\/([^\/]+)/,
132
+ /^\/exec\/obidos\/ASIN\/([^\/]+)/,
133
+ /^\/exec\/obidos\/tg\/detail\/-\/([^\/]+)/,
134
+ /^\/[^\/]+\/dp\/([^\/]+)/
135
+ ]
136
+
137
+ asin_regexps.each do |re|
138
+ md = re.match(u.path)
139
+ if md
140
+ then
141
+ asin = md[1]
142
+ break
143
+ end
144
+ end
145
+
146
+ asin
147
+ end
148
+
149
+ ##
150
+ # This method analyzes the +url+ string and returns a symbol representing
151
+ # the country (eg, +:us+). If the host is not recognized, returns +nil+
152
+ def Link.extract_country(url)
153
+ u = URI.parse(url)
154
+ c = COUNTRIES.find { |key, value| value.host == u.host }
155
+ c[0] unless c.nil? #.country unless c.nil?
156
+ end
157
+
158
+ def associate_url(assoc_id)
159
+ normalize + "/#{assoc_id}"
160
+ end
161
+
162
+ def normalize!
163
+ u = normalize
164
+ @url = URI.parse(u)
165
+ self
166
+ end
167
+
168
+ def url
169
+ @url.to_s
170
+ end
171
+
172
+ alias :to_s :url
173
+ end
174
+ end
175
+ end
176
+
177
+ module Amazon
178
+ module Hacks
179
+
180
+ ##
181
+ # Class for manipulating Amazon's image URLs. These images are generated
182
+ # on demand at Amazon, so please don't abuse this feature against their
183
+ # site (save the image locally or link to them so they can get some sales
184
+ # out of it). I also do not have transformations that apply Amazon-specific
185
+ # decorations like "20% off" badges or "Look Inside" to hinder spoofing an
186
+ # Amazon site somewhat.
187
+ #
188
+ # Amazon images require an ASIN and country. These can either be specified
189
+ # manually or imported from a URL. In addition, each image can be modified
190
+ # with zero or more transformations (all specified in the URL), although the
191
+ # using more than two transformations is not necessarily guaranteed to be
192
+ # honored by Amazon's rendering engine (only the first will generally be
193
+ # applied, but [size + transform] seems to work usually).
194
+ #
195
+ # {Abusing Amazon Images}[http://aaugh.com/imageabuse.html], a site to whom
196
+ # I am most indebted here, notes the following about transform chaining:
197
+ #
198
+ # "The cool thing (if you want to generate unlikely Amazon images) is that
199
+ # you're not limited to one use of any of these commands. You can have
200
+ # multiple discounts, multiple shadows, multiple bullets, generating images
201
+ # that Amazon would never have on its site. However, every additional command
202
+ # you add generates another 10% to the image dimensions, adding white space
203
+ # around the image. And that 10% compounds; add a lot of bullets, and you'll
204
+ # find that you have a small image in a large blank space. (You can use the
205
+ # #crop! command to cut away the excess, however.) Note also that the commands
206
+ # are interpreted in order, which can have an impact on what overlaps what."
207
+ class Image
208
+ include Countries
209
+ attr :asin, :country
210
+
211
+ SIZES = { :small => "SCTZZZZZZZ",
212
+ :medium => "SCMZZZZZZZ",
213
+ :large => "SCLZZZZZZZ" }
214
+
215
+ SHADOW_POSITIONS = [ :left, :right, :custom ]
216
+
217
+ SCALE_TYPES = { :proportion => "AA",
218
+ :square => "SS",
219
+ :width => "SX",
220
+ :height => "SY" }
221
+
222
+ TEXT_FONTS = [ :times, :arial, :arialbi, :verdanab, :advc128d ]
223
+ TEXT_ALIGNS = [ :left, :center ]
224
+
225
+ ##
226
+ # Creates an Image object from a +url+
227
+ def Image.build_from_url(url)
228
+ u = Amazon::Hacks::Link.new(url)
229
+ i = Image.new(u.asin, u.country)
230
+ end
231
+
232
+ ##
233
+ # Initializes an Image object, requires both a valid asin as well as
234
+ # a country symbol (eg, +:us+ or +:uk+)
235
+ def initialize(asin, country)
236
+ @asin = asin
237
+ @country = country
238
+ reset_transforms!
239
+ end
240
+
241
+ ##
242
+ # Add a size transform to the image. The following sizes are allowed:
243
+ # * small
244
+ # * medium
245
+ # * large
246
+ #
247
+ # These sizes are not guaranteed to particular dimensions. If you need
248
+ # exact sizing, use the #scale! transformation. These sizes are a lot
249
+ # friendlier to Amazon's image servers though, so I would recommend them
250
+ # if you can handle some variation.
251
+ def set_size!(size)
252
+ @transforms << SIZES[size]
253
+ end
254
+
255
+ ##
256
+ # Add a simple shadow to the left or right; takes arguments +:left+ or
257
+ # +:right+.
258
+ def add_shadow! (side)
259
+ case
260
+ when side == :left then @transforms << "PB"
261
+ when side == :right then @transforms << "PC"
262
+ end
263
+ end
264
+
265
+ ##
266
+ # Add a custom shadow to the image. Takes 4 parameters:
267
+ #
268
+ # * +size+ - padding around the image (pixels)
269
+ # * +xoff+ - distance from the shadow's edge to the item's edge horizontally.
270
+ # Positive values go to the right, negative to the left (pixels)
271
+ # * +yoff+ - like xoff but vertically.
272
+ # * +fuzz+ - fuzziness of shadow; 0 is perfectly square while higher values
273
+ # blur the sharpness of the shadow's edge
274
+ def add_custom_shadow! (size, xoff, yoff, fuzz)
275
+ @transforms << "PA#{size},#{xoff},#{yoff},#{fuzz}"
276
+ end
277
+
278
+ ##
279
+ # Add a border around the image. Takes the following arguments
280
+ #
281
+ # * +width+ - size of the border (pixels)
282
+ # * +color+ - color of the border in HTML format (eg, "#CCCCCC") [defaults
283
+ # black if not specified]
284
+ def add_border! (width, html_color="\#000000")
285
+ color = Color::RGB.from_html(html_color)
286
+ cmd = "BO#{width},"
287
+ cmd << [color.r, color.g, color.b].map {|c| (c*255).to_i }.join(",")
288
+ @transforms << cmd
289
+ end
290
+
291
+ ##
292
+ # Rotate the image. Takes a single argument of degrees to rotate. Positive
293
+ # values rotate to the right, negative to the left.
294
+ #
295
+ # According to auugh: "The values seem to range as high as 135. Positive
296
+ # values rotate to the right, negative numbers rotate to the left. Negative
297
+ # numbers go... well, I stopped testing in the hundreds of millions, but
298
+ # there's not much need to go beyond -360, which takes it full circle.
299
+ # Positive rotations in some values seem to cause severe image shrinkage,
300
+ # so you should consider using a size adjustment after rotation."
301
+ def tilt! (degrees)
302
+ @transforms << "PT#{degrees}"
303
+ end
304
+
305
+ ##
306
+ # Blur the image. The input argument seems to represent a radius, but the
307
+ # essential thing to know is the higher the value, the blurrier it gets.
308
+ def blur! (radius)
309
+ @transforms << "BL#{radius}"
310
+ end
311
+
312
+ ##
313
+ # Sharpen the image. The value can range from 0 - 99. Larger values may
314
+ # affect color and increase noise significantly.
315
+ def sharpen! (percent)
316
+ @transforms << "SH#{percent}"
317
+ end
318
+
319
+ ##
320
+ # Scale the image to exact dimensions. Takes a scaling type and dimension
321
+ # in pixels. There are four types of scaling possible:
322
+ #
323
+ # * +:proportion+ - preserve the image's proportions
324
+ # * +:square+ - make the image square
325
+ # * +:width+ - the size represents the width of image. Height is
326
+ # proportionally scaled.
327
+ # * +:height+ - the size represents the height of the image. Width is
328
+ # proportionally scaled.
329
+ def scale!(type, size)
330
+ @transforms << "#{SCALE_TYPES[type]}#{size}"
331
+ end
332
+
333
+ ##
334
+ # Crops the image. This can be used to generate Flickr-like square windows
335
+ # into the image (although there is no method to figure out programmatically
336
+ # the dimensions of a particular size, so this might be hard [maybe scale
337
+ # then crop?]). Takes four arguments to set the crop square:
338
+ #
339
+ # * +xoff+ - x offset from top left corner of image to tlc of box (pixels)
340
+ # * +yoff+ - y offset from top left corner of image to tlc of (pixels)
341
+ # * +width+ - width of crop square
342
+ # * +height+ - height of crop square
343
+ def crop! (xoff, yoff, width, height)
344
+ @transforms << "CR#{xoff},#{yoff},#{width},#{height}"
345
+ end
346
+
347
+ ##
348
+ # Overlay text on the image. This is easily the most complicated transformation
349
+ # you can apply in terms of sheer argument heft. The text is placed in a square
350
+ # area you must set the dimensions of first. Takes the following options:
351
+ #
352
+ # * +text+ - the text you want to overlay
353
+ # * +xoff+ - x offset from the top left corner to tlc of box (pixels)
354
+ # * +yoff+ - y offset from the top left corner to tlc of box (pixels)
355
+ # * +width+ - width of the text box
356
+ # * +height+ - height of the text box in pixels
357
+ # * +font+ - four options are allowed:
358
+ # * +:times+ - Times Roman
359
+ # * +:arial+ - Arial
360
+ # * +:arialbi+ - Arial Bold Italic
361
+ # * +:verdanab+ - Verdana Bold
362
+ # * +:advc128d+ - barcode font
363
+ # * +size+ - font size (points?)
364
+ # * +color+ - a color specified in HTML style (eg, "#CCEECC")
365
+ # * +align+ - may be +:left+ or +:center+ only, defaults to +:left+
366
+ def add_text! (text, xoff, yoff, width, height, font, size, html_color, align=:left)
367
+ color = Color::RGB.from_html(html_color)
368
+ cmd = (align == :center) ? "ZC" : "ZA"
369
+ parts = [URI.escape(text), xoff, yoff, width, height, font, size].map {|x| x.to_s} +
370
+ [color.r, color.g, color.b].map {|c| (c*255).to_i }
371
+ cmd << parts.join(",")
372
+ @transforms << cmd
373
+ end
374
+
375
+ ##
376
+ # Highlight the image. I'm still not sure what this means, but here it is.
377
+ # You specify an square highlight area of the image with the following
378
+ # parameters:
379
+ #
380
+ # * +xoff+ - x offset from the top left corner to tlc of box (pixels)
381
+ # * +yoff+ - y offset from the top left corner to tlc of box (pixels)
382
+ # * +width+ - width of the text box
383
+ # * +height+ - height of the text box in pixels
384
+ # * +intensity+ - I really don't know what this means, but more is bigger
385
+ def highlight!(xoff, yoff, width, height, intensity)
386
+ @transforms << "HL#{xoff},#{yoff},#{width},#{height},#{intensity}"
387
+ end
388
+
389
+ ##
390
+ # Transformations like #crop! and #add_shadow!, etc. can be chained and
391
+ # are potentially applied in the order specified. Should you need to clear
392
+ # the transforms and revert to the original image, this command does that.
393
+ def reset_transforms!
394
+ @transforms = []
395
+ end
396
+
397
+ ##
398
+ # Returns a URL for the image from Amazon's servers.
399
+ def url
400
+ url = "http://#{country_imghost}/images/P/#{asin}"
401
+ url << "." << country_imgcode << "."
402
+
403
+ url << "_" << @transforms.join(",") << "_" << ".jpg"
404
+ end
405
+
406
+ ##
407
+ # This method is an alias for #url
408
+ alias :to_s :url
409
+ end
410
+ end
411
+ end
@@ -0,0 +1,238 @@
1
+ # Code Generated by ZenTest v. 3.4.2
2
+ # classname: asrt / meth = ratio%
3
+ # Amazon::Hacks::Image: 0 / 15 = 0.00%
4
+ # Amazon::Hacks::Link: 0 / 8 = 0.00%
5
+ # Countries: 0 / 3 = 0.00%
6
+
7
+ require 'test/unit' unless defined? $ZENTEST and $ZENTEST
8
+ require './lib/amazon-hacks'
9
+
10
+ module TestAmazon
11
+ module TestHacks
12
+ class TestCountries
13
+ include Amazon::Hacks::Countries
14
+
15
+ def setup
16
+ @country = :uk
17
+ end
18
+
19
+ def test_country_host
20
+ assert_equal("www.amazon.co.uk", country_host)
21
+ end
22
+
23
+ def test_country_imgcode
24
+ assert_equal("02", country_imgcode)
25
+ end
26
+
27
+ def test_country_imghost
28
+ assert_equal("images.amazon.co.uk", country_imghost)
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ module TestAmazon
35
+ module TestHacks
36
+ class TestImage < Test::Unit::TestCase
37
+ URL_PREFIX = "http://images.amazon.com/images/P/0201485672.01."
38
+
39
+ def setup
40
+ @img = Amazon::Hacks::Image.new("0201485672", :us)
41
+ end
42
+
43
+ def test_build_from_url
44
+ i = Amazon::Hacks::Image.build_from_url("http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672/sr=8-1/qid=1165273301/ref=pd_bbs_sr_1/002-2410048-1716806?ie=UTF8&s=books")
45
+ assert_equal("#{URL_PREFIX}__.jpg", i.url)
46
+ end
47
+
48
+ def test_add_border_bang
49
+ @img.add_border! 12, "\#CC2244"
50
+ assert_equal("#{URL_PREFIX}_BO12,204,34,68_.jpg", @img.url)
51
+ end
52
+
53
+ def test_add_custom_shadow_bang
54
+ @img.add_custom_shadow! 2, 23, 45, 30
55
+ assert_equal("#{URL_PREFIX}_PA2,23,45,30_.jpg", @img.url)
56
+ end
57
+
58
+ def test_add_shadow_bang_left
59
+ @img.add_shadow! :left
60
+ assert_equal("#{URL_PREFIX}_PB_.jpg", @img.url)
61
+ end
62
+
63
+ def test_add_shadow_bang_right
64
+ @img.add_shadow! :right
65
+ assert_equal("#{URL_PREFIX}_PC_.jpg", @img.url)
66
+ end
67
+
68
+ def test_blur_bang
69
+ @img.blur! 23
70
+ assert_equal("#{URL_PREFIX}_BL23_.jpg", @img.url)
71
+ end
72
+
73
+ def test_crop_bang
74
+ @img.crop! 0, 10, 20, 20
75
+ assert_equal("#{URL_PREFIX}_CR0,10,20,20_.jpg", @img.url)
76
+ end
77
+
78
+ def test_highlight_bang
79
+ @img.highlight! 0, 10, 20, 15, 75
80
+ assert_equal("#{URL_PREFIX}_HL0,10,20,15,75_.jpg", @img.url)
81
+ end
82
+
83
+ def test_reset_transforms_bang
84
+ @img.add_border! 33, "\#CCCCCC"
85
+ @img.blur! 23
86
+ @img.add_shadow! :right
87
+ @img.reset_transforms!
88
+
89
+ assert_equal("#{URL_PREFIX}__.jpg", @img.url)
90
+ end
91
+
92
+ def test_scale_bang_proportion
93
+ @img.scale! :proportion, 23
94
+ assert_equal("#{URL_PREFIX}_AA23_.jpg", @img.url)
95
+ end
96
+
97
+ def test_scale_bang_square
98
+ @img.scale! :square, 23
99
+ assert_equal("#{URL_PREFIX}_SS23_.jpg", @img.url)
100
+ end
101
+
102
+ def test_scale_bang_width
103
+ @img.scale! :width, 23
104
+ assert_equal("#{URL_PREFIX}_SX23_.jpg", @img.url)
105
+ end
106
+
107
+ def test_scale_bang_height
108
+ @img.scale! :height, 23
109
+ assert_equal("#{URL_PREFIX}_SY23_.jpg", @img.url)
110
+ end
111
+
112
+ def test_set_size_bang_small
113
+ @img.set_size! :small
114
+ assert_equal("#{URL_PREFIX}_SCTZZZZZZZ_.jpg", @img.url)
115
+ end
116
+
117
+ def test_set_size_bang_medium
118
+ @img.set_size! :medium
119
+ assert_equal("#{URL_PREFIX}_SCMZZZZZZZ_.jpg", @img.url)
120
+ end
121
+
122
+ def test_set_size_bang_large
123
+ @img.set_size! :large
124
+ assert_equal("#{URL_PREFIX}_SCLZZZZZZZ_.jpg", @img.url)
125
+ end
126
+
127
+ def test_sharpen_bang
128
+ @img.sharpen! 83
129
+ assert_equal("#{URL_PREFIX}_SH83_.jpg", @img.url)
130
+ end
131
+
132
+ def test_add_text_bang
133
+ @img.add_text! "hello world", 5, 15, 100, 100, :times, 20, "\#CC2244", :left
134
+ assert_equal("#{URL_PREFIX}_ZAhello%20world,5,15,100,100,times,20,204,34,68_.jpg", @img.url)
135
+ end
136
+
137
+ def test_text_bang_center
138
+ @img.add_text! "hello world", 5, 15, 100, 100, :times, 20, "\#CC2244", :center
139
+ assert_equal("#{URL_PREFIX}_ZChello%20world,5,15,100,100,times,20,204,34,68_.jpg", @img.url)
140
+ end
141
+
142
+ def test_tilt_bang
143
+ @img.tilt! 45
144
+ assert_equal("#{URL_PREFIX}_PT45_.jpg", @img.url)
145
+ end
146
+
147
+ def test_url
148
+ assert_equal("#{URL_PREFIX}__.jpg", @img.url)
149
+ assert_equal("#{URL_PREFIX}__.jpg", @img.to_s)
150
+ end
151
+
152
+ def test_chain_transforms
153
+ @img.set_size! :small
154
+ @img.blur! 87
155
+ assert_equal("#{URL_PREFIX}_SCTZZZZZZZ,BL87_.jpg", @img.url)
156
+ end
157
+ end
158
+ end
159
+ end
160
+
161
+ module TestAmazon
162
+ module TestHacks
163
+ class TestLink < Test::Unit::TestCase
164
+ def setup
165
+ @us_link = Amazon::Hacks::Link.new("http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672/sr=8-1/qid=1165273301/ref=pd_bbs_sr_1/002-2410048-1716806?ie=UTF8&s=books")
166
+ @uk_link = Amazon::Hacks::Link.new("http://www.amazon.co.uk/The-IT-Crowd/dp/B000EU1OYC/sr=8-1/qid=1165274239/ref=pd_ka_1/026-4633332-4150855?ie=UTF8&s=dvd")
167
+ end
168
+
169
+ def test_class_extract_asin_1
170
+ asin = Amazon::Hacks::Link.extract_asin("http://www.amazon.com/o/asin/0201485672")
171
+ assert_equal("0201485672", asin)
172
+
173
+ asin = Amazon::Hacks::Link.extract_asin("http://www.amazon.co.uk/o/asin/B000EU1OYC")
174
+ assert_equal("B000EU1OYC", asin)
175
+ end
176
+
177
+ def test_class_extract_asin_2
178
+ asin = Amazon::Hacks::Link.extract_asin("http://www.amazon.com/exec/obidos/ASIN/0201485672")
179
+ assert_equal("0201485672", asin)
180
+
181
+ asin = Amazon::Hacks::Link.extract_asin("http://www.amazon.co.uk/exec/obidos/ASIN/B000EU1OYC")
182
+ assert_equal("B000EU1OYC", asin)
183
+ end
184
+
185
+ def test_class_extract_asin_3
186
+ asin = Amazon::Hacks::Link.extract_asin("http://www.amazon.com/exec/obidos/tg/detail/-/0201485672")
187
+ assert_equal("0201485672", asin)
188
+
189
+ asin = Amazon::Hacks::Link.extract_asin("http://www.amazon.co.uk/exec/obidos/tg/detail/-/B000EU1OYC")
190
+ assert_equal("B000EU1OYC", asin)
191
+ end
192
+
193
+ def test_class_extract_asin_4
194
+ asin = Amazon::Hacks::Link.extract_asin("http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672/sr=8-1/qid=1165273301/ref=pd_bbs_sr_1/002-2410048-1716806?ie=UTF8&s=books")
195
+ assert_equal("0201485672", asin)
196
+
197
+ asin = Amazon::Hacks::Link.extract_asin("http://www.amazon.co.uk/The-IT-Crowd/dp/B000EU1OYC/sr=8-1/qid=1165274239/ref=pd_ka_1/026-4633332-4150855?ie=UTF8&s=dvd")
198
+ assert_equal("B000EU1OYC", asin)
199
+ end
200
+
201
+ def test_class_extract_country
202
+ assert_equal(:us, Amazon::Hacks::Link.extract_country("http://www.amazon.com/foo"))
203
+ assert_equal(:uk, Amazon::Hacks::Link.extract_country("http://www.amazon.co.uk/foo"))
204
+ assert_equal(:de, Amazon::Hacks::Link.extract_country("http://www.amazon.de/foo"))
205
+ assert_equal(:fr, Amazon::Hacks::Link.extract_country("http://www.amazon.fr/foo"))
206
+ assert_equal(:jp, Amazon::Hacks::Link.extract_country("http://www.amazon.co.jp/foo"))
207
+ end
208
+
209
+ def test_asin
210
+ assert_equal("0201485672", @us_link.asin)
211
+ assert_equal("B000EU1OYC", @uk_link.asin)
212
+ end
213
+
214
+ def test_associate_url
215
+ assert_equal("http://www.amazon.com/o/asin/0201485672/testassoc", @us_link.associate_url("testassoc"))
216
+ assert_equal("http://www.amazon.co.uk/o/asin/B000EU1OYC/testassoc", @uk_link.associate_url("testassoc"))
217
+ end
218
+
219
+ def test_normalize
220
+ assert_equal("http://www.amazon.com/o/asin/0201485672", @us_link.normalize)
221
+ end
222
+
223
+ def test_normalize_bang
224
+ @us_link.normalize!
225
+ assert_equal("http://www.amazon.com/o/asin/0201485672", @us_link.to_s)
226
+ end
227
+
228
+ def test_url_equals
229
+ link = Amazon::Hacks::Link.new
230
+ link.url = "http://www.amazon.co.uk/The-IT-Crowd/dp/B000EU1OYC/sr=8-1/qid=1165274239/ref=pd_ka_1/026-4633332-4150855?ie=UTF8&s=dvd"
231
+ assert_equal("http://www.amazon.co.uk/The-IT-Crowd/dp/B000EU1OYC/sr=8-1/qid=1165274239/ref=pd_ka_1/026-4633332-4150855?ie=UTF8&s=dvd", link.to_s)
232
+ assert_equal(:uk, link.country)
233
+ assert_equal("B000EU1OYC", link.asin)
234
+ end
235
+ end
236
+ end
237
+ end
238
+
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: amazon-hacks
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2006-12-12 00:00:00 -05:00
8
+ summary: A collection of useful snippets against the Amazon website
9
+ require_paths:
10
+ - lib
11
+ email: harrisj@schizopolis.net
12
+ homepage: http://www.nimblecode.com/code/AmazonHacks
13
+ rubyforge_project: amazon-hacks
14
+ description: "== DESCRIPTION: Mainly the product of messing around, this gem comprises Ruby code for a few useful \"Amazon Hacks\" -- common techniques for manipulating Amazon product URLs and Images. This is mainly useful if you find yourself creating a site where you might link to Amazon product pages and display images for them. Examples of this might include: * Social consumption sites like http://www.allconsuming.net/ * Blogs or tumbleblogs with book/music/etc. reviews * Normalizing Amazon links or create associate IDs This GEM is NOT related to using the Amazon Web Services and there is already an excellent gem for that if you need more heavy-duty use of the Amazon website (this gem does not even communicate with Amazon at all). Also, note this gem is meant in the spirit of fun hackery. You can use it to create interesting images from Amazon on demand, but if you are going to use it on a serious website, please consider caching and attributing that image to Amazon (I also have no idea what the official legal policy for using Amazon's book images is). And of course, do not even consider using this for fraud. It is possible to generate \"20% off\" or \"Look Inside!\" badges on Amazon images, but this gem does not support that since I can not think of any reason why outside sites would use that."
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Jacob Harris
31
+ files:
32
+ - History.txt
33
+ - Manifest.txt
34
+ - README.txt
35
+ - Rakefile
36
+ - lib/amazon-hacks.rb
37
+ - test/test_amazon-hacks.rb
38
+ test_files:
39
+ - test/test_amazon-hacks.rb
40
+ rdoc_options: []
41
+
42
+ extra_rdoc_files: []
43
+
44
+ executables: []
45
+
46
+ extensions: []
47
+
48
+ requirements: []
49
+
50
+ dependencies:
51
+ - !ruby/object:Gem::Dependency
52
+ name: color-tools
53
+ version_requirement:
54
+ version_requirements: !ruby/object:Gem::Version::Requirement
55
+ requirements:
56
+ - - ">"
57
+ - !ruby/object:Gem::Version
58
+ version: 0.0.0
59
+ version: