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.
|
@ -16,4 +16,6 @@ output_text = Ejecutando x4B_integrate_manual_translates_to_master.run()
|
||||||
Traducciones manuales importadas y archivo maestro actualizado: .\data\1_hmi_master_translates_allenbradley.xlsx.
|
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.
|
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
|
||||||
|
|
||||||
|
|
20649
logs/translate_log.log
20649
logs/translate_log.log
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,5 @@
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import ttk
|
from tkinter import ttk, filedialog, messagebox
|
||||||
from tkinter import messagebox
|
|
||||||
import PyLibrary.funciones_comunes as fc
|
import PyLibrary.funciones_comunes as fc
|
||||||
import x1_importar_to_master
|
import x1_importar_to_master
|
||||||
import x2_master_export2translate
|
import x2_master_export2translate
|
||||||
|
@ -9,287 +8,300 @@ import x4_integrate_translates_to_master
|
||||||
import x4B_integrate_manual_translates_to_master
|
import x4B_integrate_manual_translates_to_master
|
||||||
import x5_complete_empty_cells_master
|
import x5_complete_empty_cells_master
|
||||||
import x6_update_from_master
|
import x6_update_from_master
|
||||||
|
from translation_config import TranslationConfig
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
import configparser # Para manejar el archivo de configuración
|
import os
|
||||||
import os # Para verificar si el archivo existe
|
import subprocess
|
||||||
|
|
||||||
# Crear la ventana principal
|
class TranslationApp:
|
||||||
ventana = tk.Tk()
|
def __init__(self, master):
|
||||||
ventana.title("Ayuda para traducir textos de TIA Portal y Allen Bradley")
|
self.master = master
|
||||||
ventana.geometry("800x600") # Ajustamos el tamaño de la ventana
|
self.master.title("Ayuda para traducir textos de TIA Portal y Allen Bradley")
|
||||||
|
self.master.geometry("1200x800")
|
||||||
|
|
||||||
# Diccionario para tipo_PLC
|
self.config = TranslationConfig.load()
|
||||||
tipo_PLC_dict = {'Siemens': 'siemens', 'AllenBradley': 'allenbradley'}
|
|
||||||
|
|
||||||
# Variables para almacenar las selecciones del usuario
|
self.create_variables()
|
||||||
tipo_PLC_var = tk.StringVar()
|
self.create_widgets()
|
||||||
codigo_columna_maestra_var = tk.StringVar()
|
self.place_widgets()
|
||||||
idioma_var = tk.StringVar()
|
|
||||||
idioma_var2 = tk.StringVar()
|
|
||||||
|
|
||||||
# Crear listas de idiomas con sus códigos
|
def create_variables(self):
|
||||||
idiomas_lista = [(nombre, codigo) for _, (nombre, codigo) in fc.IDIOMAS.items()]
|
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
|
self.master_name_var = tk.StringVar(value=self.config.master_name)
|
||||||
config_file = 'config.ini'
|
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():
|
def create_widgets(self):
|
||||||
tipo_PLC = tipo_PLC_dict[tipo_PLC_var.get()]
|
self.main_frame = ttk.Frame(self.master)
|
||||||
archivo_maestro = f".\\data\\1_hmi_master_translates_{tipo_PLC}.xlsx"
|
self.main_frame.grid(row=0, column=0, sticky='nsew')
|
||||||
master_directory = os.path.dirname(os.path.abspath(archivo_maestro))
|
self.master.grid_rowconfigure(0, weight=1)
|
||||||
fc.open_file_explorer(master_directory)
|
self.master.grid_columnconfigure(0, weight=1)
|
||||||
|
|
||||||
def open_log_file():
|
self.frame_combos = ttk.Frame(self.main_frame)
|
||||||
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.")
|
|
||||||
|
|
||||||
# Función para cargar las opciones guardadas
|
self.label_tipo_PLC = ttk.Label(self.frame_combos, text="Selecciona el tipo de PLC:")
|
||||||
def cargar_configuracion():
|
self.combo_tipo_PLC = ttk.Combobox(self.frame_combos, state="readonly")
|
||||||
config = configparser.ConfigParser()
|
self.combo_tipo_PLC["values"] = [nombre for nombre, _ in fc.PLCs.values()]
|
||||||
if os.path.exists(config_file):
|
self.combo_tipo_PLC.bind('<<ComboboxSelected>>', self.update_tipo_PLC)
|
||||||
config.read(config_file)
|
self.set_combo_value(self.combo_tipo_PLC, self.codigo_tipo_PLC_var.get())
|
||||||
# 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])
|
|
||||||
|
|
||||||
# Función para guardar las opciones seleccionadas
|
self.label_codigo_maestra = ttk.Label(self.frame_combos, text="Idioma Columna Maestra:")
|
||||||
def guardar_configuracion():
|
self.combo_codigo_maestra = ttk.Combobox(self.frame_combos, state="readonly")
|
||||||
config = configparser.ConfigParser()
|
self.combo_codigo_maestra["values"] = [nombre for nombre, _ in fc.IDIOMAS.values()]
|
||||||
config['Seleccion'] = {
|
self.combo_codigo_maestra.bind('<<ComboboxSelected>>', self.update_codigo_maestra)
|
||||||
'tipo_PLC': tipo_PLC_var.get(),
|
self.set_combo_value(self.combo_codigo_maestra, self.codigo_columna_maestra_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)
|
|
||||||
|
|
||||||
# Crear un Frame para la grilla de comboboxes
|
self.label1 = ttk.Label(self.frame_combos, text="Idioma de Traducción:")
|
||||||
frame_combos = tk.Frame(ventana)
|
self.combo = ttk.Combobox(self.frame_combos, state="readonly")
|
||||||
frame_combos.pack(pady=10)
|
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 los labels y comboboxes
|
self.label2 = ttk.Label(self.frame_combos, text="Selecciona segundo idioma:")
|
||||||
label_tipo_PLC = tk.Label(frame_combos, text="Selecciona el tipo de PLC:")
|
self.combo2 = ttk.Combobox(self.frame_combos, state="readonly")
|
||||||
combo_tipo_PLC = ttk.Combobox(frame_combos, textvariable=tipo_PLC_var, state="readonly")
|
self.combo2["values"] = [nombre for nombre, _ in fc.IDIOMAS.values()]
|
||||||
combo_tipo_PLC["values"] = list(tipo_PLC_dict.keys())
|
self.combo2.bind('<<ComboboxSelected>>', self.update_idioma2)
|
||||||
|
self.set_combo_value(self.combo2, self.codigo_idioma_var2.get())
|
||||||
|
|
||||||
label_codigo_maestra = tk.Label(frame_combos, text="Idioma Columna Maestra:")
|
self.work_dir_frame = ttk.Frame(self.main_frame)
|
||||||
combo_codigo_maestra = ttk.Combobox(frame_combos, textvariable=codigo_columna_maestra_var, state="readonly")
|
self.work_dir_label = ttk.Label(self.work_dir_frame, text="Directorio de trabajo:")
|
||||||
combo_codigo_maestra["values"] = [nombre for nombre, _ in idiomas_lista]
|
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)
|
||||||
|
|
||||||
label1 = tk.Label(frame_combos, text="Idioma de Traducción:")
|
style = ttk.Style()
|
||||||
combo = ttk.Combobox(frame_combos, textvariable=idioma_var, state="readonly")
|
style.configure('TButton', padding=(10, 10), font=('Helvetica', 10, 'bold'))
|
||||||
combo["values"] = [nombre for nombre, _ in idiomas_lista]
|
style.configure('Excel.TButton', padding=(10, 10), font=('Helvetica', 10), background='#69cf81')
|
||||||
|
|
||||||
label2 = tk.Label(frame_combos, text="Selecciona segundo idioma:")
|
self.button_width = 60
|
||||||
combo2 = ttk.Combobox(frame_combos, textvariable=idioma_var2, state="readonly")
|
self.entry_width = 50
|
||||||
combo2["values"] = [nombre for nombre, _ in idiomas_lista]
|
|
||||||
|
|
||||||
# Organizar los labels y comboboxes en una grilla 2x2
|
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)
|
||||||
label_tipo_PLC.grid(row=0, column=0, padx=5, pady=5, sticky='e')
|
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')
|
||||||
combo_tipo_PLC.grid(row=0, column=1, padx=5, pady=5, sticky='w')
|
|
||||||
|
|
||||||
label_codigo_maestra.grid(row=1, column=0, padx=5, pady=5, sticky='e')
|
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)
|
||||||
combo_codigo_maestra.grid(row=1, column=1, padx=5, pady=5, sticky='w')
|
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')
|
||||||
|
|
||||||
label1.grid(row=0, column=2, padx=5, pady=5, sticky='e')
|
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)
|
||||||
combo.grid(row=0, column=3, padx=5, pady=5, sticky='w')
|
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')
|
||||||
|
|
||||||
label2.grid(row=1, column=2, padx=5, pady=5, sticky='e')
|
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)
|
||||||
combo2.grid(row=1, column=3, padx=5, pady=5, sticky='w')
|
|
||||||
|
|
||||||
# Función para actualizar combo_codigo_maestra según la selección en combo_tipo_PLC
|
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)
|
||||||
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
|
|
||||||
|
|
||||||
# Vincular la función al evento de cambio de selección en combo_tipo_PLC
|
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)
|
||||||
combo_tipo_PLC.bind('<<ComboboxSelected>>', actualizar_codigo_maestra)
|
|
||||||
|
|
||||||
# Vincular eventos de cambio en los comboboxes para guardar la configuración
|
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)
|
||||||
def on_combobox_changed(event):
|
|
||||||
guardar_configuracion()
|
|
||||||
|
|
||||||
combo_codigo_maestra.bind('<<ComboboxSelected>>', on_combobox_changed)
|
self.output_text = tk.Text(self.main_frame, wrap='none', height=20)
|
||||||
combo.bind('<<ComboboxSelected>>', on_combobox_changed)
|
self.scrollbar_y = ttk.Scrollbar(self.main_frame, orient='vertical', command=self.output_text.yview)
|
||||||
combo2.bind('<<ComboboxSelected>>', on_combobox_changed)
|
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)
|
||||||
|
|
||||||
# Clase para redirigir la salida estándar a la caja de texto
|
self.clear_button = ttk.Button(self.main_frame, text="Limpiar salida", command=self.clear_output)
|
||||||
class RedirectText(object):
|
self.open_log_button = ttk.Button(self.main_frame, text="Abrir Log", command=self.open_log_file)
|
||||||
def __init__(self, text_widget):
|
|
||||||
self.output = text_widget
|
|
||||||
|
|
||||||
def write(self, string):
|
def place_widgets(self):
|
||||||
self.output.insert(tk.END, string)
|
self.main_frame.grid_columnconfigure(0, weight=1)
|
||||||
self.output.see(tk.END) # Desplaza hacia el final
|
self.main_frame.grid_columnconfigure(1, weight=1)
|
||||||
|
|
||||||
def flush(self):
|
self.frame_combos.grid(row=0, column=0, columnspan=2, pady=10, sticky='ew')
|
||||||
pass # No se requiere implementación para flush
|
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')
|
||||||
|
|
||||||
# Función para obtener el código del idioma seleccionado a partir del nombre
|
self.work_dir_frame.grid(row=1, column=0, columnspan=2, pady=10, sticky='ew')
|
||||||
def obtener_codigo_idioma_por_nombre(nombre_idioma):
|
self.work_dir_label.grid(row=0, column=0, padx=5, sticky='w')
|
||||||
for nombre, codigo in idiomas_lista:
|
self.work_dir_entry.grid(row=0, column=1, padx=5, sticky='ew')
|
||||||
if nombre == nombre_idioma:
|
self.work_dir_button.grid(row=0, column=2, padx=5, sticky='e')
|
||||||
return codigo
|
self.open_explorer_button.grid(row=0, column=3, padx=5, sticky='e')
|
||||||
return None
|
self.work_dir_frame.grid_columnconfigure(1, weight=1)
|
||||||
|
|
||||||
# Función para ejecutar las funciones run() y redirigir la salida
|
current_row = 2
|
||||||
def ejecutar_run(funcion_run):
|
self.paso1.grid(row=current_row, column=0, pady=5, padx=5, sticky='ew')
|
||||||
# Obtener los parámetros necesarios
|
self.master_name_button.grid(row=current_row, column=1, pady=5, padx=5, sticky='ew')
|
||||||
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())
|
|
||||||
|
|
||||||
# Obtener los índices de los idiomas
|
current_row += 1
|
||||||
indice_seleccionado = idiomas_lista.index((idioma_var.get(), codigo_idioma))
|
self.paso2.grid(row=current_row, column=0, pady=5, padx=5, sticky='ew')
|
||||||
indice_seleccionado2 = idiomas_lista.index((idioma_var2.get(), codigo_idioma2))
|
self.translate_name_button.grid(row=current_row, column=1, pady=5, padx=5, sticky='ew')
|
||||||
|
|
||||||
# Redirigir stdout
|
current_row += 1
|
||||||
original_stdout = sys.stdout
|
self.paso3.grid(row=current_row, column=0, pady=5, padx=5, sticky='ew')
|
||||||
sys.stdout = RedirectText(output_text)
|
self.auto_translate_name_button.grid(row=current_row, column=1, pady=5, padx=5, sticky='ew')
|
||||||
|
|
||||||
try:
|
current_row += 1
|
||||||
# Ejecutar la función correspondiente
|
self.paso4.grid(row=current_row, column=0, pady=5, padx=5, sticky='ew')
|
||||||
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
|
|
||||||
|
|
||||||
# Crear los botones con el mismo ancho
|
current_row += 1
|
||||||
button_width = 70
|
self.paso4B.grid(row=current_row, column=0, pady=5, padx=5, sticky='ew')
|
||||||
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)
|
|
||||||
|
|
||||||
boton_abrir_directorio = tk.Button(ventana, text="Abrir directorio del archivo maestro", command=open_master_directory, width=button_width)
|
current_row += 1
|
||||||
boton_abrir_log = tk.Button(ventana, text="Abrir archivo de log", command=open_log_file, width=button_width)
|
self.paso5.grid(row=current_row, column=0, columnspan=2, pady=5, padx=5, sticky='ew')
|
||||||
|
|
||||||
# Ubicar los botones en la ventana
|
current_row += 1
|
||||||
paso1.pack(pady=(10,2))
|
self.paso6.grid(row=current_row, column=0, columnspan=2, pady=5, padx=5, sticky='ew')
|
||||||
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)
|
|
||||||
|
|
||||||
# Place the new buttons in the window
|
current_row += 1
|
||||||
boton_abrir_directorio.pack(pady=2)
|
self.output_text.grid(row=current_row, column=0, columnspan=2, padx=(10, 0), pady=10, sticky='nsew')
|
||||||
boton_abrir_log.pack(pady=2)
|
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')
|
||||||
|
|
||||||
# Crear un Frame para el cuadro de texto, los scrollbars y el botón
|
current_row += 2
|
||||||
frame_texto = tk.Frame(ventana)
|
self.clear_button.grid(row=current_row, column=0, pady=10, padx=5, sticky='e')
|
||||||
frame_texto.pack(fill='both', expand=True, pady=10)
|
self.open_log_button.grid(row=current_row, column=1, pady=10, padx=5, sticky='w')
|
||||||
|
|
||||||
# Crear los scrollbars
|
self.main_frame.grid_rowconfigure(current_row-2, weight=1)
|
||||||
scrollbar_vertical = tk.Scrollbar(frame_texto, orient='vertical')
|
|
||||||
scrollbar_horizontal = tk.Scrollbar(frame_texto, orient='horizontal')
|
|
||||||
|
|
||||||
# Crear la caja de texto para mostrar la salida
|
def set_combo_value(self, combo, codigo):
|
||||||
output_text = tk.Text(
|
for nombre, code in fc.IDIOMAS.values():
|
||||||
frame_texto,
|
if code == codigo:
|
||||||
wrap='none',
|
combo.set(nombre)
|
||||||
yscrollcommand=scrollbar_vertical.set,
|
return
|
||||||
xscrollcommand=scrollbar_horizontal.set
|
for nombre, code in fc.PLCs.values():
|
||||||
)
|
if code == codigo:
|
||||||
|
combo.set(nombre)
|
||||||
|
return
|
||||||
|
|
||||||
# Configurar los scrollbars
|
def update_tipo_PLC(self, event):
|
||||||
scrollbar_vertical.config(command=output_text.yview)
|
nombre_seleccionado = self.combo_tipo_PLC.get()
|
||||||
scrollbar_horizontal.config(command=output_text.xview)
|
for nombre, codigo in fc.PLCs.values():
|
||||||
|
if nombre == nombre_seleccionado:
|
||||||
|
self.codigo_tipo_PLC_var.set(codigo)
|
||||||
|
break
|
||||||
|
self.update_file_names()
|
||||||
|
|
||||||
# Crear el botón para borrar el contenido
|
def update_codigo_maestra(self, event):
|
||||||
boton_limpiar = tk.Button(frame_texto, text="Borrar contenido", command=lambda: limpiar_texto())
|
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()
|
||||||
|
|
||||||
# Ubicar los widgets en frame_texto usando grid
|
def update_idioma(self, event):
|
||||||
output_text.grid(row=0, column=0, sticky='nsew')
|
nombre_seleccionado = self.combo.get()
|
||||||
scrollbar_vertical.grid(row=0, column=1, sticky='ns')
|
for nombre, codigo in fc.IDIOMAS.values():
|
||||||
scrollbar_horizontal.grid(row=1, column=0, sticky='ew')
|
if nombre == nombre_seleccionado:
|
||||||
boton_limpiar.grid(row=1, column=1, padx=5, pady=5)
|
self.codigo_idioma_var.set(codigo)
|
||||||
|
break
|
||||||
|
self.update_file_names()
|
||||||
|
|
||||||
# Configurar la expansión de filas y columnas
|
def update_idioma2(self, event):
|
||||||
frame_texto.grid_rowconfigure(0, weight=1)
|
nombre_seleccionado = self.combo2.get()
|
||||||
frame_texto.grid_columnconfigure(0, weight=1)
|
for nombre, codigo in fc.IDIOMAS.values():
|
||||||
|
if nombre == nombre_seleccionado:
|
||||||
|
self.codigo_idioma_var2.set(codigo)
|
||||||
|
break
|
||||||
|
self.update_file_names()
|
||||||
|
|
||||||
# Función para borrar el contenido del cuadro de texto
|
def save_config(self):
|
||||||
def limpiar_texto():
|
self.config.update(
|
||||||
output_text.delete('1.0', tk.END)
|
codigo_tipo_PLC=self.codigo_tipo_PLC_var.get(),
|
||||||
guardar_configuracion()
|
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()
|
||||||
|
|
||||||
# Cargar las opciones guardadas al iniciar
|
def select_work_dir(self):
|
||||||
cargar_configuracion()
|
dir_path = filedialog.askdirectory()
|
||||||
|
if dir_path:
|
||||||
|
self.work_dir_var.set(dir_path)
|
||||||
|
self.save_config()
|
||||||
|
self.update_file_names()
|
||||||
|
|
||||||
# Cargar el contenido del cuadro de texto desde la configuración
|
def open_file(self, file_path):
|
||||||
def cargar_texto():
|
if os.path.exists(file_path):
|
||||||
config = configparser.ConfigParser()
|
os.startfile(file_path)
|
||||||
if os.path.exists(config_file):
|
else:
|
||||||
config.read(config_file)
|
messagebox.showerror("Error", f"El archivo {file_path} no existe.")
|
||||||
texto = config.get('TextContent', 'output_text', fallback='')
|
|
||||||
output_text.insert('1.0', texto)
|
|
||||||
|
|
||||||
cargar_texto()
|
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.")
|
||||||
|
|
||||||
# Guardar la configuración al cerrar la ventana
|
def open_log_file(self):
|
||||||
def on_closing():
|
log_file_path = os.path.join(self.config.work_dir, "logs", "translate_log.log")
|
||||||
guardar_configuracion()
|
if os.path.exists(log_file_path):
|
||||||
ventana.destroy()
|
os.startfile(log_file_path)
|
||||||
|
else:
|
||||||
|
messagebox.showerror("Error", f"El archivo de log {log_file_path} no existe.")
|
||||||
|
|
||||||
ventana.protocol("WM_DELETE_WINDOW", on_closing)
|
def update_file_names(self, event=None):
|
||||||
|
codigo_tipo_PLC = self.codigo_tipo_PLC_var.get()
|
||||||
|
codigo_idioma_seleccionado = self.codigo_idioma_var.get()
|
||||||
|
|
||||||
# Iniciar el bucle principal de la interfaz
|
self.master_name_var.set(f"1_hmi_master_translates_{codigo_tipo_PLC}.xlsx")
|
||||||
ventana.mainloop()
|
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()
|
||||||
|
|
||||||
|
def ejecutar_run(self, funcion_run):
|
||||||
|
self.save_config()
|
||||||
|
|
||||||
|
original_stdout = sys.stdout
|
||||||
|
sys.stdout = self.RedirectText(self.output_text)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
class RedirectText:
|
||||||
|
def __init__(self, text_widget):
|
||||||
|
self.text_widget = text_widget
|
||||||
|
|
||||||
|
def write(self, string):
|
||||||
|
self.text_widget.insert(tk.END, string)
|
||||||
|
self.text_widget.see(tk.END)
|
||||||
|
|
||||||
|
def flush(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def main():
|
||||||
|
root = tk.Tk()
|
||||||
|
app = TranslationApp(root)
|
||||||
|
root.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,29 +3,39 @@ import os
|
||||||
import re
|
import re
|
||||||
import logging
|
import logging
|
||||||
import PyLibrary.funciones_comunes as fc
|
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 = []
|
filas_validas = []
|
||||||
|
|
||||||
for index, fila in df_importacion.iterrows():
|
for index, fila in df_importacion.iterrows():
|
||||||
clave_original = fila[codigo_columna_maestra]
|
clave_original = fila[codigo_columna_maestra]
|
||||||
|
|
||||||
# Verificar si la celda de la columna maestra está vacía o solo contiene espacios en blanco
|
# 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() == '':
|
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")
|
logger.info(
|
||||||
|
f"Fila {index}: Ignorada - Celda de columna maestra vacía o solo con espacios en blanco"
|
||||||
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Aplicar unescape solo a las filas con valor no vacío en la columna maestra
|
|
||||||
nueva_fila = fila.copy()
|
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
|
nueva_fila[codigo_columna_maestra] = clave_sustituida
|
||||||
|
|
||||||
for columna in df_importacion.columns:
|
for columna in df_importacion.columns:
|
||||||
if columna != codigo_columna_maestra and fc.es_columna_tipo_xxYY(columna):
|
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)
|
filas_validas.append(nueva_fila)
|
||||||
|
|
||||||
|
@ -34,30 +44,40 @@ def preprocesar_importacion(tipo_PLC, codigo_columna_maestra, df_importacion, lo
|
||||||
df_valido = pd.DataFrame(filas_validas, columns=df_importacion.columns)
|
df_valido = pd.DataFrame(filas_validas, columns=df_importacion.columns)
|
||||||
return df_valido
|
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(" .... ")
|
||||||
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):
|
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:
|
else:
|
||||||
df_maestro = fc.read_dataframe_with_cleanup_retries(archivo_maestro)
|
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 = []
|
filas_a_agregar = []
|
||||||
|
|
||||||
for index, fila in df_importacion.iterrows():
|
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:
|
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
|
continue
|
||||||
|
|
||||||
claves_maestro.add(clave)
|
claves_maestro.add(clave)
|
||||||
|
@ -65,7 +85,7 @@ def importar(tipo_PLC, codigo_columna_maestra, archivo_maestro, archivo_importac
|
||||||
fila_filtrada = {
|
fila_filtrada = {
|
||||||
col: fila[col]
|
col: fila[col]
|
||||||
for col in fila.index
|
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)
|
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_nuevas_filas = pd.DataFrame(filas_a_agregar)
|
||||||
df_maestro = pd.concat([df_maestro, df_nuevas_filas], ignore_index=True)
|
df_maestro = pd.concat([df_maestro, df_nuevas_filas], ignore_index=True)
|
||||||
|
|
||||||
df_maestro.to_excel(archivo_maestro, index=False)
|
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.")
|
logger.info(
|
||||||
print(f"Se han agregado {len(filas_a_agregar)} nuevas filas válidas al archivo maestro.")
|
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__":
|
if __name__ == "__main__":
|
||||||
tipo_PLC = "siemens"
|
print(
|
||||||
codigo_columna_maestra = "it-IT"
|
"Este script debe ser ejecutado desde el menú principal (menu_pasos_traduccion.py)."
|
||||||
run(tipo_PLC, codigo_columna_maestra)
|
)
|
||||||
|
print(
|
||||||
|
"Por favor, ejecute menu_pasos_traduccion.py para utilizar esta funcionalidad."
|
||||||
|
)
|
||||||
|
|
|
@ -1,15 +1,20 @@
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import os
|
import os
|
||||||
import PyLibrary.funciones_comunes as fc
|
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):
|
def exportar_para_traduccion(config: TranslationConfig):
|
||||||
if not os.path.exists(archivo_maestro):
|
master_path = config.get_master_path()
|
||||||
|
if not os.path.exists(master_path):
|
||||||
print("El archivo maestro no existe.")
|
print("El archivo maestro no existe.")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Leer el archivo maestro
|
# 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
|
# Crear un nuevo DataFrame para la exportación
|
||||||
df_export = pd.DataFrame()
|
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
|
# Copiar la primera columna y la columna del idioma de destino
|
||||||
primera_columna = df_maestro.columns[0]
|
primera_columna = df_maestro.columns[0]
|
||||||
df_export[primera_columna] = df_maestro[primera_columna]
|
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
|
# 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
|
# Usar ExcelWriter para tener más control sobre el proceso de escritura
|
||||||
with pd.ExcelWriter(ruta_export, engine='openpyxl') as writer:
|
with pd.ExcelWriter(ruta_export, engine="openpyxl") as writer:
|
||||||
df_export.to_excel(writer, index=False, sheet_name='Sheet1')
|
df_export.to_excel(writer, index=False, sheet_name="Sheet1")
|
||||||
|
|
||||||
# Ajustar el ancho de las columnas
|
# Ajustar el ancho de las columnas
|
||||||
worksheet = writer.sheets['Sheet1']
|
worksheet = writer.sheets["Sheet1"]
|
||||||
for idx, col in enumerate(df_export.columns):
|
for idx, col in enumerate(df_export.columns):
|
||||||
max_length = max(df_export[col].astype(str).map(len).max(), len(col))
|
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
|
worksheet.column_dimensions[chr(65 + idx)].width = max_length + 2
|
||||||
|
|
||||||
print(f"Archivo exportado para traducción: {ruta_export}")
|
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"
|
def run(config: TranslationConfig):
|
||||||
if seleccion_idioma not in fc.IDIOMAS:
|
global logger
|
||||||
print("Selección inválida.")
|
logger = fc.configurar_logger(config.work_dir)
|
||||||
else:
|
exportar_para_traduccion(config)
|
||||||
_, target_lang_code = fc.IDIOMAS[seleccion_idioma]
|
|
||||||
exportar_para_traduccion(tipo_PLC, archivo_maestro, target_lang_code)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
tipo_PLC = "siemens"
|
import menu_pasos_traduccion
|
||||||
codigo_columna_maestra = "it-IT"
|
|
||||||
fc.mostrar_idiomas()
|
menu_pasos_traduccion.main()
|
||||||
seleccion_idioma = int(input("Introduce el número del idioma de destino: "))
|
|
||||||
run(tipo_PLC, codigo_columna_maestra, seleccion_idioma)
|
|
||||||
|
|
|
@ -12,10 +12,17 @@ import html
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
import PyLibrary.funciones_comunes as fc
|
import PyLibrary.funciones_comunes as fc
|
||||||
import time
|
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())
|
openai_client = OpenAI(api_key=openai_api_key())
|
||||||
GOOGLE_APPLICATION_CREDENTIALS = "translate-431108-020c17463fbb.json"
|
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():
|
def init_google_translate_client():
|
||||||
|
@ -30,8 +37,10 @@ def init_google_translate_client():
|
||||||
"No se han proporcionado credenciales válidas para Google Translate"
|
"No se han proporcionado credenciales válidas para Google Translate"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
google_translate_client = init_google_translate_client()
|
google_translate_client = init_google_translate_client()
|
||||||
|
|
||||||
|
|
||||||
def google_translate(text, target_language):
|
def google_translate(text, target_language):
|
||||||
result = google_translate_client.translate(text, target_language=target_language)
|
result = google_translate_client.translate(text, target_language=target_language)
|
||||||
translated_text = result["translatedText"]
|
translated_text = result["translatedText"]
|
||||||
|
@ -187,27 +196,26 @@ def calcular_afinidad(tipo_PLC, texto1, texto2):
|
||||||
try:
|
try:
|
||||||
score = float(cleaned_response_content)
|
score = float(cleaned_response_content)
|
||||||
except ValueError:
|
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
|
return score
|
||||||
|
|
||||||
|
|
||||||
def main(tipo_PLC, codigo_columna_maestra, file_path, target_lang_code, target_lang, traducir_todo, batch_size=10):
|
def main(config: TranslationConfig):
|
||||||
df = fc.read_dataframe_with_cleanup_retries(file_path)
|
df = fc.read_dataframe_with_cleanup_retries(config.get_translate_path())
|
||||||
|
|
||||||
source_col = codigo_columna_maestra
|
source_col = config.codigo_columna_maestra
|
||||||
source_translated_col = target_lang_code
|
source_translated_col = config.codigo_idioma_seleccionado
|
||||||
target_col = f"{target_lang_code} Translated"
|
target_col = f"{config.codigo_idioma_seleccionado} Translated"
|
||||||
check_translate_col = f"{target_lang_code} CheckTranslate"
|
check_translate_col = f"{config.codigo_idioma_seleccionado} CheckTranslate"
|
||||||
affinity_col = f"{target_lang_code} Affinity"
|
affinity_col = f"{config.codigo_idioma_seleccionado} Affinity"
|
||||||
|
|
||||||
# Asegurarse de que la columna de destino existe
|
# Asegurarse de que la columna de destino existe
|
||||||
if target_col not in df.columns:
|
for col in [target_col, check_translate_col, affinity_col]:
|
||||||
df[target_col] = None
|
if col not in df.columns:
|
||||||
if check_translate_col not in df.columns:
|
df[col] = None
|
||||||
df[check_translate_col] = None
|
|
||||||
if affinity_col not in df.columns:
|
|
||||||
df[affinity_col] = None
|
|
||||||
|
|
||||||
texts_to_translate = {}
|
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
|
if source_translated_col in df.columns
|
||||||
else ""
|
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 config.traducir_todo:
|
||||||
if fc.texto_requiere_traduccion(tipo_PLC, celda_clave_compactada, logger):
|
if fc.texto_requiere_traduccion(
|
||||||
df.at[index, source_translated_col] = '' # Necesita ser traducida.
|
config.codigo_tipo_PLC, celda_clave_compactada, logger
|
||||||
|
):
|
||||||
|
df.at[index, source_translated_col] = ""
|
||||||
texts_to_translate[celda_clave] = celda_clave_compactada
|
texts_to_translate[celda_clave] = celda_clave_compactada
|
||||||
else:
|
else:
|
||||||
if (
|
if (
|
||||||
pd.isna(row[source_translated_col])
|
pd.isna(row[source_translated_col])
|
||||||
or source_translated_text.strip() == ""
|
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
|
texts_to_translate[celda_clave] = celda_clave_compactada
|
||||||
|
|
||||||
num_texts = len(texts_to_translate)
|
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):
|
for attempt in range(retries):
|
||||||
try:
|
try:
|
||||||
batch_translations = translate_batch_openai(
|
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)
|
translations.update(batch_translations)
|
||||||
break # Si la traducción es exitosa, salimos del bucle de reintentos
|
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]
|
df.at[index, target_col] = translations[celda_clave]
|
||||||
# Realizar la traducción de verificación con Google Translate
|
# Realizar la traducción de verificación con Google Translate
|
||||||
try:
|
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
|
df.at[index, check_translate_col] = google_translation
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(
|
logger.error(
|
||||||
|
@ -296,7 +317,7 @@ def main(tipo_PLC, codigo_columna_maestra, file_path, target_lang_code, target_l
|
||||||
# Afinidades
|
# Afinidades
|
||||||
# Se calculan las Afinidades
|
# Se calculan las Afinidades
|
||||||
affinities = {}
|
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)
|
end_idx = min(start_idx + batch_size, num_texts)
|
||||||
batch_texts = dict(list(texts_to_translate.items())[start_idx:end_idx])
|
batch_texts = dict(list(texts_to_translate.items())[start_idx:end_idx])
|
||||||
logger.info(f"Afinidad: celdas desde {start_idx} a {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}"
|
f"Error en el cálculo individual de Afinidad para el texto '{key}': {ind_e}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# Actualizar el DataFrame con las Afinidades
|
# Actualizar el DataFrame con las Afinidades
|
||||||
for index, row in df.iterrows():
|
for index, row in df.iterrows():
|
||||||
celda_clave = str(row[source_col])
|
celda_clave = str(row[source_col])
|
||||||
if celda_clave in affinities:
|
if celda_clave in affinities:
|
||||||
df.at[index, affinity_col] = affinities[celda_clave]
|
df.at[index, affinity_col] = affinities[celda_clave]
|
||||||
|
|
||||||
output_path = os.path.join(
|
output_path = config.get_auto_translate_path()
|
||||||
os.path.dirname(file_path), f"3_master_export2translate_translated_{tipo_PLC}.xlsx"
|
|
||||||
)
|
|
||||||
fc.save_dataframe_with_retries(df, output_path=output_path)
|
fc.save_dataframe_with_retries(df, output_path=output_path)
|
||||||
logger.info(f"Archivo traducido guardado en: {output_path}")
|
logger.info(f"Archivo traducido guardado en: {output_path}")
|
||||||
print(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:
|
def run(config: TranslationConfig):
|
||||||
print("Selección inválida.")
|
global logger
|
||||||
else:
|
logger = fc.configurar_logger(config.work_dir)
|
||||||
target_lang, target_lang_code = fc.IDIOMAS[seleccion_idioma]
|
main(config)
|
||||||
main(tipo_PLC, codigo_columna_maestra, translate_file, target_lang_code, target_lang, traducir_todo, batch_size)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
tipo_PLC = "siemens"
|
import menu_pasos_traduccion
|
||||||
codigo_columna_maestra = "it-IT"
|
|
||||||
fc.mostrar_idiomas()
|
menu_pasos_traduccion.main()
|
||||||
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)
|
|
||||||
|
|
|
@ -1,73 +1,85 @@
|
||||||
import PyLibrary.funciones_comunes as fc
|
import PyLibrary.funciones_comunes as fc
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import os
|
import os
|
||||||
import logging
|
from translation_config import TranslationConfig
|
||||||
from openpyxl import load_workbook
|
from openpyxl import load_workbook
|
||||||
from openpyxl.styles import Font
|
from openpyxl.styles import Font
|
||||||
from openpyxl.comments import Comment
|
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):
|
if not os.path.exists(archivo_maestro):
|
||||||
print("El archivo maestro no existe.")
|
print("El archivo maestro no existe.")
|
||||||
return
|
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_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(archivo_traduccion)
|
||||||
|
|
||||||
# Configurar el logger
|
|
||||||
logger = fc.configurar_logger()
|
|
||||||
|
|
||||||
# Crear un diccionario para almacenar las celdas modificadas en el maestro
|
|
||||||
celdas_modificadas = {}
|
celdas_modificadas = {}
|
||||||
# Crear un diccionario para almacenar las celdas con errores en el archivo fuente
|
|
||||||
celdas_con_errores = {}
|
celdas_con_errores = {}
|
||||||
|
|
||||||
# Iterar sobre las filas del archivo de traducción para actualizar el maestro
|
|
||||||
for index, fila in df_traduccion.iterrows():
|
for index, fila in df_traduccion.iterrows():
|
||||||
clave = fila[df_maestro.columns[0]]
|
clave = fila[df_maestro.columns[0]]
|
||||||
if clave in df_maestro[df_maestro.columns[0]].values:
|
if clave in df_maestro[df_maestro.columns[0]].values:
|
||||||
valor_traducido = fila[target_lang_code]
|
valor_traducido = fila[master_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 pd.notnull(valor_traducido) and valor_traducido != "" and str(valor_original) != str(valor_traducido):
|
if (
|
||||||
# Verificar si la traducción es válida
|
pd.notnull(valor_traducido)
|
||||||
okToSave, Error = fc.verificar_celda_traducida(tipo_PLC, clave, 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:
|
if okToSave:
|
||||||
df_maestro.loc[df_maestro[df_maestro.columns[0]] == clave, master_col] = valor_traducido
|
df_maestro.loc[
|
||||||
logger.info(f'Fila {index}, Columna {master_col}: "{valor_original}" actualizado a "{valor_traducido}"')
|
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 = (
|
||||||
fila_excel = df_maestro.index[df_maestro[df_maestro.columns[0]] == clave].tolist()[0] + 2 # +2 porque Excel empieza en 1 y tiene encabezados
|
df_maestro.index[
|
||||||
columna_excel = df_maestro.columns.get_loc(master_col) + 1 # +1 porque Excel empieza en 1
|
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
|
celdas_modificadas[(fila_excel, columna_excel)] = valor_traducido
|
||||||
else:
|
else:
|
||||||
logger.error(f'Fila {index}, Columna {master_col}: No actualizado porque: {Error}')
|
logger.error(
|
||||||
# Almacenar la posición de la celda con error en el archivo fuente
|
f"Fila {index}, Columna {master_col}: No actualizado porque: {Error}"
|
||||||
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
|
fila_excel = index + 2
|
||||||
|
columna_excel = df_traduccion.columns.get_loc(master_col) + 1
|
||||||
celdas_con_errores[(fila_excel, columna_excel)] = Error
|
celdas_con_errores[(fila_excel, columna_excel)] = Error
|
||||||
|
|
||||||
# Guardar el archivo maestro actualizado
|
|
||||||
fc.save_dataframe_with_retries(df_maestro, output_path=archivo_maestro)
|
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)
|
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)
|
marcar_errores_archivo_fuente(archivo_traduccion, celdas_con_errores)
|
||||||
|
|
||||||
print(f"Traducciones manuales importadas y archivo maestro actualizado: {archivo_maestro}.")
|
print(
|
||||||
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.")
|
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):
|
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)
|
workbook = load_workbook(archivo)
|
||||||
sheet = workbook.active
|
sheet = workbook.active
|
||||||
|
|
||||||
|
@ -77,15 +89,12 @@ def aplicar_formato_celdas_maestro(archivo, celdas_modificadas):
|
||||||
celda.value = valor
|
celda.value = valor
|
||||||
|
|
||||||
workbook.save(archivo)
|
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):
|
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)
|
workbook = load_workbook(archivo)
|
||||||
sheet = workbook.active
|
sheet = workbook.active
|
||||||
|
|
||||||
|
@ -96,21 +105,18 @@ def marcar_errores_archivo_fuente(archivo, celdas_con_errores):
|
||||||
celda.comment = comment
|
celda.comment = comment
|
||||||
|
|
||||||
workbook.save(archivo)
|
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:
|
def run(config: TranslationConfig):
|
||||||
print("Selección inválida.")
|
global logger
|
||||||
else:
|
logger = fc.configurar_logger(config.work_dir)
|
||||||
_, target_lang_code = fc.IDIOMAS[seleccion_idioma]
|
importar_traduccion_manual(config)
|
||||||
importar_traduccion_manual(tipo_PLC, archivo_maestro, archivo_traduccion, target_lang_code)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
tipo_PLC = "siemens"
|
import menu_pasos_traduccion
|
||||||
codigo_columna_maestra = "it-IT"
|
|
||||||
fc.mostrar_idiomas()
|
menu_pasos_traduccion.main()
|
||||||
seleccion_idioma = int(input("Introduce el número del idioma de destino: "))
|
|
||||||
run(tipo_PLC, codigo_columna_maestra, seleccion_idioma)
|
|
||||||
|
|
|
@ -1,89 +1,90 @@
|
||||||
import PyLibrary.funciones_comunes as fc
|
import PyLibrary.funciones_comunes as fc
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import os
|
import os
|
||||||
import re
|
from translation_config import TranslationConfig
|
||||||
import logging
|
|
||||||
from openpyxl import load_workbook
|
from openpyxl import load_workbook
|
||||||
from openpyxl.styles import Font
|
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):
|
if not os.path.exists(archivo_maestro):
|
||||||
print("El archivo maestro no existe.")
|
print("El archivo maestro no existe.")
|
||||||
return
|
return
|
||||||
|
|
||||||
master_col = target_lang_code
|
master_col = config.codigo_idioma_seleccionado
|
||||||
translated_col = f"{target_lang_code} Translated"
|
translated_col = f"{config.codigo_idioma_seleccionado} Translated"
|
||||||
affinity_col = f"{target_lang_code} Affinity"
|
affinity_col = f"{config.codigo_idioma_seleccionado} Affinity"
|
||||||
|
|
||||||
df_maestro = fc.read_dataframe_with_cleanup_retries(archivo_maestro)
|
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 = {}
|
celdas_modificadas = {}
|
||||||
|
|
||||||
# Iterar sobre las filas del archivo de traducción para actualizar el maestro
|
|
||||||
for index, fila in df_traduccion.iterrows():
|
for index, fila in df_traduccion.iterrows():
|
||||||
clave = fila[df_maestro.columns[0]]
|
clave = fila[df_maestro.columns[0]]
|
||||||
if clave in df_maestro[df_maestro.columns[0]].values:
|
if clave in df_maestro[df_maestro.columns[0]].values:
|
||||||
# Comprobar afinidad y valores no nulos/vacíos
|
if (
|
||||||
if fila[affinity_col] >= nivel_afinidad_minimo and pd.notnull(fila[translated_col]) and fila[translated_col] != "":
|
fila[affinity_col] >= config.nivel_afinidad_minimo
|
||||||
|
and pd.notnull(fila[translated_col])
|
||||||
|
and fila[translated_col] != ""
|
||||||
|
):
|
||||||
valor_traducido = 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):
|
if str(valor_original) != str(valor_traducido):
|
||||||
df_maestro.loc[df_maestro[df_maestro.columns[0]] == clave, master_col] = valor_traducido
|
df_maestro.loc[
|
||||||
logger.info(f'Fila {index}, Columna {translated_col}: "{valor_original}" actualizado a "{valor_traducido}"')
|
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 = (
|
||||||
fila_excel = df_maestro.index[df_maestro[df_maestro.columns[0]] == clave].tolist()[0] + 2 # +2 porque Excel empieza en 1 y tiene encabezados
|
df_maestro.index[
|
||||||
columna_excel = df_maestro.columns.get_loc(master_col) + 1 # +1 porque Excel empieza en 1
|
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
|
celdas_modificadas[(fila_excel, columna_excel)] = valor_traducido
|
||||||
|
|
||||||
# Guardar el archivo maestro actualizado
|
|
||||||
fc.save_dataframe_with_retries(df_maestro, output_path=archivo_maestro)
|
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)
|
aplicar_negrita_celdas_modificadas(archivo_maestro, celdas_modificadas)
|
||||||
|
|
||||||
print(f"Traducciones importadas y archivo maestro actualizado: {archivo_maestro}.")
|
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.
|
def aplicar_negrita_celdas_modificadas(archivo, celdas_modificadas):
|
||||||
:param celdas_modificadas: Diccionario con las celdas a modificar {(fila, columna): valor}.
|
|
||||||
"""
|
|
||||||
workbook = load_workbook(archivo)
|
workbook = load_workbook(archivo)
|
||||||
sheet = workbook.active
|
sheet = workbook.active
|
||||||
|
|
||||||
for (fila, columna), valor in celdas_modificadas.items():
|
for (fila, columna), valor in celdas_modificadas.items():
|
||||||
celda = sheet.cell(row=fila, column=columna)
|
celda = sheet.cell(row=fila, column=columna)
|
||||||
celda.font = Font(bold=True)
|
celda.font = Font(bold=True)
|
||||||
celda.value = valor # Asegurarse de que el valor es el correcto
|
celda.value = valor
|
||||||
|
|
||||||
workbook.save(archivo)
|
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:
|
def run(config: TranslationConfig):
|
||||||
print("Selección inválida.")
|
global logger
|
||||||
else:
|
logger = fc.configurar_logger(config.work_dir)
|
||||||
target_lang, target_lang_code = fc.IDIOMAS[seleccion_idioma]
|
importar_traduccion(config)
|
||||||
importar_traduccion(tipo_PLC, archivo_maestro, archivo_traduccion, target_lang_code, nivel_afinidad_minimo)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
tipo_PLC = "siemens"
|
import menu_pasos_traduccion
|
||||||
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
|
|
||||||
|
|
||||||
fc.mostrar_idiomas()
|
menu_pasos_traduccion.main()
|
||||||
seleccion_idioma = int(input("Introduce el número del idioma de destino: "))
|
|
||||||
run(tipo_PLC, codigo_columna_maestra, seleccion_idioma, nivel_afinidad_minimo)
|
|
||||||
|
|
|
@ -1,80 +1,54 @@
|
||||||
import PyLibrary.funciones_comunes as fc
|
import PyLibrary.funciones_comunes as fc
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import os
|
import os
|
||||||
import re
|
from translation_config import TranslationConfig
|
||||||
import logging
|
|
||||||
from openpyxl.utils.escape import unescape
|
|
||||||
|
|
||||||
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):
|
if not os.path.exists(archivo_maestro):
|
||||||
print("El archivo maestro no existe.")
|
print("El archivo maestro no existe.")
|
||||||
return
|
return
|
||||||
|
|
||||||
target_col = target_lang_code
|
target_col = config.codigo_idioma_seleccionado
|
||||||
second_col = second_lang_code
|
second_col = config.codigo_idioma_secundario
|
||||||
|
|
||||||
df_maestro = fc.read_dataframe_with_cleanup_retries(archivo_maestro)
|
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():
|
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 fila[target_col] == "" or pd.isnull(fila[target_col]):
|
||||||
if pd.notnull(fila[second_col]) and fila[second_col] != "":
|
if pd.notnull(fila[second_col]) and fila[second_col] != "":
|
||||||
df_maestro.loc[
|
df_maestro.loc[
|
||||||
df_maestro[codigo_columna_maestra] == clave, target_col
|
df_maestro[config.codigo_columna_maestra] == clave, target_col
|
||||||
] = fila[second_col]
|
] = fila[second_col]
|
||||||
logger.info(
|
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:
|
else:
|
||||||
df_maestro.loc[
|
df_maestro.loc[
|
||||||
df_maestro[codigo_columna_maestra] == clave, target_col
|
df_maestro[config.codigo_columna_maestra] == clave, target_col
|
||||||
] = fc.compactar_celda_traducida(tipo_PLC, fila[codigo_columna_maestra])
|
] = fc.compactar_celda_traducida(
|
||||||
|
config.codigo_tipo_PLC, fila[config.codigo_columna_maestra]
|
||||||
|
)
|
||||||
logger.info(
|
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)
|
||||||
fc.save_dataframe_with_retries(
|
print(f"Traducciones importadas y archivo maestro actualizado: {archivo_maestro}.")
|
||||||
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:
|
def run(config: TranslationConfig):
|
||||||
print("Selección inválida.")
|
global logger
|
||||||
exit
|
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__":
|
if __name__ == "__main__":
|
||||||
tipo_PLC = "siemens"
|
import menu_pasos_traduccion
|
||||||
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)
|
|
||||||
|
|
||||||
|
menu_pasos_traduccion.main()
|
||||||
|
|
|
@ -1,77 +1,77 @@
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import os
|
import os
|
||||||
import re
|
|
||||||
import logging
|
|
||||||
import PyLibrary.funciones_comunes as fc
|
import PyLibrary.funciones_comunes as fc
|
||||||
from openpyxl.utils.escape import unescape
|
from translation_config import TranslationConfig
|
||||||
from openpyxl import load_workbook
|
from openpyxl import load_workbook
|
||||||
from openpyxl.styles import Font
|
from openpyxl.styles import Font
|
||||||
from openpyxl.comments import Comment
|
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):
|
if not os.path.exists(archivo_maestro):
|
||||||
print("El archivo maestro no existe.")
|
print("El archivo maestro no existe.")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Configurar el logger
|
|
||||||
logger = fc.configurar_logger()
|
|
||||||
|
|
||||||
logger.info(" .... ")
|
logger.info(" .... ")
|
||||||
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_maestro = fc.read_dataframe_with_cleanup_retries(archivo_maestro)
|
||||||
df_to_update = fc.read_dataframe_with_cleanup_retries(archivo_to_update)
|
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 = {}
|
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]
|
valor_original = fila[col_clave]
|
||||||
clave = fc.compactar_celda_clave(tipo_PLC, valor_original)
|
clave = fc.compactar_celda_clave(config.codigo_tipo_PLC, valor_original)
|
||||||
logger.info(
|
logger.info(f"Fila {index} : Clave: {clave}")
|
||||||
f'Fila {index} : Clave: {clave}'
|
|
||||||
)
|
|
||||||
|
|
||||||
if not pd.isnull(clave) and clave in df_maestro[col_clave].values:
|
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()[
|
||||||
indice_maestro = df_maestro.index[df_maestro[col_clave] == clave].tolist()[0]
|
0
|
||||||
valor_traducido_compacto = df_maestro.loc[indice_maestro, target_lang_code]
|
]
|
||||||
|
valor_traducido_compacto = df_maestro.loc[
|
||||||
|
indice_maestro, config.codigo_idioma_seleccionado
|
||||||
|
]
|
||||||
|
|
||||||
# Descompactamos
|
valor_traducido = fc.decompactar_celda_traducida(
|
||||||
valor_traducido = fc.decompactar_celda_traducida(tipo_PLC,
|
config.codigo_tipo_PLC,
|
||||||
celda_original=valor_original, celda_traducida=valor_traducido_compacto
|
celda_original=valor_original,
|
||||||
|
celda_traducida=valor_traducido_compacto,
|
||||||
)
|
)
|
||||||
if (
|
if (
|
||||||
not pd.isnull(valor_traducido)
|
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(
|
||||||
okToSave, Error = fc.verificar_celda_traducida(tipo_PLC,
|
config.codigo_tipo_PLC, clave, valor_traducido_compacto
|
||||||
clave, valor_traducido_compacto
|
|
||||||
)
|
)
|
||||||
if okToSave:
|
if okToSave:
|
||||||
logger.info("Actualizado.")
|
logger.info("Actualizado.")
|
||||||
df_to_update.at[index, target_lang_code] = valor_traducido
|
df_to_update.at[index, config.codigo_idioma_seleccionado] = (
|
||||||
else:
|
valor_traducido
|
||||||
df_to_update.at[index, target_lang_code] = valor_original
|
|
||||||
logger.error(
|
|
||||||
f'No actualizado porque: {Error}'
|
|
||||||
)
|
)
|
||||||
# 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
|
celdas_con_errores[indice_maestro] = Error
|
||||||
|
|
||||||
# Guardar el archivo actualizado
|
|
||||||
nombre, extension = os.path.splitext(archivo_to_update)
|
nombre, extension = os.path.splitext(archivo_to_update)
|
||||||
nuevo_nombre = f"{nombre}_import{extension}"
|
nuevo_nombre = f"{nombre}_import{extension}"
|
||||||
fc.save_dataframe_with_retries(df_to_update, output_path=nuevo_nombre)
|
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(
|
||||||
marcar_celdas_con_errores(archivo_maestro, celdas_con_errores, target_lang_code)
|
archivo_maestro, celdas_con_errores, config.codigo_idioma_seleccionado
|
||||||
|
)
|
||||||
|
|
||||||
print(
|
print(
|
||||||
f"Se han actualizado las filas en {archivo_to_update} desde el archivo maestro. "
|
f"Se han actualizado las filas en {archivo_to_update} desde el archivo maestro. "
|
||||||
|
@ -83,18 +83,11 @@ def update_from_master(tipo_PLC, codigo_columna_maestra, archivo_maestro, archiv
|
||||||
)
|
)
|
||||||
logger.info(" .... ")
|
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.
|
def marcar_celdas_con_errores(archivo_maestro, celdas_con_errores, target_lang_code):
|
||||||
: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)
|
workbook = load_workbook(archivo_maestro)
|
||||||
sheet = workbook.active
|
sheet = workbook.active
|
||||||
|
|
||||||
# Encontrar la columna del idioma objetivo
|
|
||||||
for col in range(1, sheet.max_column + 1):
|
for col in range(1, sheet.max_column + 1):
|
||||||
if sheet.cell(row=1, column=col).value == target_lang_code:
|
if sheet.cell(row=1, column=col).value == target_lang_code:
|
||||||
target_col = col
|
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}")
|
print(f"No se encontró la columna para el idioma {target_lang_code}")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Marcar celdas con errores
|
|
||||||
for indice_maestro, mensaje_error in celdas_con_errores.items():
|
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 = sheet.cell(row=row, column=target_col)
|
||||||
cell.font = Font(color="FF0000") # Texto en rojo
|
cell.font = Font(color="FF0000")
|
||||||
|
|
||||||
# Añadir un comentario con el mensaje de error
|
|
||||||
comment = Comment(mensaje_error, "Sistema de Traducción")
|
comment = Comment(mensaje_error, "Sistema de Traducción")
|
||||||
cell.comment = comment
|
cell.comment = comment
|
||||||
|
|
||||||
workbook.save(archivo_maestro)
|
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")
|
archivo_to_update = fc.select_file("xlsx")
|
||||||
if archivo_to_update:
|
if archivo_to_update:
|
||||||
if seleccion_idioma not in fc.IDIOMAS:
|
update_from_master(config, archivo_to_update)
|
||||||
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)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
tipo_PLC = "siemens"
|
import menu_pasos_traduccion
|
||||||
codigo_columna_maestra = "it-IT"
|
|
||||||
fc.mostrar_idiomas()
|
menu_pasos_traduccion.main()
|
||||||
seleccion_idioma = int(input("Introduce el número del idioma de destino: "))
|
|
||||||
run(tipo_PLC, codigo_columna_maestra, seleccion_idioma)
|
|
||||||
|
|
Loading…
Reference in New Issue