#!/usr/bin/python # -*- coding: utf-8 -*- """A super-minimal but hopefully reliable Wiki server in Python. """ import socket, thread, sys, cgi, pickle, os, errno, urlparse, email.parser, re def main(fname, port): docs = pickle.load(open(fname)) if os.path.exists(fname) else {} s = socket.socket() s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # avoid errno 98 s.bind(('', port)) s.listen(5) lock = thread.allocate_lock() while True: thread.start_new_thread(serve, (fname, docs, lock, s.accept())) def serve(fname, docs, lock, (c, _)): f = c.makefile() method, path = f.readline().split()[:2] # XXX this is failing! with lock: old = docs.get(path) edit_form = ("
" % cgi.escape(old or 'add text here')) if method == 'POST': form = urlparse.parse_qs(f.read(int(parse(f)['content-length']))) with lock: old = docs[path] = form['e'][0] save(docs, fname) c.send(ok + "page doesn’t yet exist" + edit_form if old is None else ok + '

%s

' % cgi.escape(path[1:]) + render(old) + edit_form) css = "" ok = "HTTP/1.0 200 OK\r\nContent-type: text/html; charset=utf-8\r\n\r\n" + css def render(wikitext): return (re.compile(r'\[\[([\s\w]+)\]\]').sub(link, cgi.escape(wikitext)) .replace('\r\n', '\n').replace('\n\n', '

')) def link(mo): n = cgi.escape(mo.group(1)) return '%s' % (n, n) # n_n def save(docs, fname): with open(fname + ".new", "w") as out: pickle.dump(docs, out) out.flush() os.fsync(out.fileno()) os.rename(fname + ".new", fname) def parse(fp): header = [] for line in fp: if not line.strip(): return email.parser.Parser().parsestr(''.join(header)) header.append(line) if __name__ == '__main__': main(sys.argv[1] if sys.argv[1:] else 'attowiki.pck', int(sys.argv[2]) if sys.argv[2:] else 8080)