Mercurial > hg > commentator
annotate 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 |
rev | line source |
---|---|
0 | 1 """ |
2 request dispatcher: | |
3 data persisting across requests should go here | |
4 """ | |
5 | |
6 import os | |
7 import re | |
5 | 8 import time |
0 | 9 |
10 from handlers import PostComment | |
2
689b9d928dc8
add date, reflect api change of lxmlmiddleware
k0s <k0scist@gmail.com>
parents:
0
diff
changeset
|
11 #from model import CouchComments |
689b9d928dc8
add date, reflect api change of lxmlmiddleware
k0s <k0scist@gmail.com>
parents:
0
diff
changeset
|
12 from model import PickleComments |
0 | 13 from genshi.template import TemplateLoader |
14 from lxml import etree | |
15 from lxmlmiddleware import LXMLMiddleware | |
16 from paste.fileapp import FileApp | |
17 from pkg_resources import resource_filename | |
18 from string import Template | |
19 from webob import Request, Response, exc | |
20 | |
21 class LaxTemplate(Template): | |
22 idpattern = r'[_a-z0-9]+' | |
23 | |
24 class Commentator(LXMLMiddleware): | |
25 | |
26 ### class level variables | |
27 defaults = { 'auto_reload': 'False', | |
28 'database': 'commentator', | |
2
689b9d928dc8
add date, reflect api change of lxmlmiddleware
k0s <k0scist@gmail.com>
parents:
0
diff
changeset
|
29 'date_format': '%H:%M %m/%d/%Y', |
0 | 30 'template_dirs': '', |
31 'pattern': '.*', | |
32 'path': 'html', | |
33 'url': '.comment', | |
34 'template': 'comment.html' } | |
35 | |
36 def __init__(self, app, **kw): | |
37 | |
38 self.app = app | |
39 | |
40 # set instance parameters from kw and defaults | |
41 for key in self.defaults: | |
42 setattr(self, key, kw.get(key, self.defaults[key])) | |
43 self.auto_reload = self.auto_reload.lower() == 'true' | |
44 | |
45 # request handlers | |
46 self.handlers = [ PostComment ] | |
47 | |
48 # template loader | |
49 self.template_dirs = self.template_dirs.split() | |
50 self.template_dirs.append(resource_filename(__name__, 'templates')) | |
51 self.loader = TemplateLoader(self.template_dirs, | |
52 auto_reload=self.auto_reload) | |
53 | |
54 # URL,path | |
55 assert '#' in self.pattern | |
56 self.url_pattern, self.xpath_pattern = self.pattern.split('#', 1) | |
57 assert '->' in self.xpath_pattern | |
58 self.xpath_pattern, self.mapping = [i.strip() for i in self.xpath_pattern.split('->')] | |
59 | |
60 # string template for URL substitution | |
61 self.mapping = LaxTemplate(self.mapping) | |
62 | |
63 # backend: comment storage | |
64 self.model = PickleComments(self.database) | |
65 | |
66 def __call__(self, environ, start_response): | |
67 | |
68 # get a request object | |
69 request = Request(environ) | |
70 | |
71 # get the path | |
72 path = request.path_info.strip('/').split('/') | |
73 if path == ['']: | |
74 path = [] | |
75 request.environ['path'] = path | |
76 | |
5 | 77 # XXX save the path; not sure why i need to do this |
0 | 78 environ['commentator.path_info'] = request.path_info |
79 | |
80 # match the request to a handler | |
81 for h in self.handlers: | |
82 handler = h.match(self, request) | |
83 if handler is not None: | |
84 break | |
85 else: | |
86 return LXMLMiddleware.__call__(self, environ, start_response) | |
87 | |
88 # get response | |
89 res = handler() | |
90 return res(environ, start_response) | |
91 | |
2
689b9d928dc8
add date, reflect api change of lxmlmiddleware
k0s <k0scist@gmail.com>
parents:
0
diff
changeset
|
92 def manipulate(self, request, response, tree): |
689b9d928dc8
add date, reflect api change of lxmlmiddleware
k0s <k0scist@gmail.com>
parents:
0
diff
changeset
|
93 url_match = re.match(self.url_pattern, request.environ['commentator.path_info']) |
0 | 94 if not url_match: |
95 return tree | |
96 | |
97 # make string template of the groups | |
98 groups_dict = dict([(str(index+1), value) | |
99 for index, value in enumerate(url_match.groups())]) | |
100 | |
3
d0d8524d9495
finish basic API...still doesnt expire results correctly
k0s <k0scist@gmail.com>
parents:
2
diff
changeset
|
101 last_modified = None |
5 | 102 commentable = False |
0 | 103 for element in tree.findall(self.xpath_pattern): |
5 | 104 commentable = True |
0 | 105 |
106 # get url | |
107 str_dict = groups_dict.copy() | |
108 for key in element.keys(): | |
109 str_dict[key] = element.get(key) | |
110 uri = self.mapping.substitute(str_dict) | |
111 | |
112 # genshi data | |
113 data = {} | |
114 data['comments'] = self.model.comments(uri) | |
3
d0d8524d9495
finish basic API...still doesnt expire results correctly
k0s <k0scist@gmail.com>
parents:
2
diff
changeset
|
115 if data['comments']: |
5 | 116 _last_modified = data['comments'][-1]['date'] |
117 if last_modified is None: | |
118 last_modified = _last_modified | |
119 else: | |
120 last_modified = max(last_modified, _last_modified) | |
0 | 121 data['action'] = '%s/%s' % (uri, self.url) |
2
689b9d928dc8
add date, reflect api change of lxmlmiddleware
k0s <k0scist@gmail.com>
parents:
0
diff
changeset
|
122 data['date_format'] = self.date_format |
689b9d928dc8
add date, reflect api change of lxmlmiddleware
k0s <k0scist@gmail.com>
parents:
0
diff
changeset
|
123 data['request'] = request |
0 | 124 |
125 # render template | |
126 template = self.loader.load(self.template) | |
127 comments = template.generate(**data).render() | |
128 comments = etree.fromstring(comments) | |
129 element.append(comments) | |
130 | |
5 | 131 if commentable: |
132 response.cache_expires(0) | |
133 | |
134 if last_modified: # there are comments | |
135 page_age = time.mktime(response.last_modified.timetuple()) | |
136 comments_age = time.mktime(last_modified.timetuple()) | |
137 if comments_age > page_age: | |
138 response.last_modified = comments_age | |
139 | |
0 | 140 return tree |