]> www.average.org Git - loctrkd.git/blob - loctrkd/termconfig.py
b1ea80ae691bb1b93174c50b5d58d8150d9065fd
[loctrkd.git] / loctrkd / termconfig.py
1 """ For when responding to the terminal is not trivial """
2
3 from configparser import ConfigParser
4 from datetime import datetime, timezone
5 from logging import getLogger
6 from struct import pack
7 import zmq
8
9 from . import common
10 from .zx303proto import *
11 from .zx303proto import STATUS, SETUP, POSITION_UPLOAD_INTERVAL
12 from .zmsg import Bcast, Resp, topic
13
14 log = getLogger("loctrkd/termconfig")
15
16
17 def runserver(conf: ConfigParser) -> None:
18     # Is this https://github.com/zeromq/pyzmq/issues/1627 still not fixed?!
19     zctx = zmq.Context()  # type: ignore
20     zsub = zctx.socket(zmq.SUB)  # type: ignore
21     zsub.connect(conf.get("collector", "publishurl"))
22     for proto in (
23         proto_name(STATUS),
24         proto_name(SETUP),
25         proto_name(POSITION_UPLOAD_INTERVAL),
26     ):
27         zsub.setsockopt(zmq.SUBSCRIBE, topic(proto))
28     zpush = zctx.socket(zmq.PUSH)  # type: ignore
29     zpush.connect(conf.get("collector", "listenurl"))
30
31     try:
32         while True:
33             zmsg = Bcast(zsub.recv())
34             msg = parse_message(zmsg.packet)
35             log.debug(
36                 "IMEI %s from %s at %s: %s",
37                 zmsg.imei,
38                 zmsg.peeraddr,
39                 datetime.fromtimestamp(zmsg.when).astimezone(tz=timezone.utc),
40                 msg,
41             )
42             if msg.RESPOND is not Respond.EXT:
43                 log.error(
44                     "%s does not expect externally provided response", msg
45                 )
46             if zmsg.imei is not None and conf.has_section(zmsg.imei):
47                 termconfig = common.normconf(conf[zmsg.imei])
48             elif conf.has_section("termconfig"):
49                 termconfig = common.normconf(conf["termconfig"])
50             else:
51                 termconfig = {}
52             kwargs = {}
53             if isinstance(msg, STATUS):
54                 kwargs = {
55                     "upload_interval": termconfig.get(
56                         "statusintervalminutes", 25
57                     )
58                 }
59             elif isinstance(msg, SETUP):
60                 for key in (
61                     "uploadintervalseconds",
62                     "binaryswitch",
63                     "alarms",
64                     "dndtimeswitch",
65                     "dndtimes",
66                     "gpstimeswitch",
67                     "gpstimestart",
68                     "gpstimestop",
69                     "phonenumbers",
70                 ):
71                     if key in termconfig:
72                         kwargs[key] = termconfig[key]
73             resp = Resp(
74                 imei=zmsg.imei, when=zmsg.when, packet=msg.Out(**kwargs).packed
75             )
76             log.debug("Response: %s", resp)
77             zpush.send(resp.packed)
78
79     except KeyboardInterrupt:
80         zsub.close()
81         zpush.close()
82         zctx.destroy()  # type: ignore
83
84
85 if __name__.endswith("__main__"):
86     runserver(common.init(log))