Scrobbler: Last.fm For Ruby
May 10th, 2007
I enjoy having my life broadcast on the net and one essential part of that is music. A few weeks ago, I started working on a ruby library for accessing the audioscrobbler web services.
Last night I put the finishing touches on the first release so I thought I would say something here. If you have a last.fm profile and are logging your tunes, you can now access them using ruby with my scrobbler gem.
So how easy is it? Below are a few examples of how to work with users, artists, albums and tracks.
# get recent tracks for a user
user = Scrobbler::User.new('jnunemaker')
user.recent_tracks.each { |t| puts t.name }
# get all the tracks for an album
album = Scrobbler::Album.new('Carrie Underwood', 'Some Hearts', :include_info => true)
album.tracks.each { |t| puts t.name }
# get similar artists
artist = Scrobbler::Artist.new('Carrie Underwood')
artist.similar.each { |a| puts "(#{a.match}%) #{a.name}" }
# top albums for a tag
tag = Scrobbler::Tag.new('country')
tag.top_albums.each { |a| puts "(#{a.count}) #{a.name} by #{a.artist}" }
# top fans for a track
track = Scrobbler::Track.new('Carrie Underwood', 'Before He Cheats')
track.fans.each { |u| puts "(#{u.weight}) #{u.username}" }
I implemented pretty much everything but the group stuff. I don’t use groups so I didn’t feel like throwing it together. It probably would have been pretty easy and patches are welcome (svn repo).
This is my fifth gem and it’s really fun for me to look back and see how far I’ve come in ruby. The first was Magnolia (June 2, 2006) which had 0 tests. Yep, back then I hadn’t even heard of tests. Each gem since then has had more tests and I really feel that Scrobbler is my best to date. I mocked the class that hits audioscrobbler to instead read an xml fixture file which is kind of cool. If the services change in the future, I just have to put in a new xml file and get my tests passing again. I’m thinking in the next web service gem I’ll do something along the lines of this Scott Raymond comment. I really don’t know how I survived without tests back in my PHP and ColdFusion days.
At any rate, enjoy the gem and let me know if you do anything cool with it.

May 10th, 2007 at 11:01 PM
I can’t wait to use this John. Well done sir.
May 11th, 2007 at 06:56 PM
thanks very much!
May 16th, 2007 at 02:11 AM
sweet
May 16th, 2007 at 05:47 PM
Cool! I’ll just throw away my inferior wrapper ;-)
May 23rd, 2007 at 12:24 PM
ooops … i have error.
ruby album.rb /usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:404:in `to_constant_name’: Anonymous modules have no name to be referenced by (ArgumentError) from /usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:214:in `qualified_name_for’ from /usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:476:in `const_missing’ from /usr/local/lib/site_ruby/1.8/scrobbler/base.rb:9:in `connection’ from /usr/local/lib/site_ruby/1.8/scrobbler/base.rb:13:in `fetch_and_parse’ from /usr/local/lib/site_ruby/1.8/scrobbler/album.rb:107:in `load_info’ from /usr/local/lib/site_ruby/1.8/scrobbler/album.rb:99:in `initialize’ from album.rb:4
May 23rd, 2007 at 02:36 PM
@Konstantin – What are you calling to when you get that error. Can you paste the code in?
May 29th, 2007 at 04:23 PM
I removed my dependency on xmlsimple, I stopped parsing out the recenttracks.xml file powering my dynamic “Most Recently Played” sig, and just moved to a call with your library.
It’s down to 34 lines (down from 43 in PHP w/ GD IIRC).
http://vxjasonxv.com/images/lastfm.png
The image uses Ruby (duh), RMagick for all the text annotation and image rendering, and your lib. Hey, I can get rid of my net/http dependency too.
33 lines :).
I do need to work something in in order to see if I should even get the xml file / regenerate the image or not. (I guess this means I have to go curl -I’ing it and see if AudioScrobbler puts out reliable “Last-Modified” headers.)
May 30th, 2007 at 09:39 PM
@Jason – Sweet. Nice work. Fun to see people using my libs.
June 3rd, 2007 at 11:38 AM
i`m executing example from gem on Ubuntu Linux.
July 17th, 2007 at 12:21 AM
John,
I believe I may have found an HTML entity problem. I left a static copy of the image on Webshots:
Take a look at Huey Lewis & the News http://aycu34.webshots.com/image/22313/2006317658898393236_rs.jpg
I don’t think you mean for that literal & to be appearing.
I’m assuming that the library isn’t converting the XML character data to the single character entities?
July 17th, 2007 at 01:33 PM
Clearly I meant XML entity, or perhaps character entity, by the way.
August 11th, 2007 at 04:29 PM
Were you able to generate the flash player for the music? Thanks.
September 21st, 2007 at 08:08 AM
Hi, thanks for your work…
I’ve found that if profile isn’t complete load_profile() script breakes.
So I modified it: :)
...but I have another problem, constant timeout… I can’t do more that few requests (I’m sleep()-ing as a real gentleman), how can I solve this?
Thanks again, Nikola
October 20th, 2007 at 12:10 AM
Awesome John. I started writing this myself until I came to my senses and googled it. Very, very nice implementation!
thx
October 25th, 2007 at 08:35 PM
Glad I could help. Hopefully I’ll get to use it some day. :)
October 31st, 2007 at 01:18 PM
Hiya. Is there a way to see if a band is actually in the scrobbler system?
I can ask for their top albums, to see if anything comes back, but that seems kinda silly.
thanks, sanj
October 31st, 2007 at 04:08 PM
@sanjay – Nope. Scrobbler doesn’t have an API method for that purpose, at least not that they have documented.
January 26th, 2008 at 06:34 PM
I made a little addition to Scrobbler::Artist that will enable getting the artist cover from which you are referencing.
bc. def image doc = self.class.fetch_and_parse(”#{api_path}/similar.xml”) return (doc).at(:similarartists)[‘picture’] end
April 28th, 2008 at 11:45 AM
Is it also possible to add a song to you “Recently Listened Tracks” with this library?
Thanks in advance!
May 2nd, 2008 at 12:41 AM
@Leon – Nope. Only read, no write.