commit efbd6cce6fda52db11fb43f9352192493684f627
parent b310f46eee5ea79e09fe3e00d6d28b41f379bb17
Author: Dan Callaghan <djc@djc.id.au>
Date: Mon, 7 Apr 2008 11:57:16 +1000
WIP
committer: Dan Callaghan <djc@djc.id.au>
--HG--
extra : convert_revision : 6725f9c7ea2ce129b9ac9acd922b6a661cce1450
Diffstat:
4 files changed, 148 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,2 @@
+*.pyc
+.*.sw?
diff --git a/blog.py b/blog.py
@@ -0,0 +1,89 @@
+import os
+from datetime import datetime
+import markdown
+
+
+BASE_DIR = '.'
+BASE_URL = '/blog'
+
+
+def cleanup_metadata(meta):
+ cleaned = {}
+ for k, v in meta.iteritems():
+ v = '\n'.join(v)
+ if k.endswith('date'):
+ v = datetime.strptime(v, '%Y-%m-%d %H:%M:%S')
+ cleaned[k] = v
+ return cleaned
+
+
+class EntryNotFoundError(ValueError): pass
+
+class EntryForbiddenError(ValueError): pass
+
+class CommentNotFoundError(ValueError): pass
+
+class CommentForbiddenError(ValueError): pass
+
+
+class Entry(object):
+
+ def __init__(self, id):
+ self.id = id
+ self.dir = os.path.join(BASE_DIR, id)
+ self.comments_dir = os.path.join(self.dir, 'comments')
+
+ if not os.path.exists(self.dir):
+ raise EntryNotFoundError()
+ if not os.access(self.dir, os.R_OK):
+ raise EntryForbiddenError()
+
+ self.raw = open(os.path.join(self.dir, 'content.txt'), 'r').read()
+ md = markdown.Markdown(extensions=['meta'])
+ self.body = md.convert(self.raw)
+ self.metadata = cleanup_metadata(md.Meta)
+ self.title = self.metadata['title']
+
+ self.categories = [cat.strip() for cat in self.metadata.get('categories', '').split(',')]
+ self.tags = [tag.strip() for tag in self.metadata.get('tags', '').split(',')]
+
+ self.modified_date = datetime.fromtimestamp(os.path.getmtime(os.path.join(self.dir, 'content.txt')))
+ self.publication_date = self.metadata.get('publication-date', None) or self.modified_date
+
+ def permalink(self):
+ return '%s/%s/' % (BASE_URL, self.id)
+
+ def has_comments(self):
+ """
+ Returns True if this Entry could *possibly* have comments, although it
+ may still have no comments (yet).
+ """
+ return os.path.isdir(self.comments_dir) and \
+ os.access(self.comments_dir, os.R_OK)
+
+ def comments(self):
+ for filename in sorted(os.listdir(self.comments_dir), key=int):
+ yield Comment(os.path.join(self.comments_dir, filename))
+
+ def comment(self, id):
+ return Comment(os.path.join(self.comments_dir, str(id)))
+
+
+class Comment(object):
+
+ def __init__(self, path):
+ if not os.path.exists(path):
+ raise CommentNotFoundError()
+ if not os.access(path, os.R_OK):
+ raise CommentForbiddenError()
+
+ self.raw = open(path, 'r').read()
+ md = markdown.Markdown(extensions=['meta'])
+ self.body = md.convert(self.raw)
+ self.metadata = md.Meta
+
+ self.author = self.metadata.get('from', None)
+ self.date = self.metadata['date']
+
+ def author_link(self):
+ return self.author or u'Anonymous'
diff --git a/handler.py b/handler.py
@@ -0,0 +1,9 @@
+import os
+from genshi.template import TemplateLoader
+
+from blog import BASE_DIR, Entry
+
+template_loader = TemplateLoader(os.path.join(BASE_DIR, 'templates'), auto_reload=True)
+
+def post(id):
+ print template_loader.load('post.xml').generate(entry=Entry(id)).render('xhtml')
diff --git a/templates/post.xml b/templates/post.xml
@@ -0,0 +1,48 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:py="http://genshi.edgewall.org/">
+<head>
+ <title>${entry.title}</title>
+</head>
+<body>
+
+<div id="content">
+ <div class="entry">
+
+ <h3 class="entrytitle" id="post-${entry.id}"><a href="${entry.permalink()}" rel="bookmark">${entry.title}</a></h3>
+
+ <div class="entrymeta">
+ Posted ${entry.publication_date.strftime(str('%-1d %B %Y'))}
+ <py:if test="entry.categories">
+ in ${', '.join(entry.categories)}
+ </py:if>
+ </div>
+
+ <div class="entrybody">
+ ${Markup(entry.body)}
+ <p py:if="entry.tags">
+ <img src="${BASE_URL}/templates/images/tag_blue.png" alt="Tags:" /> ${', '.join(entry.tags)}
+ </p>
+ </div>
+
+ </div>
+
+ <div id="commentblock" py:if="entry.has_comments()">
+ <ol class="commentlist" id="commentlist">
+ <li py:for="comment in entry.comments()"
+ class="(comment.id % 2) and 'alt' or 'standard'"
+ id="comment-${comment.id}">
+ <div class="commentmeta">
+ ${comment.author_link()}
+ on ${comment.date.strftime(str('F j, Y'))}
+ </div>
+ <div class="commentbody">
+ ${comment.body}
+ </div>
+ </li>
+ </ol>
+ </div>
+</div>
+
+</body>
+</html>