summaryrefslogtreecommitdiffstats
path: root/google_appengine/lib/webob/docs/wiki-example-code/example.py
diff options
context:
space:
mode:
Diffstat (limited to 'google_appengine/lib/webob/docs/wiki-example-code/example.py')
-rwxr-xr-xgoogle_appengine/lib/webob/docs/wiki-example-code/example.py200
1 files changed, 200 insertions, 0 deletions
diff --git a/google_appengine/lib/webob/docs/wiki-example-code/example.py b/google_appengine/lib/webob/docs/wiki-example-code/example.py
new file mode 100755
index 0000000..c76ffa7
--- /dev/null
+++ b/google_appengine/lib/webob/docs/wiki-example-code/example.py
@@ -0,0 +1,200 @@
+import os
+import re
+from webob import Request, Response
+from webob import exc
+from tempita import HTMLTemplate
+
+VIEW_TEMPLATE = HTMLTemplate("""\
+<html>
+ <head>
+ <title>{{page.title}}</title>
+ </head>
+ <body>
+<h1>{{page.title}}</h1>
+{{if message}}
+<div style="background-color: #99f">{{message}}</div>
+{{endif}}
+
+<div>{{page.content|html}}</div>
+
+<hr>
+<a href="{{req.url}}?action=edit">Edit</a>
+ </body>
+</html>
+""")
+
+EDIT_TEMPLATE = HTMLTemplate("""\
+<html>
+ <head>
+ <title>Edit: {{page.title}}</title>
+ </head>
+ <body>
+{{if page.exists}}
+<h1>Edit: {{page.title}}</h1>
+{{else}}
+<h1>Create: {{page.title}}</h1>
+{{endif}}
+
+<form action="{{req.path_url}}" method="POST">
+ <input type="hidden" name="mtime" value="{{page.mtime}}">
+ Title: <input type="text" name="title" style="width: 70%" value="{{page.title}}"><br>
+ Content: <input type="submit" value="Save">
+ <a href="{{req.path_url}}">Cancel</a>
+ <br>
+ <textarea name="content" style="width: 100%; height: 75%" rows="40">{{page.content}}</textarea>
+ <br>
+ <input type="submit" value="Save">
+ <a href="{{req.path_url}}">Cancel</a>
+</form>
+</body></html>
+""")
+
+class WikiApp(object):
+
+ view_template = VIEW_TEMPLATE
+ edit_template = EDIT_TEMPLATE
+
+ def __init__(self, storage_dir):
+ self.storage_dir = os.path.abspath(os.path.normpath(storage_dir))
+
+ def __call__(self, environ, start_response):
+ req = Request(environ)
+ action = req.params.get('action', 'view')
+ page = self.get_page(req.path_info)
+ try:
+ try:
+ meth = getattr(self, 'action_%s_%s' % (action, req.method))
+ except AttributeError:
+ raise exc.HTTPBadRequest('No such action %r' % action).exception
+ resp = meth(req, page)
+ except exc.HTTPException, e:
+ resp = e
+ return resp(environ, start_response)
+
+ def get_page(self, path):
+ path = path.lstrip('/')
+ if not path:
+ path = 'index'
+ path = os.path.join(self.storage_dir)
+ path = os.path.normpath(path)
+ if path.endswith('/'):
+ path += 'index'
+ if not path.startswith(self.storage_dir):
+ raise exc.HTTPBadRequest("Bad path").exception
+ path += '.html'
+ return Page(path)
+
+ def action_view_GET(self, req, page):
+ if not page.exists:
+ return exc.HTTPTemporaryRedirect(
+ location=req.url + '?action=edit')
+ if req.cookies.get('message'):
+ message = req.cookies['message']
+ else:
+ message = None
+ text = self.view_template.substitute(
+ page=page, req=req, message=message)
+ resp = Response(text)
+ if message:
+ resp.delete_cookie('message')
+ else:
+ resp.last_modified = page.mtime
+ resp.conditional_response = True
+ return resp
+
+ def action_view_POST(self, req, page):
+ submit_mtime = int(req.params.get('mtime') or '0') or None
+ if page.mtime != submit_mtime:
+ return exc.HTTPPreconditionFailed(
+ "The page has been updated since you started editing it")
+ page.set(
+ title=req.params['title'],
+ content=req.params['content'])
+ resp = exc.HTTPSeeOther(
+ location=req.path_url)
+ resp.set_cookie('message', 'Page updated')
+ return resp
+
+ def action_edit_GET(self, req, page):
+ text = self.edit_template.substitute(
+ page=page, req=req)
+ return Response(text)
+
+class Page(object):
+ def __init__(self, filename):
+ self.filename = filename
+
+ @property
+ def exists(self):
+ return os.path.exists(self.filename)
+
+ @property
+ def title(self):
+ if not self.exists:
+ # we need to guess the title
+ basename = os.path.splitext(os.path.basename(self.filename))[0]
+ basename = re.sub(r'[_-]', ' ', basename)
+ return basename.capitalize()
+ content = self.full_content
+ match = re.search(r'<title>(.*?)</title>', content, re.I|re.S)
+ return match.group(1)
+
+ @property
+ def full_content(self):
+ f = open(self.filename, 'rb')
+ try:
+ return f.read()
+ finally:
+ f.close()
+
+ @property
+ def content(self):
+ if not self.exists:
+ return ''
+ content = self.full_content
+ match = re.search(r'<body[^>]*>(.*?)</body>', content, re.I|re.S)
+ return match.group(1)
+
+ @property
+ def mtime(self):
+ if not self.exists:
+ return None
+ else:
+ return os.stat(self.filename).st_mtime
+
+ def set(self, title, content):
+ dir = os.path.dirname(self.filename)
+ if not os.path.exists(dir):
+ os.makedirs(dir)
+ new_content = """<html><head><title>%s</title></head><body>%s</body></html>""" % (
+ title, content)
+ f = open(self.filename, 'wb')
+ f.write(new_content)
+ f.close()
+
+if __name__ == '__main__':
+ import optparse
+ parser = optparse.OptionParser(
+ usage='%prog --port=PORT'
+ )
+ parser.add_option(
+ '-p', '--port',
+ default='8080',
+ dest='port',
+ type='int',
+ help='Port to serve on (default 8080)')
+ parser.add_option(
+ '--wiki-data',
+ default='./wiki',
+ dest='wiki_data',
+ help='Place to put wiki data into (default ./wiki/)')
+ options, args = parser.parse_args()
+ print 'Writing wiki pages to %s' % options.wiki_data
+ app = WikiApp(options.wiki_data)
+ from wsgiref.simple_server import make_server
+ httpd = make_server('localhost', options.port, app)
+ print 'Serving on http://localhost:%s' % options.port
+ try:
+ httpd.serve_forever()
+ except KeyboardInterrupt:
+ print '^C'