From 483afce5adb39b973f4f6e5c57431007c3318889 Mon Sep 17 00:00:00 2001 From: Hemna Date: Mon, 17 Apr 2023 10:51:17 -0400 Subject: [PATCH] Update Listen command This patch updates the aprsd listen command to add the packet-plugins argument which allows enabling a single plugin to work against the packets recieved from the aprsis network. --- aprsd/cmds/dev.py | 4 +--- aprsd/cmds/listen.py | 34 +++++++++++++++++++++++++++++++--- aprsd/packets/core.py | 10 ++++++++++ aprsd/plugin.py | 19 +++++++++++++++---- 4 files changed, 57 insertions(+), 10 deletions(-) diff --git a/aprsd/cmds/dev.py b/aprsd/cmds/dev.py index cda428a..6e41db6 100644 --- a/aprsd/cmds/dev.py +++ b/aprsd/cmds/dev.py @@ -101,8 +101,6 @@ def test_plugin( pm = plugin.PluginManager() if load_all: pm.setup_plugins() - else: - pm._init() obj = pm._create_class(plugin_path, plugin.APRSDPluginBase) if not obj: click.echo(ctx.get_help()) @@ -116,7 +114,7 @@ def test_plugin( obj.__class__, obj.version, ), ) - pm._pluggy_pm.register(obj) + pm.register_msg(obj) packet = packets.MessagePacket( from_call=fromcall, diff --git a/aprsd/cmds/listen.py b/aprsd/cmds/listen.py index 7d3c14f..12ddcc7 100644 --- a/aprsd/cmds/listen.py +++ b/aprsd/cmds/listen.py @@ -15,7 +15,7 @@ from rich.console import Console # local imports here import aprsd -from aprsd import cli_helper, client, packets, stats, threads +from aprsd import cli_helper, client, packets, plugin, stats, threads from aprsd.aprsd import cli from aprsd.threads import rx @@ -40,9 +40,12 @@ def signal_handler(sig, frame): class APRSDListenThread(rx.APRSDRXThread): - def __init__(self, packet_queue, packet_filter=None): + def __init__(self, packet_queue, packet_filter=None, plugin_manager=None): super().__init__(packet_queue) self.packet_filter = packet_filter + self.plugin_manager = plugin_manager + if self.plugin_manager: + LOG.info(f"Plugins {self.plugin_manager.get_message_plugins()}") def process_packet(self, *args, **kwargs): packet = self._client.decode_packet(*args, **kwargs) @@ -59,8 +62,17 @@ class APRSDListenThread(rx.APRSDRXThread): filter_class = filters[self.packet_filter] if isinstance(packet, filter_class): packet.log(header="RX") + if self.plugin_manager: + # Don't do anything with the reply + # This is the listen only command. + self.plugin_manager.run(packet) else: - packet.log(header="RX") + if self.plugin_manager: + # Don't do anything with the reply. + # This is the listen only command. + self.plugin_manager.run(packet) + else: + packet.log(header="RX") packets.PacketList().rx(packet) @@ -94,6 +106,11 @@ class APRSDListenThread(rx.APRSDRXThread): ), help="Filter by packet type", ) +@click.option( + "--packet-plugins", + default=None, + help="CSV, List of aprsd plugins to enable", +) @click.argument( "filter", nargs=-1, @@ -106,6 +123,7 @@ def listen( aprs_login, aprs_password, packet_filter, + packet_plugins, filter, ): """Listen to packets on the APRS-IS Network based on FILTER. @@ -162,10 +180,20 @@ def listen( keepalive = threads.KeepAliveThread() keepalive.start() + LOG.info(f"Packet plugins {packet_plugins}") + + pm = None + if packet_plugins: + LOG.info(f"Load plugins! {packet_plugins}") + pm = plugin.PluginManager() + for plugin_path in packet_plugins.split(","): + pm._load_plugin(plugin_path) + LOG.debug("Create APRSDListenThread") listen_thread = APRSDListenThread( packet_queue=threads.packet_queue, packet_filter=packet_filter, + plugin_manager=pm, ) LOG.debug("Start APRSDListenThread") listen_thread.start() diff --git a/aprsd/packets/core.py b/aprsd/packets/core.py index 351c9c5..b946f68 100644 --- a/aprsd/packets/core.py +++ b/aprsd/packets/core.py @@ -183,6 +183,16 @@ class Packet(metaclass=abc.ABCMeta): self.prepare() return self.raw + def __repr__(self): + """Build the repr version of the packet.""" + repr = ( + f"{self.__class__.__name__}:" + f" From: {self.from_call} " + " To: " + ) + + return repr + @dataclass class PathPacket(Packet): diff --git a/aprsd/plugin.py b/aprsd/plugin.py index fd342cc..b3d90dc 100644 --- a/aprsd/plugin.py +++ b/aprsd/plugin.py @@ -338,6 +338,7 @@ class PluginManager: return cls._instance def __init__(self, config=None): + self._init() self.obj_list = [] if config: self.config = config @@ -422,10 +423,10 @@ class PluginManager: self._watchlist_pm.register(plugin_obj) else: LOG.warning(f"Plugin {plugin_obj.__class__.__name__} is disabled") - else: + elif isinstance(plugin_obj, APRSDRegexCommandPluginBase): if plugin_obj.enabled: LOG.info( - "Registering plugin '{}'({}) -- {}".format( + "Registering Regex plugin '{}'({}) -- {}".format( plugin_name, plugin_obj.version, plugin_obj.command_regex, @@ -434,6 +435,17 @@ class PluginManager: self._pluggy_pm.register(plugin_obj) else: LOG.warning(f"Plugin {plugin_obj.__class__.__name__} is disabled") + elif isinstance(plugin_obj, APRSDPluginBase): + if plugin_obj.enabled: + LOG.info( + "Registering Base plugin '{}'({})".format( + plugin_name, + plugin_obj.version, + ), + ) + self._pluggy_pm.register(plugin_obj) + else: + LOG.warning(f"Plugin {plugin_obj.__class__.__name__} is disabled") except Exception as ex: LOG.error(f"Couldn't load plugin '{plugin_name}'") LOG.exception(ex) @@ -447,7 +459,6 @@ class PluginManager: """Create the plugin manager and register plugins.""" LOG.info("Loading APRSD Plugins") - self._init() # Help plugin is always enabled. _help = HelpPlugin() self._pluggy_pm.register(_help) @@ -465,7 +476,7 @@ class PluginManager: LOG.info("Completed Plugin Loading.") def run(self, packet: packets.core.MessagePacket): - """Execute all the pluguns run method.""" + """Execute all the plugins run method.""" with self.lock: return self._pluggy_pm.hook.filter(packet=packet)