Amazon API and hardcover versus paperback - ruby

When searching Amazon using their API is there a way to separate out hardcover, paperback, kindle and preorderable books?
I'm using Ruby and Amazon Product gem and have been searching through their documentation looking for info on this and haven't managed to find anything yet.
update:
I have come across some starting points that I am working through. There seems to a way to get this information via RrelatedItems ResponseGroup as described here. The KindleStore hierarchy seems relevant.
update II:
Binding is possibly the field I need to somehow look at and amazon's API provides an way of getting to AlternateVersions of an ASIN using the AlternativeVersion ResponseGroup type for books.

I will assume you know how to set up the Amazon Product gem request object correctly. from there, you can do...
search = req.search( 'Ender\'s Game' )
search.each('Item') do |item|
asin = item["ASIN"]
title = item['ItemAttributes']['Title']
hash = {
:response_group => ['ItemAttributes']
}
items = req.find( asin, hash )
items.each('Item') do |ia|
puts "[#{asin}]: #{title} => [#{ia['ItemAttributes']['Binding']}]"
end
end
which produces output like
[0812550706]: Ender's Game (Ender, Book 1) => [Mass Market Paperback]
[0765362430]: The Ender Quartet Box Set: Ender's Game, Speaker for the Dead, Xenocide, Children of the Mind => [Mass Market Paperback]
[0812550757]: Speaker for the Dead (Ender, Book 2) => [Mass Market Paperback]
[0765342405]: Ender's Shadow (Ender, Book 5) => [Paperback]
[B003G4W49C]: Ender's Game => [Kindle Edition]
[0785135820]: Ender's Game: Command School => [Hardcover]
[0785135804]: Ender's Game: Battle School (Ender's Game Gn) => [Hardcover]
[0765362449]: The Ender's Shadow Series Box Set: Ender's Shadow, Shadow of the Hegemon, Shadow Puppets, Shadow of the Giant => [Paperback]
[0785136096]: Ender's Game: Formic Wars: Burning Earth => [Hardcover]
[0812565959]: Shadow of the Hegemon (Ender, Book 6) => [Mass Market Paperback]

You could try looking at the BrowseNodes. For example if you see the kindle store BrowseNode you know it's a kindle book.

Related

`*': negative argument (ArgumentError)

I'm trying to sort in descending order an array of photo objects from Flickr API based on the number of comments(count_comments) of each photo. I'm using the following code.
def rank_photos(photos)
photos.sort_by { |photo| photo.count_comments * -1 }
end
However I get the following error message.
*': negative argument (ArgumentError)
Here is what the Array looks like
[{"id"=>"38280904752", "owner"=>"131718287#N07",
"secret"=>"abe0b93180", "server"=>"4583", "farm"=>5,
"title"=>"IMG_3640", "ispublic"=>1, "isfriend"=>0, "isfamily"=>0,
"count_comments"=>"0", "tags"=>"washington post dc web women codeher17
dctech tech technology",
"url_m"=>"https://farm5.staticflickr.com/4583/38280904752_abe0b93180.jpg", "height_m"=>"333", "width_m"=>"500"}, {"id"=>"38312540901",
"owner"=>"131718287#N07", "secret"=>"7b6e6805d4", "server"=>"4568",
"farm"=>5, "title"=>"IMG_3458", "ispublic"=>1, "isfriend"=>0,
"isfamily"=>0, "count_comments"=>"0", "tags"=>"washington post dc web
women codeher17 dctech tech technology",
"url_m"=>"https://farm5.staticflickr.com/4568/38312540901_7b6e6805d4.jpg", "height_m"=>"500", "width_m"=>"333"}, {"id"=>"38281453252",
"owner"=>"131718287#N07", "secret"=>"438293cffd", "server"=>"4539",
"farm"=>5, "title"=>"IMG_3460", "ispublic"=>1, "isfriend"=>0,
"isfamily"=>0, "count_comments"=>"0", "tags"=>"washington post dc web
women codeher17 dctech tech technology",
"url_m"=>"https://farm5.staticflickr.com/4539/38281453252_438293cffd.jpg", "height_m"=>"333", "width_m"=>"500"}
Why is throwing this error?
count_comments is a string, so you should convert it to a number first. In the process you can also eliminate the multiplication altogether.
def rank_photos(photos)
photos.sort_by { |photo| -photo.count_comments.to_i }
end

Twitter api not working in terminal

Am using the twitter gem to connect to the twitter streaming api.
When i run the code in the console in sublime text 2, everything works as it should and am getting the results from the api. However when i try to run the script from the terminal i get this error:
/Users/username/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/twitter-5.15.0/lib/twitter/streaming/connection.rb:16:in `initialize': Can't assign requested address - connect(2) for "199.16.156.217" port (Errno::EADDRNOTAVAIL)
Am only using the example code from the github page of the twitter gem.
https://github.com/sferik/twitter
client = Twitter::Streaming::Client.new do |config|
config.consumer_key = "YOUR_CONSUMER_KEY"
config.consumer_secret = "YOUR_CONSUMER_SECRET"
config.access_token = "YOUR_ACCESS_TOKEN"
config.access_token_secret = "YOUR_ACCESS_SECRET"
end
client.sample do |object|
puts object.text if object.is_a?(Twitter::Tweet)
end
Do anyone know why i get this error, and how i can fix this?
require 'twitter'
while true
config = {
:consumer_key => CONSUMER_KEY,
:consumer_secret => COMSUMER_SECRET,
:access_token => ACCESS_TOKEN,
:access_token_secret => ACCESS_TOKEN_SECRET,
}
sClient = Twitter::Streaming::Client.new(config)
topics = ['edelweiss', 'rose']
sClient.filter(:track => topics.join(',')) do |tweet|
if tweet.is_a?(Twitter::Tweet)
puts "#{tweet.user.screen_name}: #{tweet.text}"
end
end
end
running code
$ ruby lasswi.rb
Suphatra_Rfc: RT #GGiftfyy: Rose Gold ในมือนั้นอิจเเรงงงง เครื่องเก่าโยนมาทางนี้ก็ได้นะเพ่~ น้องพร้อมเสมอ😂😂 #งานซูมต้องมา #อยากได้อ่ะอยากได้ 😆 http://t.…
CBullsfans: Jimmy Butler Reportedly Doesn't Respect Derrick Rose's Work Ethic http://t.co/3Ikjvvjuth #Bulls #NBA
sobinasalvez: RT #iPhoneTeam: Rose gold everything http://t.co/1DLhXokknu
magicearth_: RT #magazine_wmw: Rose-ringed parakeets in flight on their way to roost in an urban cemetery in London, England.
Photograph: Sam Hobson htt…
demoo2012: Rose, use this pic 👍
#Razana96 http://t.co/uAwS9JdHyl
EndearingImages: New artwork for sale! - "Grace" - http://t.co/ugpIaxABqg #fineartamerica http://t.co/jg0e3eDNll
LoveKnitting: Great rose workshop with #NickyKnits at #TheKnittingandStitchingShow such a lovely lady! #twistedthread http://t.co/rV0Bsjg63t
camarillonican4: Brand New Sealed - Apple iPhone 6S Plus - 64GB - Rose Gold - UNLOCKED http://t.co/ygFPoN7pLO http://t.co/mqXKJmmrNz
Dekho00: RT #PAPIGFUNK: Giveaway ENDING on Sunday! Enter Now- iPhone 6S Plus - Rose Gold - Unboxing + Giveaway! https://t.co/02ONZ6D8IS #iPhone6SPlu…
souravmishra1: RT #RHIndia: "Only in art will the lion lie down with the lamb, and the rose grow without thorn." - Martin Amis​ #RandomAmis http://t.co/MT…
exol_lzw0112: RT #DOThFanclub: [Preview] 151009 ONE K Concert (cr.Like a star, Lovely Rose, Chibimori)
อันนยอง~~ http://t.co/w8vvE40dEK
BruhninhaD: Livro: Hugo & Rose da Editora Agir
Será o correto deixar a realidade para viver um sonho?http://t.co/OfxkKrzBog #books #book #livros #blog
This was a known issue with the twitter gem, using an updated version from GitHub solved the problem.
https://github.com/sferik/twitter/issues/709

How to parse a more complicated JSON object in Ruby on Sinatra

I'm a Java guy, new to Ruby. I've been playing with it just to see what it can do, and I'm running into an issue that I can't solve.
I decided to try out Sinatra, again, just to see what it can do, and decided to play with the ESPN API and see if I can pull the venue of a team via the API.
I'm able to make the call and get the data back, but I am having trouble parsing it:
{"sports"=>[{"name"=>"baseball", "id"=>1, "uid"=>"s:1", "leagues"=>[{"name"=>"Major League Baseball", "abbreviation"=>"mlb", "id"=>10, "uid"=>"s:1~l:10", "groupId"=>9, "shortName"=>"MLB", "teams"=>[{"id"=>17, "uid"=>"s:1~l:10~t:17", "location"=>"Cincinnati", "name"=>"Reds", "abbreviation"=>"CIN", "color"=>"D60042", "venues"=>[{"id"=>83, "name"=>"Great American Ball Park", "city"=>"Cincinnati", "state"=>"Ohio", "country"=>"", "capacity"=>0}], "links"=>{"api"=>{"teams"=>{"href"=>"http://api.espn.com/v1/sports/baseball/mlb/teams/17"}, "news"=>{"href"=>"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news"}, "notes"=>{"href"=>"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news/notes"}}, "web"=>{"teams"=>{"href"=>"http://espn.go.com/mlb/team/_/name/cin/cincinnati-reds?ex_cid=espnapi_public"}}, "mobile"=>{"teams"=>{"href"=>"http://m.espn.go.com/mlb/clubhouse?teamId=17&ex_cid=espnapi_public"}}}}]}]}], "resultsOffset"=>0, "resultsLimit"=>50, "resultsCount"=>1, "timestamp"=>"2013-08-04T14:47:13Z", "status"=>"success"}
I want to pull the venues part of the object, specifically the name value. Every time I try to parse it I end up getting an error along the lines of "cannot change from nil to string" and then also I've gotten an integer to string error.
Here's what i have so far:
get '/venue/:team' do
id = ids[params[:team]]
url = 'http://api.espn.com/v1/sports/baseball/mlb/teams/' + id + '?enable=venues&apikey=' + $key
resp = Net::HTTP.get_response(URI.parse(url))
data = resp.body
parsed = JSON.parse(resp.body)
#venueData = parsed["sports"]
"Looking for the venue of the #{params[:team]}, which has id " + id + ", and here's the data returned: " + venueData.to_s
end
When I do parsed["sports"} I get:
[{"name"=>"baseball", "id"=>1, "uid"=>"s:1", "leagues"=>[{"name"=>"Major League Baseball", "abbreviation"=>"mlb", "id"=>10, "uid"=>"s:1~l:10", "groupId"=>9, "shortName"=>"MLB", "teams"=>[{"id"=>17, "uid"=>"s:1~l:10~t:17", "location"=>"Cincinnati", "name"=>"Reds", "abbreviation"=>"CIN", "color"=>"D60042", "venues"=>[{"id"=>83, "name"=>"Great American Ball Park", "city"=>"Cincinnati", "state"=>"Ohio", "country"=>"", "capacity"=>0}], "links"=>{"api"=>{"teams"=>{"href"=>"http://api.espn.com/v1/sports/baseball/mlb/teams/17"}, "news"=>{"href"=>"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news"}, "notes"=>{"href"=>"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news/notes"}}, "web"=>{"teams"=>{"href"=>"http://espn.go.com/mlb/team/_/name/cin/cincinnati-reds?ex_cid=espnapi_public"}}, "mobile"=>{"teams"=>{"href"=>"http://m.espn.go.com/mlb/clubhouse?teamId=17&ex_cid=espnapi_public"}}}}]}]}]
But nothing else parses. Please help!
Like I said, I'm not trying to do anything fancy, just figure out Ruby a little for fun, but I have been stuck on this issue for days now. Any help would be appreciated!
EDIT:
JSON straight from the API:
{"sports" :[{"name" :"baseball","id" :1,"uid" :"s:1","leagues" :[{"name" :"Major League Baseball","abbreviation" :"mlb","id" :10,"uid" :"s:1~l:10","groupId" :9,"shortName" :"MLB","teams" :[{"id" :17,"uid" :"s:1~l:10~t:17","location" :"Cincinnati","name" :"Reds","abbreviation" :"CIN","color" :"D60042","venues" :[{"id" :83,"name" :"Great American Ball Park","city" :"Cincinnati","state" :"Ohio","country" :"","capacity" :0}],"links" :{"api" :{"teams" :{"href" :"http://api.espn.com/v1/sports/baseball/mlb/teams/17"},"news" :{"href" :"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news"},"notes" :{"href" :"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news/notes"}},"web" :{"teams" :{"href" :"http://espn.go.com/mlb/team/_/name/cin/cincinnati-reds?ex_cid=espnapi_public"}},"mobile" :{"teams" :{"href" :"http://m.espn.go.com/mlb/clubhouse?teamId=17&ex_cid=espnapi_public"}}}}]}]}],"resultsOffset" :0,"resultsLimit" :50,"resultsCount" :1,"timestamp" :"2013-08-05T19:44:32Z","status" :"success"}
The result of data.inspect:
"{\"sports\" :[{\"name\" :\"baseball\",\"id\" :1,\"uid\" :\"s:1\",\"leagues\" :[{\"name\" :\"Major League Baseball\",\"abbreviation\" :\"mlb\",\"id\" :10,\"uid\" :\"s:1~l:10\",\"groupId\" :9,\"shortName\" :\"MLB\",\"teams\" :[{\"id\" :17,\"uid\" :\"s:1~l:10~t:17\",\"location\" :\"Cincinnati\",\"name\" :\"Reds\",\"abbreviation\" :\"CIN\",\"color\" :\"D60042\",\"venues\" :[{\"id\" :83,\"name\" :\"Great American Ball Park\",\"city\" :\"Cincinnati\",\"state\" :\"Ohio\",\"country\" :\"\",\"capacity\" :0}],\"links\" :{\"api\" :{\"teams\" :{\"href\" :\"http://api.espn.com/v1/sports/baseball/mlb/teams/17\"},\"news\" :{\"href\" :\"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news\"},\"notes\" :{\"href\" :\"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news/notes\"}},\"web\" :{\"teams\" :{\"href\" :\"http://espn.go.com/mlb/team/_/name/cin/cincinnati-reds?ex_cid=espnapi_public\"}},\"mobile\" :{\"teams\" :{\"href\" :\"http://m.espn.go.com/mlb/clubhouse?teamId=17&ex_cid=espnapi_public\"}}}}]}]}],\"resultsOffset\" :0,\"resultsLimit\" :50,\"resultsCount\" :1,\"timestamp\" :\"2013-08-05T19:44:24Z\",\"status\" :\"success\"}"
parsed["sports"] does not exist, parse your input and inspect it/ dump it
With the data you've provided in the question, you can get to the venues information like this:
require 'json'
json = JSON.parse data
json["sports"].first["leagues"].first["teams"].first["venues"]
# => [{"id"=>83, "name"=>"Great American Ball Park", "city"=>"Cincinnati", "state"=>"Ohio", "country"=>"", "capacity"=>0}]
By replacing each of the first calls with an iterator, you can search through without knowing where the data is:
json["sports"].each{|h|
h["leagues"].each{|h|
h["teams"].each{|h|
venues = h["venues"].map{|h| h["name"]}.join(", ")
puts %Q!name: #{h["location"]} #{h["name"]} venues: #{venues}!
}
}
}
This outputs:
name: Cincinnati Reds venues: Great American Ball Park
Depending on how stable the response data is you may be able to cut out several of the iterators:
json["sports"].first["leagues"]
.first["teams"]
.each{|h|
venues = h["venues"].map{|h| h["name"] }.join(", ")
puts %Q!name: #{h["location"]} #{h["name"]} venues: #{venues}!
}
and you'll most likely want to save the data, so something like each_with_object is helpful:
team_and_venues = json["sports"].first["leagues"]
.first["teams"]
.each_with_object([]){|h,xs|
venues = h["venues"].map{|h| h["name"]}.join(", ")
xs << %Q!name: #{h["location"]} #{h["name"]} venues: #{venues}!
}
# => ["name: Cincinnati Reds venues: Great American Ball Park"]
team_and_venues
# => ["name: Cincinnati Reds venues: Great American Ball Park"]
Notice that when an iterator declares variables, even if there is a variable with the same name outside the block, the scope of the block is respected and the block's variables remain local.
That's some pretty ugly code if you ask me, but it's a place to start.

Youtube_It example code draws Argument Error

I wrote some basic code to try and get the library working. I am operating on Windows 7, and I just installed the youtube_it gem and attempted to run some example code from the readme, however, I received a puzzling ArgumentError. Here is the code that I tried to run:
#Test YouTube Ruby file.
require 'youtube_it'
client = YouTubeIt::Client.new(:dev_key => "my developer key here)
client.videos_by(:query => "penguin", :max_results => 1)
client.videos.each do |video|
video.title
video.video_id
end
For reference, the error received was this: C:/RailsInstaller/Ruby1.9.3/lib/rubygems/1.9.1/gems/youtube_it-2.3.1/lib/youtube_it/request/video_upload.rb:265: in 'videos' wrong number of arguments (0 for 1) (ArgumentError).
Any input as to how I could go about troubleshooting this would be great.
First you need to close your dev key quotes
client = YouTubeIt::Client.new(:dev_key => "my developer key here")
This worked for me:
require 'youtube_it'
client = YouTubeIt::Client.new(:dev_key => "my developer key here")
response = client.videos_by(:query => "penguin")
response.videos.first.title
Try something from there:
response.videos.each do |video|
puts video.title
end
Result:
Pablo Penguin
Emperor penguins - The Greatest Wildlife Show on Earth - BBC
Penguin Fail - Best Bloopers from Penguins Spy in the Huddle
PoM - The Penguin Who Loved Me part 1
Scamper the Penguin (1988) - English Dubbed
Pet Penguin in Japan
Avicii - Penguin (Original mix)
CLUB PENGUIN....
penguin
Penguins very funny
Emperor Penguins in Antarctica
Christina Perri - Penguin (Official Lyric Video)
Club Penguin Unlock Item Codes (NEW) March 2013 Must Watch !!!! (HD)
Emperor Penguins Speed Launch Out of the Water
Avicii - 'Penguin' (Club Mix)
Cookie the Little Penguin at the Cincinnati Zoo
Penguin.avi
DONALD´S PENGUIN 1939
Penguins - BBC
Penguin Dilemma
Very happy Gentoo penguin
Zombie in a Penguin Suit
Penguin One
What should we expect in the next few months in terms of SEO for Google?
槇原敬之 - PENGUIN (2004年 日本武道館)

Working with nested hashes in Rails 3

I'm working with the Koala gem and the Facebook Graph API, and I want to break down the results I get for a users feed into separate variables for inserting into a mySQL database, probably using Active Record. Here is the code I have so far:
#token = Service.where(:provider => 'facebook', :user_id => session[:user_id]).first.token
#graph = Koala::Facebook::GraphAPI.new(#token)
#feeds = params[:page] ? #graph.get_page(params[:page]) : #graph.get_connections("me", "home")
And here is what #feeds looks like:
[{"id"=>"1519989351_1799856285747", "from"=>{"name"=>"April Daggett Swayne", "id"=>"1519989351"},
"picture"=>"http://photos-d.ak.fbcdn.net/hphotos-ak-ash4/270060_1799856805760_1519989351_31482916_3866652_s.jpg",
"link"=>"http://www.facebook.com/photo.php?fbid=1799856805760&set=a.1493877356465.2064294.1519989351&type=1", "name"=>"Mobile Uploads",
"icon"=>"http://static.ak.fbcdn.net/rsrc.php/v1/yx/r/og8V99JVf8G.gif", "type"=>"photo", "object_id"=>"1799856805760", "application"=>{"name"=>"Facebook for Android",
"id"=>"350685531728"}, "created_time"=>"2011-07-03T03:14:04+0000", "updated_time"=>"2011-07-03T03:14:04+0000"}, {"id"=>"2733058_10100271380562998", "from"=>{"name"=>"Joshua Ramirez",
"id"=>"2733058"}, "message"=>"Just posted a photo",
"picture"=>"http://platform.ak.fbcdn.net/www/app_full_proxy.php?app=124024574287414&v=1&size=z&cksum=228788edbab39cb34861aecd197ff458&src=http%3A%2F%2Fimages.instagram.com%2Fmedia%2F2011%2F07%2F02%2F2ad9768378cf405fad404b63bf5e2053_7.jpg",
"link"=>"http://instagr.am/p/G1tp8/", "name"=>"jtrainexpress's photo", "caption"=>"instagr.am",
"icon"=>"http://photos-e.ak.fbcdn.net/photos-ak-snc1/v27562/10/124024574287414/app_2_124024574287414_6936.gif", "actions"=>[{"name"=>"Comment",
"link"=>"http://www.facebook.com/2733058/posts/10100271380562998"}, {"name"=>"Like", "link"=>"http://www.facebook.com/2733058/posts/10100271380562998"}], "type"=>"link",
"application"=>{"name"=>"Instagram", "id"=>"124024574287414"}, "created_time"=>"2011-07-03T02:07:37+0000", "updated_time"=>"2011-07-03T02:07:37+0000"},
{"id"=>"588368718_10150230423643719", "from"=>{"name"=>"Eric Bailey", "id"=>"588368718"}, "link"=>"http://www.facebook.com/pages/Martis-Camp/105474549513998", "name"=>"Martis Camp",
"caption"=>"Eric checked in at Martis Camp.", "description"=>"Rockin the pool", "icon"=>"http://www.facebook.com/images/icons/place.png", "actions"=>[{"name"=>"Comment",
"link"=>"http://www.facebook.com/588368718/posts/10150230423643719"}, {"name"=>"Like", "link"=>"http://www.facebook.com/588368718/posts/10150230423643719"}],
"place"=>{"id"=>"105474549513998", "name"=>"Martis Camp", "location"=>{"city"=>"Truckee", "state"=>"CA", "country"=>"United States", "latitude"=>39.282813917575,
"longitude"=>-120.16736760768}}, "type"=>"checkin", "application"=>{"name"=>"Facebook for iPhone", "id"=>"6628568379"}, "created_time"=>"2011-07-03T01:58:32+0000",
"updated_time"=>"2011-07-03T01:58:32+0000", "likes"=>{"data"=>[{"name"=>"Mike Janes", "id"=>"725535294"}], "count"=>1}}]
I have looked around for clues on this, and haven't found it yet (but I'm still working on my stackoverflow-foo). Any help would be greatly appreciated.
That isn't a Ruby Hash, that's a fragment of a JSON string. First you need to decode into a Ruby data structure:
# If your JSON string is in json...
h = ActiveSupport::JSON.decode(json) # Or your favorite JSON decoder.
Now you'll have a Hash in h so you can access it like any other Hash:
array = h['data']
puts array[0]['id']
# prints out 1111111111_0000000000000
puts array[0]['from']['name']
# prints Jane Done

Resources