mongodb
Signed-off-by: Omar Sánchez Pizarro <omar.sanchez@pistacero.net>
This commit is contained in:
137
managers/telegram_manager_factory.py
Normal file
137
managers/telegram_manager_factory.py
Normal 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")
|
||||
|
||||
Reference in New Issue
Block a user