138 lines
5.4 KiB
Python
138 lines
5.4 KiB
Python
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")
|
|
|