--- a/lib/page.py Fri Feb 06 21:31:02 2009 +0200
+++ b/lib/page.py Fri Feb 06 22:48:00 2009 +0200
@@ -3,19 +3,169 @@
Handling page requests
"""
-def handle_html (env) :
- return "A HTML page"
+# for filesystem ops
+import os, os.path
+# for ResponseError
+import http
+
+# for TemplatePage
+import template
+
+# path to directory containing the page heirarcy
+PAGE_DIR = "pages"
+
+class PageError (http.ResponseError) :
+ """
+ Error looking up/handling a page
+ """
+
+ pass
+
+class Page (object) :
+ """
+ This object represents the information about our attempt to render some specific page
+ """
+
+ def __init__ (self, url, path, basename, url_tail) :
+ """
+ Initialize the page at the given location
+
+ @param url the URL leading to this page
+ @param path the filesystem path to this page's file
+ @param basename the filesystem name of this page's file, without the file extension
+ @param url_trail trailing URL for this page
+ """
+
+ # store
+ self.url = url
+ self.path = path
+ self.basename = basename
+ self.url_tail = url_tail
+
+ # sub-init
+ self._init()
+
+ def _init (self) :
+ """
+ Do initial data loading, etc
+ """
+
+ pass
+
+ def get_title (self) :
+ """
+ Return the page's title
+
+ Defaults to the Titlecase'd file basename
+ """
+
+ return self.basename.title()
+
+ def get_content (self) :
+ """
+ Return the page content as a string
+ """
+
+ abstract
+
+class HTMLPage (Page) :
+ """
+ A simple .html page that's just passed through directly
+ """
+
+ def get_content (self) :
+ """
+ Opens the .html file, reads and returns contents
+ """
+
+ return open(self.path, 'rb').read()
+
+class TemplatePage (Page) :
+ """
+ A template that's rendered using our template library
+ """
+
+ def get_content (self) :
+ """
+ Loads the .tmpl file, and renders it
+ """
+
+ return template.render_file(self.path)
# list of page handlers, by type
-type_handlers = [
- ('.html', handle_html),
+TYPE_HANDLERS = [
+ ('html', HTMLPage ),
+ (template.TEMPLATE_EXT, TemplatePage ),
]
-def lookup_handler (path) :
+def _lookup_handler (url, path, filename, basename, extension, tail) :
"""
- Look up and return a handler for the given page, or raise an error
+ We found the file that we looked for, now get its handler
"""
- return handle_html
+ # find appropriate handler
+ for handler_ext, handler in TYPE_HANDLERS :
+ # match against file extension?
+ if handler_ext == extension :
+ # found handler, return instance
+ return handler(url, path, basename, tail)
+ # no handler found
+ raise PageError("No handler found for page %r of type %r" % (url, extension))
+
+def lookup (name) :
+ """
+ Look up and return a Page object for the given page, or raise an error
+ """
+
+ # inital path
+ path = PAGE_DIR
+ url_segments = []
+
+ # name segments
+ segments = name.split('/')
+
+ # iterate through the parts of the page segments
+ while segments :
+ # pop segment
+ segment = segments.pop(0)
+
+ # add to page url
+ url_segments.append(segment)
+
+ # translate empty -> index
+ if not segment :
+ segment = 'index'
+
+ # look for it in the dir
+ for filename in os.listdir(path) :
+ # build full file path
+ file_path = os.path.join(path, filename)
+
+ # stat, recurse into subdirectory?
+ if os.path.isdir(file_path) and filename == segment :
+ # use new dir
+ path = file_path
+
+ # break for-loop to look at next segment
+ break
+
+ # split into basename + extension
+ basename, extension = os.path.splitext(filename)
+
+ # ...remove that dot
+ extension = extension.lstrip('.')
+
+ # match against requested page name?
+ if basename == segment :
+ # found the file we wanted
+ return _lookup_handler('/'.join(url_segments), file_path, filename, basename, extension, '/'.join(segments))
+
+ else :
+ # inspect next file in dir
+ continue
+
+ # did not find the filename we were looking for in os.listdir
+ raise PageError("Page not found: %s" % name, status='404 Not Found')
+