diff -r 19ea04f4b0cd -r 09196d5b2a39 sites/www.qmsk.net/map.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sites/www.qmsk.net/map.py Sat Feb 07 17:10:06 2009 +0200 @@ -0,0 +1,120 @@ + +import os, os.path + +from lib import http, template, map + +import page, page_tree + +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, template) : + """ + Create, path is where the pages are stored. The list of pages is loaded from $path/list + """ + + # store + self.path = path + self.template = template + + # 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 + page = self._lookup_page(page_name) + + # pass on + return page.handle_request(request) +