# -*- coding: utf-8 -*- """ Обработчик MUC комнат (Multi-User Chat). - Автоматический вход по приглашению (комната сохраняется на сервере). - Периодическая проверка присутствия в комнатах и переподключение при необходимости. - Загрузка комнат с сервера при старте. """ import logging import asyncio logger = logging.getLogger(__name__) class RoomHandler: """Управление комнатами: приглашения, реджоин, сохранение в БД через RAG-сервер.""" def __init__(self, bot): self.bot = bot async def accept_invite(self, inv): """ Обработчик события groupchat_invite. Автоматически входит в комнату, добавляет её на сервер. """ room = inv.get('room', inv.get('from')) if not room: logger.warning("Приглашение не содержит идентификатора комнаты") return room_str = room.bare if hasattr(room, 'bare') else str(room) logger.info(f"Приглашение в комнату {room_str}, входим.") # Сохраняем комнату на сервере try: await self.bot.rag_client.add_room(room_str) except Exception as e: logger.error(f"Ошибка сохранения комнаты на сервере: {e}") # Входим в MUC-комнату await self.bot.plugin['xep_0045'].join_muc(room_str, self.bot.boundjid.user) async def rejoin_loop(self): """ Бесконечный цикл переподключения к комнатам. Загружает список комнат с сервера и входит в те, где бот отсутствует. """ while True: await asyncio.sleep(60) joined_rooms = set() try: joined_rooms = {str(r) for r in self.bot.plugin['xep_0045'].rooms.keys()} except Exception as e: logger.debug(f"Ошибка получения списка комнат: {e}") continue try: rooms = await self.bot.rag_client.get_rooms() except Exception as e: logger.error(f"Ошибка загрузки комнат с сервера: {e}") continue for room in rooms: if room not in joined_rooms: logger.info(f"Попытка повторного входа в комнату {room}...") try: await self.bot.plugin['xep_0045'].join_muc(room, self.bot.boundjid.user) await asyncio.sleep(1) except Exception as e: logger.error(f"Ошибка входа в {room}: {e}") async def on_kicked(self, presence): """Обработчик события, когда бота исключают из комнаты.""" room = presence['from'].bare logger.info(f"Бот был исключён из комнаты {room}") # Комната остаётся на сервере, но бот перестаёт в ней состоять. # При следующем цикле rejoin он войдёт снова, если комната есть в списке. async def on_banned(self, presence): """Обработчик события, когда бота банят в комнате.""" room = presence['from'].bare logger.info(f"Бот был забанен в комнате {room}") # Бот не сможет войти, но комната остаётся на сервере. # Можно удалить комнату с сервера, если нужно.