#!/usr/bin/env python """ azimuth.py - Azimuth Publishing Software Author: Sean B. Palmer, inamidst.com """ import sys, os, re title = 'Lo and Behold!' r_title = re.compile('

([^<]+)') def env(name): return os.environ.get(name, '-') def mappings(): return [ ('/feed', feed()), ('/contents', contents()), ('/(?P[a-z]+)', article('')), ('/', homepage()) ] def headers(status=200, mime=None): if status != 200: print 'Status: %s' % status print 'Content-Type:', print mime or 'text/html; charset=utf-8' print def render(filename, **kargs): if not os.path.isfile(filename): print '' % filename return skip = kargs.get('skip', 0) if kargs.has_key('skip'): del kargs['skip'] f = open(filename) for line in f: if skip: skip = skip - 1 continue for (arg, value) in kargs.iteritems(): line = line.replace('$' + arg, value) sys.stdout.write(line) f.close() def notfound(): headers(200) print '

Not found!

' def articles(): mtime = os.path.getmtime names = [(mtime(fn), fn) for fn in os.listdir('.') if fn.endswith('.txt')] return sorted(names, reverse=True) def dispatcher(func): def outer(*args): args = (arg.strip('<>') for arg in args) def inner(m): kargs = {} groupdict = m.groupdict() for arg in args: if groupdict.has_key(arg): kargs[arg] = groupdict[arg] else: raise ValueError('No such group: %s' % arg) return func(**kargs) return inner return outer def articletitle(filename): f = open(filename) first = f.next() f.close() m = r_title.match(first) if m: return m.group(1) else: return title @dispatcher def article(**kargs): headers() name = kargs.get('name') text = name + '.txt' html = name + '.html' if os.path.isfile(text): render('src/head.html', title=articletitle(text)) render(text) render('src/tail.html') elif os.path.isfile(html): render('src/head.html', title=articletitle(html)) render(html) render('src/tail.html') @dispatcher def contents(**kargs): import datetime headers() render('src/head.html', title='Contents') print '

Contents

' print '
' render('src/tail.html') @dispatcher def feed(**kargs): import datetime headers(mime='application/atom+xml') render('src/head.atom') first = True for date, filename in articles(): date = datetime.datetime.fromtimestamp(date) updated = date.strftime('%Y-%m-%dT%H:%M:%SZ') a = articletitle(filename) if first: print ' %s' % updated print first = False kargs={'updated': updated, 'name': filename[:-4], 'title': a} render('src/article.atom', **kargs) sys.stdout.write(' ' print ' ' print ' ' print '' @dispatcher def homepage(**kargs): headers() render('src/head.html', title=title) for date, filename in articles(): render(filename) print render('src/tail.html') def main(): __import__('cgitb').enable() requri = env('REQUEST_URI') path = '/' + requri.split('/').pop() for regexp, dispatch in mappings(): match = re.compile('^%s$' % regexp).match(path) if match: dispatch(match) break else: notfound() if __name__ == '__main__': main()