more path fixes
[wrigit.git] / wrigit.cgi
blobfc36f40fa26f0bd51823ff1fe0fb32606f06e112
1 #!/usr/bin/env python
2 # -*- mode: python -*-
4 import os, time, datetime
5 from os.path import join, abspath
7 from docutils import core
8 from docutils.parsers import rst
9 from docutils.writers.html4css1 import Writer, HTMLTranslator
11 from mako.template import Template
12 from mako.lookup import TemplateLookup
14 def envride(name, default):
15 return os.environ.get(name, default)
17 conf = dict(
18 rst_dir = abspath(envride('RSTDIR', './example/')),
19 templates_dir = abspath(envride('TEMPLATESDIR', './example/')),
20 base_url = envride('BASEURL', 'http://localhost:8080/') # ends with slash
23 def htmlpath(rst_path):
24 """Return the .html path for the given .rst path"""
25 assert rst_path.endswith('.rst'), '<%s> is not a rst path' % rst_path
26 return rst_path[:-4] + '.html'
28 class Page(object):
29 """A rst page"""
31 def __init__(self, rst_path):
32 self.rst_path = rst_path
33 writer = Writer()
34 writer.translator_class = DocInfoProxy # see comment for `DocInfoProxy`
36 parts = core.publish_parts(
37 source=open(rst_path).read(),
38 source_path=rst_path, writer=writer)
39 self.title, self.fragment = parts['title'], parts['fragment']
40 self.meta = DocInfoProxy.ITEMS.copy()
42 def url(self):
43 path_info = htmlpath(self.rst_path[len(conf['rst_dir']):])
44 return conf['base_url'] + path_info
46 class BlogPost(Page):
48 def date(self):
49 if '|' in self.meta['date']:
50 format = '%Y-%m-%d|%M:%S'
51 else:
52 format = '%Y-%m-%d'
54 return datetime.datetime(
55 *time.strptime(self.meta['date'],
56 format)[0:6])
58 def __cmp__(self, other):
59 return cmp(self.date(), other.date())
61 def __repr__(self):
62 return '<BlogPost "%s" on %s>' % (self.title, self.date())
65 # This is a temporary hack - to extract the 'custom fields' from
66 # docutil's `docinfo` node.
68 # `HTMLTranslator` happens to process the docinfo tree and so we can steal
69 # the key,value pairs of custom fields from the `visit_field_name` function.
70 class DocInfoProxy(HTMLTranslator):
72 ITEMS = {}
74 def __init__(self, *args, **kwargs):
75 HTMLTranslator.__init__(self, *args, **kwargs)
76 DocInfoProxy.ITEMS = {}
77 self.__items = {}
79 # Custom fields are processed here (Tags and so on)
80 def visit_field_name(self, node):
81 key = node.astext().lower()
82 value = node.parent.children[1].astext() # from sibling
83 # print 'meta[%s] = {%s}' % (key, value)
84 DocInfoProxy.ITEMS[key] = value
85 return HTMLTranslator.visit_field_name(self, node)
87 # Standard fields are processed here (Date, Author and so on)
88 def visit_docinfo_item(self, node, name, meta=1):
89 key = name.lower()
90 value = node.parent.children[0].astext() # from sibling
91 # print '*meta[%s] = {%s}' % (key, value)
92 DocInfoProxy.ITEMS[key] = value
93 return HTMLTranslator.visit_docinfo_item(self, node, name, meta)
96 def rstfiles(directory):
97 for dir, subdirs, files in os.walk(directory):
98 for file in files:
99 if file.endswith('.rst'):
100 yield abspath(join(dir, file))
102 def mako():
103 templates = TemplateLookup(directories=[conf['templates_dir']])
104 def render(name, **kwargs):
105 return templates.get_template(name).render(**kwargs)
106 return render
107 mako = mako()
109 if __name__ == '__main__':
110 blog_posts = []
111 blog_path = abspath(join(conf['rst_dir'], 'blog'))
112 for f in rstfiles(conf['rst_dir']):
113 if blog_path in f:
114 page = BlogPost(f)
115 blog_posts.append(page)
116 else:
117 page = Page(f)
119 print '>', f
120 open(htmlpath(f), 'w').write(mako('page.mako', **locals()))
122 # generate blog index
123 blog_posts.sort()
124 blog_posts.reverse()
125 print 'Blog index:', blog_posts
126 open(os.path.join(
127 conf['rst_dir'],
128 'blog', 'index.html'),
129 'w').write(mako('blog/index.mako', **locals()))