changeset 1:d9519f40c177

moving to a dispatcher architecture
author k0s <k0scist@gmail.com>
date Thu, 05 Nov 2009 23:11:45 -0500
parents b65da5423cc9
children b8e5471794b2
files genshi_view/template/+package+/+package+.py_tmpl genshi_view/template/+package+/handlers.py genshi_view/template/+package+/templates/helloworld.html genshi_view/template/+package+/templates/index.html
diffstat 4 files changed, 96 insertions(+), 53 deletions(-) [+]
line wrap: on
line diff
--- a/genshi_view/template/+package+/+package+.py_tmpl	Tue Oct 27 15:11:43 2009 -0400
+++ b/genshi_view/template/+package+/+package+.py_tmpl	Thu Nov 05 23:11:45 2009 -0500
@@ -1,13 +1,15 @@
 """
-${project}: a view with webob
+request dispatcher
 """
 
+from handlers import Index
+
 from genshi.template import TemplateLoader
 from paste.fileapp import FileApp
 from pkg_resources import resource_filename
 from webob import Request, Response, exc
 
-class ${project.title()}View(object):
+class Dispatcher(object):
 
     ### class level variables
     defaults = { 'auto_reload': 'False'}
@@ -17,60 +19,37 @@
         # set instance parameters from kw and defaults
         for key in self.defaults:
             setattr(self, key, kw.get(key, self.defaults[key]))
-        self.auto_reload = self.auto_reload.lower() == 'true'
+#        self.auto_reload = self.auto_reload.lower() == 'true'
 
-        # methods to respond to
-        self.response_functions = { 'GET': self.get,
-                                    'POST': self.post,
-                                    }
+        self.handlers = [ Index ]
 
         # static files
         self.htdocs = resource_filename(__name__, 'static')
 
-        # template loader
-        templates_dir = resource_filename(__name__, 'templates')
-        self.loader = TemplateLoader(templates_dir,
-                                     auto_reload=self.auto_reload)
+        # template loader # to move???
+#        templates_dir = resource_filename(__name__, 'templates')
+#        self.loader = TemplateLoader(templates_dir,
+#                                     auto_reload=self.auto_reload)
 
     ### methods dealing with HTTP
     def __call__(self, environ, start_response):
         request = Request(environ)
+
+        # serve static files
+        # TODO: put into a handler
         filename = os.path.join(self.htdocs, request.path_info)
         if request.path_info != '/' and os.path.exists(filename):
             fileapp = FileApp(filename)
             return fileapp(environ, start_response)
-        res = self.make_response(request)
+
+        # match the request to a handler
+        for h in self.handlers:
+            handler = h.match(request)
+            if handler is not None:
+                break
+        else:
+            handler = exc.HTTPNotFound
+
+        res = handler()
         return res(environ, start_response)
                                 
-    def make_response(self, request):
-        return self.response_functions.get(request.method, self.error)(request)
-
-    def get_response(self, text, content_type='text/html'):
-        """make an HTTP response from text"""
-        res = Response(content_type=content_type, body=text)
-        return res
-
-    def get(self, request):
-        """
-        return response to a GET requst
-        """
-
-        # template data dictionary      
-        data = { 'subject': request.GET.get('subject', 'world') } 
-
-        # render the template
-        template = self.loader.load('helloworld.html')
-        res = template.generate(**data).render('html', doctype='html')
-        # generate the response
-        return self.get_response(res)
-
-    def post(self, request):
-        """
-        return response to a POST request
-        """
-        return exc.HTTPOk("Ok")
-
-    def error(self, request):
-        """deal with non-supported methods"""
-        return exc.HTTPMethodNotAllowed("Only %r operations are allowed" % self.response_functions.keys())
-        
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/genshi_view/template/+package+/handlers.py	Thu Nov 05 23:11:45 2009 -0500
@@ -0,0 +1,64 @@
+from urlparse import urlparse
+from webob import Response, exc
+
+# template loader
+from genshi.template import TemplateLoader
+templates_dir = resource_filename(__name__, 'templates')
+loader = TemplateLoader(templates_dir,
+                        auto_reload=True) # XXX should come from .ini file
+
+class HandlerMatchException(Exception):
+    """the handler doesn't match the request"""
+
+class Handler(object):
+
+    @classmethod
+    def match(cls, request):
+        try:
+            return cls(request)
+        except HandlerMatchException:
+            return None
+    
+    def __init__(self, request):
+        self.request = request
+        self.application_path = urlparse(request.application_url)[2]
+
+    def link(self, path=(), permanant=False):
+        if isinstance(path, basestring):
+            path = [ path ]
+        path = [ i.strip('/') for i in path ]
+        if permanant:
+            application_url = [ self.request.application_url ]
+        else:
+            application_url = [ self.application_path ]
+        path = application_url + path
+        return '/'.join(path)
+
+    def redirect(self, location):
+        raise exc.HTTPSeeOther(location=location)
+
+class GenshiHandler(Handler):
+    methods = set(['GET']) # methods to listen to
+    handler_path = [] # path elements to match        
+
+    def __init__(self, request):
+        if request.method not in self.methods:
+            raise HandlerMatchException
+        self.path = request.path.info.strip('/').split('/')
+        if self.path == ['']:
+            self.path = []
+        if path[:len(handler_path)] != self.handler_path:
+            raise HandlerMatchException
+
+        Handler.__init__(self, request)
+
+        self.data = { 'request': request }
+
+    def __call__(self):        
+        template = loader.load(self.template)
+        return Response(content_type='text/html',
+                        body=template.generate(**self.data).render()
+
+class Index(GenshiHandler):
+    template = 'index.html'
+
--- a/genshi_view/template/+package+/templates/helloworld.html	Tue Oct 27 15:11:43 2009 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-<!DOCTYPE html
-    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:py="http://genshi.edgewall.org/">
-<body>
-Hello ${subject}!
-</body>
-</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/genshi_view/template/+package+/templates/index.html	Thu Nov 05 23:11:45 2009 -0500
@@ -0,0 +1,9 @@
+<!DOCTYPE html
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:py="http://genshi.edgewall.org/">
+<body>
+Hello ${subject}!
+</body>
+</html>