From afc446a9aab34d00605ce9a553b10e3bcf2cd645 Mon Sep 17 00:00:00 2001 From: nickpons666 Date: Fri, 20 Mar 2026 04:30:10 -0600 Subject: [PATCH] =?UTF-8?q?fix:=20Mejorar=20segmentaci=C3=B3n=20de=20tradu?= =?UTF-8?q?cciones=20para=20textos=20largos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Limitar cada segmento a 400 caracteres - Dividir textos largos por palabras para evitar truncamiento - Limpiar logs de debug --- botdiscord/translate.py | 70 +++++++++++++++++++++++------------------ botdiscord/ui.py | 25 --------------- 2 files changed, 40 insertions(+), 55 deletions(-) diff --git a/botdiscord/translate.py b/botdiscord/translate.py index a787652..729ea8f 100644 --- a/botdiscord/translate.py +++ b/botdiscord/translate.py @@ -49,58 +49,68 @@ REVERSE_MAPPING = {} FLAG_MAPPING = {} NAME_TO_CODE = {} -async def _do_translate_request(session, url, text, target_code): +async def _do_translate_request(session, url, text, target_code, max_length=500): """Función interna para realizar una única petición de traducción.""" if not text.strip() or not re.search(r'[a-zA-Z\u00C0-\u017F]', text): return text - payload = { - "q": text, - "source": "auto", - "target": target_code, - "format": "html" - } - - try: - async with session.post(url, json=payload, timeout=30) as resp: - if resp.status == 200: - data = await resp.json() - translated = data.get("translatedText", text) - print(f"[TRANSLATE] Segmento traducido: '{text[:30]}...' -> '{translated[:30]}...'") - return translated + chunks = [] + if len(text) > max_length: + parts = text.split(' ') + current_chunk = '' + for part in parts: + if len(current_chunk) + len(part) + 1 <= max_length: + current_chunk += (' ' if current_chunk else '') + part else: - print(f"[TRANSLATE] Error HTTP {resp.status}") - return text - except Exception as e: - print(f"[TRANSLATE] Error en petición: {e}") - return text + if current_chunk: + chunks.append(current_chunk) + current_chunk = part + if current_chunk: + chunks.append(current_chunk) + else: + chunks.append(text) + + results = [] + for chunk in chunks: + payload = { + "q": chunk, + "source": "auto", + "target": target_code, + "format": "html" + } + + try: + async with session.post(url, json=payload, timeout=30) as resp: + if resp.status == 200: + data = await resp.json() + translated = data.get("translatedText", chunk) + results.append(translated) + else: + results.append(chunk) + except Exception as e: + print(f"[TRANSLATE] Error en petición: {e}") + results.append(chunk) + + return ' '.join(results) async def translate_text(text: str, target_lang: str) -> str: url = get_libretranslate_url() if not url: - print(f"[TRANSLATE] URL no configurada") return text - print(f"[TRANSLATE] target_lang recibido: '{target_lang}'") - target_code = NAME_TO_CODE.get(target_lang, target_lang) - print(f"[TRANSLATE] target_code resuelto: '{target_code}'") - print(f"[TRANSLATE] texto a traducir: '{text[:100]}...' (largo: {len(text)})") segments = re.split(r'([.!?]+\s*|\n+)', text) segments = [s for s in segments if s] - print(f"[TRANSLATE] Segmentos: {len(segments)}") async with aiohttp.ClientSession() as session: tasks = [] for segment in segments: - tasks.append(_do_translate_request(session, url, segment, target_code)) + tasks.append(_do_translate_request(session, url, segment, target_code, max_length=400)) translated_segments = await asyncio.gather(*tasks) - result = "".join(translated_segments) - print(f"[TRANSLATE] Resultado final: '{result[:100]}...'") - return result + return "".join(translated_segments) def translate_text_sync(text: str, target_lang: str) -> str: """Versión síncrona de translate_text utilizando un hilo separado.""" diff --git a/botdiscord/ui.py b/botdiscord/ui.py index 4fb81c9..8d18443 100644 --- a/botdiscord/ui.py +++ b/botdiscord/ui.py @@ -30,8 +30,6 @@ class TranslationButton(discord.ui.Button): return original_msg_id = interaction.message.reference.message_id - print(f"[UI] Traduciendo mensaje {original_msg_id} a {self.lang_code}") - db_msg = get_message(original_msg_id) if not db_msg: @@ -41,17 +39,11 @@ class TranslationButton(discord.ui.Button): text = db_msg['content'] mentions_map = db_msg['mentions_map'] - print(f"[UI] Texto original: {text}") - - # Traducción cached = get_cached_translation(original_msg_id, self.lang_code) if cached: translated = cached - print(f"[UI] Usando traducción cacheada: {translated}") else: - print(f"[UI] Traduciendo con translate_text...") translated = await translate_text(text, self.lang_code) - print(f"[UI] Traducción resultado: {translated}") save_translation(original_msg_id, self.lang_code, translated) translated = html.unescape(translated) @@ -78,9 +70,7 @@ class TranslationButton(discord.ui.Button): await interaction.edit_original_response(content=translated, view=new_view) except Exception as e: - import traceback print(f"[ERROR UI] {e}") - traceback.print_exc() await interaction.followup.send(f"❌ Error: {str(e)}", ephemeral=True) class PersistentTranslationView(discord.ui.View): @@ -90,21 +80,6 @@ class PersistentTranslationView(discord.ui.View): for lang in db_langs: self.add_item(TranslationButton(lang['name'], lang['code'], lang.get('flag', ''))) -_global_views = {} - -def get_message_translation_view(guild_id: int): - view_key = f"msg_trans_{guild_id}" - if view_key not in _global_views: - _global_views[view_key] = discord.ui.View(timeout=None) - active_codes = get_active_languages(guild_id) - if not active_codes: - active_codes = get_bot_languages("discord") - db_langs = get_available_languages() - for lang in db_langs: - if lang['code'] in active_codes: - _global_views[view_key].add_item(TranslationButton(lang['name'], lang['code'], lang.get('flag', ''))) - return _global_views[view_key] - class ConfigSelect(discord.ui.Select): def __init__(self, guild_id: int, bot_type: str = "discord"): lang_mapping = get_lang_mapping(bot_type)