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