urls
authorTero Marttila <terom@paivola.fi>
Wed, 10 Oct 2012 23:16:25 +0300
changeset 4 b09436772d46
parent 3 5990b188c54b
child 5 91970ce3fc6b
urls
pvl/verkko/hosts.py
pvl/verkko/urls.py
pvl/verkko/web.py
pvl/verkko/wsgi.py
--- a/pvl/verkko/hosts.py	Wed Oct 10 22:45:50 2012 +0300
+++ b/pvl/verkko/hosts.py	Wed Oct 10 23:16:25 2012 +0300
@@ -136,47 +136,20 @@
     )
 
 class Handler (web.Handler) :
-    TITLE = "DHCP Hosts"
+
+    def title (self) :
+        pass
     
     def index (self) :
         return render_hosts(self.hosts)
 
-    def host (self, id) :
-        host = self.hosts.get(id)
-        
-        if not host :
-            raise web.NotFound("No such host: {id}".format(id=id))
-
-        hosts = self.hosts.filter((Host.ip == host.ip) | (Host.mac == host.mac))
-        
-        # XXX
-        #self.title = "DHCP Host: {host}".format(host=unicode(host))
-
-        return render_host(host, hosts)
+    def detail (self) :
+        return render_host(self.host, self.hosts)
     
-    def list (self, attr, value) :
-        # fake host
-        host = { 'ip': None, 'mac': None, 'name': None }
-
-        if attr not in HOST_ATTRS :
-            raise web.BadRequest("Invalid attribute: {attr}".format(attr=attr))
-
-        host[attr] = value
-
-        host = Host(**host)
-
-        # query
-        attr = HOST_ATTRS[attr]
-        log.debug("%s == %s", attr, value)
-
-        hosts = self.hosts.filter(attr == value)
-        
-        # XXX
-        #self.title = "DHCP Hosts: {value}".format(value=value)
-
-        return render_host(host, hosts)
+    def list (self) :
+        return render_host(self.host, self.hosts)
     
-    def process (self) :
+    def process (self, id=None, attr=None, value=None) :
         hosts = self.db.query(Host)
 
         # sort ?
@@ -191,30 +164,40 @@
 
         hosts = hosts.order_by(sort)
         
-        # store
-        self.hosts = hosts
-    
-    def render (self) :
-        # index
-        if not self.path :
-            return self.index()
+        # lookup host
+        if id :
+            self.host = hosts.get(id)
+            
+            if not self.host :
+                raise web.NotFound("No such host: {id}".format(id=id))
+
+            self.hosts = hosts.filter((Host.ip == self.host.ip) | (Host.mac == self.host.mac))
+            self.render = self.detail
+            self.title = "DHCP Host: {host}".format(host=unicode(self.host))
         
-        # id
-        elif len(self.path) == 1 :
-            try :
-                id, = self.path
-                id = int(id)
-            except ValueError as ex :
-                raise web.BadRequest("Invalid host ID: {id}: {ex}".format(id=id, ex=ex))
+        # lookup hosts
+        elif attr and value :
+            # fake host
+            host = { 'ip': None, 'mac': None, 'name': None }
 
-            return self.host(id)
+            if attr not in HOST_ATTRS :
+                raise web.BadRequest("Invalid attribute: {attr}".format(attr=attr))
 
-        # query
-        elif len(self.path) == 2 :
-            attr, value = self.path
-            
-            return self.list(attr, value)
+            host[attr] = value
 
+            self.host = Host(**host)
+
+            # query
+            attr = HOST_ATTRS[attr]
+            log.debug("%s == %s", attr, value)
+
+            self.hosts = hosts.filter(attr == value)
+            self.render = self.list
+            self.title = "DHCP Hosts: {value}".format(value=value)
+
+        # list
         else :
-            raise web.NotFound
-
+            self.hosts = hosts
+            self.render = self.index
+            self.title = "DHCP Hosts"
+     
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pvl/verkko/urls.py	Wed Oct 10 23:16:25 2012 +0300
@@ -0,0 +1,15 @@
+from werkzeug.routing import Map, Rule
+
+def rule (string, endpoint, **opts) :
+    return Rule(string, endpoint=endpoint, **opts)
+
+# URL -> Handler
+from pvl.verkko import web, hosts
+
+urls = Map((
+    rule('/',                       web.Index),
+    rule('/hosts/',                 hosts.Handler),
+    rule('/hosts/<int:id>',         hosts.Handler),
+    rule('/hosts/<attr>/<value>',   hosts.Handler),
+))
+
--- a/pvl/verkko/web.py	Wed Oct 10 22:45:50 2012 +0300
+++ b/pvl/verkko/web.py	Wed Oct 10 23:16:25 2012 +0300
@@ -1,16 +1,16 @@
 # encoding: utf-8
 
+# response types
 from werkzeug.wrappers import Response
-
-# view
-from pvl.html import tags as html
-
-# errors
 from werkzeug.exceptions import (
         HTTPException, 
         BadRequest,         # 400
         NotFound,           # 404
 )
+from werkzeug.utils import redirect
+
+# view
+from pvl.html import tags as html
 
 class Handler (object) :
     """
@@ -23,19 +23,18 @@
         "/static/style.css", 
     )
 
-    def __init__ (self, app, request, path) :
+    def __init__ (self, app, request, urls) :
         """
             app     - wsgi.Application
             request - werkzeug.Request
+            urls    - werkzeug.routing.MapAdapter
         """
 
         self.app = app
         self.db = app.db
         self.request = request
+        self.urlmap = urls
         
-        # TODO
-        self.path = path
-    
     @property
     def title (self) :
         """
@@ -72,28 +71,29 @@
             )
         )
 
-    def process (self) :
+    def process (self, **params) :
         """
-            TODO: process request args to build internal state
+            Process request args to build internal request state.
         """
 
         pass
 
-    def respond (self) :
+    def respond (self, **params) :
         """
-            Generate a response.
+            Generate a response, or raise an HTTPException
 
             Does an HTML layout'd response per default.
+
+                **params    - url-mapped parameters
         """
         
-        try :
-            # XXX: returning e.g. redirect? args?
-            self.process()
+        # XXX: returning e.g. redirect?
+        self.process(**params)
+        
+        # render as html per default
+        text = unicode(html.document(self.render_html()))
 
-            return Response(unicode(html.document(self.render_html())), mimetype='text/html')
-        
-        except HTTPException as ex :
-            return ex
+        return Response(text, mimetype='text/html')
 
 class Index (Handler) :
     def render (self) :
--- a/pvl/verkko/wsgi.py	Wed Oct 10 22:45:50 2012 +0300
+++ b/pvl/verkko/wsgi.py	Wed Oct 10 23:16:25 2012 +0300
@@ -1,12 +1,14 @@
 import werkzeug
 from werkzeug.wrappers import Request, Response
-from werkzeug.utils import redirect
+from werkzeug.exceptions import HTTPException
 
 import logging; log = logging.getLogger('pvl.verkko.wsgi')
 
-from pvl.verkko import db as database, web, hosts
+from pvl.verkko import db as database, urls, web
 
 class Application (object) :
+    urls = urls.urls
+
     def __init__ (self, db) :
         """
             Initialize app with db.
@@ -14,31 +16,32 @@
 
         self.db = database.Database(db)
 
+    def respond (self, request) :
+        """
+            Lookup Request -> web.Handler, params
+        """
+        
+        # bind to request
+        urls = self.urls.bind_to_environ(request)
+        
+        # lookup
+        handler, params = urls.match()
+
+        # handler instance
+        handler = handler(self, request, urls)
+
+        # apply
+        return handler.respond(**params)
+
     @Request.application
     def __call__ (self, request) :
         """
             WSGI entry point, werkzeug Request -> Response
         """
-        
-        # path?
-        path = request.path.strip('/')
-        
-        if path :
-            path = path.split('/')
-        else :
-            path = []
 
-        log.debug("path: %s", path)
+        try :
+            return self.respond(request)
         
-        # lookup handler/respond
-        if not path :
-            handler = web.Index
+        except HTTPException as ex :
+            return ex
 
-        elif path[0] == 'hosts' :
-            handler = hosts.Handler
-            path.pop(0)
-
-        else :
-            return Response("Not Found", status=404)
-        
-        return handler(self, request, path).respond()