Sunday, June 6, 2010

Picasaweb & Blogger

I started this blog to play around with Google Data APIspic-stream is auto-generated (almost) from my picasaweb pics.

I usually upload my full-size photographs to picasaweb, the script provided at the end of this blog uses Picasa Web Album data APIs to get the details of the pics and then publishes a smaller sized pic along with some of the EXIF data to blogger using Blogger APIs. A little more details:

Requirements:
  1.  Python 2.5
  2. gdata python client
  3. pyexif
You will need to enter some more details before you can use the code:
  • your gmail id
  • Run the script in a shell - it will prompt for your password
  • blog-id

This script creates a draft post so that you can make any changes you want before hitting the publish button.

I know you can do something similar directly from Picasa client too, but now you have the freedom to display whatever EXIF data you want in the format you want.

#!/usr/bin/python2.5

import gdata.photos.service
import gdata.media
import gdata.geo
import gdata.blogger.client
import gdata.client
import atom.data
import getopt
import getpass
import os
import sys
import time

from gdata import service

class PicasaData(object):

  def  __init__(self, username, pw):
    """ Initializes Picasa data."""
    self.picasa_client = gdata.photos.service.PhotosService()
    self.picasa_client.source = 'API'
    self.picasa_client.ssl = False
    self.picasa_client.email = username
    self.picasa_client.password = pw
    self.picasa_client.ProgrammaticLogin()
    self.photo_name = ''
  
  def GetAlbumName(self):
    """ Get the name of the picasa album""" 
    albums = self.picasa_client.GetUserFeed(user=self.picasa_client.email)
    i = 0
    albumidlist = []
    for album in albums.entry:
      i+=1
      albumidlist.append(album)
      print '%d  %s (%s)' % (i, album.title.text, album.numphotos.text)
     
    album_choice = int(raw_input('Choose Album Name:'))
    self.album = albumidlist[album_choice-1]
    #print 'You choose: %s' %(self.album.title.text)
    return self.album.title.text
        
  def GetPicName(self):
    """ Get the name of the pic for which details are required."""
    i = 0 
    photo_id_list = []
    photos = self.picasa_client.GetFeed(
        '/data/feed/api/user/%s/albumid/%s?kind=photo&imgmax=640u' % 
        (self.picasa_client.email, self.album.gphoto_id.text))
    
    for photo in photos.entry:
      i+=1
      photo_id_list.append(photo)
      print '%d %s:' %(i, photo.title.text)
      
    pic_choice = int(raw_input('Choose Pic Name:'))
    self.photo = photo_id_list[pic_choice-1]
    return self.photo.title.text
    

  def GetPicMetadata(self):
    """ Get Metadata for the chosen pic."""
    
    meta_data = {}
    if self.photo.exif.model:
      camera = self.photo.exif.model.text
    else:
      camera = 'unknown'
      
    src = self.photo.content.src
    first_thumbnail = self.photo.media.thumbnail[0].url
    second_thumbnail = self.photo.media.thumbnail[1].url
    third_thumbnail = self.photo.media.thumbnail[2].url
    distance = self.photo.exif.distance
    if self.photo.exif.exposure:
      exposure = 1/float(self.photo.exif.exposure.text)
    else:
      exposure = 'Unknown' 
    
    if self.photo.exif.focallength:
      focallength = self.photo.exif.focallength.text
    else:
      focallength = 'Unknown'
    
    if self.photo.exif.fstop:      
      aperture = self.photo.exif.fstop.text
    else:
      aperture = 'Unknown'
      
    if self.photo.exif.iso:
      iso = self.photo.exif.iso.text
    else:
      iso = 'Unknown'
      
    if self.photo.exif.time:
      t = float(self.photo.exif.time.text)/1000
      t = str("%s-%s-%s" %(time.gmtime(t).tm_year, time.gmtime(t).tm_mon, time.gmtime(t).tm_mday))
    else:
      t = 'Unknown'
      
    if self.photo.geo:
      location = str(self.photo.geo.Point.pos.text)
    else:
      location = 'Unknown'
    
    meta_data = {'Camera': camera,
                 'Source': src,
                 'Exposure': exposure,
                 'Focallength': focallength,
                 'Aperture': aperture,
                 'ISO': iso,
                 'Time': t,
                 'Coordinates': location}
    return meta_data             
    
class BloggerData:

  def __init__(self, username, pw):
    """Initialize blogger data."""
    
    self.blogger_client = gdata.blogger.client.BloggerClient()
    
    self.blogger_client.service = 'blogger'    
    self.blogger_client.source = 'python script'
    self.blogger_client.account_type = 'GOOGLE'
    self.blogger_client.server = 'www.blogger.com'
    self.blogger_client.email = username
    self.blogger_client.password = pw
    self.blogger_client.ClientLogin(username, pw, self.blogger_client.source)
    
    # Get the blog ID for the first blog.
    self.feed = self.blogger_client.get_blogs()
    self.blog_id = self.feed.entry[0].get_blog_id()
    
  def PrintUserBlogTitles(self):
    
    self.feed = self.blogger_client.get_blogs()  
 
    for entry in self.feed.entry:
      print '%s %s' %(entry.title.text, entry.get_blog_id())
      
  def CreatePost(self, title, content, is_draft):
    blog_id = 'XXX' # Put your blog-id here, it was a 20 digit number for me
    print 'Creating Draft %s' %(title)
    return self.blogger_client.add_post(blog_id, title, content, draft=is_draft)
  
def main():
  username = 'XXX' # Put you gmail id(without '@gmail.com') here
  pw = getpass.unix_getpass("Enter your password:")
  #pw = os.environ['PASSWD']
  
  run_picasa = PicasaData(username, pw)
  album_name = run_picasa.GetAlbumName()
  photo_name = run_picasa.GetPicName()
  meta_data = run_picasa.GetPicMetadata()
  
  blogger_title = photo_name
  blogger_content = """<center><img src="%s"></img></center><br>
                       <div style="text-align: center; font-family: 'Yanone Kaffeesatz';">                      
                       <i>
                          [%s, F %s, 1/%s, ISO:%s, %s]<br>
                          Coordinates: %s
                       </i></div>
                       """ %(meta_data['Source'],
                             meta_data['Camera'],
                             meta_data['Aperture'],
                             meta_data['Exposure'],
                             meta_data['ISO'],
                             meta_data['Time'],
                             meta_data['Coordinates'])
  
  run_blogger = BloggerData(username, pw)
  run_blogger.CreatePost(blogger_title, blogger_content, True)

if __name__ == '__main__':
  main()

1 comment:

Unknown said...

LGTM

Please fix lint errors and submit.