Mercurial > hg > CAPTCHAmiddleware
view captchamiddleware/middleware.py @ 1:478d13061336
include a text input
author | k0s <k0scist@gmail.com> |
---|---|
date | Sat, 06 Feb 2010 19:00:32 -0500 |
parents | 21ec6325ae0e |
children | c861518b2a44 |
line wrap: on
line source
""" CAPTCHA middleware """ import os import random import sys from lxml import etree from lxmlmiddleware import LXMLMiddleware from skimpyGimpy import skimpyAPI from urllib2 import urlopen from webob import Request, exc class CAPTCHAmiddleware(LXMLMiddleware): """ put CAPTCHAs on forms for unauthorized users """ ### class level variables defaults = { 'dictionary': '/usr/share/dict/words', 'error': '<span class="error">Please type the CAPTCHA</span>', 'minimum_length': 5, 'path': "/input[@type='submit']", } def __init__(self, app, **kw): self.app = app # set instance parameters from kw and defaults for key in self.defaults: setattr(self, key, kw.get(key, self.defaults[key])) self.minimum_length = int(self.minimum_length) assert os.path.exists(self.dictionary) # get dictionary if self.dictionary.startswith('http://') or self.dictionary.startswith('https://'): f = urlopen(self.dictionary) else: f = file(self.dictionary) self.words = [ i.strip() for i in f.readlines() if len(i.strip()) > self.minimum_length ] random.shuffle(self.words) def __call__(self, environ, start_response): request = Request(environ) if request.method == 'post' and not request.remote_user: pass # TODO: check CAPTCHA return LXMLMiddleware.__call__(self, environ, start_response) def manipulate(self, environ, tree): """manipulate the DOM; should return an etree._Element""" request = Request(environ) # don't use CAPTCHAs for authorized users if request.remote_user: return tree for element in tree.findall(".//form[@method='post']"): key = random.Random().randint(0, len(self.words)) word = self.words[key] captcha = skimpyAPI.Pre(word).data() string = '<div class="captcha">%s<input type="hidden" value="%s"/><input type="text" name="captcha"/></div>' % (captcha, key) addition = etree.fromstring(string) insertion_point = element.find('.' + self.path) insertion_point.addprevious(addition) return tree