1
0
mirror of https://github.com/craigerl/aprsd.git synced 2025-09-04 14:17:48 -04:00

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 # The base plugin class
import abc import abc
import fnmatch
import importlib import importlib
import inspect import inspect
import logging import logging
import os
import re import re
import textwrap import textwrap
import threading import threading
import pluggy import pluggy
from thesmuggler import smuggle
import aprsd import aprsd
from aprsd import client, packets, threads from aprsd import client, packets, threads
@ -348,29 +345,9 @@ class PluginManager:
def _init(self): def _init(self):
self._pluggy_pm = pluggy.PluginManager("aprsd") self._pluggy_pm = pluggy.PluginManager("aprsd")
self._pluggy_pm.add_hookspecs(APRSDPluginSpec) self._pluggy_pm.add_hookspecs(APRSDPluginSpec)
# For the watchlist plugins
def load_plugins_from_path(self, module_path): self._watchlist_pm = pluggy.PluginManager("aprsd")
if not os.path.exists(module_path): self._watchlist_pm.add_hookspecs(APRSDPluginSpec)
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
def is_plugin(self, obj): def is_plugin(self, obj):
for c in inspect.getmro(obj): for c in inspect.getmro(obj):
@ -430,13 +407,22 @@ class PluginManager:
config=self.config, config=self.config,
) )
if plugin_obj: if plugin_obj:
LOG.info( if isinstance(plugin_obj, APRSDWatchListPluginBase):
"Registering plugin '{}'({})".format( LOG.info(
plugin_name, "Registering WatchList plugin '{}'({})".format(
plugin_obj.version, plugin_name,
), plugin_obj.version,
) ),
self._pluggy_pm.register(plugin_obj) )
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: except Exception as ex:
LOG.error(f"Couldn't load plugin '{plugin_name}'") LOG.error(f"Couldn't load plugin '{plugin_name}'")
LOG.exception(ex) LOG.exception(ex)
@ -465,15 +451,6 @@ class PluginManager:
for p_name in CORE_MESSAGE_PLUGINS: for p_name in CORE_MESSAGE_PLUGINS:
self._load_plugin(p_name) 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.") LOG.info("Completed Plugin Loading.")
def run(self, packet): def run(self, packet):
@ -481,6 +458,10 @@ class PluginManager:
with self.lock: with self.lock:
return self._pluggy_pm.hook.filter(packet=packet) 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): def stop(self):
"""Stop all threads created by all plugins.""" """Stop all threads created by all plugins."""
with self.lock: with self.lock:
@ -493,5 +474,10 @@ class PluginManager:
self._pluggy_pm.register(obj) self._pluggy_pm.register(obj)
def get_plugins(self): def get_plugins(self):
plugin_list = []
if self._pluggy_pm: 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() wl = packets.WatchList()
age = wl.age(fromcall) age = wl.age(fromcall)
if wl.is_old(fromcall): if fromcall != notify_callsign:
LOG.info( if wl.is_old(fromcall):
"NOTIFY {} last seen {} max age={}".format( LOG.info(
fromcall, "NOTIFY {} last seen {} max age={}".format(
age, fromcall,
wl.max_delta(), age,
), wl.max_delta(),
) ),
packet_type = packet.__class__.__name__ )
# we shouldn't notify the alert user that they are online. packet_type = packet.__class__.__name__
if fromcall != notify_callsign: # we shouldn't notify the alert user that they are online.
pkt = packets.MessagePacket( pkt = packets.MessagePacket(
from_call=self.config["aprsd"]["callsign"], from_call=self.config["aprsd"]["callsign"],
to_call=notify_callsign, to_call=notify_callsign,
@ -45,17 +45,14 @@ class NotifySeenPlugin(plugin.APRSDWatchListPluginBase):
), ),
allow_delay=False, allow_delay=False,
) )
# pkt.allow_delay = False pkt.allow_delay = False
return pkt return pkt
else: 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 return packets.NULL_MESSAGE
else: else:
LOG.debug( LOG.debug("fromcall and notify_callsign are the same, ignoring")
"Not old enough to notify on callsign '{}' : {} < {}".format(
fromcall,
age,
wl.max_delta(),
),
)
return packets.NULL_MESSAGE return packets.NULL_MESSAGE

View File

@ -159,7 +159,6 @@ class APRSDProcessPacketThread(APRSDThread):
LOG.info("Got a packet not meant for us.") LOG.info("Got a packet not meant for us.")
else: else:
LOG.info("Got a non AckPacket/MessagePacket") LOG.info("Got a non AckPacket/MessagePacket")
LOG.info(packet)
class APRSDPluginProcessPacketThread(APRSDProcessPacketThread): class APRSDPluginProcessPacketThread(APRSDProcessPacketThread):
@ -167,6 +166,32 @@ class APRSDPluginProcessPacketThread(APRSDProcessPacketThread):
This is the main aprsd server plugin processing thread.""" 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): def process_our_message_packet(self, packet):
"""Send the packet through the plugins.""" """Send the packet through the plugins."""
from_call = packet.from_call from_call = packet.from_call