#!/usr/bin/python -u """critter.cgi A web service for generating critters. Requires the Python Imaging Library """ __author__ = "Joe Gregorio (joe@bitworking.org)" __copyright__ = "Copyright 2007, Joe Gregorio" __contributors__ = [] __version__ = "1.0.0 $Rev: $" __license__ = "MIT" __history__ = """ """ import cgi import cgitb import sys import os import time cgitb.enable() import Image, ImageDraw, ImageFile import StringIO import urllib import sha def etag(critterid): file_version = os.stat(sys.argv[0]).st_mtime etag = sha.sha(critterid) etag.update(str(file_version)) return '"%s"' % etag.hexdigest() sizename = { "small": "-smaller", "medium": "-small", "large": "" } def compose(foot, face, hair, eyes, mouth, size): size = sizename[size] f = Image.open("foot%0d%s.png" % (foot, size)) a = Image.open("face%0d%s.png" % (face, size)) h = Image.open("hair%0d%s.png" % (hair, size)) e = Image.open("eyes%0d%s.png" % (eyes, size)) m = Image.open("mouth%0d%s.png" % (mouth, size)) f.paste(a, (0,0), a) f.paste(h, (0,0), h) f.paste(e, (0,0), e) f.paste(m, (0,0), m) out = StringIO.StringIO() f.save(out, "PNG") return out.getvalue() def not_modified(): print "Status: 304 Not Modified" print "" sys.exit() def ok(critterid): print "Status: 200 Ok" print "Content-type: image/png" #print "Vary: Accept-Encoding" print 'ETag: %s' % etag(critterid) print "" def error(status="Status: 400 Bad Request"): print "Content-type: image/png" print "X-Other: testing" print status print "" sys.exit() if not os.environ['REQUEST_METHOD'] in ['GET', 'HEAD']: error("Status: 405 Method Not Allowed") if_none_match = os.environ.get('HTTP_IF_NONE_MATCH', '') query = cgi.parse_qs(os.environ.get('QUERY_STRING', '')) size = query.get('size', ['medium'])[0] #f = open("log", "w+") #f.write(repr(size)) #f.write("\n") #f.close() if size not in ['small', 'medium', 'large']: size = 'medium' hash = sha.sha(os.environ.get('PATH_INFO', '1')).hexdigest() critterparts = [(int(hash[i], 16) % 8) + 1 for i in range(5)] critterparts.append(size) critterid = "".join([str(n) for n in critterparts]) if if_none_match and etag(critterid) == if_none_match: not_modified() image_data = compose(*critterparts) ok(critterid) sys.stdout.write(image_data)