import pandas as pd import os import PyLibrary.funciones_comunes as fc from translation_config import TranslationConfig from openpyxl import load_workbook from openpyxl.styles import Font, PatternFill from openpyxl.comments import Comment # 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 logger.info(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) # Create copy for changes tracking df_changes = df_to_update.copy() df_changes["Original_Value"] = "" col_clave = config.codigo_columna_maestra # Si la columna maestra es igual al idioma seleccionado, usamos la columna propuesta is_same_column = config.codigo_columna_maestra == config.codigo_idioma_seleccionado master_col = f"{config.codigo_idioma_seleccionado}_Propuesto" if is_same_column else config.codigo_idioma_seleccionado if master_col not in df_maestro.columns: print(f"Error: Columna {master_col} no encontrada en el archivo maestro") return celdas_modificadas = [] progress_bar = fc.ProgressBar(len(df_to_update), prefix="Actualizando filas:", suffix="Completado") for index, fila in df_to_update.iterrows(): valor_original = fila[col_clave] clave = fc.compactar_celda_clave(config.codigo_tipo_PLC, valor_original) if not pd.isna(clave) and clave in df_maestro[col_clave].values: indice_maestro = df_maestro.index[df_maestro[col_clave] == clave].tolist()[0] valor_traducido_compacto = df_maestro.loc[indice_maestro, master_col] if pd.isna(valor_traducido_compacto): continue valor_traducido = fc.decompactar_celda_traducida( config.codigo_tipo_PLC, celda_original=valor_original, celda_traducida=valor_traducido_compacto ) if not pd.isna(valor_traducido) and fila[config.codigo_idioma_seleccionado] != valor_traducido: okToSave, Error = fc.verificar_celda_traducida( config.codigo_tipo_PLC, clave, valor_traducido_compacto ) if okToSave: # Store original value in changes DataFrame df_changes.at[index, "Original_Value"] = fila[config.codigo_idioma_seleccionado] # Update both DataFrames df_to_update.at[index, config.codigo_idioma_seleccionado] = valor_traducido df_changes.at[index, config.codigo_idioma_seleccionado] = valor_traducido celdas_modificadas.append(index) logger.info(f"Actualizado: Fila {index} : Clave: {clave}") progress_bar.increment() progress_bar.finish() # Save updated file with formatting nombre, extension = os.path.splitext(archivo_to_update) nuevo_nombre = f"{nombre}_import{extension}" with pd.ExcelWriter(nuevo_nombre, engine='openpyxl') as writer: df_to_update.to_excel(writer, sheet_name="User Texts", index=False) workbook = writer.book worksheet = writer.sheets["User Texts"] # Format columns from openpyxl.utils import get_column_letter from openpyxl.styles import Alignment, PatternFill for col in worksheet.columns: max_length = 0 column = col[0].column_letter for cell in col: try: if cell.value: text_length = len(str(cell.value)) if text_length > 50: cell.alignment = Alignment(wrap_text=True, vertical='top') text_length = min(50, max(len(word) for word in str(cell.value).split())) max_length = max(max_length, text_length) except: pass adjusted_width = min(50, max_length + 2) worksheet.column_dimensions[column].width = adjusted_width if adjusted_width > 8 else 8 # Save changes file with highlighting changes_nombre = f"{nombre}_changes{extension}" if len(celdas_modificadas) > 0: with pd.ExcelWriter(changes_nombre, engine="openpyxl") as writer: df_changes.to_excel(writer, index=False) workbook = writer.book worksheet = writer.sheets["User Texts"] light_blue = PatternFill(start_color="ADD8E6", end_color="ADD8E6", fill_type="solid") for row_idx in celdas_modificadas: for col in range(1, len(df_changes.columns) + 1): cell = worksheet.cell(row=row_idx + 2, column=col) cell.fill = light_blue # Format columns in changes file too for col in worksheet.columns: max_length = 0 column = col[0].column_letter for cell in col: try: if cell.value: text_length = len(str(cell.value)) if text_length > 50: cell.alignment = Alignment(wrap_text=True, vertical='top') text_length = min(50, max(len(word) for word in str(cell.value).split())) max_length = max(max_length, text_length) except: pass adjusted_width = min(50, max_length + 2) worksheet.column_dimensions[column].width = adjusted_width if adjusted_width > 8 else 8 print(f"Se han actualizado las filas en {archivo_to_update} desde el archivo maestro.") print(f"Archivo de cambios guardado en: {changes_nombre}") print(f"Se han marcado {len(celdas_modificadas)} filas modificadas.") logger.info(" .... ") def marcar_celdas_con_errores( archivo_maestro, celdas_con_errores, celdas_vacias, target_lang_code ): workbook = load_workbook(archivo_maestro) sheet = workbook.active for col in range(1, sheet.max_column + 1): if sheet.cell(row=1, column=col).value == target_lang_code: target_col = col break else: print(f"No se encontró la columna para el idioma {target_lang_code}") return error_fill = PatternFill( start_color="FF0000", end_color="FF0000", fill_type="solid" ) empty_fill = PatternFill( start_color="FFFF00", end_color="FFFF00", fill_type="solid" ) white_font = Font(color="FFFFFF") # Fuente blanca para celdas con fondo rojo for indice_maestro, mensaje_error in celdas_con_errores.items(): row = indice_maestro + 2 cell = sheet.cell(row=row, column=target_col) cell.fill = error_fill cell.font = white_font # Aplicar fuente blanca comment = Comment(mensaje_error, "Sistema de Traducción") cell.comment = comment for indice_maestro, mensaje in celdas_vacias.items(): row = indice_maestro + 2 cell = sheet.cell(row=row, column=target_col) cell.fill = empty_fill comment = Comment(mensaje, "Sistema de Traducción") cell.comment = comment workbook.save(archivo_maestro) print( f"Se han marcado las celdas con errores y vacías en el archivo maestro {archivo_maestro}" ) def run(config: TranslationConfig, archivo_to_update): global logger logger = fc.configurar_logger(config.work_dir) script_name = os.path.basename(__file__) print(f"\rIniciando: {script_name}\r") update_from_master(config, archivo_to_update) if __name__ == "__main__": import menu_pasos_traduccion menu_pasos_traduccion.main()