Primer
This commit is contained in:
commit
f86df8f09a
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,90 @@
|
|||
import pandas as pd
|
||||
import os
|
||||
import re
|
||||
from manejoArchivos import select_file
|
||||
|
||||
def es_columna_tipo_xxYY(columna):
|
||||
# Verificar si la columna es del tipo "xx-YY" usando una expresión regular
|
||||
return bool(re.match(r'^[a-z]{2}-[A-Z]{2}$', columna))
|
||||
|
||||
def sustituir_digitos(celda):
|
||||
# Convertir a cadena y sustituir secuencias de dígitos por [[digits]]
|
||||
if pd.isnull(celda):
|
||||
return celda
|
||||
return re.sub(r'\d+', '[[digits]]', str(celda))
|
||||
|
||||
def preprocesar_importacion(df_importacion):
|
||||
# Iterar sobre las filas del DataFrame de importación
|
||||
for index, fila in df_importacion.iterrows():
|
||||
clave_original = str(fila['it-IT'])
|
||||
clave_sustituida = sustituir_digitos(clave_original)
|
||||
|
||||
# Sustituir en las demás columnas del tipo "xx-YY"
|
||||
for columna in df_importacion.columns:
|
||||
if columna != 'it-IT' and es_columna_tipo_xxYY(columna):
|
||||
df_importacion.at[index, columna] = sustituir_digitos(fila[columna])
|
||||
|
||||
# Guardar la clave sustituida
|
||||
df_importacion.at[index, 'it-IT'] = clave_sustituida
|
||||
|
||||
return df_importacion
|
||||
|
||||
def importar(archivo_maestro, archivo_importacion):
|
||||
if not os.path.exists(archivo_maestro):
|
||||
# Crear un DataFrame maestro vacío con la columna "it-IT"
|
||||
df_maestro = pd.DataFrame(columns=["it-IT"])
|
||||
else:
|
||||
df_maestro = pd.read_excel(archivo_maestro)
|
||||
|
||||
df_importacion = pd.read_excel(archivo_importacion)
|
||||
|
||||
# Preprocesar el archivo de importación
|
||||
df_importacion = preprocesar_importacion(df_importacion)
|
||||
|
||||
# Obtener las claves existentes en el archivo maestro
|
||||
claves_maestro = set(df_maestro["it-IT"].dropna().astype(str))
|
||||
|
||||
# Filtrar filas del archivo de importación que no están en el archivo maestro
|
||||
nuevas_filas = df_importacion[
|
||||
df_importacion["it-IT"].apply(
|
||||
lambda x: len(str(x)) > 5 and str(x) not in claves_maestro
|
||||
)
|
||||
]
|
||||
|
||||
# Si no hay filas nuevas, terminar
|
||||
if nuevas_filas.empty:
|
||||
print("No hay nuevas filas para agregar.")
|
||||
return
|
||||
|
||||
# Agregar columnas del tipo "xx-YY" que no existen en el archivo maestro
|
||||
for columna in nuevas_filas.columns:
|
||||
if es_columna_tipo_xxYY(columna) and columna not in df_maestro.columns:
|
||||
df_maestro[columna] = None
|
||||
|
||||
# Crear una lista de diccionarios para las filas que se van a agregar
|
||||
filas_a_agregar = []
|
||||
|
||||
# Iterar sobre las nuevas filas para agregarlas y actualizar las claves
|
||||
for _, fila in nuevas_filas.iterrows():
|
||||
clave = str(fila["it-IT"])
|
||||
if clave not in claves_maestro:
|
||||
claves_maestro.add(clave)
|
||||
# Solo agregar las columnas del tipo "xx-YY" y "it-IT"
|
||||
fila_filtrada = {col: fila[col] for col in fila.index if col == "it-IT" or es_columna_tipo_xxYY(col)}
|
||||
filas_a_agregar.append(fila_filtrada)
|
||||
|
||||
# Concatenar las nuevas filas al DataFrame maestro
|
||||
if filas_a_agregar:
|
||||
df_nuevas_filas = pd.DataFrame(filas_a_agregar)
|
||||
df_maestro = pd.concat([df_maestro, df_nuevas_filas], ignore_index=True)
|
||||
|
||||
# Guardar el archivo maestro actualizado
|
||||
df_maestro.to_excel(archivo_maestro, index=False)
|
||||
print(f"Se han agregado {len(filas_a_agregar)} nuevas filas al archivo maestro.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Cargar el archivo maestro y el archivo de importación
|
||||
archivo_maestro = "hmi_master_translates.xlsx"
|
||||
archivo_importacion = select_file("xlsx")
|
||||
if archivo_importacion:
|
||||
importar(archivo_maestro, archivo_importacion)
|
|
@ -0,0 +1,50 @@
|
|||
import pandas as pd
|
||||
import tkinter as tk
|
||||
from tkinter import filedialog
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
def select_file(extension = "txt"):
|
||||
"""
|
||||
Opens a file dialog to select a .db file and returns the selected file path.
|
||||
"""
|
||||
root = tk.Tk()
|
||||
root.withdraw() # Use to hide the tkinter root window
|
||||
|
||||
# Open file dialog and return the selected file path
|
||||
file_path = filedialog.askopenfilename(
|
||||
title="Select a .db file",
|
||||
filetypes=(("DB files", f"*.{extension}"), ("All files", "*.*"))
|
||||
)
|
||||
return file_path
|
||||
|
||||
def open_file_explorer(path):
|
||||
"""
|
||||
Opens the file explorer at the given path, correctly handling paths with spaces.
|
||||
"""
|
||||
# Normalize the path to ensure it's in the correct format
|
||||
normalized_path = os.path.normpath(path)
|
||||
|
||||
# Check if the path is a directory or a file and format the command accordingly
|
||||
if os.path.isdir(normalized_path):
|
||||
# If it's a directory, use the 'explorer' command directly
|
||||
command = f'explorer "{normalized_path}"'
|
||||
else:
|
||||
# If it's a file, use the 'explorer /select,' command to highlight the file in its folder
|
||||
command = f'explorer /select,"{normalized_path}"'
|
||||
|
||||
# Execute the command using subprocess.run, with shell=True to handle paths with spaces correctly
|
||||
subprocess.run(command, shell=True)
|
||||
|
||||
def select_directory():
|
||||
"""
|
||||
Opens a file dialog to select a directory and returns the selected directory path.
|
||||
"""
|
||||
root = tk.Tk()
|
||||
root.withdraw() # Use to hide the tkinter root window
|
||||
|
||||
# Open directory dialog and return the selected directory path
|
||||
directory_path = filedialog.askdirectory(
|
||||
title="Select a directory"
|
||||
)
|
||||
return directory_path
|
|
@ -0,0 +1,102 @@
|
|||
import pandas as pd
|
||||
import os
|
||||
import re
|
||||
import logging
|
||||
from manejoArchivos import select_file
|
||||
|
||||
def es_columna_tipo_xxYY(columna):
|
||||
# Verificar si la columna es del tipo "xx-YY" usando una expresión regular
|
||||
return bool(re.match(r'^[a-z]{2}-[A-Z]{2}$', columna))
|
||||
|
||||
def sustituir_digitos(celda):
|
||||
# Convertir a cadena y sustituir secuencias de dígitos por [[digits]]
|
||||
if pd.isnull(celda):
|
||||
return celda, []
|
||||
digitos = re.findall(r'\d+', str(celda))
|
||||
celda_sustituida = re.sub(r'\d+', '[[digits]]', str(celda))
|
||||
return celda_sustituida, digitos
|
||||
|
||||
def preprocesar_update(df_update):
|
||||
# Diccionario para almacenar los dígitos reemplazados por fila
|
||||
digitos_reemplazados = {}
|
||||
|
||||
# Iterar sobre las filas del DataFrame de actualización
|
||||
for index, fila in df_update.iterrows():
|
||||
clave_original = str(fila['it-IT'])
|
||||
clave_sustituida, digitos = sustituir_digitos(clave_original)
|
||||
digitos_reemplazados[index] = digitos
|
||||
df_update.at[index, 'it-IT_preprocessed'] = clave_sustituida # Agregar una columna preprocesada
|
||||
|
||||
return df_update, digitos_reemplazados
|
||||
|
||||
def configurar_logger(ruta_log):
|
||||
logger = logging.getLogger('actualizacion_logger')
|
||||
logger.setLevel(logging.INFO)
|
||||
fh = logging.FileHandler(ruta_log, encoding='utf-8')
|
||||
fh.setLevel(logging.INFO)
|
||||
formatter = logging.Formatter('%(asctime)s - %(message)s')
|
||||
fh.setFormatter(formatter)
|
||||
logger.addHandler(fh)
|
||||
return logger
|
||||
|
||||
def update_from_master(archivo_maestro, archivo_to_update):
|
||||
if not os.path.exists(archivo_maestro):
|
||||
print("El archivo maestro no existe.")
|
||||
return
|
||||
|
||||
df_maestro = pd.read_excel(archivo_maestro)
|
||||
df_to_update = pd.read_excel(archivo_to_update)
|
||||
|
||||
# Configurar el logger
|
||||
directorio = os.path.dirname(archivo_to_update)
|
||||
nombre_log = os.path.join(directorio, 'actualizacion.log')
|
||||
logger = configurar_logger(nombre_log)
|
||||
|
||||
# Preprocesar el archivo de actualización
|
||||
df_to_update, digitos_reemplazados = preprocesar_update(df_to_update)
|
||||
|
||||
# Obtener las claves del archivo maestro
|
||||
claves_maestro = set(df_maestro["it-IT"].dropna().astype(str))
|
||||
|
||||
# Iterar sobre las filas del archivo de actualización para actualizarlas
|
||||
for index, fila in df_to_update.iterrows():
|
||||
clave_preprocesada = str(fila['it-IT_preprocessed'])
|
||||
if clave_preprocesada in claves_maestro:
|
||||
# Obtener los dígitos originales para esta fila
|
||||
digitos = digitos_reemplazados.get(index, [])
|
||||
df_maestro_fila = df_maestro[df_maestro['it-IT'] == clave_preprocesada].iloc[0]
|
||||
|
||||
# Verificar que la cantidad de dígitos coincida con la cantidad de [[digits]] en la clave
|
||||
cantidad_digits = clave_preprocesada.count('[[digits]]')
|
||||
if len(digitos) != cantidad_digits:
|
||||
logger.info(f'Fila {index}: no se actualiza porque la cantidad de dígitos no coincide.')
|
||||
continue
|
||||
|
||||
# Actualizar solo las columnas que existen en df_to_update y que no sean 'it-IT'
|
||||
for columna in df_to_update.columns:
|
||||
if columna != 'it-IT' and columna != 'it-IT_preprocessed' and columna in df_maestro.columns:
|
||||
valor = df_maestro_fila[columna]
|
||||
# Convertir a cadena si no lo es y reemplazar [[digits]] con los dígitos originales
|
||||
if not pd.isnull(valor):
|
||||
valor_original = str(valor)
|
||||
valor_actualizado = valor_original
|
||||
for d in digitos:
|
||||
valor_actualizado = valor_actualizado.replace('[[digits]]', d, 1)
|
||||
# Solo actualizar si el valor ha cambiado
|
||||
if str(fila[columna]) != valor_actualizado:
|
||||
df_to_update.at[index, columna] = valor_actualizado
|
||||
# Registrar el cambio
|
||||
logger.info(f'Fila {index}, Columna {columna}: "{fila[columna]}" actualizado a "{valor_actualizado}"')
|
||||
|
||||
# Eliminar la columna preprocesada
|
||||
df_to_update.drop(columns=['it-IT_preprocessed'], inplace=True)
|
||||
|
||||
# Guardar el archivo actualizado
|
||||
df_to_update.to_excel(archivo_to_update, index=False)
|
||||
print(f"Se han actualizado las filas en {archivo_to_update} desde el archivo maestro. Detalles de los cambios en {nombre_log}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
archivo_maestro = "hmi_master_translates.xlsx"
|
||||
archivo_to_update = select_file("xlsx")
|
||||
if archivo_to_update:
|
||||
update_from_master(archivo_maestro, archivo_to_update)
|
Loading…
Reference in New Issue