--- /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)
+