aprsd 3.4.1__py3-none-any.whl → 3.4.3__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.
- aprsd/client/drivers/aprsis.py +5 -1
- aprsd/cmds/listen.py +2 -1
- aprsd/cmds/send_message.py +3 -5
- aprsd/cmds/server.py +11 -16
- aprsd/cmds/webchat.py +1 -8
- aprsd/conf/common.py +0 -1
- aprsd/conf/plugin_common.py +0 -9
- aprsd/main.py +1 -1
- aprsd/packets/__init__.py +8 -0
- aprsd/packets/collector.py +38 -15
- aprsd/packets/log.py +25 -7
- aprsd/packets/packet_list.py +1 -7
- aprsd/packets/seen_list.py +1 -6
- aprsd/packets/tracker.py +1 -7
- aprsd/packets/watch_list.py +1 -4
- aprsd/plugin.py +0 -1
- aprsd/stats/collector.py +6 -7
- aprsd/threads/keep_alive.py +8 -1
- aprsd/utils/__init__.py +55 -0
- {aprsd-3.4.1.dist-info → aprsd-3.4.3.dist-info}/METADATA +27 -33
- {aprsd-3.4.1.dist-info → aprsd-3.4.3.dist-info}/RECORD +26 -27
- {aprsd-3.4.1.dist-info → aprsd-3.4.3.dist-info}/WHEEL +1 -1
- aprsd/messaging.py +0 -4
- {aprsd-3.4.1.dist-info → aprsd-3.4.3.dist-info}/AUTHORS +0 -0
- {aprsd-3.4.1.dist-info → aprsd-3.4.3.dist-info}/LICENSE +0 -0
- {aprsd-3.4.1.dist-info → aprsd-3.4.3.dist-info}/entry_points.txt +0 -0
- {aprsd-3.4.1.dist-info → aprsd-3.4.3.dist-info}/top_level.txt +0 -0
aprsd/client/drivers/aprsis.py
CHANGED
@@ -33,7 +33,11 @@ class Aprsdis(aprslib.IS):
|
|
33
33
|
|
34
34
|
def stop(self):
|
35
35
|
self.thread_stop = True
|
36
|
-
LOG.
|
36
|
+
LOG.warning("Shutdown Aprsdis client.")
|
37
|
+
|
38
|
+
def close(self):
|
39
|
+
LOG.warning("Closing Aprsdis client.")
|
40
|
+
super().close()
|
37
41
|
|
38
42
|
@wrapt.synchronized(lock)
|
39
43
|
def send(self, packet: core.Packet):
|
aprsd/cmds/listen.py
CHANGED
aprsd/cmds/send_message.py
CHANGED
@@ -12,7 +12,9 @@ from aprsd import cli_helper, packets
|
|
12
12
|
from aprsd import conf # noqa : F401
|
13
13
|
from aprsd.client import client_factory
|
14
14
|
from aprsd.main import cli
|
15
|
+
import aprsd.packets # noqa : F401
|
15
16
|
from aprsd.packets import collector
|
17
|
+
from aprsd.packets import log as packet_log
|
16
18
|
from aprsd.threads import tx
|
17
19
|
|
18
20
|
|
@@ -94,10 +96,6 @@ def send_message(
|
|
94
96
|
else:
|
95
97
|
LOG.info(f"L'{aprs_login}' To'{tocallsign}' C'{command}'")
|
96
98
|
|
97
|
-
packets.PacketList()
|
98
|
-
packets.WatchList()
|
99
|
-
packets.SeenList()
|
100
|
-
|
101
99
|
got_ack = False
|
102
100
|
got_response = False
|
103
101
|
|
@@ -106,7 +104,7 @@ def send_message(
|
|
106
104
|
cl = client_factory.create()
|
107
105
|
packet = cl.decode_packet(packet)
|
108
106
|
collector.PacketCollector().rx(packet)
|
109
|
-
|
107
|
+
packet_log.log(packet, tx=False)
|
110
108
|
# LOG.debug("Got packet back {}".format(packet))
|
111
109
|
if isinstance(packet, packets.AckPacket):
|
112
110
|
got_ack = True
|
aprsd/cmds/server.py
CHANGED
@@ -8,7 +8,7 @@ from oslo_config import cfg
|
|
8
8
|
import aprsd
|
9
9
|
from aprsd import cli_helper
|
10
10
|
from aprsd import main as aprsd_main
|
11
|
-
from aprsd import
|
11
|
+
from aprsd import plugin, threads, utils
|
12
12
|
from aprsd.client import client_factory
|
13
13
|
from aprsd.main import cli
|
14
14
|
from aprsd.packets import collector as packet_collector
|
@@ -87,29 +87,24 @@ def server(ctx, flush):
|
|
87
87
|
LOG.error("APRS client is not properly configured in config file.")
|
88
88
|
sys.exit(-1)
|
89
89
|
|
90
|
+
if not CONF.enable_seen_list:
|
91
|
+
# just deregister the class from the packet collector
|
92
|
+
packet_collector.PacketCollector().unregister(seen_list.SeenList)
|
93
|
+
|
90
94
|
# Now load the msgTrack from disk if any
|
91
|
-
packets.PacketList()
|
92
95
|
if flush:
|
93
|
-
LOG.debug("
|
94
|
-
|
95
|
-
packets.WatchList().flush()
|
96
|
-
packets.SeenList().flush()
|
97
|
-
packets.PacketList().flush()
|
96
|
+
LOG.debug("Flushing All packet tracking objects.")
|
97
|
+
packet_collector.PacketCollector().flush()
|
98
98
|
else:
|
99
99
|
# Try and load saved MsgTrack list
|
100
|
-
LOG.debug("Loading saved
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
packets.PacketList().load()
|
100
|
+
LOG.debug("Loading saved packet tracking data.")
|
101
|
+
packet_collector.PacketCollector().load()
|
102
|
+
|
103
|
+
# Now start all the main processing threads.
|
105
104
|
|
106
105
|
keepalive = keep_alive.KeepAliveThread()
|
107
106
|
keepalive.start()
|
108
107
|
|
109
|
-
if not CONF.enable_seen_list:
|
110
|
-
# just deregister the class from the packet collector
|
111
|
-
packet_collector.PacketCollector().unregister(seen_list.SeenList)
|
112
|
-
|
113
108
|
stats_store_thread = stats_thread.APRSDStatsStoreThread()
|
114
109
|
stats_store_thread.start()
|
115
110
|
|
aprsd/cmds/webchat.py
CHANGED
@@ -62,9 +62,7 @@ def signal_handler(sig, frame):
|
|
62
62
|
threads.APRSDThreadList().stop_all()
|
63
63
|
if "subprocess" not in str(frame):
|
64
64
|
time.sleep(1.5)
|
65
|
-
|
66
|
-
# packets.SeenList().save()
|
67
|
-
LOG.info(stats.stats_collector.collect())
|
65
|
+
stats.stats_collector.collect()
|
68
66
|
LOG.info("Telling flask to bail.")
|
69
67
|
signal.signal(signal.SIGTERM, sys.exit(0))
|
70
68
|
|
@@ -647,11 +645,6 @@ def webchat(ctx, flush, port):
|
|
647
645
|
LOG.error("APRS client is not properly configured in config file.")
|
648
646
|
sys.exit(-1)
|
649
647
|
|
650
|
-
packets.PacketList()
|
651
|
-
packets.PacketTrack()
|
652
|
-
packets.WatchList()
|
653
|
-
packets.SeenList()
|
654
|
-
|
655
648
|
keepalive = keep_alive.KeepAliveThread()
|
656
649
|
LOG.info("Start KeepAliveThread")
|
657
650
|
keepalive.start()
|
aprsd/conf/common.py
CHANGED
@@ -205,7 +205,6 @@ enabled_plugins_opts = [
|
|
205
205
|
"aprsd.plugins.fortune.FortunePlugin",
|
206
206
|
"aprsd.plugins.location.LocationPlugin",
|
207
207
|
"aprsd.plugins.ping.PingPlugin",
|
208
|
-
"aprsd.plugins.query.QueryPlugin",
|
209
208
|
"aprsd.plugins.time.TimePlugin",
|
210
209
|
"aprsd.plugins.weather.OWMWeatherPlugin",
|
211
210
|
"aprsd.plugins.version.VersionPlugin",
|
aprsd/conf/plugin_common.py
CHANGED
@@ -31,13 +31,6 @@ aprsfi_opts = [
|
|
31
31
|
),
|
32
32
|
]
|
33
33
|
|
34
|
-
query_plugin_opts = [
|
35
|
-
cfg.StrOpt(
|
36
|
-
"callsign",
|
37
|
-
help="The Ham callsign to allow access to the query plugin from RF.",
|
38
|
-
),
|
39
|
-
]
|
40
|
-
|
41
34
|
owm_wx_opts = [
|
42
35
|
cfg.StrOpt(
|
43
36
|
"apiKey",
|
@@ -172,7 +165,6 @@ def register_opts(config):
|
|
172
165
|
config.register_group(aprsfi_group)
|
173
166
|
config.register_opts(aprsfi_opts, group=aprsfi_group)
|
174
167
|
config.register_group(query_group)
|
175
|
-
config.register_opts(query_plugin_opts, group=query_group)
|
176
168
|
config.register_group(owm_wx_group)
|
177
169
|
config.register_opts(owm_wx_opts, group=owm_wx_group)
|
178
170
|
config.register_group(avwx_group)
|
@@ -184,7 +176,6 @@ def register_opts(config):
|
|
184
176
|
def list_opts():
|
185
177
|
return {
|
186
178
|
aprsfi_group.name: aprsfi_opts,
|
187
|
-
query_group.name: query_plugin_opts,
|
188
179
|
owm_wx_group.name: owm_wx_opts,
|
189
180
|
avwx_group.name: avwx_opts,
|
190
181
|
location_group.name: location_opts,
|
aprsd/main.py
CHANGED
@@ -83,7 +83,7 @@ def signal_handler(sig, frame):
|
|
83
83
|
packets.WatchList().save()
|
84
84
|
packets.SeenList().save()
|
85
85
|
packets.PacketList().save()
|
86
|
-
|
86
|
+
collector.Collector().collect()
|
87
87
|
# signal.signal(signal.SIGTERM, sys.exit(0))
|
88
88
|
# sys.exit(0)
|
89
89
|
|
aprsd/packets/__init__.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
from aprsd.packets import collector
|
1
2
|
from aprsd.packets.core import ( # noqa: F401
|
2
3
|
AckPacket, BeaconPacket, BulletinPacket, GPSPacket, MessagePacket,
|
3
4
|
MicEPacket, ObjectPacket, Packet, RejectPacket, StatusPacket,
|
@@ -9,4 +10,11 @@ from aprsd.packets.tracker import PacketTrack # noqa: F401
|
|
9
10
|
from aprsd.packets.watch_list import WatchList # noqa: F401
|
10
11
|
|
11
12
|
|
13
|
+
# Register all the packet tracking objects.
|
14
|
+
collector.PacketCollector().register(PacketList)
|
15
|
+
collector.PacketCollector().register(SeenList)
|
16
|
+
collector.PacketCollector().register(PacketTrack)
|
17
|
+
collector.PacketCollector().register(WatchList)
|
18
|
+
|
19
|
+
|
12
20
|
NULL_MESSAGE = -1
|
aprsd/packets/collector.py
CHANGED
@@ -20,6 +20,14 @@ class PacketMonitor(Protocol):
|
|
20
20
|
"""When we send a packet out the network."""
|
21
21
|
...
|
22
22
|
|
23
|
+
def flush(self) -> None:
|
24
|
+
"""Flush out any data."""
|
25
|
+
...
|
26
|
+
|
27
|
+
def load(self) -> None:
|
28
|
+
"""Load any data."""
|
29
|
+
...
|
30
|
+
|
23
31
|
|
24
32
|
@singleton
|
25
33
|
class PacketCollector:
|
@@ -27,30 +35,45 @@ class PacketCollector:
|
|
27
35
|
self.monitors: list[Callable] = []
|
28
36
|
|
29
37
|
def register(self, monitor: Callable) -> None:
|
38
|
+
if not isinstance(monitor, PacketMonitor):
|
39
|
+
raise TypeError(f"Monitor {monitor} is not a PacketMonitor")
|
30
40
|
self.monitors.append(monitor)
|
31
41
|
|
32
42
|
def unregister(self, monitor: Callable) -> None:
|
43
|
+
if not isinstance(monitor, PacketMonitor):
|
44
|
+
raise TypeError(f"Monitor {monitor} is not a PacketMonitor")
|
33
45
|
self.monitors.remove(monitor)
|
34
46
|
|
35
47
|
def rx(self, packet: type[core.Packet]) -> None:
|
36
48
|
for name in self.monitors:
|
37
49
|
cls = name()
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
LOG.error(f"Error in monitor {name} (rx): {e}")
|
43
|
-
|
44
|
-
else:
|
45
|
-
raise TypeError(f"Monitor {name} is not a PacketMonitor")
|
50
|
+
try:
|
51
|
+
cls.rx(packet)
|
52
|
+
except Exception as e:
|
53
|
+
LOG.error(f"Error in monitor {name} (rx): {e}")
|
46
54
|
|
47
55
|
def tx(self, packet: type[core.Packet]) -> None:
|
48
56
|
for name in self.monitors:
|
49
57
|
cls = name()
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
58
|
+
try:
|
59
|
+
cls.tx(packet)
|
60
|
+
except Exception as e:
|
61
|
+
LOG.error(f"Error in monitor {name} (tx): {e}")
|
62
|
+
|
63
|
+
def flush(self):
|
64
|
+
"""Call flush on the objects. This is used to flush out any data."""
|
65
|
+
for name in self.monitors:
|
66
|
+
cls = name()
|
67
|
+
try:
|
68
|
+
cls.flush()
|
69
|
+
except Exception as e:
|
70
|
+
LOG.error(f"Error in monitor {name} (flush): {e}")
|
71
|
+
|
72
|
+
def load(self):
|
73
|
+
"""Call load on the objects. This is used to load any data."""
|
74
|
+
for name in self.monitors:
|
75
|
+
cls = name()
|
76
|
+
try:
|
77
|
+
cls.load()
|
78
|
+
except Exception as e:
|
79
|
+
LOG.error(f"Error in monitor {name} (load): {e}")
|
aprsd/packets/log.py
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
import logging
|
2
2
|
from typing import Optional
|
3
3
|
|
4
|
+
from geopy.distance import geodesic
|
4
5
|
from loguru import logger
|
5
6
|
from oslo_config import cfg
|
6
7
|
|
7
|
-
from aprsd
|
8
|
+
from aprsd import utils
|
9
|
+
from aprsd.packets.core import AckPacket, GPSPacket, RejectPacket
|
8
10
|
|
9
11
|
|
10
12
|
LOG = logging.getLogger()
|
@@ -16,6 +18,8 @@ TO_COLOR = "fg #D033FF"
|
|
16
18
|
TX_COLOR = "red"
|
17
19
|
RX_COLOR = "green"
|
18
20
|
PACKET_COLOR = "cyan"
|
21
|
+
DISTANCE_COLOR = "fg #FF5733"
|
22
|
+
DEGREES_COLOR = "fg #FFA900"
|
19
23
|
|
20
24
|
|
21
25
|
def log_multiline(packet, tx: Optional[bool] = False, header: Optional[bool] = True) -> None:
|
@@ -97,19 +101,19 @@ def log(packet, tx: Optional[bool] = False, header: Optional[bool] = True) -> No
|
|
97
101
|
if header:
|
98
102
|
if tx:
|
99
103
|
via_color = "red"
|
100
|
-
arrow = f"<{via_color}
|
104
|
+
arrow = f"<{via_color}>\u2192</{via_color}>"
|
101
105
|
logit.append(
|
102
|
-
f"<red>TX
|
106
|
+
f"<red>TX\u2191</red> "
|
103
107
|
f"<cyan>{name}</cyan>"
|
104
108
|
f":{packet.msgNo}"
|
105
109
|
f" ({packet.send_count + 1} of {pkt_max_send_count})",
|
106
110
|
)
|
107
111
|
else:
|
108
|
-
via_color = "fg #
|
109
|
-
arrow = f"<{via_color}
|
110
|
-
|
112
|
+
via_color = "fg #1AA730"
|
113
|
+
arrow = f"<{via_color}>\u2192</{via_color}>"
|
114
|
+
f"<{via_color}><-</{via_color}>"
|
111
115
|
logit.append(
|
112
|
-
f"<fg #1AA730>RX</fg #1AA730>
|
116
|
+
f"<fg #1AA730>RX\u2193</fg #1AA730> "
|
113
117
|
f"<cyan>{name}</cyan>"
|
114
118
|
f":{packet.msgNo}",
|
115
119
|
)
|
@@ -139,5 +143,19 @@ def log(packet, tx: Optional[bool] = False, header: Optional[bool] = True) -> No
|
|
139
143
|
msg = msg.replace("<", "\\<")
|
140
144
|
logit.append(f"<light-yellow><b>{msg}</b></light-yellow>")
|
141
145
|
|
146
|
+
# is there distance information?
|
147
|
+
if isinstance(packet, GPSPacket) and CONF.latitude and CONF.longitude:
|
148
|
+
my_coords = (CONF.latitude, CONF.longitude)
|
149
|
+
packet_coords = (packet.latitude, packet.longitude)
|
150
|
+
try:
|
151
|
+
bearing = utils.calculate_initial_compass_bearing(my_coords, packet_coords)
|
152
|
+
except Exception as e:
|
153
|
+
LOG.error(f"Failed to calculate bearing: {e}")
|
154
|
+
bearing = 0
|
155
|
+
logit.append(
|
156
|
+
f" : <{DEGREES_COLOR}>{utils.degrees_to_cardinal(bearing, full_string=True)}</{DEGREES_COLOR}>"
|
157
|
+
f"<{DISTANCE_COLOR}>@{geodesic(my_coords, packet_coords).miles:.2f}miles</{DISTANCE_COLOR}>",
|
158
|
+
)
|
159
|
+
|
142
160
|
LOGU.opt(colors=True).info(" ".join(logit))
|
143
161
|
log_multiline(packet, tx, header)
|
aprsd/packets/packet_list.py
CHANGED
@@ -3,7 +3,7 @@ import logging
|
|
3
3
|
|
4
4
|
from oslo_config import cfg
|
5
5
|
|
6
|
-
from aprsd.packets import
|
6
|
+
from aprsd.packets import core
|
7
7
|
from aprsd.utils import objectstore
|
8
8
|
|
9
9
|
|
@@ -108,9 +108,3 @@ class PacketList(objectstore.ObjectStoreMixin):
|
|
108
108
|
"packets": pkts,
|
109
109
|
}
|
110
110
|
return stats
|
111
|
-
|
112
|
-
|
113
|
-
# Now register the PacketList with the collector
|
114
|
-
# every packet we RX and TX goes through the collector
|
115
|
-
# for processing for whatever reason is needed.
|
116
|
-
collector.PacketCollector().register(PacketList)
|
aprsd/packets/seen_list.py
CHANGED
@@ -3,7 +3,7 @@ import logging
|
|
3
3
|
|
4
4
|
from oslo_config import cfg
|
5
5
|
|
6
|
-
from aprsd.packets import
|
6
|
+
from aprsd.packets import core
|
7
7
|
from aprsd.utils import objectstore
|
8
8
|
|
9
9
|
|
@@ -47,8 +47,3 @@ class SeenList(objectstore.ObjectStoreMixin):
|
|
47
47
|
|
48
48
|
def tx(self, packet: type[core.Packet]):
|
49
49
|
"""We don't care about TX packets."""
|
50
|
-
|
51
|
-
|
52
|
-
# Register with the packet collector so we can process the packet
|
53
|
-
# when we get it off the client (network)
|
54
|
-
collector.PacketCollector().register(SeenList)
|
aprsd/packets/tracker.py
CHANGED
@@ -3,7 +3,7 @@ import logging
|
|
3
3
|
|
4
4
|
from oslo_config import cfg
|
5
5
|
|
6
|
-
from aprsd.packets import
|
6
|
+
from aprsd.packets import core
|
7
7
|
from aprsd.utils import objectstore
|
8
8
|
|
9
9
|
|
@@ -101,9 +101,3 @@ class PacketTrack(objectstore.ObjectStoreMixin):
|
|
101
101
|
del self.data[key]
|
102
102
|
except KeyError:
|
103
103
|
pass
|
104
|
-
|
105
|
-
|
106
|
-
# Now register the PacketList with the collector
|
107
|
-
# every packet we RX and TX goes through the collector
|
108
|
-
# for processing for whatever reason is needed.
|
109
|
-
collector.PacketCollector().register(PacketTrack)
|
aprsd/packets/watch_list.py
CHANGED
@@ -4,7 +4,7 @@ import logging
|
|
4
4
|
from oslo_config import cfg
|
5
5
|
|
6
6
|
from aprsd import utils
|
7
|
-
from aprsd.packets import
|
7
|
+
from aprsd.packets import core
|
8
8
|
from aprsd.utils import objectstore
|
9
9
|
|
10
10
|
|
@@ -117,6 +117,3 @@ class WatchList(objectstore.ObjectStoreMixin):
|
|
117
117
|
return False
|
118
118
|
else:
|
119
119
|
return False
|
120
|
-
|
121
|
-
|
122
|
-
collector.PacketCollector().register(WatchList)
|
aprsd/plugin.py
CHANGED
@@ -25,7 +25,6 @@ CORE_MESSAGE_PLUGINS = [
|
|
25
25
|
"aprsd.plugins.fortune.FortunePlugin",
|
26
26
|
"aprsd.plugins.location.LocationPlugin",
|
27
27
|
"aprsd.plugins.ping.PingPlugin",
|
28
|
-
"aprsd.plugins.query.QueryPlugin",
|
29
28
|
"aprsd.plugins.time.TimePlugin",
|
30
29
|
"aprsd.plugins.weather.USWeatherPlugin",
|
31
30
|
"aprsd.plugins.version.VersionPlugin",
|
aprsd/stats/collector.py
CHANGED
@@ -25,14 +25,13 @@ class Collector:
|
|
25
25
|
stats = {}
|
26
26
|
for name in self.producers:
|
27
27
|
cls = name()
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
LOG.error(f"Error in producer {name} (stats): {e}")
|
33
|
-
else:
|
34
|
-
raise TypeError(f"{cls} is not an instance of StatsProducer")
|
28
|
+
try:
|
29
|
+
stats[cls.__class__.__name__] = cls.stats(serializable=serializable).copy()
|
30
|
+
except Exception as e:
|
31
|
+
LOG.error(f"Error in producer {name} (stats): {e}")
|
35
32
|
return stats
|
36
33
|
|
37
34
|
def register_producer(self, producer_name: Callable):
|
35
|
+
if not isinstance(producer_name, StatsProducer):
|
36
|
+
raise TypeError(f"Producer {producer_name} is not a StatsProducer")
|
38
37
|
self.producers.append(producer_name)
|
aprsd/threads/keep_alive.py
CHANGED
@@ -3,6 +3,7 @@ import logging
|
|
3
3
|
import time
|
4
4
|
import tracemalloc
|
5
5
|
|
6
|
+
from loguru import logger
|
6
7
|
from oslo_config import cfg
|
7
8
|
|
8
9
|
from aprsd import packets, utils
|
@@ -14,6 +15,7 @@ from aprsd.threads import APRSDThread, APRSDThreadList
|
|
14
15
|
|
15
16
|
CONF = cfg.CONF
|
16
17
|
LOG = logging.getLogger("APRSD")
|
18
|
+
LOGU = logger
|
17
19
|
|
18
20
|
|
19
21
|
class KeepAliveThread(APRSDThread):
|
@@ -87,7 +89,12 @@ class KeepAliveThread(APRSDThread):
|
|
87
89
|
key = thread["name"]
|
88
90
|
if not alive:
|
89
91
|
LOG.error(f"Thread {thread}")
|
90
|
-
|
92
|
+
|
93
|
+
thread_hex = f"fg {utils.hex_from_name(key)}"
|
94
|
+
t_name = f"<{thread_hex}>{key:<15}</{thread_hex}>"
|
95
|
+
thread_msg = f"{t_name} Alive? {str(alive): <5} {str(age): <20}"
|
96
|
+
LOGU.opt(colors=True).info(thread_msg)
|
97
|
+
# LOG.info(f"{key: <15} Alive? {str(alive): <5} {str(age): <20}")
|
91
98
|
|
92
99
|
# check the APRS connection
|
93
100
|
cl = client_factory.create()
|
aprsd/utils/__init__.py
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
import errno
|
4
4
|
import functools
|
5
|
+
import math
|
5
6
|
import os
|
6
7
|
import re
|
7
8
|
import sys
|
@@ -82,6 +83,16 @@ def rgb_from_name(name):
|
|
82
83
|
return red, green, blue
|
83
84
|
|
84
85
|
|
86
|
+
def hextriplet(colortuple):
|
87
|
+
"""Convert a color tuple to a hex triplet."""
|
88
|
+
return "#" + "".join(f"{i:02X}" for i in colortuple)
|
89
|
+
|
90
|
+
|
91
|
+
def hex_from_name(name):
|
92
|
+
"""Create a hex color from a string."""
|
93
|
+
return hextriplet(rgb_from_name(name))
|
94
|
+
|
95
|
+
|
85
96
|
def human_size(bytes, units=None):
|
86
97
|
"""Returns a human readable string representation of bytes"""
|
87
98
|
if not units:
|
@@ -161,3 +172,47 @@ def load_entry_points(group):
|
|
161
172
|
except Exception as e:
|
162
173
|
print(f"Extension {ep.name} of group {group} failed to load with {e}", file=sys.stderr)
|
163
174
|
print(traceback.format_exc(), file=sys.stderr)
|
175
|
+
|
176
|
+
|
177
|
+
def calculate_initial_compass_bearing(start, end):
|
178
|
+
if (type(start) != tuple) or (type(end) != tuple): # noqa: E721
|
179
|
+
raise TypeError("Only tuples are supported as arguments")
|
180
|
+
|
181
|
+
lat1 = math.radians(float(start[0]))
|
182
|
+
lat2 = math.radians(float(end[0]))
|
183
|
+
|
184
|
+
diff_long = math.radians(float(end[1]) - float(start[1]))
|
185
|
+
|
186
|
+
x = math.sin(diff_long) * math.cos(lat2)
|
187
|
+
y = math.cos(lat1) * math.sin(lat2) - (
|
188
|
+
math.sin(lat1)
|
189
|
+
* math.cos(lat2) * math.cos(diff_long)
|
190
|
+
)
|
191
|
+
|
192
|
+
initial_bearing = math.atan2(x, y)
|
193
|
+
|
194
|
+
# Now we have the initial bearing but math.atan2 return values
|
195
|
+
# from -180° to + 180° which is not what we want for a compass bearing
|
196
|
+
# The solution is to normalize the initial bearing as shown below
|
197
|
+
initial_bearing = math.degrees(initial_bearing)
|
198
|
+
compass_bearing = (initial_bearing + 360) % 360
|
199
|
+
|
200
|
+
return compass_bearing
|
201
|
+
|
202
|
+
|
203
|
+
def degrees_to_cardinal(bearing, full_string=False):
|
204
|
+
if full_string:
|
205
|
+
directions = [
|
206
|
+
"North", "North-Northeast", "Northeast", "East-Northeast", "East", "East-Southeast",
|
207
|
+
"Southeast", "South-Southeast", "South", "South-Southwest", "Southwest", "West-Southwest",
|
208
|
+
"West", "West-Northwest", "Northwest", "North-Northwest", "North",
|
209
|
+
]
|
210
|
+
else:
|
211
|
+
directions = [
|
212
|
+
"N", "NNE", "NE", "ENE", "E", "ESE",
|
213
|
+
"SE", "SSE", "S", "SSW", "SW", "WSW",
|
214
|
+
"W", "WNW", "NW", "NNW", "N",
|
215
|
+
]
|
216
|
+
|
217
|
+
cardinal = directions[round(bearing / 22.5)]
|
218
|
+
return cardinal
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: aprsd
|
3
|
-
Version: 3.4.
|
3
|
+
Version: 3.4.3
|
4
4
|
Summary: APRSd is a APRS-IS server that can be used to connect to APRS-IS and send and receive APRS packets.
|
5
5
|
Author-email: Craig Lamparter <craig@craiger.org>, "Walter A. Boring IV" <waboring@hemna.com>, Emre Saglam <emresaglam@gmail.com>, Jason Martin <jhmartin@toger.us>, John <johng42@users.noreply.github.com>, Martiros Shakhzadyan <vrzh@vrzh.net>, Zoe Moore <zoenb@mailbox.org>, ranguli <hello@joshmurphy.ca>
|
6
6
|
Maintainer-email: Craig Lamparter <craig@craiger.org>, "Walter A. Boring IV" <waboring@hemna.com>
|
@@ -206,10 +206,10 @@ Requires-Dist: attrs==24.2.0
|
|
206
206
|
Requires-Dist: ax253==0.1.5.post1
|
207
207
|
Requires-Dist: beautifulsoup4==4.12.3
|
208
208
|
Requires-Dist: bidict==0.23.1
|
209
|
-
Requires-Dist: bitarray==
|
209
|
+
Requires-Dist: bitarray==3.0.0
|
210
210
|
Requires-Dist: blinker==1.8.2
|
211
211
|
Requires-Dist: certifi==2024.8.30
|
212
|
-
Requires-Dist: charset-normalizer==3.
|
212
|
+
Requires-Dist: charset-normalizer==3.4.0
|
213
213
|
Requires-Dist: click==8.1.7
|
214
214
|
Requires-Dist: click-params==0.5.0
|
215
215
|
Requires-Dist: commonmark==0.9.1
|
@@ -217,15 +217,11 @@ Requires-Dist: dataclasses==0.6
|
|
217
217
|
Requires-Dist: dataclasses-json==0.6.7
|
218
218
|
Requires-Dist: debtcollector==3.0.0
|
219
219
|
Requires-Dist: deprecated==1.2.14
|
220
|
-
Requires-Dist: dnspython==2.6.1
|
221
|
-
Requires-Dist: eventlet==0.37.0
|
222
220
|
Requires-Dist: flask==3.0.3
|
223
221
|
Requires-Dist: flask-httpauth==4.8.0
|
224
|
-
Requires-Dist: flask-socketio==5.
|
222
|
+
Requires-Dist: flask-socketio==5.4.1
|
225
223
|
Requires-Dist: geographiclib==2.0
|
226
224
|
Requires-Dist: geopy==2.4.1
|
227
|
-
Requires-Dist: gevent==24.2.1
|
228
|
-
Requires-Dist: greenlet==3.1.0
|
229
225
|
Requires-Dist: h11==0.14.0
|
230
226
|
Requires-Dist: idna==3.10
|
231
227
|
Requires-Dist: imapclient==3.0.1
|
@@ -234,8 +230,8 @@ Requires-Dist: itsdangerous==2.2.0
|
|
234
230
|
Requires-Dist: jinja2==3.1.4
|
235
231
|
Requires-Dist: kiss3==8.0.0
|
236
232
|
Requires-Dist: loguru==0.7.2
|
237
|
-
Requires-Dist: markupsafe==
|
238
|
-
Requires-Dist: marshmallow==3.
|
233
|
+
Requires-Dist: markupsafe==3.0.2
|
234
|
+
Requires-Dist: marshmallow==3.23.0
|
239
235
|
Requires-Dist: mypy-extensions==1.0.0
|
240
236
|
Requires-Dist: netaddr==1.3.0
|
241
237
|
Requires-Dist: oslo-config==9.6.0
|
@@ -246,7 +242,7 @@ Requires-Dist: pluggy==1.5.0
|
|
246
242
|
Requires-Dist: pygments==2.18.0
|
247
243
|
Requires-Dist: pyserial==3.5
|
248
244
|
Requires-Dist: pyserial-asyncio==0.6
|
249
|
-
Requires-Dist: python-engineio==4.
|
245
|
+
Requires-Dist: python-engineio==4.10.1
|
250
246
|
Requires-Dist: python-socketio==5.11.4
|
251
247
|
Requires-Dist: pytz==2024.2
|
252
248
|
Requires-Dist: pyyaml==6.0.2
|
@@ -255,7 +251,7 @@ Requires-Dist: rfc3986==2.0.0
|
|
255
251
|
Requires-Dist: rich==12.6.0
|
256
252
|
Requires-Dist: rush==2021.4.0
|
257
253
|
Requires-Dist: shellingham==1.5.4
|
258
|
-
Requires-Dist: simple-websocket==1.
|
254
|
+
Requires-Dist: simple-websocket==1.1.0
|
259
255
|
Requires-Dist: six==1.16.0
|
260
256
|
Requires-Dist: soupsieve==2.6
|
261
257
|
Requires-Dist: stevedore==5.3.0
|
@@ -271,30 +267,28 @@ Requires-Dist: werkzeug==3.0.4
|
|
271
267
|
Requires-Dist: wrapt==1.16.0
|
272
268
|
Requires-Dist: wsproto==1.2.0
|
273
269
|
Requires-Dist: zipp==3.20.2
|
274
|
-
Requires-Dist: zope-event==5.0
|
275
|
-
Requires-Dist: zope-interface==7.0.3
|
276
270
|
Provides-Extra: dev
|
277
271
|
Requires-Dist: add-trailing-comma==3.1.0; extra == "dev"
|
278
272
|
Requires-Dist: alabaster==1.0.0; extra == "dev"
|
279
273
|
Requires-Dist: autoflake==1.5.3; extra == "dev"
|
280
274
|
Requires-Dist: babel==2.16.0; extra == "dev"
|
281
|
-
Requires-Dist: black==24.
|
282
|
-
Requires-Dist: build==1.2.2; extra == "dev"
|
275
|
+
Requires-Dist: black==24.10.0; extra == "dev"
|
276
|
+
Requires-Dist: build==1.2.2.post1; extra == "dev"
|
283
277
|
Requires-Dist: cachetools==5.5.0; extra == "dev"
|
284
278
|
Requires-Dist: certifi==2024.8.30; extra == "dev"
|
285
279
|
Requires-Dist: cfgv==3.4.0; extra == "dev"
|
286
280
|
Requires-Dist: chardet==5.2.0; extra == "dev"
|
287
|
-
Requires-Dist: charset-normalizer==3.
|
288
|
-
Requires-Dist: check-manifest==0.
|
281
|
+
Requires-Dist: charset-normalizer==3.4.0; extra == "dev"
|
282
|
+
Requires-Dist: check-manifest==0.50; extra == "dev"
|
289
283
|
Requires-Dist: click==8.1.7; extra == "dev"
|
290
284
|
Requires-Dist: colorama==0.4.6; extra == "dev"
|
291
285
|
Requires-Dist: commonmark==0.9.1; extra == "dev"
|
292
286
|
Requires-Dist: configargparse==1.7; extra == "dev"
|
293
|
-
Requires-Dist: coverage[toml]==7.6.
|
294
|
-
Requires-Dist: distlib==0.3.
|
287
|
+
Requires-Dist: coverage[toml]==7.6.3; extra == "dev"
|
288
|
+
Requires-Dist: distlib==0.3.9; extra == "dev"
|
295
289
|
Requires-Dist: docutils==0.21.2; extra == "dev"
|
296
290
|
Requires-Dist: exceptiongroup==1.2.2; extra == "dev"
|
297
|
-
Requires-Dist: filelock==3.16.
|
291
|
+
Requires-Dist: filelock==3.16.1; extra == "dev"
|
298
292
|
Requires-Dist: fixit==2.1.0; extra == "dev"
|
299
293
|
Requires-Dist: flake8==7.1.1; extra == "dev"
|
300
294
|
Requires-Dist: gray==0.15.0; extra == "dev"
|
@@ -304,35 +298,35 @@ Requires-Dist: imagesize==1.4.1; extra == "dev"
|
|
304
298
|
Requires-Dist: iniconfig==2.0.0; extra == "dev"
|
305
299
|
Requires-Dist: isort==5.13.2; extra == "dev"
|
306
300
|
Requires-Dist: jinja2==3.1.4; extra == "dev"
|
307
|
-
Requires-Dist: libcst==1.
|
301
|
+
Requires-Dist: libcst==1.5.0; extra == "dev"
|
308
302
|
Requires-Dist: m2r==0.3.1; extra == "dev"
|
309
|
-
Requires-Dist: markupsafe==
|
303
|
+
Requires-Dist: markupsafe==3.0.2; extra == "dev"
|
310
304
|
Requires-Dist: mccabe==0.7.0; extra == "dev"
|
311
305
|
Requires-Dist: mistune==0.8.4; extra == "dev"
|
312
306
|
Requires-Dist: moreorless==0.4.0; extra == "dev"
|
313
|
-
Requires-Dist: mypy==1.
|
307
|
+
Requires-Dist: mypy==1.12.0; extra == "dev"
|
314
308
|
Requires-Dist: mypy-extensions==1.0.0; extra == "dev"
|
315
309
|
Requires-Dist: nodeenv==1.9.1; extra == "dev"
|
316
310
|
Requires-Dist: packaging==24.1; extra == "dev"
|
317
311
|
Requires-Dist: pathspec==0.12.1; extra == "dev"
|
318
312
|
Requires-Dist: pep8-naming==0.14.1; extra == "dev"
|
319
313
|
Requires-Dist: pip-tools==7.4.1; extra == "dev"
|
320
|
-
Requires-Dist: platformdirs==4.3.
|
314
|
+
Requires-Dist: platformdirs==4.3.6; extra == "dev"
|
321
315
|
Requires-Dist: pluggy==1.5.0; extra == "dev"
|
322
|
-
Requires-Dist: pre-commit==
|
316
|
+
Requires-Dist: pre-commit==4.0.1; extra == "dev"
|
323
317
|
Requires-Dist: pycodestyle==2.12.1; extra == "dev"
|
324
318
|
Requires-Dist: pyflakes==3.2.0; extra == "dev"
|
325
319
|
Requires-Dist: pygments==2.18.0; extra == "dev"
|
326
|
-
Requires-Dist: pyproject-api==1.
|
327
|
-
Requires-Dist: pyproject-hooks==1.
|
320
|
+
Requires-Dist: pyproject-api==1.8.0; extra == "dev"
|
321
|
+
Requires-Dist: pyproject-hooks==1.2.0; extra == "dev"
|
328
322
|
Requires-Dist: pytest==8.3.3; extra == "dev"
|
329
323
|
Requires-Dist: pytest-cov==5.0.0; extra == "dev"
|
330
|
-
Requires-Dist: pyupgrade==3.
|
324
|
+
Requires-Dist: pyupgrade==3.18.0; extra == "dev"
|
331
325
|
Requires-Dist: pyyaml==6.0.2; extra == "dev"
|
332
326
|
Requires-Dist: requests==2.32.3; extra == "dev"
|
333
327
|
Requires-Dist: rich==12.6.0; extra == "dev"
|
334
328
|
Requires-Dist: snowballstemmer==2.2.0; extra == "dev"
|
335
|
-
Requires-Dist: sphinx==8.
|
329
|
+
Requires-Dist: sphinx==8.1.3; extra == "dev"
|
336
330
|
Requires-Dist: sphinxcontrib-applehelp==2.0.0; extra == "dev"
|
337
331
|
Requires-Dist: sphinxcontrib-devhelp==2.0.0; extra == "dev"
|
338
332
|
Requires-Dist: sphinxcontrib-htmlhelp==2.1.0; extra == "dev"
|
@@ -341,14 +335,14 @@ Requires-Dist: sphinxcontrib-qthelp==2.0.0; extra == "dev"
|
|
341
335
|
Requires-Dist: sphinxcontrib-serializinghtml==2.0.0; extra == "dev"
|
342
336
|
Requires-Dist: tokenize-rt==6.0.0; extra == "dev"
|
343
337
|
Requires-Dist: toml==0.10.2; extra == "dev"
|
344
|
-
Requires-Dist: tomli==2.0.
|
345
|
-
Requires-Dist: tox==4.
|
338
|
+
Requires-Dist: tomli==2.0.2; extra == "dev"
|
339
|
+
Requires-Dist: tox==4.23.0; extra == "dev"
|
346
340
|
Requires-Dist: trailrunner==1.4.0; extra == "dev"
|
347
341
|
Requires-Dist: typing-extensions==4.12.2; extra == "dev"
|
348
342
|
Requires-Dist: unify==0.5; extra == "dev"
|
349
343
|
Requires-Dist: untokenize==0.1.1; extra == "dev"
|
350
344
|
Requires-Dist: urllib3==2.2.3; extra == "dev"
|
351
|
-
Requires-Dist: virtualenv==20.
|
345
|
+
Requires-Dist: virtualenv==20.27.0; extra == "dev"
|
352
346
|
Requires-Dist: wheel==0.44.0; extra == "dev"
|
353
347
|
|
354
348
|
===============================================
|
@@ -1,9 +1,8 @@
|
|
1
1
|
aprsd/__init__.py,sha256=ci_49KK2a4GXyxcM2lFZfNAOsBfXzh0yayIGQazw56I,687
|
2
2
|
aprsd/cli_helper.py,sha256=AgSSn6oTUdCDv4Ne1Jyg_0bi7GwINBBKotTLk_QE-cY,4568
|
3
3
|
aprsd/exception.py,sha256=FyeehwYENwsRKyrU2WmgEPmcHsDLjdGRAe35f01Bu5A,502
|
4
|
-
aprsd/main.py,sha256=
|
5
|
-
aprsd/
|
6
|
-
aprsd/plugin.py,sha256=HGTuGUdtjOi4QBwLC1FQ4GPBBfRvGTxt1by0V9bCk1I,17366
|
4
|
+
aprsd/main.py,sha256=lNK3vogRN2ikSgBl-5gMxN3kwGq_ePsSYKZFz6f0FDQ,4663
|
5
|
+
aprsd/plugin.py,sha256=qgX_XW_U0LA0xcugMS2z6fdTGAm4DD2d3mo_JG3rfZU,17327
|
7
6
|
aprsd/plugin_utils.py,sha256=xKQbliwikJxw_E5TGK_BcBPXkHeJ1PqVxSCFcDbf1xg,2507
|
8
7
|
aprsd/wsgi.py,sha256=EsRRetouRSsQp5GCJdagybmgRXCBQeLl8rcdBUPDv7Y,8720
|
9
8
|
aprsd/client/__init__.py,sha256=aajKndFPk259RLTUuobVDleJmOENHvdRVodfhY5BmX8,348
|
@@ -14,7 +13,7 @@ aprsd/client/fake.py,sha256=-IMMpGwoQLbm0uW2eLkAADNySPj5zntBOt-tEfoF-gQ,1028
|
|
14
13
|
aprsd/client/kiss.py,sha256=y9qAJPmmtyWUy2BoMT_lrpw3fY0Ggv3smWvQabdImUI,2945
|
15
14
|
aprsd/client/stats.py,sha256=0MUS3IVfYgEX0Aan-lMz3VDi7_jCzVhacSN9XIQVJfw,1040
|
16
15
|
aprsd/client/drivers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
|
-
aprsd/client/drivers/aprsis.py,sha256=
|
16
|
+
aprsd/client/drivers/aprsis.py,sha256=V3wuCavJC_c8zezQChFP2M7dV8IScHUOTAZOKGzkL1w,7353
|
18
17
|
aprsd/client/drivers/fake.py,sha256=TyqwQ4XYzbT83r0jSBI-oyl9q6BK60TgVuFm2_nkrnw,2059
|
19
18
|
aprsd/client/drivers/kiss.py,sha256=XvXvBgpv_i1kgV5MmdTR5DwRXEiT86M49Pa7vw8-gsA,3350
|
20
19
|
aprsd/cmds/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -23,27 +22,27 @@ aprsd/cmds/dev.py,sha256=5RmGvdrObg1hjr93jLCpq2Fql6ZRPWvXcx9ZU2SNj2A,4393
|
|
23
22
|
aprsd/cmds/fetch_stats.py,sha256=dVvhOWpATNGq0e_hbLe47MZ2dCLOO3XTd6zzqqQ1Lp8,4988
|
24
23
|
aprsd/cmds/healthcheck.py,sha256=mVrBIasdCnw-_vzuh15p4H1TFmiGg80WVXgXBcd2PMg,2628
|
25
24
|
aprsd/cmds/list_plugins.py,sha256=gSIa7uMZAvXylJ89GI3RU9wj6TPioREvBNfClVyfiOM,10653
|
26
|
-
aprsd/cmds/listen.py,sha256=
|
27
|
-
aprsd/cmds/send_message.py,sha256=
|
28
|
-
aprsd/cmds/server.py,sha256=
|
29
|
-
aprsd/cmds/webchat.py,sha256=
|
25
|
+
aprsd/cmds/listen.py,sha256=1KIe2qD7cWXX58L1d57r2PtTccXPhuDz5KkkyqPlGWw,7160
|
26
|
+
aprsd/cmds/send_message.py,sha256=hoTKPsSMzd9ajz9fl9pbVxA0JL7AAW29L1jgZAlq2zw,4729
|
27
|
+
aprsd/cmds/server.py,sha256=3WGfscWUK_b5OVOqEeAtrGB7Cu51Epa1xQo6GhgAewU,4168
|
28
|
+
aprsd/cmds/webchat.py,sha256=1T70AI2bdwxWVSdP-DrqALsVPxJ6n4EvJdJzvCjLy2w,20197
|
30
29
|
aprsd/conf/__init__.py,sha256=6j-N6jT49OYcp8dD8oZGt7mxWSOSUnWXeTIZW_C0bmw,1725
|
31
30
|
aprsd/conf/client.py,sha256=w_Z6Pc5LUYzJzDsfhCcnMBLkPi9njNdCGOe3GfbpGaA,3029
|
32
|
-
aprsd/conf/common.py,sha256=
|
31
|
+
aprsd/conf/common.py,sha256=qzOgKxby1I-9_fQEAZ7jjnA2f4FLZKby9rhTFSaQQLY,8966
|
33
32
|
aprsd/conf/log.py,sha256=v5C2Lda6x39IdamHpelOY6tDHPkqHyx_qmPF3WEmeAE,1424
|
34
33
|
aprsd/conf/opts.py,sha256=Jq1DPyDdNyN2rbuHq8O-lF2Entkb9tFTbh9gjZwWC5s,2701
|
35
|
-
aprsd/conf/plugin_common.py,sha256=
|
34
|
+
aprsd/conf/plugin_common.py,sha256=pqYNKKwHTYVI-yUnrX3MZhrQz8fVx6arZN7VfAIbnzs,5999
|
36
35
|
aprsd/conf/plugin_email.py,sha256=IB8G_vTCC-6HVGx9y1PP2vKXfXRzlEx9lEFXdIIGHzA,2332
|
37
36
|
aprsd/log/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
38
37
|
aprsd/log/log.py,sha256=cd1bMGdlcWHW393btpAw1cc3oYD0nEzY5O596MO6H94,3884
|
39
|
-
aprsd/packets/__init__.py,sha256=
|
40
|
-
aprsd/packets/collector.py,sha256=
|
38
|
+
aprsd/packets/__init__.py,sha256=ELcYtnQKDvdCRhQmhiHaKG4w5JYl2foeWxnqTqsB-08,786
|
39
|
+
aprsd/packets/collector.py,sha256=VhuHj2CRxVtaC6QDKiYMnxRzNVj-fc7wkMyPpTl83Og,2322
|
41
40
|
aprsd/packets/core.py,sha256=Ke6WDofzpMZSOdDfGsxZal8vdJrKUXLedDXGu7FcAZg,27400
|
42
|
-
aprsd/packets/log.py,sha256=
|
43
|
-
aprsd/packets/packet_list.py,sha256=
|
44
|
-
aprsd/packets/seen_list.py,sha256=
|
45
|
-
aprsd/packets/tracker.py,sha256=
|
46
|
-
aprsd/packets/watch_list.py,sha256=
|
41
|
+
aprsd/packets/log.py,sha256=mqYq06mK4JgESPKZ4JQ6vWJqorTSp73u7IiITqdlWwE,5347
|
42
|
+
aprsd/packets/packet_list.py,sha256=MGLatHvdKcQvuFmeWlHsHIB0jrYMD9eszeISaL8-GYw,3304
|
43
|
+
aprsd/packets/seen_list.py,sha256=fV87eyXeFxaZKqWfY1GOCQ6zfnjI1Or6i3KS_qJLuoA,1375
|
44
|
+
aprsd/packets/tracker.py,sha256=Fr7B9Ex2kikmAkUz0HNUEsx9p60ap9L7A96bkv9WaO0,2950
|
45
|
+
aprsd/packets/watch_list.py,sha256=TcvQsleypvxI2o_fbTr4sAAlmjRb9YpC7LbyNxTwfic,3728
|
47
46
|
aprsd/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
48
47
|
aprsd/plugins/email.py,sha256=U0v4crh5uSDWrEes7HHPpXI6eyF7ySYyqqKp2j1klDs,23627
|
49
48
|
aprsd/plugins/fortune.py,sha256=XCSIaZ9JXC3LZOMV5tSr3dAvbVvIn4xSUdWxpZHStfc,1573
|
@@ -55,16 +54,16 @@ aprsd/plugins/version.py,sha256=NAPFKQ0lQqgjoDyTVy8tZcRGmdcJE_ZogRElDz27V2U,839
|
|
55
54
|
aprsd/plugins/weather.py,sha256=iZ4Zv_23-2dquNKXhsiimFVlMEVoBNKyom4LtORwuoU,13333
|
56
55
|
aprsd/stats/__init__.py,sha256=AM4GoTleOfBBitcCd6E432-jlg2dKVnL5Yw4OtcW25E,892
|
57
56
|
aprsd/stats/app.py,sha256=axqMA137zKqU03yO8XI5f1QE8ajmr9YK0J9O9m4iSzo,1378
|
58
|
-
aprsd/stats/collector.py,sha256=
|
57
|
+
aprsd/stats/collector.py,sha256=RF4QvbXa3a96ejS5TPfrtSiShMJp208Cb81-K3o_iMo,1197
|
59
58
|
aprsd/threads/__init__.py,sha256=b8Dma0cWE7356WU_Ehvm0RtL4-zCJNUchPFArJd2Gtw,274
|
60
59
|
aprsd/threads/aprsd.py,sha256=r2WlvtND0YTpq8jotRacZegD4WjX8msPDpl3ccqZo_Y,3292
|
61
|
-
aprsd/threads/keep_alive.py,sha256=
|
60
|
+
aprsd/threads/keep_alive.py,sha256=9rvzPjgpipfk_Ze47w8rnmWomdrn3sd3uUBVk9rta_I,5258
|
62
61
|
aprsd/threads/log_monitor.py,sha256=_-ku02-Sy8m2sG1HFHP2Q_KfzUQfwjd4xaJ5XQlNUTw,3368
|
63
62
|
aprsd/threads/registry.py,sha256=5DuzNSwhOEwI0Gl5j9e286uqbxzKLSHzInfPy61r7PI,1702
|
64
63
|
aprsd/threads/rx.py,sha256=_tO4agZpjb52snaIi3RbnEwaBTGIS0fzaK7pnn45QPk,13463
|
65
64
|
aprsd/threads/stats.py,sha256=Yey3B2iuGUQsNuUiFxvXKJU_1pif8gfOb5uP_U2-hS8,959
|
66
65
|
aprsd/threads/tx.py,sha256=W5mP2voefECb4UWf-BXfaFjrYLCbsjAcNmLWl10ntEo,8322
|
67
|
-
aprsd/utils/__init__.py,sha256=
|
66
|
+
aprsd/utils/__init__.py,sha256=n2LtDxMVyFrStSJYOFnWbt3blTSUDrM17-CPJJDDxw0,6336
|
68
67
|
aprsd/utils/counter.py,sha256=obIO0d9qCuhlvZI8Xf4DrjFlgHh-EuMZTVGv6gzQBkM,1202
|
69
68
|
aprsd/utils/fuzzyclock.py,sha256=qKV8SYZhQGOHG9biF8TeueLb6RMppspx1Zg4IOy1Z10,3265
|
70
69
|
aprsd/utils/json.py,sha256=LR2g-sealCRyXnujjTNxNYUxBagrdBqYQxNLYJQGYaM,2487
|
@@ -125,10 +124,10 @@ aprsd/web/chat/static/js/upstream/jquery.toast.js,sha256=V4m4PbwAYUb9yr3uP64y2og
|
|
125
124
|
aprsd/web/chat/static/js/upstream/semantic.min.js,sha256=AYdrntK9PGcU1ZsyD7fTBJ4o0j1bMeD4xn7P-UagMW4,403125
|
126
125
|
aprsd/web/chat/static/js/upstream/socket.io.min.js,sha256=dYF5MG5zs6ekpbIOXBXelJXquX0gi_c48kkYm8tCaYE,64274
|
127
126
|
aprsd/web/chat/templates/index.html,sha256=9z8JoF3W6SlPndf28iCgdHwiaG9_f9fnk5nXWEfx5wg,6633
|
128
|
-
aprsd-3.4.
|
129
|
-
aprsd-3.4.
|
130
|
-
aprsd-3.4.
|
131
|
-
aprsd-3.4.
|
132
|
-
aprsd-3.4.
|
133
|
-
aprsd-3.4.
|
134
|
-
aprsd-3.4.
|
127
|
+
aprsd-3.4.3.dist-info/AUTHORS,sha256=-4JB7i9LE12SYMbLc4Rk6iXlQ0J7C4mC1RV6-vnO53E,467
|
128
|
+
aprsd-3.4.3.dist-info/LICENSE,sha256=CeipvOyAZxBGUsFoaFqwkx54aPnIKEtm9a5u2uXxEws,10142
|
129
|
+
aprsd-3.4.3.dist-info/METADATA,sha256=JHpZuRA4Mnac5eiFaOQQKA5ywvSdUOus4gEGPdM1rCA,39875
|
130
|
+
aprsd-3.4.3.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
131
|
+
aprsd-3.4.3.dist-info/entry_points.txt,sha256=4fReoJUB-bFqOUK6eeXYYCvTdVLprL7KVH0hWQRP9eM,171
|
132
|
+
aprsd-3.4.3.dist-info/top_level.txt,sha256=v1O96niUcJOTMh9aQnFRknbScJ6mMOwqurdbxeaeSjs,6
|
133
|
+
aprsd-3.4.3.dist-info/RECORD,,
|
aprsd/messaging.py
DELETED
File without changes
|
File without changes
|
File without changes
|
File without changes
|