try: from mod_python import apache, util except ImportError: from dummy import apache, util import py from base import handler_decorator class thumbnail(handler_decorator): """generate and return a thumbnail for an image""" def __init__(self, size, condition=lambda r: 'thumbnail' in r.path_info.split('/')): self.size = size self.condition = condition def handler(self, orghandler, request): from mimetypes import guess_type # load the original data (maybe from cache) # see if they want a thumbnail if not self.condition(request): return orghandler(request) fpath = py.path.local(request.filename) cached = self.get_cached(request) if cached is not None: request.content_type = guess_type(fpath.basename)[0] return cached data = orghandler(request) if (not request.content_type.startswith('image/') or type(data) not in [str, unicode]): return data tdata = self.create_thumbnail(fpath, data, request.content_type) self.cache(fpath, tdata) return tdata def create_thumbnail(self, fpath, data, itype): from PIL import Image from StringIO import StringIO image = Image.open(StringIO(data)) image.thumbnail((self.size, self.size), Image.ANTIALIAS) s = StringIO() image.save(s, itype.split('/')[1]) return s.getvalue() # XXX should lock here, not thread-safe!!! def get_cached(self, request): fpath = py.path.local(request.filename) cpath = self.create_cachepath(fpath) tdata = None if not cpath.check() or cpath.mtime() < fpath.mtime(): return None return cpath.read() def create_cachepath(self, fpath): return fpath.dirpath() / ('.thumbnail_%s' % (fpath.basename,)) def cache(self, fpath, data): cpath = self.create_cachepath(fpath) cpath.write(data)