# Simple wiki script for Google App Engine
#
# Author: r0c rocsegg@gmail.com
#
from google.appengine.ext import webapp
from google.appengine.api import users
from google.appengine.ext import db
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.template import Template, Context
from os import path
import wsgiref.handlers
import re
import cgi
_PAT_WIKINAME = re.compile(r'([A-Z][a-z]*)+$')
def validate_wikiname(wikiname):
"""Check a wikiname """
m = _PAT_WIKINAME.match(wikiname)
return bool(m)
def make_wikilink(content, wikinames):
"""Translate wikinames to links in the content text."""
wikinames = sorted(wikinames, lambda x, y: cmp(len(y), len(x)))
link_str = '{{ wn.%d }}'
for i, wn in enumerate(wikinames):
content = content.replace(wn, link_str % (i, i))
content = content.replace('\n', '
')
result = Template(content).render(Context({'wn': wikinames}))
return result
def render_to_response(response, template_name, context):
tmpl = path.join(path.dirname(__file__), template_name)
response.out.write(template.render(tmpl, context))
### Model
class Page(db.Model):
wikiname = db.StringProperty(multiline=False)
content = db.TextProperty()
updated_date = db.DateTimeProperty(auto_now=True)
created_date = db.DateTimeProperty(auto_now_add=True)
### Handlers
class RootHandler(webapp.RequestHandler):
def get(self):
self.redirect('/list/')
class ListHandler(webapp.RequestHandler):
def get(self):
query = Page.all()
items = []
for page in query:
url = '/'.join([self.request.host_url,
'read',
page.wikiname])
title = page.wikiname
updated = page.updated_date
created = page.created_date
items.append({
'title': page.wikiname,
'link': url,
'updated': updated,
'created': created
})
host_url = self.request.host_url
values = {
'title': 'All Pages',
'items': items,
}
render_to_response(self.response, 'list.html', values)
class ReadHandler(webapp.RequestHandler):
def get(self):
wikiname = path.basename(self.request.path)
query = Page.all().filter('wikiname =', wikiname)
page = query.get()
if not page:
self.redirect('/')
# Processes wiki-markup
pages = Page.all()
wikinames = []
for p in pages:
wikinames.append(p.wikiname)
content = make_wikilink(page.content, wikinames)
values = {
'title': page.wikiname,
'wikiname': page.wikiname,
'content': content,
'updated_date': page.updated_date,
'created_date': page.created_date,
}
render_to_response(self.response, 'read.html', values)
class UpdateHandler(webapp.RequestHandler):
""" Boundd to /update/.* """
def get(self):
wikiname = path.basename(self.request.path)
query = Page.all().filter("wikiname = ", wikiname)
page = query.get()
if not page:
self.redirect('/')
values = {
'title': "Update " + page.wikiname,
'wikiname': page.wikiname,
'content': page.content
}
render_to_response(self.response, 'update.html', values)
def post(self):
wikiname = path.basename(self.request.path)
content = self.request.get('content')
query = Page().all().filter("wikiname = ", wikiname)
page = query.get()
if not page:
self.redirect('/')
page.wikiname = wikiname
page.content = cgi.escape(content)
page.put()
self.redirect('/read/' + wikiname)
class CreateHandler(webapp.RequestHandler):
def get(self):
values = {'title': "New Page"}
render_to_response(self.response, 'create.html', values)
def post(self):
wikiname = self.request.get('wikiname')
content = self.request.get('content')
if validate_wikiname(wikiname):
page = Page()
page.wikiname = wikiname
page.content = cgi.escape(content)
page.put()
self.redirect('/read/' + wikiname)
else:
values = {
'title': "New Page : Error",
'error_wikiname': True,
'wikiname': wikiname,
'content': content
}
render_to_response(self.response, 'create.html', values)
class DeleteHandler(webapp.RequestHandler):
def get(self):
wikiname = path.basename(self.request.path)
values = {
'title': "Delete",
'wikiname': wikiname
}
render_to_response(self.response, 'delete.html', values)
def post(self):
wikiname = path.basename(self.request.path)
ok = self.request.get('ok')
if ok:
query = Page.all().filter('wikiname = ', wikiname)
page = query.get()
if page:
page.delete()
self.redirect('/')
else:
self.redirect('/read/' + wikiname)
### URL Mapping
url_map = [('/', RootHandler),
('/list/', ListHandler),
('/read/.*', ReadHandler),
('/update/.*', UpdateHandler),
('/create/', CreateHandler),
('/delete/.*', DeleteHandler)]
application = webapp.WSGIApplication(url_map, debug=True)
def _main():
wsgiref.handlers.CGIHandler().run(application)
if __name__ == '__main__':
_main()