1
0
mirror of https://github.com/craigerl/aprsd.git synced 2026-08-18 17:44:02 -04:00

Compare commits

..

20 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
hemna 934ebd236d Updated ChangeLog for 4.0.0 2025-01-24 16:38:30 -05:00
hemna 4a7a902a33 Updated requirements 2025-01-24 16:35:20 -05:00
github-actions[bot] c556f5126f chore: update AUTHORS [skip ci] 2025-01-24 21:32:14 +00:00
hemna 7e4d4b3e80 Merge pull request #183 from craigerl/refactor-extraction
Migrate admin web out of aprsd.
2025-01-24 13:32:03 -08:00
hemna 375a5e5b34 Updated README.md TOC
Updated the table of contents
2025-01-24 16:23:42 -05:00
hemna cf4a29f0cb reduced logo size 50% 2025-01-23 08:55:06 -05:00
hemna 447451c6c9 Added plugin and extension links
This patch updates the README.md file to link to existing plugins
and extensions.
2025-01-23 08:51:23 -05:00
hemna 0ed648f8f8 Added APRSD logo 2025-01-23 08:23:38 -05:00
hemna e5d8796cda Enable packet stats for listen command in Docker
Update the docker listen.sh to enable tracking packet stats.
2024-12-12 08:59:28 -05:00
15 changed files with 1561 additions and 109 deletions
+3 -2
View File
@@ -6,7 +6,7 @@ on:
aprsd_version: aprsd_version:
required: true required: true
options: options:
- 3.0.0 - 4.0.0
logLevel: logLevel:
description: 'Log level' description: 'Log level'
required: true required: true
@@ -42,8 +42,9 @@ jobs:
file: ./Dockerfile file: ./Dockerfile
build-args: | build-args: |
VERSION=${{ inputs.aprsd_version }} VERSION=${{ inputs.aprsd_version }}
BRANCH=${{ inputs.aprsd_version }}
BUILDX_QEMU_ENV=true BUILDX_QEMU_ENV=true
push: true push: true
tags: | tags: |
hemna6969/aprsd:v${{ inputs.aprsd_version }} hemna6969/aprsd:${{ inputs.aprsd_version }}
hemna6969/aprsd:latest hemna6969/aprsd:latest
+1
View File
@@ -0,0 +1 @@
waboring@hemna.com : 1
+71
View File
@@ -4,6 +4,76 @@ 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). 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
- Migrate admin web out of aprsd. [`#183`](https://github.com/craigerl/aprsd/pull/183)
- Remove webchat as a built in command. [`8f8887f`](https://github.com/craigerl/aprsd/commit/8f8887f0e496d960b0e71275893b75408a40fdb2)
- Remove email plugin [`0880a35`](https://github.com/craigerl/aprsd/commit/0880a356e6df1a0924cbf6e815e68cba5f5c6cf1)
- Fixed make clean [`ae28dbb`](https://github.com/craigerl/aprsd/commit/ae28dbb0e6bc216bf78c0bd9d7804f57b39091d1)
- removed email reference [`fcd1629`](https://github.com/craigerl/aprsd/commit/fcd1629fdebb485fc763e19d73bfdafc10de6251)
- Removed more email references. [`f0c0260`](https://github.com/craigerl/aprsd/commit/f0c02606ebfc5170b80b55c73de191d27a8778a0)
- Removed LocationPlugin from aprsd core [`3bba8a1`](https://github.com/craigerl/aprsd/commit/3bba8a19da88b0912064cea786bc9f8203038946)
- Include haversine library [`bbdbb9a`](https://github.com/craigerl/aprsd/commit/bbdbb9aba189d536497ea3cd7d30911fe3d9d706)
- Update Makefile [`caa4bb8`](https://github.com/craigerl/aprsd/commit/caa4bb8bd01cbd2e02024d75e1c8af97acf6c657)
- Enable packet stats for listen command in Docker [`e5d8796`](https://github.com/craigerl/aprsd/commit/e5d8796cda1a007aa868c760b96b50b364351519)
- Added new KeepAliveCollector [`30d1eb5`](https://github.com/craigerl/aprsd/commit/30d1eb57dd249c609f5b092d8084c40cadda7bd9)
- Changed to ruff [`72d068c`](https://github.com/craigerl/aprsd/commit/72d068c0b8944c8c9eed494fc23de8d7179ee09b)
- Changed README.rst -> README.md [`b1a830d`](https://github.com/craigerl/aprsd/commit/b1a830d54e9dec473074b34f9566f161bdec0030)
- fixed list-plugins [`ec1adf4`](https://github.com/craigerl/aprsd/commit/ec1adf418203fc7d1a8fb175a075c73fa27d772b)
- Updated README.md [`fd74405`](https://github.com/craigerl/aprsd/commit/fd74405b5fb2ec3d0b432e95d715a8934d76dcd8)
- updated workflow [`df14eb8`](https://github.com/craigerl/aprsd/commit/df14eb8f288aa8cd8cab9b9263ca64093bb63c34)
- Some cleanup with list plugins [`5274c5d`](https://github.com/craigerl/aprsd/commit/5274c5dc563b40f87436378558ad843517be6939)
- Updated README.md [`275e335`](https://github.com/craigerl/aprsd/commit/275e33538db7f014eeb02deddd76bfbb63516871)
- removed BeautifulSoup usage [`a21432f`](https://github.com/craigerl/aprsd/commit/a21432fb249577489795e8a9f5d969b63c2af716)
- updated github workflows [`e3a7e7f`](https://github.com/craigerl/aprsd/commit/e3a7e7fb8a8448f7893fbe3f8cf7e876a5e2ff58)
- updated requirements-dev [`fbec716`](https://github.com/craigerl/aprsd/commit/fbec7168eb37621c0f3ca54274148704c857f506)
- updated requirements [`7f2c1d7`](https://github.com/craigerl/aprsd/commit/7f2c1d712417b55cd3535888d18d41c6a00e4d07)
- updated plugin example [`0073865`](https://github.com/craigerl/aprsd/commit/007386505ab539200b8eef438250bc73dac0079f)
- updated docs rst files [`3cd9bfa`](https://github.com/craigerl/aprsd/commit/3cd9bfa7bb79fb2ebaad7d921c7d9fd2128392f3)
- added authors.yml [`c8735c2`](https://github.com/craigerl/aprsd/commit/c8735c257a32b31974508c2ed9c1cdc8848b5150)
- updated action versions [`7702d68`](https://github.com/craigerl/aprsd/commit/7702d68cf722746952b94782ac4ed5cba935d53b)
- update to py 3.10 [`3ee422b`](https://github.com/craigerl/aprsd/commit/3ee422b5c9f79e9ee2d757abd1de9b9f2d0fc52e)
- Added .mailmap [`8d98546`](https://github.com/craigerl/aprsd/commit/8d9854605584fa35117af888fe219df610fb7cb4)
- updated tools in pre-commit [`e4f82d6`](https://github.com/craigerl/aprsd/commit/e4f82d6054d4d859023423bccdd5c402d7a83494)
- some cleanup [`e332d7c`](https://github.com/craigerl/aprsd/commit/e332d7c9d046066e2686ea0522ae06b86d2f162d)
- Added activity to README [`cdd297c`](https://github.com/craigerl/aprsd/commit/cdd297c5bbc8b93f4739f5850a3e5971ce8baeba)
- Added star history to readme [`02e2940`](https://github.com/craigerl/aprsd/commit/02e29405ce2f8310e4f87f68498dfd6575c2e43b)
- removed pytest from README [`1cba31f`](https://github.com/craigerl/aprsd/commit/1cba31f0ac9bd5ee532721a909fc752f023f3b06)
- Updated Docker for using alpine and uv [`24db814`](https://github.com/craigerl/aprsd/commit/24db814c82c9bb6634566d7428603bf7a9ae37d1)
- Update the admin and setup.sh for container [`044ea4c`](https://github.com/craigerl/aprsd/commit/044ea4cc9a0059101851d6e722e986ee236833e8)
- added healthcheck.sh [`1054999`](https://github.com/craigerl/aprsd/commit/10549995686b08e4c166f780efdec5bdae496cab)
- updated healthcheck.sh [`dabb48c`](https://github.com/craigerl/aprsd/commit/dabb48c6f64062c1fed8f83a4f0b8ffba0c206a5)
- try making image for webchat [`ba8acdc`](https://github.com/craigerl/aprsd/commit/ba8acdc5849fc7b2d8a1ee11af6f5e317cf30f45)
- Added APRSD logo [`0ed648f`](https://github.com/craigerl/aprsd/commit/0ed648f8f8a961dbbd9e22bcebadcde525ee41ae)
- Added plugin and extension links [`447451c`](https://github.com/craigerl/aprsd/commit/447451c6c97e1f2d3d0bf580db21ecd176690258)
- 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) #### [3.4.4](https://github.com/craigerl/aprsd/compare/3.4.3...3.4.4)
> 6 December 2024 > 6 December 2024
@@ -67,6 +137,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
- Update requirements.dev [`0d8a1ac`](https://github.com/craigerl/aprsd/commit/0d8a1ac33441cf85270423b80264110fe9286754) - Update requirements.dev [`0d8a1ac`](https://github.com/craigerl/aprsd/commit/0d8a1ac33441cf85270423b80264110fe9286754)
- Added new acked property to the core Packet [`3c058f3`](https://github.com/craigerl/aprsd/commit/3c058f3e7b89227c613234f8ae91687fbdf19ae1) - Added new acked property to the core Packet [`3c058f3`](https://github.com/craigerl/aprsd/commit/3c058f3e7b89227c613234f8ae91687fbdf19ae1)
- Fixed some pep8 failures [`63bcd41`](https://github.com/craigerl/aprsd/commit/63bcd4139bb40718152b66002dfa45f236c54e11) - Fixed some pep8 failures [`63bcd41`](https://github.com/craigerl/aprsd/commit/63bcd4139bb40718152b66002dfa45f236c54e11)
- Update Changelog for 3.4.4 [`bc709b3`](https://github.com/craigerl/aprsd/commit/bc709b377c423412e9093e8ecc78e561031023b8)
#### [3.4.3](https://github.com/craigerl/aprsd/compare/v3.4.3...3.4.3) #### [3.4.3](https://github.com/craigerl/aprsd/compare/v3.4.3...3.4.3)
+60 -38
View File
@@ -1,4 +1,4 @@
# APRSD - Ham radio APRS-IS Message plugin server # APRSD - Ham radio APRS-IS Message platform software
## KM6LYW and WB4BOR ## KM6LYW and WB4BOR
@@ -11,42 +11,39 @@
[![down](https://static.pepy.tech/personalized-badge/aprsd?period=month&units=international_system&left_color=black&right_color=orange&left_text=Downloads)](https://pepy.tech/project/aprsd) [![down](https://static.pepy.tech/personalized-badge/aprsd?period=month&units=international_system&left_color=black&right_color=orange&left_text=Downloads)](https://pepy.tech/project/aprsd)
[APRSD](http://github.com/craigerl/aprsd) is a Ham radio [APRSD](http://github.com/craigerl/aprsd) is a Ham radio
[APRS](http://aprs.org) message command gateway built on python. [APRS](http://aprs.org) message platform built with python.
### Table of Contents ![image](./aprsd_logo.png)
1. [What is APRSD](#what-is-aprsd) # Table of Contents
2. [APRSD Overview Diagram](#aprsd-overview-diagram)
3. [Typical Use Case](#typical-use-case) 1. [APRSD - Ham radio APRS-IS Message platform software](#aprsd---ham-radio-aprs-is-message-platform-software)
4. [Installation](#installation) 2. [What is APRSD](#what-is-aprsd)
5. [Example Usage](#example-usage) 3. [APRSD Plugins/Extensions](#aprsd-pluginsextensions)
6. [Help](#help) 4. [List of existing plugins - APRS Message processing/responders](#list-of-existing-plugins---aprs-message-processingresponders)
7. [Commands](#commands) 5. [List of existing extensions - Add new capabilities to APRSD](#list-of-existing-extensions---add-new-capabilities-to-aprsd)
- [Configuration](#configuration) 6. [APRSD Overview Diagram](#aprsd-overview-diagram)
- [Server](#server) 7. [Typical use case](#typical-use-case)
- [Current List of Built-in 8. [Installation](#installation)
Plugins](#current-list-of-built-in-plugins) 9. [Example usage](#example-usage)
- [Pypi.org APRSD Installable Plugin 10. [Help](#help)
Packages](#pypiorg-aprsd-installable-plugin-packages) 11. [Commands](#commands)
- [🐍 APRSD Installed 3rd Party 12. [Configuration](#configuration)
Plugins](#aprsd-installed-3rd-party-plugins) 13. [server](#server)
- [Send Message](#send-message) 14. [Current list plugins](#current-list-plugins)
- [Send Email (Radio to SMTP 15. [Current list extensions](#current-list-extensions)
Server)](#send-email-radio-to-smtp-server) 16. [send-message](#send-message)
- [Receive Email (IMAP Server to 17. [Development](#development)
Radio)](#receive-email-imap-server-to-radio) 18. [Release](#release)
- [Location](#location) 19. [Building your own APRSD plugins](#building-your-own-aprsd-plugins)
- [Web Admin Interface](#web-admin-interface) 20. [Overview](#overview)
8. [Development](#development) 21. [Docker Container](#docker-container)
- [Building Your Own APRSD 22. [Building](#building)
Plugins](#building-your-own-aprsd-plugins) 23. [Official Build](#official-build)
9. [Workflow](#workflow) 24. [Development Build](#development-build)
10. [Release](#release) 25. [Running the container](#running-the-container)
11. [Docker Container](#docker-container) 26. [Activity](#activity)
- [Building](#building-1) 27. [Star History](#star-history)
- [Official Build](#official-build)
- [Development Build](#development-build)
- [Running the Container](#running-the-container)
--- ---
@@ -58,7 +55,7 @@
### What is APRSD ### What is APRSD
APRSD is a python application for interacting with the APRS network and APRSD is a python application for interacting with the APRS network and Ham radios with KISS interfaces and
providing APRS services for HAM radio operators. providing APRS services for HAM radio operators.
APRSD currently has 4 main commands to use. APRSD currently has 4 main commands to use.
@@ -75,7 +72,7 @@ APRSD currently has 4 main commands to use.
Each of those commands can connect to the APRS-IS network if internet Each of those commands can connect to the APRS-IS network if internet
connectivity is available. If internet is not available, then APRS can connectivity is available. If internet is not available, then APRS can
be configured to talk to a TCP KISS TNC for radio connectivity. be configured to talk to a TCP KISS TNC for radio connectivity directly.
Please [read the docs](https://aprsd.readthedocs.io) to learn more! Please [read the docs](https://aprsd.readthedocs.io) to learn more!
@@ -87,12 +84,37 @@ APRSD Has the ability to add plugins and extensions. Plugins add new message fi
You can see the [available plugins/extensions on pypi here:](https://pypi.org/search/?q=aprsd) [https://pypi.org/search/?q=aprsd](https://pypi.org/search/?q=aprsd) You can see the [available plugins/extensions on pypi here:](https://pypi.org/search/?q=aprsd) [https://pypi.org/search/?q=aprsd](https://pypi.org/search/?q=aprsd)
> [!NOTE] > [!NOTE]
> aprsd admin and webchat have been extracted into separate extensions. > aprsd admin and webchat commands have been extracted into separate extensions.
* [See admin extension here](https://github.com/hemna/aprsd-admin-extension) <div id="admin logo" align="left"><img src="https://raw.githubusercontent.com/hemna/aprsd-admin-extension/refs/heads/master/screenshot.png" alt="Web Admin" width="340"/></div> * [See admin extension here](https://github.com/hemna/aprsd-admin-extension) <div id="admin logo" align="left"><img src="https://raw.githubusercontent.com/hemna/aprsd-admin-extension/refs/heads/master/screenshot.png" alt="Web Admin" width="340"/></div>
* [See webchat extension here](https://github.com/hemna/aprsd-webchat-extension) <div id="webchat logo" align="left"><img src="https://raw.githubusercontent.com/hemna/aprsd-webchat-extension/master/screenshot.png" alt="Webchat" width="340"/></div> * [See webchat extension here](https://github.com/hemna/aprsd-webchat-extension) <div id="webchat logo" align="left"><img src="https://raw.githubusercontent.com/hemna/aprsd-webchat-extension/master/screenshot.png" alt="Webchat" width="340"/></div>
### List of existing plugins - APRS Message processing/responders
- [aprsd-email-plugin](https://github.com/hemna/aprsd-email-plugin) - send/receive email!
- [aprsd-location-plugin](https://github.com/hemna/aprsd-location-plugin) - get latest GPS location.
- [aprsd-locationdata-plugin](https://github.com/hemna/aprsd-locationdata-plugin) - get latest GPS location
- [aprsd-digipi-plugin](https://github.com/hemna/aprsd-digipi-plugin) - Look for digipi beacon packets
- [aprsd-w3w-plugin](https://github.com/hemna/aprsd-w3w-plugin) - get your w3w coordinates
- [aprsd-mqtt-plugin](https://github.com/hemna/aprsd-mqtt-plugin) - send aprs packets to an MQTT topic
- [aprsd-telegram-plugin](https://github.com/hemna/aprsd-telegram-plugin) - send/receive messages to telegram
- [aprsd-borat-plugin](https://github.com/hemna/aprsd-borat-plugin) - get Borat quotes
- [aprsd-wxnow-plugin](https://github.com/hemna/aprsd-wxnow-plugin) - get closest N weather station reports
- [aprsd-weewx-plugin](https://github.com/hemna/aprsd-weewx-plugin) - get weather from your weewx weather station
- [aprsd-slack-plugin](https://github.com/hemna/aprsd-slack-plugin) - send/receive messages to a slack channel
- [aprsd-sentry-plugin](https://github.com/hemna/aprsd-sentry-plugin) -
- [aprsd-repeat-plugins](https://github.com/hemna/aprsd-repeat-plugins) - plugins for the REPEAT service. Get nearest Ham radio repeaters!
- [aprsd-twitter-plugin](https://github.com/hemna/aprsd-twitter-plugin) - make tweets from your Ham Radio!
- [aprsd-timeopencage-plugin](https://github.com/hemna/aprsd-timeopencage-plugin) - Get local time for a callsign
- [aprsd-stock-plugin](https://github.com/hemna/aprsd-stock-plugin) - get stock quotes from your Ham radio
### List of existing extensions - Add new capabilities to APRSD
- [aprsd-admin-extension](https://github.com/hemna/aprsd-admin-extension) - Web Administration page for APRSD
- [aprsd-webchat-extension](https://github.com/hemna/aprsd-webchat-extension) - Web page for APRS Messaging
- [aprsd-irc-extension](https://github.com/hemna/aprsd-irc-extension) - an IRC like server command for APRS
### APRSD Overview Diagram ### APRSD Overview Diagram
![image](https://raw.githubusercontent.com/craigerl/aprsd/master/docs/_static/aprsd_overview.svg?sanitize=true) ![image](https://raw.githubusercontent.com/craigerl/aprsd/master/docs/_static/aprsd_overview.svg?sanitize=true)
+5
View File
@@ -1,3 +1,4 @@
import datetime
import logging import logging
import threading import threading
import time import time
@@ -20,6 +21,9 @@ class APRSDFakeClient(metaclass=trace.TraceWrapperMetaclass):
# flag to tell us to stop # flag to tell us to stop
thread_stop = False thread_stop = False
# date for last time we heard from the server
aprsd_keepalive = datetime.datetime.now()
lock = threading.Lock() lock = threading.Lock()
path = [] 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' raw = 'GTOWN>APDW16,WIDE1-1,WIDE2-1:}KM6LYW-9>APZ100,TCPIP,GTOWN*::KM6LYW :KM6LYW: 19 Miles SW'
pkt_raw = aprslib.parse(raw) pkt_raw = aprslib.parse(raw)
pkt = core.factory(pkt_raw) pkt = core.factory(pkt_raw)
self.aprsd_keepalive = datetime.datetime.now()
callback(packet=pkt) callback(packet=pkt)
LOG.debug(f'END blocking FAKE consumer {self}') LOG.debug(f'END blocking FAKE consumer {self}')
time.sleep(8) time.sleep(8)
+17 -15
View File
@@ -1,21 +1,24 @@
import datetime
import logging import logging
from ax253 import Frame
import kiss import kiss
from ax253 import Frame
from oslo_config import cfg from oslo_config import cfg
from aprsd import conf # noqa from aprsd import conf # noqa
from aprsd.packets import core from aprsd.packets import core
from aprsd.utils import trace from aprsd.utils import trace
CONF = cfg.CONF CONF = cfg.CONF
LOG = logging.getLogger("APRSD") LOG = logging.getLogger('APRSD')
class KISS3Client: class KISS3Client:
path = [] path = []
# date for last time we heard from the server
aprsd_keepalive = datetime.datetime.now()
def __init__(self): def __init__(self):
self.setup() self.setup()
@@ -26,7 +29,7 @@ class KISS3Client:
# we can be TCP kiss or Serial kiss # we can be TCP kiss or Serial kiss
if CONF.kiss_serial.enabled: if CONF.kiss_serial.enabled:
LOG.debug( LOG.debug(
"KISS({}) Serial connection to {}".format( 'KISS({}) Serial connection to {}'.format(
kiss.__version__, kiss.__version__,
CONF.kiss_serial.device, CONF.kiss_serial.device,
), ),
@@ -39,7 +42,7 @@ class KISS3Client:
self.path = CONF.kiss_serial.path self.path = CONF.kiss_serial.path
elif CONF.kiss_tcp.enabled: elif CONF.kiss_tcp.enabled:
LOG.debug( LOG.debug(
"KISS({}) TCP Connection to {}:{}".format( 'KISS({}) TCP Connection to {}:{}'.format(
kiss.__version__, kiss.__version__,
CONF.kiss_tcp.host, CONF.kiss_tcp.host,
CONF.kiss_tcp.port, CONF.kiss_tcp.port,
@@ -52,7 +55,7 @@ class KISS3Client:
) )
self.path = CONF.kiss_tcp.path self.path = CONF.kiss_tcp.path
LOG.debug("Starting KISS interface connection") LOG.debug('Starting KISS interface connection')
self.kiss.start() self.kiss.start()
@trace.trace @trace.trace
@@ -74,18 +77,17 @@ class KISS3Client:
frame = Frame.from_bytes(frame_bytes) frame = Frame.from_bytes(frame_bytes)
# Now parse it with aprslib # Now parse it with aprslib
kwargs = { kwargs = {
"frame": frame, 'frame': frame,
} }
self._parse_callback(**kwargs) self._parse_callback(**kwargs)
self.aprsd_keepalive = datetime.datetime.now()
except Exception as ex: 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) LOG.exception(ex)
def consumer(self, callback): def consumer(self, callback):
LOG.debug("Start blocking KISS consumer")
self._parse_callback = callback self._parse_callback = callback
self.kiss.read(callback=self.parse_frame, min_frames=None) self.kiss.read(callback=self.parse_frame, min_frames=None)
LOG.debug(f"END blocking KISS consumer {self.kiss}")
def send(self, packet): def send(self, packet):
"""Send an APRS Message object.""" """Send an APRS Message object."""
@@ -94,24 +96,24 @@ class KISS3Client:
path = self.path path = self.path
if isinstance(packet, core.Packet): if isinstance(packet, core.Packet):
packet.prepare() packet.prepare()
payload = packet.payload.encode("US-ASCII") payload = packet.payload.encode('US-ASCII')
if packet.path: if packet.path:
path = packet.path path = packet.path
else: else:
msg_payload = f"{packet.raw}{{{str(packet.msgNo)}" msg_payload = f'{packet.raw}{{{str(packet.msgNo)}'
payload = ( payload = (
":{:<9}:{}".format( ':{:<9}:{}'.format(
packet.to_call, packet.to_call,
msg_payload, msg_payload,
) )
).encode("US-ASCII") ).encode('US-ASCII')
LOG.debug( LOG.debug(
f"KISS Send '{payload}' TO '{packet.to_call}' From " f"KISS Send '{payload}' TO '{packet.to_call}' From "
f"'{packet.from_call}' with PATH '{path}'", f"'{packet.from_call}' with PATH '{path}'",
) )
frame = Frame.ui( frame = Frame.ui(
destination="APZ100", destination='APZ100',
source=packet.from_call, source=packet.from_call,
path=path, path=path,
info=payload, info=payload,
+28 -25
View File
@@ -12,7 +12,7 @@ from aprsd.client.drivers import kiss
from aprsd.packets import core from aprsd.packets import core
CONF = cfg.CONF CONF = cfg.CONF
LOG = logging.getLogger("APRSD") LOG = logging.getLogger('APRSD')
LOGU = logger LOGU = logger
@@ -27,15 +27,15 @@ class KISSClient(base.APRSClient):
if serializable: if serializable:
keepalive = keepalive.isoformat() keepalive = keepalive.isoformat()
stats = { stats = {
"connected": self.is_connected, 'connected': self.is_connected,
"connection_keepalive": keepalive, 'connection_keepalive': keepalive,
"transport": self.transport(), 'transport': self.transport(),
} }
if self.transport() == client.TRANSPORT_TCPKISS: if self.transport() == client.TRANSPORT_TCPKISS:
stats["host"] = CONF.kiss_tcp.host stats['host'] = CONF.kiss_tcp.host
stats["port"] = CONF.kiss_tcp.port stats['port'] = CONF.kiss_tcp.port
elif self.transport() == client.TRANSPORT_SERIALKISS: elif self.transport() == client.TRANSPORT_SERIALKISS:
stats["device"] = CONF.kiss_serial.device stats['device'] = CONF.kiss_serial.device
return stats return stats
@staticmethod @staticmethod
@@ -56,15 +56,15 @@ class KISSClient(base.APRSClient):
transport = KISSClient.transport() transport = KISSClient.transport()
if transport == client.TRANSPORT_SERIALKISS: if transport == client.TRANSPORT_SERIALKISS:
if not CONF.kiss_serial.device: 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( raise exception.MissingConfigOptionException(
"kiss_serial.device is not set.", 'kiss_serial.device is not set.',
) )
elif transport == client.TRANSPORT_TCPKISS: elif transport == client.TRANSPORT_TCPKISS:
if not CONF.kiss_tcp.host: 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( raise exception.MissingConfigOptionException(
"kiss_tcp.host is not set.", 'kiss_tcp.host is not set.',
) )
return True return True
@@ -91,8 +91,8 @@ class KISSClient(base.APRSClient):
if ka := self._client.aprsd_keepalive: if ka := self._client.aprsd_keepalive:
keepalive = timeago.format(ka) keepalive = timeago.format(ka)
else: else:
keepalive = "N/A" keepalive = 'N/A'
LOGU.opt(colors=True).info(f"<green>Client keepalive {keepalive}</green>") LOGU.opt(colors=True).info(f'<green>Client keepalive {keepalive}</green>')
@staticmethod @staticmethod
def transport(): def transport():
@@ -104,8 +104,8 @@ class KISSClient(base.APRSClient):
def decode_packet(self, *args, **kwargs): def decode_packet(self, *args, **kwargs):
"""We get a frame, which has to be decoded.""" """We get a frame, which has to be decoded."""
LOG.debug(f"kwargs {kwargs}") LOG.debug(f'kwargs {kwargs}')
frame = kwargs["frame"] frame = kwargs['frame']
LOG.debug(f"Got an APRS Frame '{frame}'") LOG.debug(f"Got an APRS Frame '{frame}'")
# try and nuke the * from the fromcall sign. # try and nuke the * from the fromcall sign.
# frame.header._source._ch = False # frame.header._source._ch = False
@@ -114,20 +114,23 @@ class KISSClient(base.APRSClient):
# msg = frame.tnc2 # msg = frame.tnc2
# LOG.debug(f"Decoding {msg}") # LOG.debug(f"Decoding {msg}")
raw = aprslib.parse(str(frame)) try:
packet = core.factory(raw) raw = aprslib.parse(str(frame))
if isinstance(packet, core.ThirdPartyPacket): packet = core.factory(raw)
return packet.subpacket if isinstance(packet, core.ThirdPartyPacket):
else: return packet.subpacket
return packet else:
return packet
except Exception as ex:
LOG.error(f'Error decoding packet: {ex}')
def setup_connection(self): def setup_connection(self):
try: try:
self._client = kiss.KISS3Client() self._client = kiss.KISS3Client()
self.connected = self.login_status["success"] = True self.connected = self.login_status['success'] = True
except Exception as ex: except Exception as ex:
self.connected = self.login_status["success"] = False self.connected = self.login_status['success'] = False
self.login_status["message"] = str(ex) self.login_status['message'] = str(ex)
return self._client return self._client
def consumer(self, callback, blocking=False, immortal=False, raw=False): def consumer(self, callback, blocking=False, immortal=False, raw=False):
@@ -135,5 +138,5 @@ class KISSClient(base.APRSClient):
self._client.consumer(callback) self._client.consumer(callback)
self.keepalive = datetime.datetime.now() self.keepalive = datetime.datetime.now()
except Exception as ex: except Exception as ex:
LOG.error(f"Consumer failed {ex}") LOG.error(f'Consumer failed {ex}')
LOG.error(ex) LOG.error(ex)
+21 -15
View File
@@ -5,24 +5,30 @@ import subprocess
from aprsd import packets, plugin from aprsd import packets, plugin
from aprsd.utils import trace from aprsd.utils import trace
LOG = logging.getLogger('APRSD')
LOG = logging.getLogger("APRSD") FORTUNE_PATHS = [
'/usr/games/fortune',
DEFAULT_FORTUNE_PATH = "/usr/games/fortune" '/usr/local/bin/fortune',
'/usr/bin/fortune',
]
class FortunePlugin(plugin.APRSDRegexCommandPluginBase): class FortunePlugin(plugin.APRSDRegexCommandPluginBase):
"""Fortune.""" """Fortune."""
command_regex = r"^([f]|[f]\s|fortune)" command_regex = r'^([f]|[f]\s|fortune)'
command_name = "fortune" command_name = 'fortune'
short_description = "Give me a fortune" short_description = 'Give me a fortune'
fortune_path = None fortune_path = None
def setup(self): def setup(self):
self.fortune_path = shutil.which(DEFAULT_FORTUNE_PATH) for path in FORTUNE_PATHS:
LOG.info(f"Fortune path {self.fortune_path}") self.fortune_path = shutil.which(path)
LOG.info(f'Fortune path {self.fortune_path}')
if self.fortune_path:
break
if not self.fortune_path: if not self.fortune_path:
self.enabled = False self.enabled = False
else: else:
@@ -30,7 +36,7 @@ class FortunePlugin(plugin.APRSDRegexCommandPluginBase):
@trace.trace @trace.trace
def process(self, packet: packets.MessagePacket): def process(self, packet: packets.MessagePacket):
LOG.info("FortunePlugin") LOG.info('FortunePlugin')
# fromcall = packet.get("from") # fromcall = packet.get("from")
# message = packet.get("message_text", None) # message = packet.get("message_text", None)
@@ -39,8 +45,8 @@ class FortunePlugin(plugin.APRSDRegexCommandPluginBase):
reply = None reply = None
try: try:
cmnd = [self.fortune_path, "-s", "-n 60"] cmnd = [self.fortune_path, '-s', '-n 60']
command = " ".join(cmnd) command = ' '.join(cmnd)
output = subprocess.check_output( output = subprocess.check_output(
command, command,
shell=True, shell=True,
@@ -48,10 +54,10 @@ class FortunePlugin(plugin.APRSDRegexCommandPluginBase):
text=True, text=True,
) )
output = ( output = (
output.replace("\r", "") output.replace('\r', '')
.replace("\n", "") .replace('\n', '')
.replace(" ", "") .replace(' ', '')
.replace("\t", " ") .replace('\t', ' ')
) )
except subprocess.CalledProcessError as ex: except subprocess.CalledProcessError as ex:
reply = f"Fortune command failed '{ex.output}'" reply = f"Fortune command failed '{ex.output}'"
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

+2 -1
View File
@@ -55,7 +55,8 @@ RUN if [ "$INSTALL_TYPE" = "pypi" ]; then \
uv pip install aprsd==$APRSD_PIP_VERSION; \ uv pip install aprsd==$APRSD_PIP_VERSION; \
elif [ "$INSTALL_TYPE" = "github" ]; then \ elif [ "$INSTALL_TYPE" = "github" ]; then \
git clone -b $APRSD_BRANCH https://github.com/craigerl/aprsd; \ 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*; \ ls -al /app/.venv/lib/python3.11/site-packages/aprsd*; \
fi fi
# RUN uv pip install gevent uwsgi # RUN uv pip install gevent uwsgi
+1 -1
View File
@@ -39,4 +39,4 @@ fi
export COLUMNS=200 export COLUMNS=200
python3 -m rich.diagnose python3 -m rich.diagnose
exec aprsd listen -c $APRSD_CONFIG --loglevel ${LOG_LEVEL} ${APRSD_LOAD_PLUGINS} ${APRSD_LISTEN_FILTER} exec aprsd listen -c $APRSD_CONFIG --loglevel ${LOG_LEVEL} --enable-packet-stats ${APRSD_LOAD_PLUGINS} ${APRSD_LISTEN_FILTER}
+1 -1
View File
@@ -30,7 +30,7 @@ dynamic = ["version", "dependencies", "optional-dependencies"]
# #
# This field corresponds to the "Description" metadata field: # This field corresponds to the "Description" metadata field:
# https://packaging.python.org/specifications/core-metadata/#description-optional # 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 # This is either text indicating the license for the distribution, or a file
+8 -8
View File
@@ -3,7 +3,7 @@
alabaster==1.0.0 # via sphinx alabaster==1.0.0 # via sphinx
babel==2.16.0 # via sphinx babel==2.16.0 # via sphinx
build==1.2.2.post1 # via pip-tools, -r requirements-dev.in build==1.2.2.post1 # via pip-tools, -r requirements-dev.in
cachetools==5.5.0 # via tox cachetools==5.5.1 # via tox
certifi==2024.12.14 # via requests certifi==2024.12.14 # via requests
cfgv==3.4.0 # via pre-commit cfgv==3.4.0 # via pre-commit
chardet==5.2.0 # via tox chardet==5.2.0 # via tox
@@ -12,8 +12,8 @@ click==8.1.8 # via pip-tools
colorama==0.4.6 # via tox colorama==0.4.6 # via tox
distlib==0.3.9 # via virtualenv distlib==0.3.9 # via virtualenv
docutils==0.21.2 # via m2r, sphinx docutils==0.21.2 # via m2r, sphinx
filelock==3.16.1 # via tox, virtualenv filelock==3.17.0 # via tox, virtualenv
identify==2.6.5 # via pre-commit identify==2.6.6 # via pre-commit
idna==3.10 # via requests idna==3.10 # via requests
imagesize==1.4.1 # via sphinx imagesize==1.4.1 # via sphinx
jinja2==3.1.5 # via sphinx jinja2==3.1.5 # via sphinx
@@ -26,13 +26,13 @@ pip==24.3.1 # via pip-tools, -r requirements-dev.in
pip-tools==7.4.1 # via -r requirements-dev.in pip-tools==7.4.1 # via -r requirements-dev.in
platformdirs==4.3.6 # via tox, virtualenv platformdirs==4.3.6 # via tox, virtualenv
pluggy==1.5.0 # via tox pluggy==1.5.0 # via tox
pre-commit==4.0.1 # via -r requirements-dev.in pre-commit==4.1.0 # via -r requirements-dev.in
pygments==2.19.1 # via sphinx pygments==2.19.1 # via sphinx
pyproject-api==1.8.0 # via tox pyproject-api==1.9.0 # via tox
pyproject-hooks==1.2.0 # via build, pip-tools pyproject-hooks==1.2.0 # via build, pip-tools
pyyaml==6.0.2 # via pre-commit pyyaml==6.0.2 # via pre-commit
requests==2.32.3 # via sphinx requests==2.32.3 # via sphinx
setuptools==75.7.0 # via pip-tools setuptools==75.8.0 # via pip-tools
snowballstemmer==2.2.0 # via sphinx snowballstemmer==2.2.0 # via sphinx
sphinx==8.1.3 # via -r requirements-dev.in sphinx==8.1.3 # via -r requirements-dev.in
sphinxcontrib-applehelp==2.0.0 # via sphinx sphinxcontrib-applehelp==2.0.0 # via sphinx
@@ -42,8 +42,8 @@ sphinxcontrib-jsmath==1.0.1 # via sphinx
sphinxcontrib-qthelp==2.0.0 # via sphinx sphinxcontrib-qthelp==2.0.0 # via sphinx
sphinxcontrib-serializinghtml==2.0.0 # via sphinx sphinxcontrib-serializinghtml==2.0.0 # via sphinx
tomli==2.2.1 # via build, pip-tools, pyproject-api, sphinx, tox tomli==2.2.1 # via build, pip-tools, pyproject-api, sphinx, tox
tox==4.23.2 # via -r requirements-dev.in tox==4.24.1 # via -r requirements-dev.in
typing-extensions==4.12.2 # via tox typing-extensions==4.12.2 # via tox
urllib3==2.3.0 # via requests urllib3==2.3.0 # via requests
virtualenv==20.28.1 # via pre-commit, tox virtualenv==20.29.1 # via pre-commit, tox
wheel==0.45.1 # via pip-tools, -r requirements-dev.in wheel==0.45.1 # via pip-tools, -r requirements-dev.in
+3 -3
View File
@@ -12,10 +12,10 @@ dataclasses-json==0.6.7 # via -r requirements.in
debtcollector==3.0.0 # via oslo-config debtcollector==3.0.0 # via oslo-config
haversine==2.9.0 # via -r requirements.in haversine==2.9.0 # via -r requirements.in
idna==3.10 # via requests idna==3.10 # via requests
importlib-metadata==8.5.0 # via ax253, kiss3 importlib-metadata==8.6.1 # via ax253, kiss3
kiss3==8.0.0 # via -r requirements.in kiss3==8.0.0 # via -r requirements.in
loguru==0.7.3 # via -r requirements.in loguru==0.7.3 # via -r requirements.in
marshmallow==3.24.1 # via dataclasses-json marshmallow==3.26.0 # via dataclasses-json
mypy-extensions==1.0.0 # via typing-inspect mypy-extensions==1.0.0 # via typing-inspect
netaddr==1.3.0 # via oslo-config netaddr==1.3.0 # via oslo-config
oslo-config==9.7.0 # via -r requirements.in oslo-config==9.7.0 # via -r requirements.in
@@ -40,5 +40,5 @@ typing-inspect==0.9.0 # via dataclasses-json
tzlocal==5.2 # via -r requirements.in tzlocal==5.2 # via -r requirements.in
update-checker==0.18.0 # via -r requirements.in update-checker==0.18.0 # via -r requirements.in
urllib3==2.3.0 # via requests urllib3==2.3.0 # via requests
wrapt==1.17.0 # via debtcollector, -r requirements.in wrapt==1.17.2 # via debtcollector, -r requirements.in
zipp==3.21.0 # via importlib-metadata zipp==3.21.0 # via importlib-metadata
Generated
+1340
View File
File diff suppressed because it is too large Load Diff