route requests through sites/www.qmsk.net, although still hardcoded sites
authorTero Marttila <terom@fixme.fi>
Sat, 07 Feb 2009 06:54:52 +0200
branchsites
changeset 30 a86a25a9f75b
parent 29 b06ff4c05d42
child 31 107062ebb6f9
route requests through sites/www.qmsk.net, although still hardcoded
lib/handler.py
lib/map.py
lib/site.py
lib/wsgi.py
sites/irclogs.qmsk.net/__init__.py
sites/irclogs.qmsk.net/urls.py
sites/www.qmsk.net/__init__.py
--- a/lib/handler.py	Sat Feb 07 06:05:10 2009 +0200
+++ b/lib/handler.py	Sat Feb 07 06:54:52 2009 +0200
@@ -2,6 +2,24 @@
     The actual application behaviour, i.e. generating a Response from a Request :)
 """
 
+class Handler (object) :
+    """
+        A handler handles a Request, returning a Response
+    """
+
+    def __init__ (self, func, *args, **kwargs) :
+        self.func = func
+        self.args = args
+        self.kwargs = kwargs
+    
+    def handle_request (self, request) :
+        """
+            Handle the request, returning a Response object
+        """
+
+        return self.func(request, *self.args, **self.kwargs)
+
+# fs handler
 import http, page, menu, template
 
 def handle_request (request) :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/map.py	Sat Feb 07 06:54:52 2009 +0200
@@ -0,0 +1,112 @@
+"""
+    Handles mapping URLs to request handlers
+"""
+
+import http
+import handler
+
+class MappingError (http.ResponseError) :
+    """
+        URL could not be mapped
+    """
+
+    def __init__ (self, url) :
+        super(MappingError, self).__init__("URL not found: %s" % (url, ), status='404 Not Found')
+
+class Mapper (object) :
+    """
+        Translates requests to handlers
+    """
+
+    def map_request (self, request) :
+        """
+            Map the given request, returning a Handler
+        """
+
+        abstract
+
+class Mapping (object) :
+    """
+        A mapping object for StaticMapping
+    """
+
+    def test (self, request) :
+        """
+            Either return a handler, or None
+        """
+
+        abstract
+
+class RegexpMapping (object) :
+    """
+        A mapping object that uses regular expressions
+    """
+
+    def __init__ (self, regexp, handler) :
+        pass
+
+    def test (self, request) :
+        xxx
+
+class SimpleMapping (object) :
+    """
+        A mapping object that uses simple expressions
+    """
+
+    def __init__ (self, expression, handler) :
+        pass
+
+    def test (self, request) :
+        xxx
+
+class StaticMapping (Mapper) :
+    """
+        Translates requests to handlers using a list of pre-determined Mapping's
+    """
+
+    def __init__ (self, mappings) :
+        # store
+        self.mappings = mappings
+
+    def map_request (self, request) :
+        """
+            Returns the appropriate handler
+        """
+
+        # just test each mapping in turn
+        for mapping in self.mappings :
+            handler = mapping.test(request)
+
+            if handler :
+                return handler
+        
+        # fail, not found
+        raise MappingError(request.get_page_name())
+        
+class FilesystemMapper (Mapper) :
+    """
+        Translates requests to handlers based on a filesystem directory containing various kinds of files
+    """
+
+    def __init__ (self, path) :
+        """
+            Create, path is where the pages are stored
+        """
+        
+        # store
+        self.path = path
+    
+    def map_request (self, request) :
+        """
+            Looks up the appropriate Page, and then returns a generic Handler
+        """
+
+        # XXX: harcoded
+        return handler.Handler(handler.handle_request)
+
+# "friendly" names
+fstree  = FilesystemMapper
+
+map     = SimpleMapping
+mapre   = RegexpMapping
+
--- a/lib/site.py	Sat Feb 07 06:05:10 2009 +0200
+++ b/lib/site.py	Sat Feb 07 06:54:52 2009 +0200
@@ -2,6 +2,8 @@
     Per-site stuff
 """
 
+import imp
+
 SITE_DIR = "sites"
 
 class Site (object) :
@@ -9,6 +11,46 @@
         A site is a website and its configuration
     """
 
-    pass
+    def __init__ (self, name) :
+        """
+            The given name must be like a valid hostname, e.g. 'www.qmsk.net'
+        """
 
+        # store
+        self.name = name
 
+        # load the site
+        self._load()
+
+    def _load (self) :
+        """
+            Loads this site, as a python module (i.e. dir with __init__.py)
+        """
+
+        # first, we need to find it
+        file, pathname, description = imp.find_module(self.name, [SITE_DIR])
+
+        # then, we can load it
+        self.module = imp.load_module(self.name, file, pathname, description)
+        
+        # create our mapper
+        self.mapper = self.module.build_mapper()
+
+    def get_mapper (self) :
+        """
+            Return the Mapper for this site
+        """
+
+        return self.mapper
+
+def lookup (request) :
+    """
+        Lookup and return a Site object for the given request
+    """
+
+    # request hostnmae
+    hostname = request.env.get('HTTP_POST')
+
+    # XXX: hardcoded for now
+    return Site("www.qmsk.net")
+
--- a/lib/wsgi.py	Sat Feb 07 06:05:10 2009 +0200
+++ b/lib/wsgi.py	Sat Feb 07 06:54:52 2009 +0200
@@ -9,6 +9,9 @@
 # for Request/Response
 import http
 
+# to lookup the Site
+from site import lookup as site_lookup
+
 # for the request -> response bit :)
 import handler
 
@@ -19,6 +22,15 @@
 
     # build Request object
     request = http.Request(env)
+
+    # lookup site
+    site = site_lookup(request)
+
+    # mapper...
+    mapper = site.get_mapper()
+
+    # lookup handler
+    handler = mapper.map_request(request)
     
     try :
         # request -> response
--- a/sites/irclogs.qmsk.net/__init__.py	Sat Feb 07 06:05:10 2009 +0200
+++ b/sites/irclogs.qmsk.net/__init__.py	Sat Feb 07 06:54:52 2009 +0200
@@ -3,5 +3,5 @@
 """
 
 # the URL mapper
-from urls import url_mapper
+from urls import build_mapper
 
--- a/sites/irclogs.qmsk.net/urls.py	Sat Feb 07 06:05:10 2009 +0200
+++ b/sites/irclogs.qmsk.net/urls.py	Sat Feb 07 06:54:52 2009 +0200
@@ -7,16 +7,16 @@
 import handlers
 
 # library stuff
-from lib.map import Mapping, map, mapre
+from lib.map import StaticMapping, map, mapre
 
-def url_mapper () :
+def build_mapper () :
     """
         Construct and return the Mapping object
     """
 
-    return Mapping(
+    return StaticMapping([
         map(    '/',                                        handlers.index                  ),
         map(    '/channel/%s',                              handlers.channel_view           ),
         mapre(  r'^/channel/(\w+)/last/(\d+)(\.\w+)?',      handlers.channel_last           ),
-    )
+    ])
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/www.qmsk.net/__init__.py	Sat Feb 07 06:54:52 2009 +0200
@@ -0,0 +1,8 @@
+"""
+    The www.qmsk.net site is just a simple site with a filesystem-based URL mapping
+"""
+
+from lib.map import fstree
+
+build_mapper = lambda: fstree("site/www.qmsk.net")
+