77 lines
3.7 KiB
Python
77 lines
3.7 KiB
Python
# -*- 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) |