aprsd 3.4.1__py3-none-any.whl → 3.4.2__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.
@@ -33,7 +33,11 @@ class Aprsdis(aprslib.IS):
33
33
 
34
34
  def stop(self):
35
35
  self.thread_stop = True
36
- LOG.info("Shutdown Aprsdis client.")
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
@@ -42,7 +42,8 @@ def signal_handler(sig, frame):
42
42
  ),
43
43
  )
44
44
  time.sleep(5)
45
- LOG.info(collector.Collector().collect())
45
+ # Last save to disk
46
+ collector.Collector().collect()
46
47
 
47
48
 
48
49
  class APRSDListenThread(rx.APRSDRXThread):
@@ -12,6 +12,7 @@ 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
16
17
  from aprsd.threads import tx
17
18
 
@@ -94,10 +95,6 @@ def send_message(
94
95
  else:
95
96
  LOG.info(f"L'{aprs_login}' To'{tocallsign}' C'{command}'")
96
97
 
97
- packets.PacketList()
98
- packets.WatchList()
99
- packets.SeenList()
100
-
101
98
  got_ack = False
102
99
  got_response = False
103
100
 
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 packets, plugin, threads, utils
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("Deleting saved MsgTrack.")
94
- packets.PacketTrack().flush()
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 MsgTrack object.")
101
- packets.PacketTrack().load()
102
- packets.WatchList().load()
103
- packets.SeenList().load()
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
- # packets.WatchList().save()
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",
@@ -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
- LOG.info(collector.Collector().collect())
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
@@ -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
- 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")
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
- 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")
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.packets.core import AckPacket, RejectPacket
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}>-></{via_color}>"
104
+ arrow = f"<{via_color}>\u2192</{via_color}>"
101
105
  logit.append(
102
- f"<red>TX {arrow}</red> "
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 #828282"
109
- arrow = f"<{via_color}>-></{via_color}>"
110
- left_arrow = f"<{via_color}><-</{via_color}>"
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> {left_arrow} "
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)
@@ -3,7 +3,7 @@ import logging
3
3
 
4
4
  from oslo_config import cfg
5
5
 
6
- from aprsd.packets import collector, core
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)
@@ -3,7 +3,7 @@ import logging
3
3
 
4
4
  from oslo_config import cfg
5
5
 
6
- from aprsd.packets import collector, core
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 collector, core
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)
@@ -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 collector, core
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
- if isinstance(cls, StatsProducer):
29
- try:
30
- stats[cls.__class__.__name__] = cls.stats(serializable=serializable).copy()
31
- except Exception as e:
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)
@@ -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
- LOG.info(f"{key: <15} Alive? {str(alive): <5} {str(age): <20}")
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.1
3
+ Version: 3.4.2
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==2.9.2
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.3.2
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.3.7
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==2.1.5
238
- Requires-Dist: marshmallow==3.22.0
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.9.1
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.0.0
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.8.0; extra == "dev"
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.3.2; extra == "dev"
288
- Requires-Dist: check-manifest==0.49; extra == "dev"
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.1; extra == "dev"
294
- Requires-Dist: distlib==0.3.8; extra == "dev"
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.0; extra == "dev"
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.4.0; extra == "dev"
301
+ Requires-Dist: libcst==1.5.0; extra == "dev"
308
302
  Requires-Dist: m2r==0.3.1; extra == "dev"
309
- Requires-Dist: markupsafe==2.1.5; extra == "dev"
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.11.2; extra == "dev"
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.3; extra == "dev"
314
+ Requires-Dist: platformdirs==4.3.6; extra == "dev"
321
315
  Requires-Dist: pluggy==1.5.0; extra == "dev"
322
- Requires-Dist: pre-commit==3.8.0; extra == "dev"
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.7.1; extra == "dev"
327
- Requires-Dist: pyproject-hooks==1.1.0; extra == "dev"
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.17.0; extra == "dev"
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.0.2; extra == "dev"
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.1; extra == "dev"
345
- Requires-Dist: tox==4.18.1; extra == "dev"
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.26.4; extra == "dev"
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=aOVLKdTWVx9ahoG2UAqtPJVzy6sScekwBFkj6gjaIeM,4673
5
- aprsd/messaging.py,sha256=0zE2y0jJBTxTwwgt8_XmSeMZfBTO77ZBY0GyGe8DX_w,134
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=PsIR77ao5QlaLR_Jq7uAkNUJQiw6q8swch2Pl8m2JyM,7257
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=PH7wGporM8LJDVHyDsZ--kKZ0oIGoR3q9hhKu6FfE64,7142
27
- aprsd/cmds/send_message.py,sha256=cZ1fbWB9SeI5ga4_Omr-Ucq8QML1aenaO17N-QB1Abg,4706
28
- aprsd/cmds/server.py,sha256=Un5mTIN9ilUWwP-Wn8Gi_lMQ5O94EWVWmqJ5urno368,4321
29
- aprsd/cmds/webchat.py,sha256=EwIkr2QXpmOQLrTfuU2JaYv8frELww1I0vII-a7hNtE,20379
25
+ aprsd/cmds/listen.py,sha256=1KIe2qD7cWXX58L1d57r2PtTccXPhuDz5KkkyqPlGWw,7160
26
+ aprsd/cmds/send_message.py,sha256=lNIjlezdntAAqGwgXQ4sJwKnUBnKUyCwok68jc35MYs,4669
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=LTLVtz9fFXsnYIhq2Hv73r-tn-Y7nW4rRJj5KCLFtuA,9013
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=HKNV2JKCJOPUqTdoFgc96mGNZLU6zNii2syjuJj8tAo,6253
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=OK2qFCNscFcMlimHJvP__R-7Igre4b912t3gGflNqIw,510
40
- aprsd/packets/collector.py,sha256=qPk2vQZyBJSjgOsc_RTSWUsXMsKd6L4YJoVG5NjFV1c,1636
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=jCcZazhivzlo38nEE3qnUiaZGNhtpX3QUgG1ExofwrM,4545
43
- aprsd/packets/packet_list.py,sha256=s3b3uFyZYo_3xv4DFLTKU2qyQHTaTxAW6wotgZksc1o,3518
44
- aprsd/packets/seen_list.py,sha256=mH_yAN5KVajmF-W5G-uKPgZDhxy7lOI1Ds7n1mkBGdE,1543
45
- aprsd/packets/tracker.py,sha256=4uZJ7I1uAxOohF1LFxhsokNYKA7Am_XbAP3Kix_XLJw,3165
46
- aprsd/packets/watch_list.py,sha256=Fn6_eqkgWnXjEIx82roiWqJoPewcb7qdNjq_gpYqWD8,3789
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=NqThUI3d2WTwf2CbXooTIUWXlqt91cC4HTW3dPBt8jg,1219
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=pAhBdzBFcAgQ4_DEUdOVfrIpyM-Rz_rO9Hp8KI-Yyq8,4934
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=X9tYE5o5Bn_dn-y0N33JEJ-GBQWr-isLn6GiEV1LCsg,4547
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.1.dist-info/AUTHORS,sha256=-4JB7i9LE12SYMbLc4Rk6iXlQ0J7C4mC1RV6-vnO53E,467
129
- aprsd-3.4.1.dist-info/LICENSE,sha256=CeipvOyAZxBGUsFoaFqwkx54aPnIKEtm9a5u2uXxEws,10142
130
- aprsd-3.4.1.dist-info/METADATA,sha256=aSg0NUOpR19y8oJAtiT_rCzfOSO5-u7b7mm3IT3SQLc,40060
131
- aprsd-3.4.1.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
132
- aprsd-3.4.1.dist-info/entry_points.txt,sha256=4fReoJUB-bFqOUK6eeXYYCvTdVLprL7KVH0hWQRP9eM,171
133
- aprsd-3.4.1.dist-info/top_level.txt,sha256=v1O96niUcJOTMh9aQnFRknbScJ6mMOwqurdbxeaeSjs,6
134
- aprsd-3.4.1.dist-info/RECORD,,
127
+ aprsd-3.4.2.dist-info/AUTHORS,sha256=-4JB7i9LE12SYMbLc4Rk6iXlQ0J7C4mC1RV6-vnO53E,467
128
+ aprsd-3.4.2.dist-info/LICENSE,sha256=CeipvOyAZxBGUsFoaFqwkx54aPnIKEtm9a5u2uXxEws,10142
129
+ aprsd-3.4.2.dist-info/METADATA,sha256=G25erCky2XI69HPnI27Ia5ti-mK4u7Op3dff4zttSDY,39875
130
+ aprsd-3.4.2.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
131
+ aprsd-3.4.2.dist-info/entry_points.txt,sha256=4fReoJUB-bFqOUK6eeXYYCvTdVLprL7KVH0hWQRP9eM,171
132
+ aprsd-3.4.2.dist-info/top_level.txt,sha256=v1O96niUcJOTMh9aQnFRknbScJ6mMOwqurdbxeaeSjs,6
133
+ aprsd-3.4.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.1.0)
2
+ Generator: setuptools (75.2.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
aprsd/messaging.py DELETED
@@ -1,4 +0,0 @@
1
- # What to return from a plugin if we have processed the message
2
- # and it's ok, but don't send a usage string back
3
-
4
- # REMOVE THIS FILE
File without changes
File without changes