#!/usr/bin/python """ noets - A weblog-style site CGI. License: GPL 2; share and enjoy! Author: Sean B. Palmer, inamidst.com Date: 2003-10ish About: This script originally powered the noets website, which was written to from IRC on various different channels by any of its participants. In that respect, it was like Edd Dumbill's chump bot, but the input was oriented towards prose rather than line-by-line input, and so the output was more like a conventional weblog. If you want to use this yourself, you'll have to change all of the hardcoded site names, paths, &c. """ import sys, os, re, cgi, time from cStringIO import StringIO base = '/noets' bloguri = 'http://sbp.f2o.org/noets/' blogname = 'nœts' password = '@@ Your Password Here' navigation = '
\n' address = '\n' address += 'Sean B. Palmer, \n' address += 'and the irc.freenode.net/#sbp folk.\n' address += '\n' def quoteHTML(s): s = s.replace('&', '&') s = s.replace('<', '<') return s r_wlink = re.compile(r'(?]+)>(?"]+$') def wikiLinkify(s): def htmlify(m): title, uri = m.group(1), m.group(2) return '%s' % (uri, title) s = r_wlink.sub(htmlify, s) return s def unicodeify(s): i = int(s, 16) if i in (0x9, 0xA, 0xD) + tuple(xrange(0x20, 0x7E)): return chr(i) elif i > 0x10FFFF: raise "UnicodeError", "Codepoint exceeds U+10FFFF" return '%s;' % s def wikiFormat(s): # @@ reserve \[A-Za-z]+{...} for future extensions # @@ use a proper parser, or catch the matches using a function result = '' pos = 0 while pos < len(s): m = r_wlink.match(s[pos:]) if m: span = m.span() result += wikiLinkify(s[pos:pos+span[1]]) pos += len(m.group(0)) else: m = re.compile(r'[A-Za-z0-9]--[A-Za-z0-9]').match(s[pos:]) if m: result += s[pos] + '—' + s[pos+3] pos += 4 else: m = r_uniquot.match(s[pos:]) if m: result += unicodeify(m.group(1)) pos += len(m.group(0)) elif s[pos:pos+4] == '\n..\n': result += '\n\n' pos += 4 elif s[pos] == '&': result += '&' pos += 1 elif s[pos] == '<': result += '<' pos += 1 else: result += s[pos] pos += 1 return result def html(title, body): s = '\n' s += '
\n' s += '%s
' % wikiFormat(content) data.close() # Return the ID as a string return str(nextid) r_meta = re.compile('(?s)([^\n:]+): (.*?)(?=\n[^ \t]|\Z)') def getEntry(i): meta = dict(r_meta.findall(open('./%s.txt' % i, 'r').read())) data = open('./%s.html' % i, 'r').read() title = quoteHTML(meta.get('title')) datetime = meta.get('datetime') datetime = datetime.replace('T', ' ').replace('Z', ' UTC') nick = quoteHTML(meta.get('nick')) channel = quoteHTML(meta.get('channel')) entry = 'No entries yet.
\n' result += address return html("%s - the noets of #sbp &c." % blogname, result) def main(env=None): if env is None: env = os.environ method = env.get('REQUEST_METHOD') if method not in ('GET', 'POST'): raise "UnsupportedMethodError", "Unsupported method: %s" % method uri = env.get('REQUEST_URI') assert uri.startswith(base) # @@ path = uri[len(base):] # Log the request t = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()) f = open('/home/sites/sbp/misc/noets-%s.log' % t[:7], 'a') addr = env.get('REMOTE_ADDR') referer = env.get('HTTP_REFERER', '[direct]').replace(' ', '') print >> f, t, method, path, addr, referer f.close() if False: if (method == 'GET') and (path == '/0'): print "Content-Type: text/plain" print print re.sub("(?m)^password = '.+'$", "password = 'yourpasswordhere'", open('index.cgi').read()) return if (method == 'GET') and (path == '/rss'): print "Content-Type: text/xml" print print buildRSS() return print "Content-Type: text/html; charset=utf-8" print if (method == 'POST') and (path == '/'): print postEntry() elif (method == 'GET') and (path == '/'): print buildIndex() elif (method == 'GET') and (path == '/archives'): print buildArchives() elif (method == 'GET') and ('-' in path): print buildMonthArchive(path[1:]) elif method == 'GET': i = int(path[1:]) print buildEntry(i) if __name__=="__main__": try: main() except: cgi.print_exception()