mongodb
Signed-off-by: Omar Sánchez Pizarro <omar.sanchez@pistacero.net>
This commit is contained in:
@@ -26,10 +26,29 @@ ITEM_HTML = """
|
||||
"""
|
||||
|
||||
class TelegramManager:
|
||||
def __init__(self):
|
||||
def __init__(self, token=None, channel=None, enable_polling=True, username=None):
|
||||
"""
|
||||
Inicializa TelegramManager con configuración específica
|
||||
|
||||
Args:
|
||||
token: Token del bot de Telegram (si None, intenta leer de config.yaml)
|
||||
channel: Canal de Telegram (si None, intenta leer de config.yaml)
|
||||
enable_polling: Si iniciar el polling del bot
|
||||
username: Usuario propietario de esta configuración (para logging)
|
||||
"""
|
||||
self.logger = logging.getLogger(__name__)
|
||||
token, channel = self.get_config()
|
||||
self._username = username
|
||||
|
||||
# Si no se proporcionan token/channel, intentar leer de config.yaml (compatibilidad)
|
||||
if token is None or channel is None:
|
||||
token, channel, enable_polling = self._get_config_from_file()
|
||||
|
||||
if not token or not channel:
|
||||
raise ValueError("Token y channel de Telegram son requeridos")
|
||||
|
||||
self._channel = channel
|
||||
self._token = token
|
||||
|
||||
# Use ApplicationBuilder to create the bot application with increased timeouts
|
||||
self._application = telegram.ext.ApplicationBuilder() \
|
||||
.token(token) \
|
||||
@@ -42,26 +61,35 @@ class TelegramManager:
|
||||
self._loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(self._loop)
|
||||
|
||||
# Inicializar Redis para favoritos
|
||||
self._article_cache = self._init_redis_cache()
|
||||
# Inicializar MongoDB para favoritos
|
||||
self._article_cache = self._init_mongodb_cache()
|
||||
|
||||
# Añadir handlers para comandos y callbacks
|
||||
self._add_handlers()
|
||||
|
||||
# Iniciar polling en un thread separado
|
||||
self._start_polling()
|
||||
# Iniciar polling en un thread separado solo si está habilitado
|
||||
if enable_polling:
|
||||
self._start_polling()
|
||||
else:
|
||||
self.logger.info(f"Polling deshabilitado por configuración{' para usuario ' + username if username else ''}")
|
||||
|
||||
def get_config(self):
|
||||
def _get_config_from_file(self):
|
||||
"""Lee configuración de config.yaml (para compatibilidad hacia atrás)"""
|
||||
base_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
config_file = os.path.join(os.path.dirname(base_dir), 'config.yaml')
|
||||
with open(config_file, 'r') as file:
|
||||
config = yaml.safe_load(file)
|
||||
token = config['telegram_token']
|
||||
telegram_channel = config['telegram_channel']
|
||||
return token, telegram_channel
|
||||
try:
|
||||
with open(config_file, 'r') as file:
|
||||
config = yaml.safe_load(file)
|
||||
token = config.get('telegram_token')
|
||||
telegram_channel = config.get('telegram_channel')
|
||||
enable_polling = config.get('enable_polling', True)
|
||||
return token, telegram_channel, enable_polling
|
||||
except Exception as e:
|
||||
self.logger.warning(f"No se pudo leer config.yaml: {e}")
|
||||
return None, None, False
|
||||
|
||||
def _init_redis_cache(self):
|
||||
"""Inicializa Redis cache para favoritos"""
|
||||
def _init_mongodb_cache(self):
|
||||
"""Inicializa MongoDB cache para favoritos"""
|
||||
try:
|
||||
base_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
config_file = os.path.join(os.path.dirname(base_dir), 'config.yaml')
|
||||
@@ -69,20 +97,22 @@ class TelegramManager:
|
||||
config = yaml.safe_load(file)
|
||||
|
||||
cache_config = config.get('cache', {})
|
||||
if cache_config.get('type') == 'redis':
|
||||
redis_config = cache_config.get('redis', {})
|
||||
if cache_config.get('type') == 'mongodb':
|
||||
mongodb_config = cache_config.get('mongodb', {})
|
||||
return create_article_cache(
|
||||
cache_type='redis',
|
||||
redis_host=redis_config.get('host', 'localhost'),
|
||||
redis_port=redis_config.get('port', 6379),
|
||||
redis_db=redis_config.get('db', 0),
|
||||
redis_password=redis_config.get('password')
|
||||
cache_type='mongodb',
|
||||
mongodb_host=os.environ.get('MONGODB_HOST') or mongodb_config.get('host', 'localhost'),
|
||||
mongodb_port=int(os.environ.get('MONGODB_PORT') or mongodb_config.get('port', 27017)),
|
||||
mongodb_database=os.environ.get('MONGODB_DATABASE') or mongodb_config.get('database', 'wallabicher'),
|
||||
mongodb_username=os.environ.get('MONGODB_USERNAME') or mongodb_config.get('username'),
|
||||
mongodb_password=os.environ.get('MONGODB_PASSWORD') or mongodb_config.get('password'),
|
||||
mongodb_auth_source=mongodb_config.get('auth_source', 'admin')
|
||||
)
|
||||
else:
|
||||
self.logger.warning("Redis no configurado para favoritos, se requiere Redis")
|
||||
self.logger.warning("MongoDB no configurado para favoritos, se requiere MongoDB")
|
||||
return None
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error inicializando Redis para favoritos: {e}")
|
||||
self.logger.error(f"Error inicializando MongoDB para favoritos: {e}")
|
||||
return None
|
||||
|
||||
def escape_html(self, text):
|
||||
@@ -198,7 +228,8 @@ class TelegramManager:
|
||||
"""Inicia el bot en modo polling en un thread separado"""
|
||||
def run_polling():
|
||||
try:
|
||||
self.logger.info("Iniciando polling de Telegram bot...")
|
||||
user_info = f" para usuario '{self._username}'" if self._username else ""
|
||||
self.logger.info(f"Iniciando polling de Telegram bot{user_info}...")
|
||||
# Crear un nuevo event loop para este thread
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
@@ -208,11 +239,13 @@ class TelegramManager:
|
||||
loop.create_task(self._application.updater.start_polling(allowed_updates=["message", "callback_query"]))
|
||||
loop.run_forever()
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error en polling: {e}")
|
||||
user_info = f" (usuario: {self._username})" if self._username else ""
|
||||
self.logger.error(f"Error en polling{user_info}: {e}")
|
||||
|
||||
polling_thread = threading.Thread(target=run_polling, daemon=True)
|
||||
polling_thread.start()
|
||||
self.logger.info("Thread de polling iniciado")
|
||||
user_info = f" para usuario '{self._username}'" if self._username else ""
|
||||
self.logger.info(f"Thread de polling iniciado{user_info}")
|
||||
|
||||
async def handle_favorite_callback(self, update: telegram.Update, context: telegram.ext.ContextTypes.DEFAULT_TYPE):
|
||||
"""Maneja el callback cuando se presiona el botón de favoritos"""
|
||||
@@ -220,7 +253,7 @@ class TelegramManager:
|
||||
await query.answer()
|
||||
|
||||
if not self._article_cache:
|
||||
await query.edit_message_text("❌ Redis no está disponible para favoritos")
|
||||
await query.edit_message_text("❌ MongoDB no está disponible para favoritos")
|
||||
return
|
||||
|
||||
# Extraer plataforma, ID del artículo y nombre de búsqueda del callback_data
|
||||
@@ -241,23 +274,23 @@ class TelegramManager:
|
||||
await query.message.reply_text("ℹ️ Este artículo ya está en favoritos")
|
||||
return
|
||||
|
||||
# Obtener la URL del artículo desde Redis
|
||||
# Obtener la URL del artículo desde MongoDB
|
||||
url = ""
|
||||
try:
|
||||
redis_client = self._article_cache._redis_client
|
||||
key = f"notified:{platform}:{article_id}"
|
||||
value = redis_client.get(key)
|
||||
if value:
|
||||
article_data = json.loads(value)
|
||||
url = article_data.get('url', '')
|
||||
article = self._article_cache._articles_collection.find_one({
|
||||
'platform': platform,
|
||||
'id': str(article_id)
|
||||
})
|
||||
if article:
|
||||
url = article.get('url', '')
|
||||
except Exception as e:
|
||||
self.logger.debug(f"Error obteniendo URL: {e}")
|
||||
|
||||
# Marcar como favorito en Redis
|
||||
# Marcar como favorito en MongoDB
|
||||
success = self._article_cache.set_favorite(platform, article_id, is_favorite=True)
|
||||
|
||||
if not success:
|
||||
await query.edit_message_text("❌ No se pudo encontrar el artículo en Redis")
|
||||
await query.edit_message_text("❌ No se pudo encontrar el artículo en MongoDB")
|
||||
return
|
||||
|
||||
# Actualizar el mensaje del botón
|
||||
@@ -320,7 +353,7 @@ class TelegramManager:
|
||||
async def handle_favs_command(self, update: telegram.Update, context: telegram.ext.ContextTypes.DEFAULT_TYPE):
|
||||
"""Maneja el comando /favs para mostrar los favoritos"""
|
||||
if not self._article_cache:
|
||||
await update.message.reply_text("❌ Redis no está disponible para favoritos")
|
||||
await update.message.reply_text("❌ MongoDB no está disponible para favoritos")
|
||||
return
|
||||
|
||||
favorites = self._article_cache.get_favorites()
|
||||
@@ -357,7 +390,7 @@ class TelegramManager:
|
||||
await query.answer()
|
||||
|
||||
if not self._article_cache:
|
||||
await query.edit_message_text("❌ Redis no está disponible para favoritos")
|
||||
await query.edit_message_text("❌ MongoDB no está disponible para favoritos")
|
||||
return
|
||||
|
||||
# Extraer plataforma e ID del artículo del callback_data
|
||||
@@ -372,19 +405,19 @@ class TelegramManager:
|
||||
platform = parts[1]
|
||||
article_id = parts[2]
|
||||
|
||||
# Obtener la URL del artículo desde Redis antes de desmarcar
|
||||
# Obtener la URL del artículo desde MongoDB antes de desmarcar
|
||||
url = ""
|
||||
try:
|
||||
redis_client = self._article_cache._redis_client
|
||||
key = f"notified:{platform}:{article_id}"
|
||||
value = redis_client.get(key)
|
||||
if value:
|
||||
article_data = json.loads(value)
|
||||
url = article_data.get('url', '')
|
||||
article = self._article_cache._articles_collection.find_one({
|
||||
'platform': platform,
|
||||
'id': str(article_id)
|
||||
})
|
||||
if article:
|
||||
url = article.get('url', '')
|
||||
except Exception as e:
|
||||
self.logger.debug(f"Error obteniendo URL: {e}")
|
||||
|
||||
# Desmarcar como favorito en Redis
|
||||
# Desmarcar como favorito en MongoDB
|
||||
success = self._article_cache.set_favorite(platform, article_id, is_favorite=False)
|
||||
|
||||
if not success:
|
||||
|
||||
Reference in New Issue
Block a user