diff --git a/aprsd/plugin.py b/aprsd/plugin.py index db85a5d..0603666 100644 --- a/aprsd/plugin.py +++ b/aprsd/plugin.py @@ -1,16 +1,13 @@ # The base plugin class import abc -import fnmatch import importlib import inspect import logging -import os import re import textwrap import threading import pluggy -from thesmuggler import smuggle import aprsd from aprsd import client, packets, threads @@ -348,29 +345,9 @@ class PluginManager: def _init(self): self._pluggy_pm = pluggy.PluginManager("aprsd") self._pluggy_pm.add_hookspecs(APRSDPluginSpec) - - def load_plugins_from_path(self, module_path): - if not os.path.exists(module_path): - LOG.error(f"plugin path '{module_path}' doesn't exist.") - return None - - dir_path = os.path.realpath(module_path) - pattern = "*.py" - - self.obj_list = [] - - for path, _subdirs, files in os.walk(dir_path): - for name in files: - if fnmatch.fnmatch(name, pattern): - LOG.debug(f"MODULE? '{name}' '{path}'") - module = smuggle(f"{path}/{name}") - for mem_name, obj in inspect.getmembers(module): - if inspect.isclass(obj) and self.is_plugin(obj): - self.obj_list.append( - {"name": mem_name, "obj": obj(self.config)}, - ) - - return self.obj_list + # For the watchlist plugins + self._watchlist_pm = pluggy.PluginManager("aprsd") + self._watchlist_pm.add_hookspecs(APRSDPluginSpec) def is_plugin(self, obj): for c in inspect.getmro(obj): @@ -430,13 +407,22 @@ class PluginManager: config=self.config, ) if plugin_obj: - LOG.info( - "Registering plugin '{}'({})".format( - plugin_name, - plugin_obj.version, - ), - ) - self._pluggy_pm.register(plugin_obj) + if isinstance(plugin_obj, APRSDWatchListPluginBase): + LOG.info( + "Registering WatchList plugin '{}'({})".format( + plugin_name, + plugin_obj.version, + ), + ) + self._watchlist_pm.register(plugin_obj) + else: + LOG.info( + "Registering plugin '{}'({})".format( + plugin_name, + plugin_obj.version, + ), + ) + self._pluggy_pm.register(plugin_obj) except Exception as ex: LOG.error(f"Couldn't load plugin '{plugin_name}'") LOG.exception(ex) @@ -465,15 +451,6 @@ class PluginManager: for p_name in CORE_MESSAGE_PLUGINS: self._load_plugin(p_name) - if self.config["aprsd"]["watch_list"].get("enabled", False): - LOG.info("Loading APRSD WatchList Plugins") - enabled_notify_plugins = self.config["aprsd"]["watch_list"].get( - "enabled_plugins", - None, - ) - if enabled_notify_plugins: - for p_name in enabled_notify_plugins: - self._load_plugin(p_name) LOG.info("Completed Plugin Loading.") def run(self, packet): @@ -481,6 +458,10 @@ class PluginManager: with self.lock: return self._pluggy_pm.hook.filter(packet=packet) + def run_watchlist(self, packet): + with self.lock: + return self._watchlist_pm.hook.filter(packet=packet) + def stop(self): """Stop all threads created by all plugins.""" with self.lock: @@ -493,5 +474,10 @@ class PluginManager: self._pluggy_pm.register(obj) def get_plugins(self): + plugin_list = [] if self._pluggy_pm: - return self._pluggy_pm.get_plugins() + plugin_list.append(self._pluggy_pm.get_plugins()) + if self._watchlist_pm: + plugin_list.append(self._watchlist_pm.get_plugins()) + + return plugin_list diff --git a/aprsd/plugins/notify.py b/aprsd/plugins/notify.py index 15a9b22..9009c66 100644 --- a/aprsd/plugins/notify.py +++ b/aprsd/plugins/notify.py @@ -26,17 +26,17 @@ class NotifySeenPlugin(plugin.APRSDWatchListPluginBase): wl = packets.WatchList() age = wl.age(fromcall) - if wl.is_old(fromcall): - LOG.info( - "NOTIFY {} last seen {} max age={}".format( - fromcall, - age, - wl.max_delta(), - ), - ) - packet_type = packet.__class__.__name__ - # we shouldn't notify the alert user that they are online. - if fromcall != notify_callsign: + if fromcall != notify_callsign: + if wl.is_old(fromcall): + LOG.info( + "NOTIFY {} last seen {} max age={}".format( + fromcall, + age, + wl.max_delta(), + ), + ) + packet_type = packet.__class__.__name__ + # we shouldn't notify the alert user that they are online. pkt = packets.MessagePacket( from_call=self.config["aprsd"]["callsign"], to_call=notify_callsign, @@ -45,17 +45,14 @@ class NotifySeenPlugin(plugin.APRSDWatchListPluginBase): ), allow_delay=False, ) - # pkt.allow_delay = False + pkt.allow_delay = False return pkt else: - LOG.debug("fromcall and notify_callsign are the same, not notifying") + LOG.debug( + "Not old enough to notify on callsign " + f"'{fromcall}' : {age} < {wl.max_delta()}", + ) return packets.NULL_MESSAGE else: - LOG.debug( - "Not old enough to notify on callsign '{}' : {} < {}".format( - fromcall, - age, - wl.max_delta(), - ), - ) + LOG.debug("fromcall and notify_callsign are the same, ignoring") return packets.NULL_MESSAGE diff --git a/aprsd/threads/rx.py b/aprsd/threads/rx.py index 4db1577..3df02fe 100644 --- a/aprsd/threads/rx.py +++ b/aprsd/threads/rx.py @@ -159,7 +159,6 @@ class APRSDProcessPacketThread(APRSDThread): LOG.info("Got a packet not meant for us.") else: LOG.info("Got a non AckPacket/MessagePacket") - LOG.info(packet) class APRSDPluginProcessPacketThread(APRSDProcessPacketThread): @@ -167,6 +166,32 @@ class APRSDPluginProcessPacketThread(APRSDProcessPacketThread): This is the main aprsd server plugin processing thread.""" + def process_other_packet(self, packet, for_us=False): + pm = plugin.PluginManager() + try: + results = pm.run_watchlist(packet) + for reply in results: + if isinstance(reply, list): + for subreply in reply: + LOG.debug(f"Sending '{subreply}'") + if isinstance(subreply, packets.Packet): + subreply.send() + else: + to_call = self.config["aprsd"]["watch_list"]["alert_callsign"] + msg_pkt = packets.MessagePacket( + from_call=self.config["aprsd"]["callsign"], + to_call=to_call, + message_text=subreply, + ) + msg_pkt.send() + elif isinstance(reply, packets.Packet): + # We have a message based object. + reply.send() + except Exception as ex: + LOG.error("Plugin failed!!!") + LOG.exception(ex) + + def process_our_message_packet(self, packet): """Send the packet through the plugins.""" from_call = packet.from_call