Tuesday, March 27, 2007

Using Python to display a Picasa Web photo album

I came up with this after the picasa gdata feeds came out last Wednesday. The following is a brief overview of how you can use python to interact with picasa web. I will be using django to handle passing to the functions, but they should be usable in any python code.

Edit: decided to try digg


The two main functions we are going to define are album and photo. The first will generate a list of photos to pick from, and the latter will show the enlarged individual photos.

We'll need to include urllib to get the gdata, and define some variable's we'll need later. I also create a small Photo class to hold the important data to pass to the page (in my case the view in django)



The album method should take the album (name or id, it depends how you build the url request to gdata, I use name. I also store the album information in a database on my site. This holds the authkeys i would need for a hidden album. You can store them however you would like.) We would also like to have previous and next buttons on the thumbnail page. the values of start, next, and prev correspond to the start-index value that we will use on the calls to gdata



Now its time to build the url call to gdata. For this example I am sending the authkey in the url. The other method to get a hidden album (or to write to picasa web) is to authenticate using a google account; check back later on how to do this with regular python as well as with the new gdata python library.



We will use the minidom implementation which is fairly lightweight. For a tutorial on minidom check out this <a href="http://developer.yahoo.com/python/python-xml.html">article</a>



After we have all the photos we loop through them grabbing any info we might need.



After we've looped through we have all the data stored that we need:
rows: # of row's we want
cols: # of cols we want
photo_list: list of all important photo data
per_page: how many thumbnails to use in each page (I send this so theres no calculation in my view)
next/prev: indices to the previous and next sets of gdata
start: the current index of gdata
album_id: the album name (or id) that we are using

Now you have to decide how you want to display the data. One option is building up the html from within python and returning it to the browser. The below example is a view for django. It has the general idea of how to work with the data, just a basic layout using a table and a cell for each thumbnail.

First we'll want to loop through each photo and start adding to the table (along with a link to the full sized photo which we'll build later)



Then we check if we should start a new row, and finish off the table



What would an album be without navigation? this is where the prev and next variables come in. We use them to pass to our album function to get the previous and next sets of gdata:



This concludes the core functionality our gallery will have. But... its a little boring. Want to make the images fade as they load? Yes, yes you do. There are MANY javascript techniques, libraries, modules, etc, for transition and animation effects. I've chosen to go with YUI (yahoo!) because it's examples are really good and it has a strong user base. Yahoo also hosts compressed versions of the script files. We'll need to include yahoo-dom-event and animation. Include these in the head of your page.



Now in order to have access to the thumbnails we must give them an ID. I've wrapped them in a div below. The id should be unique so they can fade in on their own as they load. I've used a built in django property forloop.counter that does the equivalent of looping through a for loop and keeping track of 'i'. My div's will have an id of thumb1, thumb2, thumb3, etc



And finally some javascript at the bottom of the page. There are two parts to this. The first, sets the opacity of all the images to 0. The second is called when the image finishes loading and fades in the image.



And now the thumbnail page is done. On to the full sized images!

The photo function is done in a similar manner to the album function. It uses the same gdata call. There is a separate call you can make that is specifically for dealing with a single image. I chose to use this call because I was already keeping track of the indices within the album gdata feed. In this function call, album_id is the same, start is still where the gdata call for the page that the photo is on came from, inc is the difference between the start and the current image's index. (calculated during the for loop in the view (so start + inc = photo's index in the gdata stream).

So the first step is to grab the gdata



Then we load the gdata into a minidom object



The next step depends on how big you want to show the photo. If you want to show them at a width of 800 like I do, then you have to change the URL a little. Google doesn't seem to like direct linking to photos from other domains, but if you dig into the urls that the 'add to blog' widget uses, you can manipulate the url you have in the gdata. We need to insert the folder 's800' near the end of the url:



Then throw in some logic for the prev / next links to cycle between full sized photos



And we have all the info we need to display: url of full sized image, prev next buttons, the album id, and a way to link back to the page the thumbnail was on


To the view!

We will again be using YUI to fade in the image so we can include the javascript files from the start. Then the image itself:



And last but not least, the navigation for this page:



And the same javascript from before



We also could have included more info on the photo, this was just a start.

I hope this helps people use picasa web before a module for it gets added to the new python gdata library.
Edit: Example