diff -r 9ed4c7d2bdd2 -r 5565d94da522 lib/loaders.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/loaders.py Fri Feb 06 20:49:29 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) +