aprsd 3.3.4__py2.py3-none-any.whl → 3.4.0__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. aprsd/client.py +133 -20
  2. aprsd/clients/aprsis.py +6 -3
  3. aprsd/clients/fake.py +1 -1
  4. aprsd/clients/kiss.py +1 -1
  5. aprsd/cmds/completion.py +13 -27
  6. aprsd/cmds/fetch_stats.py +53 -57
  7. aprsd/cmds/healthcheck.py +32 -30
  8. aprsd/cmds/list_plugins.py +2 -2
  9. aprsd/cmds/listen.py +33 -17
  10. aprsd/cmds/send_message.py +2 -2
  11. aprsd/cmds/server.py +26 -9
  12. aprsd/cmds/webchat.py +34 -29
  13. aprsd/conf/common.py +46 -31
  14. aprsd/log/log.py +28 -6
  15. aprsd/main.py +4 -17
  16. aprsd/packets/__init__.py +3 -2
  17. aprsd/packets/collector.py +56 -0
  18. aprsd/packets/core.py +456 -321
  19. aprsd/packets/log.py +143 -0
  20. aprsd/packets/packet_list.py +83 -66
  21. aprsd/packets/seen_list.py +30 -19
  22. aprsd/packets/tracker.py +60 -62
  23. aprsd/packets/watch_list.py +64 -38
  24. aprsd/plugin.py +41 -16
  25. aprsd/plugins/email.py +35 -7
  26. aprsd/plugins/time.py +3 -2
  27. aprsd/plugins/version.py +4 -5
  28. aprsd/plugins/weather.py +0 -1
  29. aprsd/stats/__init__.py +20 -0
  30. aprsd/stats/app.py +46 -0
  31. aprsd/stats/collector.py +38 -0
  32. aprsd/threads/__init__.py +3 -2
  33. aprsd/threads/aprsd.py +67 -36
  34. aprsd/threads/keep_alive.py +55 -49
  35. aprsd/threads/log_monitor.py +46 -0
  36. aprsd/threads/rx.py +43 -24
  37. aprsd/threads/stats.py +44 -0
  38. aprsd/threads/tx.py +36 -17
  39. aprsd/utils/__init__.py +12 -0
  40. aprsd/utils/counter.py +6 -3
  41. aprsd/utils/json.py +20 -0
  42. aprsd/utils/objectstore.py +22 -17
  43. aprsd/web/admin/static/css/prism.css +4 -189
  44. aprsd/web/admin/static/js/charts.js +9 -7
  45. aprsd/web/admin/static/js/echarts.js +71 -9
  46. aprsd/web/admin/static/js/main.js +47 -6
  47. aprsd/web/admin/static/js/prism.js +11 -2246
  48. aprsd/web/admin/templates/index.html +18 -7
  49. aprsd/web/chat/static/js/gps.js +3 -1
  50. aprsd/web/chat/static/js/main.js +4 -3
  51. aprsd/web/chat/static/js/send-message.js +5 -2
  52. aprsd/web/chat/templates/index.html +1 -0
  53. aprsd/wsgi.py +62 -127
  54. {aprsd-3.3.4.dist-info → aprsd-3.4.0.dist-info}/METADATA +14 -16
  55. {aprsd-3.3.4.dist-info → aprsd-3.4.0.dist-info}/RECORD +60 -63
  56. {aprsd-3.3.4.dist-info → aprsd-3.4.0.dist-info}/WHEEL +1 -1
  57. aprsd-3.4.0.dist-info/pbr.json +1 -0
  58. aprsd/plugins/query.py +0 -81
  59. aprsd/rpc/__init__.py +0 -14
  60. aprsd/rpc/client.py +0 -165
  61. aprsd/rpc/server.py +0 -99
  62. aprsd/stats.py +0 -266
  63. aprsd/web/admin/static/json-viewer/jquery.json-viewer.css +0 -57
  64. aprsd/web/admin/static/json-viewer/jquery.json-viewer.js +0 -158
  65. aprsd/web/chat/static/json-viewer/jquery.json-viewer.css +0 -57
  66. aprsd/web/chat/static/json-viewer/jquery.json-viewer.js +0 -158
  67. aprsd-3.3.4.dist-info/pbr.json +0 -1
  68. {aprsd-3.3.4.dist-info → aprsd-3.4.0.dist-info}/LICENSE +0 -0
  69. {aprsd-3.3.4.dist-info → aprsd-3.4.0.dist-info}/entry_points.txt +0 -0
  70. {aprsd-3.3.4.dist-info → aprsd-3.4.0.dist-info}/top_level.txt +0 -0
aprsd/log/log.py CHANGED
@@ -6,11 +6,12 @@ import sys
6
6
  from loguru import logger
7
7
  from oslo_config import cfg
8
8
 
9
- from aprsd import conf
9
+ from aprsd.conf import log as conf_log
10
10
 
11
11
 
12
12
  CONF = cfg.CONF
13
- LOG = logging.getLogger("APRSD")
13
+ # LOG = logging.getLogger("APRSD")
14
+ LOG = logger
14
15
  logging_queue = queue.Queue()
15
16
 
16
17
 
@@ -38,7 +39,7 @@ def setup_logging(loglevel=None, quiet=False):
38
39
  if not loglevel:
39
40
  log_level = CONF.logging.log_level
40
41
  else:
41
- log_level = conf.log.LOG_LEVELS[loglevel]
42
+ log_level = conf_log.LOG_LEVELS[loglevel]
42
43
 
43
44
  # intercept everything at the root logger
44
45
  logging.root.handlers = [InterceptHandler()]
@@ -53,9 +54,15 @@ def setup_logging(loglevel=None, quiet=False):
53
54
  "aprslib.parsing",
54
55
  "aprslib.exceptions",
55
56
  ]
57
+ webserver_list = [
58
+ "werkzeug",
59
+ "werkzeug._internal",
60
+ "socketio",
61
+ "urllib3.connectionpool",
62
+ ]
56
63
 
57
64
  # We don't really want to see the aprslib parsing debug output.
58
- disable_list = imap_list + aprslib_list
65
+ disable_list = imap_list + aprslib_list + webserver_list
59
66
 
60
67
  # remove every other logger's handlers
61
68
  # and propagate to root logger
@@ -66,17 +73,29 @@ def setup_logging(loglevel=None, quiet=False):
66
73
  else:
67
74
  logging.getLogger(name).propagate = True
68
75
 
76
+ if CONF.webchat.disable_url_request_logging:
77
+ for name in webserver_list:
78
+ logging.getLogger(name).handlers = []
79
+ logging.getLogger(name).propagate = True
80
+ logging.getLogger(name).setLevel(logging.ERROR)
81
+
69
82
  handlers = [
70
83
  {
71
- "sink": sys.stdout, "serialize": False,
84
+ "sink": sys.stdout,
85
+ "serialize": False,
72
86
  "format": CONF.logging.logformat,
87
+ "colorize": True,
88
+ "level": log_level,
73
89
  },
74
90
  ]
75
91
  if CONF.logging.logfile:
76
92
  handlers.append(
77
93
  {
78
- "sink": CONF.logging.logfile, "serialize": False,
94
+ "sink": CONF.logging.logfile,
95
+ "serialize": False,
79
96
  "format": CONF.logging.logformat,
97
+ "colorize": False,
98
+ "level": log_level,
80
99
  },
81
100
  )
82
101
 
@@ -90,8 +109,11 @@ def setup_logging(loglevel=None, quiet=False):
90
109
  {
91
110
  "sink": qh, "serialize": False,
92
111
  "format": CONF.logging.logformat,
112
+ "level": log_level,
113
+ "colorize": False,
93
114
  },
94
115
  )
95
116
 
96
117
  # configure loguru
97
118
  logger.configure(handlers=handlers)
119
+ logger.level("DEBUG", color="<fg #BABABA>")
aprsd/main.py CHANGED
@@ -24,18 +24,17 @@ import datetime
24
24
  import importlib.metadata as imp
25
25
  from importlib.metadata import version as metadata_version
26
26
  import logging
27
- import os
28
27
  import signal
29
28
  import sys
30
29
  import time
31
30
 
32
31
  import click
33
- import click_completion
34
32
  from oslo_config import cfg, generator
35
33
 
36
34
  # local imports here
37
35
  import aprsd
38
- from aprsd import cli_helper, packets, stats, threads, utils
36
+ from aprsd import cli_helper, packets, threads, utils
37
+ from aprsd.stats import collector
39
38
 
40
39
 
41
40
  # setup the global logger
@@ -44,19 +43,6 @@ CONF = cfg.CONF
44
43
  LOG = logging.getLogger("APRSD")
45
44
  CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
46
45
  flask_enabled = False
47
- rpc_serv = None
48
-
49
-
50
- def custom_startswith(string, incomplete):
51
- """A custom completion match that supports case insensitive matching."""
52
- if os.environ.get("_CLICK_COMPLETION_COMMAND_CASE_INSENSITIVE_COMPLETE"):
53
- string = string.lower()
54
- incomplete = incomplete.lower()
55
- return string.startswith(incomplete)
56
-
57
-
58
- click_completion.core.startswith = custom_startswith
59
- click_completion.init()
60
46
 
61
47
 
62
48
  @click.group(cls=cli_helper.AliasedGroup, context_settings=CONTEXT_SETTINGS)
@@ -96,7 +82,8 @@ def signal_handler(sig, frame):
96
82
  packets.PacketTrack().save()
97
83
  packets.WatchList().save()
98
84
  packets.SeenList().save()
99
- LOG.info(stats.APRSDStats())
85
+ packets.PacketList().save()
86
+ LOG.info(collector.Collector().collect())
100
87
  # signal.signal(signal.SIGTERM, sys.exit(0))
101
88
  # sys.exit(0)
102
89
 
aprsd/packets/__init__.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from aprsd.packets.core import ( # noqa: F401
2
- AckPacket, BeaconPacket, GPSPacket, MessagePacket, MicEPacket, Packet,
3
- RejectPacket, StatusPacket, WeatherPacket,
2
+ AckPacket, BeaconPacket, BulletinPacket, GPSPacket, MessagePacket,
3
+ MicEPacket, ObjectPacket, Packet, RejectPacket, StatusPacket,
4
+ ThirdPartyPacket, UnknownPacket, WeatherPacket, factory,
4
5
  )
5
6
  from aprsd.packets.packet_list import PacketList # noqa: F401
6
7
  from aprsd.packets.seen_list import SeenList # noqa: F401
@@ -0,0 +1,56 @@
1
+ import logging
2
+ from typing import Callable, Protocol, runtime_checkable
3
+
4
+ from aprsd.packets import core
5
+ from aprsd.utils import singleton
6
+
7
+
8
+ LOG = logging.getLogger("APRSD")
9
+
10
+
11
+ @runtime_checkable
12
+ class PacketMonitor(Protocol):
13
+ """Protocol for Monitoring packets in some way."""
14
+
15
+ def rx(self, packet: type[core.Packet]) -> None:
16
+ """When we get a packet from the network."""
17
+ ...
18
+
19
+ def tx(self, packet: type[core.Packet]) -> None:
20
+ """When we send a packet out the network."""
21
+ ...
22
+
23
+
24
+ @singleton
25
+ class PacketCollector:
26
+ def __init__(self):
27
+ self.monitors: list[Callable] = []
28
+
29
+ def register(self, monitor: Callable) -> None:
30
+ self.monitors.append(monitor)
31
+
32
+ def unregister(self, monitor: Callable) -> None:
33
+ self.monitors.remove(monitor)
34
+
35
+ def rx(self, packet: type[core.Packet]) -> None:
36
+ for name in self.monitors:
37
+ cls = name()
38
+ if isinstance(cls, PacketMonitor):
39
+ try:
40
+ cls.rx(packet)
41
+ except Exception as e:
42
+ LOG.error(f"Error in monitor {name} (rx): {e}")
43
+
44
+ else:
45
+ raise TypeError(f"Monitor {name} is not a PacketMonitor")
46
+
47
+ def tx(self, packet: type[core.Packet]) -> None:
48
+ for name in self.monitors:
49
+ cls = name()
50
+ if isinstance(cls, PacketMonitor):
51
+ try:
52
+ cls.tx(packet)
53
+ except Exception as e:
54
+ LOG.error(f"Error in monitor {name} (tx): {e}")
55
+ else:
56
+ raise TypeError(f"Monitor {name} is not a PacketMonitor")