aprsd 3.4.4__py3-none-any.whl → 4.0.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.
Files changed (115) 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.0.dist-info/AUTHORS +1 -0
  46. aprsd-4.0.0.dist-info/METADATA +293 -0
  47. aprsd-4.0.0.dist-info/RECORD +74 -0
  48. {aprsd-3.4.4.dist-info → aprsd-4.0.0.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/METADATA +0 -849
  112. aprsd-3.4.4.dist-info/RECORD +0 -134
  113. {aprsd-3.4.4.dist-info → aprsd-4.0.0.dist-info}/LICENSE +0 -0
  114. {aprsd-3.4.4.dist-info → aprsd-4.0.0.dist-info}/entry_points.txt +0 -0
  115. {aprsd-3.4.4.dist-info → aprsd-4.0.0.dist-info}/top_level.txt +0 -0
@@ -5,14 +5,12 @@ import tracemalloc
5
5
 
6
6
  from loguru import logger
7
7
  from oslo_config import cfg
8
- import timeago
9
8
 
10
9
  from aprsd import packets, utils
11
- from aprsd.client import client_factory
12
10
  from aprsd.log import log as aprsd_log
13
11
  from aprsd.stats import collector
14
12
  from aprsd.threads import APRSDThread, APRSDThreadList
15
-
13
+ from aprsd.utils import keepalive_collector
16
14
 
17
15
  CONF = cfg.CONF
18
16
  LOG = logging.getLogger("APRSD")
@@ -36,18 +34,14 @@ class KeepAliveThread(APRSDThread):
36
34
  thread_list = APRSDThreadList()
37
35
  now = datetime.datetime.now()
38
36
 
39
- if "EmailStats" in stats_json:
40
- email_stats = stats_json["EmailStats"]
41
- if email_stats.get("last_check_time"):
42
- email_thread_time = utils.strfdelta(now - email_stats["last_check_time"])
43
- else:
44
- email_thread_time = "N/A"
45
- else:
46
- email_thread_time = "N/A"
47
-
48
- if "APRSClientStats" in stats_json and stats_json["APRSClientStats"].get("transport") == "aprsis":
37
+ if (
38
+ "APRSClientStats" in stats_json
39
+ and stats_json["APRSClientStats"].get("transport") == "aprsis"
40
+ ):
49
41
  if stats_json["APRSClientStats"].get("server_keepalive"):
50
- last_msg_time = utils.strfdelta(now - stats_json["APRSClientStats"]["server_keepalive"])
42
+ last_msg_time = utils.strfdelta(
43
+ now - stats_json["APRSClientStats"]["server_keepalive"]
44
+ )
51
45
  else:
52
46
  last_msg_time = "N/A"
53
47
  else:
@@ -64,7 +58,7 @@ class KeepAliveThread(APRSDThread):
64
58
 
65
59
  keepalive = (
66
60
  "{} - Uptime {} RX:{} TX:{} Tracker:{} Msgs TX:{} RX:{} "
67
- "Last:{} Email: {} - RAM Current:{} Peak:{} Threads:{} LoggingQueue:{}"
61
+ "Last:{} - RAM Current:{} Peak:{} Threads:{} LoggingQueue:{}"
68
62
  ).format(
69
63
  stats_json["APRSDStats"]["callsign"],
70
64
  stats_json["APRSDStats"]["uptime"],
@@ -74,7 +68,6 @@ class KeepAliveThread(APRSDThread):
74
68
  tx_msg,
75
69
  rx_msg,
76
70
  last_msg_time,
77
- email_thread_time,
78
71
  stats_json["APRSDStats"]["memory_current_str"],
79
72
  stats_json["APRSDStats"]["memory_peak_str"],
80
73
  len(thread_list),
@@ -97,35 +90,11 @@ class KeepAliveThread(APRSDThread):
97
90
  LOGU.opt(colors=True).info(thread_msg)
98
91
  # LOG.info(f"{key: <15} Alive? {str(alive): <5} {str(age): <20}")
99
92
 
100
- # check the APRS connection
101
- cl = client_factory.create()
102
- cl_stats = cl.stats()
103
- ka = cl_stats.get("connection_keepalive", None)
104
- if ka:
105
- keepalive = timeago.format(ka)
106
- else:
107
- keepalive = "N/A"
108
- LOGU.opt(colors=True).info(f"<green>Client keepalive {keepalive}</green>")
109
- # Reset the connection if it's dead and this isn't our
110
- # First time through the loop.
111
- # The first time through the loop can happen at startup where
112
- # The keepalive thread starts before the client has a chance
113
- # to make it's connection the first time.
114
- if not cl.is_alive() and self.cntr > 0:
115
- LOG.error(f"{cl.__class__.__name__} is not alive!!! Resetting")
116
- client_factory.create().reset()
117
- # else:
118
- # # See if we should reset the aprs-is client
119
- # # Due to losing a keepalive from them
120
- # delta_dict = utils.parse_delta_str(last_msg_time)
121
- # delta = datetime.timedelta(**delta_dict)
122
- #
123
- # if delta > self.max_delta:
124
- # # We haven't gotten a keepalive from aprs-is in a while
125
- # # reset the connection.a
126
- # if not client.KISSClient.is_enabled():
127
- # LOG.warning(f"Resetting connection to APRS-IS {delta}")
128
- # client.factory.create().reset()
93
+ # Go through the registered keepalive collectors
94
+ # and check them as well as call log.
95
+ collect = keepalive_collector.KeepAliveCollector()
96
+ collect.check()
97
+ collect.log()
129
98
 
130
99
  # Check version every day
131
100
  delta = now - self.checker_time
aprsd/threads/registry.py CHANGED
@@ -1,19 +1,19 @@
1
1
  import logging
2
2
  import time
3
3
 
4
- from oslo_config import cfg
5
4
  import requests
5
+ from oslo_config import cfg
6
6
 
7
7
  import aprsd
8
8
  from aprsd import threads as aprsd_threads
9
9
 
10
-
11
10
  CONF = cfg.CONF
12
11
  LOG = logging.getLogger("APRSD")
13
12
 
14
13
 
15
14
  class APRSRegistryThread(aprsd_threads.APRSDThread):
16
15
  """This sends service information to the configured APRS Registry."""
16
+
17
17
  _loop_cnt: int = 1
18
18
 
19
19
  def __init__(self):
@@ -41,7 +41,7 @@ class APRSRegistryThread(aprsd_threads.APRSDThread):
41
41
  "description": CONF.aprs_registry.description,
42
42
  "service_website": CONF.aprs_registry.service_website,
43
43
  "software": f"APRSD version {aprsd.__version__} "
44
- "https://github.com/craigerl/aprsd",
44
+ "https://github.com/craigerl/aprsd",
45
45
  }
46
46
  try:
47
47
  requests.post(
aprsd/threads/rx.py CHANGED
@@ -13,7 +13,6 @@ from aprsd.packets import log as packet_log
13
13
  from aprsd.threads import APRSDThread, tx
14
14
  from aprsd.utils import trace
15
15
 
16
-
17
16
  CONF = cfg.CONF
18
17
  LOG = logging.getLogger("APRSD")
19
18
 
@@ -53,7 +52,9 @@ class APRSDRXThread(APRSDThread):
53
52
  # kwargs. :(
54
53
  # https://github.com/rossengeorgiev/aprs-python/pull/56
55
54
  self._client.consumer(
56
- self._process_packet, raw=False, blocking=False,
55
+ self._process_packet,
56
+ raw=False,
57
+ blocking=False,
57
58
  )
58
59
  except (
59
60
  aprslib.exceptions.ConnectionDrop,
@@ -138,7 +139,9 @@ class APRSDDupeRXThread(APRSDRXThread):
138
139
  elif packet.timestamp - found.timestamp < CONF.packet_dupe_timeout:
139
140
  # If the packet came in within N seconds of the
140
141
  # Last time seeing the packet, then we drop it as a dupe.
141
- LOG.warning(f"Packet {packet.from_call}:{packet.msgNo} already tracked, dropping.")
142
+ LOG.warning(
143
+ f"Packet {packet.from_call}:{packet.msgNo} already tracked, dropping."
144
+ )
142
145
  else:
143
146
  LOG.warning(
144
147
  f"Packet {packet.from_call}:{packet.msgNo} already tracked "
@@ -149,7 +152,7 @@ class APRSDDupeRXThread(APRSDRXThread):
149
152
 
150
153
 
151
154
  class APRSDPluginRXThread(APRSDDupeRXThread):
152
- """"Process received packets.
155
+ """ "Process received packets.
153
156
 
154
157
  For backwards compatibility, we keep the APRSDPluginRXThread.
155
158
  """
@@ -249,7 +252,8 @@ class APRSDProcessPacketThread(APRSDThread):
249
252
  self.process_other_packet(packet, for_us=False)
250
253
  else:
251
254
  self.process_other_packet(
252
- packet, for_us=(to_call.lower() == our_call),
255
+ packet,
256
+ for_us=(to_call.lower() == our_call),
253
257
  )
254
258
  LOG.debug(f"Packet processing complete for pkt '{packet.key}'")
255
259
  return False
@@ -349,7 +353,6 @@ class APRSDPluginProcessPacketThread(APRSDProcessPacketThread):
349
353
  # If the message was for us and we didn't have a
350
354
  # response, then we send a usage statement.
351
355
  if to_call == CONF.callsign and not replied:
352
-
353
356
  # Tailor the messages accordingly
354
357
  if CONF.load_help_plugin:
355
358
  LOG.warning("Sending help!")
aprsd/threads/stats.py CHANGED
@@ -2,20 +2,20 @@ import logging
2
2
  import threading
3
3
  import time
4
4
 
5
- from oslo_config import cfg
6
5
  import wrapt
6
+ from oslo_config import cfg
7
7
 
8
8
  from aprsd.stats import collector
9
9
  from aprsd.threads import APRSDThread
10
10
  from aprsd.utils import objectstore
11
11
 
12
-
13
12
  CONF = cfg.CONF
14
13
  LOG = logging.getLogger("APRSD")
15
14
 
16
15
 
17
16
  class StatsStore(objectstore.ObjectStoreMixin):
18
17
  """Container to save the stats from the collector."""
18
+
19
19
  lock = threading.Lock()
20
20
  data = {}
21
21
 
aprsd/threads/tx.py CHANGED
@@ -2,20 +2,18 @@ import logging
2
2
  import threading
3
3
  import time
4
4
 
5
+ import wrapt
5
6
  from oslo_config import cfg
6
7
  from rush import quota, throttle
7
8
  from rush.contrib import decorator
8
9
  from rush.limiters import periodic
9
10
  from rush.stores import dictionary
10
- import wrapt
11
11
 
12
12
  from aprsd import conf # noqa
13
13
  from aprsd import threads as aprsd_threads
14
14
  from aprsd.client import client_factory
15
- from aprsd.packets import collector, core
15
+ from aprsd.packets import collector, core, tracker
16
16
  from aprsd.packets import log as packet_log
17
- from aprsd.packets import tracker
18
-
19
17
 
20
18
  CONF = cfg.CONF
21
19
  LOG = logging.getLogger("APRSD")
@@ -238,6 +236,7 @@ class BeaconSendThread(aprsd_threads.APRSDThread):
238
236
 
239
237
  Settings are in the [DEFAULT] section of the config file.
240
238
  """
239
+
241
240
  _loop_cnt: int = 1
242
241
 
243
242
  def __init__(self):
aprsd/utils/__init__.py CHANGED
@@ -13,11 +13,11 @@ import update_checker
13
13
  import aprsd
14
14
 
15
15
  from .fuzzyclock import fuzzy # noqa: F401
16
+
16
17
  # Make these available by anyone importing
17
18
  # aprsd.utils
18
19
  from .ring_buffer import RingBuffer # noqa: F401
19
20
 
20
-
21
21
  if sys.version_info.major == 3 and sys.version_info.minor >= 3:
22
22
  from collections.abc import MutableMapping
23
23
  else:
@@ -26,11 +26,13 @@ else:
26
26
 
27
27
  def singleton(cls):
28
28
  """Make a class a Singleton class (only one instance)"""
29
+
29
30
  @functools.wraps(cls)
30
31
  def wrapper_singleton(*args, **kwargs):
31
32
  if wrapper_singleton.instance is None:
32
33
  wrapper_singleton.instance = cls(*args, **kwargs)
33
34
  return wrapper_singleton.instance
35
+
34
36
  wrapper_singleton.instance = None
35
37
  return wrapper_singleton
36
38
 
@@ -170,7 +172,10 @@ def load_entry_points(group):
170
172
  try:
171
173
  ep.load()
172
174
  except Exception as e:
173
- print(f"Extension {ep.name} of group {group} failed to load with {e}", file=sys.stderr)
175
+ print(
176
+ f"Extension {ep.name} of group {group} failed to load with {e}",
177
+ file=sys.stderr,
178
+ )
174
179
  print(traceback.format_exc(), file=sys.stderr)
175
180
 
176
181
 
@@ -200,8 +205,7 @@ def calculate_initial_compass_bearing(point_a, point_b):
200
205
 
201
206
  x = math.sin(diff_long) * math.cos(lat2)
202
207
  y = math.cos(lat1) * math.sin(lat2) - (
203
- math.sin(lat1)
204
- * math.cos(lat2) * math.cos(diff_long)
208
+ math.sin(lat1) * math.cos(lat2) * math.cos(diff_long)
205
209
  )
206
210
 
207
211
  initial_bearing = math.atan2(x, y)
@@ -218,15 +222,43 @@ def calculate_initial_compass_bearing(point_a, point_b):
218
222
  def degrees_to_cardinal(bearing, full_string=False):
219
223
  if full_string:
220
224
  directions = [
221
- "North", "North-Northeast", "Northeast", "East-Northeast", "East", "East-Southeast",
222
- "Southeast", "South-Southeast", "South", "South-Southwest", "Southwest", "West-Southwest",
223
- "West", "West-Northwest", "Northwest", "North-Northwest", "North",
225
+ "North",
226
+ "North-Northeast",
227
+ "Northeast",
228
+ "East-Northeast",
229
+ "East",
230
+ "East-Southeast",
231
+ "Southeast",
232
+ "South-Southeast",
233
+ "South",
234
+ "South-Southwest",
235
+ "Southwest",
236
+ "West-Southwest",
237
+ "West",
238
+ "West-Northwest",
239
+ "Northwest",
240
+ "North-Northwest",
241
+ "North",
224
242
  ]
225
243
  else:
226
244
  directions = [
227
- "N", "NNE", "NE", "ENE", "E", "ESE",
228
- "SE", "SSE", "S", "SSW", "SW", "WSW",
229
- "W", "WNW", "NW", "NNW", "N",
245
+ "N",
246
+ "NNE",
247
+ "NE",
248
+ "ENE",
249
+ "E",
250
+ "ESE",
251
+ "SE",
252
+ "SSE",
253
+ "S",
254
+ "SSW",
255
+ "SW",
256
+ "WSW",
257
+ "W",
258
+ "WNW",
259
+ "NW",
260
+ "NNW",
261
+ "N",
230
262
  ]
231
263
 
232
264
  cardinal = directions[round(bearing / 22.5)]
aprsd/utils/json.py CHANGED
@@ -10,8 +10,13 @@ class EnhancedJSONEncoder(json.JSONEncoder):
10
10
  def default(self, obj):
11
11
  if isinstance(obj, datetime.datetime):
12
12
  args = (
13
- "year", "month", "day", "hour", "minute",
14
- "second", "microsecond",
13
+ "year",
14
+ "month",
15
+ "day",
16
+ "hour",
17
+ "minute",
18
+ "second",
19
+ "microsecond",
15
20
  )
16
21
  return {
17
22
  "__type__": "datetime.datetime",
@@ -63,10 +68,10 @@ class SimpleJSONEncoder(json.JSONEncoder):
63
68
 
64
69
 
65
70
  class EnhancedJSONDecoder(json.JSONDecoder):
66
-
67
71
  def __init__(self, *args, **kwargs):
68
72
  super().__init__(
69
- *args, object_hook=self.object_hook,
73
+ *args,
74
+ object_hook=self.object_hook,
70
75
  **kwargs,
71
76
  )
72
77
 
@@ -0,0 +1,55 @@
1
+ import logging
2
+ from typing import Callable, Protocol, runtime_checkable
3
+
4
+ from aprsd.utils import singleton
5
+
6
+ LOG = logging.getLogger("APRSD")
7
+
8
+
9
+ @runtime_checkable
10
+ class KeepAliveProducer(Protocol):
11
+ """The KeepAliveProducer protocol is used to define the interface for running Keepalive checks."""
12
+
13
+ def keepalive_check(self) -> dict:
14
+ """Check for keepalive."""
15
+ ...
16
+
17
+ def keepalive_log(self):
18
+ """Log any keepalive information."""
19
+ ...
20
+
21
+
22
+ @singleton
23
+ class KeepAliveCollector:
24
+ """The Collector class is used to collect stats from multiple StatsProducer instances."""
25
+
26
+ def __init__(self):
27
+ self.producers: list[Callable] = []
28
+
29
+ def check(self) -> None:
30
+ """Do any keepalive checks."""
31
+ for name in self.producers:
32
+ cls = name()
33
+ try:
34
+ cls.keepalive_check()
35
+ except Exception as e:
36
+ LOG.error(f"Error in producer {name} (check): {e}")
37
+
38
+ def log(self) -> None:
39
+ """Log any relevant information during a KeepAlive check"""
40
+ for name in self.producers:
41
+ cls = name()
42
+ try:
43
+ cls.keepalive_log()
44
+ except Exception as e:
45
+ LOG.error(f"Error in producer {name} (check): {e}")
46
+
47
+ def register(self, producer_name: Callable):
48
+ if not isinstance(producer_name, KeepAliveProducer):
49
+ raise TypeError(f"Producer {producer_name} is not a KeepAliveProducer")
50
+ self.producers.append(producer_name)
51
+
52
+ def unregister(self, producer_name: Callable):
53
+ if not isinstance(producer_name, KeepAliveProducer):
54
+ raise TypeError(f"Producer {producer_name} is not a KeepAliveProducer")
55
+ self.producers.remove(producer_name)
aprsd/utils/trace.py CHANGED
@@ -5,7 +5,6 @@ import logging
5
5
  import time
6
6
  import types
7
7
 
8
-
9
8
  VALID_TRACE_FLAGS = {"method", "api"}
10
9
  TRACE_API = False
11
10
  TRACE_METHOD = False
@@ -27,7 +26,6 @@ def trace(*dec_args, **dec_kwargs):
27
26
  """
28
27
 
29
28
  def _decorator(f):
30
-
31
29
  func_name = f.__qualname__
32
30
  func_file = "/".join(f.__code__.co_filename.split("/")[-4:])
33
31
 
@@ -0,0 +1 @@
1
+ waboring@hemna.com : 1