import re import os import time from .download_audio_services import get_downloader class CommandHandler: def __init__(self, bot): self.bot = bot self.commands = self._register_commands() def _register_commands(self): """Регистрация всех доступных команд""" return { "help": { "handler": self.cmd_help, "description": "Показать справку по командам", "public": True }, "ping": { "handler": self.cmd_ping, "description": "Проверить работоспособность бота", "public": True }, "mp3": { "handler": self.cmd_mp3, "description": f"Скачать аудио из YouTube. Использование: {self.bot.config['command_prefix']} mp3 ", "public": True }, # Здесь можно добавлять новые команды } def generate_help_text(self, detailed=False): """Генерация текста справки""" if detailed: text = f"**Полная справка по командам бота**\n\nВсе команды начинаются с `{self.bot.config['command_prefix']}`:\n" for cmd, info in self.commands.items(): if info.get("public", False): text += f"\n• `{self.bot.config['command_prefix']} {cmd}` - {info['description']}" text += "\n\nБот игнорирует сообщения без префикса команды." return text return ( f"Привет! Я бот PingPong. Для взаимодействия используйте команды " f"с префиксом `{self.bot.config['command_prefix']}`. " f"Напишите `{self.bot.config['command_prefix']} help` для получения полной справки." ) # --- Обработчики команд --- async def cmd_help(self, room_id, event, args): await self.bot.send_text(room_id, self.generate_help_text(detailed=True)) async def cmd_ping(self, room_id, event, args): await self.bot.send_text(room_id, "pong") async def cmd_mp3(self, room_id, event, args): """Обработчик команды mp3""" if not args: await self.bot.send_text( room_id, "❌ Укажите URL видео. Например: `/media mp3 https://www.youtube.com/watch?v=...`" ) return url = args.strip() download_config = self.bot.config.get('download_audio', {}) downloader_config = None # Определяем загрузчик для URL downloader = None for service, config in download_config.get('services', {}).items(): if config.get('enabled', False): downloader_config = config dl_class = get_downloader(service) if dl_class: downloader = dl_class() if downloader.is_supported_url(url): break else: downloader = None downloader_config = None if not downloader: await self.bot.send_text(room_id, "❌ Этот сервис не поддерживается.") return # Уведомляем о начале загрузки await self.bot.send_text(room_id, "⏳ Начинаю загрузку... Это может занять несколько минут.") try: # Запускаем загрузку file_path, title_or_error, duration = await downloader.download_audio(url, downloader_config) if not file_path: raise Exception(title_or_error or "Ошибка загрузки") # Простой метод отправки файла with open(file_path, 'rb') as f: # Получаем размер файла file_size = os.path.getsize(file_path) # Загружаем файл на сервер Matrix mime_type = "audio/mpeg" response, _ = await self.bot.client.upload( f, content_type=mime_type, filename=f"{title_or_error}.mp3" ) # Формируем сообщение с аудио audio_content = { "body": f"{title_or_error}.mp3", "info": { "mimetype": mime_type, "size": file_size, "duration": duration or 0 # Можно оставить 0, если длительность неизвестна }, "msgtype": "m.audio", "url": response.content_uri, } # Отправляем сообщение await self.bot.client.room_send( room_id, message_type="m.room.message", content=audio_content ) await self.bot.send_text(room_id, "✅ Готово! Аудио отправлено.") except Exception as e: error_msg = f"⚠️ Ошибка при загрузке: {str(e)}" await self.bot.send_text(room_id, error_msg) print(f"[ERROR] MP3 download failed: {str(e)}") finally: # Очистка временных файлов if file_path and os.path.exists(file_path): try: os.remove(file_path) except: pass # --- Обработка входящих команд --- async def process_command(self, room_id, event): """Обработка и выполнение команд""" msg = event.body.strip() command_prefix = self.bot.config["command_prefix"] # Проверяем префикс команды if not msg.startswith(command_prefix): return # Извлекаем команду и аргументы cmd_parts = re.split(r'\s+', msg[len(command_prefix):].strip(), maxsplit=1) command = cmd_parts[0].lower() args = cmd_parts[1] if len(cmd_parts) > 1 else "" # Ищем обработчик команды cmd_info = self.commands.get(command) if not cmd_info: await self.bot.send_text( room_id, f"Неизвестная команда. Используйте `{command_prefix} help` для справки." ) return try: # Выполняем команду await cmd_info["handler"](room_id, event, args) except Exception as e: print(f"[ERROR] Command '{command}' failed: {str(e)}") await self.bot.send_text(room_id, "⚠️ Произошла ошибка при выполнении команды")