sites/www.qmsk.net/map.py
branchsites
changeset 34 09196d5b2a39
parent 33 19ea04f4b0cd
--- /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)
+