You want to use Ruby code to find freely reusable photos: perhaps to automatically illustrate a piece of text.
The Flickr photo-sharing web site has a huge number of photos and provides web services for searching them. Many of the photos are licensed under Creative Commons licenses, which give you permission to reuse the photos under various restrictions.
There are several Ruby bindings to Flickrs various web service APIs, but its REST API is so simple that Im just going to use it directly. Given a tag name (like "elephants"), this code will find an appropriate picture, and return the URL to a thumbnail version of the picture.
First, a bit of setup. As with Amazon and Google, to use the Flickr API at all youll need to sign up for an API key (see below for details).
require open-uri require exml/document require cgi FLICKR_API_KEY = Your API key here
The first method, flickr_call, sends a generic query to Flickrs REST web service. It doesn do anything special: it just makes an HTTP GET request and parses the XML response.[5]
[5] Some of Flickrs APIs let you do things like upload photos and add comments. Youll need to use POST requests to make these calls, since they modify the state of the site. More importantly, youll also need to authenticate against your Flickr account.
def flickr_call(method_name, arg_map={}.freeze) args = arg_map.collect {|k,v| CGI.escape(k) + = + CGI.escape(v)}.join(&) url = "http://www.flickr.com/services/rest/?api_key=%s&method=%s&%s" % [FLICKR_API_KEY, method_name, args] doc = REXML::Document.new(open(url).read) end
Now comes pick_a_photo, a method that uses flickr_call to invoke the flickr.photos.search web service method. That method returns a REXML Document object containing a
def pick_a_photo(tag) doc = flickr_call(flickr.photos.search, ags => tag, license => 4, per_page => 1) photo = REXML::XPath.first(doc, //photo) small_photo_url(photo) if photo end
Finally, Ill define the method, small_photo_url. Given a
def small_photo_url(photo) server, id, secret = [server, id, secret].collect do |field| photo.attribute(field) end "http://static. flickr.com/#{server}/#{id}_#{secret}_m.jpg" end
Now I can find an appropriate photo for any common word (Figure 16-1):
pick_a_photo(elephants) # => http://static. flickr.com/32/102580480_506d5865d0_m.jpg pick_a_photo(what-will-happen-tomorrow) # => nil
Its nice if theres a predefined Ruby binding available for a particular REST-style web service, but its usually pretty easy to roll your own. All you need to do is to craft an HTTP request and figure out how to process the response document. Its usually an XML document, and a well-crafted XPath statement should be enough to grab the data you want.
Note the clause license=4 in pick_a_photos arguments to flickr_call. I wanted to find a picture that I could publish in this book, so I limited my search to pictures made available under a Creative Commons "Attribution" license. I can reproduce that picture of the elephants so long as I credit the person who took the photo. (Nick Scott-Smith of London. Hi, Nick!)
Flickr has a separate API call that lists the available licenses (flickr.licenses.getInfo), but once I looked them up and found that "Creative Commons Attribution" was number four, it was easier to hardcode the number than to look it up every time.
Strings
Numbers
Date and Time
Arrays
Hashes
Files and Directories
Code Blocks and Iteration
Objects and Classes8
Modules and Namespaces
Reflection and Metaprogramming
XML and HTML
Graphics and Other File Formats
Databases and Persistence
Internet Services
Web Development Ruby on Rails
Web Services and Distributed Programming
Testing, Debugging, Optimizing, and Documenting
Packaging and Distributing Software
Automating Tasks with Rake
Multitasking and Multithreading
User Interface
Extending Ruby with Other Languages
System Administration