Below is the file 'poetweb.py' from this revision. You can also download the file.
#!/usr/bin/env python2.4 # # LiveJournal Haiku 2 # Copyright (C) 2006 Grahame Bowland # All rights reserved. # import datetime import urlparse import web from poet3 import Poet3 from forms import haiku import cPickle import config import syslog import re # for debugging, logging of referrers, etc. syslog.openlog("poetweb") # valid sites site_id_re = r'[A-Za-z\.]+' # specific to livejournal-based sites username_re = r'[A-Za-z0-9\_\-]+' username_re_c = re.compile(username_re) class NewLivejournal: @classmethod def user_uri(self, site, username): if username.startswith('-') or username.startswith('_') or \ username.endswith('-') or username.endswith('_'): return 'http://users.%s/%s/' % (site, username) else: return 'http://%s.%s/' % (username, site) @classmethod def rss_uri(self, site, username): return NewLivejournal.user_uri(site, username) + 'data/rss' rss_lookup = { 'livejournal.com' : NewLivejournal, 'deadjournal.com' : NewLivejournal, } urls = ( '/', 'IndexView', '/post/([A-Za-z]+)', 'PostMemeView', '/forms/haiku', 'HaikuFormView', '.*/(' + site_id_re + ')/(' + username_re + ')' + '/haiku', 'HaikuView', '/robots.txt', 'RobotsView', ) def gen_haiku(rss_uri): poet = Poet3(rss_uri) last_update = poet.storage.mtime('last_update') if datetime.datetime.now() - last_update > config.update_interval: poet.update() # FIXME this doesn't work.. poet.storage.open('last_update', 'w').write('') poet.build_state() if poet.symbol_state.forward_markov.total == 0: return -1, None # if there has been no upwriting yet, then let's do some now. # we save the resulting combined tokens, so the code uses those # when adding new tokens to the corpus from now on if not poet.upwritten_seqs: to_upwrite = poet.symbol_state.chunkable() cPickle.dump(to_upwrite, poet.storage.open('upwritten.txt', 'w')) poet.upwrite(to_upwrite) for attempt in xrange(config.haiku_attempts): poem = haiku(poet) if poem != None: break return attempt, poem class Renderer: def __init__(self): # any templates that can be inherited from, should be added to the list here self.templates = [ ('base.html', 'base') ] self._templates_loaded = False # these variables will be available to any template self.terms = { 'context' : web.context, # fugly 'dynamic_uri_path' : config.dynamic_uri_path, 'dynamic_join' : lambda path: urlparse.urljoin(config.dynamic_uri_path, path), 'static_uri_path' : config.static_uri_path, 'static_join' : lambda path: urlparse.urljoin(config.static_uri_path, path), } def load_templates(self): if self._templates_loaded: return for template, mod_name in self.templates: web.render(template, None, True, mod_name) self._templates_loaded = True def render(self, template, **kwargs): self.load_templates() terms = self.terms.copy() terms.update(kwargs) web.render(template, terms) renderer = Renderer() haiku_base = '''<form action="%(dynamic_uri_path)spost/haiku" method="post"><table align="center" border="0" bgcolor="#DDDDFF" style="border: 1px solid black;"><tr><th>LJ-Haiku<sup>2</sup> for %(username)s</th></tr><tr><td><blockquote align="right" style="text-align:right;border-right:1px solid #808080; padding:5px;"> %(haiku)s</blockquote></td></tr><tr><td align="center"><input type="text" size=8 name="haiku_username" value="%(username)s" /> @ <select name="haiku_server"><option selected value="%(mysite)s">%(mysite)s</option><option value="x">Other...</option></select><input value="%(username)s" type="hidden" name="haiku_referrer" /></td></tr><tr><td align="center"><input type="submit" value="What's my Haiku?"></td></tr><tr><td align="center" bgcolor="#CCCCCC"><small><a href="http://www.livejournal.com/users/grahame/">Created by Grahame</a></small></td></tr></table></form>''' class HaikuView: def GET(self, site, username): if not rss_lookup.has_key(site): ## fixme; this is a site we don't know about; let's return a friendly ## page suggesting the user might want to ask about adding it return web.notfound() uri = rss_lookup[site].rss_uri(site, username) web.debug(uri) attempts, haiku = gen_haiku(uri) if haiku == None: haiku_code = None else: haiku_code = haiku_base % { 'mysite' : site, 'dynamic_uri_path' : config.dynamic_uri_path, 'username' : username, 'haiku' : '<br />'.join(' '.join(t) for t in haiku) } web.debug("haiku_code=%s" % haiku_code) renderer.render("haiku.html", attempts=attempts, page_title="your haiku", username=username, haiku_code=haiku_code ) class PostMemeView: def GET(self, meme_name): web.seeother(config.dynamic_uri_path) def POST(self, meme_name): meme_name = meme_name.lower() i = web.input() if meme_name == "haiku" and i.has_key('haiku_username') and i.has_key('haiku_referrer') and i.has_key('haiku_server'): username, referrer, server = i['haiku_username'], i['haiku_referrer'], i['haiku_server'] if not username_re_c.match(username): web.seeother(config.dynamic_uri_path) if not rss_lookup.has_key(server): web.seeother(urlparse.urljoin(config.dynamic_uri_path, "forms/haiku")) syslog.syslog("haiku: username=%s referrer=%s server=%s" % (username, referrer, server)) web.seeother(urlparse.urljoin(config.dynamic_uri_path, server + '/' + username + '/haiku')) else: web.seeother(config.dynamic_uri_path) print "hello, you posted!" class IndexView: def GET(self, *args, **kwargs): renderer.render("index.html", page_title="welcome") class RobotsView: def GET(self, *args, **kwargs): print "User-agent: *" for key in rss_lookup.keys(): print "Disallow: /%s/" % (key) if __name__ == '__main__': web.internalerror = web.debugerror web.run(urls, web.reloader)