#!/usr/bin/env python """ index.cgi - Serve Changes Author: Sean B. Palmer, inamidst.com """ import cgitb; cgitb.enable() import sys, os, re, tarfile import changes r_month = re.compile(r'^\d{4}-\d{2}$') def header(status=200, mime='text/html', other={}): if status != 200: print 'Status:', status for (key, value) in other.iteritems(): print key + ':', value print 'Content-Type:', mime print def template(mappings): f = open('template.txt') bytes = f.read() f.close() for (key, value) in mappings.iteritems(): bytes = bytes.replace('$' + key, value) return bytes def listMonths(): months = [] for month in changes.monthLogsBackwards(): if changes.monthExists(month): months.append(month) months = sorted(months) def generator(): yield '
Access all of the archives:
' yield '' yield 'These are the 250 most recent change summaries:
\n\n' print template({ 'title': 'Change Summaries', 'changes': msg + '\n'.join(generateSummary()), 'months': listMonths() }) def month(method, path, match, template=template): header() month = path[1:] assert r_month.match(month) print template({ 'title': 'Changes and Updates for %s' % month, 'changes': changes.changesByMonth(month), 'months': '' }) def diff(method, path, match): filename = match.group(1) lines = changes.getdiff(filename) if lines is not False: header(mime='text/plain') for line in lines: sys.stdout.write(line) else: header(status=404, mime='text/plain') print "Not found:", filename def diffget(method, path, match): header() hmm = match.group(1) if len(hmm) > 1: hmm = hmm.lstrip('/') date, abspath = hmm.split('/', 1) abspath = '/' + abspath date = date.replace('T', ' ') else: date, abspath = '', '' print """ """ % (date, abspath) def diffpost(method, path, match): import cgi form = cgi.FieldStorage() form.__call__ = lambda s: form[s].value if form.has_key('date') and form.has_key('path'): date = form('date').replace(' ', '-') path = form('path').lstrip('/') path = path.replace('_', '__') path = path.replace('/', '_') + '.diff' uri = '/changes/' + date + '-' + path header(status=303, other={'Location': uri}) else: barf() def head(method, path, match): header() def request(): method = os.environ['REQUEST_METHOD'] # Assume that the script is being mod_rewritten to script = os.environ['SCRIPT_NAME'] script = '/'.join(script.split('/')[:-1]) requri = os.environ['REQUEST_URI'] assert requri.startswith(script) path = requri[len(script):] return method, path def main(): # Get the method and path method, path = request() mappings = { 'GET /': homepage, 'GET /summary': summary, 'GET /(\d+-\d+)': month, 'GET /(\d+-\d+-\d+-.+\.diff)': diff, 'GET /diff(/.*)?': diffget, 'POST /diff': diffpost, # 'HEAD /.*': head } for (pattern, dispatch) in mappings.iteritems(): patmethod, regexp = pattern.split(' ', 1) r_path = re.compile(r'^%s$' % regexp) if method == patmethod: match = r_path.match(path) if match: dispatch(method, path, match) break else: barf() if __name__=="__main__": main()