# -*- coding: utf-8 -*- """ Базовый класс для всех команд бота. Реализует: - алиасы (альтернативные имена команд) - проверку прав доступа (admin) - парсинг аргументов (через core.utils.arg_parser) - метод справки get_help() - кэширование результатов (опционально) Изменения для групповой работы: - метод execute теперь принимает дополнительный параметр room_jid (None для личных чатов). - Команды, которым нужен контекст комнаты, могут его использовать. """ from abc import ABC, abstractmethod from typing import TYPE_CHECKING, Dict, Any, Tuple, List, Optional import time from core.utils.arg_parser import parse_args # путь изменён: arg_parser перенесён в utils if TYPE_CHECKING: from core.xmpp.client import Bot # обновлённый импорт class Command(ABC): """Абстрактный базовый класс команды. Все команды должны наследоваться от него.""" # Основное имя команды (например "!info") name: str = None # Альтернативные имена (например ["!help", "!справка"]) aliases: List[str] = [] # Необходимые права: None – любой, "admin" – только администраторы permission: Optional[str] = None # Время жизни кэша в секундах (0 – не кэшировать) cache_ttl: int = 0 def __init__(self, bot: 'Bot'): self.bot = bot # Кэш: ключ -> (время, результат) self._cache: Dict[str, Tuple[float, Any]] = {} @abstractmethod async def execute(self, msg, args: str, user_jid: str, room_jid: str = None): """ Выполнить команду. :param msg: объект сообщения slixmpp (для ответа) :param args: полная строка аргументов (включая имя команды) :param user_jid: JID пользователя (без ресурса) :param room_jid: JID комнаты, если команда вызвана в групповом чате; иначе None """ pass def get_help(self) -> str: """Возвращает строку справки для команды. Переопределяется в дочерних классах.""" return "Нет описания." def check_permission(self, user_jid: str) -> bool: """Проверяет, имеет ли пользователь право на выполнение команды.""" if self.permission is None: return True if self.permission == "admin": return user_jid in self.bot.config.admin_jids return False def get_cache_key(self, user_jid: str, args: str) -> str: """Формирует ключ для кэширования (по умолчанию user_jid).""" return user_jid def parse_args(self, args_str: str) -> Tuple[str, Dict[str, Any], List[str]]: """Разбирает строку аргументов на команду, флаги и позиционные аргументы.""" return parse_args(args_str) def _cache_result(self, key: str, result: str): """Сохраняет результат в кэш (вызывается из команды).""" self._cache[key] = (time.time(), result)