--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/site/loaders.py Fri Feb 06 20:46:43 2009 +0200
@@ -0,0 +1,160 @@
+
+from __future__ import with_statement
+
+# XXX: for _HTMLPage
+import page
+import templates
+
+from pages import error404
+
+import os.path
+import imp
+
+# the page dir
+PAGE_DIR_PATH = "pages/"
+
+def build_page_path (*bits) :
+ # XXX: fix directory traversal...
+
+ return os.path.join(PAGE_DIR_PATH, *bits)
+
+class PageLoader (object) :
+ """
+ Load Page objects from files under pages/
+ """
+
+ # file extension, e.g. '.html' or '.py'
+ suffix = None
+
+ def __init__ (self, suffix) :
+ self.suffix = suffix
+
+ def _build_path (self, page_path) :
+ """
+ Builds a path from base_path + page_path + suffix. Returns None if the path does not exist
+ """
+
+ path = build_page_path(page_path) + self.suffix
+
+ if os.path.exists(path) :
+ return path
+
+ else :
+ return None
+
+ def load (self, page_path) :
+ """
+ Attempts to load the page at the given path, returns the class on success, None on failure
+ """
+
+ abstract
+
+class _HTMLPage (page.Page) :
+ # the path to the .html file
+ file_path = None
+
+ # parent page
+ # parent = None
+
+ def __init__ (self, *args) :
+ super(_HTMLPage, self).__init__(*args)
+
+ # open the .html and read in the contents
+ with open(self.file_path, "r") as fh :
+ self.file_data = fh.read()
+
+ def render_template (self) :
+ tpl = self._build_template(templates.layout)
+
+ tpl.page_content = self.file_data
+
+ return tpl
+
+class HTMLLoader (PageLoader) :
+ """
+ Static .html files that are inserted into the layout template as-is
+
+ Sub-pages are not supported...
+ """
+
+ def __init__ (self) :
+ super(HTMLLoader, self).__init__(".html")
+
+ def get_title (self, page_path) :
+ head, tail = os.path.split(page_path)
+
+ return tail.title() if tail else "Index"
+
+ def load (self, _page_path) :
+ _file_path = self._build_path(_page_path)
+
+ # ignore if it doesn't exist
+ if not _file_path :
+ return
+
+ # get page title
+ _title = self.get_title(_page_path)
+
+ # create a new class and return it
+ class _html_page (_HTMLPage) :
+ file_path = _file_path
+ title = _title
+ name = _title
+ path = _page_path
+
+ # return it
+ return _html_page
+
+class PythonLoader (PageLoader) :
+ """
+ Dynamic .py files that define a Page class
+ """
+
+ def __init__ (self) :
+ super(PythonLoader, self).__init__(".py")
+
+ def load (self, page_path) :
+ path = self._build_path(page_path)
+
+ # ignore if not exists
+ if not path :
+ return
+
+ # load the module dynamically
+ module = imp.load_source("__dyn_%d" % id(path), path)
+
+ # return the Page object
+ return module.Page
+
+# our defined loaders
+loaders = [
+ HTMLLoader(),
+ PythonLoader(),
+]
+
+def load_page (req) :
+ """
+ Returns an instance of a Page object corresponding to the given req
+ """
+
+ # page path is given in req
+ page_path = req.page_path
+
+ # if it's a dir, then add 'index'
+ if os.path.isdir(build_page_path(page_path)) :
+ page_path = os.path.join(page_path, "index")
+
+ # try each loader in turn
+ for loader in loaders :
+ page = loader.load(req.page_path)
+
+ # found?
+ if page :
+ break
+
+ # 404 error...
+ if not page :
+ page = error404.Error404
+
+ return page(req, req.page_path)
+