--- 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()