Tuesday, March 08, 2005

WSGI Wiki Application

For my WSGI talk at the Sydney Python Meetup I decided that showing a simple "hello world" or echo WSGI application would not hammer home why WSGI is so good. So I decided to create a WSGI wiki app. Also to show what is needed to convert an existing Python CGI script I decided to base it on Ian Bicking's CGI wiki in the Web Framework Shootout. So after about 80 minutes work this is what I came up with and was able to run under isapi_wsgi. It still needs some final touches but it works.

import cgi, os
import cgitb; cgitb.enable()
import Wiki


# There's several different actions that may occur -- we
# may just display the page, we may edit it, save the edits
# that were submitted, or show a preview. We define each of
# these as a function:

def printPage(page):
pp = []
if not page.exists():
pp.append("This page does not yet exist. Create it:")
pp.append(printEdit(page))
else:
pp.append(page.html)
pp.append('<hr noshade>')
pp.append('<a href="%s?edit=yes">Edit this page</a>' % page.name)
return "".join(pp)

def printEdit(page, text=None):
# The text argument is used in previews -- you want the
# textarea to be loaded with the same text they submitted.
pe = []
if text is None:
# This isn't a preview, so we get the page's text.
text = page.text
pe.append('<h1>Edit %s</h1>' % page.title)
pe.append('<form action="%s" method="POST">' % page.name)
pe.append('<textarea name="text" rows=10 cols=50 style="width: 90%%">' '%s</textarea><br>' % cgi.escape(text))
pe.append('<input type="submit" name="save" value="Save">')
pe.append('<input type="submit" name="preview" value="Preview">')
pe.append('</form>')
return "".join(pe)

def printSave(page, form):
ps = []
page.text = form['text'].value
ps.append(printPage(page))
return "".join(ps)

def printPreview(page, form):
ps = []
ps.append('<h1>Preview %s</h1>' % page.title)
ps.append(page.preview(form['text'].value))
ps.append('<hr noshade>')
ps.append(printEdit(page, form['text'].value))
return "".join(ps)

def application(environ, start_response):
# PATH_INFO contains the portion of the URL that comes after
# script name. For all actions, this is the page we are using.
pagename = environ['PATH_INFO'][1:]
if len(pagename) == 0:
pagename = "frontpage"
page = Wiki.WikiPage(pagename)
form = cgi.FieldStorage(fp=environ['wsgi.input'],environ=environ)
start_response('200 OK', [('Content-type','text/html')])
response = []
response.append("<html><head><title>%s</title>" % page.title)
response.append(page.css)
response.append("</head><body>")
# Here we use fields to determine what action we should take:
# edit, save, preview, or display
if form.has_key('edit'):
response.append(printEdit(page))
elif form.has_key('save'):
response.append(printSave(page, form))
elif form.has_key('preview'):
response.append(printPreview(page, form))
else:
response.append("<h1>%s</h1>" % page.title)
response.append(printPage(page))
response.append("</body></html>")
return response

No comments: