more refactoring

This commit is contained in:
William Kray
2025-09-09 14:49:45 -07:00
parent 6582112dfb
commit 87e02b7ea6
28 changed files with 4664 additions and 894 deletions
+266
View File
@@ -0,0 +1,266 @@
"""Base command handler for common command patterns."""
from abc import ABC, abstractmethod
from typing import Any, Optional
from mautrix.types import MessageEvent, UserID
from .decorators import require_permission, require_parent_room, handle_errors
class BaseCommandHandler(ABC):
"""Base class for command handlers with common patterns."""
def __init__(self, bot):
"""Initialize with bot instance.
Args:
bot: CommunityBot instance
"""
self.bot = bot
self.client = bot.client
self.config = bot.config
self.config_manager = bot.config_manager
self.log = bot.log
self.database = bot.database
@abstractmethod
async def execute(self, evt: MessageEvent, *args, **kwargs) -> Any:
"""Execute the command logic.
Args:
evt: Message event
*args: Command arguments
**kwargs: Additional keyword arguments
Returns:
Command result
"""
pass
async def check_permissions(self, evt: MessageEvent, min_level: int = 50, room_id: str = None) -> bool:
"""Check if user has required permissions.
Args:
evt: Message event
min_level: Minimum required power level
room_id: Room ID to check permissions in
Returns:
bool: True if user has permissions
"""
return await self.bot.user_permitted(evt.sender, min_level, room_id)
async def check_parent_room(self, evt: MessageEvent) -> bool:
"""Check if parent room is configured.
Args:
evt: Message event
Returns:
bool: True if parent room is configured
"""
return await self.bot.check_parent_room(evt)
async def reply_error(self, evt: MessageEvent, message: str) -> None:
"""Reply with an error message.
Args:
evt: Message event
message: Error message
"""
await evt.reply(message)
async def reply_success(self, evt: MessageEvent, message: str) -> None:
"""Reply with a success message.
Args:
evt: Message event
message: Success message
"""
await evt.reply(message)
async def respond_html(self, evt: MessageEvent, message: str, edits: Optional[MessageEvent] = None) -> None:
"""Respond with HTML content.
Args:
evt: Message event
message: HTML message
edits: Optional message to edit
"""
await evt.respond(message, allow_html=True, edits=edits)
def is_tracking_enabled(self) -> bool:
"""Check if user tracking is enabled.
Returns:
bool: True if tracking is enabled
"""
return self.config_manager.is_tracking_enabled()
def is_verification_enabled(self) -> bool:
"""Check if verification is enabled.
Returns:
bool: True if verification is enabled
"""
return self.config_manager.is_verification_enabled()
def get_parent_room(self) -> Optional[str]:
"""Get the parent room ID.
Returns:
str: Parent room ID or None
"""
return self.config_manager.get_parent_room()
class TrackingCommandHandler(BaseCommandHandler):
"""Base handler for commands that require user tracking."""
async def execute(self, evt: MessageEvent, *args, **kwargs) -> Any:
"""Execute command with tracking check."""
if not self.is_tracking_enabled():
await self.reply_error(evt, "user tracking is disabled")
return
return await self.execute_tracking_command(evt, *args, **kwargs)
@abstractmethod
async def execute_tracking_command(self, evt: MessageEvent, *args, **kwargs) -> Any:
"""Execute the tracking command logic.
Args:
evt: Message event
*args: Command arguments
**kwargs: Additional keyword arguments
Returns:
Command result
"""
pass
class AdminCommandHandler(BaseCommandHandler):
"""Base handler for admin-only commands."""
async def execute(self, evt: MessageEvent, *args, **kwargs) -> Any:
"""Execute command with admin permission check."""
if not await self.check_permissions(evt, min_level=100):
await self.reply_error(evt, "You don't have permission to use this command")
return
return await self.execute_admin_command(evt, *args, **kwargs)
@abstractmethod
async def execute_admin_command(self, evt: MessageEvent, *args, **kwargs) -> Any:
"""Execute the admin command logic.
Args:
evt: Message event
*args: Command arguments
**kwargs: Additional keyword arguments
Returns:
Command result
"""
pass
class ModeratorCommandHandler(BaseCommandHandler):
"""Base handler for moderator commands."""
async def execute(self, evt: MessageEvent, *args, **kwargs) -> Any:
"""Execute command with moderator permission check."""
if not await self.check_permissions(evt, min_level=50):
await self.reply_error(evt, "You don't have permission to use this command")
return
return await self.execute_moderator_command(evt, *args, **kwargs)
@abstractmethod
async def execute_moderator_command(self, evt: MessageEvent, *args, **kwargs) -> Any:
"""Execute the moderator command logic.
Args:
evt: Message event
*args: Command arguments
**kwargs: Additional keyword arguments
Returns:
Command result
"""
pass
class SpaceCommandHandler(BaseCommandHandler):
"""Base handler for commands that require parent space."""
async def execute(self, evt: MessageEvent, *args, **kwargs) -> Any:
"""Execute command with parent space check."""
if not await self.check_parent_room(evt):
return
return await self.execute_space_command(evt, *args, **kwargs)
@abstractmethod
async def execute_space_command(self, evt: MessageEvent, *args, **kwargs) -> Any:
"""Execute the space command logic.
Args:
evt: Message event
*args: Command arguments
**kwargs: Additional keyword arguments
Returns:
Command result
"""
pass
class SpaceModeratorCommandHandler(SpaceCommandHandler, ModeratorCommandHandler):
"""Base handler for commands that require both parent space and moderator permissions."""
async def execute(self, evt: MessageEvent, *args, **kwargs) -> Any:
"""Execute command with both space and moderator checks."""
if not await self.check_parent_room(evt):
return
if not await self.check_permissions(evt, min_level=50):
await self.reply_error(evt, "You don't have permission to use this command")
return
return await self.execute_space_moderator_command(evt, *args, **kwargs)
@abstractmethod
async def execute_space_moderator_command(self, evt: MessageEvent, *args, **kwargs) -> Any:
"""Execute the space moderator command logic.
Args:
evt: Message event
*args: Command arguments
**kwargs: Additional keyword arguments
Returns:
Command result
"""
pass
class SpaceAdminCommandHandler(SpaceCommandHandler, AdminCommandHandler):
"""Base handler for commands that require both parent space and admin permissions."""
async def execute(self, evt: MessageEvent, *args, **kwargs) -> Any:
"""Execute command with both space and admin checks."""
if not await self.check_parent_room(evt):
return
if not await self.check_permissions(evt, min_level=100):
await self.reply_error(evt, "You don't have permission to use this command")
return
return await self.execute_space_admin_command(evt, *args, **kwargs)
@abstractmethod
async def execute_space_admin_command(self, evt: MessageEvent, *args, **kwargs) -> Any:
"""Execute the space admin command logic.
Args:
evt: Message event
*args: Command arguments
**kwargs: Additional keyword arguments
Returns:
Command result
"""
pass