From 1e4f0ca65af38f728de6c917d09b19450aceaa2b Mon Sep 17 00:00:00 2001 From: Hemna Date: Mon, 26 Feb 2024 18:28:52 -0500 Subject: [PATCH] Added the new APRS Registry thread This patch adds the new APRSRegistryThread, which enabled in config, will send a small packet of information to the as yet deployed APRS service registry every 900 seconds. The data that this thread will send is the service callsign, a description of the service, a website url for the service. The idea being that the registry website that this thread sends information to, will show all the services that are running on the ARPS network, so Ham operators can discover them and try them out. --- .pre-commit-config.yaml | 6 ++--- aprsd/cmds/server.py | 7 +++++- aprsd/conf/common.py | 41 ++++++++++++++++++++++++++++++++++ aprsd/threads/registry.py | 46 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 aprsd/threads/registry.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4e63957..431ef0e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.4.0 + rev: v4.5.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -12,11 +12,11 @@ repos: - id: check-builtin-literals - repo: https://github.com/asottile/setup-cfg-fmt - rev: v1.16.0 + rev: v2.5.0 hooks: - id: setup-cfg-fmt - repo: https://github.com/dizballanze/gray - rev: v0.10.1 + rev: v0.14.0 hooks: - id: gray diff --git a/aprsd/cmds/server.py b/aprsd/cmds/server.py index b1848ae..89a6c74 100644 --- a/aprsd/cmds/server.py +++ b/aprsd/cmds/server.py @@ -11,7 +11,7 @@ from aprsd import main as aprsd_main from aprsd import packets, plugin, threads, utils from aprsd.main import cli from aprsd.rpc import server as rpc_server -from aprsd.threads import rx, tx +from aprsd.threads import registry, rx, tx CONF = cfg.CONF @@ -112,6 +112,11 @@ def server(ctx, flush): bcn_thread = tx.BeaconSendThread() bcn_thread.start() + if CONF.aprs_registry.enabled: + LOG.info("Registry Enabled. Starting Registry thread.") + registry_thread = registry.APRSRegistryThread() + registry_thread.start() + if CONF.rpc_settings.enabled: rpc = rpc_server.APRSDRPCThread() rpc.start() diff --git a/aprsd/conf/common.py b/aprsd/conf/common.py index e615601..553c9ea 100644 --- a/aprsd/conf/common.py +++ b/aprsd/conf/common.py @@ -24,6 +24,11 @@ webchat_group = cfg.OptGroup( title="Settings specific to the webchat command", ) +registry_group = cfg.OptGroup( + name="aprs_registry", + title="APRS Registry settings", +) + aprsd_opts = [ cfg.StrOpt( @@ -222,6 +227,39 @@ webchat_opts = [ ), ] +registry_opts = [ + cfg.StrOpt( + "enabled", + default=False, + help="Enable sending aprs registry information. This will let the " + "APRS registry know about your service and it's uptime. " + "No personal information is sent, just the callsign, uptime and description. " + "The service callsign is the callsign set in [DEFAULT] section.", + ), + cfg.StrOpt( + "description", + default=None, + help="Description of the service to send to the APRS registry. " + "This is what will show up in the APRS registry." + "If not set, the description will be the same as the callsign.", + ), + cfg.StrOpt( + "registry_url", + default="https://aprs.hemna.com", + help="The APRS registry domain name to send the information to.", + ), + cfg.StrOpt( + "service_website", + default=None, + help="The website for your APRS service to send to the APRS registry.", + ), + cfg.StrOpt( + "frequency_seconds", + default=900, + help="The frequency in seconds to send the APRS registry information.", + ), +] + def register_opts(config): config.register_opts(aprsd_opts) @@ -234,6 +272,8 @@ def register_opts(config): config.register_opts(rpc_opts, group=rpc_group) config.register_group(webchat_group) config.register_opts(webchat_opts, group=webchat_group) + config.register_group(registry_group) + config.register_opts(registry_opts, group=registry_group) def list_opts(): @@ -243,4 +283,5 @@ def list_opts(): watch_list_group.name: watch_list_opts, rpc_group.name: rpc_opts, webchat_group.name: webchat_opts, + registry_group.name: registry_opts, } diff --git a/aprsd/threads/registry.py b/aprsd/threads/registry.py new file mode 100644 index 0000000..10e03d7 --- /dev/null +++ b/aprsd/threads/registry.py @@ -0,0 +1,46 @@ +import logging + +from oslo_config import cfg +import requests + +from aprsd import stats +from aprsd import threads as aprsd_threads + + +CONF = cfg.CONF +LOG = logging.getLogger("APRSD") + +class APRSRegistryThread(aprsd_threads.APRSDThread): + """This sends service information to the configured APRS Registry.""" + _loop_cnt: int = 1 + + def __init__(self): + super().__init__("APRSRegistryThread") + self._loop_cnt = 1 + if not CONF.registry.enabled: + LOG.error( + "APRS Registry is not enabled. ", + ) + LOG.error( + "APRS Registry thread is STOPPING.", + ) + self.stop() + + def loop(self): + # Only call the registry every N seconds + if self._loop_cnt % CONF.registry.frequency_seconds == 0: + info = { + "callsign": CONF.callsign, + "description": CONF.registry.description, + "service_website": CONF.registry.service_website, + "uptime": stats.APRSDStats().uptime, + } + try: + requests.post( + f"{CONF.registry.registry_url}/api/v1/register", + json=info, + ) + except Exception as e: + LOG.error(f"Failed to send registry info: {e}") + + return True