thirdparty/google_appengine/lib/webob/docs/wiki-example-code/example.py
changeset 109 620f9b141567
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/thirdparty/google_appengine/lib/webob/docs/wiki-example-code/example.py	Tue Aug 26 21:49:54 2008 +0000
@@ -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'