aprsd 4.1.0__py3-none-any.whl → 4.1.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.
aprsd/main.py CHANGED
@@ -39,8 +39,8 @@ from aprsd.stats import collector
39
39
  # setup the global logger
40
40
  # log.basicConfig(level=log.DEBUG) # level=10
41
41
  CONF = cfg.CONF
42
- LOG = logging.getLogger("APRSD")
43
- CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
42
+ LOG = logging.getLogger('APRSD')
43
+ CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
44
44
  flask_enabled = False
45
45
 
46
46
 
@@ -68,18 +68,18 @@ def main():
68
68
  # First import all the possible commands for the CLI
69
69
  # The commands themselves live in the cmds directory
70
70
  load_commands()
71
- utils.load_entry_points("aprsd.extension")
72
- cli(auto_envvar_prefix="APRSD")
71
+ utils.load_entry_points('aprsd.extension')
72
+ cli(auto_envvar_prefix='APRSD')
73
73
 
74
74
 
75
75
  def signal_handler(sig, frame):
76
76
  global flask_enabled
77
77
 
78
- click.echo("signal_handler: called")
78
+ click.echo('signal_handler: called')
79
79
  threads.APRSDThreadList().stop_all()
80
- if "subprocess" not in str(frame):
80
+ if 'subprocess' not in str(frame):
81
81
  LOG.info(
82
- "Ctrl+C, Sending all threads exit! Can take up to 10 seconds {}".format(
82
+ 'Ctrl+C, Sending all threads exit! Can take up to 10 seconds {}'.format(
83
83
  datetime.datetime.now(),
84
84
  ),
85
85
  )
@@ -91,7 +91,7 @@ def signal_handler(sig, frame):
91
91
  packets.PacketList().save()
92
92
  collector.Collector().collect()
93
93
  except Exception as e:
94
- LOG.error(f"Failed to save data: {e}")
94
+ LOG.error(f'Failed to save data: {e}')
95
95
  sys.exit(0)
96
96
  # signal.signal(signal.SIGTERM, sys.exit(0))
97
97
  # sys.exit(0)
@@ -108,9 +108,9 @@ def check_version(ctx):
108
108
  """Check this version against the latest in pypi.org."""
109
109
  level, msg = utils._check_version()
110
110
  if level:
111
- click.secho(msg, fg="yellow")
111
+ click.secho(msg, fg='yellow')
112
112
  else:
113
- click.secho(msg, fg="green")
113
+ click.secho(msg, fg='green')
114
114
 
115
115
 
116
116
  @cli.command()
@@ -124,12 +124,12 @@ def sample_config(ctx):
124
124
  if sys.version_info < (3, 10):
125
125
  all = imp.entry_points()
126
126
  selected = []
127
- if "oslo.config.opts" in all:
128
- for x in all["oslo.config.opts"]:
129
- if x.group == "oslo.config.opts":
127
+ if 'oslo.config.opts' in all:
128
+ for x in all['oslo.config.opts']:
129
+ if x.group == 'oslo.config.opts':
130
130
  selected.append(x)
131
131
  else:
132
- selected = imp.entry_points(group="oslo.config.opts")
132
+ selected = imp.entry_points(group='oslo.config.opts')
133
133
 
134
134
  return selected
135
135
 
@@ -139,23 +139,23 @@ def sample_config(ctx):
139
139
  # selected = imp.entry_points(group="oslo.config.opts")
140
140
  selected = _get_selected_entry_points()
141
141
  for entry in selected:
142
- if "aprsd" in entry.name:
143
- args.append("--namespace")
142
+ if 'aprsd' in entry.name:
143
+ args.append('--namespace')
144
144
  args.append(entry.name)
145
145
 
146
146
  return args
147
147
 
148
148
  args = get_namespaces()
149
- config_version = metadata_version("oslo.config")
149
+ config_version = metadata_version('oslo.config')
150
150
  logging.basicConfig(level=logging.WARN)
151
151
  conf = cfg.ConfigOpts()
152
152
  generator.register_cli_opts(conf)
153
153
  try:
154
154
  conf(args, version=config_version)
155
- except cfg.RequiredOptError:
155
+ except cfg.RequiredOptError as ex:
156
156
  conf.print_help()
157
157
  if not sys.argv[1:]:
158
- raise SystemExit
158
+ raise SystemExit from ex
159
159
  raise
160
160
  generator.generate(conf)
161
161
  return
@@ -165,9 +165,9 @@ def sample_config(ctx):
165
165
  @click.pass_context
166
166
  def version(ctx):
167
167
  """Show the APRSD version."""
168
- click.echo(click.style("APRSD Version : ", fg="white"), nl=False)
169
- click.secho(f"{aprsd.__version__}", fg="yellow", bold=True)
168
+ click.echo(click.style('APRSD Version : ', fg='white'), nl=False)
169
+ click.secho(f'{aprsd.__version__}', fg='yellow', bold=True)
170
170
 
171
171
 
172
- if __name__ == "__main__":
172
+ if __name__ == '__main__':
173
173
  main()
aprsd/plugin.py CHANGED
@@ -17,24 +17,24 @@ from aprsd.packets import watch_list
17
17
 
18
18
  # setup the global logger
19
19
  CONF = cfg.CONF
20
- LOG = logging.getLogger("APRSD")
20
+ LOG = logging.getLogger('APRSD')
21
21
 
22
22
  CORE_MESSAGE_PLUGINS = [
23
- "aprsd.plugins.email.EmailPlugin",
24
- "aprsd.plugins.fortune.FortunePlugin",
25
- "aprsd.plugins.location.LocationPlugin",
26
- "aprsd.plugins.ping.PingPlugin",
27
- "aprsd.plugins.time.TimePlugin",
28
- "aprsd.plugins.weather.USWeatherPlugin",
29
- "aprsd.plugins.version.VersionPlugin",
23
+ 'aprsd.plugins.email.EmailPlugin',
24
+ 'aprsd.plugins.fortune.FortunePlugin',
25
+ 'aprsd.plugins.location.LocationPlugin',
26
+ 'aprsd.plugins.ping.PingPlugin',
27
+ 'aprsd.plugins.time.TimePlugin',
28
+ 'aprsd.plugins.weather.USWeatherPlugin',
29
+ 'aprsd.plugins.version.VersionPlugin',
30
30
  ]
31
31
 
32
32
  CORE_NOTIFY_PLUGINS = [
33
- "aprsd.plugins.notify.NotifySeenPlugin",
33
+ 'aprsd.plugins.notify.NotifySeenPlugin',
34
34
  ]
35
35
 
36
- hookspec = pluggy.HookspecMarker("aprsd")
37
- hookimpl = pluggy.HookimplMarker("aprsd")
36
+ hookspec = pluggy.HookspecMarker('aprsd')
37
+ hookimpl = pluggy.HookimplMarker('aprsd')
38
38
 
39
39
 
40
40
  class APRSDPluginSpec:
@@ -76,14 +76,14 @@ class APRSDPluginBase(metaclass=abc.ABCMeta):
76
76
  else:
77
77
  LOG.error(
78
78
  "Can't start thread {}:{}, Must be a child "
79
- "of aprsd.threads.APRSDThread".format(
79
+ 'of aprsd.threads.APRSDThread'.format(
80
80
  self,
81
81
  thread,
82
82
  ),
83
83
  )
84
84
  except Exception:
85
85
  LOG.error(
86
- "Failed to start threads for plugin {}".format(
86
+ 'Failed to start threads for plugin {}'.format(
87
87
  self,
88
88
  ),
89
89
  )
@@ -93,7 +93,7 @@ class APRSDPluginBase(metaclass=abc.ABCMeta):
93
93
  return self.message_counter
94
94
 
95
95
  def help(self) -> str:
96
- return "Help!"
96
+ return 'Help!'
97
97
 
98
98
  @abc.abstractmethod
99
99
  def setup(self):
@@ -147,10 +147,10 @@ class APRSDWatchListPluginBase(APRSDPluginBase, metaclass=abc.ABCMeta):
147
147
  # make sure the timeout is set or this doesn't work
148
148
  if watch_list:
149
149
  aprs_client = client.client_factory.create().client
150
- filter_str = "b/{}".format("/".join(watch_list))
150
+ filter_str = 'b/{}'.format('/'.join(watch_list))
151
151
  aprs_client.set_filter(filter_str)
152
152
  else:
153
- LOG.warning("Watch list enabled, but no callsigns set.")
153
+ LOG.warning('Watch list enabled, but no callsigns set.')
154
154
 
155
155
  @hookimpl
156
156
  def filter(self, packet: type[packets.Packet]) -> str | packets.MessagePacket:
@@ -164,7 +164,7 @@ class APRSDWatchListPluginBase(APRSDPluginBase, metaclass=abc.ABCMeta):
164
164
  result = self.process(packet)
165
165
  except Exception as ex:
166
166
  LOG.error(
167
- "Plugin {} failed to process packet {}".format(
167
+ 'Plugin {} failed to process packet {}'.format(
168
168
  self.__class__,
169
169
  ex,
170
170
  ),
@@ -172,7 +172,7 @@ class APRSDWatchListPluginBase(APRSDPluginBase, metaclass=abc.ABCMeta):
172
172
  if result:
173
173
  self.tx_inc()
174
174
  else:
175
- LOG.warning(f"{self.__class__} plugin is not enabled")
175
+ LOG.warning(f'{self.__class__} plugin is not enabled')
176
176
 
177
177
  return result
178
178
 
@@ -196,7 +196,7 @@ class APRSDRegexCommandPluginBase(APRSDPluginBase, metaclass=abc.ABCMeta):
196
196
  raise NotImplementedError
197
197
 
198
198
  def help(self):
199
- return "{}: {}".format(
199
+ return '{}: {}'.format(
200
200
  self.command_name.lower(),
201
201
  self.command_regex,
202
202
  )
@@ -207,7 +207,7 @@ class APRSDRegexCommandPluginBase(APRSDPluginBase, metaclass=abc.ABCMeta):
207
207
 
208
208
  @hookimpl
209
209
  def filter(self, packet: packets.MessagePacket) -> str | packets.MessagePacket:
210
- LOG.debug(f"{self.__class__.__name__} called")
210
+ LOG.debug(f'{self.__class__.__name__} called')
211
211
  if not self.enabled:
212
212
  result = f"{self.__class__.__name__} isn't enabled"
213
213
  LOG.warning(result)
@@ -215,7 +215,7 @@ class APRSDRegexCommandPluginBase(APRSDPluginBase, metaclass=abc.ABCMeta):
215
215
 
216
216
  if not isinstance(packet, packets.MessagePacket):
217
217
  LOG.warning(
218
- f"{self.__class__.__name__} Got a {packet.__class__.__name__} ignoring"
218
+ f'{self.__class__.__name__} Got a {packet.__class__.__name__} ignoring'
219
219
  )
220
220
  return packets.NULL_MESSAGE
221
221
 
@@ -237,7 +237,7 @@ class APRSDRegexCommandPluginBase(APRSDPluginBase, metaclass=abc.ABCMeta):
237
237
  result = self.process(packet)
238
238
  except Exception as ex:
239
239
  LOG.error(
240
- "Plugin {} failed to process packet {}".format(
240
+ 'Plugin {} failed to process packet {}'.format(
241
241
  self.__class__,
242
242
  ex,
243
243
  ),
@@ -254,7 +254,7 @@ class APRSFIKEYMixin:
254
254
 
255
255
  def ensure_aprs_fi_key(self):
256
256
  if not CONF.aprs_fi.apiKey:
257
- LOG.error("Config aprs_fi.apiKey is not set")
257
+ LOG.error('Config aprs_fi.apiKey is not set')
258
258
  self.enabled = False
259
259
  else:
260
260
  self.enabled = True
@@ -266,25 +266,25 @@ class HelpPlugin(APRSDRegexCommandPluginBase):
266
266
  This plugin is in this file to prevent a circular import.
267
267
  """
268
268
 
269
- command_regex = "^[hH]"
270
- command_name = "help"
269
+ command_regex = '^[hH]'
270
+ command_name = 'help'
271
271
 
272
272
  def help(self):
273
- return "Help: send APRS help or help <plugin>"
273
+ return 'Help: send APRS help or help <plugin>'
274
274
 
275
275
  def process(self, packet: packets.MessagePacket):
276
- LOG.info("HelpPlugin")
276
+ LOG.info('HelpPlugin')
277
277
  # fromcall = packet.get("from")
278
278
  message = packet.message_text
279
279
  # ack = packet.get("msgNo", "0")
280
- a = re.search(r"^.*\s+(.*)", message)
280
+ a = re.search(r'^.*\s+(.*)', message)
281
281
  command_name = None
282
282
  if a is not None:
283
283
  command_name = a.group(1).lower()
284
284
 
285
285
  pm = PluginManager()
286
286
 
287
- if command_name and "?" not in command_name:
287
+ if command_name and '?' not in command_name:
288
288
  # user wants help for a specific plugin
289
289
  reply = None
290
290
  for p in pm.get_plugins():
@@ -303,20 +303,20 @@ class HelpPlugin(APRSDRegexCommandPluginBase):
303
303
  LOG.debug(p)
304
304
  if p.enabled and isinstance(p, APRSDRegexCommandPluginBase):
305
305
  name = p.command_name.lower()
306
- if name not in list and "help" not in name:
306
+ if name not in list and 'help' not in name:
307
307
  list.append(name)
308
308
 
309
309
  list.sort()
310
- reply = " ".join(list)
310
+ reply = ' '.join(list)
311
311
  lines = textwrap.wrap(reply, 60)
312
312
  replies = ["Send APRS MSG of 'help' or 'help <plugin>'"]
313
313
  for line in lines:
314
- replies.append(f"plugins: {line}")
314
+ replies.append(f'plugins: {line}')
315
315
 
316
316
  for entry in replies:
317
- LOG.debug(f"{len(entry)} {entry}")
317
+ LOG.debug(f'{len(entry)} {entry}')
318
318
 
319
- LOG.debug(f"{replies}")
319
+ LOG.debug(f'{replies}')
320
320
  return replies
321
321
 
322
322
 
@@ -341,17 +341,17 @@ class PluginManager:
341
341
  return cls._instance
342
342
 
343
343
  def _init(self):
344
- self._pluggy_pm = pluggy.PluginManager("aprsd")
344
+ self._pluggy_pm = pluggy.PluginManager('aprsd')
345
345
  self._pluggy_pm.add_hookspecs(APRSDPluginSpec)
346
346
  # For the watchlist plugins
347
- self._watchlist_pm = pluggy.PluginManager("aprsd")
347
+ self._watchlist_pm = pluggy.PluginManager('aprsd')
348
348
  self._watchlist_pm.add_hookspecs(APRSDPluginSpec)
349
349
 
350
350
  def stats(self, serializable=False) -> dict:
351
351
  """Collect and return stats for all plugins."""
352
352
 
353
353
  def full_name_with_qualname(obj):
354
- return "{}.{}".format(
354
+ return '{}.{}'.format(
355
355
  obj.__class__.__module__,
356
356
  obj.__class__.__qualname__,
357
357
  )
@@ -361,10 +361,10 @@ class PluginManager:
361
361
  if plugins:
362
362
  for p in plugins:
363
363
  plugin_stats[full_name_with_qualname(p)] = {
364
- "enabled": p.enabled,
365
- "rx": p.rx_count,
366
- "tx": p.tx_count,
367
- "version": p.version,
364
+ 'enabled': p.enabled,
365
+ 'rx': p.rx_count,
366
+ 'tx': p.tx_count,
367
+ 'version': p.version,
368
368
  }
369
369
 
370
370
  return plugin_stats
@@ -392,19 +392,19 @@ class PluginManager:
392
392
  module_name = None
393
393
  class_name = None
394
394
  try:
395
- module_name, class_name = module_class_string.rsplit(".", 1)
395
+ module_name, class_name = module_class_string.rsplit('.', 1)
396
396
  module = importlib.import_module(module_name)
397
397
  # Commented out because the email thread starts in a different context
398
398
  # and hence gives a different singleton for the EmailStats
399
399
  # module = importlib.reload(module)
400
400
  except Exception as ex:
401
401
  if not module_name:
402
- LOG.error(f"Failed to load Plugin {module_class_string}")
402
+ LOG.error(f'Failed to load Plugin {module_class_string}')
403
403
  else:
404
404
  LOG.error(f"Failed to load Plugin '{module_name}' : '{ex}'")
405
405
  return
406
406
 
407
- assert hasattr(module, class_name), "class {} is not in {}".format(
407
+ assert hasattr(module, class_name), 'class {} is not in {}'.format(
408
408
  class_name,
409
409
  module_name,
410
410
  )
@@ -412,7 +412,7 @@ class PluginManager:
412
412
  # class_name, module_name))
413
413
  cls = getattr(module, class_name)
414
414
  if super_cls is not None:
415
- assert issubclass(cls, super_cls), "class {} should inherit from {}".format(
415
+ assert issubclass(cls, super_cls), 'class {} should inherit from {}'.format(
416
416
  class_name,
417
417
  super_cls.__name__,
418
418
  )
@@ -444,7 +444,7 @@ class PluginManager:
444
444
  self._watchlist_pm.register(plugin_obj)
445
445
  else:
446
446
  LOG.warning(
447
- f"Plugin {plugin_obj.__class__.__name__} is disabled"
447
+ f'Plugin {plugin_obj.__class__.__name__} is disabled'
448
448
  )
449
449
  elif isinstance(plugin_obj, APRSDRegexCommandPluginBase):
450
450
  if plugin_obj.enabled:
@@ -458,7 +458,7 @@ class PluginManager:
458
458
  self._pluggy_pm.register(plugin_obj)
459
459
  else:
460
460
  LOG.warning(
461
- f"Plugin {plugin_obj.__class__.__name__} is disabled"
461
+ f'Plugin {plugin_obj.__class__.__name__} is disabled'
462
462
  )
463
463
  elif isinstance(plugin_obj, APRSDPluginBase):
464
464
  if plugin_obj.enabled:
@@ -471,7 +471,7 @@ class PluginManager:
471
471
  self._pluggy_pm.register(plugin_obj)
472
472
  else:
473
473
  LOG.warning(
474
- f"Plugin {plugin_obj.__class__.__name__} is disabled"
474
+ f'Plugin {plugin_obj.__class__.__name__} is disabled'
475
475
  )
476
476
  except Exception as ex:
477
477
  LOG.error(f"Couldn't load plugin '{plugin_name}'")
@@ -485,11 +485,11 @@ class PluginManager:
485
485
  def setup_plugins(
486
486
  self,
487
487
  load_help_plugin=True,
488
- plugin_list=[],
488
+ plugin_list=None,
489
489
  ):
490
490
  """Create the plugin manager and register plugins."""
491
491
 
492
- LOG.info("Loading APRSD Plugins")
492
+ LOG.info('Loading APRSD Plugins')
493
493
  # Help plugin is always enabled.
494
494
  if load_help_plugin:
495
495
  _help = HelpPlugin()
@@ -509,7 +509,7 @@ class PluginManager:
509
509
  for p_name in CORE_MESSAGE_PLUGINS:
510
510
  self._load_plugin(p_name)
511
511
 
512
- LOG.info("Completed Plugin Loading.")
512
+ LOG.info('Completed Plugin Loading.')
513
513
 
514
514
  def run(self, packet: packets.MessagePacket):
515
515
  """Execute all the plugins run method."""
@@ -524,7 +524,7 @@ class PluginManager:
524
524
  """Stop all threads created by all plugins."""
525
525
  with self.lock:
526
526
  for p in self.get_plugins():
527
- if hasattr(p, "stop_threads"):
527
+ if hasattr(p, 'stop_threads'):
528
528
  p.stop_threads()
529
529
 
530
530
  def register_msg(self, obj):
aprsd/plugin_utils.py CHANGED
@@ -4,21 +4,20 @@ import logging
4
4
 
5
5
  import requests
6
6
 
7
-
8
- LOG = logging.getLogger("APRSD")
7
+ LOG = logging.getLogger('APRSD')
9
8
 
10
9
 
11
10
  def get_aprs_fi(api_key, callsign):
12
11
  LOG.debug(f"Fetch aprs.fi location for '{callsign}'")
13
12
  try:
14
13
  url = (
15
- "http://api.aprs.fi/api/get?"
16
- "&what=loc&apikey={}&format=json"
17
- "&name={}".format(api_key, callsign)
14
+ 'http://api.aprs.fi/api/get?&what=loc&apikey={}&format=json&name={}'.format(
15
+ api_key, callsign
16
+ )
18
17
  )
19
18
  response = requests.get(url)
20
- except Exception:
21
- raise Exception("Failed to get aprs.fi location")
19
+ except Exception as e:
20
+ raise Exception('Failed to get aprs.fi location') from e
22
21
  else:
23
22
  response.raise_for_status()
24
23
  return json.loads(response.text)
@@ -26,22 +25,22 @@ def get_aprs_fi(api_key, callsign):
26
25
 
27
26
  def get_weather_gov_for_gps(lat, lon):
28
27
  # FIXME(hemna) This is currently BROKEN
29
- LOG.debug(f"Fetch station at {lat}, {lon}")
28
+ LOG.debug(f'Fetch station at {lat}, {lon}')
30
29
  headers = requests.utils.default_headers()
31
30
  headers.update(
32
- {"User-Agent": "(aprsd, waboring@hemna.com)"},
31
+ {'User-Agent': '(aprsd, waboring@hemna.com)'},
33
32
  )
34
33
  try:
35
34
  url2 = (
36
- "https://forecast.weather.gov/MapClick.php?lat=%s"
37
- "&lon=%s&FcstType=json" % (lat, lon)
35
+ 'https://forecast.weather.gov/MapClick.php?lat=%s'
36
+ '&lon=%s&FcstType=json' % (lat, lon)
38
37
  # f"https://api.weather.gov/points/{lat},{lon}"
39
38
  )
40
39
  LOG.debug(f"Fetching weather '{url2}'")
41
40
  response = requests.get(url2, headers=headers)
42
41
  except Exception as e:
43
42
  LOG.error(e)
44
- raise Exception("Failed to get weather")
43
+ raise Exception('Failed to get weather') from e
45
44
  else:
46
45
  response.raise_for_status()
47
46
  return json.loads(response.text)
@@ -50,25 +49,25 @@ def get_weather_gov_for_gps(lat, lon):
50
49
  def get_weather_gov_metar(station):
51
50
  LOG.debug(f"Fetch metar for station '{station}'")
52
51
  try:
53
- url = "https://api.weather.gov/stations/{}/observations/latest".format(
52
+ url = 'https://api.weather.gov/stations/{}/observations/latest'.format(
54
53
  station,
55
54
  )
56
55
  response = requests.get(url)
57
- except Exception:
58
- raise Exception("Failed to fetch metar")
56
+ except Exception as e:
57
+ raise Exception('Failed to fetch metar') from e
59
58
  else:
60
59
  response.raise_for_status()
61
60
  return json.loads(response)
62
61
 
63
62
 
64
- def fetch_openweathermap(api_key, lat, lon, units="metric", exclude=None):
65
- LOG.debug(f"Fetch openweathermap for {lat}, {lon}")
63
+ def fetch_openweathermap(api_key, lat, lon, units='metric', exclude=None):
64
+ LOG.debug(f'Fetch openweathermap for {lat}, {lon}')
66
65
  if not exclude:
67
- exclude = "minutely,hourly,daily,alerts"
66
+ exclude = 'minutely,hourly,daily,alerts'
68
67
  try:
69
68
  url = (
70
- "https://api.openweathermap.org/data/2.5/onecall?"
71
- "lat={}&lon={}&appid={}&units={}&exclude={}".format(
69
+ 'https://api.openweathermap.org/data/2.5/onecall?'
70
+ 'lat={}&lon={}&appid={}&units={}&exclude={}'.format(
72
71
  lat,
73
72
  lon,
74
73
  api_key,
@@ -80,7 +79,7 @@ def fetch_openweathermap(api_key, lat, lon, units="metric", exclude=None):
80
79
  response = requests.get(url)
81
80
  except Exception as e:
82
81
  LOG.error(e)
83
- raise Exception("Failed to get weather")
82
+ raise Exception('Failed to get weather') from e
84
83
  else:
85
84
  response.raise_for_status()
86
85
  return json.loads(response.text)