aprsd 3.4.4__py3-none-any.whl → 4.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. aprsd/cli_helper.py +12 -5
  2. aprsd/client/aprsis.py +31 -9
  3. aprsd/client/base.py +13 -2
  4. aprsd/client/drivers/aprsis.py +6 -3
  5. aprsd/client/drivers/fake.py +15 -20
  6. aprsd/client/factory.py +0 -2
  7. aprsd/client/fake.py +0 -2
  8. aprsd/client/kiss.py +17 -2
  9. aprsd/client/stats.py +1 -3
  10. aprsd/cmds/completion.py +7 -4
  11. aprsd/cmds/dev.py +38 -42
  12. aprsd/cmds/fetch_stats.py +140 -143
  13. aprsd/cmds/healthcheck.py +5 -3
  14. aprsd/cmds/list_plugins.py +140 -134
  15. aprsd/cmds/listen.py +13 -9
  16. aprsd/cmds/server.py +53 -27
  17. aprsd/conf/__init__.py +1 -2
  18. aprsd/conf/client.py +3 -4
  19. aprsd/conf/common.py +19 -93
  20. aprsd/conf/log.py +2 -4
  21. aprsd/conf/opts.py +5 -4
  22. aprsd/conf/plugin_common.py +11 -121
  23. aprsd/exception.py +2 -0
  24. aprsd/log/log.py +7 -46
  25. aprsd/main.py +10 -4
  26. aprsd/packets/__init__.py +14 -4
  27. aprsd/packets/core.py +57 -67
  28. aprsd/packets/log.py +8 -8
  29. aprsd/packets/packet_list.py +9 -6
  30. aprsd/plugin.py +22 -11
  31. aprsd/plugins/notify.py +1 -4
  32. aprsd/plugins/weather.py +10 -8
  33. aprsd/stats/collector.py +5 -2
  34. aprsd/threads/__init__.py +3 -2
  35. aprsd/threads/aprsd.py +12 -7
  36. aprsd/threads/{keep_alive.py → keepalive.py} +14 -45
  37. aprsd/threads/registry.py +3 -3
  38. aprsd/threads/rx.py +9 -6
  39. aprsd/threads/stats.py +2 -2
  40. aprsd/threads/tx.py +3 -4
  41. aprsd/utils/__init__.py +42 -10
  42. aprsd/utils/json.py +9 -4
  43. aprsd/utils/keepalive_collector.py +55 -0
  44. aprsd/utils/trace.py +0 -2
  45. aprsd-4.0.1.dist-info/AUTHORS +1 -0
  46. {aprsd-3.4.4.dist-info → aprsd-4.0.1.dist-info}/METADATA +307 -408
  47. aprsd-4.0.1.dist-info/RECORD +74 -0
  48. {aprsd-3.4.4.dist-info → aprsd-4.0.1.dist-info}/WHEEL +1 -1
  49. aprsd/cmds/admin.py +0 -57
  50. aprsd/cmds/webchat.py +0 -662
  51. aprsd/conf/plugin_email.py +0 -105
  52. aprsd/plugins/email.py +0 -715
  53. aprsd/plugins/location.py +0 -181
  54. aprsd/threads/log_monitor.py +0 -121
  55. aprsd/web/__init__.py +0 -0
  56. aprsd/web/admin/__init__.py +0 -0
  57. aprsd/web/admin/static/css/index.css +0 -84
  58. aprsd/web/admin/static/css/prism.css +0 -4
  59. aprsd/web/admin/static/css/tabs.css +0 -35
  60. aprsd/web/admin/static/images/Untitled.png +0 -0
  61. aprsd/web/admin/static/images/aprs-symbols-16-0.png +0 -0
  62. aprsd/web/admin/static/images/aprs-symbols-16-1.png +0 -0
  63. aprsd/web/admin/static/images/aprs-symbols-64-0.png +0 -0
  64. aprsd/web/admin/static/images/aprs-symbols-64-1.png +0 -0
  65. aprsd/web/admin/static/images/aprs-symbols-64-2.png +0 -0
  66. aprsd/web/admin/static/js/charts.js +0 -235
  67. aprsd/web/admin/static/js/echarts.js +0 -465
  68. aprsd/web/admin/static/js/logs.js +0 -26
  69. aprsd/web/admin/static/js/main.js +0 -231
  70. aprsd/web/admin/static/js/prism.js +0 -12
  71. aprsd/web/admin/static/js/send-message.js +0 -114
  72. aprsd/web/admin/static/js/tabs.js +0 -28
  73. aprsd/web/admin/templates/index.html +0 -196
  74. aprsd/web/chat/static/css/chat.css +0 -115
  75. aprsd/web/chat/static/css/index.css +0 -66
  76. aprsd/web/chat/static/css/style.css.map +0 -1
  77. aprsd/web/chat/static/css/tabs.css +0 -41
  78. aprsd/web/chat/static/css/upstream/bootstrap.min.css +0 -6
  79. aprsd/web/chat/static/css/upstream/font.woff2 +0 -0
  80. aprsd/web/chat/static/css/upstream/google-fonts.css +0 -23
  81. aprsd/web/chat/static/css/upstream/jquery-ui.css +0 -1311
  82. aprsd/web/chat/static/css/upstream/jquery.toast.css +0 -28
  83. aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Bold.woff +0 -0
  84. aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Bold.woff2 +0 -0
  85. aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Regular.woff +0 -0
  86. aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Regular.woff2 +0 -0
  87. aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/icons.woff +0 -0
  88. aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/icons.woff2 +0 -0
  89. aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/outline-icons.woff +0 -0
  90. aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/outline-icons.woff2 +0 -0
  91. aprsd/web/chat/static/images/Untitled.png +0 -0
  92. aprsd/web/chat/static/images/aprs-symbols-16-0.png +0 -0
  93. aprsd/web/chat/static/images/aprs-symbols-16-1.png +0 -0
  94. aprsd/web/chat/static/images/aprs-symbols-64-0.png +0 -0
  95. aprsd/web/chat/static/images/aprs-symbols-64-1.png +0 -0
  96. aprsd/web/chat/static/images/aprs-symbols-64-2.png +0 -0
  97. aprsd/web/chat/static/images/globe.svg +0 -3
  98. aprsd/web/chat/static/js/gps.js +0 -84
  99. aprsd/web/chat/static/js/main.js +0 -45
  100. aprsd/web/chat/static/js/send-message.js +0 -612
  101. aprsd/web/chat/static/js/tabs.js +0 -28
  102. aprsd/web/chat/static/js/upstream/bootstrap.bundle.min.js +0 -7
  103. aprsd/web/chat/static/js/upstream/jquery-3.7.1.min.js +0 -2
  104. aprsd/web/chat/static/js/upstream/jquery-ui.min.js +0 -13
  105. aprsd/web/chat/static/js/upstream/jquery.toast.js +0 -374
  106. aprsd/web/chat/static/js/upstream/semantic.min.js +0 -11
  107. aprsd/web/chat/static/js/upstream/socket.io.min.js +0 -7
  108. aprsd/web/chat/templates/index.html +0 -139
  109. aprsd/wsgi.py +0 -322
  110. aprsd-3.4.4.dist-info/AUTHORS +0 -13
  111. aprsd-3.4.4.dist-info/RECORD +0 -134
  112. {aprsd-3.4.4.dist-info → aprsd-4.0.1.dist-info}/LICENSE +0 -0
  113. {aprsd-3.4.4.dist-info → aprsd-4.0.1.dist-info}/entry_points.txt +0 -0
  114. {aprsd-3.4.4.dist-info → aprsd-4.0.1.dist-info}/top_level.txt +0 -0
aprsd/cli_helper.py CHANGED
@@ -1,7 +1,7 @@
1
- from functools import update_wrapper
2
1
  import logging
3
- from pathlib import Path
4
2
  import typing as t
3
+ from functools import update_wrapper
4
+ from pathlib import Path
5
5
 
6
6
  import click
7
7
  from oslo_config import cfg
@@ -11,7 +11,6 @@ from aprsd import conf # noqa: F401
11
11
  from aprsd.log import log
12
12
  from aprsd.utils import trace
13
13
 
14
-
15
14
  CONF = cfg.CONF
16
15
  home = str(Path.home())
17
16
  DEFAULT_CONFIG_DIR = f"{home}/.config/aprsd/"
@@ -58,6 +57,7 @@ class AliasedGroup(click.Group):
58
57
  calling into :meth:`add_command`.
59
58
  Copied from `click` and extended for `aliases`.
60
59
  """
60
+
61
61
  def decorator(f):
62
62
  aliases = kwargs.pop("aliases", [])
63
63
  cmd = click.decorators.command(*args, **kwargs)(f)
@@ -65,6 +65,7 @@ class AliasedGroup(click.Group):
65
65
  for alias in aliases:
66
66
  self.add_command(cmd, name=alias)
67
67
  return cmd
68
+
68
69
  return decorator
69
70
 
70
71
  def group(self, *args, **kwargs):
@@ -74,6 +75,7 @@ class AliasedGroup(click.Group):
74
75
  calling into :meth:`add_command`.
75
76
  Copied from `click` and extended for `aliases`.
76
77
  """
78
+
77
79
  def decorator(f):
78
80
  aliases = kwargs.pop("aliases", [])
79
81
  cmd = click.decorators.group(*args, **kwargs)(f)
@@ -81,6 +83,7 @@ class AliasedGroup(click.Group):
81
83
  for alias in aliases:
82
84
  self.add_command(cmd, name=alias)
83
85
  return cmd
86
+
84
87
  return decorator
85
88
 
86
89
 
@@ -89,6 +92,7 @@ def add_options(options):
89
92
  for option in reversed(options):
90
93
  func = option(func)
91
94
  return func
95
+
92
96
  return _add_options
93
97
 
94
98
 
@@ -103,7 +107,9 @@ def process_standard_options(f: F) -> F:
103
107
  default_config_files = None
104
108
  try:
105
109
  CONF(
106
- [], project="aprsd", version=aprsd.__version__,
110
+ [],
111
+ project="aprsd",
112
+ version=aprsd.__version__,
107
113
  default_config_files=default_config_files,
108
114
  )
109
115
  except cfg.ConfigFilesNotFoundError:
@@ -119,7 +125,7 @@ def process_standard_options(f: F) -> F:
119
125
  trace.setup_tracing(["method", "api"])
120
126
 
121
127
  if not config_file_found:
122
- LOG = logging.getLogger("APRSD") # noqa: N806
128
+ LOG = logging.getLogger("APRSD") # noqa: N806
123
129
  LOG.error("No config file found!! run 'aprsd sample-config'")
124
130
 
125
131
  del kwargs["loglevel"]
@@ -132,6 +138,7 @@ def process_standard_options(f: F) -> F:
132
138
 
133
139
  def process_standard_options_no_config(f: F) -> F:
134
140
  """Use this as a decorator when config isn't needed."""
141
+
135
142
  def new_func(*args, **kwargs):
136
143
  ctx = args[0]
137
144
  ctx.ensure_object(dict)
aprsd/client/aprsis.py CHANGED
@@ -2,7 +2,9 @@ import datetime
2
2
  import logging
3
3
  import time
4
4
 
5
+ import timeago
5
6
  from aprslib.exceptions import LoginError
7
+ from loguru import logger
6
8
  from oslo_config import cfg
7
9
 
8
10
  from aprsd import client, exception
@@ -10,14 +12,14 @@ from aprsd.client import base
10
12
  from aprsd.client.drivers import aprsis
11
13
  from aprsd.packets import core
12
14
 
13
-
14
15
  CONF = cfg.CONF
15
16
  LOG = logging.getLogger("APRSD")
17
+ LOGU = logger
16
18
 
17
19
 
18
20
  class APRSISClient(base.APRSClient):
19
-
20
21
  _client = None
22
+ _checks = False
21
23
 
22
24
  def __init__(self):
23
25
  max_timeout = {"hours": 0.0, "minutes": 2, "seconds": 0}
@@ -45,6 +47,20 @@ class APRSISClient(base.APRSClient):
45
47
 
46
48
  return stats
47
49
 
50
+ def keepalive_check(self):
51
+ # Don't check the first time through.
52
+ if not self.is_alive() and self._checks:
53
+ LOG.warning("Resetting client. It's not alive.")
54
+ self.reset()
55
+ self._checks = True
56
+
57
+ def keepalive_log(self):
58
+ if ka := self._client.aprsd_keepalive:
59
+ keepalive = timeago.format(ka)
60
+ else:
61
+ keepalive = "N/A"
62
+ LOGU.opt(colors=True).info(f"<green>Client keepalive {keepalive}</green>")
63
+
48
64
  @staticmethod
49
65
  def is_enabled():
50
66
  # Defaults to True if the enabled flag is non existent
@@ -81,13 +97,13 @@ class APRSISClient(base.APRSClient):
81
97
  if delta > self.max_delta:
82
98
  LOG.error(f"Connection is stale, last heard {delta} ago.")
83
99
  return True
100
+ return False
84
101
 
85
102
  def is_alive(self):
86
- if self._client:
87
- return self._client.is_alive() and not self._is_stale_connection()
88
- else:
103
+ if not self._client:
89
104
  LOG.warning(f"APRS_CLIENT {self._client} alive? NO!!!")
90
105
  return False
106
+ return self._client.is_alive() and not self._is_stale_connection()
91
107
 
92
108
  def close(self):
93
109
  if self._client:
@@ -117,8 +133,12 @@ class APRSISClient(base.APRSClient):
117
133
  if retry_count >= retries:
118
134
  break
119
135
  try:
120
- LOG.info(f"Creating aprslib client({host}:{port}) and logging in {user}.")
121
- aprs_client = aprsis.Aprsdis(user, passwd=password, host=host, port=port)
136
+ LOG.info(
137
+ f"Creating aprslib client({host}:{port}) and logging in {user}."
138
+ )
139
+ aprs_client = aprsis.Aprsdis(
140
+ user, passwd=password, host=host, port=port
141
+ )
122
142
  # Force the log to be the same
123
143
  aprs_client.logger = LOG
124
144
  aprs_client.connect()
@@ -149,8 +169,10 @@ class APRSISClient(base.APRSClient):
149
169
  if self._client:
150
170
  try:
151
171
  self._client.consumer(
152
- callback, blocking=blocking,
153
- immortal=immortal, raw=raw,
172
+ callback,
173
+ blocking=blocking,
174
+ immortal=immortal,
175
+ raw=raw,
154
176
  )
155
177
  except Exception as e:
156
178
  LOG.error(e)
aprsd/client/base.py CHANGED
@@ -2,11 +2,11 @@ import abc
2
2
  import logging
3
3
  import threading
4
4
 
5
- from oslo_config import cfg
6
5
  import wrapt
6
+ from oslo_config import cfg
7
7
 
8
8
  from aprsd.packets import core
9
-
9
+ from aprsd.utils import keepalive_collector
10
10
 
11
11
  CONF = cfg.CONF
12
12
  LOG = logging.getLogger("APRSD")
@@ -30,6 +30,7 @@ class APRSClient:
30
30
  """This magic turns this into a singleton."""
31
31
  if cls._instance is None:
32
32
  cls._instance = super().__new__(cls)
33
+ keepalive_collector.KeepAliveCollector().register(cls)
33
34
  # Put any initialization here.
34
35
  cls._instance._create_client()
35
36
  return cls._instance
@@ -42,6 +43,16 @@ class APRSClient:
42
43
  dict: Statistics about the connection and packet handling
43
44
  """
44
45
 
46
+ @abc.abstractmethod
47
+ def keepalive_check(self) -> None:
48
+ """Called during keepalive run to check status."""
49
+ ...
50
+
51
+ @abc.abstractmethod
52
+ def keepalive_log(self) -> None:
53
+ """Log any keepalive information."""
54
+ ...
55
+
45
56
  @property
46
57
  def is_connected(self):
47
58
  return self.connected
@@ -4,17 +4,20 @@ import select
4
4
  import threading
5
5
 
6
6
  import aprslib
7
+ import wrapt
7
8
  from aprslib import is_py3
8
9
  from aprslib.exceptions import (
9
- ConnectionDrop, ConnectionError, GenericError, LoginError, ParseError,
10
+ ConnectionDrop,
11
+ ConnectionError,
12
+ GenericError,
13
+ LoginError,
14
+ ParseError,
10
15
  UnknownFormat,
11
16
  )
12
- import wrapt
13
17
 
14
18
  import aprsd
15
19
  from aprsd.packets import core
16
20
 
17
-
18
21
  LOG = logging.getLogger("APRSD")
19
22
 
20
23
 
@@ -3,20 +3,19 @@ import threading
3
3
  import time
4
4
 
5
5
  import aprslib
6
- from oslo_config import cfg
7
6
  import wrapt
7
+ from oslo_config import cfg
8
8
 
9
9
  from aprsd import conf # noqa
10
10
  from aprsd.packets import core
11
11
  from aprsd.utils import trace
12
12
 
13
-
14
13
  CONF = cfg.CONF
15
- LOG = logging.getLogger("APRSD")
14
+ LOG = logging.getLogger('APRSD')
16
15
 
17
16
 
18
17
  class APRSDFakeClient(metaclass=trace.TraceWrapperMetaclass):
19
- '''Fake client for testing.'''
18
+ """Fake client for testing."""
20
19
 
21
20
  # flag to tell us to stop
22
21
  thread_stop = False
@@ -25,12 +24,12 @@ class APRSDFakeClient(metaclass=trace.TraceWrapperMetaclass):
25
24
  path = []
26
25
 
27
26
  def __init__(self):
28
- LOG.info("Starting APRSDFakeClient client.")
29
- self.path = ["WIDE1-1", "WIDE2-1"]
27
+ LOG.info('Starting APRSDFakeClient client.')
28
+ self.path = ['WIDE1-1', 'WIDE2-1']
30
29
 
31
30
  def stop(self):
32
31
  self.thread_stop = True
33
- LOG.info("Shutdown APRSDFakeClient client.")
32
+ LOG.info('Shutdown APRSDFakeClient client.')
34
33
 
35
34
  def is_alive(self):
36
35
  """If the connection is alive or not."""
@@ -39,35 +38,31 @@ class APRSDFakeClient(metaclass=trace.TraceWrapperMetaclass):
39
38
  @wrapt.synchronized(lock)
40
39
  def send(self, packet: core.Packet):
41
40
  """Send an APRS Message object."""
42
- LOG.info(f"Sending packet: {packet}")
41
+ LOG.info(f'Sending packet: {packet}')
43
42
  payload = None
44
43
  if isinstance(packet, core.Packet):
45
44
  packet.prepare()
46
- payload = packet.payload.encode("US-ASCII")
47
- if packet.path:
48
- packet.path
49
- else:
50
- self.path
45
+ payload = packet.payload.encode('US-ASCII')
51
46
  else:
52
- msg_payload = f"{packet.raw}{{{str(packet.msgNo)}"
47
+ msg_payload = f'{packet.raw}{{{str(packet.msgNo)}'
53
48
  payload = (
54
- ":{:<9}:{}".format(
49
+ ':{:<9}:{}'.format(
55
50
  packet.to_call,
56
51
  msg_payload,
57
52
  )
58
- ).encode("US-ASCII")
53
+ ).encode('US-ASCII')
59
54
 
60
55
  LOG.debug(
61
56
  f"FAKE::Send '{payload}' TO '{packet.to_call}' From "
62
- f"'{packet.from_call}' with PATH \"{self.path}\"",
57
+ f'\'{packet.from_call}\' with PATH "{self.path}"',
63
58
  )
64
59
 
65
60
  def consumer(self, callback, blocking=False, immortal=False, raw=False):
66
- LOG.debug("Start non blocking FAKE consumer")
61
+ LOG.debug('Start non blocking FAKE consumer')
67
62
  # Generate packets here?
68
- raw = "GTOWN>APDW16,WIDE1-1,WIDE2-1:}KM6LYW-9>APZ100,TCPIP,GTOWN*::KM6LYW :KM6LYW: 19 Miles SW"
63
+ raw = 'GTOWN>APDW16,WIDE1-1,WIDE2-1:}KM6LYW-9>APZ100,TCPIP,GTOWN*::KM6LYW :KM6LYW: 19 Miles SW'
69
64
  pkt_raw = aprslib.parse(raw)
70
65
  pkt = core.factory(pkt_raw)
71
66
  callback(packet=pkt)
72
- LOG.debug(f"END blocking FAKE consumer {self}")
67
+ LOG.debug(f'END blocking FAKE consumer {self}')
73
68
  time.sleep(8)
aprsd/client/factory.py CHANGED
@@ -4,13 +4,11 @@ from typing import Callable, Protocol, runtime_checkable
4
4
  from aprsd import exception
5
5
  from aprsd.packets import core
6
6
 
7
-
8
7
  LOG = logging.getLogger("APRSD")
9
8
 
10
9
 
11
10
  @runtime_checkable
12
11
  class Client(Protocol):
13
-
14
12
  def __init__(self):
15
13
  pass
16
14
 
aprsd/client/fake.py CHANGED
@@ -7,13 +7,11 @@ from aprsd.client import base
7
7
  from aprsd.client.drivers import fake as fake_driver
8
8
  from aprsd.utils import trace
9
9
 
10
-
11
10
  CONF = cfg.CONF
12
11
  LOG = logging.getLogger("APRSD")
13
12
 
14
13
 
15
14
  class APRSDFakeClient(base.APRSClient, metaclass=trace.TraceWrapperMetaclass):
16
-
17
15
  def stats(self, serializable=False) -> dict:
18
16
  return {
19
17
  "transport": "Fake",
aprsd/client/kiss.py CHANGED
@@ -2,6 +2,8 @@ import datetime
2
2
  import logging
3
3
 
4
4
  import aprslib
5
+ import timeago
6
+ from loguru import logger
5
7
  from oslo_config import cfg
6
8
 
7
9
  from aprsd import client, exception
@@ -9,13 +11,12 @@ from aprsd.client import base
9
11
  from aprsd.client.drivers import kiss
10
12
  from aprsd.packets import core
11
13
 
12
-
13
14
  CONF = cfg.CONF
14
15
  LOG = logging.getLogger("APRSD")
16
+ LOGU = logger
15
17
 
16
18
 
17
19
  class KISSClient(base.APRSClient):
18
-
19
20
  _client = None
20
21
  keepalive = datetime.datetime.now()
21
22
 
@@ -79,6 +80,20 @@ class KISSClient(base.APRSClient):
79
80
  if self._client:
80
81
  self._client.stop()
81
82
 
83
+ def keepalive_check(self):
84
+ # Don't check the first time through.
85
+ if not self.is_alive() and self._checks:
86
+ LOG.warning("Resetting client. It's not alive.")
87
+ self.reset()
88
+ self._checks = True
89
+
90
+ def keepalive_log(self):
91
+ if ka := self._client.aprsd_keepalive:
92
+ keepalive = timeago.format(ka)
93
+ else:
94
+ keepalive = "N/A"
95
+ LOGU.opt(colors=True).info(f"<green>Client keepalive {keepalive}</green>")
96
+
82
97
  @staticmethod
83
98
  def transport():
84
99
  if CONF.kiss_serial.enabled:
aprsd/client/stats.py CHANGED
@@ -1,18 +1,16 @@
1
1
  import threading
2
2
 
3
- from oslo_config import cfg
4
3
  import wrapt
4
+ from oslo_config import cfg
5
5
 
6
6
  from aprsd import client
7
7
  from aprsd.utils import singleton
8
8
 
9
-
10
9
  CONF = cfg.CONF
11
10
 
12
11
 
13
12
  @singleton
14
13
  class APRSClientStats:
15
-
16
14
  lock = threading.Lock()
17
15
 
18
16
  @wrapt.synchronized(lock)
aprsd/cmds/completion.py CHANGED
@@ -3,12 +3,13 @@ import click.shell_completion
3
3
 
4
4
  from aprsd.main import cli
5
5
 
6
-
7
6
  CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
8
7
 
9
8
 
10
9
  @cli.command()
11
- @click.argument("shell", type=click.Choice(list(click.shell_completion._available_shells)))
10
+ @click.argument(
11
+ "shell", type=click.Choice(list(click.shell_completion._available_shells))
12
+ )
12
13
  def completion(shell):
13
14
  """Show the shell completion code"""
14
15
  from click.utils import _detect_program_name
@@ -17,6 +18,8 @@ def completion(shell):
17
18
  prog_name = _detect_program_name()
18
19
  complete_var = f"_{prog_name}_COMPLETE".replace("-", "_").upper()
19
20
  print(cls(cli, {}, prog_name, complete_var).source())
20
- print("# Add the following line to your shell configuration file to have aprsd command line completion")
21
+ print(
22
+ "# Add the following line to your shell configuration file to have aprsd command line completion"
23
+ )
21
24
  print("# but remove the leading '#' character.")
22
- print(f"# eval \"$(aprsd completion {shell})\"")
25
+ print(f'# eval "$(aprsd completion {shell})"')
aprsd/cmds/dev.py CHANGED
@@ -9,18 +9,18 @@ import click
9
9
  from oslo_config import cfg
10
10
 
11
11
  from aprsd import cli_helper, conf, packets, plugin
12
+
12
13
  # local imports here
13
14
  from aprsd.client import base
14
15
  from aprsd.main import cli
15
16
  from aprsd.utils import trace
16
17
 
17
-
18
18
  CONF = cfg.CONF
19
- LOG = logging.getLogger("APRSD")
20
- CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
19
+ LOG = logging.getLogger('APRSD')
20
+ CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
21
21
 
22
22
 
23
- @cli.group(help="Development type subcommands", context_settings=CONTEXT_SETTINGS)
23
+ @cli.group(help='Development type subcommands', context_settings=CONTEXT_SETTINGS)
24
24
  @click.pass_context
25
25
  def dev(ctx):
26
26
  pass
@@ -29,37 +29,37 @@ def dev(ctx):
29
29
  @dev.command()
30
30
  @cli_helper.add_options(cli_helper.common_options)
31
31
  @click.option(
32
- "--aprs-login",
33
- envvar="APRS_LOGIN",
32
+ '--aprs-login',
33
+ envvar='APRS_LOGIN',
34
34
  show_envvar=True,
35
- help="What callsign to send the message from.",
35
+ help='What callsign to send the message from.',
36
36
  )
37
37
  @click.option(
38
- "-p",
39
- "--plugin",
40
- "plugin_path",
38
+ '-p',
39
+ '--plugin',
40
+ 'plugin_path',
41
41
  show_default=True,
42
42
  default=None,
43
- help="The plugin to run. Ex: aprsd.plugins.ping.PingPlugin",
43
+ help='The plugin to run. Ex: aprsd.plugins.ping.PingPlugin',
44
44
  )
45
45
  @click.option(
46
- "-a",
47
- "--all",
48
- "load_all",
46
+ '-a',
47
+ '--all',
48
+ 'load_all',
49
49
  show_default=True,
50
50
  is_flag=True,
51
51
  default=False,
52
- help="Load all the plugins in config?",
52
+ help='Load all the plugins in config?',
53
53
  )
54
54
  @click.option(
55
- "-n",
56
- "--num",
57
- "number",
55
+ '-n',
56
+ '--num',
57
+ 'number',
58
58
  show_default=True,
59
59
  default=1,
60
- help="Number of times to call the plugin",
60
+ help='Number of times to call the plugin',
61
61
  )
62
- @click.argument("message", nargs=-1, required=True)
62
+ @click.argument('message', nargs=-1, required=True)
63
63
  @click.pass_context
64
64
  @cli_helper.process_standard_options
65
65
  def test_plugin(
@@ -76,7 +76,7 @@ def test_plugin(
76
76
 
77
77
  if not aprs_login:
78
78
  if CONF.aprs_network.login == conf.client.DEFAULT_LOGIN:
79
- click.echo("Must set --aprs_login or APRS_LOGIN")
79
+ click.echo('Must set --aprs_login or APRS_LOGIN')
80
80
  ctx.exit(-1)
81
81
  return
82
82
  else:
@@ -86,16 +86,16 @@ def test_plugin(
86
86
 
87
87
  if not plugin_path:
88
88
  click.echo(ctx.get_help())
89
- click.echo("")
90
- click.echo("Failed to provide -p option to test a plugin")
89
+ click.echo('')
90
+ click.echo('Failed to provide -p option to test a plugin')
91
91
  ctx.exit(-1)
92
92
  return
93
93
 
94
94
  if type(message) is tuple:
95
- message = " ".join(message)
95
+ message = ' '.join(message)
96
96
 
97
97
  if CONF.trace_enabled:
98
- trace.setup_tracing(["method", "api"])
98
+ trace.setup_tracing(['method', 'api'])
99
99
 
100
100
  base.APRSClient()
101
101
 
@@ -105,14 +105,15 @@ def test_plugin(
105
105
  obj = pm._create_class(plugin_path, plugin.APRSDPluginBase)
106
106
  if not obj:
107
107
  click.echo(ctx.get_help())
108
- click.echo("")
108
+ click.echo('')
109
109
  ctx.fail(f"Failed to create object from plugin path '{plugin_path}'")
110
110
  ctx.exit()
111
111
 
112
112
  # Register the plugin they wanted tested.
113
113
  LOG.info(
114
- "Testing plugin {} Version {}".format(
115
- obj.__class__, obj.version,
114
+ 'Testing plugin {} Version {}'.format(
115
+ obj.__class__,
116
+ obj.version,
116
117
  ),
117
118
  )
118
119
  pm.register_msg(obj)
@@ -125,7 +126,7 @@ def test_plugin(
125
126
  )
126
127
  LOG.info(f"P'{plugin_path}' F'{fromcall}' C'{message}'")
127
128
 
128
- for x in range(number):
129
+ for _ in range(number):
129
130
  replies = pm.run(packet)
130
131
  # Plugin might have threads, so lets stop them so we can exit.
131
132
  # obj.stop_threads()
@@ -146,17 +147,12 @@ def test_plugin(
146
147
  elif isinstance(reply, packets.Packet):
147
148
  # We have a message based object.
148
149
  LOG.info(reply)
149
- else:
150
- # A plugin can return a null message flag which signals
151
- # us that they processed the message correctly, but have
152
- # nothing to reply with, so we avoid replying with a
153
- # usage string
154
- if reply is not packets.NULL_MESSAGE:
155
- LOG.info(
156
- packets.MessagePacket(
157
- from_call=CONF.callsign,
158
- to_call=fromcall,
159
- message_text=reply,
160
- ),
161
- )
150
+ elif reply is not packets.NULL_MESSAGE:
151
+ LOG.info(
152
+ packets.MessagePacket(
153
+ from_call=CONF.callsign,
154
+ to_call=fromcall,
155
+ message_text=reply,
156
+ ),
157
+ )
162
158
  pm.stop()