1
0
mirror of https://github.com/craigerl/aprsd.git synced 2026-08-19 01:53:58 -04:00

Compare commits

...

11 Commits

Author SHA1 Message Date
hemna 000adef6d4 Prep for 4.0.2 2025-01-25 13:29:04 -05:00
hemna bea481555b update the install from github in Dockerfile 2025-01-25 13:06:53 -05:00
hemna 3c4e200d70 Fix the testing of fortune path 2025-01-25 12:54:18 -05:00
hemna 2f26eb86f4 Added uv.lock 2025-01-25 12:33:29 -05:00
hemna 97ffffc10d Look in multiple places for fortune bin
Update the fortune plugin to look in multiple places for the
fortune binary.  It lives in different places for debian vs alpine.
2025-01-25 12:32:15 -05:00
hemna c1319c3ab8 Removed some verbose output from KISS
This removes some overly verbose output from the KISS driver.
2025-01-25 12:31:27 -05:00
hemna 1f65bbe13a Pass branch in github release_build
Try and pass the build arg BRANCH along with the
building of the image.
2025-01-24 20:50:33 -05:00
hemna 9501a63bd6 Trap for failed parsing of packets on KISS
This adds a try block around the aprslib.parse() for packets incoming
on the KISS interface.  Often times we'll get invalid packets and
this prevents stack dumps to the log.
2025-01-24 17:44:58 -05:00
hemna edeba7f514 Fix for KISS/Fake client drivers
They were both missing a setting of aprsd_keepalive to test
for the logging of the keepalive last time called.
2025-01-24 17:28:59 -05:00
hemna 24f567224c Updated Changelog 2025-01-24 16:46:02 -05:00
hemna e08039431e Update pyproject for README.rst -> md
Updated the pyproject.toml to reflect the name change of
README.rst -> README.md
2025-01-24 16:43:52 -05:00
9 changed files with 1439 additions and 59 deletions
+3 -2
View File
@@ -6,7 +6,7 @@ on:
aprsd_version:
required: true
options:
- 3.0.0
- 4.0.0
logLevel:
description: 'Log level'
required: true
@@ -42,8 +42,9 @@ jobs:
file: ./Dockerfile
build-args: |
VERSION=${{ inputs.aprsd_version }}
BRANCH=${{ inputs.aprsd_version }}
BUILDX_QEMU_ENV=true
push: true
tags: |
hemna6969/aprsd:v${{ inputs.aprsd_version }}
hemna6969/aprsd:${{ inputs.aprsd_version }}
hemna6969/aprsd:latest
+22
View File
@@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file. Dates are d
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
#### [4.0.2](https://github.com/craigerl/aprsd/compare/4.0.1...4.0.2)
> 25 January 2025
- Fix for KISS/Fake client drivers [`edeba7f`](https://github.com/craigerl/aprsd/commit/edeba7f5141c3197a3ddff5fe45127894c861e07)
- Trap for failed parsing of packets on KISS [`9501a63`](https://github.com/craigerl/aprsd/commit/9501a63bd61a681daf9eb9e41704e31570b7b385)
- Pass branch in github release_build [`1f65bbe`](https://github.com/craigerl/aprsd/commit/1f65bbe13a33c1fffad650c87c949bbe844d27f6)
- Removed some verbose output from KISS [`c1319c3`](https://github.com/craigerl/aprsd/commit/c1319c3ab8822f24c0e3b2c74d151d4e13a0039a)
- Look in multiple places for fortune bin [`97ffffc`](https://github.com/craigerl/aprsd/commit/97ffffc10dd05bd785134877ddb94437cf9b7f97)
- Added uv.lock [`2f26eb8`](https://github.com/craigerl/aprsd/commit/2f26eb86f44625547f72f7c3612494b1bc44bc99)
- Fix the testing of fortune path [`3c4e200`](https://github.com/craigerl/aprsd/commit/3c4e200d700c24125479bb754b5f68bdf35b85a6)
- update the install from github in Dockerfile [`bea4815`](https://github.com/craigerl/aprsd/commit/bea481555bc1270ab371a22c69973d648e526d54)
#### [4.0.1](https://github.com/craigerl/aprsd/compare/4.0.0...4.0.1)
> 24 January 2025
- Update pyproject for README.rst -> md [`e080394`](https://github.com/craigerl/aprsd/commit/e08039431ebde92a162ab422c05391dc55d3d3fa)
- Updated Changelog [`24f5672`](https://github.com/craigerl/aprsd/commit/24f567224cf8ecdebd51f49804425565883acb94)
### [4.0.0](https://github.com/craigerl/aprsd/compare/3.4.4...4.0.0)
> 24 January 2025
@@ -51,6 +71,8 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
- reduced logo size 50% [`cf4a29f`](https://github.com/craigerl/aprsd/commit/cf4a29f0cb3ed366b21ec3120a189614e0955180)
- Updated README.md TOC [`375a5e5`](https://github.com/craigerl/aprsd/commit/375a5e5b34718cadc6ee8a51484fc91441440a61)
- chore: update AUTHORS [skip ci] [`c556f51`](https://github.com/craigerl/aprsd/commit/c556f5126f725904822a75427475d46986f8e9f3)
- Updated requirements [`4a7a902`](https://github.com/craigerl/aprsd/commit/4a7a902a337759a352560d4d92dc314b1726412a)
- Updated ChangeLog for 4.0.0 [`934ebd2`](https://github.com/craigerl/aprsd/commit/934ebd236d044625b911dd8ca45293f6c5680a68)
#### [3.4.4](https://github.com/craigerl/aprsd/compare/3.4.3...3.4.4)
+5
View File
@@ -1,3 +1,4 @@
import datetime
import logging
import threading
import time
@@ -20,6 +21,9 @@ class APRSDFakeClient(metaclass=trace.TraceWrapperMetaclass):
# flag to tell us to stop
thread_stop = False
# date for last time we heard from the server
aprsd_keepalive = datetime.datetime.now()
lock = threading.Lock()
path = []
@@ -63,6 +67,7 @@ class APRSDFakeClient(metaclass=trace.TraceWrapperMetaclass):
raw = 'GTOWN>APDW16,WIDE1-1,WIDE2-1:}KM6LYW-9>APZ100,TCPIP,GTOWN*::KM6LYW :KM6LYW: 19 Miles SW'
pkt_raw = aprslib.parse(raw)
pkt = core.factory(pkt_raw)
self.aprsd_keepalive = datetime.datetime.now()
callback(packet=pkt)
LOG.debug(f'END blocking FAKE consumer {self}')
time.sleep(8)
+17 -15
View File
@@ -1,21 +1,24 @@
import datetime
import logging
from ax253 import Frame
import kiss
from ax253 import Frame
from oslo_config import cfg
from aprsd import conf # noqa
from aprsd.packets import core
from aprsd.utils import trace
CONF = cfg.CONF
LOG = logging.getLogger("APRSD")
LOG = logging.getLogger('APRSD')
class KISS3Client:
path = []
# date for last time we heard from the server
aprsd_keepalive = datetime.datetime.now()
def __init__(self):
self.setup()
@@ -26,7 +29,7 @@ class KISS3Client:
# we can be TCP kiss or Serial kiss
if CONF.kiss_serial.enabled:
LOG.debug(
"KISS({}) Serial connection to {}".format(
'KISS({}) Serial connection to {}'.format(
kiss.__version__,
CONF.kiss_serial.device,
),
@@ -39,7 +42,7 @@ class KISS3Client:
self.path = CONF.kiss_serial.path
elif CONF.kiss_tcp.enabled:
LOG.debug(
"KISS({}) TCP Connection to {}:{}".format(
'KISS({}) TCP Connection to {}:{}'.format(
kiss.__version__,
CONF.kiss_tcp.host,
CONF.kiss_tcp.port,
@@ -52,7 +55,7 @@ class KISS3Client:
)
self.path = CONF.kiss_tcp.path
LOG.debug("Starting KISS interface connection")
LOG.debug('Starting KISS interface connection')
self.kiss.start()
@trace.trace
@@ -74,18 +77,17 @@ class KISS3Client:
frame = Frame.from_bytes(frame_bytes)
# Now parse it with aprslib
kwargs = {
"frame": frame,
'frame': frame,
}
self._parse_callback(**kwargs)
self.aprsd_keepalive = datetime.datetime.now()
except Exception as ex:
LOG.error("Failed to parse bytes received from KISS interface.")
LOG.error('Failed to parse bytes received from KISS interface.')
LOG.exception(ex)
def consumer(self, callback):
LOG.debug("Start blocking KISS consumer")
self._parse_callback = callback
self.kiss.read(callback=self.parse_frame, min_frames=None)
LOG.debug(f"END blocking KISS consumer {self.kiss}")
def send(self, packet):
"""Send an APRS Message object."""
@@ -94,24 +96,24 @@ class KISS3Client:
path = self.path
if isinstance(packet, core.Packet):
packet.prepare()
payload = packet.payload.encode("US-ASCII")
payload = packet.payload.encode('US-ASCII')
if packet.path:
path = packet.path
else:
msg_payload = f"{packet.raw}{{{str(packet.msgNo)}"
msg_payload = f'{packet.raw}{{{str(packet.msgNo)}'
payload = (
":{:<9}:{}".format(
':{:<9}:{}'.format(
packet.to_call,
msg_payload,
)
).encode("US-ASCII")
).encode('US-ASCII')
LOG.debug(
f"KISS Send '{payload}' TO '{packet.to_call}' From "
f"'{packet.from_call}' with PATH '{path}'",
)
frame = Frame.ui(
destination="APZ100",
destination='APZ100',
source=packet.from_call,
path=path,
info=payload,
+28 -25
View File
@@ -12,7 +12,7 @@ from aprsd.client.drivers import kiss
from aprsd.packets import core
CONF = cfg.CONF
LOG = logging.getLogger("APRSD")
LOG = logging.getLogger('APRSD')
LOGU = logger
@@ -27,15 +27,15 @@ class KISSClient(base.APRSClient):
if serializable:
keepalive = keepalive.isoformat()
stats = {
"connected": self.is_connected,
"connection_keepalive": keepalive,
"transport": self.transport(),
'connected': self.is_connected,
'connection_keepalive': keepalive,
'transport': self.transport(),
}
if self.transport() == client.TRANSPORT_TCPKISS:
stats["host"] = CONF.kiss_tcp.host
stats["port"] = CONF.kiss_tcp.port
stats['host'] = CONF.kiss_tcp.host
stats['port'] = CONF.kiss_tcp.port
elif self.transport() == client.TRANSPORT_SERIALKISS:
stats["device"] = CONF.kiss_serial.device
stats['device'] = CONF.kiss_serial.device
return stats
@staticmethod
@@ -56,15 +56,15 @@ class KISSClient(base.APRSClient):
transport = KISSClient.transport()
if transport == client.TRANSPORT_SERIALKISS:
if not CONF.kiss_serial.device:
LOG.error("KISS serial enabled, but no device is set.")
LOG.error('KISS serial enabled, but no device is set.')
raise exception.MissingConfigOptionException(
"kiss_serial.device is not set.",
'kiss_serial.device is not set.',
)
elif transport == client.TRANSPORT_TCPKISS:
if not CONF.kiss_tcp.host:
LOG.error("KISS TCP enabled, but no host is set.")
LOG.error('KISS TCP enabled, but no host is set.')
raise exception.MissingConfigOptionException(
"kiss_tcp.host is not set.",
'kiss_tcp.host is not set.',
)
return True
@@ -91,8 +91,8 @@ class KISSClient(base.APRSClient):
if ka := self._client.aprsd_keepalive:
keepalive = timeago.format(ka)
else:
keepalive = "N/A"
LOGU.opt(colors=True).info(f"<green>Client keepalive {keepalive}</green>")
keepalive = 'N/A'
LOGU.opt(colors=True).info(f'<green>Client keepalive {keepalive}</green>')
@staticmethod
def transport():
@@ -104,8 +104,8 @@ class KISSClient(base.APRSClient):
def decode_packet(self, *args, **kwargs):
"""We get a frame, which has to be decoded."""
LOG.debug(f"kwargs {kwargs}")
frame = kwargs["frame"]
LOG.debug(f'kwargs {kwargs}')
frame = kwargs['frame']
LOG.debug(f"Got an APRS Frame '{frame}'")
# try and nuke the * from the fromcall sign.
# frame.header._source._ch = False
@@ -114,20 +114,23 @@ class KISSClient(base.APRSClient):
# msg = frame.tnc2
# LOG.debug(f"Decoding {msg}")
raw = aprslib.parse(str(frame))
packet = core.factory(raw)
if isinstance(packet, core.ThirdPartyPacket):
return packet.subpacket
else:
return packet
try:
raw = aprslib.parse(str(frame))
packet = core.factory(raw)
if isinstance(packet, core.ThirdPartyPacket):
return packet.subpacket
else:
return packet
except Exception as ex:
LOG.error(f'Error decoding packet: {ex}')
def setup_connection(self):
try:
self._client = kiss.KISS3Client()
self.connected = self.login_status["success"] = True
self.connected = self.login_status['success'] = True
except Exception as ex:
self.connected = self.login_status["success"] = False
self.login_status["message"] = str(ex)
self.connected = self.login_status['success'] = False
self.login_status['message'] = str(ex)
return self._client
def consumer(self, callback, blocking=False, immortal=False, raw=False):
@@ -135,5 +138,5 @@ class KISSClient(base.APRSClient):
self._client.consumer(callback)
self.keepalive = datetime.datetime.now()
except Exception as ex:
LOG.error(f"Consumer failed {ex}")
LOG.error(f'Consumer failed {ex}')
LOG.error(ex)
+21 -15
View File
@@ -5,24 +5,30 @@ import subprocess
from aprsd import packets, plugin
from aprsd.utils import trace
LOG = logging.getLogger('APRSD')
LOG = logging.getLogger("APRSD")
DEFAULT_FORTUNE_PATH = "/usr/games/fortune"
FORTUNE_PATHS = [
'/usr/games/fortune',
'/usr/local/bin/fortune',
'/usr/bin/fortune',
]
class FortunePlugin(plugin.APRSDRegexCommandPluginBase):
"""Fortune."""
command_regex = r"^([f]|[f]\s|fortune)"
command_name = "fortune"
short_description = "Give me a fortune"
command_regex = r'^([f]|[f]\s|fortune)'
command_name = 'fortune'
short_description = 'Give me a fortune'
fortune_path = None
def setup(self):
self.fortune_path = shutil.which(DEFAULT_FORTUNE_PATH)
LOG.info(f"Fortune path {self.fortune_path}")
for path in FORTUNE_PATHS:
self.fortune_path = shutil.which(path)
LOG.info(f'Fortune path {self.fortune_path}')
if self.fortune_path:
break
if not self.fortune_path:
self.enabled = False
else:
@@ -30,7 +36,7 @@ class FortunePlugin(plugin.APRSDRegexCommandPluginBase):
@trace.trace
def process(self, packet: packets.MessagePacket):
LOG.info("FortunePlugin")
LOG.info('FortunePlugin')
# fromcall = packet.get("from")
# message = packet.get("message_text", None)
@@ -39,8 +45,8 @@ class FortunePlugin(plugin.APRSDRegexCommandPluginBase):
reply = None
try:
cmnd = [self.fortune_path, "-s", "-n 60"]
command = " ".join(cmnd)
cmnd = [self.fortune_path, '-s', '-n 60']
command = ' '.join(cmnd)
output = subprocess.check_output(
command,
shell=True,
@@ -48,10 +54,10 @@ class FortunePlugin(plugin.APRSDRegexCommandPluginBase):
text=True,
)
output = (
output.replace("\r", "")
.replace("\n", "")
.replace(" ", "")
.replace("\t", " ")
output.replace('\r', '')
.replace('\n', '')
.replace(' ', '')
.replace('\t', ' ')
)
except subprocess.CalledProcessError as ex:
reply = f"Fortune command failed '{ex.output}'"
+2 -1
View File
@@ -55,7 +55,8 @@ RUN if [ "$INSTALL_TYPE" = "pypi" ]; then \
uv pip install aprsd==$APRSD_PIP_VERSION; \
elif [ "$INSTALL_TYPE" = "github" ]; then \
git clone -b $APRSD_BRANCH https://github.com/craigerl/aprsd; \
cd /app/aprsd && uv pip install .; \
ls -al /app/aprsd; \
uv pip install /app/aprsd; \
ls -al /app/.venv/lib/python3.11/site-packages/aprsd*; \
fi
# RUN uv pip install gevent uwsgi
+1 -1
View File
@@ -30,7 +30,7 @@ dynamic = ["version", "dependencies", "optional-dependencies"]
#
# This field corresponds to the "Description" metadata field:
# https://packaging.python.org/specifications/core-metadata/#description-optional
readme = {file = "README.rst", content-type = "text/x-rst"}
readme = {file = "README.md", content-type = "text/markdown"}
# This is either text indicating the license for the distribution, or a file
Generated
+1340
View File
File diff suppressed because it is too large Load Diff