--- 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('«'), 'Back'),
+ html.a(href=self.url(ListHandler))(html('«'), '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('«'), '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),
))