annotate examples/tutorial/geddit/controller.py @ 1043:a21009a2bc3a trunk

Return correct value and properly namespaced attribute name when matching namespaced attributes with XPath expressions (fixes #572; thanks to Olemis Lang <olemis+trac@gmail.com> for bug report and suggestion for fix).
author hodgestar
date Thu, 20 Mar 2014 12:58:48 +0000
parents fdebe71666ce
children
rev   line source
611
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
1 #!/usr/bin/env python
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
2
628
9822dfff0fd5 GenshiTutorial: tweaks to sync with code on wiki page.
cmlenz
parents: 627
diff changeset
3 import operator, os, pickle, sys
611
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
4
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
5 import cherrypy
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
6 from formencode import Invalid
631
e990fa05d80b GenshiTutorial: implement the XSS section.
cmlenz
parents: 628
diff changeset
7 from genshi.input import HTML
e990fa05d80b GenshiTutorial: implement the XSS section.
cmlenz
parents: 628
diff changeset
8 from genshi.filters import HTMLFormFiller, HTMLSanitizer
611
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
9
619
756e7418e10c GenshiTutorial: various updates to sync with wiki page.
cmlenz
parents: 618
diff changeset
10 from geddit.form import LinkForm, CommentForm
625
abad7c2ebe15 GenshiTutorial: implemented AJAX commenting.
cmlenz
parents: 622
diff changeset
11 from geddit.lib import ajax, template
619
756e7418e10c GenshiTutorial: various updates to sync with wiki page.
cmlenz
parents: 618
diff changeset
12 from geddit.model import Link, Comment
611
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
13
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
14
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
15 class Root(object):
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
16
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
17 def __init__(self, data):
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
18 self.data = data
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
19
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
20 @cherrypy.expose
615
06165fee45ab GenshiTutorial: make URLs dynamic so that the app could theoretically be mounted on some other SCRIPT_NAME.
cmlenz
parents: 613
diff changeset
21 @template.output('index.html')
611
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
22 def index(self):
619
756e7418e10c GenshiTutorial: various updates to sync with wiki page.
cmlenz
parents: 618
diff changeset
23 links = sorted(self.data.values(), key=operator.attrgetter('time'))
756e7418e10c GenshiTutorial: various updates to sync with wiki page.
cmlenz
parents: 618
diff changeset
24 return template.render(links=links)
611
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
25
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
26 @cherrypy.expose
615
06165fee45ab GenshiTutorial: make URLs dynamic so that the app could theoretically be mounted on some other SCRIPT_NAME.
cmlenz
parents: 613
diff changeset
27 @template.output('submit.html')
611
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
28 def submit(self, cancel=False, **data):
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
29 if cherrypy.request.method == 'POST':
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
30 if cancel:
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
31 raise cherrypy.HTTPRedirect('/')
619
756e7418e10c GenshiTutorial: various updates to sync with wiki page.
cmlenz
parents: 618
diff changeset
32 form = LinkForm()
611
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
33 try:
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
34 data = form.to_python(data)
619
756e7418e10c GenshiTutorial: various updates to sync with wiki page.
cmlenz
parents: 618
diff changeset
35 link = Link(**data)
756e7418e10c GenshiTutorial: various updates to sync with wiki page.
cmlenz
parents: 618
diff changeset
36 self.data[link.id] = link
611
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
37 raise cherrypy.HTTPRedirect('/')
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
38 except Invalid, e:
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
39 errors = e.unpack_errors()
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
40 else:
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
41 errors = {}
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
42
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
43 return template.render(errors=errors) | HTMLFormFiller(data=data)
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
44
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
45 @cherrypy.expose
627
3ed77fbfafa8 GenshiTutorial: minor tweaks to sync with Wiki page.
cmlenz
parents: 625
diff changeset
46 @template.output('info.html')
3ed77fbfafa8 GenshiTutorial: minor tweaks to sync with Wiki page.
cmlenz
parents: 625
diff changeset
47 def info(self, id):
3ed77fbfafa8 GenshiTutorial: minor tweaks to sync with Wiki page.
cmlenz
parents: 625
diff changeset
48 link = self.data.get(id)
3ed77fbfafa8 GenshiTutorial: minor tweaks to sync with Wiki page.
cmlenz
parents: 625
diff changeset
49 if not link:
3ed77fbfafa8 GenshiTutorial: minor tweaks to sync with Wiki page.
cmlenz
parents: 625
diff changeset
50 raise cherrypy.NotFound()
3ed77fbfafa8 GenshiTutorial: minor tweaks to sync with Wiki page.
cmlenz
parents: 625
diff changeset
51 return template.render(link=link)
3ed77fbfafa8 GenshiTutorial: minor tweaks to sync with Wiki page.
cmlenz
parents: 625
diff changeset
52
3ed77fbfafa8 GenshiTutorial: minor tweaks to sync with Wiki page.
cmlenz
parents: 625
diff changeset
53 @cherrypy.expose
615
06165fee45ab GenshiTutorial: make URLs dynamic so that the app could theoretically be mounted on some other SCRIPT_NAME.
cmlenz
parents: 613
diff changeset
54 @template.output('comment.html')
622
6780f1b1b20d GenshiTutorial: add Atom feeds.
cmlenz
parents: 619
diff changeset
55 def comment(self, id, cancel=False, **data):
6780f1b1b20d GenshiTutorial: add Atom feeds.
cmlenz
parents: 619
diff changeset
56 link = self.data.get(id)
619
756e7418e10c GenshiTutorial: various updates to sync with wiki page.
cmlenz
parents: 618
diff changeset
57 if not link:
611
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
58 raise cherrypy.NotFound()
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
59 if cherrypy.request.method == 'POST':
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
60 if cancel:
619
756e7418e10c GenshiTutorial: various updates to sync with wiki page.
cmlenz
parents: 618
diff changeset
61 raise cherrypy.HTTPRedirect('/info/%s' % link.id)
611
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
62 form = CommentForm()
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
63 try:
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
64 data = form.to_python(data)
631
e990fa05d80b GenshiTutorial: implement the XSS section.
cmlenz
parents: 628
diff changeset
65 markup = HTML(data['content']) | HTMLSanitizer()
e990fa05d80b GenshiTutorial: implement the XSS section.
cmlenz
parents: 628
diff changeset
66 data['content'] = markup.render('xhtml')
619
756e7418e10c GenshiTutorial: various updates to sync with wiki page.
cmlenz
parents: 618
diff changeset
67 comment = link.add_comment(**data)
625
abad7c2ebe15 GenshiTutorial: implemented AJAX commenting.
cmlenz
parents: 622
diff changeset
68 if not ajax.is_xhr():
abad7c2ebe15 GenshiTutorial: implemented AJAX commenting.
cmlenz
parents: 622
diff changeset
69 raise cherrypy.HTTPRedirect('/info/%s' % link.id)
abad7c2ebe15 GenshiTutorial: implemented AJAX commenting.
cmlenz
parents: 622
diff changeset
70 return template.render('_comment.html', comment=comment,
abad7c2ebe15 GenshiTutorial: implemented AJAX commenting.
cmlenz
parents: 622
diff changeset
71 num=len(link.comments))
611
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
72 except Invalid, e:
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
73 errors = e.unpack_errors()
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
74 else:
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
75 errors = {}
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
76
625
abad7c2ebe15 GenshiTutorial: implemented AJAX commenting.
cmlenz
parents: 622
diff changeset
77 if ajax.is_xhr():
abad7c2ebe15 GenshiTutorial: implemented AJAX commenting.
cmlenz
parents: 622
diff changeset
78 stream = template.render('_form.html', link=link, errors=errors)
abad7c2ebe15 GenshiTutorial: implemented AJAX commenting.
cmlenz
parents: 622
diff changeset
79 else:
abad7c2ebe15 GenshiTutorial: implemented AJAX commenting.
cmlenz
parents: 622
diff changeset
80 stream = template.render(link=link, comment=None, errors=errors)
abad7c2ebe15 GenshiTutorial: implemented AJAX commenting.
cmlenz
parents: 622
diff changeset
81 return stream | HTMLFormFiller(data=data)
611
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
82
628
9822dfff0fd5 GenshiTutorial: tweaks to sync with code on wiki page.
cmlenz
parents: 627
diff changeset
83 @cherrypy.expose
9822dfff0fd5 GenshiTutorial: tweaks to sync with code on wiki page.
cmlenz
parents: 627
diff changeset
84 @template.output('index.xml', method='xml')
9822dfff0fd5 GenshiTutorial: tweaks to sync with code on wiki page.
cmlenz
parents: 627
diff changeset
85 def feed(self, id=None):
9822dfff0fd5 GenshiTutorial: tweaks to sync with code on wiki page.
cmlenz
parents: 627
diff changeset
86 if id:
9822dfff0fd5 GenshiTutorial: tweaks to sync with code on wiki page.
cmlenz
parents: 627
diff changeset
87 link = self.data.get(id)
9822dfff0fd5 GenshiTutorial: tweaks to sync with code on wiki page.
cmlenz
parents: 627
diff changeset
88 if not link:
9822dfff0fd5 GenshiTutorial: tweaks to sync with code on wiki page.
cmlenz
parents: 627
diff changeset
89 raise cherrypy.NotFound()
9822dfff0fd5 GenshiTutorial: tweaks to sync with code on wiki page.
cmlenz
parents: 627
diff changeset
90 return template.render('info.xml', link=link)
9822dfff0fd5 GenshiTutorial: tweaks to sync with code on wiki page.
cmlenz
parents: 627
diff changeset
91 else:
9822dfff0fd5 GenshiTutorial: tweaks to sync with code on wiki page.
cmlenz
parents: 627
diff changeset
92 links = sorted(self.data.values(), key=operator.attrgetter('time'))
9822dfff0fd5 GenshiTutorial: tweaks to sync with code on wiki page.
cmlenz
parents: 627
diff changeset
93 return template.render(links=links)
9822dfff0fd5 GenshiTutorial: tweaks to sync with code on wiki page.
cmlenz
parents: 627
diff changeset
94
611
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
95
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
96 def main(filename):
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
97 # load data from the pickle file, or initialize it to an empty list
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
98 if os.path.exists(filename):
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
99 fileobj = open(filename, 'rb')
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
100 try:
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
101 data = pickle.load(fileobj)
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
102 finally:
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
103 fileobj.close()
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
104 else:
618
b6706f9346ac Simplify the tutorial project: comments are now flat, not hierarchical.
cmlenz
parents: 616
diff changeset
105 data = {}
611
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
106
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
107 def _save_data():
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
108 # save data back to the pickle file
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
109 fileobj = open(filename, 'wb')
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
110 try:
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
111 pickle.dump(data, fileobj)
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
112 finally:
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
113 fileobj.close()
664
fdebe71666ce Fix compatibility of tutorial code with CherryPy 3.1. Closes #159.
cmlenz
parents: 632
diff changeset
114 if hasattr(cherrypy.engine, 'subscribe'): # CherryPy >= 3.1
fdebe71666ce Fix compatibility of tutorial code with CherryPy 3.1. Closes #159.
cmlenz
parents: 632
diff changeset
115 cherrypy.engine.subscribe('stop', _save_data)
fdebe71666ce Fix compatibility of tutorial code with CherryPy 3.1. Closes #159.
cmlenz
parents: 632
diff changeset
116 else:
fdebe71666ce Fix compatibility of tutorial code with CherryPy 3.1. Closes #159.
cmlenz
parents: 632
diff changeset
117 cherrypy.engine.on_stop_engine_list.append(_save_data)
611
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
118
628
9822dfff0fd5 GenshiTutorial: tweaks to sync with code on wiki page.
cmlenz
parents: 627
diff changeset
119 # Some global configuration; note that this could be moved into a
619
756e7418e10c GenshiTutorial: various updates to sync with wiki page.
cmlenz
parents: 618
diff changeset
120 # configuration file
611
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
121 cherrypy.config.update({
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
122 'tools.encode.on': True, 'tools.encode.encoding': 'utf-8',
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
123 'tools.decode.on': True,
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
124 'tools.trailing_slash.on': True,
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
125 'tools.staticdir.root': os.path.abspath(os.path.dirname(__file__)),
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
126 })
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
127
619
756e7418e10c GenshiTutorial: various updates to sync with wiki page.
cmlenz
parents: 618
diff changeset
128 cherrypy.quickstart(Root(data), '/', {
611
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
129 '/media': {
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
130 'tools.staticdir.on': True,
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
131 'tools.staticdir.dir': 'static'
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
132 }
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
133 })
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
134
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
135 if __name__ == '__main__':
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
136 import formencode
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
137 formencode.api.set_stdtranslation(languages=['en'])
236c351928a2 Add current code for GenshiTutorial to the `examples` directory.
cmlenz
parents:
diff changeset
138 main(sys.argv[1])
Copyright (C) 2012-2017 Edgewall Software