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__))))
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands, tasks
|
||||||
from discord import app_commands
|
from discord import app_commands
|
||||||
import re
|
import re
|
||||||
|
from botdiscord.reload_marker import check_reload_marker
|
||||||
import html
|
import html
|
||||||
|
|
||||||
from botdiscord.config import get_discord_token, load_config, get_languages
|
from botdiscord.config import get_discord_token, load_config, get_languages
|
||||||
@@ -22,6 +23,17 @@ intents.message_content = True
|
|||||||
intents.members = True
|
intents.members = True
|
||||||
bot = commands.Bot(command_prefix="!", intents=intents)
|
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
|
@bot.event
|
||||||
async def on_ready():
|
async def on_ready():
|
||||||
init_db()
|
init_db()
|
||||||
@@ -30,12 +42,15 @@ async def on_ready():
|
|||||||
bot.add_view(PersistentTranslationView())
|
bot.add_view(PersistentTranslationView())
|
||||||
bot.add_view(WelcomeTranslationView())
|
bot.add_view(WelcomeTranslationView())
|
||||||
|
|
||||||
|
if not restart_monitor.is_running():
|
||||||
|
restart_monitor.start()
|
||||||
|
|
||||||
print(f"Bot Discord conectado como {bot.user}")
|
print(f"Bot Discord conectado como {bot.user}")
|
||||||
try:
|
# try:
|
||||||
synced = await bot.tree.sync()
|
# synced = await bot.tree.sync()
|
||||||
print(f"Sincronizados {len(synced)} comandos.")
|
# print(f"Sincronizados {len(synced)} comandos.")
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
print(f"Error sync: {e}")
|
# print(f"Error sync: {e}")
|
||||||
|
|
||||||
@bot.event
|
@bot.event
|
||||||
async def on_member_join(member):
|
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"),
|
password=db_config.get("password"),
|
||||||
database=db_config.get("name"),
|
database=db_config.get("name"),
|
||||||
consume_results=True,
|
consume_results=True,
|
||||||
connection_timeout=10
|
connection_timeout=10,
|
||||||
|
autocommit=True
|
||||||
)
|
)
|
||||||
print(f"[DB] MySQL conectado exitosamente")
|
print(f"[DB] MySQL conectado exitosamente")
|
||||||
break
|
break
|
||||||
@@ -52,7 +53,8 @@ def get_connection():
|
|||||||
password=db_config.get("password"),
|
password=db_config.get("password"),
|
||||||
database=db_config.get("name"),
|
database=db_config.get("name"),
|
||||||
consume_results=True,
|
consume_results=True,
|
||||||
connection_timeout=10
|
connection_timeout=10,
|
||||||
|
autocommit=True
|
||||||
)
|
)
|
||||||
print(f"[DB] MySQL reconectado exitosamente")
|
print(f"[DB] MySQL reconectado exitosamente")
|
||||||
break
|
break
|
||||||
@@ -72,7 +74,7 @@ def get_connection():
|
|||||||
db_dir = os.path.dirname(db_path)
|
db_dir = os.path.dirname(db_path)
|
||||||
if db_dir and not os.path.exists(db_dir):
|
if db_dir and not os.path.exists(db_dir):
|
||||||
os.makedirs(db_dir, exist_ok=True)
|
os.makedirs(db_dir, exist_ok=True)
|
||||||
return sqlite3.connect(db_path)
|
return sqlite3.connect(db_path, isolation_level=None)
|
||||||
|
|
||||||
def close_connection():
|
def close_connection():
|
||||||
global _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:
|
try:
|
||||||
from botdiscord.database import toggle_channel_status
|
from botdiscord.database import toggle_channel_status
|
||||||
|
from botdiscord.reload_marker import set_reload_marker
|
||||||
toggle_channel_status(int(channel_id), is_active)
|
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)
|
return RedirectResponse(url="/discord-channels?success=1", status_code=status.HTTP_303_SEE_OTHER)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error toggling channel: {e}")
|
print(f"Error toggling channel: {e}")
|
||||||
@@ -495,7 +497,9 @@ async def delete_discord_server(request: Request):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
from botdiscord.database import delete_discord_server
|
from botdiscord.database import delete_discord_server
|
||||||
|
from botdiscord.reload_marker import set_reload_marker
|
||||||
delete_discord_server(int(server_id))
|
delete_discord_server(int(server_id))
|
||||||
|
set_reload_marker()
|
||||||
return RedirectResponse(url="/discord-channels?success=1", status_code=status.HTTP_303_SEE_OTHER)
|
return RedirectResponse(url="/discord-channels?success=1", status_code=status.HTTP_303_SEE_OTHER)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error deleting server: {e}")
|
print(f"Error deleting server: {e}")
|
||||||
@@ -550,6 +554,8 @@ async def bulk_toggle_discord_channels(request: Request):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
print(f"[Panel] Bulk toggle: {success_count} canales {'activados' if is_active else 'desactivados'}")
|
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)
|
return RedirectResponse(url="/discord-channels?success=1", status_code=status.HTTP_303_SEE_OTHER)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user