]> www.average.org Git - loctrkd.git/blob - loctrkd/googlemaps.py
6838324bd1c95062df2b4db4a62eb532bc41c8f4
[loctrkd.git] / loctrkd / googlemaps.py
1 """
2 Google Maps location service lookaside backend
3 """
4
5 from configparser import ConfigParser
6 import googlemaps as gmaps
7 from typing import Any, Callable, Dict, List, Tuple
8
9 gclient = None
10
11
12 def init(conf: ConfigParser) -> None:
13     global gclient
14     with open(conf["googlemaps"]["accesstoken"], encoding="ascii") as fl:
15         token = fl.read().rstrip()
16     gclient = gmaps.Client(key=token)
17
18
19 def shut() -> None:
20     return
21
22
23 def _lookup(
24     mcc: int,
25     mnc: int,
26     gsm_cells: List[Tuple[int, int, int]],
27     wifi_aps: List[Tuple[str, int]],
28 ) -> Any:
29     assert gclient is not None
30     kwargs = {
31         "home_mobile_country_code": mcc,
32         "home_mobile_network_code": mnc,
33         "radio_type": "gsm",
34         "carrier": "O2",
35         "consider_ip": False,
36         "cell_towers": [
37             {
38                 "locationAreaCode": loc,
39                 "cellId": cellid,
40                 "signalStrength": sig,
41             }
42             for loc, cellid, sig in gsm_cells
43         ],
44         "wifi_access_points": [
45             {"macAddress": mac, "signalStrength": sig} for mac, sig in wifi_aps
46         ],
47     }
48     return gclient.geolocate(**kwargs)
49
50
51 def lookup(
52     mcc: int,
53     mnc: int,
54     gsm_cells: List[Tuple[int, int, int]],
55     wifi_aps: List[Tuple[str, int]],
56 ) -> Tuple[float, float]:
57     result = _lookup(mcc, mnc, gsm_cells, wifi_aps)
58     if "location" in result:
59         return result["location"]["lat"], result["location"]["lng"]
60     else:
61         raise ValueError("google geolocation: " + str(result))
62
63
64 if __name__.endswith("__main__"):
65     from getopt import getopt
66     from json import loads
67     from logging import getLogger
68     from sys import argv
69     from . import common
70
71     def cell_list(s: str) -> List[Tuple[int, int, int]]:
72         return [(int(ac), int(ci), int(sg)) for [ac, ci, sg] in loads(s)]
73
74     def ap_list(s: str) -> List[Tuple[str, int]]:
75         return [(mac, int(sg)) for [mac, sg] in loads(s)]
76
77     log = getLogger("loctrkd/googlemaps")
78     opts, args = getopt(argv[1:], "c:d")
79     conf = common.init(log, opts=opts)
80     init(conf)
81     parms = {}
82     needed: Dict[str, Callable[[Any], Any]] = {
83         "mcc": int,
84         "mnc": int,
85         "gsm_cells": cell_list,
86         "wifi_aps": ap_list,
87     }
88     parms = {k: needed.pop(k)(v) for k, v in [arg.split("=") for arg in args]}
89     if needed:
90         raise ValueError(f"still needed: {needed}")
91     print(_lookup(**parms))