diff --git a/data/bak/1_hmi_master_translates - copia.xlsx b/data/bak/1_hmi_master_translates - copia.xlsx new file mode 100644 index 0000000..7c3e863 Binary files /dev/null and b/data/bak/1_hmi_master_translates - copia.xlsx differ diff --git a/data/2_master_export2translate - copia.xlsx b/data/bak/2_master_export2translate - copia.xlsx similarity index 100% rename from data/2_master_export2translate - copia.xlsx rename to data/bak/2_master_export2translate - copia.xlsx diff --git a/data/3_master_export2translate_translated - copia.xlsx b/data/bak/3_master_export2translate_translated - copia.xlsx similarity index 100% rename from data/3_master_export2translate_translated - copia.xlsx rename to data/bak/3_master_export2translate_translated - copia.xlsx diff --git a/funciones_comunes/__init__.py b/funciones_comunes/__init__.py new file mode 100644 index 0000000..67d9a2e --- /dev/null +++ b/funciones_comunes/__init__.py @@ -0,0 +1 @@ +from funciones_comunes import * \ No newline at end of file diff --git a/funciones_comunes/__pycache__/__init__.cpython-310.pyc b/funciones_comunes/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..4f669ef Binary files /dev/null and b/funciones_comunes/__pycache__/__init__.cpython-310.pyc differ diff --git a/funciones_comunes/funciones_base.py b/funciones_comunes/funciones_base.py new file mode 100644 index 0000000..bc2e280 --- /dev/null +++ b/funciones_comunes/funciones_base.py @@ -0,0 +1,44 @@ +# Diccionario de idiomas +IDIOMAS = { + 1: ("English", "en-GB"), + 2: ("Portuguese", "pt-PT"), + 3: ("Spanish", "es-ES"), + 4: ("Russian", "ru-RU"), + 5: ("French", "fr-FR"), + 6: ("German", "de-DE"), +} + +def mostrar_idiomas(): + print("Selecciona el idioma de destino:") + for numero, (nombre, _) in IDIOMAS.items(): + print(f"{numero}: {nombre}") + +def transformar_texto(texto): + # Sustituir [[digits]] por <> + texto_transformado = re.sub(r'\[\[digits\]\]', '<>', texto) + # Sustituir cualquier <...> por <#> + texto_transformado = re.sub(r'<.*?>', '<#>', texto_transformado) + return texto_transformado + + +def save_dataframe_with_retries(df, output_path, max_retries=5, retry_delay=5): + """ + Guarda un DataFrame en un archivo Excel, reintentando si el archivo está en uso. + + :param df: El DataFrame a guardar. + :param output_path: La ruta del archivo donde se guardará el DataFrame. + :param max_retries: El número máximo de reintentos en caso de error. + :param retry_delay: El tiempo de espera (en segundos) entre cada reintento. + """ + retries = 0 + while retries < max_retries: + try: + df.to_excel(output_path, index=False) + print("Archivo guardado exitosamente.") + return + except PermissionError as e: + print(f"Error de permiso: {e}. Reintentando en {retry_delay} segundos...") + retries += 1 + time.sleep(retry_delay) + + print(f"No se pudo guardar el archivo después de {max_retries} intentos.") \ No newline at end of file diff --git a/x2_master_export2translate.py b/x2_master_export2translate.py index 0e2f9a7..e67f709 100644 --- a/x2_master_export2translate.py +++ b/x2_master_export2translate.py @@ -2,13 +2,7 @@ import pandas as pd import os import re from manejoArchivos import select_file - -def transformar_texto(texto): - # Sustituir [[digits]] por <> - texto_transformado = re.sub(r'\[\[digits\]\]', '<>', texto) - # Sustituir cualquier <...> por <#> - texto_transformado = re.sub(r'<.*?>', '<#>', texto_transformado) - return texto_transformado +import funciones_comunes def exportar_para_traduccion(archivo_maestro): if not os.path.exists(archivo_maestro): @@ -25,7 +19,7 @@ def exportar_para_traduccion(archivo_maestro): # Transformar las demás columnas for columna in df_maestro.columns[1:]: - df_export[columna] = df_maestro[columna].apply(lambda x: transformar_texto(str(x)) if pd.notnull(x) else x) + df_export[columna] = df_maestro[columna].apply(lambda x: funciones_comunes.transformar_texto(str(x)) if pd.notnull(x) else x) # Guardar el archivo exportado ruta_export = os.path.join(os.path.dirname(archivo_maestro), '.\\data\\2_master_export2translate.xlsx') diff --git a/x3.5_integrate_translates.py b/x3.5_integrate_translates.py new file mode 100644 index 0000000..87ee2a6 --- /dev/null +++ b/x3.5_integrate_translates.py @@ -0,0 +1,74 @@ +import funciones_comunes + +import pandas as pd +import os +import re +import logging +from manejoArchivos import select_file + +def configurar_logger(ruta_log): + os.makedirs(".\\data", exist_ok=True) + logger = logging.getLogger('.\\data\\importacion_logger') + logger.setLevel(logging.INFO) + fh = logging.FileHandler(ruta_log, encoding='utf-8') + fh.setLevel(logging.INFO) + formatter = logging.Formatter('%(asctime)s - %(message)s') + fh.setFormatter(formatter) + logger.addHandler(fh) + return logger + +def revertir_transformaciones(texto, digitos, secciones): + # Revertir <> a [[digits]] + for digito in digitos: + texto = texto.replace('<>', digito, 1) + # Revertir <#> a <...> usando las secciones originales + for seccion in secciones: + texto = texto.replace('<#>', f'<{seccion}>', 1) + return texto + +def importar_traduccion(archivo_maestro, archivo_traduccion, target_lang_code, nivel_afinidad_minimo): + if not os.path.exists(archivo_maestro): + print("El archivo maestro no existe.") + return + + target_col = f"{target_lang_code} Translated" + affinity_col = f"{target_lang_code} Affinity" + + df_maestro = pd.read_excel(archivo_maestro) + df_traduccion = pd.read_excel(archivo_traduccion) + + # Configurar el logger + directorio = os.path.dirname(archivo_maestro) + nombre_log = os.path.join(directorio, 'importacion_traduccion.log') + logger = configurar_logger(nombre_log) + + # Iterar sobre las filas del archivo de traducción para actualizar el maestro + for index, fila in df_traduccion.iterrows(): + clave = fila[df_maestro.columns[0]] + if clave in df_maestro[df_maestro.columns[0]].values: + # Comprobar afinidad y valores no nulos/vacíos + if fila[affinity_col] >= nivel_afinidad_minimo and pd.notnull(fila[target_col]) and fila[target_col] != "": + valor_traducido = fila[target_col] + valor_original = df_maestro.loc[df_maestro[df_maestro.columns[0]] == clave, target_col].values[0] + + if pd.notnull(valor_original) and str(valor_original) != str(valor_traducido): + df_maestro.loc[df_maestro[df_maestro.columns[0]] == clave, target_col] = valor_traducido + logger.info(f'Fila {index}, Columna {target_col}: "{valor_original}" actualizado a "{valor_traducido}"') + + # Guardar el archivo maestro actualizado + funciones_comunes.save_dataframe_with_retries(df_maestro,output_path=archivo_maestro) + print(f"Traducciones importadas y archivo maestro actualizado: {archivo_maestro}. Detalles de los cambios en {nombre_log}") + + +if __name__ == "__main__": + archivo_maestro = ".\\data\\1_hmi_master_translates.xlsx" + archivo_traduccion = ".\\data\\3_master_export2translate_translated.xlsx" + + nivel_afinidad_minimo = float(input("Introduce el nivel minimo de afinidad para importar: ")) + funciones_comunes.mostrar_idiomas() + seleccion_idioma = int(input("Introduce el número del idioma de destino: ")) + if seleccion_idioma not in funciones_comunes.IDIOMAS: + print("Selección inválida.") + else: + target_lang, target_lang_code = funciones_comunes.IDIOMAS[seleccion_idioma] + importar_traduccion(archivo_maestro, archivo_traduccion, target_lang_code, nivel_afinidad_minimo ) diff --git a/x3_llm_translate_text.py b/x3_llm_translate_text.py index cf0b659..8d55e0b 100644 --- a/x3_llm_translate_text.py +++ b/x3_llm_translate_text.py @@ -5,7 +5,6 @@ import re import logging from openai_api_key import openai_api_key from google_api_key import google_api_key -from x2_master_export2translate import transformar_texto import ollama import json from google.cloud import translate_v2 as translate @@ -13,42 +12,11 @@ from google.oauth2 import service_account import html from tqdm import tqdm import time +import funciones_comunes openai_client = OpenAI(api_key=openai_api_key()) GOOGLE_APPLICATION_CREDENTIALS = "translate-431108-020c17463fbb.json" -# Diccionario de idiomas -IDIOMAS = { - 1: ("English", "en-GB"), - 2: ("Portuguese", "pt-PT"), - 3: ("Spanish", "es-ES"), - 4: ("Russian", "ru-RU"), - 5: ("French", "fr-FR"), - 6: ("German", "de-DE"), -} - -def save_dataframe_with_retries(df, output_path, max_retries=5, retry_delay=5): - """ - Guarda un DataFrame en un archivo Excel, reintentando si el archivo está en uso. - - :param df: El DataFrame a guardar. - :param output_path: La ruta del archivo donde se guardará el DataFrame. - :param max_retries: El número máximo de reintentos en caso de error. - :param retry_delay: El tiempo de espera (en segundos) entre cada reintento. - """ - retries = 0 - while retries < max_retries: - try: - df.to_excel(output_path, index=False) - print("Archivo guardado exitosamente.") - return - except PermissionError as e: - print(f"Error de permiso: {e}. Reintentando en {retry_delay} segundos...") - retries += 1 - time.sleep(retry_delay) - - print(f"No se pudo guardar el archivo después de {max_retries} intentos.") - def configurar_logger(): logger = logging.getLogger("translate_logger") @@ -87,12 +55,6 @@ def google_translate(text, target_language): logger = configurar_logger() -def mostrar_idiomas(): - print("Selecciona el idioma de destino:") - for numero, (nombre, _) in IDIOMAS.items(): - print(f"{numero}: {nombre}") - - def read_system_prompt(): try: with open(".\\data\\system_prompt.txt", "r", encoding="utf-8") as file: @@ -169,7 +131,7 @@ def affinity_batch_openai(texts_dict): "Evaluate the semantic similarity between the following table of pairs of texts in json format on a scale from 0 to 1. " "Return the similarity scores for every row in JSON format as a list of numbers, without any additional text or formatting." ) - original_list = [transformar_texto(key) for key in texts_dict.keys()] + original_list = [funciones_comunes.transformar_texto(key) for key in texts_dict.keys()] re_translated_list = list(texts_dict.values()) request_payload = json.dumps( @@ -243,7 +205,7 @@ def main(file_path, target_lang_code, target_lang, traducir_todo, batch_size=10) if source_translated_col in df.columns else "" ) - processed_text = transformar_texto(source_text) + processed_text = funciones_comunes.transformar_texto(source_text) if traducir_todo: if texto_requiere_traduccion(processed_text): @@ -353,7 +315,7 @@ def main(file_path, target_lang_code, target_lang, traducir_todo, batch_size=10) output_path = os.path.join( os.path.dirname(file_path), "3_master_export2translate_translated.xlsx" ) - save_dataframe_with_retries(df,output_path=output_path) + funciones_comunes.save_dataframe_with_retries(df,output_path=output_path) logger.info(f"Archivo traducido guardado en: {output_path}") print(f"Archivo traducido guardado en: {output_path}") @@ -362,12 +324,12 @@ if __name__ == "__main__": batch_size = 20 translate_file = ".\\data\\2_master_export2translate.xlsx" - mostrar_idiomas() + funciones_comunes.mostrar_idiomas() seleccion_idioma = int(input("Introduce el número del idioma de destino: ")) - if seleccion_idioma not in IDIOMAS: + if seleccion_idioma not in funciones_comunes.IDIOMAS: print("Selección inválida.") else: - target_lang, target_lang_code = IDIOMAS[seleccion_idioma] + target_lang, target_lang_code = funciones_comunes.IDIOMAS[seleccion_idioma] traducir_todo = ( input("¿Desea traducir todas las celdas (s/n)? ").strip().lower() == "s" )