#script to query amazon for album information #author: Dan Pickett ( dpickett@enlightsolutions.com ) require 'amazon/search' require 'time' require 'date' require 'optparse' require 'ostruct' include Amazon::Search # don't want to have to fully qualify identifiers class Connector ASSOCIATES_ID = "webservices-20" # if you don't have one of these, don't # pass the second argument to Request.new DEV_TOKEN = "1ZVJEA6D3VH000PJTM02" # your development token DEBUG = false def self.search(query, sort_by_field, sort_order) begin #perform search off of amazon request = Request.new(DEV_TOKEN) # second argument optional response = request.keyword_search(query, 'music', HEAVY, 1) rescue Amazon::Search::Request::SearchError => e return nil end if DEBUG #prints out complete product information for product in response.products printf("Found a product:\n%s---\n", product) end end #add track quantity as an attribute so that we can use it for sorting products = Array.new for product in response.products product = product.to_h if product['tracks'].nil? product['track_qty'] = 0 else product['track_qty'] = (product['tracks'].size || 0) end if !product['release_date'].nil? product['date_released'] = Date.parse(product['release_date']) end products << product end if sort_by_field == 'date_released' sort_minimum = Date.parse('11/11/1900') sort_maximum = Date.parse('11/11/3050') else sort_minimum = -1 sort_maximum = 2^32 end if sort_order == 'D' products = products.sort_by {|x| x[sort_by_field] || sort_minimum} products.reverse! else products = products.sort_by {|x| x[sort_by_field] || sort_maximum} end return products; end end class AmazonXmlTranslator def self.to_xml(amazon_result, image_only = false) xml_result = REXML::Element.new('results') if !amazon_result.nil? for album in amazon_result xml_album = REXML::Element.new('album') xml_album.add_attribute('title', album['product_name']) xml_album.add_attribute('artist', album['artists']) xml_album.add_attribute('sales_rank', album['sales_rank']) xml_album.add_attribute('image_url', album['image_url_large']) xml_album.add_attribute('release_date', album['release_date']) xml_album.add_attribute('user_rating', album['average_customer_rating']) if !image_only i = 0 #clean up and get rid of nil entries tracks = (album['tracks'] || []).reject{|x| x.nil?} #iterate through tracks and put into xml for track in tracks i += 1 xml_track = REXML::Element.new('track') xml_track.add_attribute('id', i.to_s) xml_track.add_text(track) xml_album.add_element(xml_track) end end if(!album['tracks'].nil?) xml_album.add_attribute("tracks", album['tracks'].size || 0) end xml_result.add_element(xml_album) end end return xml_result end end require 'optparse' options = OpenStruct.new options.sort_by_field = 'sales_rank' options.sort_order = 'A' options.image_only = false OptionParser.new do |opts| opts.banner = "Usage: amazon.rb 'search query' [options]" opts.on("-a", "--album_only", "Only retrieve album information (no tracks)") do |i| options.image_only = true end opts.on("-s", "--sort_by FIELD", "Sort by field (Acceptable options: average_user_rating, date_released, sales_rank, track_qty)") do |sort| #TODO validate sort fields options.sort_by_field = sort end opts.on("-d", "--descending", "Sort in descending order") do |a| options.sort_order = 'D' end end.parse! if ARGV[0].nil? puts "Improper Usage: please supply a quoted search argument" else results = Connector.search(ARGV[0], options.sort_by_field, options.sort_order) AmazonXmlTranslator.to_xml(results, options.image_only).write($stdout, 0) end