]> www.average.org Git - loctrkd.git/blob - loctrkd/qry.py
qry: initial support for saving data in a file
[loctrkd.git] / loctrkd / qry.py
1 """ Print out contens of the event database """
2
3 from configparser import ConfigParser
4 from datetime import datetime, timezone
5 from getopt import getopt
6 from importlib import import_module
7 from logging import getLogger
8 from sqlite3 import connect
9 from sys import argv
10 from typing import Any, cast, List, Tuple
11
12 from . import common
13
14 log = getLogger("loctrkd/qry")
15
16
17 class ProtoModule:
18     @staticmethod
19     def proto_handled(proto: str) -> bool:
20         ...
21
22     @staticmethod
23     def parse_message(packet: bytes, is_incoming: bool = True) -> Any:
24         ...
25
26
27 pmods: List[ProtoModule] = []
28
29
30 def main(
31     conf: ConfigParser, opts: List[Tuple[str, str]], args: List[str]
32 ) -> None:
33     global pmods
34     pmods = [
35         cast(ProtoModule, import_module("." + modnm, __package__))
36         for modnm in conf.get("collector", "protocols").split(",")
37     ]
38     db = connect(conf.get("storage", "dbfn"))
39     c = db.cursor()
40     if len(args) > 0:
41         proto = args[0]
42         selector = " where proto = :proto"
43     else:
44         proto = ""
45         selector = ""
46     dopts = dict(opts)
47     if len(args) > 1 and "-o" in dopts:
48         attr = args[1]
49         fn = dopts["-o"]
50     else:
51         attr = ""
52         fn = ""
53
54     c.execute(
55         """select tstamp, imei, peeraddr, is_incoming, proto, packet
56            from events"""
57         + selector,
58         {"proto": proto},
59     )
60
61     for tstamp, imei, peeraddr, is_incoming, proto, packet in c:
62         msg: Any = f"Unparseable({packet.hex()})"
63         for pmod in pmods:
64             if pmod.proto_handled(proto):
65                 msg = pmod.parse_message(packet, is_incoming)
66         print(
67             datetime.fromtimestamp(tstamp)
68             .astimezone(tz=timezone.utc)
69             .isoformat(),
70             imei,
71             peeraddr,
72             msg,
73         )
74         if fn and hasattr(msg, attr):
75             with open(fn, "wb") as fl:  # TODO support multiple files
76                 fl.write(getattr(msg, attr))
77
78
79 if __name__.endswith("__main__"):
80     opts, args = getopt(argv[1:], "o:c:d")
81     main(common.init(log, opts=opts), opts, args)