0
|
1 import re, ast, restkit, logging, socket
|
36
|
2 from rdflib import Literal, Graph
|
0
|
3
|
|
4 log = logging.getLogger()
|
|
5
|
|
6 class Wifi(object):
|
|
7 """
|
|
8 gather the users of wifi from the tomato routers
|
|
9 """
|
|
10 def __init__(self, tomatoConfig="/my/site/magma/tomato_config.js",
|
|
11 accessN3="/my/proj/openid_proxy/access.n3"):
|
|
12
|
|
13 # ideally this would all be in the same rdf store, with int and
|
|
14 # ext versions of urls
|
|
15
|
|
16 txt = open(tomatoConfig).read().replace('\n', '')
|
|
17 self.knownMacAddr = jsValue(txt, 'knownMacAddr')
|
|
18 tomatoUrl = jsValue(txt, 'tomatoUrl')
|
|
19
|
|
20 g = Graph()
|
|
21 g.parse(accessN3, format="n3")
|
|
22 repl = {'/tomato1/' : None, '/tomato2/' : None}
|
|
23 for k in repl:
|
|
24 rows = list(g.query('''
|
|
25 PREFIX p: <http://bigasterisk.com/openid_proxy#>
|
|
26 SELECT ?prefix WHERE {
|
|
27 [
|
|
28 p:requestPrefix ?public;
|
|
29 p:proxyUrlPrefix ?prefix
|
|
30 ]
|
|
31 }''', initBindings={"public" : Literal(k)}))
|
|
32 repl[k] = str(rows[0][0])
|
|
33
|
|
34 self.routers = []
|
|
35 for url in tomatoUrl:
|
|
36 name = url
|
|
37 for k, v in repl.items():
|
|
38 url = url.replace(k, v)
|
|
39
|
|
40 r = restkit.Resource(url, timeout=2)
|
|
41 r.name = {'tomato1' : 'bigasterisk3',
|
|
42 'tomato2' : 'bigasterisk4'}[name.split('/')[1]]
|
|
43 self.routers.append(r)
|
|
44
|
|
45
|
|
46 def getPresentMacAddrs(self):
|
|
47 aboutIp = {}
|
|
48 byMac = {} # mac : [ip]
|
|
49
|
|
50 for router in self.routers:
|
|
51 log.debug("GET %s", router)
|
|
52 try:
|
|
53 data = router.get().body_string()
|
|
54 except socket.error:
|
|
55 log.warn("get on %s failed" % router)
|
|
56 continue
|
|
57
|
|
58 for (ip, mac, iface) in jsValue(data, 'arplist'):
|
|
59 aboutIp.setdefault(ip, {}).update(dict(
|
|
60 ip=ip,
|
|
61 router=router.name,
|
|
62 mac=mac,
|
|
63 iface=iface,
|
|
64 ))
|
|
65
|
|
66 byMac.setdefault(mac, set()).add(ip)
|
|
67
|
|
68 for (name, ip, mac, lease) in jsValue(data, 'dhcpd_lease'):
|
|
69 if lease.startswith('0 days, '):
|
|
70 lease = lease[len('0 days, '):]
|
|
71 aboutIp.setdefault(ip, {}).update(dict(
|
|
72 router=router.name,
|
|
73 rawName=name,
|
|
74 mac=mac,
|
|
75 lease=lease
|
|
76 ))
|
|
77
|
|
78 byMac.setdefault(mac, set()).add(ip)
|
|
79
|
|
80 for iface, mac, signal in jsValue(data, 'wldev'):
|
|
81 matched = False
|
|
82 for addr in aboutIp.values():
|
|
83 if (addr['router'], addr['mac']) == (router.name, mac):
|
|
84 addr.update(dict(signal=signal, iface=iface))
|
|
85 matched = True
|
|
86 if not matched:
|
|
87 aboutIp["mac-%s-%s" % (router, mac)] = dict(
|
|
88 router=router.name,
|
|
89 mac=mac,
|
|
90 signal=signal,
|
|
91 )
|
|
92
|
|
93 ret = []
|
|
94 for addr in aboutIp.values():
|
|
95 if addr.get('ip') in ['192.168.1.1', '192.168.1.2', '192.168.0.2']:
|
|
96 continue
|
|
97 try:
|
|
98 addr['name'] = self.knownMacAddr[addr['mac']]
|
|
99 except KeyError:
|
|
100 addr['name'] = addr.get('rawName')
|
|
101 if addr['name'] in [None, '*']:
|
|
102 addr['name'] = 'unknown'
|
|
103 ret.append(addr)
|
|
104
|
|
105 return ret
|
|
106
|
|
107
|
|
108 def jsValue(js, variableName):
|
|
109 # using literal_eval instead of json parser to handle the trailing commas
|
|
110 val = re.search(variableName + r'\s*=\s*(.*?);', js, re.DOTALL).group(1)
|
|
111 return ast.literal_eval(val)
|