Raging Goblin

30 July 2010

Precache script for Zenphoto

Filed under: Zenphoto — Raging Goblin @ 20:37
Tags: , ,

To make my pictures and photo’s available on the web I use Zenphoto. An ideal web-album solution that simply takes a directory and makes this available on the web. By means of a symlink that points from /srv/www/htdocs/zenphoto/albums to my pictures folder, Zenphoto displays all my pictures (note that you have to enable apache to follow symlinks for this). This directory which resides on my home server, is also mounted by nfs (network file system) on /home/_user_/pictures. Now, whenever I add a picture to this folder it will also be available through Zenphoto. The only problem I had was that my homeserver is not that fast and when I want to browse the pictures quickly, it takes ages to load or to generate a cached version. Zenphoto has this feature of precaching, but precaching your photos through the browser involves some extra manual labour which I absolutely despise ;). So I decided to write a little precache script:


import os
import sys
import Image
import time

preCachSize = 25
albumfiles = []
result = []
zenphoto = '/srv/www/htdocs/zenphoto/'
cache = zenphoto + 'cache/'
albums = zenphoto + 'albums/'
small = '_100_thumb.jpg'
big = '_595.jpg'
small_size = 100
big_size = 595

def preCache(original, newSize, append):
	cachedFile = getCachedFileName(original, append)
	dirname = os.path.dirname(cachedFile)
	if not os.path.exists(dirname):
	command = 'convert -auto-orient "' + original + '" -resize "%dx%d" "' + cachedFile + '"'
	command = command % (newSize, newSize)
	print time.asctime() + ' ' + cachedFile
def getCachedFileName(original, append):
		cachedFile = original.replace(albums, cache, 1).replace('.jpg', '', 1).replace('.JPG', '', 1) + append
		return cachedFile
# Add photo's to the list if no small cache exists
for root, subFolders, files in os.walk(albums):
    for file in files:
		albumfile = os.path.join(root, file)
		if not os.path.exists(getCachedFileName(albumfile, small)):
# Only precache jpg
for albumfile in albumfiles:
	if (albumfile.find('jpg')>=0 or albumfile.find('JPG')>=0):

# Just a few		
for uncachedFile in result[0:preCachSize]:
	max_side = max(Image.open(uncachedFile).size)
	if max_side >= big_size:
		preCache(uncachedFile, big_size, big)
	if max_side >= small_size:
		preCache(uncachedFile, small_size, small)

os.system('chown -R wwwrun:www ' + cache)

It is a combination of Python’s os module and the fabulous imagemagick suite. This will precache 25 pictures (only jpg) for which no small thumbnail exists and make a thumbnail and a smaller image for it (all my pictures are shot with the same camera and therefore have the same size). By running the following bash script through a daily cron job, I also have a rudimentary log of the precached images:

/root/scripts/preCache.py >> /var/log/preCacheZenphoto.log

Blog at WordPress.com.