diff -r d6a8258bd90e -r 0ce1f471e9d7 lib/page.py --- 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') +