1 """ For when responding to the terminal is not trivial """
3 from configparser import ConfigParser, SectionProxy
4 from datetime import datetime, timezone
5 from logging import getLogger
6 from struct import pack
7 from typing import Any, Dict, List, Union
11 from .zx303proto import *
12 from .zx303proto import STATUS, SETUP, POSITION_UPLOAD_INTERVAL
13 from .zmsg import Bcast, Resp, topic
15 log = getLogger("loctrkd/termconfig")
18 def normconf(section: SectionProxy) -> Dict[str, Any]:
19 result: Dict[str, Any] = {}
20 for key, val in section.items():
21 vals = val.split("\n")
22 if len(vals) > 1 and vals[0] == "":
24 lst: List[Union[str, int]] = []
27 lst.append(int(el, 0))
29 if el[0] == '"' and el[-1] == '"':
30 el = el.strip('"').rstrip('"')
33 all([isinstance(x, int) for x in lst])
34 or all([isinstance(x, str) for x in lst])
37 "Values of %s - %s are of different type", key, vals
46 def runserver(conf: ConfigParser) -> None:
47 # Is this https://github.com/zeromq/pyzmq/issues/1627 still not fixed?!
48 zctx = zmq.Context() # type: ignore
49 zsub = zctx.socket(zmq.SUB) # type: ignore
50 zsub.connect(conf.get("collector", "publishurl"))
54 POSITION_UPLOAD_INTERVAL.proto_name(),
56 zsub.setsockopt(zmq.SUBSCRIBE, topic(proto))
57 zpush = zctx.socket(zmq.PUSH) # type: ignore
58 zpush.connect(conf.get("collector", "listenurl"))
62 zmsg = Bcast(zsub.recv())
63 msg = parse_message(zmsg.packet)
65 "IMEI %s from %s at %s: %s",
68 datetime.fromtimestamp(zmsg.when).astimezone(tz=timezone.utc),
71 if msg.RESPOND is not Respond.EXT:
73 "%s does not expect externally provided response", msg
75 if zmsg.imei is not None and conf.has_section(zmsg.imei):
76 termconfig = normconf(conf[zmsg.imei])
77 elif conf.has_section("termconfig"):
78 termconfig = normconf(conf["termconfig"])
82 if isinstance(msg, STATUS):
84 "upload_interval": termconfig.get(
85 "statusintervalminutes", 25
88 elif isinstance(msg, SETUP):
90 "uploadintervalseconds",
100 if key in termconfig:
101 kwargs[key] = termconfig[key]
103 imei=zmsg.imei, when=zmsg.when, packet=msg.Out(**kwargs).packed
105 log.debug("Response: %s", resp)
106 zpush.send(resp.packed)
108 except KeyboardInterrupt:
111 zctx.destroy() # type: ignore
114 if __name__.endswith("__main__"):
115 runserver(common.init(log))