hosts: change ListHandler to use filtering
authorTero Marttila <terom@paivola.fi>
Thu, 11 Oct 2012 00:44:08 +0300
changeset 8 f64c44640b15
parent 7 7baf4cccb4a9
child 9 3334d8ddf2f1
hosts: change ListHandler to use filtering
pvl/verkko/hosts.py
pvl/verkko/urls.py
--- a/pvl/verkko/hosts.py	Wed Oct 10 23:44:37 2012 +0300
+++ b/pvl/verkko/hosts.py	Thu Oct 11 00:44:08 2012 +0300
@@ -2,6 +2,7 @@
 
 from pvl.html import tags as html
 
+import re
 import socket # dns
 
 import logging; log = logging.getLogger('pvl.verkko.hosts')
@@ -9,6 +10,20 @@
 # XXX: this should actually be DHCPHost
 class Host (object) :
     DATE_FMT = '%Y%m%d'
+    
+    MAC_HEX = r'([A-Za-z0-9]{2})'
+    MAC_SEP = r'[-:.]?'
+    MAC_RE = re.compile(MAC_SEP.join([MAC_HEX] * 6))
+
+    @classmethod
+    def normalize_mac (cls, mac) :
+        match = cls.MAC_RE.search(mac)
+
+        if not match :
+            raise ValueError(mac)
+
+        else :
+            return ':'.join(hh.lower() for hh in match.groups())
 
     def __init__ (self, ip, mac, name=None) :
         self.ip = ip
@@ -91,6 +106,8 @@
         hosts = hosts.order_by(sort)
 
         # k
+        self.sort = sort
+
         return hosts
     
     def render_hosts (self, hosts, title=None) :
@@ -120,12 +137,12 @@
                         )
                     ),
                     html.td(class_='ip')(
-                        html.a(href=self.url(ListHandler, attr='ip', value=host.ip))(
+                        html.a(href=self.url(ListHandler, ip=host.ip))(
                             host.ip
                         )
                     ),
                     html.td(class_='mac')(
-                        html.a(href=self.url(ListHandler, attr='mac', value=host.mac))(
+                        html.a(href=self.url(ListHandler, mac=host.mac))(
                             host.render_mac()
                         )
                     ),
@@ -141,6 +158,8 @@
                 ('MAC',         host.mac),
                 ('Hostname',    host.name),
                 ('DNS',         host.dns()),
+                ('First seen',  host.first_seen),
+                ('Last seen',   host.last_seen),
         )
 
         return (
@@ -152,7 +171,7 @@
             html.h2('Related'),
             self.render_hosts(hosts),
 
-            html.a(href=self.url(IndexHandler))(html('&laquo;'), 'Back'),
+            html.a(href=self.url(ListHandler))(html('&laquo;'), 'Back'),
         )
 
 class IndexHandler (BaseHandler) :
@@ -182,27 +201,35 @@
         return self.render_host(self.host, self.hosts)
 
 class ListHandler (BaseHandler) :
-    def process (self, attr, value) :
-        # fake host
-        _host = { 'ip': None, 'mac': None, 'name': None }
-
-        if attr not in self.HOST_ATTRS :
-            raise web.BadRequest("Invalid attribute: {attr}".format(attr=attr))
+    def process (self) :
+        hosts = self.query()
+        self.filters = {}
 
-        _host[attr] = value
-
-        self.host = Host(**_host)
-        self.expression = "{attr}: {value}".format(attr=attr, value=value)
+        for attr in self.HOST_ATTRS :
+            value = self.request.args.get(attr)
 
-        # query
-        attr = self.HOST_ATTRS[attr]
-        log.debug("%s == %s", attr, value)
+            if not value :
+                continue
+
+            # preprocess
+            if attr == 'mac' :
+                value = Host.normalize_mac(value)
+
+            # filter
+            hosts = hosts.filter(self.HOST_ATTRS[attr] == value)
+            self.filters[attr] = value
         
-        self.hosts = self.query().filter(attr == value)
+        self.hosts = hosts
 
     def title (self) :
-        return "DHCP Hosts: {self.expression}".format(self=self)
+        if self.filters :
+            return "DHCP Hosts: {filters}".format(filters=', '.join(self.filters.itervalues()))
+        else :
+            return "DHCP Hosts"
     
     def render (self) :
-        return self.render_host(self.host, self.hosts)
-    
+        return (
+            self.render_hosts(self.hosts),
+
+            html.a(href=self.url())(html('&laquo;'), 'Back') if self.filters else None,
+        )
--- a/pvl/verkko/urls.py	Wed Oct 10 23:44:37 2012 +0300
+++ b/pvl/verkko/urls.py	Thu Oct 11 00:44:08 2012 +0300
@@ -21,8 +21,7 @@
 
 urls = Map((
     rule('/',                       Index),
-    rule('/hosts/',                 hosts.IndexHandler),
+    rule('/hosts/',                 hosts.ListHandler),
     rule('/hosts/<int:id>',         hosts.ItemHandler),
-    rule('/hosts/<attr>/<value>',   hosts.ListHandler),
 ))