Mercurial > hg > commentator
view commentator/middleware.py @ 5:451169e51935
work to make cache expiry work
author | k0s <k0scist@gmail.com> |
---|---|
date | Fri, 26 Feb 2010 12:27:25 -0500 |
parents | d0d8524d9495 |
children |
line wrap: on
line source
""" request dispatcher: data persisting across requests should go here """ import os import re import time from handlers import PostComment #from model import CouchComments from model import PickleComments from genshi.template import TemplateLoader from lxml import etree from lxmlmiddleware import LXMLMiddleware from paste.fileapp import FileApp from pkg_resources import resource_filename from string import Template from webob import Request, Response, exc class LaxTemplate(Template): idpattern = r'[_a-z0-9]+' class Commentator(LXMLMiddleware): ### class level variables defaults = { 'auto_reload': 'False', 'database': 'commentator', 'date_format': '%H:%M %m/%d/%Y', 'template_dirs': '', 'pattern': '.*', 'path': 'html', 'url': '.comment', 'template': 'comment.html' } 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.auto_reload = self.auto_reload.lower() == 'true' # request handlers self.handlers = [ PostComment ] # template loader self.template_dirs = self.template_dirs.split() self.template_dirs.append(resource_filename(__name__, 'templates')) self.loader = TemplateLoader(self.template_dirs, auto_reload=self.auto_reload) # URL,path assert '#' in self.pattern self.url_pattern, self.xpath_pattern = self.pattern.split('#', 1) assert '->' in self.xpath_pattern self.xpath_pattern, self.mapping = [i.strip() for i in self.xpath_pattern.split('->')] # string template for URL substitution self.mapping = LaxTemplate(self.mapping) # backend: comment storage self.model = PickleComments(self.database) def __call__(self, environ, start_response): # get a request object request = Request(environ) # get the path path = request.path_info.strip('/').split('/') if path == ['']: path = [] request.environ['path'] = path # XXX save the path; not sure why i need to do this environ['commentator.path_info'] = request.path_info # match the request to a handler for h in self.handlers: handler = h.match(self, request) if handler is not None: break else: return LXMLMiddleware.__call__(self, environ, start_response) # get response res = handler() return res(environ, start_response) def manipulate(self, request, response, tree): url_match = re.match(self.url_pattern, request.environ['commentator.path_info']) if not url_match: return tree # make string template of the groups groups_dict = dict([(str(index+1), value) for index, value in enumerate(url_match.groups())]) last_modified = None commentable = False for element in tree.findall(self.xpath_pattern): commentable = True # get url str_dict = groups_dict.copy() for key in element.keys(): str_dict[key] = element.get(key) uri = self.mapping.substitute(str_dict) # genshi data data = {} data['comments'] = self.model.comments(uri) if data['comments']: _last_modified = data['comments'][-1]['date'] if last_modified is None: last_modified = _last_modified else: last_modified = max(last_modified, _last_modified) data['action'] = '%s/%s' % (uri, self.url) data['date_format'] = self.date_format data['request'] = request # render template template = self.loader.load(self.template) comments = template.generate(**data).render() comments = etree.fromstring(comments) element.append(comments) if commentable: response.cache_expires(0) if last_modified: # there are comments page_age = time.mktime(response.last_modified.timetuple()) comments_age = time.mktime(last_modified.timetuple()) if comments_age > page_age: response.last_modified = comments_age return tree