Fix: Recarga en caliente para canales y solución a caché estancado en MySQL

This commit is contained in:
2026-03-20 13:01:26 -06:00
parent 97ce9fce86
commit df56e7d841
5 changed files with 135 additions and 9 deletions

View File

@@ -5,9 +5,10 @@ import time
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import discord
from discord.ext import commands
from discord.ext import commands, tasks
from discord import app_commands
import re
from botdiscord.reload_marker import check_reload_marker
import html
from botdiscord.config import get_discord_token, load_config, get_languages
@@ -22,6 +23,17 @@ intents.message_content = True
intents.members = True
bot = commands.Bot(command_prefix="!", intents=intents)
@tasks.loop(seconds=3)
async def restart_monitor():
if check_reload_marker():
print("[Bot] Cambios desde panel detectados. Recargando configuraciones sin reiniciar...")
from botdiscord.database import clear_channel_cache
from botdiscord.translate import load_lang_mappings
from botdiscord.config import load_config
clear_channel_cache()
load_config()
load_lang_mappings("discord")
@bot.event
async def on_ready():
init_db()
@@ -30,12 +42,15 @@ async def on_ready():
bot.add_view(PersistentTranslationView())
bot.add_view(WelcomeTranslationView())
if not restart_monitor.is_running():
restart_monitor.start()
print(f"Bot Discord conectado como {bot.user}")
try:
synced = await bot.tree.sync()
print(f"Sincronizados {len(synced)} comandos.")
except Exception as e:
print(f"Error sync: {e}")
# try:
# synced = await bot.tree.sync()
# print(f"Sincronizados {len(synced)} comandos.")
# except Exception as e:
# print(f"Error sync: {e}")
@bot.event
async def on_member_join(member):

43
botdiscord/bot_reload.py Normal file
View File

@@ -0,0 +1,43 @@
import asyncio
import sys
import os
# Agregar el path del proyecto para importar configuración
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from botdiscord.config import load_config, get_discord_token
from botdiscord.database import clear_channel_cache
async def reload_bot_config():
"""
Recarga la configuración del bot y limpia caches
"""
try:
print("[Bot Reload] Iniciando recarga de configuración...")
# Limpiar cache de canales
clear_channel_cache()
print("[Bot Reload] Cache de canales limpiado")
# Recargar configuración
load_config()
print("[Bot Reload] Configuración recargada")
# Verificar token
token = get_discord_token()
if token:
print(f"[Bot Reload] Token encontrado: {bool(token)}")
else:
print("[Bot Reload] ADVERTENCIA: No se encontró token de Discord")
print("[Bot Reload] ✅ Recarga completada")
return True
except Exception as e:
print(f"[Bot Reload] Error en recarga: {e}")
import traceback
traceback.print_exc()
return False
if __name__ == "__main__":
asyncio.run(reload_bot_config())

View File

@@ -26,7 +26,8 @@ def get_connection():
password=db_config.get("password"),
database=db_config.get("name"),
consume_results=True,
connection_timeout=10
connection_timeout=10,
autocommit=True
)
print(f"[DB] MySQL conectado exitosamente")
break
@@ -52,7 +53,8 @@ def get_connection():
password=db_config.get("password"),
database=db_config.get("name"),
consume_results=True,
connection_timeout=10
connection_timeout=10,
autocommit=True
)
print(f"[DB] MySQL reconectado exitosamente")
break
@@ -72,7 +74,7 @@ def get_connection():
db_dir = os.path.dirname(db_path)
if db_dir and not os.path.exists(db_dir):
os.makedirs(db_dir, exist_ok=True)
return sqlite3.connect(db_path)
return sqlite3.connect(db_path, isolation_level=None)
def close_connection():
global _connection

View File

@@ -0,0 +1,60 @@
import os
import time
import json
import threading
MARKER_FILE = "/tmp/bot_reload_marker"
_last_marker_time = 0
_marker_lock = threading.Lock()
def set_reload_marker():
"""Crea un marcador para indicar que se necesita recarga"""
global _last_marker_time
with _marker_lock:
current_time = time.time()
# Evitar crear marcadores muy seguidos (mínimo 2 segundos)
if current_time - _last_marker_time < 2:
print(f"[Marker] Marcador omitido (demasiado pronto)")
return False
try:
with open(MARKER_FILE, 'w') as f:
json.dump({
'timestamp': current_time,
'reason': 'channel_toggle'
}, f)
_last_marker_time = current_time
print(f"[Marker] Marcador de recarga creado")
return True
except Exception as e:
print(f"[Marker] Error creando marcador: {e}")
return False
def check_reload_marker():
"""Verifica si existe un marcador de recarga"""
try:
if os.path.exists(MARKER_FILE):
with open(MARKER_FILE, 'r') as f:
data = json.load(f)
# Eliminar el marcador
os.remove(MARKER_FILE)
print(f"[Marker] Marcador encontrado y eliminado: {data}")
return True
return False
except Exception as e:
print(f"[Marker] Error verificando marcador: {e}")
return False
def clear_all_markers():
"""Limpia todos los marcadores existentes"""
try:
if os.path.exists(MARKER_FILE):
os.remove(MARKER_FILE)
print(f"[Marker] Todos los marcadores limpiados")
except Exception as e:
print(f"[Marker] Error limpiando marcadores: {e}")
if __name__ == "__main__":
set_reload_marker()

View File

@@ -476,7 +476,9 @@ async def toggle_discord_channel(request: Request):
try:
from botdiscord.database import toggle_channel_status
from botdiscord.reload_marker import set_reload_marker
toggle_channel_status(int(channel_id), is_active)
set_reload_marker()
return RedirectResponse(url="/discord-channels?success=1", status_code=status.HTTP_303_SEE_OTHER)
except Exception as e:
print(f"Error toggling channel: {e}")
@@ -495,7 +497,9 @@ async def delete_discord_server(request: Request):
try:
from botdiscord.database import delete_discord_server
from botdiscord.reload_marker import set_reload_marker
delete_discord_server(int(server_id))
set_reload_marker()
return RedirectResponse(url="/discord-channels?success=1", status_code=status.HTTP_303_SEE_OTHER)
except Exception as e:
print(f"Error deleting server: {e}")
@@ -550,6 +554,8 @@ async def bulk_toggle_discord_channels(request: Request):
continue
print(f"[Panel] Bulk toggle: {success_count} canales {'activados' if is_active else 'desactivados'}")
from botdiscord.reload_marker import set_reload_marker
set_reload_marker()
return RedirectResponse(url="/discord-channels?success=1", status_code=status.HTTP_303_SEE_OTHER)
except Exception as e: