From 7601979d3e378dc353780d4453f5b5e53b312418 Mon Sep 17 00:00:00 2001 From: nickpons666 Date: Fri, 6 Mar 2026 19:28:48 -0600 Subject: [PATCH] =?UTF-8?q?feat(discord):=20proteger=20menciones=20y=20mej?= =?UTF-8?q?orar=20traducci=C3=B3n=20HTML=20para=20mensajes=20multil=C3=ADn?= =?UTF-8?q?ea?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- botdiscord/bot.py | 14 +++++++++----- botdiscord/translate.py | 2 +- botdiscord/ui.py | 20 +++++++++++++++++++- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/botdiscord/bot.py b/botdiscord/bot.py index fefc107..0948b19 100644 --- a/botdiscord/bot.py +++ b/botdiscord/bot.py @@ -77,17 +77,21 @@ async def on_message(message): if not active_langs: return - text_to_translate = message.content + import html + text_escaped = html.escape(message.content) - mention_pattern = re.compile(r'<@!?(\d+)>|<@&(\d+)>|<#(\d+)>') + # Buscamos menciones que ya están escapadas (<@...>) + mention_pattern = re.compile(r'<@!?(\d+)>|<@&(\d+)>|<#(\d+)>') mentions_map = {} def replace_mention(match): - placeholder = f"__MENTION_{len(mentions_map)}__" - mentions_map[placeholder] = match.group(0) + # Usamos una etiqueta autocerrada para que el traductor no intente cerrarla él mismo + placeholder = f"" + # Guardamos la mención original (sin escapar) para restaurarla luego + mentions_map[placeholder] = html.unescape(match.group(0)) return placeholder - text_to_translate = mention_pattern.sub(replace_mention, text_to_translate) + text_to_translate = mention_pattern.sub(replace_mention, text_escaped) langs_to_show = active_langs diff --git a/botdiscord/translate.py b/botdiscord/translate.py index dccdb9e..26b309c 100644 --- a/botdiscord/translate.py +++ b/botdiscord/translate.py @@ -58,7 +58,7 @@ async def translate_text(text: str, target_lang: str) -> str: "q": text, "source": "auto", "target": target_code, - "format": "text" + "format": "html" } async with aiohttp.ClientSession() as session: diff --git a/botdiscord/ui.py b/botdiscord/ui.py index 6c606d0..69f817f 100644 --- a/botdiscord/ui.py +++ b/botdiscord/ui.py @@ -34,9 +34,27 @@ class TranslationButton(discord.ui.Button): # Traducimos el texto translated = await translate_text(self.text, self.lang_code) + # Desescapamos el HTML para recuperar caracteres especiales + import html + import re + translated = html.unescape(translated) + # Reemplazamos menciones si existen for placeholder, mention in self.mentions_map.items(): - translated = translated.replace(placeholder, mention) + # Extraer el número del tag, ej: m0 de + match = re.search(r'm\d+', placeholder) + if not match: continue + tag_num = match.group() + + # 1. Reemplazamos la etiqueta de apertura (o autocontenida) por la mención + # Patrón: < \s* mX \s* /? \s* > + open_pattern = re.compile(rf'<\s*{tag_num}\s*/?\s*>') + translated = open_pattern.sub(mention, translated) + + # 2. Eliminamos cualquier etiqueta de cierre que el traductor haya "inventado" + # Patrón: < \s* / \s* mX \s* > + close_pattern = re.compile(rf'<\s*/\s*{tag_num}\s*>') + translated = close_pattern.sub('', translated) # En lugar de enviar un mensaje nuevo, EDITAMOS el mensaje actual (el de los botones) if self.attachments: