83 lines
4.0 KiB
Python
83 lines
4.0 KiB
Python
# -*- 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}")
|
||
# Бот не сможет войти, но комната остаётся на сервере.
|
||
# Можно удалить комнату с сервера, если нужно. |