diff service/wifi/scrape.py @ 1679:f88ff1021ee0

checkpoint service/wifi
author drewp@bigasterisk.com
date Mon, 27 Sep 2021 23:02:33 -0700
parents 5fd7aef3b2b2
children 41394bc1d1b0
line wrap: on
line diff
--- a/service/wifi/scrape.py	Mon Sep 27 22:59:39 2021 -0700
+++ b/service/wifi/scrape.py	Mon Sep 27 23:02:33 2021 -0700
@@ -1,67 +1,73 @@
-import logging, json, base64
-from typing import List, Iterable
+import base64
+import json
+import logging
+import re
+import time
+from typing import Awaitable, Callable, Iterable, List
 
 from cyclone.httpclient import fetch
-from rdflib import Literal, Graph, RDF, URIRef, Namespace, RDFS
-from twisted.internet.defer import inlineCallbacks, returnValue
+from rdflib import Graph, Literal, Namespace, RDF, RDFS, URIRef
 
 log = logging.getLogger()
 ROOM = Namespace("http://projects.bigasterisk.com/room/")
 AST = Namespace("http://bigasterisk.com/")
 
+
 def macUri(macAddress: str) -> URIRef:
     return URIRef("http://bigasterisk.com/mac/%s" % macAddress.lower())
 
+
 class SeenNode(object):
+
     def __init__(self, uri: URIRef, mac: str, ip: str, stmts: Iterable):
         self.connected = True
         self.uri = uri
         self.mac = mac
         self.ip = ip
         self.stmts = stmts
-    
+
+
 class Wifi(object):
     """
     gather the users of wifi from the tomato routers
     """
+
     def __init__(self, config: Graph):
         self.config = config
-        
-    @inlineCallbacks
-    def getPresentMacAddrs(self): # returnValue List[SeenNode]
-        rows = yield self._loader()(self.config)
-        returnValue(rows)
 
-    def _loader(self):
+    async def getPresentMacAddrs(self) -> List[SeenNode]:
+        rows = await self._loader()(self.config)
+        return rows
+
+    def _loader(self) -> Callable[[Graph], Awaitable[List[SeenNode]]]:
         cls = self.config.value(ROOM['wifiScraper'], RDF.type)
         if cls == ROOM['OrbiScraper']:
             return loadOrbiData
         raise NotImplementedError(cls)
 
 
-@inlineCallbacks
-def loadOrbiData(config):
+async def loadOrbiData(config: Graph) -> List[SeenNode]:
     user = config.value(ROOM['wifiScraper'], ROOM['user'])
     passwd = config.value(ROOM['wifiScraper'], ROOM['password'])
     basicAuth = '%s:%s' % (user, passwd)
     headers = {
-        b'Authorization': [
-            b'Basic %s' % base64.encodebytes(basicAuth.encode('utf8')).strip()],
+        b'Authorization': [b'Basic %s' % base64.encodebytes(basicAuth.encode('utf8')).strip()],
     }
     uri = config.value(ROOM['wifiScraper'], ROOM['deviceInfoPage'])
-    resp = yield fetch(uri.encode('utf8'), method=b'GET', headers=headers)
+    resp = await fetch(f"{uri}?ts={time.time()}".encode('utf8'), method=b'GET', headers=headers)
+
+    if not resp.body.startswith((b'device=', b'device_changed=0\ndevice=', b'device_changed=1\ndevice=')):
+        raise ValueError(resp.body)
 
-    if not resp.body.startswith((b'device=',
-                                 b'device_changed=0\ndevice=',
-                                 b'device_changed=1\ndevice=')):
-        raise ValueError(resp.body)
-        
-    log.debug(resp.body)
+    
     rows = []
-    for row in json.loads(resp.body.split(b'device=', 1)[-1]):
+    for rowNum, row in enumerate(json.loads(resp.body.split(b'device=', 1)[-1])):        
+        log.debug('response row [%d] %r', rowNum, row)
+        if not re.match(r'\w\w:\w\w:\w\w:\w\w:\w\w:\w\w', row['mac']):
+            raise ValueError(f"corrupt response: mac was {row['mac']!r}")
         triples = set()
         uri = macUri(row['mac'].lower())
-        
+
         if row['contype'] in ['2.4G', '5G']:
             orbi = macUri(row['conn_orbi_mac'])
             ct = ROOM['wifiBand/%s' % row['contype']]
@@ -69,8 +75,7 @@
             triples.add((uri, ROOM['wifiBand'], ct))
             triples.add((orbi, RDF.type, ROOM['AccessPoint']))
             triples.add((orbi, ROOM['wifiBand'], ct))
-            triples.add((orbi, ROOM['macAddress'],
-                           Literal(row['conn_orbi_mac'].lower())))
+            triples.add((orbi, ROOM['macAddress'], Literal(row['conn_orbi_mac'].lower())))
             triples.add((orbi, RDFS.label, Literal(row['conn_orbi_name'])))
         elif row['contype'] == 'wireless':
             pass
@@ -84,10 +89,6 @@
 
         if row['model'] != 'Unknown':
             triples.add((uri, ROOM['networkModel'], Literal(row['model'])))
-            
-        rows.append(SeenNode(
-            uri=uri,
-            mac=row['mac'].lower(),
-            ip=row['ip'],
-            stmts=triples))
-    returnValue(rows)
+
+        rows.append(SeenNode(uri=uri, mac=row['mac'].lower(), ip=row['ip'], stmts=triples))
+    return rows