Flickr provides an API for which there are numerous language bindings. A binding for Lisp was, however, missing, and because I wanted to write an application for automating some tasks in Flickr (more on that later on), I decided some time ago to start by implementing bindings to the Flickr API for Common Lisp, aptly named “Clickr”.
Instead of telling you how great my bindings are I think it’s best if I just demonstrate how they work:
Let’s get my Flickr user first and see what my name is:
CL-USER> (defvar *schani* (user-with-name “schani”))
CL-USER> (user-realname *schani*)
How many favorites do I have?
CL-USER> (length (user-favorites *schani*))
Every bit of information that Clickr gets from the API is stored. If you request it again, Clickr will used that stored information instead of making the same API calls again. Also, every Flickr object that Clickr knows about corresponds to exactly one Clickr object. If you get, say, the same photo via two different routes, Clickr will give you the same photo object twice.
Let’s do some more complicated stuff! What’s the number of users whose photos are in my favorites?
CL-USER> (defvar *fav-users* (remove-duplicates (mapcar #’photo-owner (user-favorites *schani*))))
CL-USER> (length *fav-users*)
How many of those have faved at least one of my photos?
CL-USER> (length (remove-if-not #'(lambda (user)
(find-if #'(lambda (photo)
(eq (photo-owner photo) *schani*))
This last query makes a huge number of API calls, so try it at your own risk! The second time you do it, though, it’s lightning fast!
Clickr can even provide you with some information not available through the API:
CL-USER> (photo-num-views (first (user-photos *schani*)))
CL-USER> (photo-num-faves (first (user-photos *schani*)))
I need that information for my little application, and since the Flickr API still doesn’t provide it, Clickr has to fetch the photo page and extract those numbers from the HTML code.
On to my application, which I’ve called “Automatr”! There are lots of groups on Flickr, like top-f or top-v, whose only posting requirements are that your photo fulfills some simple “counting” rule. In the case of top-f the rule is that you can post any image provided that it has at least 25 faves. Being very lazy I wanted a tool that did those posting jobs for me automatically, which is why I wrote Automatr.
Right now Automatr can do five things: Adding and removing tags, adding and removing photos to and from groups and adding photos to sets. Let’s look at the simplest job, adding a tag! Let’s say that I want to add the tag “top-f25″ to all my photos which have at least 25 faves. Here’s the Automatr rule for that:
‘(>= (count faves) 25))
The first argument is just the name of the rule and can be anything. The second argument is the action and the third argument is the condition under which the action is to be applied. Of course Automatr is smart enough not to try to add the tag a second time, so it’s not necessary to specify that only photos without that same tag be tagged.
Groups are more complicated in that they need to be declared first. Here’s the declaration of the top-f group:
The main argument here is the ID of the group. The easiest way to get to it that I know of is to look it up in the HTML source of the group page. Yeah, it sucks. Clickr should be able to do that automatically if you provide it with the group URL, but I was too lazy to implement that. Anyway, the “max-batch” argument specifies how many photos Automatr is allowed to add to that group in one batch. In this case it’s one, meaning that even if I had a hundred photos eligible for entry, Automatr would post only one, determined at random. Here’s the rule for posting photos to top-f:
‘(>= (count faves) 25))
Pretty straightforward. Here’s a more complicated group declaration:
The “max-posted” argument tells Automatr that at any point in time there can be at most 11 photos posted to that group (by the user in question). If Automatr wants to post an additional photo to the group, it has to delete one of the 11 first. The photo to be deleted is, again, chosen at random.
That’s basically it. If you want to play around with Clickr and Automatr yourself, just download it and follow the README file in the package. If you do something with it, I’d love to hear from you!