Mercurial > code > home > repos > homeauto
diff service/tomatoWifi/wifi.py @ 980:2f1cb8b5950a
rewrites for better graph export, removal of dhcp reader
Ignore-this: ecc5280b15d66020412f82ad84862074
darcs-hash:20150504002120-312f9-85bcb342f5bdae78d7b6d9083929944d4a467001
author | drewp <drewp@bigasterisk.com> |
---|---|
date | Sun, 03 May 2015 17:21:20 -0700 |
parents | d9bc9a82dcca |
children | 7faf642438bc |
line wrap: on
line diff
--- a/service/tomatoWifi/wifi.py Sat May 02 18:52:15 2015 -0700 +++ b/service/tomatoWifi/wifi.py Sun May 03 17:21:20 2015 -0700 @@ -1,8 +1,8 @@ -import re, ast, logging, socket +import re, ast, logging, socket, json import lxml.html.soupparser from twisted.internet.defer import inlineCallbacks, returnValue from cyclone.httpclient import fetch -from rdflib import Literal, Graph +from rdflib import Literal, Graph, RDFS, URIRef log = logging.getLogger() @@ -13,32 +13,31 @@ 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"): + def __init__(self, accessN3="/my/proj/openid_proxy/access.n3"): + self.graph = Graph() + self.graph.parse('config.n3', format='n3') - # ideally this would all be in the same rdf store, with int and - # ext versions of urls - - txt = open(tomatoConfig).read().replace('\n', '') - self.knownMacAddr = jsValue(txt, 'knownMacAddr') - tomatoUrl = jsValue(txt, 'tomatoUrl') - + #self._loadRouters(accessN3, tomatoUrl) + + def _loadRouters(self, accessN3, tomatoUrl): g = Graph() g.parse(accessN3, format="n3") - repl = {'/tomato1/' : None, '/tomato2/' : None} + repl = { + '/wifiRouter1/' : None, + #'/tomato2/' : None + } for k in repl: rows = list(g.query(''' PREFIX p: <http://bigasterisk.com/openid_proxy#> SELECT ?prefix WHERE { - [ + ?site p:requestPrefix ?public; p:proxyUrlPrefix ?prefix - ] + . }''', initBindings={"public" : Literal(k)})) repl[k] = str(rows[0][0]) + log.debug('repl %r', repl) self.routers = [] for url in tomatoUrl: @@ -51,12 +50,24 @@ userPass, tail = tail.split("@", 1) r.url = http + '//' + tail r.headers = {'Authorization': ['Basic %s' % userPass.encode('base64').strip()]} - r.name = {'tomato1' : 'bigasterisk5', + r.name = {'wifiRouter1' : 'bigasterisk5', 'tomato2' : 'bigasterisk4'}[name.split('/')[1]] self.routers.append(r) @inlineCallbacks def getPresentMacAddrs(self): + rows = yield loadUvaData() + for row in rows: + if 'clientHostname' in row: + row['name'] = row['clientHostname'] + mac = URIRef('http://bigasterisk.com/mac/%s' % row['mac'].lower()) + label = self.graph.value(mac, RDFS.label) + if label: + row['name'] = label + returnValue(rows) + + @inlineCallbacks + def getPresentMacAddrs_multirouter(self): rows = [] for router in self.routers: @@ -70,10 +81,10 @@ data = resp.body if 'Wireless -- Authenticated Stations' in data: # zyxel 'Station Info' page - rows.extend(self.parseZyxel(data, router.name)) + rows.extend(self._parseZyxel(data, router.name)) else: # tomato page - rows.extend(self.parseTomato(data, router.name)) + rows.extend(self._parseTomato(data, router.name)) for r in rows: try: @@ -83,7 +94,7 @@ returnValue(rows) - def parseZyxel(self, data, routerName): + 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()] @@ -92,10 +103,35 @@ assoc = assoc.lower() == 'yes' yield dict(router=routerName, mac=mac, assoc=assoc, connected=assoc) - def parseTomato(self, data, routerName): + def _parseTomato(self, data, routerName): for iface, mac, signal in jsValue(data, 'wldev'): yield dict(router=routerName, mac=mac, signal=signal, connected=bool(signal)) + + +@inlineCallbacks +def loadUvaData(): + config = json.load(open("/my/proj/homeauto/service/tomatoWifi/priv-uva.json")) + headers = {'Authorization': ['Basic %s' % config['userPass'].encode('base64').strip()]} + resp = yield fetch('http://10.2.0.2/wlstationlist.cmd', headers=headers) + root = lxml.html.soupparser.fromstring(resp.body) + byMac = {} + for tr in root.cssselect('tr'): + mac, connected, auth, ssid, iface = [td.text_content().strip() for td in tr.getchildren()] + if mac == "MAC": + continue + connected = connected.lower() == 'yes' + byMac[mac] = dict(mac=mac, connected=connected, auth=auth == 'Yes', ssid=ssid, iface=iface) + resp = yield fetch('http://10.2.0.2/DHCPTable.asp', headers=headers) + for row in re.findall(r'new AAA\((.*)\)', resp.body): + clientHostname, ipaddr, mac, expires, iface = [s.strip("'") for s in row.rsplit(',', 4)] + if clientHostname == 'wlanadv.none': + continue + byMac.setdefault(mac, {}).update(dict( + clientHostname=clientHostname, connection=iface, ipaddr=ipaddr, dhcpExpires=expires)) + + returnValue(sorted(byMac.values())) + def jsValue(js, variableName): # using literal_eval instead of json parser to handle the trailing commas