mirror of
https://github.com/agessaman/meshcore-bot.git
synced 2026-09-16 21:02:35 +00:00
refactor: move command aliases to per-command config section
Each command's aliases are now configured as an `aliases` key in its own config section (e.g. [Wx_Command] aliases = !weather, !w) rather than a separate [Aliases] section. BaseCommand._load_aliases_from_config() reads and injects them into keywords at startup. CommandManager.load_aliases() and _apply_aliases() are removed. No behaviour change for commands without aliases configured.
This commit is contained in:
@@ -95,10 +95,6 @@ class CommandManager:
|
||||
self.plugin_loader = PluginLoader(bot, local_commands_dir=local_commands_dir)
|
||||
self.commands = self.plugin_loader.load_all_plugins()
|
||||
|
||||
# Load aliases and inject them into command keyword lists
|
||||
self.aliases = self.load_aliases()
|
||||
self._apply_aliases()
|
||||
|
||||
# Cache for internet connectivity status to avoid checking on every command
|
||||
# Thread-safe cache with asyncio.Lock
|
||||
self._internet_cache = InternetStatusCache(has_internet=True, timestamp=0)
|
||||
@@ -500,49 +496,6 @@ class CommandManager:
|
||||
prefix = self.bot.config.get('Bot', 'command_prefix', fallback='')
|
||||
return prefix.strip() if prefix else ''
|
||||
|
||||
def load_aliases(self) -> dict[str, str]:
|
||||
"""Load command aliases from the ``[Aliases]`` config section.
|
||||
|
||||
Each entry maps a short alias to a canonical command name, e.g.::
|
||||
|
||||
[Aliases]
|
||||
s = schedule
|
||||
wx = weather
|
||||
|
||||
Returns:
|
||||
Dict[str, str]: alias → canonical command name (both lowercase).
|
||||
"""
|
||||
aliases: dict[str, str] = {}
|
||||
if not self.bot.config.has_section('Aliases'):
|
||||
return aliases
|
||||
for alias, canonical in self.bot.config.items('Aliases'):
|
||||
alias = alias.strip().lower()
|
||||
canonical = canonical.strip().lower()
|
||||
if alias and canonical:
|
||||
aliases[alias] = canonical
|
||||
return aliases
|
||||
|
||||
def _apply_aliases(self) -> None:
|
||||
"""Inject each alias into the keyword list of its canonical command.
|
||||
|
||||
This lets the existing ``matches_keyword()`` dispatch handle aliases
|
||||
transparently — no changes needed in ``check_keywords()``.
|
||||
|
||||
Unknown aliases (pointing to commands that are not loaded) are logged
|
||||
and skipped.
|
||||
"""
|
||||
for alias, canonical in self.aliases.items():
|
||||
command = self.commands.get(canonical)
|
||||
if command is None:
|
||||
self.logger.warning(
|
||||
f"Alias '{alias}' → '{canonical}' skipped: "
|
||||
f"command '{canonical}' is not loaded"
|
||||
)
|
||||
continue
|
||||
if alias not in [k.lower() for k in command.keywords]:
|
||||
command.keywords.append(alias)
|
||||
self.logger.debug(f"Alias '{alias}' → '{canonical}' registered")
|
||||
|
||||
def format_keyword_response(self, response_format: str, message: MeshMessage) -> str:
|
||||
"""Format a keyword response string with message data.
|
||||
|
||||
|
||||
@@ -48,6 +48,9 @@ class BaseCommand(ABC):
|
||||
# Load allowed channels from config (standardized channel override)
|
||||
self.allowed_channels = self._load_allowed_channels()
|
||||
|
||||
# Load aliases from this command's config section and extend keywords
|
||||
self._load_aliases_from_config()
|
||||
|
||||
# Load translated keywords after initialization
|
||||
self._load_translated_keywords()
|
||||
|
||||
@@ -356,6 +359,27 @@ class BaseCommand(ABC):
|
||||
channels = [ch.strip() for ch in channels_str.split(',') if ch.strip()]
|
||||
return channels if channels else None
|
||||
|
||||
def _load_aliases_from_config(self) -> None:
|
||||
"""Load aliases from this command's own config section and extend keywords.
|
||||
|
||||
Config format::
|
||||
|
||||
[Wx_Command]
|
||||
aliases = !weather, !w
|
||||
|
||||
Each alias is appended to ``self.keywords`` if not already present.
|
||||
"""
|
||||
section_name = self._derive_config_section_name()
|
||||
aliases_str = self.get_config_value(section_name, 'aliases', fallback=None, value_type='str')
|
||||
if not aliases_str:
|
||||
return
|
||||
for alias in aliases_str.split(','):
|
||||
alias = alias.strip().lower()
|
||||
if alias and alias not in [k.lower() for k in self.keywords]:
|
||||
self.keywords = list(self.keywords) # ensure instance-level list
|
||||
self.keywords.append(alias)
|
||||
self.logger.debug(f"Alias '{alias}' registered for command '{self.name}'")
|
||||
|
||||
def is_channel_allowed(self, message: MeshMessage) -> bool:
|
||||
"""Check if this command is allowed in the message's channel.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user