]> git.llucax.com Git - software/forestcms.git/blob - fcms.py
ForestCMS - Filesystem-Oriented reST CMS
[software/forestcms.git] / fcms.py
1 # forestcms - Filesystem-Oriented reST CMS
2 # Or, for long, Filesystem-Oriented reStrcuturedText Content Management System
3
4 from __future__ import with_statement
5
6 import errno
7 from os import path
8 from wsgiref.simple_server import make_server
9 from pprint import pprint
10 from StringIO import StringIO
11 from docutils.core import publish_parts
12 import threading
13
14 local = threading.local()
15
16 class Conf:
17         pass
18
19 conf = Conf()
20 conf.docroot = '.' # 'docroot'
21 conf.sysroot = 'sysroot'
22
23 STATUS = {
24         200: 'OK',
25         404: 'Not Found',
26 }
27
28 class HttpError (Exception):
29         def __init__(self, status):
30                 self.status = status
31
32 def page2fname(page):
33         if not page or page == '/':
34                 page = '/index'
35         return path.join(conf.docroot, page[1:]) + '.rst'
36
37 def status2rstfile(status):
38         return path.join(conf.sysroot, str(status)) + '.rst'
39
40 def render_rst(rst, whole=True):
41         what = 'whole' if whole else 'html_body'
42         content = publish_parts(rst, writer_name="html")[what]
43         return content.encode('utf-8')
44
45 def render_file(fname, whole=True):
46         try:
47                 with file(fname) as f:
48                         rst = f.read()
49         except IOError, e:
50                 if e.errno == errno.ENOENT:
51                         raise HttpError(404)
52         return render_rst(rst, whole)
53
54 def render_page(page, whole=True):
55         fname = page2fname(page)
56         return render_file(fname, whole)
57
58 def forestcms(environ, start_response):
59         local.page = environ['PATH_INFO']
60         local.env = environ
61         local.headers = [('Content-type', 'text/html; charset=utf-8')]
62         output = ''
63         try:
64                 status = 200
65                 output = render_page(local.page)
66         except HttpError, e:
67                 status = e.status
68                 output = render_file(status2rstfile(status))
69         status = '%s %s' % (status, STATUS[status])
70         start_response(status, local.headers)
71         return [output]
72
73 httpd = make_server('', 8000, forestcms)
74 httpd.serve_forever()
75