Signed-off-by: Omar Sánchez Pizarro <omar.sanchez@pistacero.net>
This commit is contained in:
Omar Sánchez Pizarro
2026-01-20 03:22:56 +01:00
parent 81bf0675ed
commit d28710b927
12 changed files with 1166 additions and 310 deletions

View File

@@ -0,0 +1,137 @@
import logging
import threading
from managers.telegram_manager import TelegramManager
from pymongo import MongoClient
from pymongo.errors import ConnectionFailure
class TelegramManagerFactory:
"""Factory para gestionar múltiples instancias de TelegramManager (una por usuario)"""
_instances = {} # Dict: username -> TelegramManager
_lock = threading.Lock()
_mongodb_client = None
_mongodb_config = None
@classmethod
def initialize(cls, mongodb_config=None):
"""Inicializa la factory con configuración de MongoDB"""
cls._mongodb_config = mongodb_config
cls.logger = logging.getLogger(__name__)
@classmethod
def _get_mongodb_client(cls):
"""Obtiene cliente de MongoDB para leer configuración de Telegram"""
if cls._mongodb_client is not None:
return cls._mongodb_client
if not cls._mongodb_config:
return None
try:
mongodb_config = cls._mongodb_config.get('mongodb', {})
mongodb_host = mongodb_config.get('host', 'localhost')
mongodb_port = mongodb_config.get('port', 27017)
mongodb_database = mongodb_config.get('database', 'wallabicher')
mongodb_username = mongodb_config.get('username')
mongodb_password = mongodb_config.get('password')
mongodb_auth_source = mongodb_config.get('auth_source', 'admin')
if mongodb_username and mongodb_password:
connection_string = f"mongodb://{mongodb_username}:{mongodb_password}@{mongodb_host}:{mongodb_port}/?authSource={mongodb_auth_source}"
else:
connection_string = f"mongodb://{mongodb_host}:{mongodb_port}/"
client = MongoClient(connection_string, serverSelectionTimeoutMS=5000)
client.admin.command('ping')
cls._mongodb_client = client[mongodb_database]
return cls._mongodb_client
except Exception as e:
cls.logger.error(f"Error conectando a MongoDB para configuración de Telegram: {e}")
return None
@classmethod
def get_telegram_config(cls, username):
"""Obtiene configuración de Telegram para un usuario desde MongoDB"""
db = cls._get_mongodb_client()
if db is None:
return None
try:
users_collection = db['users']
user = users_collection.find_one({'username': username})
if user and 'telegram' in user:
telegram_config = user['telegram']
return {
'token': telegram_config.get('token'),
'channel': telegram_config.get('channel'),
'enable_polling': telegram_config.get('enable_polling', False)
}
except Exception as e:
cls.logger.error(f"Error obteniendo configuración de Telegram para {username}: {e}")
return None
@classmethod
def get_manager(cls, username):
"""
Obtiene o crea un TelegramManager para un usuario específico
Args:
username: Nombre de usuario
Returns:
TelegramManager o None si no hay configuración
"""
if username is None:
# Si no hay username, usar configuración global (compatibilidad)
with cls._lock:
if 'global' not in cls._instances:
try:
cls._instances['global'] = TelegramManager()
except Exception as e:
cls.logger.error(f"Error creando TelegramManager global: {e}")
return None
return cls._instances.get('global')
with cls._lock:
# Si ya existe, retornarlo
if username in cls._instances:
return cls._instances[username]
# Obtener configuración de MongoDB
config = cls.get_telegram_config(username)
if not config or not config.get('token') or not config.get('channel'):
cls.logger.warning(f"No hay configuración de Telegram para usuario '{username}'")
return None
# Crear nueva instancia
try:
manager = TelegramManager(
token=config['token'],
channel=config['channel'],
enable_polling=config.get('enable_polling', False),
username=username
)
cls._instances[username] = manager
cls.logger.info(f"TelegramManager creado para usuario '{username}'")
return manager
except Exception as e:
cls.logger.error(f"Error creando TelegramManager para usuario '{username}': {e}")
return None
@classmethod
def remove_manager(cls, username):
"""Elimina un TelegramManager del cache"""
with cls._lock:
if username in cls._instances:
del cls._instances[username]
cls.logger.info(f"TelegramManager eliminado del cache para usuario '{username}'")
@classmethod
def clear_cache(cls):
"""Limpia todo el cache de managers"""
with cls._lock:
cls._instances.clear()
cls.logger.info("Cache de TelegramManager limpiado")