author | Tero Marttila <terom@fixme.fi> |
Sat, 07 Feb 2009 16:33:27 +0200 | |
branch | sites |
changeset 31 | 107062ebb6f9 |
child 32 | be954df4f0e8 |
permissions | -rw-r--r-- |
import os, os.path from lib import http, template, map import page, page_tree, menu class FilesystemMapper (map.Mapper) : """ Translates requests to handlers based on a filesystem directory containing various kinds of files """ # list of page handlers, by type PAGE_TYPES = [ ('html', page.HTMLPage ), (template.TEMPLATE_EXT, page.TemplatePage ), ] def __init__ (self, path) : """ Create, path is where the pages are stored. The list of pages is loaded from $path/list """ # store self.path = path # load the page tree self.tree = page_tree.PageTree(path + '/list') def _lookup_page_type (self, url, path, filename, basename, extension, tail) : """ We found the file that we looked for, now get the correct type """ # find appropriate handler for handler_ext, type in self.PAGE_TYPES : # match against file extension? if handler_ext == extension : # found handler, return instance return type(self, url, path, basename, tail) # no handler found raise PageError("No handler found for page %r of type %r" % (url, extension)) def _lookup_page (self, name) : """ Look up and return a Page object for the given page, or raise an error """ # inital path path = self.path url_segments = [] # name segments segments = name.split('/') # iterate through the parts of the page segments while True : segment = None # pop segment if segments : segment = segments.pop(0) 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 self._lookup_page_type('/'.join(url_segments), file_path, filename, basename, extension, '/'.join(segments)) else : # inspect next file in dir continue else : # did not find any dir or file, break out of while loop break # did not find the filename we were looking for in os.listdir raise PageError("Page not found: %s" % name, status='404 Not Found') def handle_request (self, request) : """ Looks up the appropriate Page, and then renders it """ # determine the page name page_name = request.get_page_name() # get the page handler p = self._lookup_page(page_name) # bind to request p.bind_request(request) # render the template response_data = template.render("layout", site_root_url = request.get_script_dir(), site_page_url = request.get_page_prefix(), page = p, menu = menu.Menu(self, p), ) # return the response return http.Response(response_data)