constance

Scripts for generating (an earlier obsolete version of) my personal web site
git clone https://code.djc.id.au/git/constance/
commit de6de8f177b0034015d492473267cc4245cf23af
parent 6b908f1d1ffc25501b2c06c9bbb01ecb34ccfac4
Author: Dan Callaghan <djc@djc.id.au>
Date:   Sat, 11 Dec 2010 12:33:40 +1000

rearranged config; use hardcoded paths within the site (makes things a lot simpler)

Diffstat:
Mblog.py | 14+++++++-------
Mconstance.conf.sample | 35++++++++++++++++++++++++++++-------
Mconstance.py | 43++++++++++++++++++++-----------------------
Mhomepage.py | 8++++----
Mreading.py | 12++++++------
Mtags.py | 6+++---
Mtemplates/blog/entry.atom | 10+++++-----
Mtemplates/blog/entry.html | 10+++++-----
Mtemplates/blog/index.atom | 10+++++-----
Mtemplates/blog/index.html | 4++--
Mtemplates/homepage/firehose.atom | 10+++++-----
Mtemplates/homepage/index.html | 11+++++++++++
Mtemplates/reading/entry.atom | 6+++---
Mtemplates/reading/reading.atom | 10+++++-----
Mtemplates/reading/reading.html | 4++--
Mtemplates/tags/index.html | 2+-
Mtemplates/tags/tag.html | 2+-
17 files changed, 113 insertions(+), 84 deletions(-)
diff --git a/blog.py b/blog.py
@@ -12,7 +12,7 @@ import constance
 import viewutils
 
 template_loader = genshi.template.TemplateLoader(
-        os.path.join(os.path.dirname(__file__), 'templates', 'blog'), 
+        os.path.join(os.path.realpath(os.path.dirname(__file__)), 'templates', 'blog'), 
         variable_lookup='strict')
 
 def cleanup_metadata(header_items):
@@ -49,9 +49,9 @@ class BlogEntry(object):
         self.guid = self.metadata['guid']
         self.language = self.metadata.get('language', None)
 
-    def generate_atom(self, template_config):
+    def generate_atom(self, config):
         return template_loader.load('entry.atom').generate(item=self,
-                template_config=template_config)
+                config=config)
 
 class BlogEntrySet(object):
 
@@ -69,24 +69,24 @@ class BlogEntrySet(object):
     def __len__(self):
         return len(self.entries)
 
-def generate(dir, xslt, template_config):
+def generate(dir, xslt, config):
     entries = BlogEntrySet(dir)
     
     for entry in entries:
         rendered = template_loader.load('entry.html').generate(item=entry,
-                template_config=template_config).render('xhtml')
+                config=config).render('xhtml')
         transformed = str(xslt(lxml.etree.fromstring(rendered)))
         constance.output(os.path.join(dir, entry.id.encode('utf8') + '.html'), transformed)
     
     # index
     rendered = template_loader.load('index.html').generate(items=entries,
-            template_config=template_config).render('xhtml')
+            config=config).render('xhtml')
     transformed = str(xslt(lxml.etree.fromstring(rendered)))
     constance.output(os.path.join(dir, 'index.html'), transformed)
 
     # feed
     rendered = template_loader.load('index.atom').generate(items=entries,
-            template_config=template_config).render('xml')
+            config=config).render('xml')
     constance.output(os.path.join(dir, 'index.atom'), rendered)
 
     return entries
diff --git a/constance.conf.sample b/constance.conf.sample
@@ -1,12 +1,33 @@
 [paths]
 root = ./htdocs
-blog = %(root)s/blog
-tags = %(root)s/tags
-reading_log =
-xslt = ./sample.xsl
+xslt = ../sample.xsl
 
-[template]
-website = http://localhost
+# Base for absolute URLs
+url_base = http://localhost/
+
+# These are used in Atom feeds
 name = Joe Bloggs
 email = user@domain.com
-disqus_user = 
+
+[disqus]
+site = 
+
+[homepage]
+enabled = True
+title = Joe Bloggs’ homepage
+firehose_title = Joe Bloggs’ firehose
+icbm = 38.897686,-77.036514
+openid_server = 
+openid_delegate = 
+xrds = 
+
+[blog]
+enabled = True
+title = Joe Bloggs’ blog
+
+[tags]
+enabled = True
+
+[reading]
+enabled = True
+title Joe Bloggs’ reading log
diff --git a/constance.py b/constance.py
@@ -1,4 +1,4 @@
-
+#!/usr/bin/env python
 # vim:encoding=utf-8
 
 import os, sys
@@ -10,6 +10,7 @@ import re
 import datetime
 import time
 import urllib
+import codecs
 import optparse
 import genshi.template
 import lxml.etree
@@ -39,39 +40,35 @@ def main():
     # populate config from default location (which would have been
     # overidden by --config above, if given)
     config = SafeConfigParser()
-    with open(os.path.expanduser(options.config), 'r') as fp:
+    with codecs.open(os.path.expanduser(options.config), 'r', 'utf8') as fp:
         config.readfp(fp)
-    template_config = dict(config.items('template'))
 
-    # strip trailing slash if it was given
-    website = config.get('template', 'website')
-    if website[-1] == '/':
-        website = website[:-1]
+    if config.get('global', 'root'):
+        os.chdir(config.get('global', 'root'))
 
-    xslt = lxml.etree.XSLT(lxml.etree.parse(config.get('paths', 'xslt')))
+    xslt = lxml.etree.XSLT(lxml.etree.parse(config.get('global', 'xslt')))
 
-    blog_entries = blog.generate(config.get('paths', 'blog'), xslt,
-            template_config=template_config)
+    if config.get('blog', 'enabled'):
+        blog_entries = blog.generate('blog', xslt, config)
+    else:
+        blog_entries = []
 
-    rl_path = config.get('paths', 'reading_log')
-    if rl_path is not None and rl_path != '':
-        reading_entries = reading.generate(rl_path, xslt, 
-                template_config=template_config)
+    if config.get('reading', 'enabled'):
+        reading_entries = reading.generate('reading_log.yaml', xslt, config)
     else:
         reading_entries = []
 
-    tags.generate(config.get('paths', 'tags'), xslt, blog_entries, 
-            template_config=template_config)
+    if config.get('tags', 'enabled'):
+        tags.generate('tags', xslt, blog_entries, config)
 
-    for filename in os.listdir(config.get('paths', 'root')):
+    for filename in os.listdir('.'):
         if filename.endswith('.html.in'):
-            src = os.path.join(config.get('paths', 'root'), filename)
-            dest = src[:-3]
-            transformed = str(xslt(lxml.etree.parse(src)))
-            output(dest, transformed)
+            transformed = str(xslt(lxml.etree.parse(filename)))
+            output(filename[:-3], transformed)
 
-    homepage.generate(config.get('paths', 'root'), xslt, blog_entries, 
-            reading_entries, template_config=template_config)
+    if config.get('homepage', 'enabled'):
+        homepage.generate('', xslt, blog_entries, 
+                reading_entries, config)
 
 if __name__ == '__main__':
     main()
diff --git a/homepage.py b/homepage.py
@@ -10,20 +10,20 @@ import constance
 import viewutils
 
 template_loader = genshi.template.TemplateLoader(
-        os.path.join(os.path.dirname(__file__), 'templates', 'homepage'), 
+        os.path.join(os.path.realpath(os.path.dirname(__file__)), 'templates', 'homepage'), 
         variable_lookup='strict')
 
-def generate(dir, xslt, blog_entries, reading_entries, template_config):
+def generate(dir, xslt, blog_entries, reading_entries, config):
     # index
     template = template_loader.load('index.html')
     rendered = template.generate(blog_entries=blog_entries, 
             reading_entries=reading_entries, 
-            template_config=template_config).render('xhtml')
+            config=config).render('xhtml')
     transformed = str(xslt(lxml.etree.fromstring(rendered)))
     constance.output(os.path.join(dir, 'index.html'), transformed)
 
     # firehose
     rendered = template_loader.load('firehose.atom').generate(
             items=chain(blog_entries, reading_entries),
-            template_config=template_config).render('xml')
+            config=config).render('xml')
     constance.output(os.path.join(dir, 'firehose.atom'), rendered)
diff --git a/reading.py b/reading.py
@@ -10,7 +10,7 @@ import constance
 import viewutils
 
 template_loader = genshi.template.TemplateLoader(
-        os.path.join(os.path.dirname(__file__), 'templates', 'reading'), 
+        os.path.join(os.path.realpath(os.path.dirname(__file__)), 'templates', 'reading'), 
         variable_lookup='strict')
 
 class ReadingLogEntry(object):
@@ -25,9 +25,9 @@ class ReadingLogEntry(object):
         self.tags = frozenset()
         self.guid = yaml_dict['GUID']
 
-    def generate_atom(self, template_config):
+    def generate_atom(self, config):
         return template_loader.load('entry.atom').generate(item=self,
-                template_config=template_config)
+                config=config)
 
 class ReadingLogEntrySet(object):
 
@@ -43,17 +43,17 @@ class ReadingLogEntrySet(object):
     def __len__(self):
         return len(self.entries)
 
-def generate(filename, xslt, template_config):
+def generate(filename, xslt, config):
     entries = ReadingLogEntrySet(filename)
 
     rendered = template_loader.load('reading.html').generate(items=entries,
-            template_config=template_config).render('xhtml')
+            config=config).render('xhtml')
     transformed = str(xslt(lxml.etree.fromstring(rendered)))
     constance.output(os.path.join(os.path.dirname(filename), 'reading.html'), transformed)
 
     # feed
     rendered = template_loader.load('reading.atom').generate(items=entries,
-            template_config=template_config).render('xml')
+            config=config).render('xml')
     constance.output(os.path.join(os.path.dirname(filename), 'reading.atom'), rendered)
 
     return entries
diff --git a/tags.py b/tags.py
@@ -9,10 +9,10 @@ import constance
 import viewutils
 
 template_loader = genshi.template.TemplateLoader(
-        os.path.join(os.path.dirname(__file__), 'templates', 'tags'), 
+        os.path.join(os.path.realpath(os.path.dirname(__file__)), 'templates', 'tags'), 
         variable_lookup='strict')
 
-def generate(dir, xslt, blog_entries, template_config):
+def generate(dir, xslt, blog_entries, config):
     tag_freqs = {}
     for entry in blog_entries:
         for tag in entry.tags:
@@ -25,6 +25,6 @@ def generate(dir, xslt, blog_entries, template_config):
         constance.output(os.path.join(dir, tag.encode('utf8') + '.html'), transformed)
 
     rendered = template_loader.load('index.html').generate(tag_freqs=tag_freqs,
-            template_config=template_config).render('xhtml')
+            config=config).render('xhtml')
     transformed = str(xslt(lxml.etree.fromstring(rendered)))
     constance.output(os.path.join(dir, 'index.html'), transformed)
diff --git a/templates/blog/entry.atom b/templates/blog/entry.atom
@@ -12,13 +12,13 @@ from viewutils import ATOM_TIME_FORMAT
 <published>${item.publication_date.strftime(ATOM_TIME_FORMAT)}</published>
 <updated>${item.modified_date.strftime(ATOM_TIME_FORMAT)}</updated>
 <author>
-    <name>${template_config.get('name')}</name>
-    <email>${template_config.get('email')}</email>
+    <name>${config.get('global', 'name')}</name>
+    <email>${config.get('global', 'email')}</email>
 </author>
-<category py:for="tag in item.tags" scheme="${template_config.get('website')}/tags/" term="${tag}" />
-<link rel="alternate" href="${template_config.get('website')}/blog/${urllib.quote(item.id.encode('utf8'), '')}" />
+<category py:for="tag in item.tags" scheme="${config.get('global', 'url_base')}tags/" term="${tag}" />
+<link rel="alternate" href="${config.get('global', 'url_base')}blog/${urllib.quote(item.id.encode('utf8'), '')}" />
 <title type="text">${item.title.striptags()}</title>
-<content type="xhtml" xml:base="${template_config.get('website')}/blog/${urllib.quote(item.id.encode('utf8'), '')}">
+<content type="xhtml" xml:base="${config.get('global', 'url_base')}blog/${urllib.quote(item.id.encode('utf8'), '')}">
     <div xmlns="http://www.w3.org/1999/xhtml">
         ${item.body}
     </div>
diff --git a/templates/blog/entry.html b/templates/blog/entry.html
@@ -7,13 +7,13 @@ from viewutils import tag_list
 ?>
 
 <head>
-    <title>${item.title.striptags()}</title>
+    <title>${item.title.striptags()} - ${config.get('blog', 'title')}</title>
     <meta name="DC.date" content="${item.publication_date.strftime(str('%Y-%m-%d'))}" />
 </head>
 <body>
     <div class="item blog-entry" py:attrs="(item.language is not None) and {'lang': item.language} or {}">
 
-        <h1 class="entry-title"><a href="${template_config.get('website')}/blog/${item.id}" rel="bookmark">${item.title}</a></h1>
+        <h1 class="entry-title"><a href="${config.get('global', 'url_base')}blog/${item.id}" rel="bookmark">${item.title}</a></h1>
 
         <div class="date published">${item.publication_date.strftime(str('%-1d %b %Y'))}</div>
 
@@ -25,16 +25,16 @@ from viewutils import tag_list
             ${item.body}
         </div>
 
-        <py:if test="template_config.get('disqus_user') is not None and template_config.get('disqus_user') != ''">
+        <py:if test="config.get('disqus', 'site')">
         <div id="disqus_thread"></div>
         <script type="text/javascript">
           (function() {
            var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
-           dsq.src = 'http://${template_config.get("disqus_user")}.disqus.com/embed.js';
+           dsq.src = 'http://${config.get("disqus", "site")}.disqus.com/embed.js';
            (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
           })();
         </script>
-        <noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript=${template_config.get('disqus_user')}">comments powered by Disqus.</a></noscript>
+        <noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript=${config.get('disqus', 'site')}">comments powered by Disqus.</a></noscript>
         </py:if>
 
     </div>
diff --git a/templates/blog/index.atom b/templates/blog/index.atom
@@ -7,15 +7,15 @@ from viewutils import ATOM_TIME_FORMAT
 sorted_items = sorted(items, key=lambda item: item.publication_date, reverse=True)
 ?>
 
-<id>${template_config.get('website')}/blog/index.atom</id>
-<title type="text">Blog entries</title>
-<link rel="self" type="application/atom+xml" href="${template_config.get('website')}/blog/index.atom" />
-<link rel="alternate" href="${template_config.get('website')}/blog/" />
+<id>${config.get('global', 'url_base')}blog/index.atom</id>
+<title type="text">${config.get('blog', 'title')}</title>
+<link rel="self" type="application/atom+xml" href="${config.get('global', 'url_base')}blog/index.atom" />
+<link rel="alternate" href="${config.get('global', 'url_base')}blog/" />
 <generator>constance</generator>
 <updated py:if="sorted_items">${max(item.modified_date for item in sorted_items).strftime(ATOM_TIME_FORMAT)}</updated>
 
 <py:for each="item in sorted_items">
-    ${item.generate_atom(template_config)}
+    ${item.generate_atom(config)}
 </py:for>
 
 </feed>
diff --git a/templates/blog/index.html b/templates/blog/index.html
@@ -8,13 +8,13 @@ from viewutils import markdown, mini_markdown, tag_list
 ?>
 
 <head>
-    <title>Blog archive</title>
+    <title>${config.get('blog', 'title')}</title>
     <link rel="alternate" type="application/atom+xml" title="Atom feed" href="index.atom" />
 </head>
 
 <body>
 
-    <h1>Blog archive</h1>
+    <h1>${config.get('blog', 'title')}</h1>
 
     <py:for each="year, items in groupby(sorted(items, key=lambda e: e.publication_date, reverse=True), key=lambda e: e.publication_date.year)">
         <h2>${year}</h2>
diff --git a/templates/homepage/firehose.atom b/templates/homepage/firehose.atom
@@ -7,15 +7,15 @@ from viewutils import ATOM_TIME_FORMAT
 sorted_items = sorted(items, key=lambda item: item.publication_date, reverse=True)
 ?>
 
-<id>${template_config.get('website')}/firehose.atom</id>
-<title type="text">Firehose</title>
-<link rel="self" type="application/atom+xml" href="${template_config.get('website')}/firehose.atom" />
-<link rel="alternate" href="${template_config.get('website')}/" />
+<id>${config.get('global', 'url_base')}firehose.atom</id>
+<title type="text">${config.get('homepage', 'firehose_Title')}</title>
+<link rel="self" type="application/atom+xml" href="${config.get('global', 'url_base')}firehose.atom" />
+<link rel="alternate" href="${config.get('global', 'url_base')}" />
 <generator>constance</generator>
 <updated py:if="sorted_items">${max(item.modified_date for item in sorted_items).strftime(ATOM_TIME_FORMAT)}</updated>
 
 <py:for each="item in sorted_items">
-    ${item.generate_atom(template_config)}
+    ${item.generate_atom(config)}
 </py:for>
 
 </feed>
diff --git a/templates/homepage/index.html b/templates/homepage/index.html
@@ -9,6 +9,17 @@ from viewutils import markdown, mini_markdown, tag_list
 
 <head>
     <link rel="alternate" type="application/atom+xml" title="Atom feed" href="firehose.atom" />
+    <title>${config.get('homepage', 'title')}</title>
+    <meta py:if="config.get('homepage', 'icbm')" name="ICBM" content="${config.get('homepage', 'icbm')}" />
+    <py:if test="config.get('homepage', 'openid_delegate')">
+        <link rel="openid.delegate" href="${config.get('homepage', 'openid_delegate')}" />
+        <link rel="openid2.local_id" href="${config.get('homepage', 'openid_delegate')}" />
+    </py:if>
+    <py:if test="config.get('homepage', 'openid_server')">
+        <link rel="openid.server" href="${config.get('homepage', 'openid_server')}" />
+        <link rel="openid2.provider" href="${config.get('homepage', 'openid_server')}" />
+    </py:if>
+    <meta py:if="config.get('homepage', 'xrds')" http-equiv="X-XRDS-Location" content="${config.get('homepage', 'xrds')}" />
 </head>
 
 <body>
diff --git a/templates/reading/entry.atom b/templates/reading/entry.atom
@@ -10,10 +10,10 @@ from viewutils import ATOM_TIME_FORMAT
 <published>${item.publication_date.strftime(ATOM_TIME_FORMAT)}</published>
 <updated>${item.modified_date.strftime(ATOM_TIME_FORMAT)}</updated>
 <author>
-    <name>${template_config.get('name')}</name>
-    <email>${template_config.get('email')}</email>
+    <name>${config.get('global', 'name')}</name>
+    <email>${config.get('global', 'email')}</email>
 </author>
-<category py:for="tag in item.tags" scheme="${template_config.get('website')}/tags/" term="${tag}" />
+<category py:for="tag in item.tags" scheme="${config.get('global', 'url_base')}tags/" term="${tag}" />
 <title type="text">${item.title.striptags()} by ${item.author}</title>
 <summary py:if="item.rating" type="text">${item.rating} stars</summary>
 <content type="xhtml">
diff --git a/templates/reading/reading.atom b/templates/reading/reading.atom
@@ -7,15 +7,15 @@ from viewutils import ATOM_TIME_FORMAT
 sorted_items = sorted(items, key=lambda item: item.publication_date, reverse=True)
 ?>
 
-<id>${template_config.get('website')}/reading.atom</id>
-<title type="text">Reading log</title>
-<link rel="self" type="application/atom+xml" href="${template_config.get('website')}/reading.atom" />
-<link rel="alternate" href="${template_config.get('website')}/reading" />
+<id>${config.get('global', 'url_base')}reading.atom</id>
+<title type="text">${config.get('reading', 'title')}</title>
+<link rel="self" type="application/atom+xml" href="${config.get('global', 'url_base')}reading.atom" />
+<link rel="alternate" href="${config.get('global', 'url_base')}reading" />
 <generator>constance</generator>
 <updated py:if="sorted_items">${max(item.modified_date for item in sorted_items).strftime(ATOM_TIME_FORMAT)}</updated>
 
 <py:for each="item in sorted_items">
-    ${item.generate_atom(template_config)}
+    ${item.generate_atom(config)}
 </py:for>
 
 </feed>
diff --git a/templates/reading/reading.html b/templates/reading/reading.html
@@ -11,13 +11,13 @@ from viewutils import markdown, mini_markdown, tag_list, idify
 </span>
 
 <head>
-    <title>Reading log</title>
+    <title>${config.get('reading', 'title')}</title>
     <link rel="alternate" type="application/atom+xml" title="Atom feed" href="reading.atom" />
 </head>
 
 <body>
 
-    <h1>Reading log</h1>
+    <h1>${config.get('reading', 'title')}</h1>
 
     <py:for each="item in sorted(items, key=lambda e: e.publication_date, reverse=True)">
         <div class="item reading-log-entry">
diff --git a/templates/tags/index.html b/templates/tags/index.html
@@ -12,7 +12,7 @@
 
 <ol id="tagcloud">
     <li py:for="tag, freq in sorted(tag_freqs.iteritems(), key=lambda (t, f): t.lower())">
-        <!-- XXX script_name --><a rel="tag" href="/tags/${tag}" style="font-size: ${0.8 + (freq / 10.)}em;">${tag}</a>
+        <a rel="tag" href="${tag}" style="font-size: ${0.8 + (freq / 10.)}em;">${tag}</a>
         <span class="frequency">(used ${freq} times)</span>
     </li>
 </ol>
diff --git a/templates/tags/tag.html b/templates/tags/tag.html
@@ -16,7 +16,7 @@ from viewutils import markdown, mini_markdown, tag_list
     <h1>&ldquo;${tag}&rdquo; tag</h1>
 
     <div class="item blog-entry-stub" py:for="item in sorted(items, key=lambda e: e.publication_date, reverse=True)">
-        <h3 class="entry-title"><a href="/blog/${item.id}">${item.title}</a></h3>
+        <h3 class="entry-title"><a href="../blog/${item.id}">${item.title}</a></h3>
         <div class="date published">${item.publication_date.strftime(str('%-1d %b %Y'))}</div>
     </div>