view service/tomatoWifi/wifi.py @ 0:6fd208b97616

start Ignore-this: e06ac598970a0d4750f588ab89f56996
author Drew Perttula <drewp@bigasterisk.com>
date Mon, 01 Aug 2011 03:30:30 -0700
parents
children 0ab069867c64
line wrap: on
line source

import re, ast, restkit, logging, socket
from rdflib import Literal

log = logging.getLogger()

class Wifi(object):
    """
    gather the users of wifi from the tomato routers
    """
    def __init__(self, tomatoConfig="/my/site/magma/tomato_config.js",
                 accessN3="/my/proj/openid_proxy/access.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')

        from rdflib.Graph import Graph
        g = Graph()
        g.parse(accessN3, format="n3")
        repl = {'/tomato1/' : None, '/tomato2/' : None}
        for k in repl:
            rows = list(g.query('''
            PREFIX p: <http://bigasterisk.com/openid_proxy#>
            SELECT ?prefix WHERE {
              [
                p:requestPrefix ?public;
                p:proxyUrlPrefix ?prefix
                ]
            }''', initBindings={"public" : Literal(k)}))
            repl[k] = str(rows[0][0])

        self.routers = []
        for url in tomatoUrl:
            name = url
            for k, v in repl.items():
                url = url.replace(k, v)

            r = restkit.Resource(url, timeout=2)
            r.name = {'tomato1' : 'bigasterisk3',
                      'tomato2' : 'bigasterisk4'}[name.split('/')[1]]
            self.routers.append(r)


    def getPresentMacAddrs(self):
        aboutIp = {}
        byMac = {} # mac : [ip]

        for router in self.routers:
            log.debug("GET %s", router)
            try:
                data = router.get().body_string()
            except socket.error:
                log.warn("get on %s failed" % router)
                continue

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

        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)

        return ret


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)
    return ast.literal_eval(val)