the making of earthalbum.com - a flickr, google maps, Ruby on Rails, and scriptaculous mash-up

September 24th, 2006 by ed_park

I’ve always loved the romance of travel. I’ve traveled to much of the U.S. and Europe, but I’ve always wanted more. I’ve wanted to see Angkor Wat in Cambodia, Macchu Picchu in Peru, and penguins on the ice shelves of Antarctica. I’ve wanted to spend more time wandering the streets of Harajuku in Tokyo, marveling at the pyramids in Egypt, and sunnyng myself on the tropical beaches of French Polynesia.

While I don’t really have the time to go to those places, google maps and flickr have given me the opportunity to visit those places virtually using the best of what Flickr has to offer. Over the past few weeks, my principal hobby project has been “lifespree explorer”, a google maps + flickr mash-up built with Ruby on Rails and scriptaculous. I released the first version of lifespree explorer about a week and half ago via programmableweb.com. Soon, it was given a thumbs-up by someone at stumbleupon.com; in the next week, I received at least 10,000 hits from web stumblers, and was one of the most popular sites (5000+ votes) on stumbleupon for a while. (note: special thanks to all the stumblers who voted for me, and especially those folks that commented on the site!)

The responses were encouraging, so I decided to plow ahead. Next, I tried playing with the YouTube API in order to create a YouTube version of the site– i.e., a google maps + YouTube mash-up. There were no readily available Ruby libraries for it, but I was able to create a library that was good enough for what I wanted it to do pretty quickly; the code to do is listed at the bottom of this blog post.

I also registered earthalbum.com as a new site on westhost. I’d had a hell of a time trying to make the mash-up work with fastcgi– the rewriterule sections start getting ridiculously difficult to debug– so I’m currently running it with a mongrel back-end.

Currently, you can access the original flickr version of the site at www.earthalbum.com, and the YouTube version at www.earthalbum.com/youtube.

####################################################################
#
# This is a *seriously* simple API to for using just the list_by_tag
# function in the the YouTube api-- haven't added much in the way
# of error-checking. You need to have installed xml-simple for this to work.
#
# Usage:
# youtube_requester = Youtube.new [your youtube id]
# r = youtube_requester.list_by_tag "china duck"
# r.each do |video|
#       print video.title + "\n"
#       print video.url + "\n"
#       print video.youtube_id + "\n"
# end
#
# -Ed Park 9/20/2006
#
####################################################################
require 'rubygems'
require 'net/http'
require 'uri'
require 'xmlsimple'

class Youtube
        def initialize(api_key)
                @api_key = api_key
        end

        def list_by_tag(tag = nil, page = 1, per_page = 10)
                path = "/api2_rest?method=youtube.videos.list_by_tag"
                         + "&dev_id=#{ @api_key }&tag=#{ URI.escape tag }"
                         + &page=#{ page }&per_page=#{ per_page }"
                response = Net::HTTP.get("www.youtube.com", path)

                r = XmlSimple.xml_in(response)

                if r["status"] == "ok" && ! r["video_list"][0].nil?
                        return r["video_list"][0]["video"].nil? ?
                                 [] :
                                 r["video_list"][0]["video"].map { |x| x.extend(YoutubeVideo)
}
                end

                return []
        end
end

# Allows us to access most of the youtube hashkeys as methods.
# Note that we don't really want to override the id method, which
# is a ruby-native method, so we instead create a new method: youtube_id.
module YoutubeVideo
        def method_missing(meth, *args)
                if meth.to_s == 'youtube_id'
                        return self["id"][0]
                end
                if ! self[meth.to_s].nil?
                        return self[meth.to_s][0]
                end
                return ""
        end
end

Leave a Reply