Fix Discord channel activation system
- Fix MySQL boolean conversion in toggle_channel_status - Improve cache management with 5-second timeout - Add bulk channel selection and toggle functionality - Fix Jinja2 template syntax errors - Add comprehensive debugging for channel status queries - Implement real-time channel activation without container restart
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import os
|
||||
import sys
|
||||
import signal
|
||||
import time
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
import discord
|
||||
@@ -9,7 +11,7 @@ import re
|
||||
import html
|
||||
|
||||
from botdiscord.config import get_discord_token, load_config, get_languages
|
||||
from botdiscord.database import init_db, get_active_languages, get_bot_languages, save_message, get_welcome_message
|
||||
from botdiscord.database import init_db, get_active_languages, get_bot_languages, save_message, get_welcome_message, is_channel_enabled
|
||||
from botdiscord.ui import PersistentTranslationView, ConfigView, WelcomeTranslationView, TranslationButton
|
||||
from botdiscord.translate import get_reverse_mapping, load_lang_mappings, get_name_to_code, get_flag_mapping
|
||||
|
||||
@@ -115,6 +117,14 @@ def get_active_langs_for_guild(guild_id):
|
||||
async def on_message(message):
|
||||
if message.author.bot: return
|
||||
|
||||
# Verificar si el canal está habilitado para traducción
|
||||
channel_enabled = is_channel_enabled(message.channel.id)
|
||||
print(f"[Bot] Mensaje en canal {message.channel.id} ({message.channel.name}) - Habilitado: {channel_enabled} - Timestamp: {time.strftime('%H:%M:%S')}")
|
||||
|
||||
if not channel_enabled:
|
||||
print(f"[Bot] Ignorando mensaje en canal desactivado: {message.channel.name}")
|
||||
return
|
||||
|
||||
text_content = message.content.strip()
|
||||
if not text_content: return
|
||||
|
||||
|
||||
@@ -190,6 +190,19 @@ def init_db():
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4''')
|
||||
|
||||
cursor.execute('''CREATE TABLE IF NOT EXISTS discord_servers
|
||||
(server_id BIGINT NOT NULL PRIMARY KEY,
|
||||
server_name VARCHAR(255) NOT NULL,
|
||||
added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4''')
|
||||
|
||||
cursor.execute('''CREATE TABLE IF NOT EXISTS discord_channels
|
||||
(channel_id BIGINT NOT NULL PRIMARY KEY,
|
||||
channel_name VARCHAR(255) NOT NULL,
|
||||
server_id BIGINT NOT NULL,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (server_id) REFERENCES discord_servers(server_id) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4''')
|
||||
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
else:
|
||||
@@ -243,6 +256,20 @@ def init_db():
|
||||
channel_id INTEGER NOT NULL,
|
||||
message_content TEXT NOT NULL,
|
||||
enabled INTEGER DEFAULT 1)''')
|
||||
|
||||
c.execute('''CREATE TABLE IF NOT EXISTS discord_servers
|
||||
(server_id INTEGER PRIMARY KEY,
|
||||
server_name TEXT NOT NULL,
|
||||
added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)''')
|
||||
|
||||
c.execute('''CREATE TABLE IF NOT EXISTS discord_channels
|
||||
(channel_id INTEGER PRIMARY KEY,
|
||||
channel_name TEXT NOT NULL,
|
||||
server_id INTEGER NOT NULL,
|
||||
is_active INTEGER DEFAULT 1,
|
||||
added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (server_id) REFERENCES discord_servers(server_id))''')
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
@@ -716,3 +743,232 @@ def delete_welcome_message(guild_id: int):
|
||||
c.execute("DELETE FROM welcome_messages WHERE guild_id = ?", (guild_id,))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
# Funciones para gestión de servidores y canales de Discord
|
||||
def sync_discord_servers(servers: list):
|
||||
db_type = get_db_type()
|
||||
|
||||
if db_type == "mysql":
|
||||
conn = get_connection()
|
||||
cursor = conn.cursor()
|
||||
for server in servers:
|
||||
server_id = server.get('id')
|
||||
server_name = server.get('name', '')
|
||||
cursor.execute("""INSERT INTO discord_servers (server_id, server_name)
|
||||
VALUES (%s, %s)
|
||||
ON DUPLICATE KEY UPDATE server_name = %s""",
|
||||
(server_id, server_name, server_name))
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
else:
|
||||
conn = get_connection()
|
||||
c = conn.cursor()
|
||||
for server in servers:
|
||||
server_id = server.get('id')
|
||||
server_name = server.get('name', '')
|
||||
c.execute("""INSERT OR REPLACE INTO discord_servers (server_id, server_name)
|
||||
VALUES (?, ?)""", (server_id, server_name))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
def get_discord_servers() -> list:
|
||||
db_type = get_db_type()
|
||||
|
||||
if db_type == "mysql":
|
||||
conn = get_connection()
|
||||
cursor = conn.cursor(dictionary=True)
|
||||
cursor.execute("SELECT server_id, server_name, added_at FROM discord_servers ORDER BY server_name")
|
||||
rows = cursor.fetchall()
|
||||
cursor.close()
|
||||
return rows
|
||||
else:
|
||||
conn = get_connection()
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT server_id, server_name, added_at FROM discord_servers ORDER BY server_name")
|
||||
rows = [{"server_id": r[0], "server_name": r[1], "added_at": r[2]} for r in c.fetchall()]
|
||||
conn.close()
|
||||
return rows
|
||||
|
||||
def sync_discord_channels(server_id: int, channels: list):
|
||||
db_type = get_db_type()
|
||||
|
||||
try:
|
||||
if db_type == "mysql":
|
||||
conn = get_connection()
|
||||
cursor = conn.cursor()
|
||||
for channel in channels:
|
||||
channel_id = channel.get('id')
|
||||
channel_name = channel.get('name', '')
|
||||
cursor.execute("""INSERT INTO discord_channels (channel_id, channel_name, server_id)
|
||||
VALUES (%s, %s, %s)
|
||||
ON DUPLICATE KEY UPDATE channel_name = %s, server_id = %s""",
|
||||
(channel_id, channel_name, server_id, channel_name, server_id))
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
else:
|
||||
conn = get_connection()
|
||||
c = conn.cursor()
|
||||
for channel in channels:
|
||||
channel_id = channel.get('id')
|
||||
channel_name = channel.get('name', '')
|
||||
c.execute("""INSERT OR REPLACE INTO discord_channels (channel_id, channel_name, server_id)
|
||||
VALUES (?, ?, ?)""", (channel_id, channel_name, server_id))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
# Limpiar todo el cache de canales después de sincronizar
|
||||
clear_channel_cache()
|
||||
print(f"[DB] Canales sincronizados para servidor {server_id}, cache limpiado")
|
||||
|
||||
except Exception as e:
|
||||
print(f"[DB] Error sincronizando canales del servidor {server_id}: {e}")
|
||||
raise
|
||||
|
||||
def get_discord_channels(server_id: int = None) -> list:
|
||||
db_type = get_db_type()
|
||||
|
||||
if db_type == "mysql":
|
||||
conn = get_connection()
|
||||
cursor = conn.cursor(dictionary=True)
|
||||
if server_id:
|
||||
cursor.execute("SELECT channel_id, channel_name, server_id, is_active, added_at FROM discord_channels WHERE server_id = %s ORDER BY channel_name", (server_id,))
|
||||
else:
|
||||
cursor.execute("SELECT channel_id, channel_name, server_id, is_active, added_at FROM discord_channels ORDER BY server_id, channel_name")
|
||||
rows = cursor.fetchall()
|
||||
cursor.close()
|
||||
return rows
|
||||
else:
|
||||
conn = get_connection()
|
||||
c = conn.cursor()
|
||||
if server_id:
|
||||
c.execute("SELECT channel_id, channel_name, server_id, is_active, added_at FROM discord_channels WHERE server_id = ? ORDER BY channel_name", (server_id,))
|
||||
else:
|
||||
c.execute("SELECT channel_id, channel_name, server_id, is_active, added_at FROM discord_channels ORDER BY server_id, channel_name")
|
||||
rows = [{"channel_id": r[0], "channel_name": r[1], "server_id": r[2], "is_active": bool(r[3]), "added_at": r[4]} for r in c.fetchall()]
|
||||
conn.close()
|
||||
return rows
|
||||
|
||||
def toggle_channel_status(channel_id: int, is_active: bool):
|
||||
db_type = get_db_type()
|
||||
|
||||
try:
|
||||
if db_type == "mysql":
|
||||
conn = get_connection()
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("UPDATE discord_channels SET is_active = %s WHERE channel_id = %s",
|
||||
(1 if is_active else 0, channel_id))
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
else:
|
||||
conn = get_connection()
|
||||
c = conn.cursor()
|
||||
c.execute("UPDATE discord_channels SET is_active = ? WHERE channel_id = ?",
|
||||
(1 if is_active else 0, channel_id))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
# Limpiar el cache para forzar re-lectura
|
||||
clear_channel_cache(channel_id)
|
||||
print(f"[DB] Canal {channel_id} actualizado a {is_active}, cache limpiado")
|
||||
|
||||
except Exception as e:
|
||||
print(f"[DB] Error actualizando canal {channel_id}: {e}")
|
||||
raise
|
||||
|
||||
# Cache simple para estados de canales (evita consultas excesivas)
|
||||
_channel_status_cache = {}
|
||||
_cache_timeout = 5 # segundos
|
||||
_last_cache_update = {}
|
||||
|
||||
def is_channel_enabled(channel_id: int) -> bool:
|
||||
global _channel_status_cache, _last_cache_update
|
||||
|
||||
db_type = get_db_type()
|
||||
current_time = time.time()
|
||||
|
||||
# Verificar si tenemos un cache válido
|
||||
if (channel_id in _channel_status_cache and
|
||||
channel_id in _last_cache_update and
|
||||
current_time - _last_cache_update[channel_id] < _cache_timeout):
|
||||
result = _channel_status_cache[channel_id]
|
||||
print(f"[DB Cache] Canal {channel_id} estado (cache): {result}")
|
||||
return result
|
||||
|
||||
try:
|
||||
if db_type == "mysql":
|
||||
conn = get_connection()
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT is_active FROM discord_channels WHERE channel_id = %s", (channel_id,))
|
||||
row = cursor.fetchone()
|
||||
cursor.close()
|
||||
print(f"[DB] MySQL Query: SELECT is_active FROM discord_channels WHERE channel_id = {channel_id}")
|
||||
print(f"[DB] MySQL Row: {row}")
|
||||
result = bool(row[0]) if row else False
|
||||
else:
|
||||
conn = get_connection()
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT is_active FROM discord_channels WHERE channel_id = ?", (channel_id,))
|
||||
row = c.fetchone()
|
||||
conn.close()
|
||||
print(f"[DB] SQLite Query: SELECT is_active FROM discord_channels WHERE channel_id = {channel_id}")
|
||||
print(f"[DB] SQLite Row: {row}")
|
||||
result = bool(row[0]) if row else False
|
||||
|
||||
# Actualizar cache
|
||||
_channel_status_cache[channel_id] = result
|
||||
_last_cache_update[channel_id] = current_time
|
||||
|
||||
print(f"[DB] Canal {channel_id} estado (DB): {result} - Timestamp: {time.strftime('%H:%M:%S')}")
|
||||
return result
|
||||
except Exception as e:
|
||||
print(f"[DB] Error verificando canal {channel_id}: {e}")
|
||||
# En caso de error, devolver False por seguridad
|
||||
return False
|
||||
|
||||
def clear_channel_cache(channel_id: int = None):
|
||||
"""Limpia el cache de un canal específico o de todos"""
|
||||
global _channel_status_cache, _last_cache_update
|
||||
if channel_id:
|
||||
_channel_status_cache.pop(channel_id, None)
|
||||
_last_cache_update.pop(channel_id, None)
|
||||
print(f"[DB] Cache limpiado para canal {channel_id}")
|
||||
# Forzar expiración inmediata poniendo un timestamp antiguo
|
||||
_last_cache_update[channel_id] = 0
|
||||
else:
|
||||
_channel_status_cache.clear()
|
||||
_last_cache_update.clear()
|
||||
print(f"[DB] Todo el cache de canales limpiado")
|
||||
|
||||
def delete_server_channels(server_id: int):
|
||||
"""Elimina todos los canales de un servidor específico"""
|
||||
db_type = get_db_type()
|
||||
|
||||
if db_type == "mysql":
|
||||
conn = get_connection()
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("DELETE FROM discord_channels WHERE server_id = %s", (server_id,))
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
else:
|
||||
conn = get_connection()
|
||||
c = conn.cursor()
|
||||
c.execute("DELETE FROM discord_channels WHERE server_id = ?", (server_id,))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
def delete_discord_server(server_id: int):
|
||||
"""Elimina un servidor y todos sus canales"""
|
||||
db_type = get_db_type()
|
||||
|
||||
if db_type == "mysql":
|
||||
conn = get_connection()
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("DELETE FROM discord_servers WHERE server_id = %s", (server_id,))
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
else:
|
||||
conn = get_connection()
|
||||
c = conn.cursor()
|
||||
c.execute("DELETE FROM discord_servers WHERE server_id = ?", (server_id,))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
Reference in New Issue
Block a user