aprsd 4.0.1__py3-none-any.whl → 4.1.0__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/cmds/listen.py CHANGED
@@ -20,8 +20,10 @@ from aprsd import cli_helper, packets, plugin, threads, utils
20
20
  from aprsd.client import client_factory
21
21
  from aprsd.main import cli
22
22
  from aprsd.packets import collector as packet_collector
23
+ from aprsd.packets import core, seen_list
23
24
  from aprsd.packets import log as packet_log
24
- from aprsd.packets import seen_list
25
+ from aprsd.packets.filter import PacketFilter
26
+ from aprsd.packets.filters import dupe_filter, packet_type
25
27
  from aprsd.stats import collector
26
28
  from aprsd.threads import keepalive, rx
27
29
  from aprsd.threads import stats as stats_thread
@@ -29,7 +31,7 @@ from aprsd.threads.aprsd import APRSDThread
29
31
 
30
32
  # setup the global logger
31
33
  # log.basicConfig(level=log.DEBUG) # level=10
32
- LOG = logging.getLogger("APRSD")
34
+ LOG = logging.getLogger('APRSD')
33
35
  CONF = cfg.CONF
34
36
  LOGU = logger
35
37
  console = Console()
@@ -37,9 +39,9 @@ console = Console()
37
39
 
38
40
  def signal_handler(sig, frame):
39
41
  threads.APRSDThreadList().stop_all()
40
- if "subprocess" not in str(frame):
42
+ if 'subprocess' not in str(frame):
41
43
  LOG.info(
42
- "Ctrl+C, Sending all threads exit! Can take up to 10 seconds {}".format(
44
+ 'Ctrl+C, Sending all threads exit! Can take up to 10 seconds {}'.format(
43
45
  datetime.datetime.now(),
44
46
  ),
45
47
  )
@@ -48,90 +50,66 @@ def signal_handler(sig, frame):
48
50
  collector.Collector().collect()
49
51
 
50
52
 
51
- class APRSDListenThread(rx.APRSDRXThread):
53
+ class APRSDListenProcessThread(rx.APRSDFilterThread):
52
54
  def __init__(
53
55
  self,
54
56
  packet_queue,
55
57
  packet_filter=None,
56
58
  plugin_manager=None,
57
- enabled_plugins=[],
59
+ enabled_plugins=None,
58
60
  log_packets=False,
59
61
  ):
60
- super().__init__(packet_queue)
62
+ super().__init__('ListenProcThread', packet_queue)
61
63
  self.packet_filter = packet_filter
62
64
  self.plugin_manager = plugin_manager
63
65
  if self.plugin_manager:
64
- LOG.info(f"Plugins {self.plugin_manager.get_message_plugins()}")
66
+ LOG.info(f'Plugins {self.plugin_manager.get_message_plugins()}')
65
67
  self.log_packets = log_packets
66
68
 
67
- def process_packet(self, *args, **kwargs):
68
- packet = self._client.decode_packet(*args, **kwargs)
69
- filters = {
70
- packets.Packet.__name__: packets.Packet,
71
- packets.AckPacket.__name__: packets.AckPacket,
72
- packets.BeaconPacket.__name__: packets.BeaconPacket,
73
- packets.GPSPacket.__name__: packets.GPSPacket,
74
- packets.MessagePacket.__name__: packets.MessagePacket,
75
- packets.MicEPacket.__name__: packets.MicEPacket,
76
- packets.ObjectPacket.__name__: packets.ObjectPacket,
77
- packets.StatusPacket.__name__: packets.StatusPacket,
78
- packets.ThirdPartyPacket.__name__: packets.ThirdPartyPacket,
79
- packets.WeatherPacket.__name__: packets.WeatherPacket,
80
- packets.UnknownPacket.__name__: packets.UnknownPacket,
81
- }
82
-
83
- if self.packet_filter:
84
- filter_class = filters[self.packet_filter]
85
- if isinstance(packet, filter_class):
86
- if self.log_packets:
87
- packet_log.log(packet)
88
- if self.plugin_manager:
89
- # Don't do anything with the reply
90
- # This is the listen only command.
91
- self.plugin_manager.run(packet)
92
- else:
93
- if self.log_packets:
94
- packet_log.log(packet)
95
- if self.plugin_manager:
96
- # Don't do anything with the reply.
97
- # This is the listen only command.
98
- self.plugin_manager.run(packet)
99
-
100
- packet_collector.PacketCollector().rx(packet)
69
+ def print_packet(self, packet):
70
+ if self.log_packets:
71
+ packet_log.log(packet)
72
+
73
+ def process_packet(self, packet: type[core.Packet]):
74
+ if self.plugin_manager:
75
+ # Don't do anything with the reply.
76
+ # This is the listen only command.
77
+ self.plugin_manager.run(packet)
101
78
 
102
79
 
103
80
  class ListenStatsThread(APRSDThread):
104
81
  """Log the stats from the PacketList."""
105
82
 
106
83
  def __init__(self):
107
- super().__init__("PacketStatsLog")
84
+ super().__init__('PacketStatsLog')
108
85
  self._last_total_rx = 0
86
+ self.period = 31
109
87
 
110
88
  def loop(self):
111
- if self.loop_count % 10 == 0:
89
+ if self.loop_count % self.period == 0:
112
90
  # log the stats every 10 seconds
113
91
  stats_json = collector.Collector().collect()
114
- stats = stats_json["PacketList"]
115
- total_rx = stats["rx"]
116
- packet_count = len(stats["packets"])
92
+ stats = stats_json['PacketList']
93
+ total_rx = stats['rx']
94
+ packet_count = len(stats['packets'])
117
95
  rx_delta = total_rx - self._last_total_rx
118
- rate = rx_delta / 10
96
+ rate = rx_delta / self.period
119
97
 
120
98
  # Log summary stats
121
99
  LOGU.opt(colors=True).info(
122
- f"<green>RX Rate: {rate} pps</green> "
123
- f"<yellow>Total RX: {total_rx}</yellow> "
124
- f"<red>RX Last 10 secs: {rx_delta}</red> "
125
- f"<white>Packets in PacketList: {packet_count}</white>",
100
+ f'<green>RX Rate: {rate:.2f} pps</green> '
101
+ f'<yellow>Total RX: {total_rx}</yellow> '
102
+ f'<red>RX Last {self.period} secs: {rx_delta}</red> '
103
+ f'<white>Packets in PacketListStats: {packet_count}</white>',
126
104
  )
127
105
  self._last_total_rx = total_rx
128
106
 
129
107
  # Log individual type stats
130
- for k, v in stats["types"].items():
131
- thread_hex = f"fg {utils.hex_from_name(k)}"
108
+ for k, v in stats['types'].items():
109
+ thread_hex = f'fg {utils.hex_from_name(k)}'
132
110
  LOGU.opt(colors=True).info(
133
- f"<{thread_hex}>{k:<15}</{thread_hex}> "
134
- f"<blue>RX: {v['rx']}</blue> <red>TX: {v['tx']}</red>",
111
+ f'<{thread_hex}>{k:<15}</{thread_hex}> '
112
+ f'<blue>RX: {v["rx"]}</blue> <red>TX: {v["tx"]}</red>',
135
113
  )
136
114
 
137
115
  time.sleep(1)
@@ -141,19 +119,19 @@ class ListenStatsThread(APRSDThread):
141
119
  @cli.command()
142
120
  @cli_helper.add_options(cli_helper.common_options)
143
121
  @click.option(
144
- "--aprs-login",
145
- envvar="APRS_LOGIN",
122
+ '--aprs-login',
123
+ envvar='APRS_LOGIN',
146
124
  show_envvar=True,
147
- help="What callsign to send the message from.",
125
+ help='What callsign to send the message from.',
148
126
  )
149
127
  @click.option(
150
- "--aprs-password",
151
- envvar="APRS_PASSWORD",
128
+ '--aprs-password',
129
+ envvar='APRS_PASSWORD',
152
130
  show_envvar=True,
153
- help="the APRS-IS password for APRS_LOGIN",
131
+ help='the APRS-IS password for APRS_LOGIN',
154
132
  )
155
133
  @click.option(
156
- "--packet-filter",
134
+ '--packet-filter',
157
135
  type=click.Choice(
158
136
  [
159
137
  packets.AckPacket.__name__,
@@ -170,35 +148,37 @@ class ListenStatsThread(APRSDThread):
170
148
  ],
171
149
  case_sensitive=False,
172
150
  ),
173
- help="Filter by packet type",
151
+ multiple=True,
152
+ default=[],
153
+ help='Filter by packet type',
174
154
  )
175
155
  @click.option(
176
- "--enable-plugin",
156
+ '--enable-plugin',
177
157
  multiple=True,
178
- help="Enable a plugin. This is the name of the file in the plugins directory.",
158
+ help='Enable a plugin. This is the name of the file in the plugins directory.',
179
159
  )
180
160
  @click.option(
181
- "--load-plugins",
161
+ '--load-plugins',
182
162
  default=False,
183
163
  is_flag=True,
184
- help="Load plugins as enabled in aprsd.conf ?",
164
+ help='Load plugins as enabled in aprsd.conf ?',
185
165
  )
186
166
  @click.argument(
187
- "filter",
167
+ 'filter',
188
168
  nargs=-1,
189
169
  required=True,
190
170
  )
191
171
  @click.option(
192
- "--log-packets",
172
+ '--log-packets',
193
173
  default=False,
194
174
  is_flag=True,
195
- help="Log incoming packets.",
175
+ help='Log incoming packets.',
196
176
  )
197
177
  @click.option(
198
- "--enable-packet-stats",
178
+ '--enable-packet-stats',
199
179
  default=False,
200
180
  is_flag=True,
201
- help="Enable packet stats periodic logging.",
181
+ help='Enable packet stats periodic logging.',
202
182
  )
203
183
  @click.pass_context
204
184
  @cli_helper.process_standard_options
@@ -228,46 +208,46 @@ def listen(
228
208
 
229
209
  if not aprs_login:
230
210
  click.echo(ctx.get_help())
231
- click.echo("")
232
- ctx.fail("Must set --aprs-login or APRS_LOGIN")
211
+ click.echo('')
212
+ ctx.fail('Must set --aprs-login or APRS_LOGIN')
233
213
  ctx.exit()
234
214
 
235
215
  if not aprs_password:
236
216
  click.echo(ctx.get_help())
237
- click.echo("")
238
- ctx.fail("Must set --aprs-password or APRS_PASSWORD")
217
+ click.echo('')
218
+ ctx.fail('Must set --aprs-password or APRS_PASSWORD')
239
219
  ctx.exit()
240
220
 
241
221
  # CONF.aprs_network.login = aprs_login
242
222
  # config["aprs"]["password"] = aprs_password
243
223
 
244
- LOG.info(f"APRSD Listen Started version: {aprsd.__version__}")
224
+ LOG.info(f'APRSD Listen Started version: {aprsd.__version__}')
245
225
 
246
226
  CONF.log_opt_values(LOG, logging.DEBUG)
247
227
  collector.Collector()
248
228
 
249
229
  # Try and load saved MsgTrack list
250
- LOG.debug("Loading saved MsgTrack object.")
230
+ LOG.debug('Loading saved MsgTrack object.')
251
231
 
252
232
  # Initialize the client factory and create
253
233
  # The correct client object ready for use
254
234
  # Make sure we have 1 client transport enabled
255
235
  if not client_factory.is_client_enabled():
256
- LOG.error("No Clients are enabled in config.")
236
+ LOG.error('No Clients are enabled in config.')
257
237
  sys.exit(-1)
258
238
 
259
239
  # Creates the client object
260
- LOG.info("Creating client connection")
240
+ LOG.info('Creating client connection')
261
241
  aprs_client = client_factory.create()
262
242
  LOG.info(aprs_client)
263
243
  if not aprs_client.login_success:
264
244
  # We failed to login, will just quit!
265
- msg = f"Login Failure: {aprs_client.login_failure}"
245
+ msg = f'Login Failure: {aprs_client.login_failure}'
266
246
  LOG.error(msg)
267
247
  print(msg)
268
248
  sys.exit(-1)
269
249
 
270
- LOG.debug(f"Filter by '{filter}'")
250
+ LOG.debug(f"Filter messages on aprsis server by '{filter}'")
271
251
  aprs_client.set_filter(filter)
272
252
 
273
253
  keepalive_thread = keepalive.KeepAliveThread()
@@ -276,10 +256,19 @@ def listen(
276
256
  # just deregister the class from the packet collector
277
257
  packet_collector.PacketCollector().unregister(seen_list.SeenList)
278
258
 
259
+ # we don't want the dupe filter to run here.
260
+ PacketFilter().unregister(dupe_filter.DupePacketFilter)
261
+ if packet_filter:
262
+ LOG.info('Enabling packet filtering for {packet_filter}')
263
+ packet_type.PacketTypeFilter().set_allow_list(packet_filter)
264
+ PacketFilter().register(packet_type.PacketTypeFilter)
265
+ else:
266
+ LOG.info('No packet filtering enabled.')
267
+
279
268
  pm = None
280
269
  if load_plugins:
281
270
  pm = plugin.PluginManager()
282
- LOG.info("Loading plugins")
271
+ LOG.info('Loading plugins')
283
272
  pm.setup_plugins(load_help_plugin=False)
284
273
  elif enable_plugin:
285
274
  pm = plugin.PluginManager()
@@ -290,33 +279,37 @@ def listen(
290
279
  else:
291
280
  LOG.warning(
292
281
  "Not Loading any plugins use --load-plugins to load what's "
293
- "defined in the config file.",
282
+ 'defined in the config file.',
294
283
  )
295
284
 
296
285
  if pm:
297
286
  for p in pm.get_plugins():
298
- LOG.info("Loaded plugin %s", p.__class__.__name__)
287
+ LOG.info('Loaded plugin %s', p.__class__.__name__)
299
288
 
300
289
  stats = stats_thread.APRSDStatsStoreThread()
301
290
  stats.start()
302
291
 
303
- LOG.debug("Create APRSDListenThread")
304
- listen_thread = APRSDListenThread(
292
+ LOG.debug('Start APRSDRxThread')
293
+ rx_thread = rx.APRSDRXThread(packet_queue=threads.packet_queue)
294
+ rx_thread.start()
295
+
296
+ LOG.debug('Create APRSDListenProcessThread')
297
+ listen_thread = APRSDListenProcessThread(
305
298
  packet_queue=threads.packet_queue,
306
299
  packet_filter=packet_filter,
307
300
  plugin_manager=pm,
308
301
  enabled_plugins=enable_plugin,
309
302
  log_packets=log_packets,
310
303
  )
311
- LOG.debug("Start APRSDListenThread")
304
+ LOG.debug('Start APRSDListenProcessThread')
312
305
  listen_thread.start()
313
306
  if enable_packet_stats:
314
307
  listen_stats = ListenStatsThread()
315
308
  listen_stats.start()
316
309
 
317
310
  keepalive_thread.start()
318
- LOG.debug("keepalive Join")
311
+ LOG.debug('keepalive Join')
319
312
  keepalive_thread.join()
320
- LOG.debug("listen_thread Join")
313
+ rx_thread.join()
321
314
  listen_thread.join()
322
315
  stats.join()
aprsd/cmds/server.py CHANGED
@@ -147,7 +147,7 @@ def server(ctx, flush):
147
147
  server_threads.register(keepalive.KeepAliveThread())
148
148
  server_threads.register(stats_thread.APRSDStatsStoreThread())
149
149
  server_threads.register(
150
- rx.APRSDPluginRXThread(
150
+ rx.APRSDRXThread(
151
151
  packet_queue=threads.packet_queue,
152
152
  ),
153
153
  )