From 87957915307f1571e266d3a7f67d560bfad50390 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Tue, 22 Dec 2009 22:05:34 -0300 Subject: [PATCH] ForestCMS - Filesystem-Oriented reST CMS ForestCMS stands for Filesystem-Oriented reStructuredText Content Management System. It's inspired in the ideas brought by the Hooks PHP framework for content managements and it's intended to make easy to publish contents in a filesystem-oriented way (i.e. use the hierarchical nature of the filesystem to build a tree-like content management). This makes very easy to manage contents without a web interface (by just editing files in the filesystem). A web interface can come in the future, thoug. ForestCMS is written in Python, and the content is written in reST instead of HTML. This is the initial commit with just a proof of concept, a small web server that serve reST files as if they were web pages. --- README.rst | 50 +++++++++++++++++++++++++++++++++ fcms.py | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ sysroot/404.rst | 7 +++++ 3 files changed, 132 insertions(+) create mode 100644 README.rst create mode 100644 fcms.py create mode 100644 sysroot/404.rst diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..75dc902 --- /dev/null +++ b/README.rst @@ -0,0 +1,50 @@ + +=========== +|ForestCMS| +=========== + +|ForestCMS| stands for "Filesystem_-Oriented reST_ CMS_" (or +"Filesystem_-Oriented reStructuredText_ `Content Management System`_" for long +;). + +It's a `Web CMS`_ inspired in the ideas brought by the Hooks_ PHP_ framework +for content managements and it's intended to make easy to publish contents in +a filesystem_-oriented way (i.e. use the hierarchical nature of the filesystem_ +to build a tree-like content database). This makes very easy to manage contents +without a web interface (by just editing files in the filesystem_). A web +interface can come in the future, though, it just have to manage files in the +filesystem_ instead of rows in a relational database. + +|ForestCMS| is written in Python_, and the content is written in +reStructuredText_ instead of HTML_. Why? Just because reStructuredText_ is +great for writing content, and if you *really* need to do some nasty HTML_ +tricks, you can always use the `raw directive`_. + + + +Quick Test +========== + +If you want to quickly try ForestCMS just run:: + + python fcms.py + +And point your browser to http://localhost:8000/README to see this very same +file rendered as HTML_. + + + +.. |ForestCMS| replace:: **ForestCMS** + +.. _PHP: http://www.php.net/ +.. _Python: http://www.python.org/ +.. _reStructuredText: +.. _reST: http://docutils.sourceforge.net/rst.html +.. _Hooks: http://hooks.gforge.lug.fi.uba.ar/hooks/docs/html/ +.. _HTML: http://en.wikipedia.org/wiki/HTML +.. _Filesystem: http://en.wikipedia.org/wiki/Filesystem +.. _Content Management System: +.. _CMS: http://en.wikipedia.org/wiki/Content_Management_System +.. _Web CMS: http://en.wikipedia.org/wiki/Web_Content_Management_System +.. _raw directive: http://docutils.sourceforge.net/docs/ref/rst/directives.html#raw-data-pass-through + diff --git a/fcms.py b/fcms.py new file mode 100644 index 0000000..3a9903c --- /dev/null +++ b/fcms.py @@ -0,0 +1,75 @@ +# forestcms - Filesystem-Oriented reST CMS +# Or, for long, Filesystem-Oriented reStrcuturedText Content Management System + +from __future__ import with_statement + +import errno +from os import path +from wsgiref.simple_server import make_server +from pprint import pprint +from StringIO import StringIO +from docutils.core import publish_parts +import threading + +local = threading.local() + +class Conf: + pass + +conf = Conf() +conf.docroot = '.' # 'docroot' +conf.sysroot = 'sysroot' + +STATUS = { + 200: 'OK', + 404: 'Not Found', +} + +class HttpError (Exception): + def __init__(self, status): + self.status = status + +def page2fname(page): + if not page or page == '/': + page = '/index' + return path.join(conf.docroot, page[1:]) + '.rst' + +def status2rstfile(status): + return path.join(conf.sysroot, str(status)) + '.rst' + +def render_rst(rst, whole=True): + what = 'whole' if whole else 'html_body' + content = publish_parts(rst, writer_name="html")[what] + return content.encode('utf-8') + +def render_file(fname, whole=True): + try: + with file(fname) as f: + rst = f.read() + except IOError, e: + if e.errno == errno.ENOENT: + raise HttpError(404) + return render_rst(rst, whole) + +def render_page(page, whole=True): + fname = page2fname(page) + return render_file(fname, whole) + +def forestcms(environ, start_response): + local.page = environ['PATH_INFO'] + local.env = environ + local.headers = [('Content-type', 'text/html; charset=utf-8')] + output = '' + try: + status = 200 + output = render_page(local.page) + except HttpError, e: + status = e.status + output = render_file(status2rstfile(status)) + status = '%s %s' % (status, STATUS[status]) + start_response(status, local.headers) + return [output] + +httpd = make_server('', 8000, forestcms) +httpd.serve_forever() + diff --git a/sysroot/404.rst b/sysroot/404.rst new file mode 100644 index 0000000..ec3bd16 --- /dev/null +++ b/sysroot/404.rst @@ -0,0 +1,7 @@ + +========= +Not Found +========= + +The requested page was not found in this server. + -- 2.43.0