Mercurial > code > home > repos > homeauto
diff service/tomatoWifi/wifi.py @ 867:d9bc9a82dcca
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
Ignore-this: 18bade72e14d40532bd019791d03fa7d
darcs-hash:20130407000819-312f9-6b262edf71421b17947050e80560005d7bffa80b
author | drewp <drewp@bigasterisk.com> |
---|---|
date | Sat, 06 Apr 2013 17:08:19 -0700 |
parents | 1168b0cd90af |
children | c81a451f9b26 |
line wrap: on
line diff
--- a/service/tomatoWifi/wifi.py Sun Feb 10 13:41:35 2013 -0800 +++ b/service/tomatoWifi/wifi.py Sat Apr 06 17:08:19 2013 -0700 @@ -1,4 +1,5 @@ import re, ast, logging, socket +import lxml.html.soupparser from twisted.internet.defer import inlineCallbacks, returnValue from cyclone.httpclient import fetch from rdflib import Literal, Graph @@ -12,6 +13,8 @@ class Wifi(object): """ gather the users of wifi from the tomato routers + + with host names from /var/lib/dhcp/dhcpd.leases """ def __init__(self, tomatoConfig="/my/site/magma/tomato_config.js", accessN3="/my/proj/openid_proxy/access.n3"): @@ -48,15 +51,14 @@ userPass, tail = tail.split("@", 1) r.url = http + '//' + tail r.headers = {'Authorization': ['Basic %s' % userPass.encode('base64').strip()]} - r.name = {'tomato1' : 'bigasterisk3', + r.name = {'tomato1' : 'bigasterisk5', 'tomato2' : 'bigasterisk4'}[name.split('/')[1]] self.routers.append(r) @inlineCallbacks def getPresentMacAddrs(self): - aboutIp = {} - byMac = {} # mac : [ip] - + rows = [] + for router in self.routers: log.debug("GET %s", router) try: @@ -66,57 +68,35 @@ log.warn("get on %s failed" % router) continue data = resp.body - - for (ip, mac, iface) in jsValue(data, 'arplist'): - aboutIp.setdefault(ip, {}).update(dict( - ip=ip, - router=router.name, - mac=mac, - iface=iface, - )) - - byMac.setdefault(mac, set()).add(ip) - - for (name, ip, mac, lease) in jsValue(data, 'dhcpd_lease'): - if lease.startswith('0 days, '): - lease = lease[len('0 days, '):] - aboutIp.setdefault(ip, {}).update(dict( - router=router.name, - rawName=name, - mac=mac, - lease=lease - )) - - byMac.setdefault(mac, set()).add(ip) + if 'Wireless -- Authenticated Stations' in data: + # zyxel 'Station Info' page + rows.extend(self.parseZyxel(data, router.name)) + else: + # tomato page + rows.extend(self.parseTomato(data, router.name)) - for iface, mac, signal in jsValue(data, 'wldev'): - matched = False - for addr in aboutIp.values(): - if (addr['router'], addr['mac']) == (router.name, mac): - addr.update(dict(signal=signal, iface=iface)) - matched = True - if not matched: - aboutIp["mac-%s-%s" % (router, mac)] = dict( - router=router.name, - mac=mac, - signal=signal, - ) + for r in rows: + try: + r['name'] = self.knownMacAddr[r['mac']] + except KeyError: + pass + + returnValue(rows) + + def parseZyxel(self, data, routerName): + root = lxml.html.soupparser.fromstring(data) + for tr in root.cssselect('tr'): + mac, assoc, uth, ssid, iface = [td.text_content().strip() for td in tr.getchildren()] + if mac == "MAC": + continue + assoc = assoc.lower() == 'yes' + yield dict(router=routerName, mac=mac, assoc=assoc, connected=assoc) - ret = [] - for addr in aboutIp.values(): - if addr.get('ip') in ['192.168.1.1', '192.168.1.2', '192.168.0.2']: - continue - try: - addr['name'] = self.knownMacAddr[addr['mac']] - except KeyError: - addr['name'] = addr.get('rawName') - if addr['name'] in [None, '*']: - addr['name'] = 'unknown' - ret.append(addr) - - returnValue(ret) - - + def parseTomato(self, data, routerName): + for iface, mac, signal in jsValue(data, 'wldev'): + yield dict(router=routerName, mac=mac, signal=signal, connected=bool(signal)) + + def jsValue(js, variableName): # using literal_eval instead of json parser to handle the trailing commas val = re.search(variableName + r'\s*=\s*(.*?);', js, re.DOTALL).group(1)