Fix WebSocket block and add sync spinner to discord_channels UI
This commit is contained in:
204
botdiscord/server_sync.py
Normal file
204
botdiscord/server_sync.py
Normal file
@@ -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())
|
||||
Reference in New Issue
Block a user