]> www.average.org Git - loctrkd.git/blob - loctrkd/googlemaps.py
Update changelog for 2.00 release
[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, float]:
57     result = _lookup(mcc, mnc, gsm_cells, wifi_aps)
58     if "location" in result:
59         return (
60             result["location"]["lat"],
61             result["location"]["lng"],
62             result["accuracy"],
63         )
64     else:
65         raise ValueError("google geolocation: " + str(result))
66
67
68 if __name__.endswith("__main__"):
69     from getopt import getopt
70     from json import loads
71     from logging import getLogger
72     from sys import argv
73     from . import common
74
75     def cell_list(s: str) -> List[Tuple[int, int, int]]:
76         return [(int(ac), int(ci), int(sg)) for [ac, ci, sg] in loads(s)]
77
78     def ap_list(s: str) -> List[Tuple[str, int]]:
79         return [(mac, int(sg)) for [mac, sg] in loads(s)]
80
81     log = getLogger("loctrkd/googlemaps")
82     opts, args = getopt(argv[1:], "c:d")
83     conf = common.init(log, opts=opts)
84     init(conf)
85     parms = {}
86     needed: Dict[str, Callable[[Any], Any]] = {
87         "mcc": int,
88         "mnc": int,
89         "gsm_cells": cell_list,
90         "wifi_aps": ap_list,
91     }
92     parms = {k: needed.pop(k)(v) for k, v in [arg.split("=") for arg in args]}
93     if needed:
94         raise ValueError(f"still needed: {needed}")
95     print(_lookup(**parms))