Fix: Recarga en caliente para canales y solución a caché estancado en MySQL
This commit is contained in:
@@ -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
43
botdiscord/bot_reload.py
Normal 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())
|
||||
@@ -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
|
||||
|
||||
60
botdiscord/reload_marker.py
Normal file
60
botdiscord/reload_marker.py
Normal 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()
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user