Posted by Dan Sosedoff
on June 15, 2010
Amazon has an awesome image service. You can use their product images on your site, adjusting them for you needs. All you have to know – one image url of your product. Having that string will provide you an access to its dynamic image scaling service which i had to use recently.
So, lets say you have books on your website, but you dont have any good images for them. There is 2 ways to solve your problem: 1) download it from whatever place and resize 2) use amazon!
Here goes small overview.
Unfortunately, i didnt have any time to play with image service for different countries, but i assume that wont change that much. Lets take a look on a regular image:
http://ecx.images-amazon.com/images/I/41ygBmdaIfL._SL500_SS100_.jpg
It has different parts:
1) URL base: http://ecx.images-amazon.com/images/I/
2) Image code: 41ygBmdaIfL
3) Size format (surrounded by underscores): _SL500_SS100_
4) Format: jpg/gif/png
Some words about image format. It can vary from square thumbnails to images with specific max width and height. For example: _SX100_ will produce image that 100 pixels wide, height will be calculated proportionally. SH100 will give opposite result, scaled by 100 pixels maximum height, SS100 – 100×100 pixels thumbnail. And so on, you can find other similar crop codes while exploring amazon store on different pages, all you need is to take a look on image sources.
Now, we need to use this with Ruby:
require 'net/http'
module Amazon
# parse amazon image url and get image code and extension
def self.parse_image(url)
result = url.scan(/^http:\/\/ecx.images-amazon.com\/images\/I\/([a-z0-9\-\%]{1,})(.*)_.(jpg|jpeg|gif)/i)
unless result.nil?
unless result[0].nil?
match = result.first
return {:code => match.first.to_s, :extension => match.last.to_s}
end
end
end
# make a new amazon image url based on code and size
def self.make_image(image, size)
"http://ecx.images-amazon.com/images/I/#{image[:code]}._#{size.upcase}.#{image[:extension]}"
end
# check if actual image exists
def self.check_image(url)
begin
uri = URI.parse(url)
req = Net::HTTP::Get.new(uri.path)
res = Net::HTTP.start(uri.host, uri.port) { |http| http.request(req) }
return res.code == '200' && res.content_length.to_i > 0
rescue Exception
false
end
end
end
And usage:
url = 'http://ecx.images-amazon.com/images/I/51O65dIoZCL._SX117_.jpg'
info = Amazon.parse_image(url)
unless info.nil?
new_url = Amazon.make_image(info, 'sx100')
if Amazon.check_image(new_url)
puts "Cool! Resized image: #{new_url}"
else
puts "Sorry, this image does not exist!"
end
else
puts "Cant identify image!"
end
Some notes about the process. The only reason why method “check_image” uses GET method instead of HEAD is because if image cannot be generated or not found in amazon`s cache the response is still valid sometimes. I`ve checked it on 50k images and sometimes HEAD request indicates that response is valid while it not supposed to. Otherwise i would use HEAD.
Posted by Dan Sosedoff
on March 22, 2009
For a long time i was thinking that Amazon`s Simple Storage Service (S3) is very complicated thing. But, it was before i tried it. Couple days ago, i got account to S3 and started exploring API`s and architecture. Now i see how stupid i was
It`s really easy to handle all operations with files and buckets. Pricing also comfortable.
Welcome to cloud computing!
I started using it with Ruby. Regular gem and docs can be found at http://amazon.rubyforge.org/
So, the first useful tool i decided to created – simple uploader of local files to amazons server.
First, we need to create bucket and make it public:
Bucket.create('NAME_HERE',:access => :public_read)
Here`s the client ruby script:
#!/usr/bin/ruby
require 'rubygems'
require 'aws/s3'
include AWS::S3
$s3_bucket = "BUCKET_NAME"
$s3_key = "API_KEY"
$s3_secret = "API_SECRET"
def s3_store(localfile)
if File.exists?(localfile) && File.readable?(localfile)
puts "Uploading file [#{localfile}]. Size: #{File.size(localfile)} bytes."
name = File.basename(localfile)
Base.establish_connection!(:access_key_id => $s3_key, :secret_access_key => $s3_secret)
S3Object.store(name, open(localfile), $s3_bucket, :access => :public_read)
puts "Download link: http://s3.amazonaws.com/#{$s3_bucket}/#{name}"
else
puts "File not exists or not accessible. Please check file and try again!"
end
end
path = ARGV[0]
if !path
"Please specify the file to upload."
else
s3_store(path)
end
Download script: http://files.sosedoff.com/036cfedd/
BTW, I found cool firefox add-on to manage S3 objects/files. It`s pretty easy.
Link to extension – http://www.s3fox.net
Screenshot:

Posted by Dan Sosedoff
on February 15, 2009
On my small project i was looking for web service to get media covers from. I found that i can use Amazon Web Services API. The documentation for this ECommerce Service is pretty old, but it still works.
More detailed information about API you can find here
#!/usr/bin/ruby
require 'rubygems'
require 'net/http'
require 'cgi'
require 'xmlsimple'
$amazon_key = "12DR2PGAQT303YTEWP02" # NOT MY KEY (FOUND ON INTERNET)
$amazon_host = "webservices.amazon.com"
def fetch_cover(artist, album)
artist = CGI.escape(artist)
album = CGI.escape(album)
path = "/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=#{$amazon_key}&Operation=ItemSearch&SearchIndex=Music&Artist=#{artist}&ResponseGroup=Images&Keywords=#{album}"
data = Net::HTTP.get($amazon_host, path)
xml = XmlSimple.xml_in(data)
if xml['Items'][0]['TotalResults'].to_s.to_i then
cover = {
:small => xml['Items'][0]['Item'][0]['SmallImage'][0]['URL'],
:medium => xml['Items'][0]['Item'][0]['MediumImage'][0]['URL'],
:big => xml['Items'][0]['Item'][0]['LargeImage'][0]['URL']
}
return cover
end
return nil
end
So, after execution of this function you will get array with 3 different images (small, medium, big).
I use XML-Simple gem for ruby. Can be installed this way
sudo gem install xml-simple
That`s it. Download script