From 97ce9fce861cdba752ed395a9c6b74c5694d5a85 Mon Sep 17 00:00:00 2001 From: nickpons666 Date: Fri, 20 Mar 2026 12:18:32 -0600 Subject: [PATCH] Fix WebSocket block and add sync spinner to discord_channels UI --- botdiscord/server_sync.py | 204 ++++++++++++++++++++++++++ panel/templates/discord_channels.html | 20 ++- 2 files changed, 221 insertions(+), 3 deletions(-) create mode 100644 botdiscord/server_sync.py diff --git a/botdiscord/server_sync.py b/botdiscord/server_sync.py new file mode 100644 index 0000000..6258fd6 --- /dev/null +++ b/botdiscord/server_sync.py @@ -0,0 +1,204 @@ +import discord +from discord.ext import commands +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 sync_discord_servers, sync_discord_channels, delete_server_channels + +# Variables globales para el bot +_bot_instance = None +_client = None + +async def get_discord_client(): + """Obtiene o crea una instancia del cliente de Discord""" + global _client + + if _client is None: + intents = discord.Intents.default() + intents.guilds = True # Necesario para obtener servidores + intents.message_content = False # No necesitamos leer mensajes + + _client = discord.Client(intents=intents) + + # Evento de conexión + @_client.event + async def on_ready(): + print(f"[Discord Sync] Conectado como {_client.user}") + + return _client + +async def sync_discord_servers_from_api(): + """ + Sincroniza los servidores y canales desde Discord API + Returns True si fue exitoso, False si hubo error + """ + global _client + try: + print("[Discord Sync] Iniciando sincronización...") + + # Cargar configuración + load_config() + token = get_discord_token() + + print(f"[Discord Sync] Token encontrado: {bool(token)}") + print(f"[Discord Sync] Token length: {len(token) if token else 0}") + + if not token: + print("[Discord Sync] Error: No se encontró el token de Discord") + print("[Discord Sync] Variables de entorno disponibles:") + for key, value in os.environ.items(): + if 'DISCORD' in key or 'TOKEN' in key: + print(f" {key}: {'***' if 'TOKEN' in key else value}") + return False + + # Obtener cliente de Discord + client = await get_discord_client() + + # Conectar si no está conectado + if not client.is_ready(): + try: + print("[Discord Sync] Conectando a Discord...") + await client.login(token) + asyncio.create_task(client.connect()) + # Esperar hasta que el bot esté listo + await client.wait_until_ready() + except Exception as e: + print(f"[Discord Sync] Error conectando a Discord: {e}") + return False + + # Obtener servidores donde está el bot + guilds = client.guilds + servers_data = [] + + for guild in guilds: + servers_data.append({ + 'id': guild.id, + 'name': guild.name + }) + + # Sincronizar servidores en la base de datos + sync_discord_servers(servers_data) + print(f"[Discord Sync] Sincronizados {len(servers_data)} servidores") + + # Sincronizar canales para cada servidor + for guild in guilds: + try: + # Obtener canales de texto del servidor + text_channels = [ch for ch in guild.text_channels] + channels_data = [] + + for channel in text_channels: + channels_data.append({ + 'id': channel.id, + 'name': channel.name + }) + + # Sincronizar canales del servidor + sync_discord_channels(guild.id, channels_data) + print(f"[Discord Sync] Sincronizados {len(channels_data)} canales del servidor {guild.name}") + + except Exception as e: + print(f"[Discord Sync] Error sincronizando canales del servidor {guild.name}: {e}") + # Eliminar canales de este servidor si hay error + delete_server_channels(guild.id) + + # Desconectar cliente para liberar recursos + if client.is_ready(): + await client.close() + _client = None + + return True + + except Exception as e: + print(f"[Discord Sync] Error general: {e}") + # Limpiar cliente en caso de error + if _client and _client.is_ready(): + try: + await _client.close() + except: + pass + _client = None + return False + +async def get_server_channels(server_id: int): + """ + Obtiene los canales de un servidor específico desde Discord API + """ + try: + client = await get_discord_client() + token = get_discord_token() + + if not token: + return [] + + # Conectar si es necesario + if not client.is_ready(): + await client.login(token) + asyncio.create_task(client.connect()) + await client.wait_until_ready() + + # Buscar el servidor + guild = client.get_guild(server_id) + if not guild: + print(f"[Discord Sync] No se encontró el servidor {server_id}") + return [] + + # Obtener canales de texto + text_channels = [ch for ch in guild.text_channels] + channels_data = [] + + for channel in text_channels: + channels_data.append({ + 'id': channel.id, + 'name': channel.name + }) + + # Cerrar cliente + if client.is_ready(): + await client.close() + _client = None + + return channels_data + + except Exception as e: + print(f"[Discord Sync] Error obteniendo canales del servidor {server_id}: {e}") + return [] + +# Función de prueba para verificar la conexión +async def test_discord_connection(): + """Prueba la conexión con Discord API""" + try: + client = await get_discord_client() + token = get_discord_token() + + if not token: + return False, "No hay token de Discord" + + await client.login(token) + asyncio.create_task(client.connect()) + await client.wait_until_ready() + + # Verificar si podemos obtener guilds + guilds = client.guilds + + await client.close() + _client = None + + return True, f"Conexión exitosa. Bot en {len(guilds)} servidores" + + except Exception as e: + return False, f"Error de conexión: {e}" + +if __name__ == "__main__": + # Prueba de sincronización + async def test_sync(): + print("Iniciando prueba de sincronización...") + result = await sync_discord_servers_from_api() + print(f"Resultado: {'Exitoso' if result else 'Fallido'}") + + asyncio.run(test_sync()) diff --git a/panel/templates/discord_channels.html b/panel/templates/discord_channels.html index 0cfbfde..2335cbf 100644 --- a/panel/templates/discord_channels.html +++ b/panel/templates/discord_channels.html @@ -102,9 +102,9 @@ {{ "Diagnóstico" | translate(lang) }} -
-
@@ -265,6 +265,20 @@ checkbox.addEventListener('change', updateBulkButtons); }); }); + + function handleSync() { + if (confirm('{{ "¿Sincronizar servidores y canales desde Discord?" | translate(lang) }}')) { + const btn = document.getElementById('syncBtn'); + const icon = document.getElementById('syncIcon'); + const text = document.getElementById('syncText'); + + btn.disabled = true; + icon.className = 'spinner-border spinner-border-sm'; + text.innerText = ' {{ "Sincronizando..." | translate(lang) }}'; + + document.getElementById('syncForm').submit(); + } + }