diff --git a/.gitignore b/.gitignore index 976fbbd..2dc5bd7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .pyenv .vscode config.yaml +custom_plugins/* meshtastic.sqlite __pycache__/ ./plugins/__pycache__/ \ No newline at end of file diff --git a/example_plugins/hello_world.py b/example_plugins/hello_world.py new file mode 100644 index 0000000..b64b028 --- /dev/null +++ b/example_plugins/hello_world.py @@ -0,0 +1,13 @@ +from plugins.base_plugin import BasePlugin + + +class Plugin(BasePlugin): + plugin_name = "helloworld" + + async def handle_meshtastic_message( + self, packet, formatted_message, longname, meshnet_name + ): + self.logger.debug("Hello world, Meshtastic") + + async def handle_room_message(self, room, event, full_message): + self.logger.debug("Hello world, Matrix") diff --git a/main.py b/main.py index 6c56efc..099d51d 100644 --- a/main.py +++ b/main.py @@ -16,7 +16,7 @@ from matrix_utils import ( on_room_message, logger as matrix_logger, ) - +from plugin_loader import load_plugins from config import relay_config from log_utils import get_logger from meshtastic_utils import ( @@ -35,6 +35,9 @@ async def main(): # Initialize the SQLite database initialize_database() + # Load plugins early + load_plugins() + matrix_client = await connect_matrix() matrix_logger.info("Connecting ...") diff --git a/plugin_loader.py b/plugin_loader.py index fb6d0cb..4f8c5ee 100644 --- a/plugin_loader.py +++ b/plugin_loader.py @@ -1,6 +1,9 @@ import sys import importlib from pathlib import Path +from log_utils import get_logger + +logger = get_logger(name="Plugins") plugins = [] @@ -11,15 +14,20 @@ def load_plugins(): return plugins plugins = [] - plugin_folder = Path("plugins") - sys.path.insert(0, str(plugin_folder.resolve())) + plugin_dirs = [Path("plugins"), Path("custom_plugins")] - for plugin_file in plugin_folder.glob("*.py"): - plugin_name = plugin_file.stem - if plugin_name == "__init__": - continue - plugin_module = importlib.import_module(plugin_name) - if hasattr(plugin_module, "Plugin"): - plugins.append(plugin_module.Plugin()) + for plugin_folder in plugin_dirs: + sys.path.insert(0, str(plugin_folder.resolve())) + + for plugin_file in plugin_folder.glob("*.py"): + plugin_name = plugin_file.stem + if plugin_name == "__init__": + continue + plugin_module = importlib.import_module(plugin_name) + if hasattr(plugin_module, "Plugin"): + plugin = plugin_module.Plugin() + if plugin.config["active"]: + logger.debug(f"Loaded plugin {plugin_folder/plugin_name}") + plugins.append(plugin) return plugins diff --git a/plugins/base_plugin.py b/plugins/base_plugin.py index f888e4e..1eaadba 100644 --- a/plugins/base_plugin.py +++ b/plugins/base_plugin.py @@ -1,7 +1,18 @@ from abc import ABC, abstractmethod +from log_utils import get_logger +from config import relay_config class BasePlugin(ABC): + plugin_name = None + + def __init__(self) -> None: + super().__init__() + self.logger = get_logger(f"Plugin:{self.plugin_name}") + self.config = {"active": False} + if "plugins" in relay_config and self.plugin_name in relay_config["plugins"]: + self.config = relay_config["plugins"][self.plugin_name] + @abstractmethod async def handle_meshtastic_message( packet, formatted_message, longname, meshnet_name diff --git a/plugins/health_plugin.py b/plugins/health_plugin.py index dd322f5..6094fca 100644 --- a/plugins/health_plugin.py +++ b/plugins/health_plugin.py @@ -7,6 +7,8 @@ from meshtastic_utils import connect_meshtastic class Plugin(BasePlugin): + plugin_name = "health" + async def handle_meshtastic_message( self, packet, formatted_message, longname, meshnet_name ): diff --git a/plugins/map_plugin.py b/plugins/map_plugin.py index 5a6c47d..6061a60 100644 --- a/plugins/map_plugin.py +++ b/plugins/map_plugin.py @@ -81,6 +81,8 @@ async def send_image(client: AsyncClient, room_id: str, image: Image.Image): class Plugin(BasePlugin): + plugin_name = "map" + async def handle_meshtastic_message( self, packet, formatted_message, longname, meshnet_name ):