The unified diff between revisions [0b849689..] and [8c5c8a3d..] is displayed below. It can also be downloaded as a raw diff.

#
#
# patch "config.py"
#  from [695a5fb88edd1190cefe0d3958e8358d46e1376b]
#    to [2532e16eeb23781130fb73fc44f0ea8c78037dff]
#
# patch "poetweb.py"
#  from [024693486e0ca4cae14590fd8483f3780293b2cd]
#    to [b7f62177c811a28243a96a0921525f950120e23c]
#
# patch "static/memes.css"
#  from [7c6605d4ef2e94da826e5e23df478298f71b465d]
#    to [8fe01d520f90887fd761d918180b1eb9101b7334]
#
# patch "symbolstate.py"
#  from [a144283fbc3b059a8e34856c43012fe514eb7305]
#    to [f2e0c7f4711de6cf900b5c09d0786ffb7d1ed72f]
#
# patch "templates/base.html"
#  from [48e7bd91711d09f059c914396551a9fb5ddde222]
#    to [8f3545d98812a0f20d84551a7471b15a2c8152d4]
#
# patch "templates/haiku.html"
#  from [7e6b5dc5f4f1ae18bccec9332b5782ae0307fa30]
#    to [e18c4556feb6de7c6c4a7a7e24dcae959075f3a0]
#
============================================================
--- config.py	695a5fb88edd1190cefe0d3958e8358d46e1376b
+++ config.py	2532e16eeb23781130fb73fc44f0ea8c78037dff
@@ -2,7 +2,7 @@ import os
 import datetime
 import os

-install_path = '/Users/grahame/monotone/memes/'
+install_path = '/home/grahame/monotone/memes/'
 storage_path = os.path.join(install_path, 'storage')
 word_db = os.path.join(install_path, 'word.db')

@@ -13,6 +13,6 @@ update_interval = datetime.timedelta(day

 update_interval = datetime.timedelta(days=7)

-dynamic_uri_path = 'http://localhost:8080/'
-static_uri_path = 'http://glamdring.local/~grahame/memes/static/'
+dynamic_uri_path = 'http://memes.angrygoats.net:3128/'
+static_uri_path = 'http://memes.angrygoats.net:3128/static/'

============================================================
--- poetweb.py	024693486e0ca4cae14590fd8483f3780293b2cd
+++ poetweb.py	b7f62177c811a28243a96a0921525f950120e23c
@@ -1,5 +1,11 @@
-#!/usr/bin/env python
+#!/usr/bin/env python2.4

+#
+# LiveJournal Haiku 2
+# Copyright (C) 2006 Grahame Bowland
+# All rights reserved.
+#
+
 import datetime
 import urlparse
 import web
@@ -7,42 +13,52 @@ import config
 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)

-def newstyle_lj_address(site, username):
-    if username.startswith('-') or username.startswith('_') or \
-                username.endswith('-') or username.endswith('_'):
-        base_uri = 'http://users.livejournal.com/%s/' % username
-    else:
-        base_uri = 'http://%s.livejournal.com/' % username
-    return base_uri + 'data/rss'
+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'

-def test_address(site, username):
-    return "http://glamdring.local/~grahame/rss"
-
 rss_lookup = {
-    'livejournal.com' : newstyle_lj_address,
-    'test' : test_address,
+    'livejournal.com' : NewLivejournal,
+    'deadjournal.com' : NewLivejournal,
 }

 urls = (
-    '.*/(' + site_id_re + ')/(' + username_re + ')' + '/haiku', 'view',
-    '.*', 'testthing'
+    '/', '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:
-        web.debug("calling poet.update()")
         poet.update()
         # FIXME this doesn't work..
         poet.storage.open('last_update', 'w').write('')
     poet.build_state()
-    web.debug("debug: poet.upwritten_seqs=%s" % (poet.upwritten_seqs))
+    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
@@ -88,25 +104,59 @@ renderer = Renderer()

 renderer = Renderer()

-class view:
+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](site, username)
+        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,
-                        haiku=[' '.join(t) for t in haiku],
                         page_title="your haiku",
-                        username=username)
+                        username=username,
+                        haiku_code=haiku_code )

-class testthing:
-    def GET(self):
-        print "Hello, world: this is the catch-all page"
+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)
-
============================================================
--- static/memes.css	7c6605d4ef2e94da826e5e23df478298f71b465d
+++ static/memes.css	8fe01d520f90887fd761d918180b1eb9101b7334
@@ -10,12 +10,11 @@ h1#pageTitle {
 	background-color: #7070F0;
 	color: black;
 	text-align: center;
-	padding-top: 1em;
-	padding-bottom: 1em;
+	padding-top: 0.5em;
+	padding-bottom: 0.5em;
 	margin-bottom: 1em;
-	border-bottom-width: 1px;
-	border-bottom-color: black;
-	border-bottom-style: solid;
+	border-bottom: 1px solid black;
+	border-top: 1px solid black;
 }

 DIV.banner {
============================================================
--- symbolstate.py	a144283fbc3b059a8e34856c43012fe514eb7305
+++ symbolstate.py	f2e0c7f4711de6cf900b5c09d0786ffb7d1ed72f
@@ -53,6 +53,8 @@ class SymbolState:

     def chunkable(self):
         entropies = [self.forward_markov.scores[t].entropy() for t in self.forward_markov.scores]
+        if len(entropies) == 0:
+            return []
         mean_h = sum(entropies) / len(entropies)
         sd_h = math.sqrt(sum([ pow(t - mean_h, 2) for t in entropies ]) / len(entropies))
         cutoff = mean_h + 6 * sd_h # should really justify in some way other than 'it works'
============================================================
--- templates/base.html	48e7bd91711d09f059c914396551a9fb5ddde222
+++ templates/base.html	8f3545d98812a0f20d84551a7471b15a2c8152d4
@@ -7,6 +7,20 @@
 </head>
 <body>

+<div align="center">
+	<script type="text/javascript"><!--
+	google_ad_client = "pub-9483024257119602";
+	google_ad_width = 728;
+	google_ad_height = 90;
+	google_ad_format = "728x90_as";
+	google_ad_type = "text_image";
+	google_ad_channel ="";
+	//--></script>
+	<script type="text/javascript"
+	  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
+	</script>
+</div>
+
 <h1 id="pageTitle">memes.angrygoats.net</h1>

 #block body
============================================================
--- templates/haiku.html	7e6b5dc5f4f1ae18bccec9332b5782ae0307fa30
+++ templates/haiku.html	e18c4556feb6de7c6c4a7a7e24dcae959075f3a0
@@ -2,8 +2,8 @@

 #def body

-#if $haiku == None
-<p>
+#if $haiku_code == None
+<p align="center">
 Sorry, something went wrong generating your Haiku.
 </p>

@@ -13,28 +13,18 @@ Sorry, something went wrong generating y
 	Your freshly generated Haiku is:
 </p>

-<form action="http://grahame.angrygoats.net/lj-haiku/index.psp" method="post">
-<table align="center" border="0" bgcolor="#DDDDFF" style="border: 1px solid black;">
-<tr><th>LJ-Haiku<sup>2</sup> for $username</th></tr>
-<tr><td>
-<blockquote align="right" style="text-align:right;border-right:1px solid #808080; padding:5px;">
-	#for line in $haiku
-	$line<br />
-	#end for
-</blockquote>
-</td></tr>
-<tr><td align="center">
-<input type="text" size=8 name="haiku_username" value="$username" /> @
-<select name="server">
-	<option selected value="livejournal.com">LJ</option>
-	<option value="pick">Other</option>
-</select>
-<input value="$username" 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>
+#filter Filter
+$haiku_code
+#filter WebSafe

+<p align="center">
+	Want to add this to your journal? Just copy the following code into your journal.
+</p>
+<p style='border-style: solid; width: 50%; position: relative; left: 25%; padding: 3px; border-width: 2; border-color: green;'>
+<small><small><code>
+$haiku_code
+</small></small></code>
+</p>
+
 #end if
 #end def