# 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()