a simple wiki with web.py

Ran into web.py here, while it was still unreleased and got hooked by the API design and the comment Aaron made here

The third principle is that web.py should, by default, do the right thing by the Web. This means distinguishing between GET and POST properly. It means simple, canonical URLs which synonyms redirect to. It means readable HTML with the proper HTTP headers.

Since then web.py has been released with an initial reaction here – agree with those remarks so don’t need to repeat.

More interesting was hacking something together with it – a very simple wiki which took about 2 hours to get to where it is (below), while reading the docs and tutorial. Note this isn’t pretty code – the HTML in embedded directly, violating Aaron’s principle (didn’t want to have to mess with Cheetah as well), plus my Python skills are not the greatest but perhaps it makes a useful beginners example.

To install and run (Linux) to a file like wiki.py then do the following;

  $ wget http://webpy.org/web.py $ wget http://webpy.org/markdown.py $ mkdir pages $ chmod +x wiki.py $ ./wiki.py 

Then point your browser at http://localhost:8080/page/somepage to get started

The code;

  #!/usr/bin/python  import web from markdown import Markdown import os, time, re, cgi  # For debugging use only web.internalerror = web.debugerror  urls = (     '/', 'WikiPages',     '/page/([a-zA-Z_]+)', 'WikiPage',     '/editor/([a-zA-Z_]+)', 'WikiEditor' )  wikidir = os.path.realpath('./pages')  class WikiPages:         def GET(self):      web.header("Content-Type","text/html; charset=utf-8")       t = re.compile('^[a-zA-Z_]+$')      wikipages = os.listdir(wikidir)         print "<html><head><title>wiki pages</title></head><body>"        print "<h1>Wiki Pages:</h1><ul>"        for wikipage in wikipages:          if os.path.isfile(os.path.join(wikidir, wikipage)) and t.match(wikipage):               print "<li><a href="%(path)s/page/%(page)s">%(page)s</a></li>"                      % {'path':web.ctx.home+web.ctx.path[1:],'page':wikipage}        print "</ul></body></html>"  class WikiPage:        def GET(self, name):        page = os.path.join(wikidir,name)       web.header("Content-Type","text/html; charset=utf-8")       if os.path.exists(page):            print "<html><head><title>%s</title></head><body>" % name             print "<h1>%s</h1>" % name            print "<p>"             print "[<a href="%s">Pages</a>] "                   % (web.ctx.home+"/")          print "[<a href="%s">Edit</a>] "                    % (web.ctx.home+'/editor/'+name)            print "</p>"            print Markdown(open(page).read())           print "</body></html>"        else:           web.ctx.status = '404 Not Found'            print "<html><head><title>Does not exist: %s</title></head><body>" % name             print "<p>Page %s does not yet exist - " % name             print "<a href="%s">Create</a>" % (web.ctx.home+'/editor/'+name)        def POST(self,name):        page = os.path.join(wikidir,name)       if os.path.exists(page):            newpage = page+'.'+time.strftime("%Y%m%d%H%M%S", time.gmtime())           os.rename(page,newpage)         f = open(page, "w")       f.write(web.input(page='').page)        f.close()       web.redirect(web.ctx.home+'/page/'+name)  class WikiEditor:     def GET(self,name):         web.header("Content-Type","text/html; charset=utf-8")       print "<html><head><title>Editing %s</title></head><body>" % name;        print "<h1>Editing: %s</h1>" % name       print "<form method="POST" accept-charset="utf-8" action="%s">"           % (web.ctx.home+'/page/'+name)      print "<textarea name="page" cols="100" rows="20">"       page = os.path.join(wikidir,name)       if os.path.exists(page):            print cgi.escape(open(page).read())         print "</textarea><br><input type="submit" value="Update"></form>"        print "<p><a href="http://daringfireball.net/projects/markdown/syntax">Markdown Syntax</a></p>"         print "</body></html>"     if __name__ == "__main__": web.run(urls) 

Thoughts on the experience some other time, suffice to say I think Aaron is headed in the right direction.

Note I dumped this under PHP as Sitepoint doesn’t (yet) have a Python category and so as this follows on somewhere from here, figured I stick with the PHP theme.

Update: it needs pointing out there are two issues with the code below.

First, the Markdown parser is not designed to escape HTML special chars, hence the web.safemarkdown() function in web.py. In otherwords the code below exposes the risk of XSS exploits.

Second it should do some kind of file locking while writing to wiki pages.


Category: programming Time: 2006-01-06 Views: 1

Related post

iOS development

Android development

Python development

JAVA development

Development language

PHP development

Ruby development


Front-end development


development tools

Open Platform

Javascript development

.NET development

cloud computing


Copyright (C) avrocks.com, All Rights Reserved.

processed in 0.141 (s). 12 q(s)