Mejorado el Menu y creado archivo de config TranslationConfig para simplificar las llamadas a los run
This commit is contained in:
parent
8d1eadb49f
commit
97de43cba7
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -15,5 +15,7 @@ output_text = Ejecutando x4B_integrate_manual_translates_to_master.run()
|
|||
Se han marcado 3 celdas con errores en rojo en el archivo fuente.
|
||||
Traducciones manuales importadas y archivo maestro actualizado: .\data\1_hmi_master_translates_allenbradley.xlsx.
|
||||
Se han actualizado 0 celdas en el maestro y se han encontrado 3 errores en el archivo fuente.
|
||||
|
||||
|
||||
[Directorios]
|
||||
work_dir = C:/Trabajo/VM/31 - 9.3953 - Omega - Mexico - (ABradley)/Reporte/Languages
|
||||
|
||||
|
|
113785
logs/translate_log.log
113785
logs/translate_log.log
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,5 @@
|
|||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
from tkinter import messagebox
|
||||
from tkinter import ttk, filedialog, messagebox
|
||||
import PyLibrary.funciones_comunes as fc
|
||||
import x1_importar_to_master
|
||||
import x2_master_export2translate
|
||||
|
@ -9,287 +8,300 @@ import x4_integrate_translates_to_master
|
|||
import x4B_integrate_manual_translates_to_master
|
||||
import x5_complete_empty_cells_master
|
||||
import x6_update_from_master
|
||||
from translation_config import TranslationConfig
|
||||
import sys
|
||||
import threading
|
||||
import configparser # Para manejar el archivo de configuración
|
||||
import os # Para verificar si el archivo existe
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
# Crear la ventana principal
|
||||
ventana = tk.Tk()
|
||||
ventana.title("Ayuda para traducir textos de TIA Portal y Allen Bradley")
|
||||
ventana.geometry("800x600") # Ajustamos el tamaño de la ventana
|
||||
class TranslationApp:
|
||||
def __init__(self, master):
|
||||
self.master = master
|
||||
self.master.title("Ayuda para traducir textos de TIA Portal y Allen Bradley")
|
||||
self.master.geometry("1200x800")
|
||||
|
||||
# Diccionario para tipo_PLC
|
||||
tipo_PLC_dict = {'Siemens': 'siemens', 'AllenBradley': 'allenbradley'}
|
||||
self.config = TranslationConfig.load()
|
||||
|
||||
# Variables para almacenar las selecciones del usuario
|
||||
tipo_PLC_var = tk.StringVar()
|
||||
codigo_columna_maestra_var = tk.StringVar()
|
||||
idioma_var = tk.StringVar()
|
||||
idioma_var2 = tk.StringVar()
|
||||
self.create_variables()
|
||||
self.create_widgets()
|
||||
self.place_widgets()
|
||||
|
||||
# Crear listas de idiomas con sus códigos
|
||||
idiomas_lista = [(nombre, codigo) for _, (nombre, codigo) in fc.IDIOMAS.items()]
|
||||
def create_variables(self):
|
||||
self.codigo_tipo_PLC_var = tk.StringVar(value=self.config.codigo_tipo_PLC)
|
||||
self.codigo_columna_maestra_var = tk.StringVar(value=self.config.codigo_columna_maestra)
|
||||
self.codigo_idioma_var = tk.StringVar(value=self.config.codigo_idioma_seleccionado)
|
||||
self.codigo_idioma_var2 = tk.StringVar(value=self.config.codigo_idioma_secundario)
|
||||
self.work_dir_var = tk.StringVar(value=self.config.work_dir)
|
||||
|
||||
# Ruta del archivo de configuración
|
||||
config_file = 'config.ini'
|
||||
self.master_name_var = tk.StringVar(value=self.config.master_name)
|
||||
self.translate_name_var = tk.StringVar(value=self.config.translate_name)
|
||||
self.auto_translate_name_var = tk.StringVar(value=self.config.auto_translate_name)
|
||||
|
||||
def open_master_directory():
|
||||
tipo_PLC = tipo_PLC_dict[tipo_PLC_var.get()]
|
||||
archivo_maestro = f".\\data\\1_hmi_master_translates_{tipo_PLC}.xlsx"
|
||||
master_directory = os.path.dirname(os.path.abspath(archivo_maestro))
|
||||
fc.open_file_explorer(master_directory)
|
||||
def create_widgets(self):
|
||||
self.main_frame = ttk.Frame(self.master)
|
||||
self.main_frame.grid(row=0, column=0, sticky='nsew')
|
||||
self.master.grid_rowconfigure(0, weight=1)
|
||||
self.master.grid_columnconfigure(0, weight=1)
|
||||
|
||||
def open_log_file():
|
||||
log_file_path = ".\\logs\\translate_log.log"
|
||||
if os.path.exists(log_file_path):
|
||||
fc.open_file_explorer(log_file_path)
|
||||
else:
|
||||
messagebox.showinfo("Archivo de registro", "El archivo de registro aún no existe.")
|
||||
self.frame_combos = ttk.Frame(self.main_frame)
|
||||
|
||||
self.label_tipo_PLC = ttk.Label(self.frame_combos, text="Selecciona el tipo de PLC:")
|
||||
self.combo_tipo_PLC = ttk.Combobox(self.frame_combos, state="readonly")
|
||||
self.combo_tipo_PLC["values"] = [nombre for nombre, _ in fc.PLCs.values()]
|
||||
self.combo_tipo_PLC.bind('<<ComboboxSelected>>', self.update_tipo_PLC)
|
||||
self.set_combo_value(self.combo_tipo_PLC, self.codigo_tipo_PLC_var.get())
|
||||
|
||||
# Función para cargar las opciones guardadas
|
||||
def cargar_configuracion():
|
||||
config = configparser.ConfigParser()
|
||||
if os.path.exists(config_file):
|
||||
config.read(config_file)
|
||||
# Cargar tipo_PLC
|
||||
tipo_PLC_var.set(config.get('Seleccion', 'tipo_PLC', fallback='Siemens'))
|
||||
# Cargar codigo_columna_maestra
|
||||
codigo_columna_maestra_var.set(config.get('Seleccion', 'codigo_columna_maestra', fallback=idiomas_lista[0][0]))
|
||||
# Cargar idioma_var
|
||||
idioma_var.set(config.get('Seleccion', 'idioma_var', fallback=idiomas_lista[4][0]))
|
||||
# Cargar idioma_var2
|
||||
idioma_var2.set(config.get('Seleccion', 'idioma_var2', fallback=idiomas_lista[1][0]))
|
||||
else:
|
||||
# Valores por defecto si no existe el archivo
|
||||
tipo_PLC_var.set('Siemens')
|
||||
codigo_columna_maestra_var.set(idiomas_lista[0][0])
|
||||
idioma_var.set(idiomas_lista[4][0])
|
||||
idioma_var2.set(idiomas_lista[1][0])
|
||||
self.label_codigo_maestra = ttk.Label(self.frame_combos, text="Idioma Columna Maestra:")
|
||||
self.combo_codigo_maestra = ttk.Combobox(self.frame_combos, state="readonly")
|
||||
self.combo_codigo_maestra["values"] = [nombre for nombre, _ in fc.IDIOMAS.values()]
|
||||
self.combo_codigo_maestra.bind('<<ComboboxSelected>>', self.update_codigo_maestra)
|
||||
self.set_combo_value(self.combo_codigo_maestra, self.codigo_columna_maestra_var.get())
|
||||
|
||||
# Función para guardar las opciones seleccionadas
|
||||
def guardar_configuracion():
|
||||
config = configparser.ConfigParser()
|
||||
config['Seleccion'] = {
|
||||
'tipo_PLC': tipo_PLC_var.get(),
|
||||
'codigo_columna_maestra': codigo_columna_maestra_var.get(),
|
||||
'idioma_var': idioma_var.get(),
|
||||
'idioma_var2': idioma_var2.get()
|
||||
}
|
||||
# Guardar el contenido del cuadro de texto
|
||||
config['TextContent'] = {
|
||||
'output_text': output_text.get("1.0", tk.END)
|
||||
}
|
||||
with open(config_file, 'w') as configfile:
|
||||
config.write(configfile)
|
||||
self.label1 = ttk.Label(self.frame_combos, text="Idioma de Traducción:")
|
||||
self.combo = ttk.Combobox(self.frame_combos, state="readonly")
|
||||
self.combo["values"] = [nombre for nombre, _ in fc.IDIOMAS.values()]
|
||||
self.combo.bind('<<ComboboxSelected>>', self.update_idioma)
|
||||
self.set_combo_value(self.combo, self.codigo_idioma_var.get())
|
||||
|
||||
# Crear un Frame para la grilla de comboboxes
|
||||
frame_combos = tk.Frame(ventana)
|
||||
frame_combos.pack(pady=10)
|
||||
self.label2 = ttk.Label(self.frame_combos, text="Selecciona segundo idioma:")
|
||||
self.combo2 = ttk.Combobox(self.frame_combos, state="readonly")
|
||||
self.combo2["values"] = [nombre for nombre, _ in fc.IDIOMAS.values()]
|
||||
self.combo2.bind('<<ComboboxSelected>>', self.update_idioma2)
|
||||
self.set_combo_value(self.combo2, self.codigo_idioma_var2.get())
|
||||
|
||||
# Crear los labels y comboboxes
|
||||
label_tipo_PLC = tk.Label(frame_combos, text="Selecciona el tipo de PLC:")
|
||||
combo_tipo_PLC = ttk.Combobox(frame_combos, textvariable=tipo_PLC_var, state="readonly")
|
||||
combo_tipo_PLC["values"] = list(tipo_PLC_dict.keys())
|
||||
self.work_dir_frame = ttk.Frame(self.main_frame)
|
||||
self.work_dir_label = ttk.Label(self.work_dir_frame, text="Directorio de trabajo:")
|
||||
self.work_dir_entry = ttk.Entry(self.work_dir_frame, textvariable=self.work_dir_var, width=50)
|
||||
self.work_dir_button = ttk.Button(self.work_dir_frame, text="Seleccionar", command=self.select_work_dir)
|
||||
self.open_explorer_button = ttk.Button(self.work_dir_frame, text="Abrir Explorador", command=self.open_explorer)
|
||||
|
||||
label_codigo_maestra = tk.Label(frame_combos, text="Idioma Columna Maestra:")
|
||||
combo_codigo_maestra = ttk.Combobox(frame_combos, textvariable=codigo_columna_maestra_var, state="readonly")
|
||||
combo_codigo_maestra["values"] = [nombre for nombre, _ in idiomas_lista]
|
||||
style = ttk.Style()
|
||||
style.configure('TButton', padding=(10, 10), font=('Helvetica', 10, 'bold'))
|
||||
style.configure('Excel.TButton', padding=(10, 10), font=('Helvetica', 10), background='#69cf81')
|
||||
|
||||
label1 = tk.Label(frame_combos, text="Idioma de Traducción:")
|
||||
combo = ttk.Combobox(frame_combos, textvariable=idioma_var, state="readonly")
|
||||
combo["values"] = [nombre for nombre, _ in idiomas_lista]
|
||||
self.button_width = 60
|
||||
self.entry_width = 50
|
||||
|
||||
self.paso1 = ttk.Button(self.main_frame, text="1 - Importar al Master", command=lambda: self.ejecutar_run(x1_importar_to_master.run), width=self.button_width)
|
||||
self.master_name_button = ttk.Button(self.main_frame, textvariable=self.master_name_var, command=lambda: self.open_file(self.config.get_master_path()), width=self.entry_width, style='Excel.TButton')
|
||||
|
||||
label2 = tk.Label(frame_combos, text="Selecciona segundo idioma:")
|
||||
combo2 = ttk.Combobox(frame_combos, textvariable=idioma_var2, state="readonly")
|
||||
combo2["values"] = [nombre for nombre, _ in idiomas_lista]
|
||||
self.paso2 = ttk.Button(self.main_frame, text="2 - Exportar Idioma a 2_master_export2translate.xlsx", command=lambda: self.ejecutar_run(x2_master_export2translate.run), width=self.button_width)
|
||||
self.translate_name_button = ttk.Button(self.main_frame, textvariable=self.translate_name_var, command=lambda: self.open_file(self.config.get_translate_path()), width=self.entry_width, style='Excel.TButton')
|
||||
|
||||
# Organizar los labels y comboboxes en una grilla 2x2
|
||||
label_tipo_PLC.grid(row=0, column=0, padx=5, pady=5, sticky='e')
|
||||
combo_tipo_PLC.grid(row=0, column=1, padx=5, pady=5, sticky='w')
|
||||
self.paso3 = ttk.Button(self.main_frame, text="3 - Traducir y generar 3_master_export2translate_translated.xlsx", command=lambda: self.ejecutar_run(x3_llm_auto_translate.run), width=self.button_width)
|
||||
self.auto_translate_name_button = ttk.Button(self.main_frame, textvariable=self.auto_translate_name_var, command=lambda: self.open_file(self.config.get_auto_translate_path()), width=self.entry_width, style='Excel.TButton')
|
||||
|
||||
label_codigo_maestra.grid(row=1, column=0, padx=5, pady=5, sticky='e')
|
||||
combo_codigo_maestra.grid(row=1, column=1, padx=5, pady=5, sticky='w')
|
||||
self.paso4 = ttk.Button(self.main_frame, text="4 - Integrar las traducciones al 1_hmi_master_translates", command=lambda: self.ejecutar_run(x4_integrate_translates_to_master.run), width=self.button_width)
|
||||
|
||||
label1.grid(row=0, column=2, padx=5, pady=5, sticky='e')
|
||||
combo.grid(row=0, column=3, padx=5, pady=5, sticky='w')
|
||||
self.paso4B = ttk.Button(self.main_frame, text="4B - Integrar traducciones manuales al 1_hmi_master_translates", command=lambda: self.ejecutar_run(x4B_integrate_manual_translates_to_master.run), width=self.button_width)
|
||||
|
||||
label2.grid(row=1, column=2, padx=5, pady=5, sticky='e')
|
||||
combo2.grid(row=1, column=3, padx=5, pady=5, sticky='w')
|
||||
self.paso5 = ttk.Button(self.main_frame, text="5 - Completar en 1_hmi_master_translates el idioma seleccionado usando el segundo idioma", command=lambda: self.ejecutar_run(x5_complete_empty_cells_master.run), width=self.button_width)
|
||||
|
||||
# Función para actualizar combo_codigo_maestra según la selección en combo_tipo_PLC
|
||||
def actualizar_codigo_maestra(event):
|
||||
plc_seleccionado = tipo_PLC_var.get()
|
||||
if plc_seleccionado == 'Siemens':
|
||||
# Buscar el índice de 'Italian' en idiomas_lista
|
||||
indice_italiano = next((i for i, (nombre, _) in enumerate(idiomas_lista) if nombre == 'Italian'), None)
|
||||
if indice_italiano is not None:
|
||||
combo_codigo_maestra.current(indice_italiano)
|
||||
elif plc_seleccionado == 'AllenBradley':
|
||||
# Buscar el índice de 'English_US' en idiomas_lista
|
||||
indice_ingles = next((i for i, (nombre, _) in enumerate(idiomas_lista) if nombre == 'English_US'), None)
|
||||
if indice_ingles is not None:
|
||||
combo_codigo_maestra.current(indice_ingles)
|
||||
guardar_configuracion() # Guardar la configuración cuando se cambia el tipo de PLC
|
||||
self.paso6 = ttk.Button(self.main_frame, text="6 - Exportar usando un archivo exportado desde TIA Portal usando 1_hmi_master_translates", command=lambda: self.ejecutar_run(x6_update_from_master.run), width=self.button_width)
|
||||
|
||||
# Vincular la función al evento de cambio de selección en combo_tipo_PLC
|
||||
combo_tipo_PLC.bind('<<ComboboxSelected>>', actualizar_codigo_maestra)
|
||||
self.output_text = tk.Text(self.main_frame, wrap='none', height=20)
|
||||
self.scrollbar_y = ttk.Scrollbar(self.main_frame, orient='vertical', command=self.output_text.yview)
|
||||
self.scrollbar_x = ttk.Scrollbar(self.main_frame, orient='horizontal', command=self.output_text.xview)
|
||||
self.output_text.configure(yscrollcommand=self.scrollbar_y.set, xscrollcommand=self.scrollbar_x.set)
|
||||
|
||||
# Vincular eventos de cambio en los comboboxes para guardar la configuración
|
||||
def on_combobox_changed(event):
|
||||
guardar_configuracion()
|
||||
self.clear_button = ttk.Button(self.main_frame, text="Limpiar salida", command=self.clear_output)
|
||||
self.open_log_button = ttk.Button(self.main_frame, text="Abrir Log", command=self.open_log_file)
|
||||
|
||||
combo_codigo_maestra.bind('<<ComboboxSelected>>', on_combobox_changed)
|
||||
combo.bind('<<ComboboxSelected>>', on_combobox_changed)
|
||||
combo2.bind('<<ComboboxSelected>>', on_combobox_changed)
|
||||
def place_widgets(self):
|
||||
self.main_frame.grid_columnconfigure(0, weight=1)
|
||||
self.main_frame.grid_columnconfigure(1, weight=1)
|
||||
|
||||
# Clase para redirigir la salida estándar a la caja de texto
|
||||
class RedirectText(object):
|
||||
def __init__(self, text_widget):
|
||||
self.output = text_widget
|
||||
self.frame_combos.grid(row=0, column=0, columnspan=2, pady=10, sticky='ew')
|
||||
self.label_tipo_PLC.grid(row=0, column=0, padx=5, pady=5, sticky='e')
|
||||
self.combo_tipo_PLC.grid(row=0, column=1, padx=5, pady=5, sticky='w')
|
||||
self.label_codigo_maestra.grid(row=1, column=0, padx=5, pady=5, sticky='e')
|
||||
self.combo_codigo_maestra.grid(row=1, column=1, padx=5, pady=5, sticky='w')
|
||||
self.label1.grid(row=0, column=2, padx=5, pady=5, sticky='e')
|
||||
self.combo.grid(row=0, column=3, padx=5, pady=5, sticky='w')
|
||||
self.label2.grid(row=1, column=2, padx=5, pady=5, sticky='e')
|
||||
self.combo2.grid(row=1, column=3, padx=5, pady=5, sticky='w')
|
||||
|
||||
def write(self, string):
|
||||
self.output.insert(tk.END, string)
|
||||
self.output.see(tk.END) # Desplaza hacia el final
|
||||
self.work_dir_frame.grid(row=1, column=0, columnspan=2, pady=10, sticky='ew')
|
||||
self.work_dir_label.grid(row=0, column=0, padx=5, sticky='w')
|
||||
self.work_dir_entry.grid(row=0, column=1, padx=5, sticky='ew')
|
||||
self.work_dir_button.grid(row=0, column=2, padx=5, sticky='e')
|
||||
self.open_explorer_button.grid(row=0, column=3, padx=5, sticky='e')
|
||||
self.work_dir_frame.grid_columnconfigure(1, weight=1)
|
||||
|
||||
def flush(self):
|
||||
pass # No se requiere implementación para flush
|
||||
current_row = 2
|
||||
self.paso1.grid(row=current_row, column=0, pady=5, padx=5, sticky='ew')
|
||||
self.master_name_button.grid(row=current_row, column=1, pady=5, padx=5, sticky='ew')
|
||||
|
||||
current_row += 1
|
||||
self.paso2.grid(row=current_row, column=0, pady=5, padx=5, sticky='ew')
|
||||
self.translate_name_button.grid(row=current_row, column=1, pady=5, padx=5, sticky='ew')
|
||||
|
||||
current_row += 1
|
||||
self.paso3.grid(row=current_row, column=0, pady=5, padx=5, sticky='ew')
|
||||
self.auto_translate_name_button.grid(row=current_row, column=1, pady=5, padx=5, sticky='ew')
|
||||
|
||||
current_row += 1
|
||||
self.paso4.grid(row=current_row, column=0, pady=5, padx=5, sticky='ew')
|
||||
|
||||
current_row += 1
|
||||
self.paso4B.grid(row=current_row, column=0, pady=5, padx=5, sticky='ew')
|
||||
|
||||
current_row += 1
|
||||
self.paso5.grid(row=current_row, column=0, columnspan=2, pady=5, padx=5, sticky='ew')
|
||||
|
||||
current_row += 1
|
||||
self.paso6.grid(row=current_row, column=0, columnspan=2, pady=5, padx=5, sticky='ew')
|
||||
|
||||
# Función para obtener el código del idioma seleccionado a partir del nombre
|
||||
def obtener_codigo_idioma_por_nombre(nombre_idioma):
|
||||
for nombre, codigo in idiomas_lista:
|
||||
if nombre == nombre_idioma:
|
||||
return codigo
|
||||
return None
|
||||
current_row += 1
|
||||
self.output_text.grid(row=current_row, column=0, columnspan=2, padx=(10, 0), pady=10, sticky='nsew')
|
||||
self.scrollbar_y.grid(row=current_row, column=2, pady=10, sticky='ns')
|
||||
self.scrollbar_x.grid(row=current_row+1, column=0, columnspan=2, padx=10, sticky='ew')
|
||||
|
||||
# Función para ejecutar las funciones run() y redirigir la salida
|
||||
def ejecutar_run(funcion_run):
|
||||
# Obtener los parámetros necesarios
|
||||
tipo_PLC = tipo_PLC_dict[tipo_PLC_var.get()]
|
||||
codigo_columna_maestra = obtener_codigo_idioma_por_nombre(codigo_columna_maestra_var.get())
|
||||
codigo_idioma = obtener_codigo_idioma_por_nombre(idioma_var.get())
|
||||
codigo_idioma2 = obtener_codigo_idioma_por_nombre(idioma_var2.get())
|
||||
current_row += 2
|
||||
self.clear_button.grid(row=current_row, column=0, pady=10, padx=5, sticky='e')
|
||||
self.open_log_button.grid(row=current_row, column=1, pady=10, padx=5, sticky='w')
|
||||
|
||||
# Obtener los índices de los idiomas
|
||||
indice_seleccionado = idiomas_lista.index((idioma_var.get(), codigo_idioma))
|
||||
indice_seleccionado2 = idiomas_lista.index((idioma_var2.get(), codigo_idioma2))
|
||||
self.main_frame.grid_rowconfigure(current_row-2, weight=1)
|
||||
|
||||
# Redirigir stdout
|
||||
original_stdout = sys.stdout
|
||||
sys.stdout = RedirectText(output_text)
|
||||
def set_combo_value(self, combo, codigo):
|
||||
for nombre, code in fc.IDIOMAS.values():
|
||||
if code == codigo:
|
||||
combo.set(nombre)
|
||||
return
|
||||
for nombre, code in fc.PLCs.values():
|
||||
if code == codigo:
|
||||
combo.set(nombre)
|
||||
return
|
||||
|
||||
try:
|
||||
# Ejecutar la función correspondiente
|
||||
if funcion_run == x1_importar_to_master.run:
|
||||
print("Ejecutando x1_importar_to_master.run()")
|
||||
funcion_run(tipo_PLC, codigo_columna_maestra)
|
||||
elif funcion_run == x2_master_export2translate.run:
|
||||
print("Ejecutando x2_master_export2translate.run()")
|
||||
funcion_run(tipo_PLC, codigo_columna_maestra, indice_seleccionado)
|
||||
elif funcion_run == x3_llm_auto_translate.run:
|
||||
traducir_todo = messagebox.askyesno("Traducir todo", "¿Desea traducir todas las celdas?")
|
||||
print("Ejecutando x3_llm_auto_translate.run()")
|
||||
funcion_run(tipo_PLC, codigo_columna_maestra, indice_seleccionado, traducir_todo)
|
||||
elif funcion_run == x4_integrate_translates_to_master.run:
|
||||
print("Ejecutando x4_integrate_translates_to_master.run()")
|
||||
funcion_run(tipo_PLC, codigo_columna_maestra, indice_seleccionado, 0.5)
|
||||
elif funcion_run == x4B_integrate_manual_translates_to_master.run:
|
||||
print("Ejecutando x4B_integrate_manual_translates_to_master.run()")
|
||||
funcion_run(tipo_PLC, codigo_columna_maestra, indice_seleccionado)
|
||||
elif funcion_run == x5_complete_empty_cells_master.run:
|
||||
print("Ejecutando x5_complete_empty_cells_master.run()")
|
||||
funcion_run(tipo_PLC, codigo_columna_maestra, indice_seleccionado, indice_seleccionado2)
|
||||
elif funcion_run == x6_update_from_master.run:
|
||||
print("Ejecutando x6_update_from_master.run()")
|
||||
funcion_run(tipo_PLC, codigo_columna_maestra, indice_seleccionado)
|
||||
finally:
|
||||
# Restaurar stdout
|
||||
sys.stdout = original_stdout
|
||||
guardar_configuracion() # Guardar el contenido del cuadro de texto
|
||||
def update_tipo_PLC(self, event):
|
||||
nombre_seleccionado = self.combo_tipo_PLC.get()
|
||||
for nombre, codigo in fc.PLCs.values():
|
||||
if nombre == nombre_seleccionado:
|
||||
self.codigo_tipo_PLC_var.set(codigo)
|
||||
break
|
||||
self.update_file_names()
|
||||
|
||||
# Crear los botones con el mismo ancho
|
||||
button_width = 70
|
||||
paso1 = tk.Button(ventana, text="1 - Importar al Master", command=lambda: threading.Thread(target=ejecutar_run, args=(x1_importar_to_master.run,)).start(), width=button_width)
|
||||
paso2 = tk.Button(ventana, text="2 - Exportar Idioma a 2_master_export2translate.xlsx.", command=lambda: threading.Thread(target=ejecutar_run, args=(x2_master_export2translate.run,)).start(), width=button_width)
|
||||
paso3 = tk.Button(ventana, text="3 - Traducir y generar 3_master_export2translate_translated.xlsx.", command=lambda: threading.Thread(target=ejecutar_run, args=(x3_llm_auto_translate.run,)).start(), width=button_width)
|
||||
paso4 = tk.Button(ventana, text="4 - Integrar las traducciones al 1_hmi_master_translates.", command=lambda: threading.Thread(target=ejecutar_run, args=(x4_integrate_translates_to_master.run,)).start(), width=button_width)
|
||||
paso4B = tk.Button(ventana, text="4B - Integrar traducciones manuales al 1_hmi_master_translates.", command=lambda: threading.Thread(target=ejecutar_run, args=(x4B_integrate_manual_translates_to_master.run,)).start(), width=button_width)
|
||||
paso5 = tk.Button(ventana, text="5 - Completar en 1_hmi_master_translates el idioma seleccionado usando el segundo idioma.", command=lambda: threading.Thread(target=ejecutar_run, args=(x5_complete_empty_cells_master.run,)).start(), width=button_width)
|
||||
paso6 = tk.Button(ventana, text="6 - Exportar usando un archivo exportado desde TIA Portal usando 1_hmi_master_translates.", command=lambda: threading.Thread(target=ejecutar_run, args=(x6_update_from_master.run,)).start(), width=button_width)
|
||||
def update_codigo_maestra(self, event):
|
||||
nombre_seleccionado = self.combo_codigo_maestra.get()
|
||||
for nombre, codigo in fc.IDIOMAS.values():
|
||||
if nombre == nombre_seleccionado:
|
||||
self.codigo_columna_maestra_var.set(codigo)
|
||||
break
|
||||
self.update_file_names()
|
||||
|
||||
boton_abrir_directorio = tk.Button(ventana, text="Abrir directorio del archivo maestro", command=open_master_directory, width=button_width)
|
||||
boton_abrir_log = tk.Button(ventana, text="Abrir archivo de log", command=open_log_file, width=button_width)
|
||||
def update_idioma(self, event):
|
||||
nombre_seleccionado = self.combo.get()
|
||||
for nombre, codigo in fc.IDIOMAS.values():
|
||||
if nombre == nombre_seleccionado:
|
||||
self.codigo_idioma_var.set(codigo)
|
||||
break
|
||||
self.update_file_names()
|
||||
|
||||
# Ubicar los botones en la ventana
|
||||
paso1.pack(pady=(10,2))
|
||||
paso2.pack(pady=2)
|
||||
paso3.pack(pady=2)
|
||||
paso4.pack(pady=2)
|
||||
paso4B.pack(pady=2) # Nuevo botón para el paso 4B
|
||||
paso5.pack(pady=2)
|
||||
paso6.pack(pady=2)
|
||||
def update_idioma2(self, event):
|
||||
nombre_seleccionado = self.combo2.get()
|
||||
for nombre, codigo in fc.IDIOMAS.values():
|
||||
if nombre == nombre_seleccionado:
|
||||
self.codigo_idioma_var2.set(codigo)
|
||||
break
|
||||
self.update_file_names()
|
||||
|
||||
# Place the new buttons in the window
|
||||
boton_abrir_directorio.pack(pady=2)
|
||||
boton_abrir_log.pack(pady=2)
|
||||
def save_config(self):
|
||||
self.config.update(
|
||||
codigo_tipo_PLC=self.codigo_tipo_PLC_var.get(),
|
||||
codigo_columna_maestra=self.codigo_columna_maestra_var.get(),
|
||||
codigo_idioma_seleccionado=self.codigo_idioma_var.get(),
|
||||
codigo_idioma_secundario=self.codigo_idioma_var2.get(),
|
||||
work_dir=self.work_dir_var.get(),
|
||||
master_name=self.master_name_var.get(),
|
||||
translate_name=self.translate_name_var.get(),
|
||||
auto_translate_name=self.auto_translate_name_var.get(),
|
||||
)
|
||||
self.config.save()
|
||||
|
||||
# Crear un Frame para el cuadro de texto, los scrollbars y el botón
|
||||
frame_texto = tk.Frame(ventana)
|
||||
frame_texto.pack(fill='both', expand=True, pady=10)
|
||||
def select_work_dir(self):
|
||||
dir_path = filedialog.askdirectory()
|
||||
if dir_path:
|
||||
self.work_dir_var.set(dir_path)
|
||||
self.save_config()
|
||||
self.update_file_names()
|
||||
|
||||
# Crear los scrollbars
|
||||
scrollbar_vertical = tk.Scrollbar(frame_texto, orient='vertical')
|
||||
scrollbar_horizontal = tk.Scrollbar(frame_texto, orient='horizontal')
|
||||
def open_file(self, file_path):
|
||||
if os.path.exists(file_path):
|
||||
os.startfile(file_path)
|
||||
else:
|
||||
messagebox.showerror("Error", f"El archivo {file_path} no existe.")
|
||||
|
||||
# Crear la caja de texto para mostrar la salida
|
||||
output_text = tk.Text(
|
||||
frame_texto,
|
||||
wrap='none',
|
||||
yscrollcommand=scrollbar_vertical.set,
|
||||
xscrollcommand=scrollbar_horizontal.set
|
||||
)
|
||||
def open_explorer(self):
|
||||
if os.path.exists(self.config.work_dir):
|
||||
os.startfile(self.config.work_dir)
|
||||
else:
|
||||
messagebox.showerror("Error", f"El directorio {self.config.work_dir} no existe.")
|
||||
|
||||
# Configurar los scrollbars
|
||||
scrollbar_vertical.config(command=output_text.yview)
|
||||
scrollbar_horizontal.config(command=output_text.xview)
|
||||
def open_log_file(self):
|
||||
log_file_path = os.path.join(self.config.work_dir, "logs", "translate_log.log")
|
||||
if os.path.exists(log_file_path):
|
||||
os.startfile(log_file_path)
|
||||
else:
|
||||
messagebox.showerror("Error", f"El archivo de log {log_file_path} no existe.")
|
||||
|
||||
# Crear el botón para borrar el contenido
|
||||
boton_limpiar = tk.Button(frame_texto, text="Borrar contenido", command=lambda: limpiar_texto())
|
||||
def update_file_names(self, event=None):
|
||||
codigo_tipo_PLC = self.codigo_tipo_PLC_var.get()
|
||||
codigo_idioma_seleccionado = self.codigo_idioma_var.get()
|
||||
|
||||
self.master_name_var.set(f"1_hmi_master_translates_{codigo_tipo_PLC}.xlsx")
|
||||
self.translate_name_var.set(f'2_master_export2translate_{codigo_tipo_PLC}_{codigo_idioma_seleccionado}.xlsx')
|
||||
self.auto_translate_name_var.set(f"3_master_export2translate_translated_{codigo_tipo_PLC}_{codigo_idioma_seleccionado}.xlsx")
|
||||
|
||||
self.save_config()
|
||||
|
||||
# Ubicar los widgets en frame_texto usando grid
|
||||
output_text.grid(row=0, column=0, sticky='nsew')
|
||||
scrollbar_vertical.grid(row=0, column=1, sticky='ns')
|
||||
scrollbar_horizontal.grid(row=1, column=0, sticky='ew')
|
||||
boton_limpiar.grid(row=1, column=1, padx=5, pady=5)
|
||||
def ejecutar_run(self, funcion_run):
|
||||
self.save_config()
|
||||
|
||||
original_stdout = sys.stdout
|
||||
sys.stdout = self.RedirectText(self.output_text)
|
||||
|
||||
# Configurar la expansión de filas y columnas
|
||||
frame_texto.grid_rowconfigure(0, weight=1)
|
||||
frame_texto.grid_columnconfigure(0, weight=1)
|
||||
try:
|
||||
if funcion_run == x1_importar_to_master.run:
|
||||
funcion_run(self.config)
|
||||
elif funcion_run == x2_master_export2translate.run:
|
||||
funcion_run(self.config)
|
||||
elif funcion_run == x3_llm_auto_translate.run:
|
||||
traducir_todo = messagebox.askyesno("Traducir todo", "¿Desea traducir todas las celdas?")
|
||||
self.config.traducir_todo = traducir_todo
|
||||
funcion_run(self.config)
|
||||
elif funcion_run == x4_integrate_translates_to_master.run:
|
||||
funcion_run(self.config)
|
||||
elif funcion_run == x4B_integrate_manual_translates_to_master.run:
|
||||
funcion_run(self.config)
|
||||
elif funcion_run == x5_complete_empty_cells_master.run:
|
||||
funcion_run(self.config)
|
||||
elif funcion_run == x6_update_from_master.run:
|
||||
archivo_to_update = filedialog.askopenfilename(title="Seleccione el archivo a actualizar", filetypes=[("Excel files", "*.xlsx")])
|
||||
if archivo_to_update:
|
||||
funcion_run(self.config, archivo_to_update)
|
||||
except Exception as e:
|
||||
messagebox.showerror("Error", str(e))
|
||||
finally:
|
||||
sys.stdout = original_stdout
|
||||
self.save_config()
|
||||
def clear_output(self):
|
||||
self.output_text.delete('1.0', tk.END)
|
||||
|
||||
# Función para borrar el contenido del cuadro de texto
|
||||
def limpiar_texto():
|
||||
output_text.delete('1.0', tk.END)
|
||||
guardar_configuracion()
|
||||
class RedirectText:
|
||||
def __init__(self, text_widget):
|
||||
self.text_widget = text_widget
|
||||
|
||||
# Cargar las opciones guardadas al iniciar
|
||||
cargar_configuracion()
|
||||
def write(self, string):
|
||||
self.text_widget.insert(tk.END, string)
|
||||
self.text_widget.see(tk.END)
|
||||
|
||||
# Cargar el contenido del cuadro de texto desde la configuración
|
||||
def cargar_texto():
|
||||
config = configparser.ConfigParser()
|
||||
if os.path.exists(config_file):
|
||||
config.read(config_file)
|
||||
texto = config.get('TextContent', 'output_text', fallback='')
|
||||
output_text.insert('1.0', texto)
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
cargar_texto()
|
||||
def main():
|
||||
root = tk.Tk()
|
||||
app = TranslationApp(root)
|
||||
root.mainloop()
|
||||
|
||||
# Guardar la configuración al cerrar la ventana
|
||||
def on_closing():
|
||||
guardar_configuracion()
|
||||
ventana.destroy()
|
||||
|
||||
ventana.protocol("WM_DELETE_WINDOW", on_closing)
|
||||
|
||||
# Iniciar el bucle principal de la interfaz
|
||||
ventana.mainloop()
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"codigo_tipo_PLC": "allenbradley",
|
||||
"codigo_columna_maestra": "es-ES",
|
||||
"codigo_idioma_seleccionado": "es-ES",
|
||||
"codigo_idioma_secundario": "en-US",
|
||||
"work_dir": "C:/Trabajo/VM/31 - 9.3953 - Omega - Mexico - (ABradley)/Reporte/Languages",
|
||||
"master_name": "1_hmi_master_translates_allenbradley.xlsx",
|
||||
"translate_name": "2_master_export2translate_allenbradley_es-ES.xlsx",
|
||||
"auto_translate_name": "3_master_export2translate_translated_allenbradley_es-ES.xlsx",
|
||||
"nivel_afinidad_minimo": 0.5,
|
||||
"traducir_todo": false
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
from dataclasses import dataclass, asdict
|
||||
import json
|
||||
import os
|
||||
import PyLibrary.funciones_comunes as fc
|
||||
|
||||
@dataclass
|
||||
class TranslationConfig:
|
||||
codigo_tipo_PLC: str
|
||||
codigo_columna_maestra: str
|
||||
codigo_idioma_seleccionado: str
|
||||
codigo_idioma_secundario: str
|
||||
work_dir: str
|
||||
master_name: str
|
||||
translate_name: str
|
||||
auto_translate_name: str
|
||||
nivel_afinidad_minimo: float = 0.5
|
||||
traducir_todo: bool = False
|
||||
|
||||
@classmethod
|
||||
def load(cls, filename="translation_config.json"):
|
||||
if os.path.exists(filename):
|
||||
with open(filename, "r") as f:
|
||||
data = json.load(f)
|
||||
return cls(**data)
|
||||
return cls.default()
|
||||
|
||||
def save(self, filename="translation_config.json"):
|
||||
with open(filename, "w") as f:
|
||||
json.dump(asdict(self), f, indent=2)
|
||||
|
||||
@classmethod
|
||||
def default(cls):
|
||||
return cls(
|
||||
codigo_tipo_PLC="siemens",
|
||||
codigo_columna_maestra="it-IT",
|
||||
codigo_idioma_seleccionado="en-GB",
|
||||
codigo_idioma_secundario="es-ES",
|
||||
work_dir="",
|
||||
master_name="1_hmi_master_translates_siemens.xlsx",
|
||||
translate_name="2_master_export2translate_siemens_en-GB.xlsx",
|
||||
auto_translate_name="3_master_export2translate_translated_siemens_en-GB.xlsx",
|
||||
)
|
||||
|
||||
def update(self, **kwargs):
|
||||
for key, value in kwargs.items():
|
||||
if hasattr(self, key):
|
||||
setattr(self, key, value)
|
||||
|
||||
def get_tipo_PLC_nombre(self) -> str:
|
||||
return next(nombre for nombre, codigo in fc.PLCs.values() if codigo == self.codigo_tipo_PLC)
|
||||
|
||||
def get_idioma_nombre(self, codigo: str) -> str:
|
||||
return next(nombre for nombre, code in fc.IDIOMAS.values() if code == codigo)
|
||||
|
||||
def get_idioma_seleccionado_nombre(self) -> str:
|
||||
return self.get_idioma_nombre(self.codigo_idioma_seleccionado)
|
||||
|
||||
def get_idioma_secundario_nombre(self) -> str:
|
||||
return self.get_idioma_nombre(self.codigo_idioma_secundario)
|
||||
|
||||
def get_full_path(self, filename: str) -> str:
|
||||
return os.path.join(self.work_dir, filename)
|
||||
|
||||
def get_master_path(self) -> str:
|
||||
return self.get_full_path(self.master_name)
|
||||
|
||||
def get_translate_path(self) -> str:
|
||||
return self.get_full_path(self.translate_name)
|
||||
|
||||
def get_auto_translate_path(self) -> str:
|
||||
return self.get_full_path(self.auto_translate_name)
|
|
@ -3,69 +3,89 @@ import os
|
|||
import re
|
||||
import logging
|
||||
import PyLibrary.funciones_comunes as fc
|
||||
from translation_config import TranslationConfig
|
||||
|
||||
def preprocesar_importacion(tipo_PLC, codigo_columna_maestra, df_importacion, logger):
|
||||
# Definir el logger a nivel de módulo
|
||||
logger = None
|
||||
|
||||
|
||||
def preprocesar_importacion(
|
||||
codigo_tipo_PLC, codigo_columna_maestra, df_importacion, logger
|
||||
):
|
||||
filas_validas = []
|
||||
|
||||
|
||||
for index, fila in df_importacion.iterrows():
|
||||
clave_original = fila[codigo_columna_maestra]
|
||||
|
||||
|
||||
# Verificar si la celda de la columna maestra está vacía o solo contiene espacios en blanco
|
||||
if pd.isna(clave_original) or str(clave_original).strip() == '':
|
||||
logger.info(f"Fila {index}: Ignorada - Celda de columna maestra vacía o solo con espacios en blanco")
|
||||
if pd.isna(clave_original) or str(clave_original).strip() == "":
|
||||
logger.info(
|
||||
f"Fila {index}: Ignorada - Celda de columna maestra vacía o solo con espacios en blanco"
|
||||
)
|
||||
continue
|
||||
|
||||
# Aplicar unescape solo a las filas con valor no vacío en la columna maestra
|
||||
|
||||
nueva_fila = fila.copy()
|
||||
for col in nueva_fila.index:
|
||||
nueva_fila[col] = fc.limpiar_caracteres_especiales(str(nueva_fila[col]))
|
||||
|
||||
clave_sustituida = fc.compactar_celda_clave(tipo_PLC, str(nueva_fila[codigo_columna_maestra]))
|
||||
|
||||
clave_sustituida = fc.compactar_celda_clave(
|
||||
codigo_tipo_PLC, str(nueva_fila[codigo_columna_maestra])
|
||||
)
|
||||
nueva_fila[codigo_columna_maestra] = clave_sustituida
|
||||
|
||||
|
||||
for columna in df_importacion.columns:
|
||||
if columna != codigo_columna_maestra and fc.es_columna_tipo_xxYY(columna):
|
||||
nueva_fila[columna] = fc.compactar_celda_traducida(tipo_PLC, nueva_fila[columna])
|
||||
|
||||
nueva_fila[columna] = fc.compactar_celda_traducida(
|
||||
codigo_tipo_PLC, nueva_fila[columna]
|
||||
)
|
||||
|
||||
filas_validas.append(nueva_fila)
|
||||
|
||||
|
||||
logger.info(f"Fila {index}: Aceptada - Clave '{clave_sustituida}' procesada")
|
||||
|
||||
df_valido = pd.DataFrame(filas_validas, columns=df_importacion.columns)
|
||||
return df_valido
|
||||
|
||||
def importar(tipo_PLC, codigo_columna_maestra, archivo_maestro, archivo_importacion):
|
||||
logger = fc.configurar_logger()
|
||||
|
||||
def importar(config: TranslationConfig):
|
||||
logger.info(" .... ")
|
||||
logger.info(f"Iniciando importacion en {archivo_maestro} desde el archivo {archivo_importacion}")
|
||||
|
||||
logger.info(f"Iniciando importacion en {config.master_name}")
|
||||
|
||||
archivo_maestro = os.path.join(config.work_dir, config.master_name)
|
||||
|
||||
if not os.path.exists(archivo_maestro):
|
||||
df_maestro = pd.DataFrame(columns=[codigo_columna_maestra])
|
||||
df_maestro = pd.DataFrame(columns=[config.codigo_columna_maestra])
|
||||
else:
|
||||
df_maestro = fc.read_dataframe_with_cleanup_retries(archivo_maestro)
|
||||
# Aplicar unescape solo a las filas con valor no vacío en la columna maestra
|
||||
|
||||
df_importacion = pd.read_excel(archivo_importacion)
|
||||
archivo_importacion = fc.select_file("xlsx")
|
||||
if not archivo_importacion:
|
||||
logger.info("No se seleccionó ningún archivo para importar.")
|
||||
return
|
||||
|
||||
df_importacion = preprocesar_importacion(tipo_PLC, codigo_columna_maestra, df_importacion, logger)
|
||||
df_importacion = fc.read_dataframe_with_cleanup_retries(archivo_importacion)
|
||||
|
||||
claves_maestro = set(df_maestro[codigo_columna_maestra].dropna().astype(str))
|
||||
df_importacion = preprocesar_importacion(
|
||||
config.codigo_tipo_PLC, config.codigo_columna_maestra, df_importacion, logger
|
||||
)
|
||||
|
||||
claves_maestro = set(df_maestro[config.codigo_columna_maestra].dropna().astype(str))
|
||||
|
||||
filas_a_agregar = []
|
||||
|
||||
for index, fila in df_importacion.iterrows():
|
||||
clave = str(fila[codigo_columna_maestra])
|
||||
|
||||
clave = str(fila[config.codigo_columna_maestra])
|
||||
|
||||
if clave in claves_maestro:
|
||||
logger.info(f"Fila {index}: Ignorada - Clave '{clave}' ya existe en el archivo maestro")
|
||||
logger.info(
|
||||
f"Fila {index}: Ignorada - Clave '{clave}' ya existe en el archivo maestro"
|
||||
)
|
||||
continue
|
||||
|
||||
|
||||
claves_maestro.add(clave)
|
||||
|
||||
|
||||
fila_filtrada = {
|
||||
col: fila[col]
|
||||
for col in fila.index
|
||||
if col == codigo_columna_maestra or fc.es_columna_tipo_xxYY(col)
|
||||
if col == config.codigo_columna_maestra or fc.es_columna_tipo_xxYY(col)
|
||||
}
|
||||
filas_a_agregar.append(fila_filtrada)
|
||||
|
||||
|
@ -80,17 +100,25 @@ def importar(tipo_PLC, codigo_columna_maestra, archivo_maestro, archivo_importac
|
|||
df_nuevas_filas = pd.DataFrame(filas_a_agregar)
|
||||
df_maestro = pd.concat([df_maestro, df_nuevas_filas], ignore_index=True)
|
||||
|
||||
df_maestro.to_excel(archivo_maestro, index=False)
|
||||
logger.info(f"Se han agregado {len(filas_a_agregar)} nuevas filas válidas al archivo maestro.")
|
||||
print(f"Se han agregado {len(filas_a_agregar)} nuevas filas válidas al archivo maestro.")
|
||||
fc.save_dataframe_with_retries(df_maestro, output_path=archivo_maestro)
|
||||
logger.info(
|
||||
f"Se han agregado {len(filas_a_agregar)} nuevas filas válidas al archivo maestro."
|
||||
)
|
||||
print(
|
||||
f"Se han agregado {len(filas_a_agregar)} nuevas filas válidas al archivo maestro."
|
||||
)
|
||||
|
||||
|
||||
def run(config: TranslationConfig):
|
||||
global logger
|
||||
logger = fc.configurar_logger(config.work_dir)
|
||||
importar(config)
|
||||
|
||||
def run(tipo_PLC, codigo_columna_maestra):
|
||||
archivo_maestro = f".\\data\\1_hmi_master_translates_{tipo_PLC}.xlsx"
|
||||
archivo_importacion = fc.select_file("xlsx")
|
||||
if archivo_importacion:
|
||||
importar(tipo_PLC, codigo_columna_maestra, archivo_maestro, archivo_importacion)
|
||||
|
||||
if __name__ == "__main__":
|
||||
tipo_PLC = "siemens"
|
||||
codigo_columna_maestra = "it-IT"
|
||||
run(tipo_PLC, codigo_columna_maestra)
|
||||
print(
|
||||
"Este script debe ser ejecutado desde el menú principal (menu_pasos_traduccion.py)."
|
||||
)
|
||||
print(
|
||||
"Por favor, ejecute menu_pasos_traduccion.py para utilizar esta funcionalidad."
|
||||
)
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
import pandas as pd
|
||||
import os
|
||||
import PyLibrary.funciones_comunes as fc
|
||||
from translation_config import TranslationConfig
|
||||
|
||||
# Definir el logger a nivel de módulo
|
||||
logger = None
|
||||
|
||||
|
||||
def exportar_para_traduccion(tipo_PLC, archivo_maestro, target_lang_code):
|
||||
if not os.path.exists(archivo_maestro):
|
||||
def exportar_para_traduccion(config: TranslationConfig):
|
||||
master_path = config.get_master_path()
|
||||
if not os.path.exists(master_path):
|
||||
print("El archivo maestro no existe.")
|
||||
return
|
||||
|
||||
# Leer el archivo maestro
|
||||
df_maestro = fc.read_dataframe_with_cleanup_retries(archivo_maestro)
|
||||
df_maestro = fc.read_dataframe_with_cleanup_retries(master_path)
|
||||
|
||||
# Crear un nuevo DataFrame para la exportación
|
||||
df_export = pd.DataFrame()
|
||||
|
@ -17,35 +22,35 @@ def exportar_para_traduccion(tipo_PLC, archivo_maestro, target_lang_code):
|
|||
# Copiar la primera columna y la columna del idioma de destino
|
||||
primera_columna = df_maestro.columns[0]
|
||||
df_export[primera_columna] = df_maestro[primera_columna]
|
||||
df_export[target_lang_code] = df_maestro[target_lang_code]
|
||||
df_export[config.codigo_idioma_seleccionado] = df_maestro[
|
||||
config.codigo_idioma_seleccionado
|
||||
]
|
||||
|
||||
# Guardar el archivo exportado
|
||||
ruta_export = os.path.join(os.path.dirname(archivo_maestro), f'2_master_export2translate_{tipo_PLC}.xlsx')
|
||||
|
||||
ruta_export = config.get_translate_path()
|
||||
|
||||
# Usar ExcelWriter para tener más control sobre el proceso de escritura
|
||||
with pd.ExcelWriter(ruta_export, engine='openpyxl') as writer:
|
||||
df_export.to_excel(writer, index=False, sheet_name='Sheet1')
|
||||
|
||||
with pd.ExcelWriter(ruta_export, engine="openpyxl") as writer:
|
||||
df_export.to_excel(writer, index=False, sheet_name="Sheet1")
|
||||
|
||||
# Ajustar el ancho de las columnas
|
||||
worksheet = writer.sheets['Sheet1']
|
||||
worksheet = writer.sheets["Sheet1"]
|
||||
for idx, col in enumerate(df_export.columns):
|
||||
max_length = max(df_export[col].astype(str).map(len).max(), len(col))
|
||||
if max_length > 50 : max_length = 50
|
||||
if max_length > 50:
|
||||
max_length = 50
|
||||
worksheet.column_dimensions[chr(65 + idx)].width = max_length + 2
|
||||
|
||||
print(f"Archivo exportado para traducción: {ruta_export}")
|
||||
|
||||
def run(tipo_PLC, codigo_columna_maestra, seleccion_idioma):
|
||||
archivo_maestro = f".\\data\\1_hmi_master_translates_{tipo_PLC}.xlsx"
|
||||
if seleccion_idioma not in fc.IDIOMAS:
|
||||
print("Selección inválida.")
|
||||
else:
|
||||
_, target_lang_code = fc.IDIOMAS[seleccion_idioma]
|
||||
exportar_para_traduccion(tipo_PLC, archivo_maestro, target_lang_code)
|
||||
|
||||
def run(config: TranslationConfig):
|
||||
global logger
|
||||
logger = fc.configurar_logger(config.work_dir)
|
||||
exportar_para_traduccion(config)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
tipo_PLC = "siemens"
|
||||
codigo_columna_maestra = "it-IT"
|
||||
fc.mostrar_idiomas()
|
||||
seleccion_idioma = int(input("Introduce el número del idioma de destino: "))
|
||||
run(tipo_PLC, codigo_columna_maestra, seleccion_idioma)
|
||||
import menu_pasos_traduccion
|
||||
|
||||
menu_pasos_traduccion.main()
|
||||
|
|
|
@ -12,10 +12,17 @@ import html
|
|||
from tqdm import tqdm
|
||||
import PyLibrary.funciones_comunes as fc
|
||||
import time
|
||||
import PyLibrary.funciones_comunes as fc
|
||||
from translation_config import TranslationConfig
|
||||
from openai import OpenAI
|
||||
from tqdm import tqdm
|
||||
|
||||
openai_client = OpenAI(api_key=openai_api_key())
|
||||
GOOGLE_APPLICATION_CREDENTIALS = "translate-431108-020c17463fbb.json"
|
||||
logger = fc.configurar_logger()
|
||||
batch_size = 20
|
||||
|
||||
# Definir el logger a nivel de módulo
|
||||
logger = None
|
||||
|
||||
|
||||
def init_google_translate_client():
|
||||
|
@ -30,8 +37,10 @@ def init_google_translate_client():
|
|||
"No se han proporcionado credenciales válidas para Google Translate"
|
||||
)
|
||||
|
||||
|
||||
google_translate_client = init_google_translate_client()
|
||||
|
||||
|
||||
def google_translate(text, target_language):
|
||||
result = google_translate_client.translate(text, target_language=target_language)
|
||||
translated_text = result["translatedText"]
|
||||
|
@ -187,27 +196,26 @@ def calcular_afinidad(tipo_PLC, texto1, texto2):
|
|||
try:
|
||||
score = float(cleaned_response_content)
|
||||
except ValueError:
|
||||
raise ValueError(f"La respuesta no se pudo decodificar como un número: {cleaned_response_content}")
|
||||
raise ValueError(
|
||||
f"La respuesta no se pudo decodificar como un número: {cleaned_response_content}"
|
||||
)
|
||||
|
||||
return score
|
||||
|
||||
|
||||
def main(tipo_PLC, codigo_columna_maestra, file_path, target_lang_code, target_lang, traducir_todo, batch_size=10):
|
||||
df = fc.read_dataframe_with_cleanup_retries(file_path)
|
||||
def main(config: TranslationConfig):
|
||||
df = fc.read_dataframe_with_cleanup_retries(config.get_translate_path())
|
||||
|
||||
source_col = codigo_columna_maestra
|
||||
source_translated_col = target_lang_code
|
||||
target_col = f"{target_lang_code} Translated"
|
||||
check_translate_col = f"{target_lang_code} CheckTranslate"
|
||||
affinity_col = f"{target_lang_code} Affinity"
|
||||
source_col = config.codigo_columna_maestra
|
||||
source_translated_col = config.codigo_idioma_seleccionado
|
||||
target_col = f"{config.codigo_idioma_seleccionado} Translated"
|
||||
check_translate_col = f"{config.codigo_idioma_seleccionado} CheckTranslate"
|
||||
affinity_col = f"{config.codigo_idioma_seleccionado} Affinity"
|
||||
|
||||
# Asegurarse de que la columna de destino existe
|
||||
if target_col not in df.columns:
|
||||
df[target_col] = None
|
||||
if check_translate_col not in df.columns:
|
||||
df[check_translate_col] = None
|
||||
if affinity_col not in df.columns:
|
||||
df[affinity_col] = None
|
||||
for col in [target_col, check_translate_col, affinity_col]:
|
||||
if col not in df.columns:
|
||||
df[col] = None
|
||||
|
||||
texts_to_translate = {}
|
||||
|
||||
|
@ -218,18 +226,26 @@ def main(tipo_PLC, codigo_columna_maestra, file_path, target_lang_code, target_l
|
|||
if source_translated_col in df.columns
|
||||
else ""
|
||||
)
|
||||
celda_clave_compactada = fc.compactar_celda_traducida(tipo_PLC, celda_clave)
|
||||
celda_clave_compactada = fc.compactar_celda_traducida(
|
||||
config.codigo_tipo_PLC, celda_clave
|
||||
)
|
||||
|
||||
if traducir_todo:
|
||||
if fc.texto_requiere_traduccion(tipo_PLC, celda_clave_compactada, logger):
|
||||
df.at[index, source_translated_col] = '' # Necesita ser traducida.
|
||||
if config.traducir_todo:
|
||||
if fc.texto_requiere_traduccion(
|
||||
config.codigo_tipo_PLC, celda_clave_compactada, logger
|
||||
):
|
||||
df.at[index, source_translated_col] = ""
|
||||
texts_to_translate[celda_clave] = celda_clave_compactada
|
||||
else:
|
||||
if (
|
||||
pd.isna(row[source_translated_col])
|
||||
or source_translated_text.strip() == ""
|
||||
):
|
||||
if fc.texto_requiere_traduccion(tipo_PLC, celda_clave_compactada, logger) or fc.texto_con_campos_especiales(tipo_PLC, celda_clave_compactada):
|
||||
if fc.texto_requiere_traduccion(
|
||||
config.codigo_tipo_PLC, celda_clave_compactada, logger
|
||||
) or fc.texto_con_campos_especiales(
|
||||
config.codigo_tipo_PLC, celda_clave_compactada
|
||||
):
|
||||
texts_to_translate[celda_clave] = celda_clave_compactada
|
||||
|
||||
num_texts = len(texts_to_translate)
|
||||
|
@ -251,7 +267,9 @@ def main(tipo_PLC, codigo_columna_maestra, file_path, target_lang_code, target_l
|
|||
for attempt in range(retries):
|
||||
try:
|
||||
batch_translations = translate_batch_openai(
|
||||
batch_texts, fc.idiomas_idiomafromcode(codigo_columna_maestra) , target_lang
|
||||
batch_texts,
|
||||
fc.idiomas_idiomafromcode(codigo_columna_maestra),
|
||||
target_lang,
|
||||
)
|
||||
translations.update(batch_translations)
|
||||
break # Si la traducción es exitosa, salimos del bucle de reintentos
|
||||
|
@ -284,7 +302,10 @@ def main(tipo_PLC, codigo_columna_maestra, file_path, target_lang_code, target_l
|
|||
df.at[index, target_col] = translations[celda_clave]
|
||||
# Realizar la traducción de verificación con Google Translate
|
||||
try:
|
||||
google_translation = google_translate(translations[celda_clave], fc.idiomas_shortcodefromcode(codigo_columna_maestra))
|
||||
google_translation = google_translate(
|
||||
translations[celda_clave],
|
||||
fc.idiomas_shortcodefromcode(codigo_columna_maestra),
|
||||
)
|
||||
df.at[index, check_translate_col] = google_translation
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
|
@ -296,7 +317,7 @@ def main(tipo_PLC, codigo_columna_maestra, file_path, target_lang_code, target_l
|
|||
# Afinidades
|
||||
# Se calculan las Afinidades
|
||||
affinities = {}
|
||||
for start_idx in range(0, num_texts, batch_size): # num_text
|
||||
for start_idx in range(0, num_texts, batch_size): # num_text
|
||||
end_idx = min(start_idx + batch_size, num_texts)
|
||||
batch_texts = dict(list(texts_to_translate.items())[start_idx:end_idx])
|
||||
logger.info(f"Afinidad: celdas desde {start_idx} a {end_idx}.")
|
||||
|
@ -338,37 +359,25 @@ def main(tipo_PLC, codigo_columna_maestra, file_path, target_lang_code, target_l
|
|||
f"Error en el cálculo individual de Afinidad para el texto '{key}': {ind_e}"
|
||||
)
|
||||
|
||||
|
||||
# Actualizar el DataFrame con las Afinidades
|
||||
for index, row in df.iterrows():
|
||||
celda_clave = str(row[source_col])
|
||||
if celda_clave in affinities:
|
||||
df.at[index, affinity_col] = affinities[celda_clave]
|
||||
|
||||
output_path = os.path.join(
|
||||
os.path.dirname(file_path), f"3_master_export2translate_translated_{tipo_PLC}.xlsx"
|
||||
)
|
||||
output_path = config.get_auto_translate_path()
|
||||
fc.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}")
|
||||
|
||||
def run(tipo_PLC, codigo_columna_maestra, seleccion_idioma, traducir_todo):
|
||||
batch_size = 20
|
||||
translate_file = f".\\data\\2_master_export2translate_{tipo_PLC}.xlsx"
|
||||
|
||||
if seleccion_idioma not in fc.IDIOMAS:
|
||||
print("Selección inválida.")
|
||||
else:
|
||||
target_lang, target_lang_code = fc.IDIOMAS[seleccion_idioma]
|
||||
main(tipo_PLC, codigo_columna_maestra, translate_file, target_lang_code, target_lang, traducir_todo, batch_size)
|
||||
def run(config: TranslationConfig):
|
||||
global logger
|
||||
logger = fc.configurar_logger(config.work_dir)
|
||||
main(config)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
tipo_PLC = "siemens"
|
||||
codigo_columna_maestra = "it-IT"
|
||||
fc.mostrar_idiomas()
|
||||
seleccion_idioma = int(input("Introduce el número del idioma de destino: "))
|
||||
traducir_todo = (
|
||||
input("¿Desea traducir todas las celdas (s/n)? ").strip().lower() == "s"
|
||||
)
|
||||
tipo_PLC = "siemens"
|
||||
run(tipo_PLC, codigo_columna_maestra, seleccion_idioma, traducir_todo)
|
||||
import menu_pasos_traduccion
|
||||
|
||||
menu_pasos_traduccion.main()
|
||||
|
|
|
@ -1,116 +1,122 @@
|
|||
import PyLibrary.funciones_comunes as fc
|
||||
import pandas as pd
|
||||
import os
|
||||
import logging
|
||||
from translation_config import TranslationConfig
|
||||
from openpyxl import load_workbook
|
||||
from openpyxl.styles import Font
|
||||
from openpyxl.comments import Comment
|
||||
|
||||
def importar_traduccion_manual(tipo_PLC, archivo_maestro, archivo_traduccion, target_lang_code):
|
||||
# Definir el logger a nivel de módulo
|
||||
logger = None
|
||||
|
||||
|
||||
def importar_traduccion_manual(config: TranslationConfig):
|
||||
archivo_maestro = config.get_master_path()
|
||||
if not os.path.exists(archivo_maestro):
|
||||
print("El archivo maestro no existe.")
|
||||
return
|
||||
|
||||
master_col = target_lang_code
|
||||
archivo_traduccion = config.get_translate_path()
|
||||
master_col = config.codigo_idioma_seleccionado
|
||||
|
||||
df_maestro = fc.read_dataframe_with_cleanup_retries(archivo_maestro)
|
||||
df_traduccion = fc.read_dataframe_with_cleanup_retries(archivo_traduccion)
|
||||
|
||||
# Configurar el logger
|
||||
logger = fc.configurar_logger()
|
||||
|
||||
# Crear un diccionario para almacenar las celdas modificadas en el maestro
|
||||
celdas_modificadas = {}
|
||||
# Crear un diccionario para almacenar las celdas con errores en el archivo fuente
|
||||
celdas_con_errores = {}
|
||||
|
||||
# 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:
|
||||
valor_traducido = fila[target_lang_code]
|
||||
valor_original = df_maestro.loc[df_maestro[df_maestro.columns[0]] == clave, master_col].values[0]
|
||||
|
||||
if pd.notnull(valor_traducido) and valor_traducido != "" and str(valor_original) != str(valor_traducido):
|
||||
# Verificar si la traducción es válida
|
||||
okToSave, Error = fc.verificar_celda_traducida(tipo_PLC, clave, valor_traducido)
|
||||
valor_traducido = fila[master_col]
|
||||
valor_original = df_maestro.loc[
|
||||
df_maestro[df_maestro.columns[0]] == clave, master_col
|
||||
].values[0]
|
||||
|
||||
if (
|
||||
pd.notnull(valor_traducido)
|
||||
and valor_traducido != ""
|
||||
and str(valor_original) != str(valor_traducido)
|
||||
):
|
||||
okToSave, Error = fc.verificar_celda_traducida(
|
||||
config.codigo_tipo_PLC, clave, valor_traducido
|
||||
)
|
||||
if okToSave:
|
||||
df_maestro.loc[df_maestro[df_maestro.columns[0]] == clave, master_col] = valor_traducido
|
||||
logger.info(f'Fila {index}, Columna {master_col}: "{valor_original}" actualizado a "{valor_traducido}"')
|
||||
|
||||
# Almacenar la posición de la celda modificada en el maestro
|
||||
fila_excel = df_maestro.index[df_maestro[df_maestro.columns[0]] == clave].tolist()[0] + 2 # +2 porque Excel empieza en 1 y tiene encabezados
|
||||
columna_excel = df_maestro.columns.get_loc(master_col) + 1 # +1 porque Excel empieza en 1
|
||||
df_maestro.loc[
|
||||
df_maestro[df_maestro.columns[0]] == clave, master_col
|
||||
] = valor_traducido
|
||||
logger.info(
|
||||
f'Fila {index}, Columna {master_col}: "{valor_original}" actualizado a "{valor_traducido}"'
|
||||
)
|
||||
|
||||
fila_excel = (
|
||||
df_maestro.index[
|
||||
df_maestro[df_maestro.columns[0]] == clave
|
||||
].tolist()[0]
|
||||
+ 2
|
||||
)
|
||||
columna_excel = df_maestro.columns.get_loc(master_col) + 1
|
||||
celdas_modificadas[(fila_excel, columna_excel)] = valor_traducido
|
||||
else:
|
||||
logger.error(f'Fila {index}, Columna {master_col}: No actualizado porque: {Error}')
|
||||
# Almacenar la posición de la celda con error en el archivo fuente
|
||||
fila_excel = index + 2 # +2 porque Excel empieza en 1 y tiene encabezados
|
||||
columna_excel = df_traduccion.columns.get_loc(target_lang_code) + 1 # +1 porque Excel empieza en 1
|
||||
logger.error(
|
||||
f"Fila {index}, Columna {master_col}: No actualizado porque: {Error}"
|
||||
)
|
||||
fila_excel = index + 2
|
||||
columna_excel = df_traduccion.columns.get_loc(master_col) + 1
|
||||
celdas_con_errores[(fila_excel, columna_excel)] = Error
|
||||
|
||||
# Guardar el archivo maestro actualizado
|
||||
fc.save_dataframe_with_retries(df_maestro, output_path=archivo_maestro)
|
||||
|
||||
# Aplicar formato de negrita a las celdas modificadas en el maestro
|
||||
|
||||
aplicar_formato_celdas_maestro(archivo_maestro, celdas_modificadas)
|
||||
|
||||
# Marcar errores en rojo en el archivo fuente
|
||||
|
||||
marcar_errores_archivo_fuente(archivo_traduccion, celdas_con_errores)
|
||||
|
||||
print(f"Traducciones manuales importadas y archivo maestro actualizado: {archivo_maestro}.")
|
||||
print(f"Se han actualizado {len(celdas_modificadas)} celdas en el maestro y se han encontrado {len(celdas_con_errores)} errores en el archivo fuente.")
|
||||
|
||||
print(
|
||||
f"Traducciones manuales importadas y archivo maestro actualizado: {archivo_maestro}."
|
||||
)
|
||||
print(
|
||||
f"Se han actualizado {len(celdas_modificadas)} celdas en el maestro y se han encontrado {len(celdas_con_errores)} errores en el archivo fuente."
|
||||
)
|
||||
|
||||
|
||||
def aplicar_formato_celdas_maestro(archivo, celdas_modificadas):
|
||||
"""
|
||||
Aplica formato de negrita a las celdas modificadas en el archivo maestro.
|
||||
|
||||
:param archivo: Ruta del archivo Excel maestro.
|
||||
:param celdas_modificadas: Diccionario con las celdas modificadas {(fila, columna): valor}.
|
||||
"""
|
||||
workbook = load_workbook(archivo)
|
||||
sheet = workbook.active
|
||||
|
||||
|
||||
for (fila, columna), valor in celdas_modificadas.items():
|
||||
celda = sheet.cell(row=fila, column=columna)
|
||||
celda.font = Font(bold=True)
|
||||
celda.value = valor
|
||||
|
||||
workbook.save(archivo)
|
||||
print(f"Se han formateado {len(celdas_modificadas)} celdas modificadas en negrita en el archivo maestro.")
|
||||
print(
|
||||
f"Se han formateado {len(celdas_modificadas)} celdas modificadas en negrita en el archivo maestro."
|
||||
)
|
||||
|
||||
|
||||
def marcar_errores_archivo_fuente(archivo, celdas_con_errores):
|
||||
"""
|
||||
Marca en rojo las celdas con errores en el archivo fuente y añade comentarios.
|
||||
|
||||
:param archivo: Ruta del archivo Excel fuente.
|
||||
:param celdas_con_errores: Diccionario con las celdas con errores {(fila, columna): mensaje_error}.
|
||||
"""
|
||||
workbook = load_workbook(archivo)
|
||||
sheet = workbook.active
|
||||
|
||||
|
||||
for (fila, columna), mensaje_error in celdas_con_errores.items():
|
||||
celda = sheet.cell(row=fila, column=columna)
|
||||
celda.font = Font(color="FF0000") # Texto en rojo
|
||||
comment = Comment(mensaje_error, "Sistema de Traducción")
|
||||
celda.comment = comment
|
||||
|
||||
|
||||
workbook.save(archivo)
|
||||
print(f"Se han marcado {len(celdas_con_errores)} celdas con errores en rojo en el archivo fuente.")
|
||||
print(
|
||||
f"Se han marcado {len(celdas_con_errores)} celdas con errores en rojo en el archivo fuente."
|
||||
)
|
||||
|
||||
def run(tipo_PLC, codigo_columna_maestra, seleccion_idioma):
|
||||
archivo_maestro = f".\\data\\1_hmi_master_translates_{tipo_PLC}.xlsx"
|
||||
archivo_traduccion = f".\\data\\2_master_export2translate_{tipo_PLC}.xlsx"
|
||||
|
||||
if seleccion_idioma not in fc.IDIOMAS:
|
||||
print("Selección inválida.")
|
||||
else:
|
||||
_, target_lang_code = fc.IDIOMAS[seleccion_idioma]
|
||||
importar_traduccion_manual(tipo_PLC, archivo_maestro, archivo_traduccion, target_lang_code)
|
||||
|
||||
if __name__ == "__main__":
|
||||
tipo_PLC = "siemens"
|
||||
codigo_columna_maestra = "it-IT"
|
||||
fc.mostrar_idiomas()
|
||||
seleccion_idioma = int(input("Introduce el número del idioma de destino: "))
|
||||
run(tipo_PLC, codigo_columna_maestra, seleccion_idioma)
|
||||
def run(config: TranslationConfig):
|
||||
global logger
|
||||
logger = fc.configurar_logger(config.work_dir)
|
||||
importar_traduccion_manual(config)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import menu_pasos_traduccion
|
||||
|
||||
menu_pasos_traduccion.main()
|
||||
|
|
|
@ -1,89 +1,90 @@
|
|||
import PyLibrary.funciones_comunes as fc
|
||||
import pandas as pd
|
||||
import os
|
||||
import re
|
||||
import logging
|
||||
from translation_config import TranslationConfig
|
||||
from openpyxl import load_workbook
|
||||
from openpyxl.styles import Font
|
||||
|
||||
def importar_traduccion(tipo_PLC, archivo_maestro, archivo_traduccion, target_lang_code, nivel_afinidad_minimo):
|
||||
# Definir el logger a nivel de módulo
|
||||
logger = None
|
||||
|
||||
|
||||
def importar_traduccion(config: TranslationConfig):
|
||||
archivo_maestro = config.get_master_path()
|
||||
if not os.path.exists(archivo_maestro):
|
||||
print("El archivo maestro no existe.")
|
||||
return
|
||||
|
||||
master_col = target_lang_code
|
||||
translated_col = f"{target_lang_code} Translated"
|
||||
affinity_col = f"{target_lang_code} Affinity"
|
||||
master_col = config.codigo_idioma_seleccionado
|
||||
translated_col = f"{config.codigo_idioma_seleccionado} Translated"
|
||||
affinity_col = f"{config.codigo_idioma_seleccionado} Affinity"
|
||||
|
||||
df_maestro = fc.read_dataframe_with_cleanup_retries(archivo_maestro)
|
||||
df_traduccion = fc.read_dataframe_with_cleanup_retries(archivo_traduccion)
|
||||
df_traduccion = fc.read_dataframe_with_cleanup_retries(
|
||||
config.get_auto_translate_path()
|
||||
)
|
||||
|
||||
# Configurar el logger
|
||||
logger = fc.configurar_logger()
|
||||
|
||||
# Crear un diccionario para almacenar las celdas modificadas
|
||||
celdas_modificadas = {}
|
||||
|
||||
# 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[translated_col]) and fila[translated_col] != "":
|
||||
if (
|
||||
fila[affinity_col] >= config.nivel_afinidad_minimo
|
||||
and pd.notnull(fila[translated_col])
|
||||
and fila[translated_col] != ""
|
||||
):
|
||||
valor_traducido = fila[translated_col]
|
||||
valor_original = df_maestro.loc[df_maestro[df_maestro.columns[0]] == clave, master_col].values[0]
|
||||
|
||||
valor_original = df_maestro.loc[
|
||||
df_maestro[df_maestro.columns[0]] == clave, master_col
|
||||
].values[0]
|
||||
|
||||
if str(valor_original) != str(valor_traducido):
|
||||
df_maestro.loc[df_maestro[df_maestro.columns[0]] == clave, master_col] = valor_traducido
|
||||
logger.info(f'Fila {index}, Columna {translated_col}: "{valor_original}" actualizado a "{valor_traducido}"')
|
||||
|
||||
# Almacenar la posición de la celda modificada
|
||||
fila_excel = df_maestro.index[df_maestro[df_maestro.columns[0]] == clave].tolist()[0] + 2 # +2 porque Excel empieza en 1 y tiene encabezados
|
||||
columna_excel = df_maestro.columns.get_loc(master_col) + 1 # +1 porque Excel empieza en 1
|
||||
df_maestro.loc[
|
||||
df_maestro[df_maestro.columns[0]] == clave, master_col
|
||||
] = valor_traducido
|
||||
logger.info(
|
||||
f'Fila {index}, Columna {translated_col}: "{valor_original}" actualizado a "{valor_traducido}"'
|
||||
)
|
||||
|
||||
fila_excel = (
|
||||
df_maestro.index[
|
||||
df_maestro[df_maestro.columns[0]] == clave
|
||||
].tolist()[0]
|
||||
+ 2
|
||||
)
|
||||
columna_excel = df_maestro.columns.get_loc(master_col) + 1
|
||||
celdas_modificadas[(fila_excel, columna_excel)] = valor_traducido
|
||||
|
||||
# Guardar el archivo maestro actualizado
|
||||
fc.save_dataframe_with_retries(df_maestro, output_path=archivo_maestro)
|
||||
|
||||
# Aplicar formato de negrita a las celdas modificadas
|
||||
|
||||
aplicar_negrita_celdas_modificadas(archivo_maestro, celdas_modificadas)
|
||||
|
||||
|
||||
print(f"Traducciones importadas y archivo maestro actualizado: {archivo_maestro}.")
|
||||
|
||||
|
||||
def aplicar_negrita_celdas_modificadas(archivo, celdas_modificadas):
|
||||
"""
|
||||
Aplica formato de negrita a las celdas especificadas en un archivo Excel.
|
||||
|
||||
:param archivo: Ruta del archivo Excel.
|
||||
:param celdas_modificadas: Diccionario con las celdas a modificar {(fila, columna): valor}.
|
||||
"""
|
||||
workbook = load_workbook(archivo)
|
||||
sheet = workbook.active
|
||||
|
||||
|
||||
for (fila, columna), valor in celdas_modificadas.items():
|
||||
celda = sheet.cell(row=fila, column=columna)
|
||||
celda.font = Font(bold=True)
|
||||
celda.value = valor # Asegurarse de que el valor es el correcto
|
||||
|
||||
celda.value = valor
|
||||
|
||||
workbook.save(archivo)
|
||||
print(f"Se han marcado en negrita {len(celdas_modificadas)} celdas modificadas en {archivo}.")
|
||||
print(
|
||||
f"Se han marcado en negrita {len(celdas_modificadas)} celdas modificadas en {archivo}."
|
||||
)
|
||||
|
||||
def run(tipo_PLC, codigo_columna_maestra, seleccion_idioma, nivel_afinidad_minimo):
|
||||
archivo_maestro = f".\\data\\1_hmi_master_translates_{tipo_PLC}.xlsx"
|
||||
archivo_traduccion = f".\\data\\3_master_export2translate_translated_{tipo_PLC}.xlsx"
|
||||
|
||||
if seleccion_idioma not in fc.IDIOMAS:
|
||||
print("Selección inválida.")
|
||||
else:
|
||||
target_lang, target_lang_code = fc.IDIOMAS[seleccion_idioma]
|
||||
importar_traduccion(tipo_PLC, archivo_maestro, archivo_traduccion, target_lang_code, nivel_afinidad_minimo)
|
||||
|
||||
if __name__ == "__main__":
|
||||
tipo_PLC = "siemens"
|
||||
codigo_columna_maestra = "it-IT"
|
||||
nivel_afinidad_minimo = input("Introduce el nivel mínimo de afinidad para importar (presiona Enter para usar el valor por defecto 0.5): ")
|
||||
nivel_afinidad_minimo = float(nivel_afinidad_minimo) if nivel_afinidad_minimo else 0.5
|
||||
def run(config: TranslationConfig):
|
||||
global logger
|
||||
logger = fc.configurar_logger(config.work_dir)
|
||||
importar_traduccion(config)
|
||||
|
||||
fc.mostrar_idiomas()
|
||||
seleccion_idioma = int(input("Introduce el número del idioma de destino: "))
|
||||
run(tipo_PLC, codigo_columna_maestra, seleccion_idioma, nivel_afinidad_minimo)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import menu_pasos_traduccion
|
||||
|
||||
menu_pasos_traduccion.main()
|
||||
|
|
|
@ -1,80 +1,54 @@
|
|||
import PyLibrary.funciones_comunes as fc
|
||||
import pandas as pd
|
||||
import os
|
||||
import re
|
||||
import logging
|
||||
from openpyxl.utils.escape import unescape
|
||||
from translation_config import TranslationConfig
|
||||
|
||||
def complete_emptys(tipo_PLC,codigo_columna_maestra, archivo_maestro, target_lang_code, second_lang_code):
|
||||
# Definir el logger a nivel de módulo
|
||||
logger = None
|
||||
|
||||
|
||||
def complete_emptys(config: TranslationConfig):
|
||||
archivo_maestro = config.get_master_path()
|
||||
if not os.path.exists(archivo_maestro):
|
||||
print("El archivo maestro no existe.")
|
||||
return
|
||||
|
||||
target_col = target_lang_code
|
||||
second_col = second_lang_code
|
||||
target_col = config.codigo_idioma_seleccionado
|
||||
second_col = config.codigo_idioma_secundario
|
||||
|
||||
df_maestro = fc.read_dataframe_with_cleanup_retries(archivo_maestro)
|
||||
|
||||
# Configurar el logger
|
||||
logger = fc.configurar_logger()
|
||||
|
||||
# Iterar sobre las filas del archivo de traducción para actualizar el maestro
|
||||
for index, fila in df_maestro.iterrows():
|
||||
clave = fila[codigo_columna_maestra]
|
||||
clave = fila[config.codigo_columna_maestra]
|
||||
if fila[target_col] == "" or pd.isnull(fila[target_col]):
|
||||
if pd.notnull(fila[second_col]) and fila[second_col] != "":
|
||||
df_maestro.loc[
|
||||
df_maestro[codigo_columna_maestra] == clave, target_col
|
||||
df_maestro[config.codigo_columna_maestra] == clave, target_col
|
||||
] = fila[second_col]
|
||||
logger.info(
|
||||
f'Fila {index}, Columna {target_col}: " actualizado a "{fila[second_col]}"'
|
||||
f'Fila {index}, Columna {target_col}: "" actualizado a "{fila[second_col]}"'
|
||||
)
|
||||
else:
|
||||
df_maestro.loc[
|
||||
df_maestro[codigo_columna_maestra] == clave, target_col
|
||||
] = fc.compactar_celda_traducida(tipo_PLC, fila[codigo_columna_maestra])
|
||||
df_maestro[config.codigo_columna_maestra] == clave, target_col
|
||||
] = fc.compactar_celda_traducida(
|
||||
config.codigo_tipo_PLC, fila[config.codigo_columna_maestra]
|
||||
)
|
||||
logger.info(
|
||||
f'Fila {index}, Columna {target_col}: " actualizado a "{fila[codigo_columna_maestra]}"'
|
||||
f'Fila {index}, Columna {target_col}: "" actualizado a "{fila[config.codigo_columna_maestra]}"'
|
||||
)
|
||||
|
||||
# Guardar el archivo maestro actualizado
|
||||
fc.save_dataframe_with_retries(
|
||||
df_maestro, output_path=archivo_maestro
|
||||
)
|
||||
print(
|
||||
f"Traducciones importadas y archivo maestro actualizado: {archivo_maestro}."
|
||||
)
|
||||
fc.save_dataframe_with_retries(df_maestro, output_path=archivo_maestro)
|
||||
print(f"Traducciones importadas y archivo maestro actualizado: {archivo_maestro}.")
|
||||
|
||||
def run(tipo_PLC, codigo_columna_maestra, seleccion_idioma, seleccion_idioma_secundario):
|
||||
archivo_maestro = f".\\data\\1_hmi_master_translates_{tipo_PLC}.xlsx"
|
||||
|
||||
if seleccion_idioma not in fc.IDIOMAS:
|
||||
print("Selección inválida.")
|
||||
exit
|
||||
def run(config: TranslationConfig):
|
||||
global logger
|
||||
logger = fc.configurar_logger(config.work_dir)
|
||||
complete_emptys(config)
|
||||
|
||||
if seleccion_idioma_secundario not in fc.IDIOMAS:
|
||||
print("Selección inválida.")
|
||||
exit
|
||||
|
||||
_, target_lang_code = fc.IDIOMAS[seleccion_idioma]
|
||||
_, second_lang_code = fc.IDIOMAS[seleccion_idioma_secundario]
|
||||
complete_emptys(tipo_PLC, codigo_columna_maestra, archivo_maestro, target_lang_code, second_lang_code)
|
||||
|
||||
if __name__ == "__main__":
|
||||
tipo_PLC = "siemens"
|
||||
codigo_columna_maestra = "it-IT"
|
||||
fc.mostrar_idiomas()
|
||||
seleccion_idioma = int(input("Introduce el número del idioma de destino: "))
|
||||
if seleccion_idioma not in fc.IDIOMAS:
|
||||
print("Selección inválida.")
|
||||
exit
|
||||
seleccion_idioma_secundario = int(
|
||||
input(
|
||||
"Introduce el número del idioma de secundario para copiar desde en caso de vacios: "
|
||||
)
|
||||
)
|
||||
if seleccion_idioma_secundario not in fc.IDIOMAS:
|
||||
print("Selección inválida.")
|
||||
exit
|
||||
run(tipo_PLC, codigo_columna_maestra, seleccion_idioma, seleccion_idioma_secundario)
|
||||
import menu_pasos_traduccion
|
||||
|
||||
menu_pasos_traduccion.main()
|
||||
|
|
|
@ -1,78 +1,78 @@
|
|||
import pandas as pd
|
||||
import os
|
||||
import re
|
||||
import logging
|
||||
import PyLibrary.funciones_comunes as fc
|
||||
from openpyxl.utils.escape import unescape
|
||||
from translation_config import TranslationConfig
|
||||
from openpyxl import load_workbook
|
||||
from openpyxl.styles import Font
|
||||
from openpyxl.comments import Comment
|
||||
|
||||
def update_from_master(tipo_PLC, codigo_columna_maestra, archivo_maestro, archivo_to_update, target_lang_code):
|
||||
# Definir el logger a nivel de módulo
|
||||
logger = None
|
||||
|
||||
|
||||
def update_from_master(config: TranslationConfig, archivo_to_update):
|
||||
archivo_maestro = config.get_master_path()
|
||||
if not os.path.exists(archivo_maestro):
|
||||
print("El archivo maestro no existe.")
|
||||
return
|
||||
|
||||
# Configurar el logger
|
||||
logger = fc.configurar_logger()
|
||||
|
||||
logger.info(" .... ")
|
||||
logger.info(
|
||||
f"Iniciando actualización en {archivo_to_update} desde el archivo maestro. Para {target_lang_code} "
|
||||
f"Iniciando actualización en {archivo_to_update} desde el archivo maestro. Para {config.codigo_idioma_seleccionado}"
|
||||
)
|
||||
|
||||
df_maestro = fc.read_dataframe_with_cleanup_retries(archivo_maestro)
|
||||
df_to_update = fc.read_dataframe_with_cleanup_retries(archivo_to_update)
|
||||
|
||||
col_clave = codigo_columna_maestra
|
||||
col_clave = config.codigo_columna_maestra
|
||||
|
||||
# Diccionario para almacenar las celdas con errores en el archivo maestro
|
||||
celdas_con_errores = {}
|
||||
|
||||
# Iterar sobre las filas del archivo de actualización para actualizarlas
|
||||
for index, fila in df_to_update.iterrows():
|
||||
for index, fila in df_to_update.iterrows():
|
||||
valor_original = fila[col_clave]
|
||||
clave = fc.compactar_celda_clave(tipo_PLC, valor_original)
|
||||
logger.info(
|
||||
f'Fila {index} : Clave: {clave}'
|
||||
)
|
||||
clave = fc.compactar_celda_clave(config.codigo_tipo_PLC, valor_original)
|
||||
logger.info(f"Fila {index} : Clave: {clave}")
|
||||
|
||||
if not pd.isnull(clave) and clave in df_maestro[col_clave].values:
|
||||
# Obtenemos los valores
|
||||
indice_maestro = df_maestro.index[df_maestro[col_clave] == clave].tolist()[0]
|
||||
valor_traducido_compacto = df_maestro.loc[indice_maestro, target_lang_code]
|
||||
|
||||
# Descompactamos
|
||||
valor_traducido = fc.decompactar_celda_traducida(tipo_PLC,
|
||||
celda_original=valor_original, celda_traducida=valor_traducido_compacto
|
||||
indice_maestro = df_maestro.index[df_maestro[col_clave] == clave].tolist()[
|
||||
0
|
||||
]
|
||||
valor_traducido_compacto = df_maestro.loc[
|
||||
indice_maestro, config.codigo_idioma_seleccionado
|
||||
]
|
||||
|
||||
valor_traducido = fc.decompactar_celda_traducida(
|
||||
config.codigo_tipo_PLC,
|
||||
celda_original=valor_original,
|
||||
celda_traducida=valor_traducido_compacto,
|
||||
)
|
||||
if (
|
||||
not pd.isnull(valor_traducido)
|
||||
and fila[target_lang_code] != valor_traducido
|
||||
and fila[config.codigo_idioma_seleccionado] != valor_traducido
|
||||
):
|
||||
# Verificamos si la traducción es válida
|
||||
okToSave, Error = fc.verificar_celda_traducida(tipo_PLC,
|
||||
clave, valor_traducido_compacto
|
||||
okToSave, Error = fc.verificar_celda_traducida(
|
||||
config.codigo_tipo_PLC, clave, valor_traducido_compacto
|
||||
)
|
||||
if okToSave:
|
||||
logger.info("Actualizado.")
|
||||
df_to_update.at[index, target_lang_code] = valor_traducido
|
||||
else:
|
||||
df_to_update.at[index, target_lang_code] = valor_original
|
||||
logger.error(
|
||||
f'No actualizado porque: {Error}'
|
||||
df_to_update.at[index, config.codigo_idioma_seleccionado] = (
|
||||
valor_traducido
|
||||
)
|
||||
# Almacenar la celda con error para marcarla en rojo más tarde en el archivo maestro
|
||||
else:
|
||||
df_to_update.at[index, config.codigo_idioma_seleccionado] = (
|
||||
valor_original
|
||||
)
|
||||
logger.error(f"No actualizado porque: {Error}")
|
||||
celdas_con_errores[indice_maestro] = Error
|
||||
|
||||
# Guardar el archivo actualizado
|
||||
nombre, extension = os.path.splitext(archivo_to_update)
|
||||
nuevo_nombre = f"{nombre}_import{extension}"
|
||||
fc.save_dataframe_with_retries(df_to_update, output_path=nuevo_nombre)
|
||||
|
||||
# Marcar celdas con errores en rojo en el archivo maestro
|
||||
marcar_celdas_con_errores(archivo_maestro, celdas_con_errores, target_lang_code)
|
||||
|
||||
|
||||
marcar_celdas_con_errores(
|
||||
archivo_maestro, celdas_con_errores, config.codigo_idioma_seleccionado
|
||||
)
|
||||
|
||||
print(
|
||||
f"Se han actualizado las filas en {archivo_to_update} desde el archivo maestro. "
|
||||
f"Se han marcado {len(celdas_con_errores)} celdas con errores en el archivo maestro."
|
||||
|
@ -83,18 +83,11 @@ def update_from_master(tipo_PLC, codigo_columna_maestra, archivo_maestro, archiv
|
|||
)
|
||||
logger.info(" .... ")
|
||||
|
||||
|
||||
def marcar_celdas_con_errores(archivo_maestro, celdas_con_errores, target_lang_code):
|
||||
"""
|
||||
Marca las celdas con errores en rojo en el archivo maestro Excel.
|
||||
|
||||
:param archivo_maestro: Ruta del archivo maestro Excel.
|
||||
:param celdas_con_errores: Diccionario con las celdas a marcar {indice_maestro: mensaje_error}.
|
||||
:param target_lang_code: Código del idioma objetivo.
|
||||
"""
|
||||
workbook = load_workbook(archivo_maestro)
|
||||
sheet = workbook.active
|
||||
|
||||
# Encontrar la columna del idioma objetivo
|
||||
|
||||
for col in range(1, sheet.max_column + 1):
|
||||
if sheet.cell(row=1, column=col).value == target_lang_code:
|
||||
target_col = col
|
||||
|
@ -103,32 +96,29 @@ def marcar_celdas_con_errores(archivo_maestro, celdas_con_errores, target_lang_c
|
|||
print(f"No se encontró la columna para el idioma {target_lang_code}")
|
||||
return
|
||||
|
||||
# Marcar celdas con errores
|
||||
for indice_maestro, mensaje_error in celdas_con_errores.items():
|
||||
row = indice_maestro + 2 # +2 porque Excel empieza en 1 y tiene encabezados
|
||||
row = indice_maestro + 2
|
||||
cell = sheet.cell(row=row, column=target_col)
|
||||
cell.font = Font(color="FF0000") # Texto en rojo
|
||||
|
||||
# Añadir un comentario con el mensaje de error
|
||||
cell.font = Font(color="FF0000")
|
||||
|
||||
comment = Comment(mensaje_error, "Sistema de Traducción")
|
||||
cell.comment = comment
|
||||
|
||||
workbook.save(archivo_maestro)
|
||||
print(f"Se han marcado {len(celdas_con_errores)} celdas con errores en rojo en el archivo maestro {archivo_maestro}")
|
||||
print(
|
||||
f"Se han marcado {len(celdas_con_errores)} celdas con errores en rojo en el archivo maestro {archivo_maestro}"
|
||||
)
|
||||
|
||||
def run(tipo_PLC, codigo_columna_maestra, seleccion_idioma):
|
||||
archivo_maestro = f".\\data\\1_hmi_master_translates_{tipo_PLC}.xlsx"
|
||||
|
||||
def run(config: TranslationConfig):
|
||||
global logger
|
||||
logger = fc.configurar_logger(config.work_dir)
|
||||
archivo_to_update = fc.select_file("xlsx")
|
||||
if archivo_to_update:
|
||||
if seleccion_idioma not in fc.IDIOMAS:
|
||||
print("Selección inválida.")
|
||||
else:
|
||||
_, target_lang_code = fc.IDIOMAS[seleccion_idioma]
|
||||
update_from_master(tipo_PLC, codigo_columna_maestra, archivo_maestro, archivo_to_update, target_lang_code)
|
||||
update_from_master(config, archivo_to_update)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
tipo_PLC = "siemens"
|
||||
codigo_columna_maestra = "it-IT"
|
||||
fc.mostrar_idiomas()
|
||||
seleccion_idioma = int(input("Introduce el número del idioma de destino: "))
|
||||
run(tipo_PLC, codigo_columna_maestra, seleccion_idioma)
|
||||
import menu_pasos_traduccion
|
||||
|
||||
menu_pasos_traduccion.main()
|
||||
|
|
Loading…
Reference in New Issue