commit 1eb8f5eaf1503ab2e02e523a6dc5d82ff6ebcdc7
parent 77d9488ba0972f856d5839e4c44e34dd8d36c78b
Author: Dan Callaghan <djc@djc.id.au>
Date: Fri, 5 Sep 2008 22:58:40 +1000
restructured blog.py a bit, now supports having no readinglog
Diffstat:
6 files changed, 60 insertions(+), 60 deletions(-)
diff --git a/TODO b/TODO
@@ -1,5 +1,3 @@
-- handle absent readinglog
-- restructure blog.py class hierarchy: EntrySet, DirectoryEntrySet, YamlStreamSet, ... or something
- ignore pages in export_wp.py
- feeds everywhere else
- monthly archives
diff --git a/app.py b/app.py
@@ -2,6 +2,7 @@
# vim:encoding=utf-8
import os
+from itertools import chain
import wsgiref.util
from genshi.template import TemplateLoader
from colubrid import RegexApplication, HttpResponse
@@ -28,12 +29,17 @@ class Constance(RegexApplication):
super(Constance, self).__init__(*args, **kwargs)
self.request.environ['APP_URI'] = wsgiref.util.application_uri(self.request.environ) # Colubrid ought to do this for us
self.config = config.ConstanceConfigParser(self.request.environ['constance.config_filename'])
- self.entries = blog.Entries(self.config.getunicode('blog', 'dir'),
- self.config.getunicode('readinglog', 'filename'))
+ self.blog_entries = blog.BlogEntrySet(self.config.getunicode('blog', 'dir'))
+ readinglog_filename = self.config.getunicode('readinglog', 'filename')
+ if readinglog_filename:
+ self.readinglog_entries = blog.ReadingLogEntrySet(readinglog_filename)
+ else:
+ self.readinglog_entries = frozenset()
def index(self):
offset = int(self.request.args.get('offset', 0))
- sorted_entries = sorted(self.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)
format = self.request.args.get('format', 'html')
if format == 'html':
rendered = template_loader.load('multiple.xml').generate(
@@ -60,7 +66,7 @@ class Constance(RegexApplication):
def post(self, id):
id = id.decode(self.charset) # shouldn't Colubrid do this?
try:
- entry = self.entries[id]
+ entry = self.blog_entries[id]
rendered = template_loader.load('single.xml').generate(
config=self.config,
environ=self.request.environ,
@@ -72,12 +78,11 @@ class Constance(RegexApplication):
def tag(self, tag):
tag = tag.decode(self.charset)
- by_tag = self.entries.by_tag()
- if tag not in by_tag:
+ with_tag = [e for e in self.blog_entries if tag in e.tags]
+ if not with_tag:
raise PageNotFound()
offset = int(self.request.args.get('offset', 0))
- entries = by_tag[tag]
- sorted_entries = sorted(entries, key=lambda e: e.publication_date, reverse=True)
+ sorted_entries = sorted(with_tag, key=lambda e: e.publication_date, reverse=True)
format = self.request.args.get('format', 'html')
if format == 'html':
rendered = template_loader.load('multiple.xml').generate(
diff --git a/blog.py b/blog.py
@@ -1,6 +1,5 @@
import os, re
from datetime import datetime
-from itertools import chain
import markdown
import genshi
import yaml
@@ -39,37 +38,42 @@ class CommentNotFoundError(ValueError): pass
class CommentForbiddenError(ValueError): pass
-class Entries(object):
+class DirectoryEntrySet(object):
+
+ def __init__(self, base_dir):
+ self.base_dir = base_dir
+ assert os.path.isdir(self.base_dir), self.base_dir
+
+ def __contains__(self, key):
+ return os.path.exists(os.path.join(self.base_dir, key))
+
+ def __getitem__(self, key):
+ if key not in self: raise KeyError(key)
+ return self.entry_class(self.base_dir, key)
+
+ def __len__(self):
+ return count(filename
+ for filename in os.listdir(self.base_dir)
+ if not filename.startswith('.'))
- def __init__(self, entries_dir, readinglog_file):
- self.entries_dir = entries_dir
- self.readinglog_file = readinglog_file
-
- def __contains__(self, id):
- return os.path.exists(os.path.join(self.entries_dir, id))
-
- def __getitem__(self, id):
- # XXX reading log entries don't have a key
- return Entry(self.entries_dir, id)
-
def __iter__(self):
- return chain(
- (Entry(self.entries_dir, filename)
- for filename in os.listdir(self.entries_dir)
- if not filename.startswith('.')),
- (ReadingLogEntry(d)
- for d in yaml.load_all(open(self.readinglog_file, 'r')))
- )
+ return (self.entry_class(self.base_dir, filename)
+ for filename in os.listdir(self.base_dir)
+ if not filename.startswith('.'))
+
- def by_tag(self):
- d = {}
- for entry in self:
- for tag in entry.tags:
- d.setdefault(tag, set()).add(entry)
- return d
+class YamlEntrySet(object):
+
+ def __init__(self, filename):
+ self.filename = filename
+ assert os.path.isfile(self.filename), self.filename
+
+ def __iter__(self):
+ return (self.entry_class(d)
+ for d in yaml.load_all(open(self.filename, 'r')))
-class Entry(object):
+class BlogEntry(object):
def __init__(self, entries_dir, id):
assert isinstance(id, unicode), id
@@ -99,7 +103,7 @@ class Entry(object):
self.guid = self.metadata['guid']
def comments(self):
- return Comments(self.comments_dir)
+ return CommentSet(self.comments_dir)
def has_comments(self):
"""
@@ -110,6 +114,11 @@ class Entry(object):
os.access(self.comments_dir, os.R_OK)
+class BlogEntrySet(DirectoryEntrySet):
+
+ entry_class = BlogEntry
+
+
class ReadingLogEntry(object):
def __init__(self, yaml_dict):
@@ -127,26 +136,9 @@ class ReadingLogEntry(object):
return False
-class Comments(object):
+class ReadingLogEntrySet(YamlEntrySet):
- def __init__(self, path):
- self.path = path
-
- def __contains__(self, id):
- return os.path.exists(os.path.join(self.path, id))
-
- def __len__(self):
- return count(filename
- for filename in os.listdir(self.path)
- if not filename.startswith('.'))
-
- def __getitem__(self, id):
- return Comment(self.path, id)
-
- def __iter__(self):
- return (Comment(self.path, filename)
- for filename in os.listdir(self.path)
- if not filename.startswith('.'))
+ entry_class = ReadingLogEntry
class Comment(object):
@@ -171,3 +163,8 @@ class Comment(object):
def author_name(self):
return self.author or u'Anonymous'
+
+
+class CommentSet(DirectoryEntrySet):
+
+ entry_class = Comment
diff --git a/config.defaults b/config.defaults
@@ -21,7 +21,7 @@ dir = ./entries
[readinglog]
# The name of the file containing a YAML stream of readinglog entries.
-filename = ./reading_log
+filename =
# Should LibraryThing covers be shown for readinglog entries?
# See also librarything_devkey below.
diff --git a/templates/_entry.xml b/templates/_entry.xml
@@ -8,7 +8,7 @@ import blog
from viewutils import mini_markdown, tag_list
?>
-<div class="entry" py:if="isinstance(entry, blog.Entry)">
+<div class="entry" py:if="isinstance(entry, blog.BlogEntry)">
<h3 class="entrytitle" id="post-${entry.id}">${mini_markdown(entry.title)}</h3>
diff --git a/templates/multiple_atom.xml b/templates/multiple_atom.xml
@@ -25,7 +25,7 @@ ATOM_TIME_FORMAT = str('%Y-%m-%dT%H:%M:%S+10:00')
<email py:if="email">${email}</email>
</author>
<category py:for="tag in entry.tags" scheme="${environ['APP_URI']}/+tags/" term="${tag}" />
- <py:if test="isinstance(entry, blog.Entry)">
+ <py:if test="isinstance(entry, blog.BlogEntry)">
<link rel="alternate" href="${environ['APP_URI']}/${entry.id}" />
<title type="text">${entry.title}</title>
<content type="xhtml" xml:base="${environ['APP_URI']}/${entry.id}"><xhtml:div>