Cleaned up PluginManager

Added a separate pluggy track for normal plugins
and watch list plugins.
This commit is contained in:
Hemna 2022-12-20 15:13:13 -05:00
parent 088cbb81ed
commit 220fb58f97
3 changed files with 72 additions and 64 deletions

View File

@ -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

View File

@ -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

View File

@ -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