constance

Scripts for generating (an earlier obsolete version of) my personal web site
git clone https://code.djc.id.au/git/constance/
commit 14d1e9ceb79f294300144e9a0cb1851db3ceedcf
parent 4b075d41f0a141a34eee79dbe3e3b2edb34fcbac
Author: Dan Callaghan <djc@djc.id.au>
Date:   Sat, 22 Nov 2008 13:46:39 +1000

Automated merge with http://source.sjkwi.com.au/hg/constance/

Diffstat:
Mapp.py | 55++++++++++++++++++++++++++++++++++++++++++++++---------
Mtemplates/_entry.xml | 8++++----
Mtemplates/multiple_atom.xml | 8++++----
Mtemplates/sitemap.xml | 14++++++++++----
Mtemplates/tag_cloud.xml | 2+-
Mviewutils.py | 2+-
6 files changed, 66 insertions(+), 23 deletions(-)
diff --git a/app.py b/app.py
@@ -109,12 +109,13 @@ class Constance(object):
 
     # XXX keep sitemap in sync with these
     urls = [(r'/$', 'index'), 
-            (r'/\+tags/$', 'tag_cloud'), 
-            (r'/\+tags/(.+)$', 'tag'), 
-            (r'/\+reading/?$', 'reading'), 
+            (r'/tags/$', 'tag_cloud'), 
+            (r'/tags/(.+)$', 'tag'), 
+            (r'/reading/?$', 'reading'), 
             (r'/sitemap.xml$', 'sitemap'), 
-            (r'/([^+/][^/]*)/?$', 'post'), 
-            (r'/([^+/][^/]*)/comments/\+new$', 'add_post_comment')]
+            (r'/blog/?$', 'blog_index'), 
+            (r'/blog/([^/]+)/?$', 'blog_entry'), 
+            (r'/blog/([^/]+)/comments/\+new$', 'add_post_comment')]
     urls = [(re.compile(patt), method) for patt, method in urls]
 
     def index(self):
@@ -160,8 +161,40 @@ class Constance(object):
                 tag_freqs=tag_freqs
                 ).render('xhtml', encoding=self.encoding)
         return (rendered, [('Content-Type', 'text/html')])
+
+    def blog_index(self):
+        try:
+            offset = int(self.args.get('offset', 0))
+        except ValueError:
+            raise NotFoundError('Invalid offset %r' % self.args['offset'])
+        sorted_entries = sorted(self.blog_entries, 
+                key=lambda e: e.publication_date, reverse=True)
+        if offset >= len(sorted_entries):
+            raise NotFoundError('Offset beyond end of entries')
+        format = self.args.get('format', 'html')
+        if format == 'html':
+            rendered = template_loader.load('multiple.xml').generate(
+                    config=self.config, 
+                    environ=self.environ, 
+                    title=None, 
+                    sorted_entries=sorted_entries, 
+                    offset=offset,
+                    ).render('xhtml', encoding=self.encoding)
+            return (rendered, [('Content-Type', 'text/html')])
+        elif format == 'atom':
+            rendered = template_loader.load('multiple_atom.xml').generate(
+                    config=self.config, 
+                    environ=self.environ, 
+                    title=None, 
+                    self_url='%s/blog/' % self.environ['APP_URI'], 
+                    sorted_entries=sorted_entries[:self.config.getint('global', 'entries_in_feed')], 
+                    feed_updated=max(e.modified_date for e in sorted_entries[:self.config.getint('global', 'entries_in_feed')])
+                    ).render('xml', encoding=self.encoding)
+            return (rendered, [('Content-Type', 'application/atom+xml')])
+        else:
+            raise NotFoundError('Unknown format %r' % format)
     
-    def post(self, id):
+    def blog_entry(self, id):
         try:
             entry = self.blog_entries[id]
         except KeyError:
@@ -257,7 +290,7 @@ class Constance(object):
                     config=self.config, 
                     environ=self.environ, 
                     title=u'reading log', 
-                    self_url='%s/+reading/' % self.environ['APP_URI'], 
+                    self_url='%s/reading/' % self.environ['APP_URI'], 
                     sorted_entries=sorted_entries[:self.config.getint('global', 'entries_in_feed')], 
                     feed_updated=sorted_entries[0].modified_date
                     ).render('xml', encoding=self.encoding)
@@ -270,10 +303,13 @@ class Constance(object):
         for entry in self.blog_entries:
             for tag in entry.tags:
                 tags[tag] = max(entry.modified_date, tags.get(tag, datetime.datetime.min))
+        sorted_blog_entries = sorted(self.blog_entries, 
+                key=lambda e: e.publication_date, reverse=True)
         sorted_entries = sorted(chain(self.blog_entries, self.readinglog_entries), 
                 key=lambda e: e.publication_date, reverse=True)
-        if len(self.readinglog_entries) != 0:
-            rl_updated = max(e.date for e in self.readlinglog_entries)
+        readinglog_entries = list(self.readinglog_entries)
+        if len(readinglog_entries) != 0:
+            rl_updated = max(e.date for e in readinglog_entries)
         else:
             rl_updated = None
         rendered = template_loader.load('sitemap.xml').generate(
@@ -282,6 +318,7 @@ class Constance(object):
                 blog_entries=self.blog_entries, 
                 tags=tags, 
                 readinglog_updated=rl_updated,
+                blog_index_updated=max(e.modified_date for e in sorted_blog_entries[:self.config.getint('global', 'entries_per_page')]), 
                 index_updated=max(e.modified_date for e in sorted_entries[:self.config.getint('global', 'entries_per_page')]), 
                 ).render('xml', encoding='utf8') # sitemaps must be UTF-8
         return (rendered, [('Content-Type', 'text/xml')])
diff --git a/templates/_entry.xml b/templates/_entry.xml
@@ -18,7 +18,7 @@ from recaptcha.client import captcha
 
 	<div class="entrydate">
 		${entry.publication_date.strftime(str('%-1d %b %Y'))}
-	    <a href="${uri(entry.id)}" rel="bookmark" class="permalink" title="permalink">#</a>
+	    <a href="${uri('blog', entry.id)}" rel="bookmark" class="permalink" title="permalink">#</a>
 	</div>
 
     <div py:if="entry.tags" class="entrytags">
@@ -30,7 +30,7 @@ from recaptcha.client import captcha
     </div>
 
     <div class="entrycommentslink" py:if="not show_comments and entry.has_comments()">
-        <a href="${uri(entry.id)}#comments" py:choose="len(entry.comments())">
+        <a href="${uri('blog', entry.id)}#comments" py:choose="len(entry.comments())">
             <py:when test="0">no comments »</py:when>
             <py:when test="1">1 comment »</py:when>
             <py:otherwise>${len(entry.comments())} comments »</py:otherwise>
@@ -53,7 +53,7 @@ from recaptcha.client import captcha
             </p>
             ${block_sep()}
         </div>
-        <div class="commentform"><form method="post" action="${uri(entry.id, 'comments', '+new')}">
+        <div class="commentform"><form method="post" action="${uri('blog', entry.id, 'comments', '+new')}">
             <p>
                 <label for="commentform-from">Name</label>
                 <input type="text" id="commentform-from" name="from" />
@@ -101,7 +101,7 @@ from recaptcha.client import captcha
 
     <div class="entrydate">
         ${entry.publication_date.strftime(str('%-1d %b %Y'))}
-	    <a href="${uri('+reading', '')}#entry-${entry.id}" rel="bookmark" class="permalink" title="permalink">#</a>
+	    <a href="${uri('reading', '')}#entry-${entry.id}" rel="bookmark" class="permalink" title="permalink">#</a>
     </div>
 
     <div py:if="entry.rating" class="rating">
diff --git a/templates/multiple_atom.xml b/templates/multiple_atom.xml
@@ -25,11 +25,11 @@ ATOM_TIME_FORMAT = str('%Y-%m-%dT%H:%M:%S+10:00')
 		<name>${config.getunicode('global', 'author')}</name>
 		<email py:if="email">${email}</email>
 	</author>
-	<category py:for="tag in entry.tags" scheme="${abs_uri('+tags', '')}" term="${tag}" />
+	<category py:for="tag in entry.tags" scheme="${abs_uri('tags', '')}" term="${tag}" />
 	<py:if test="isinstance(entry, blog.BlogEntry)">
-		<link rel="alternate" href="${abs_uri(entry.id)}" />
+		<link rel="alternate" href="${abs_uri('blog', entry.id)}" />
 		<title type="text">${entry.title}</title>
-		<content type="xhtml" xml:base="${abs_uri(entry.id)}">
+		<content type="xhtml" xml:base="${abs_uri('blog', entry.id)}">
             <div xmlns="http://www.w3.org/1999/xhtml">
                 <p py:if="entry.tags">Tagged: ${tag_list(environ.get('SCRIPT_NAME', ''), entry.tags)}</p>
                 ${markdown(entry.body)}
@@ -37,7 +37,7 @@ ATOM_TIME_FORMAT = str('%Y-%m-%dT%H:%M:%S+10:00')
 		</content>
 	</py:if>
 	<py:if test="isinstance(entry, blog.ReadingLogEntry)">
-		<link rel="alternate" href="${abs_uri('+reading', '')}#entry-${entry.id}" />
+		<link rel="alternate" href="${abs_uri('reading', '')}#entry-${entry.id}" />
 		<title type="text">${entry.title} by ${entry.author}</title>
 		<summary py:if="entry.rating" type="text">${entry.rating} stars</summary>
 		<content type="xhtml">
diff --git a/templates/sitemap.xml b/templates/sitemap.xml
@@ -16,23 +16,29 @@ W3C_TIME_FORMAT = str('%Y-%m-%dT%H:%M:%S+10:00')
     <priority>1.0</priority>
 </url>
 <url>
-    <loc>${abs_uri('+tags', '')}</loc>
+    <loc>${abs_uri('tags', '')}</loc>
     <priority>0.25</priority>
 </url>
 <url py:for="tag, modtime in tags.iteritems()">
-    <loc>${abs_uri('+tags', tag)}</loc>
+    <loc>${abs_uri('tags', tag)}</loc>
     <lastmod>${modtime.strftime(W3C_TIME_FORMAT)}</lastmod>
     <changefreq>weekly</changefreq>
     <priority>0.25</priority>
 </url>
 <url py:if="readinglog_updated is not None">
-    <loc>${abs_uri('+reading', '')}</loc>
+    <loc>${abs_uri('reading', '')}</loc>
     <lastmod>${readinglog_updated.strftime(W3C_TIME_FORMAT)}</lastmod>
     <changefreq>weekly</changefreq>
     <priority>0.75</priority>
 </url>
+<url>
+    <loc>${abs_uri('blog', '')}</loc>
+    <lastmod>${blog_index_updated.strftime(W3C_TIME_FORMAT)}</lastmod>
+    <changefreq>weekly</changefreq>
+    <priority>0.5</priority>
+</url>
 <url py:for="entry in blog_entries">
-    <loc>${abs_uri(entry.id)}</loc>
+    <loc>${abs_uri('blog', entry.id)}</loc>
     <lastmod>${entry.modified_date.strftime(W3C_TIME_FORMAT)}</lastmod>
     <changefreq>never</changefreq>
     <priority>1.0</priority>
diff --git a/templates/tag_cloud.xml b/templates/tag_cloud.xml
@@ -15,7 +15,7 @@
 
 <ol id="tagcloud">
     <li py:for="tag, freq in sorted(tag_freqs.iteritems(), key=lambda (t, f): t.lower())">
-        <a rel="tag" href="${uri('+tags', tag)}" style="font-size: ${0.8 + (freq / 10.)}em;">${tag}</a>
+        <a rel="tag" href="${uri('tags', tag)}" style="font-size: ${0.8 + (freq / 10.)}em;">${tag}</a>
         <span class="frequency">(used ${freq} times)</span>
     </li>
 </ol>
diff --git a/viewutils.py b/viewutils.py
@@ -16,5 +16,5 @@ def mini_markdown(s, safe_mode=None):
 def tag_list(script_name, tags):
     # XXX urllib.quote
     return genshi.Markup(u', ').join(
-            genshi.Markup(u'<a rel="tag" href="%s/+tags/%s">%s</a>' % (script_name, tag, tag)) 
+            genshi.Markup(u'<a rel="tag" href="%s/tags/%s">%s</a>' % (script_name, tag, tag)) 
             for tag in tags)