Skip to content

Commit

Permalink
Merge pull request #93 from jeremiah-k/plugin-system-work
Browse files Browse the repository at this point in the history
Smooth out new plugin system issues
  • Loading branch information
jeremiah-k authored Nov 8, 2024
2 parents e8b65a6 + d472f29 commit 4ad3efd
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 21 deletions.
23 changes: 11 additions & 12 deletions matrix_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@
)
from config import relay_config
from log_utils import get_logger
from plugin_loader import load_plugins
# Do not import plugin_loader here to avoid circular imports
from meshtastic_utils import connect_meshtastic
from PIL import Image
import meshtastic.protobuf.portnums_pb2

# Extract Matrix configuration
matrix_homeserver = relay_config["matrix"]["homeserver"]
matrix_rooms: List[dict] = relay_config["matrix_rooms"]
matrix_access_token = relay_config["matrix"]["access_token"]
Expand All @@ -35,12 +36,13 @@

matrix_client = None


def bot_command(command, payload):
return f"{bot_user_name}: !{command}" in payload


async def connect_matrix():
"""
Establish a connection to the Matrix homeserver.
"""
global matrix_client
global bot_user_name
if matrix_client:
Expand Down Expand Up @@ -116,7 +118,6 @@ async def join_matrix_room(matrix_client, room_id_or_alias: str) -> None:
except Exception as e:
logger.error(f"Error joining room '{room_id_or_alias}': {e}")


# Send message to the Matrix room
async def matrix_relay(room_id, message, longname, shortname, meshnet_name, portnum):
matrix_client = await connect_matrix()
Expand Down Expand Up @@ -144,7 +145,6 @@ async def matrix_relay(room_id, message, longname, shortname, meshnet_name, port
except Exception as e:
logger.error(f"Error sending radio message to matrix room {room_id}: {e}")


def truncate_message(
text, max_bytes=227
): # 227 is the maximum that we can run without an error so far. 228 throws an error.
Expand All @@ -158,7 +158,6 @@ def truncate_message(
truncated_text = text.encode("utf-8")[:max_bytes].decode("utf-8", "ignore")
return truncated_text


# Callback for new messages in Matrix room
async def on_room_message(
room: MatrixRoom, event: Union[RoomMessageText, RoomMessageNotice]
Expand Down Expand Up @@ -199,7 +198,7 @@ async def on_room_message(
short_meshnet_name = meshnet_name[:4]
# If shortname is None, truncate the longname to 3 characters
if shortname is None:
shortname = longname[:3]
shortname = longname[:3]
prefix = f"{shortname}/{short_meshnet_name}: "
text = re.sub(
rf"^\[{full_display_name}\]: ", "", text
Expand All @@ -221,9 +220,8 @@ async def on_room_message(
truncated_message = f"{prefix}{text}"

# Plugin functionality
plugins = load_plugins()
meshtastic_interface = connect_meshtastic()
from meshtastic_utils import logger as meshtastic_logger
from plugin_loader import load_plugins # Import here to avoid circular imports
plugins = load_plugins() # Load plugins within the function

found_matching_plugin = False
for plugin in plugins:
Expand All @@ -234,6 +232,9 @@ async def on_room_message(
if found_matching_plugin:
logger.debug(f"Processed by plugin {plugin.plugin_name}")

meshtastic_interface = connect_meshtastic()
from meshtastic_utils import logger as meshtastic_logger

meshtastic_channel = room_config["meshtastic_channel"]

if not found_matching_plugin and event.sender != bot_user_id:
Expand Down Expand Up @@ -263,7 +264,6 @@ async def on_room_message(
f"Broadcast not supported: Message from {full_display_name} dropped."
)


async def upload_image(
client: AsyncClient, image: Image.Image, filename: str
) -> UploadResponse:
Expand All @@ -280,7 +280,6 @@ async def upload_image(

return response


async def send_room_image(
client: AsyncClient, room_id: str, upload_response: UploadResponse
):
Expand Down
7 changes: 5 additions & 2 deletions meshtastic_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from config import relay_config
from db_utils import get_longname, get_shortname
from log_utils import get_logger
from plugin_loader import load_plugins
# Do not import plugin_loader here to avoid circular imports

# Extract matrix rooms configuration
matrix_rooms: List[dict] = relay_config["matrix_rooms"]
Expand Down Expand Up @@ -251,7 +251,9 @@ def on_meshtastic_message(packet, interface):
formatted_message = f"[{longname}/{meshnet_name}]: {text}"

# Plugin functionality
plugins = load_plugins()
from plugin_loader import load_plugins # Import here to avoid circular imports
plugins = load_plugins() # Load plugins within the function

found_matching_plugin = False
for plugin in plugins:
if not found_matching_plugin:
Expand Down Expand Up @@ -287,6 +289,7 @@ def on_meshtastic_message(packet, interface):
else:
# Handle non-text messages via plugins
portnum = decoded.get("portnum")
from plugin_loader import load_plugins # Import here to avoid circular imports
plugins = load_plugins()
found_matching_plugin = False
for plugin in plugins:
Expand Down
26 changes: 19 additions & 7 deletions plugin_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

logger = get_logger(name="Plugins")
sorted_active_plugins = []
plugins_loaded = False # Add this flag to track if plugins have been loaded

def load_config():
config_path = os.path.join(os.path.dirname(__file__), 'config.yaml')
Expand Down Expand Up @@ -38,6 +39,7 @@ def clone_or_update_repo(repo_url, tag, plugins_dir):
sys.exit(1)
else:
try:
os.makedirs(plugins_dir, exist_ok=True)
subprocess.check_call(['git', 'clone', '--branch', tag, repo_url], cwd=plugins_dir)
logger.info(f"Cloned repository {repo_name} from {repo_url} at {tag}")
except subprocess.CalledProcessError as e:
Expand Down Expand Up @@ -77,15 +79,19 @@ def load_plugins_from_directory(directory, recursive=False):
if not recursive:
break
else:
logger.warning(f"Directory {directory} does not exist.")
if not plugins_loaded: # Only log the missing directory once
logger.debug(f"Directory {directory} does not exist.") # Changed to DEBUG level
return plugins


def load_plugins():
global sorted_active_plugins
if sorted_active_plugins:
global plugins_loaded

if plugins_loaded:
return sorted_active_plugins

logger.debug("Loading plugins...") # Optional: Log when plugins are being loaded

config = load_config()

# Import core plugins
Expand Down Expand Up @@ -124,6 +130,10 @@ def load_plugins():
community_plugins_config = config.get('community-plugins', {})
community_plugins_dir = os.path.join(os.path.dirname(__file__), 'plugins', 'community')

# Create community plugins directory if needed
if any(plugin_info.get('active', False) for plugin_info in community_plugins_config.values()):
os.makedirs(community_plugins_dir, exist_ok=True)

for plugin_info in community_plugins_config.values():
if plugin_info.get('active', False):
repo_url = plugin_info.get('repository')
Expand All @@ -145,9 +155,9 @@ def load_plugins():

# Determine if the plugin is active based on the configuration
if plugin in core_plugins:
# Core plugins: default to active unless specified otherwise
# Core plugins: default to inactive unless specified otherwise
plugin_config = config.get('plugins', {}).get(plugin_name, {})
is_active = plugin_config.get("active", True)
is_active = plugin_config.get("active", False)
else:
# Custom and community plugins: default to inactive unless specified
if plugin_name in config.get('custom-plugins', {}):
Expand All @@ -167,7 +177,9 @@ def load_plugins():
except Exception as e:
logger.error(f"Error starting plugin {plugin_name}: {e}")
else:
logger.info(f"Plugin '{plugin_name}' is inactive or not configured, skipping")
if not plugins_loaded: # Only log about inactive plugins once
logger.debug(f"Plugin '{plugin_name}' is inactive or not configured, skipping") # Changed to DEBUG level

sorted_active_plugins = sorted(active_plugins, key=lambda plugin: plugin.priority)
return sorted_active_plugins
plugins_loaded = True # Set the flag to indicate that plugins have been loaded
return sorted_active_plugins

0 comments on commit 4ad3efd

Please sign in to comment.