1
0
mirror of https://github.com/craigerl/aprsd.git synced 2026-01-17 02:55:49 -05:00

refactored list-plugins

created new package module that gets information from installed
plugins and extensions so we can print it out to log at startup.

Updated commands to output the the installed extensions and plugins
This commit is contained in:
Walter Boring 2025-09-27 14:19:59 -04:00
parent 3961e1d1ad
commit c7c9a92b15
6 changed files with 23 additions and 136 deletions

View File

@ -4,11 +4,13 @@
#
# python included libs
import logging
import sys
import click
from oslo_config import cfg
from aprsd import cli_helper, conf, packets, plugin
import aprsd
from aprsd import cli_helper, conf, packets, plugin, utils
# local imports here
from aprsd.main import cli
@ -71,6 +73,9 @@ def test_plugin(
):
"""Test an individual APRSD plugin given a python path."""
LOG.info(f'Python version: {sys.version}')
LOG.info(f'APRSD DEV Started version: {aprsd.__version__}')
utils.package.log_installed_extensions_and_plugins()
CONF.log_opt_values(LOG, logging.DEBUG)
if not aprs_login:

View File

@ -1,5 +1,6 @@
# Fetch active stats from a remote running instance of aprsd admin web interface.
import logging
import sys
import click
import requests
@ -38,6 +39,7 @@ CONF = cfg.CONF
def fetch_stats(ctx, host, port):
"""Fetch stats from a APRSD admin web interface."""
console = Console()
console.print(f'Python version: {sys.version}')
console.print(f'APRSD Fetch-Stats started version: {aprsd.__version__}')
CONF.log_opt_values(LOG, logging.DEBUG)

View File

@ -1,119 +1,18 @@
import fnmatch
import importlib
import inspect
import logging
import os
import pkgutil
import sys
from traceback import print_tb
import click
import requests
from rich.console import Console
from rich.table import Table
from rich.text import Text
from thesmuggler import smuggle
from aprsd import cli_helper
from aprsd import plugin as aprsd_plugin
from aprsd.main import cli
from aprsd.plugins import fortune, notify, ping, time, version, weather
from aprsd.utils import package as aprsd_package
LOG = logging.getLogger('APRSD')
PYPI_URL = 'https://pypi.org/search/'
def onerror(name):
print(f'Error importing module {name}')
type, value, traceback = sys.exc_info()
print_tb(traceback)
def is_plugin(obj):
for c in inspect.getmro(obj):
if issubclass(c, aprsd_plugin.APRSDPluginBase):
return True
return False
def plugin_type(obj):
for c in inspect.getmro(obj):
if issubclass(c, aprsd_plugin.APRSDRegexCommandPluginBase):
return 'RegexCommand'
if issubclass(c, aprsd_plugin.APRSDWatchListPluginBase):
return 'WatchList'
if issubclass(c, aprsd_plugin.APRSDPluginBase):
return 'APRSDPluginBase'
return 'Unknown'
def walk_package(package):
return pkgutil.walk_packages(
package.__path__,
package.__name__ + '.',
onerror=onerror,
)
def get_module_info(package_name, module_name, module_path):
if not os.path.exists(module_path):
return None
dir_path = os.path.realpath(module_path)
pattern = '*.py'
obj_list = []
for path, _subdirs, files in os.walk(dir_path):
for name in files:
if fnmatch.fnmatch(name, pattern):
module = smuggle(f'{path}/{name}')
for mem_name, obj in inspect.getmembers(module):
if inspect.isclass(obj) and is_plugin(obj):
obj_list.append(
{
'package': package_name,
'name': mem_name,
'obj': obj,
'version': obj.version,
'path': f'{".".join([module_name, obj.__name__])}',
},
)
return obj_list
def _get_installed_aprsd_items():
# installed plugins
plugins = {}
extensions = {}
for _finder, name, ispkg in pkgutil.iter_modules():
if ispkg and name.startswith('aprsd_'):
module = importlib.import_module(name)
pkgs = walk_package(module)
for pkg in pkgs:
pkg_info = get_module_info(
module.__name__, pkg.name, module.__path__[0]
)
if 'plugin' in name:
plugins[name] = pkg_info
elif 'extension' in name:
extensions[name] = pkg_info
return plugins, extensions
def get_installed_plugins():
# installed plugins
plugins, extensions = _get_installed_aprsd_items()
return plugins
def get_installed_extensions():
# installed plugins
plugins, extensions = _get_installed_aprsd_items()
return extensions
def show_built_in_plugins(console):
@ -157,34 +56,8 @@ def show_built_in_plugins(console):
console.print(table)
def _get_pypi_packages():
if simple_r := requests.get(
'https://pypi.org/simple',
headers={'Accept': 'application/vnd.pypi.simple.v1+json'},
):
simple_response = simple_r.json()
else:
simple_response = {}
key = 'aprsd'
matches = [
p['name'] for p in simple_response['projects'] if p['name'].startswith(key)
]
packages = []
for pkg in matches:
# Get info for first match
if r := requests.get(
f'https://pypi.org/pypi/{pkg}/json',
headers={'Accept': 'application/json'},
):
packages.append(r.json())
return packages
def show_pypi_plugins(installed_plugins, console):
packages = _get_pypi_packages()
packages = aprsd_package.get_pypi_packages()
title = Text.assemble(
('Pypi.org APRSD Installable Plugin Packages\n\n', 'bold magenta'),
@ -225,7 +98,7 @@ def show_pypi_plugins(installed_plugins, console):
def show_pypi_extensions(installed_extensions, console):
packages = _get_pypi_packages()
packages = aprsd_package.get_pypi_packages()
title = Text.assemble(
('Pypi.org APRSD Installable Extension Packages\n\n', 'bold magenta'),
@ -282,7 +155,7 @@ def show_installed_plugins(installed_plugins, console):
name.replace('_', '-'),
plugin['name'],
plugin['version'],
plugin_type(plugin['obj']),
aprsd_package.plugin_type(plugin['obj']),
plugin['path'],
)
@ -302,7 +175,7 @@ def list_plugins(ctx):
show_built_in_plugins(console)
status.update('Fetching pypi.org plugins')
installed_plugins = get_installed_plugins()
installed_plugins = aprsd_package.get_installed_plugins()
show_pypi_plugins(installed_plugins, console)
status.update('Looking for installed APRSD plugins')
@ -321,5 +194,5 @@ def list_extensions(ctx):
status.update('Fetching pypi.org APRSD Extensions')
status.update('Looking for installed APRSD Extensions')
installed_extensions = get_installed_extensions()
installed_extensions = aprsd_package.get_installed_extensions()
show_pypi_extensions(installed_extensions, console)

View File

@ -221,7 +221,9 @@ def listen(
# CONF.aprs_network.login = aprs_login
# config["aprs"]["password"] = aprs_password
LOG.info(f'Python version: {sys.version}')
LOG.info(f'APRSD Listen Started version: {aprsd.__version__}')
utils.package.log_installed_extensions_and_plugins()
CONF.log_opt_values(LOG, logging.DEBUG)
collector.Collector()

View File

@ -13,6 +13,7 @@ from aprsd import (
cli_helper,
conf, # noqa : F401
packets,
utils,
)
from aprsd.client.client import APRSDClient
from aprsd.main import cli
@ -89,7 +90,9 @@ def send_message(
else:
aprs_password = CONF.aprs_network.password
LOG.info(f'APRSD LISTEN Started version: {aprsd.__version__}')
LOG.info(f'Python version: {sys.version}')
LOG.info(f'APRSD SEND_MESSAGE Started version: {aprsd.__version__}')
utils.package.log_installed_extensions_and_plugins()
if type(command) is tuple:
command = ' '.join(command)
if not quiet:

View File

@ -40,12 +40,14 @@ def server(ctx, flush):
service_threads = service.ServiceThreads()
LOG.info(f'Python version: {sys.version}')
LOG.info(f'APRSD Started version: {aprsd.__version__}')
level, msg = utils._check_version()
if level:
LOG.warning(msg)
else:
LOG.info(msg)
LOG.info(f'APRSD Started version: {aprsd.__version__}')
utils.package.log_installed_extensions_and_plugins()
# Make sure we have 1 client transport enabled
if not APRSDClient().is_enabled: