Damjan
gdamjan at mail.net.mk
Tue Sep 21 17:53:26 EDT 2004
I've hacked this last evening (stayed a bit longer that should've). Its an handler that allows modifications of images on the fly, but also cache's the results... its a bit hackish but anyway I'll sahre it here as a demo of mod_python. I enable it with this .htaccess file AcceptPathInfo On AddHandler mod_python .png .py .jpg .jpeg PythonHandler image | .png .jpg .jpeg PythonHandler mptest | .py PythonDebug On PythonOption Cache on PythonOption CacheDir /tmp/cache Ok what exactly the modules does? Say you have e picture at the /images/me.jpg URL Retrieving /images/me.jpg will let Apache handle the request (apache.DECLINED), that way proper caching is allowed etc. But getting /images/me.jpg/size?width=100;height=200 will resize the image with PIL, store the resized image as /tmp/cache/images/me.jpg/size?width=100;height=200 (but only if "Cache on") and send back the resized image to the user. Other methods are also possible, there's also /thumb?... similar to /size? but retains the aspect-ratio of the original. /datemodified returns text/plain content with the data of the last modification of the image file. Other methods could extract other meta info from images, implement other transformations, filters etc... TODO: - more error checking is needed -- damjan | дамјан This is my jabber ID --> damjan at bagra.net.mk <-- not my mail address!!! -------------- next part -------------- # image.py, mod_python handler # adds methods to image files (.png, jpeg, .gif and other supported by PIL) # minimal penalty when no method is used # on error: raise apache.SERVER_RETURN, apache.HTTP_NOT_IMPLEMENTED # # !!! = may throw exception # from mod_python import apache from mod_python import util from os import path import os def handler(req): if not path.exists(req.filename): return apache.HTTP_NOT_FOUND obj = ImageHandler(req) # !!! methodname = 'handle_'+req.path_info[1:] method = getattr(obj, methodname, obj.default) args = util.parse_qs(req.args or '') return method(**args) # !!! class ImageHandler(object): def __init__(self, req): self.req = req self.filename = req.filename config = req.get_options() self.cache_dir = config.get('CacheDir', None) self.usecache = config.get('Cache', 'off').lower() in ('on', 'yes') def handle_thumb(self, **args): # find in cache or make the thumbnail # cache it if needed from PIL import Image key = self.req.unparsed_uri filename = self.getcached(key) if filename: self.req.sendfile(filename) return apache.OK img = Image.open(self.filename) width, height = img.size width = int(args.get('width', args.get('w', (width,) )) [0]) height = int(args.get('height', args.get('h', (height,) )) [0]) img.thumbnail((width, height), resample=Image.ANTIALIAS) img.save(self.req, format=img.format) self.putincache(key, img) return apache.OK def handle_size(self, **args): from PIL import Image key = self.req.unparsed_uri filename = self.getcached(key) if filename: self.req.sendfile(filename) return apache.OK img = Image.open(self.filename) width, height = img.size width = int(args.get('width', args.get('w', (width,) )) [0]) height = int(args.get('height', args.get('h', (height,) )) [0]) i2 = img.resize((width, height), resample=Image.ANTIALIAS) i2.format = img.format i2.save(self.req, format=i2.format) self.putincache(key, i2) return apache.OK def handle_view(self, **args): self.req.sendfile(self.filename) return apache.OK def handle_datemodified(self, **args): import time import locale locale.setlocale(locale.LC_ALL, 'mk_MK.UTF-8') self.req.content_type = 'text/plain' ss=os.stat(self.filename) tt=time.localtime(ss.st_mtime) s=time.strftime('%c', tt) self.req.write(s) return apache.OK def default(self, **args): return apache.DECLINED def getcached(self, key): cached = self.key2filename(key) try: css = os.stat(cached) fss = os.stat(self.filename) except OSError: return None if css.st_mtime < fss.st_mtime: return None return cached def putincache(self, key, img): if not self.usecache: return filename = self.key2filename(key) dirname = path.dirname(filename) if not path.exists(dirname): os.makedirs(dirname) try: fp = file(filename,'w') img.save(fp, img.format) fp.close() except: pass def key2filename(self, key): filename = path.join(self.cache_dir, key[1:]) return filename
|