# HG changeset patch # User Tero Marttila # Date 1233982492 -7200 # Node ID a86a25a9f75be7e05395fb58db62f3c58b738433 # Parent b06ff4c05d4285800671b6e799aecb9bd99a9de0 route requests through sites/www.qmsk.net, although still hardcoded diff -r b06ff4c05d42 -r a86a25a9f75b lib/handler.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) : diff -r b06ff4c05d42 -r a86a25a9f75b lib/map.py --- /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 + diff -r b06ff4c05d42 -r a86a25a9f75b lib/site.py --- 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") + diff -r b06ff4c05d42 -r a86a25a9f75b lib/wsgi.py --- 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 diff -r b06ff4c05d42 -r a86a25a9f75b sites/irclogs.qmsk.net/__init__.py --- 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 diff -r b06ff4c05d42 -r a86a25a9f75b sites/irclogs.qmsk.net/urls.py --- 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 ), - ) + ]) diff -r b06ff4c05d42 -r a86a25a9f75b sites/www.qmsk.net/__init__.py --- /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") +