Importing your Flickr photos with Django
Friday, February 6th 2009 — Programming, Python, Django
Recently, I made my blog import updates from Flickr automatically. Since this is a pretty neat feature that is nice to have on your blog, I figured I'd share my code with you. There are a few prerequisites to using this code:
- Your blog needs to be built using the Django framework.
- You need a Flickr account and a Flickr API key.
- You need the Python Flickr API.
Additionally, you need Python programming experience and a basic understanding of the Django framework.
First of all, let's go through what my blog models look like.
class Entry(models.Model):
title = models.CharField(max_length=50)
slug = models.SlugField(max_length=50, unique_for_date='published')
published = models.DateTimeField(auto_now_add=True)
tags = models.ManyToManyField('Tag')
content = models.TextField()
class Meta:
get_latest_by = 'published'
ordering = ['-published']
verbose_name_plural = 'entries'
def __unicode__(self):
return self.title
def get_absolute_url(self):
return '/%s/%s' % (self.published.strftime('%Y/%m/%d'), self.slug)
class Tag(models.Model):
name = models.CharField(max_length=30, unique=True)
display_name = models.CharField(max_length=50)
def __unicode__(self):
return self.display_name
def get_absolute_url(self):
return '/tagged/%s' % self.name
As you can see, they're pretty straight-forward, and shouldn't be too dissimilar to your blog models. Now, let's go through the code that does the actual work!
The following code is basically just a function that will request all the recent photos of a user (specified in your settings.py file, see further below.) The photos that have not been added to your blog will be added automatically as a blog entry. I call the function whenever the front page is requested, at a maximum rate of once per hour (I used the cache module to store a global variable for one hour and only fetched the images when the variable didn't exist.)
I'm assuming you have some Python and Django experience, so the code shouldn't be too hard to customize. Feel free to contact me if you have any questions.
from datetime import datetime
from django.utils.dateformat import format
from django.utils.html import escape
from blixt import settings
from blixt.blog.models import Entry, Tag
import flickrapi
def sync_flickr():
flickr = flickrapi.FlickrAPI(settings.FLICKR_API_KEY)
cur_date = None
entry = None
page = 1
pages = 1
# Get/create a tag to use for Flickr update entries.
tag, created = Tag.objects.get_or_create(
name='photo', display_name='Photography')
# Try to get the most recent Flickr update entry.
try:
flickr_updates = Entry.objects.filter(slug='flickr-update')
most_recent = flickr_updates[0].published
except:
most_recent = None
# Start a loop that will get all public photos of the user specified in the
# settings.
while page <= pages:
res = flickr.people_getPublicPhotos(user_id=settings.FLICKR_USER_ID,
extras='date_upload',
per_page=10, page=page)
page += 1
pages = int(res.find('photos').get('pages'))
# Get all <photo> elements and handle them one by one.
photos = res.findall('photos/photo')
for photo in photos:
# Determine the date/time that the current photo was uploaded.
photo_uploaded = datetime.fromtimestamp(
int(photo.get('dateupload')))
# If the most recently added entry is more recent than the current
# photo, there is no need to continue because all older photos have
# already been added.
if most_recent and photo_uploaded <= most_recent:
pages = 0
break
# Create a new entry for every unique upload date.
if photo_uploaded.date() != cur_date:
if entry: entry.save()
cur_date = photo_uploaded.date()
entry = Entry(
title=format(photo_uploaded, r'\F\l\i\c\k\r: M j, Y'),
slug='flickr-update',
content='')
entry.save()
entry.published = photo_uploaded
entry.tags = [tag]
# Build the HTML content for the entry.
entry.content += settings.FLICKR_IMAGE_HTML % {
'src': settings.FLICKR_IMAGE_SRC % photo.attrib,
'title': escape(photo.get('title')),
'url': settings.FLICKR_IMAGE_URL % photo.attrib
}
if entry: entry.save()
The following code is a snippet from my settings.py file. You'll need to replace the API key and user ID values with your own. You can customize the HTML of the generated blog entry here as well.
FLICKR_API_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' FLICKR_USER_ID = '12345678@N00' FLICKR_IMAGE_HTML = \ '<div class="thumb"><p class="image"><a href="%(url)s" title="%(title)s">' \ '<img src="%(src)s" width="75" height="75" alt="%(title)s" /></a></p>' \ '<p class="title"><a href="%(url)s" title="%(title)s">%(title)s</a></p></div>' FLICKR_IMAGE_SRC = \ 'http://farm%(farm)s.static.flickr.com/%(server)s/%(id)s_%(secret)s_s.jpg' FLICKR_IMAGE_URL = 'http://www.flickr.com/photos/%(owner)s/%(id)s'
Comment by otBSite
Added at 22:03 on Wednesday, April 14th 2010
HDmjJciv