aprsd 4.0.1__tar.gz → 4.0.2__tar.gz

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 (158) hide show
  1. {aprsd-4.0.1 → aprsd-4.0.2}/.github/workflows/release_build.yml +3 -2
  2. {aprsd-4.0.1 → aprsd-4.0.2}/ChangeLog.md +14 -0
  3. {aprsd-4.0.1 → aprsd-4.0.2}/PKG-INFO +1 -1
  4. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/client/drivers/fake.py +5 -0
  5. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/client/drivers/kiss.py +17 -15
  6. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/client/kiss.py +28 -25
  7. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/plugins/fortune.py +21 -15
  8. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd.egg-info/PKG-INFO +1 -1
  9. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd.egg-info/SOURCES.txt +1 -0
  10. {aprsd-4.0.1 → aprsd-4.0.2}/docker/Dockerfile +2 -1
  11. aprsd-4.0.2/uv.lock +1340 -0
  12. {aprsd-4.0.1 → aprsd-4.0.2}/.coveragerc +0 -0
  13. {aprsd-4.0.1 → aprsd-4.0.2}/.github/workflows/authors.yml +0 -0
  14. {aprsd-4.0.1 → aprsd-4.0.2}/.github/workflows/codeql.yml +0 -0
  15. {aprsd-4.0.1 → aprsd-4.0.2}/.github/workflows/manual_build.yml +0 -0
  16. {aprsd-4.0.1 → aprsd-4.0.2}/.github/workflows/master-build.yml +0 -0
  17. {aprsd-4.0.1 → aprsd-4.0.2}/.github/workflows/python.yml +0 -0
  18. {aprsd-4.0.1 → aprsd-4.0.2}/.mailmap +0 -0
  19. {aprsd-4.0.1 → aprsd-4.0.2}/.pre-commit-config.yaml +0 -0
  20. {aprsd-4.0.1 → aprsd-4.0.2}/.readthedocs.yaml +0 -0
  21. {aprsd-4.0.1 → aprsd-4.0.2}/AUTHORS +0 -0
  22. {aprsd-4.0.1 → aprsd-4.0.2}/CONTRIBUTING.md +0 -0
  23. {aprsd-4.0.1 → aprsd-4.0.2}/INSTALL.txt +0 -0
  24. {aprsd-4.0.1 → aprsd-4.0.2}/LICENSE +0 -0
  25. {aprsd-4.0.1 → aprsd-4.0.2}/MANIFEST.in +0 -0
  26. {aprsd-4.0.1 → aprsd-4.0.2}/Makefile +0 -0
  27. {aprsd-4.0.1 → aprsd-4.0.2}/README.md +0 -0
  28. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/__init__.py +0 -0
  29. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/cli_helper.py +0 -0
  30. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/client/__init__.py +0 -0
  31. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/client/aprsis.py +0 -0
  32. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/client/base.py +0 -0
  33. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/client/drivers/__init__.py +0 -0
  34. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/client/drivers/aprsis.py +0 -0
  35. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/client/factory.py +0 -0
  36. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/client/fake.py +0 -0
  37. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/client/stats.py +0 -0
  38. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/cmds/__init__.py +0 -0
  39. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/cmds/completion.py +0 -0
  40. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/cmds/dev.py +0 -0
  41. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/cmds/fetch_stats.py +0 -0
  42. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/cmds/healthcheck.py +0 -0
  43. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/cmds/list_plugins.py +0 -0
  44. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/cmds/listen.py +0 -0
  45. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/cmds/send_message.py +0 -0
  46. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/cmds/server.py +0 -0
  47. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/conf/__init__.py +0 -0
  48. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/conf/client.py +0 -0
  49. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/conf/common.py +0 -0
  50. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/conf/log.py +0 -0
  51. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/conf/opts.py +0 -0
  52. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/conf/plugin_common.py +0 -0
  53. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/exception.py +0 -0
  54. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/log/__init__.py +0 -0
  55. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/log/log.py +0 -0
  56. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/main.py +0 -0
  57. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/packets/__init__.py +0 -0
  58. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/packets/collector.py +0 -0
  59. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/packets/core.py +0 -0
  60. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/packets/log.py +0 -0
  61. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/packets/packet_list.py +0 -0
  62. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/packets/seen_list.py +0 -0
  63. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/packets/tracker.py +0 -0
  64. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/packets/watch_list.py +0 -0
  65. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/plugin.py +0 -0
  66. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/plugin_utils.py +0 -0
  67. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/plugins/__init__.py +0 -0
  68. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/plugins/notify.py +0 -0
  69. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/plugins/ping.py +0 -0
  70. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/plugins/time.py +0 -0
  71. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/plugins/version.py +0 -0
  72. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/plugins/weather.py +0 -0
  73. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/stats/__init__.py +0 -0
  74. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/stats/app.py +0 -0
  75. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/stats/collector.py +0 -0
  76. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/threads/__init__.py +0 -0
  77. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/threads/aprsd.py +0 -0
  78. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/threads/keepalive.py +0 -0
  79. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/threads/registry.py +0 -0
  80. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/threads/rx.py +0 -0
  81. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/threads/stats.py +0 -0
  82. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/threads/tx.py +0 -0
  83. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/utils/__init__.py +0 -0
  84. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/utils/counter.py +0 -0
  85. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/utils/fuzzyclock.py +0 -0
  86. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/utils/json.py +0 -0
  87. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/utils/keepalive_collector.py +0 -0
  88. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/utils/objectstore.py +0 -0
  89. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/utils/ring_buffer.py +0 -0
  90. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd/utils/trace.py +0 -0
  91. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd-lnav.json +0 -0
  92. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd.egg-info/dependency_links.txt +0 -0
  93. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd.egg-info/entry_points.txt +0 -0
  94. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd.egg-info/requires.txt +0 -0
  95. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd.egg-info/top_level.txt +0 -0
  96. {aprsd-4.0.1 → aprsd-4.0.2}/aprsd_logo.png +0 -0
  97. {aprsd-4.0.1 → aprsd-4.0.2}/docker/bin/admin.sh +0 -0
  98. {aprsd-4.0.1 → aprsd-4.0.2}/docker/bin/healthcheck.sh +0 -0
  99. {aprsd-4.0.1 → aprsd-4.0.2}/docker/bin/listen.sh +0 -0
  100. {aprsd-4.0.1 → aprsd-4.0.2}/docker/bin/run.sh +0 -0
  101. {aprsd-4.0.1 → aprsd-4.0.2}/docker/bin/setup.sh +0 -0
  102. {aprsd-4.0.1 → aprsd-4.0.2}/docker/build.sh +0 -0
  103. {aprsd-4.0.1 → aprsd-4.0.2}/docker/docker-compose.yml +0 -0
  104. {aprsd-4.0.1 → aprsd-4.0.2}/docs/_static/.keep +0 -0
  105. {aprsd-4.0.1 → aprsd-4.0.2}/docs/_static/aprsd_overview.png +0 -0
  106. {aprsd-4.0.1 → aprsd-4.0.2}/docs/_static/aprsd_overview.svg +0 -0
  107. {aprsd-4.0.1 → aprsd-4.0.2}/docs/_templates/.keep +0 -0
  108. {aprsd-4.0.1 → aprsd-4.0.2}/docs/apidoc/aprsd.client.drivers.rst +0 -0
  109. {aprsd-4.0.1 → aprsd-4.0.2}/docs/apidoc/aprsd.client.rst +0 -0
  110. {aprsd-4.0.1 → aprsd-4.0.2}/docs/apidoc/aprsd.cmds.rst +0 -0
  111. {aprsd-4.0.1 → aprsd-4.0.2}/docs/apidoc/aprsd.conf.rst +0 -0
  112. {aprsd-4.0.1 → aprsd-4.0.2}/docs/apidoc/aprsd.log.rst +0 -0
  113. {aprsd-4.0.1 → aprsd-4.0.2}/docs/apidoc/aprsd.packets.rst +0 -0
  114. {aprsd-4.0.1 → aprsd-4.0.2}/docs/apidoc/aprsd.plugins.rst +0 -0
  115. {aprsd-4.0.1 → aprsd-4.0.2}/docs/apidoc/aprsd.rst +0 -0
  116. {aprsd-4.0.1 → aprsd-4.0.2}/docs/apidoc/aprsd.stats.rst +0 -0
  117. {aprsd-4.0.1 → aprsd-4.0.2}/docs/apidoc/aprsd.threads.rst +0 -0
  118. {aprsd-4.0.1 → aprsd-4.0.2}/docs/apidoc/aprsd.utils.rst +0 -0
  119. {aprsd-4.0.1 → aprsd-4.0.2}/docs/apidoc/modules.rst +0 -0
  120. {aprsd-4.0.1 → aprsd-4.0.2}/docs/aprsd.drawio +0 -0
  121. {aprsd-4.0.1 → aprsd-4.0.2}/docs/changelog.rst +0 -0
  122. {aprsd-4.0.1 → aprsd-4.0.2}/docs/clean_docs.py +0 -0
  123. {aprsd-4.0.1 → aprsd-4.0.2}/docs/conf.py +0 -0
  124. {aprsd-4.0.1 → aprsd-4.0.2}/docs/configure.rst +0 -0
  125. {aprsd-4.0.1 → aprsd-4.0.2}/docs/index.rst +0 -0
  126. {aprsd-4.0.1 → aprsd-4.0.2}/docs/install.rst +0 -0
  127. {aprsd-4.0.1 → aprsd-4.0.2}/docs/links.rst +0 -0
  128. {aprsd-4.0.1 → aprsd-4.0.2}/docs/plugin.rst +0 -0
  129. {aprsd-4.0.1 → aprsd-4.0.2}/docs/readme.rst +0 -0
  130. {aprsd-4.0.1 → aprsd-4.0.2}/docs/server.rst +0 -0
  131. {aprsd-4.0.1 → aprsd-4.0.2}/examples/plugins/__init__.py +0 -0
  132. {aprsd-4.0.1 → aprsd-4.0.2}/examples/plugins/example_plugin.py +0 -0
  133. {aprsd-4.0.1 → aprsd-4.0.2}/gray.conf +0 -0
  134. {aprsd-4.0.1 → aprsd-4.0.2}/pyproject.toml +0 -0
  135. {aprsd-4.0.1 → aprsd-4.0.2}/requirements-dev.in +0 -0
  136. {aprsd-4.0.1 → aprsd-4.0.2}/requirements-dev.txt +0 -0
  137. {aprsd-4.0.1 → aprsd-4.0.2}/requirements.in +0 -0
  138. {aprsd-4.0.1 → aprsd-4.0.2}/requirements.txt +0 -0
  139. {aprsd-4.0.1 → aprsd-4.0.2}/setup.cfg +0 -0
  140. {aprsd-4.0.1 → aprsd-4.0.2}/setup.py +0 -0
  141. {aprsd-4.0.1 → aprsd-4.0.2}/tests/__init__.py +0 -0
  142. {aprsd-4.0.1 → aprsd-4.0.2}/tests/client/test_aprsis.py +0 -0
  143. {aprsd-4.0.1 → aprsd-4.0.2}/tests/client/test_client_base.py +0 -0
  144. {aprsd-4.0.1 → aprsd-4.0.2}/tests/client/test_factory.py +0 -0
  145. {aprsd-4.0.1 → aprsd-4.0.2}/tests/cmds/__init__.py +0 -0
  146. {aprsd-4.0.1 → aprsd-4.0.2}/tests/cmds/test_send_message.py +0 -0
  147. {aprsd-4.0.1 → aprsd-4.0.2}/tests/fake.py +0 -0
  148. {aprsd-4.0.1 → aprsd-4.0.2}/tests/plugins/__init__.py +0 -0
  149. {aprsd-4.0.1 → aprsd-4.0.2}/tests/plugins/test_fortune.py +0 -0
  150. {aprsd-4.0.1 → aprsd-4.0.2}/tests/plugins/test_notify.py +0 -0
  151. {aprsd-4.0.1 → aprsd-4.0.2}/tests/plugins/test_ping.py +0 -0
  152. {aprsd-4.0.1 → aprsd-4.0.2}/tests/plugins/test_time.py +0 -0
  153. {aprsd-4.0.1 → aprsd-4.0.2}/tests/plugins/test_version.py +0 -0
  154. {aprsd-4.0.1 → aprsd-4.0.2}/tests/plugins/test_weather.py +0 -0
  155. {aprsd-4.0.1 → aprsd-4.0.2}/tests/test_packets.py +0 -0
  156. {aprsd-4.0.1 → aprsd-4.0.2}/tests/test_plugin.py +0 -0
  157. {aprsd-4.0.1 → aprsd-4.0.2}/tools/fast8.sh +0 -0
  158. {aprsd-4.0.1 → aprsd-4.0.2}/tox.ini +0 -0
@@ -6,7 +6,7 @@ on:
6
6
  aprsd_version:
7
7
  required: true
8
8
  options:
9
- - 3.0.0
9
+ - 4.0.0
10
10
  logLevel:
11
11
  description: 'Log level'
12
12
  required: true
@@ -42,8 +42,9 @@ jobs:
42
42
  file: ./Dockerfile
43
43
  build-args: |
44
44
  VERSION=${{ inputs.aprsd_version }}
45
+ BRANCH=${{ inputs.aprsd_version }}
45
46
  BUILDX_QEMU_ENV=true
46
47
  push: true
47
48
  tags: |
48
- hemna6969/aprsd:v${{ inputs.aprsd_version }}
49
+ hemna6969/aprsd:${{ inputs.aprsd_version }}
49
50
  hemna6969/aprsd:latest
@@ -4,11 +4,25 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ #### [4.0.2](https://github.com/craigerl/aprsd/compare/4.0.1...4.0.2)
8
+
9
+ > 25 January 2025
10
+
11
+ - Fix for KISS/Fake client drivers [`edeba7f`](https://github.com/craigerl/aprsd/commit/edeba7f5141c3197a3ddff5fe45127894c861e07)
12
+ - Trap for failed parsing of packets on KISS [`9501a63`](https://github.com/craigerl/aprsd/commit/9501a63bd61a681daf9eb9e41704e31570b7b385)
13
+ - Pass branch in github release_build [`1f65bbe`](https://github.com/craigerl/aprsd/commit/1f65bbe13a33c1fffad650c87c949bbe844d27f6)
14
+ - Removed some verbose output from KISS [`c1319c3`](https://github.com/craigerl/aprsd/commit/c1319c3ab8822f24c0e3b2c74d151d4e13a0039a)
15
+ - Look in multiple places for fortune bin [`97ffffc`](https://github.com/craigerl/aprsd/commit/97ffffc10dd05bd785134877ddb94437cf9b7f97)
16
+ - Added uv.lock [`2f26eb8`](https://github.com/craigerl/aprsd/commit/2f26eb86f44625547f72f7c3612494b1bc44bc99)
17
+ - Fix the testing of fortune path [`3c4e200`](https://github.com/craigerl/aprsd/commit/3c4e200d700c24125479bb754b5f68bdf35b85a6)
18
+ - update the install from github in Dockerfile [`bea4815`](https://github.com/craigerl/aprsd/commit/bea481555bc1270ab371a22c69973d648e526d54)
19
+
7
20
  #### [4.0.1](https://github.com/craigerl/aprsd/compare/4.0.0...4.0.1)
8
21
 
9
22
  > 24 January 2025
10
23
 
11
24
  - Update pyproject for README.rst -> md [`e080394`](https://github.com/craigerl/aprsd/commit/e08039431ebde92a162ab422c05391dc55d3d3fa)
25
+ - Updated Changelog [`24f5672`](https://github.com/craigerl/aprsd/commit/24f567224cf8ecdebd51f49804425565883acb94)
12
26
 
13
27
  ### [4.0.0](https://github.com/craigerl/aprsd/compare/3.4.4...4.0.0)
14
28
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: aprsd
3
- Version: 4.0.1
3
+ Version: 4.0.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>
@@ -1,3 +1,4 @@
1
+ import datetime
1
2
  import logging
2
3
  import threading
3
4
  import time
@@ -20,6 +21,9 @@ class APRSDFakeClient(metaclass=trace.TraceWrapperMetaclass):
20
21
  # flag to tell us to stop
21
22
  thread_stop = False
22
23
 
24
+ # date for last time we heard from the server
25
+ aprsd_keepalive = datetime.datetime.now()
26
+
23
27
  lock = threading.Lock()
24
28
  path = []
25
29
 
@@ -63,6 +67,7 @@ class APRSDFakeClient(metaclass=trace.TraceWrapperMetaclass):
63
67
  raw = 'GTOWN>APDW16,WIDE1-1,WIDE2-1:}KM6LYW-9>APZ100,TCPIP,GTOWN*::KM6LYW :KM6LYW: 19 Miles SW'
64
68
  pkt_raw = aprslib.parse(raw)
65
69
  pkt = core.factory(pkt_raw)
70
+ self.aprsd_keepalive = datetime.datetime.now()
66
71
  callback(packet=pkt)
67
72
  LOG.debug(f'END blocking FAKE consumer {self}')
68
73
  time.sleep(8)
@@ -1,21 +1,24 @@
1
+ import datetime
1
2
  import logging
2
3
 
3
- from ax253 import Frame
4
4
  import kiss
5
+ from ax253 import Frame
5
6
  from oslo_config import cfg
6
7
 
7
8
  from aprsd import conf # noqa
8
9
  from aprsd.packets import core
9
10
  from aprsd.utils import trace
10
11
 
11
-
12
12
  CONF = cfg.CONF
13
- LOG = logging.getLogger("APRSD")
13
+ LOG = logging.getLogger('APRSD')
14
14
 
15
15
 
16
16
  class KISS3Client:
17
17
  path = []
18
18
 
19
+ # date for last time we heard from the server
20
+ aprsd_keepalive = datetime.datetime.now()
21
+
19
22
  def __init__(self):
20
23
  self.setup()
21
24
 
@@ -26,7 +29,7 @@ class KISS3Client:
26
29
  # we can be TCP kiss or Serial kiss
27
30
  if CONF.kiss_serial.enabled:
28
31
  LOG.debug(
29
- "KISS({}) Serial connection to {}".format(
32
+ 'KISS({}) Serial connection to {}'.format(
30
33
  kiss.__version__,
31
34
  CONF.kiss_serial.device,
32
35
  ),
@@ -39,7 +42,7 @@ class KISS3Client:
39
42
  self.path = CONF.kiss_serial.path
40
43
  elif CONF.kiss_tcp.enabled:
41
44
  LOG.debug(
42
- "KISS({}) TCP Connection to {}:{}".format(
45
+ 'KISS({}) TCP Connection to {}:{}'.format(
43
46
  kiss.__version__,
44
47
  CONF.kiss_tcp.host,
45
48
  CONF.kiss_tcp.port,
@@ -52,7 +55,7 @@ class KISS3Client:
52
55
  )
53
56
  self.path = CONF.kiss_tcp.path
54
57
 
55
- LOG.debug("Starting KISS interface connection")
58
+ LOG.debug('Starting KISS interface connection')
56
59
  self.kiss.start()
57
60
 
58
61
  @trace.trace
@@ -74,18 +77,17 @@ class KISS3Client:
74
77
  frame = Frame.from_bytes(frame_bytes)
75
78
  # Now parse it with aprslib
76
79
  kwargs = {
77
- "frame": frame,
80
+ 'frame': frame,
78
81
  }
79
82
  self._parse_callback(**kwargs)
83
+ self.aprsd_keepalive = datetime.datetime.now()
80
84
  except Exception as ex:
81
- LOG.error("Failed to parse bytes received from KISS interface.")
85
+ LOG.error('Failed to parse bytes received from KISS interface.')
82
86
  LOG.exception(ex)
83
87
 
84
88
  def consumer(self, callback):
85
- LOG.debug("Start blocking KISS consumer")
86
89
  self._parse_callback = callback
87
90
  self.kiss.read(callback=self.parse_frame, min_frames=None)
88
- LOG.debug(f"END blocking KISS consumer {self.kiss}")
89
91
 
90
92
  def send(self, packet):
91
93
  """Send an APRS Message object."""
@@ -94,24 +96,24 @@ class KISS3Client:
94
96
  path = self.path
95
97
  if isinstance(packet, core.Packet):
96
98
  packet.prepare()
97
- payload = packet.payload.encode("US-ASCII")
99
+ payload = packet.payload.encode('US-ASCII')
98
100
  if packet.path:
99
101
  path = packet.path
100
102
  else:
101
- msg_payload = f"{packet.raw}{{{str(packet.msgNo)}"
103
+ msg_payload = f'{packet.raw}{{{str(packet.msgNo)}'
102
104
  payload = (
103
- ":{:<9}:{}".format(
105
+ ':{:<9}:{}'.format(
104
106
  packet.to_call,
105
107
  msg_payload,
106
108
  )
107
- ).encode("US-ASCII")
109
+ ).encode('US-ASCII')
108
110
 
109
111
  LOG.debug(
110
112
  f"KISS Send '{payload}' TO '{packet.to_call}' From "
111
113
  f"'{packet.from_call}' with PATH '{path}'",
112
114
  )
113
115
  frame = Frame.ui(
114
- destination="APZ100",
116
+ destination='APZ100',
115
117
  source=packet.from_call,
116
118
  path=path,
117
119
  info=payload,
@@ -12,7 +12,7 @@ from aprsd.client.drivers import kiss
12
12
  from aprsd.packets import core
13
13
 
14
14
  CONF = cfg.CONF
15
- LOG = logging.getLogger("APRSD")
15
+ LOG = logging.getLogger('APRSD')
16
16
  LOGU = logger
17
17
 
18
18
 
@@ -27,15 +27,15 @@ class KISSClient(base.APRSClient):
27
27
  if serializable:
28
28
  keepalive = keepalive.isoformat()
29
29
  stats = {
30
- "connected": self.is_connected,
31
- "connection_keepalive": keepalive,
32
- "transport": self.transport(),
30
+ 'connected': self.is_connected,
31
+ 'connection_keepalive': keepalive,
32
+ 'transport': self.transport(),
33
33
  }
34
34
  if self.transport() == client.TRANSPORT_TCPKISS:
35
- stats["host"] = CONF.kiss_tcp.host
36
- stats["port"] = CONF.kiss_tcp.port
35
+ stats['host'] = CONF.kiss_tcp.host
36
+ stats['port'] = CONF.kiss_tcp.port
37
37
  elif self.transport() == client.TRANSPORT_SERIALKISS:
38
- stats["device"] = CONF.kiss_serial.device
38
+ stats['device'] = CONF.kiss_serial.device
39
39
  return stats
40
40
 
41
41
  @staticmethod
@@ -56,15 +56,15 @@ class KISSClient(base.APRSClient):
56
56
  transport = KISSClient.transport()
57
57
  if transport == client.TRANSPORT_SERIALKISS:
58
58
  if not CONF.kiss_serial.device:
59
- LOG.error("KISS serial enabled, but no device is set.")
59
+ LOG.error('KISS serial enabled, but no device is set.')
60
60
  raise exception.MissingConfigOptionException(
61
- "kiss_serial.device is not set.",
61
+ 'kiss_serial.device is not set.',
62
62
  )
63
63
  elif transport == client.TRANSPORT_TCPKISS:
64
64
  if not CONF.kiss_tcp.host:
65
- LOG.error("KISS TCP enabled, but no host is set.")
65
+ LOG.error('KISS TCP enabled, but no host is set.')
66
66
  raise exception.MissingConfigOptionException(
67
- "kiss_tcp.host is not set.",
67
+ 'kiss_tcp.host is not set.',
68
68
  )
69
69
 
70
70
  return True
@@ -91,8 +91,8 @@ class KISSClient(base.APRSClient):
91
91
  if ka := self._client.aprsd_keepalive:
92
92
  keepalive = timeago.format(ka)
93
93
  else:
94
- keepalive = "N/A"
95
- LOGU.opt(colors=True).info(f"<green>Client keepalive {keepalive}</green>")
94
+ keepalive = 'N/A'
95
+ LOGU.opt(colors=True).info(f'<green>Client keepalive {keepalive}</green>')
96
96
 
97
97
  @staticmethod
98
98
  def transport():
@@ -104,8 +104,8 @@ class KISSClient(base.APRSClient):
104
104
 
105
105
  def decode_packet(self, *args, **kwargs):
106
106
  """We get a frame, which has to be decoded."""
107
- LOG.debug(f"kwargs {kwargs}")
108
- frame = kwargs["frame"]
107
+ LOG.debug(f'kwargs {kwargs}')
108
+ frame = kwargs['frame']
109
109
  LOG.debug(f"Got an APRS Frame '{frame}'")
110
110
  # try and nuke the * from the fromcall sign.
111
111
  # frame.header._source._ch = False
@@ -114,20 +114,23 @@ class KISSClient(base.APRSClient):
114
114
  # msg = frame.tnc2
115
115
  # LOG.debug(f"Decoding {msg}")
116
116
 
117
- raw = aprslib.parse(str(frame))
118
- packet = core.factory(raw)
119
- if isinstance(packet, core.ThirdPartyPacket):
120
- return packet.subpacket
121
- else:
122
- return packet
117
+ try:
118
+ raw = aprslib.parse(str(frame))
119
+ packet = core.factory(raw)
120
+ if isinstance(packet, core.ThirdPartyPacket):
121
+ return packet.subpacket
122
+ else:
123
+ return packet
124
+ except Exception as ex:
125
+ LOG.error(f'Error decoding packet: {ex}')
123
126
 
124
127
  def setup_connection(self):
125
128
  try:
126
129
  self._client = kiss.KISS3Client()
127
- self.connected = self.login_status["success"] = True
130
+ self.connected = self.login_status['success'] = True
128
131
  except Exception as ex:
129
- self.connected = self.login_status["success"] = False
130
- self.login_status["message"] = str(ex)
132
+ self.connected = self.login_status['success'] = False
133
+ self.login_status['message'] = str(ex)
131
134
  return self._client
132
135
 
133
136
  def consumer(self, callback, blocking=False, immortal=False, raw=False):
@@ -135,5 +138,5 @@ class KISSClient(base.APRSClient):
135
138
  self._client.consumer(callback)
136
139
  self.keepalive = datetime.datetime.now()
137
140
  except Exception as ex:
138
- LOG.error(f"Consumer failed {ex}")
141
+ LOG.error(f'Consumer failed {ex}')
139
142
  LOG.error(ex)
@@ -5,24 +5,30 @@ import subprocess
5
5
  from aprsd import packets, plugin
6
6
  from aprsd.utils import trace
7
7
 
8
+ LOG = logging.getLogger('APRSD')
8
9
 
9
- LOG = logging.getLogger("APRSD")
10
-
11
- DEFAULT_FORTUNE_PATH = "/usr/games/fortune"
10
+ FORTUNE_PATHS = [
11
+ '/usr/games/fortune',
12
+ '/usr/local/bin/fortune',
13
+ '/usr/bin/fortune',
14
+ ]
12
15
 
13
16
 
14
17
  class FortunePlugin(plugin.APRSDRegexCommandPluginBase):
15
18
  """Fortune."""
16
19
 
17
- command_regex = r"^([f]|[f]\s|fortune)"
18
- command_name = "fortune"
19
- short_description = "Give me a fortune"
20
+ command_regex = r'^([f]|[f]\s|fortune)'
21
+ command_name = 'fortune'
22
+ short_description = 'Give me a fortune'
20
23
 
21
24
  fortune_path = None
22
25
 
23
26
  def setup(self):
24
- self.fortune_path = shutil.which(DEFAULT_FORTUNE_PATH)
25
- LOG.info(f"Fortune path {self.fortune_path}")
27
+ for path in FORTUNE_PATHS:
28
+ self.fortune_path = shutil.which(path)
29
+ LOG.info(f'Fortune path {self.fortune_path}')
30
+ if self.fortune_path:
31
+ break
26
32
  if not self.fortune_path:
27
33
  self.enabled = False
28
34
  else:
@@ -30,7 +36,7 @@ class FortunePlugin(plugin.APRSDRegexCommandPluginBase):
30
36
 
31
37
  @trace.trace
32
38
  def process(self, packet: packets.MessagePacket):
33
- LOG.info("FortunePlugin")
39
+ LOG.info('FortunePlugin')
34
40
 
35
41
  # fromcall = packet.get("from")
36
42
  # message = packet.get("message_text", None)
@@ -39,8 +45,8 @@ class FortunePlugin(plugin.APRSDRegexCommandPluginBase):
39
45
  reply = None
40
46
 
41
47
  try:
42
- cmnd = [self.fortune_path, "-s", "-n 60"]
43
- command = " ".join(cmnd)
48
+ cmnd = [self.fortune_path, '-s', '-n 60']
49
+ command = ' '.join(cmnd)
44
50
  output = subprocess.check_output(
45
51
  command,
46
52
  shell=True,
@@ -48,10 +54,10 @@ class FortunePlugin(plugin.APRSDRegexCommandPluginBase):
48
54
  text=True,
49
55
  )
50
56
  output = (
51
- output.replace("\r", "")
52
- .replace("\n", "")
53
- .replace(" ", "")
54
- .replace("\t", " ")
57
+ output.replace('\r', '')
58
+ .replace('\n', '')
59
+ .replace(' ', '')
60
+ .replace('\t', ' ')
55
61
  )
56
62
  except subprocess.CalledProcessError as ex:
57
63
  reply = f"Fortune command failed '{ex.output}'"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: aprsd
3
- Version: 4.0.1
3
+ Version: 4.0.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>
@@ -20,6 +20,7 @@ requirements.in
20
20
  requirements.txt
21
21
  setup.py
22
22
  tox.ini
23
+ uv.lock
23
24
  ./requirements-dev.txt
24
25
  ./requirements.txt
25
26
  .github/workflows/authors.yml
@@ -55,7 +55,8 @@ RUN if [ "$INSTALL_TYPE" = "pypi" ]; then \
55
55
  uv pip install aprsd==$APRSD_PIP_VERSION; \
56
56
  elif [ "$INSTALL_TYPE" = "github" ]; then \
57
57
  git clone -b $APRSD_BRANCH https://github.com/craigerl/aprsd; \
58
- cd /app/aprsd && uv pip install .; \
58
+ ls -al /app/aprsd; \
59
+ uv pip install /app/aprsd; \
59
60
  ls -al /app/.venv/lib/python3.11/site-packages/aprsd*; \
60
61
  fi
61
62
  # RUN uv pip install gevent uwsgi