Newer
Older
csvCompare / src / csvCompare_list1notin2.py
#       Ce programme compare 2 fichiers au format .csv avec des séparateurs ";"
#       Le fichier 1 est le fichier de référence auquel on va comparer le fichier 2
#		On va lister les lignes du fichier 1 dont la valeur de la colonne ci n'est pas trouvée dans la colonne cj du fichier 2
#
#       Les fichiers sont triés et dédoublonnés à la volée sur la bonne colonne
#       Les retours à la ligne sont codés à la volée au format Unix
#       Le script prend en compte d'éventuelles lignes d'entete de colonne
#
#       Ce programme utilise le script shell csvCompare_list1notin2.sh
#       Il suffit juste que le script et l'executable soient dans le même répertoire et que Git Bash soit installé
#       Le répertoire Git va être cherché par défaut sur le chemin indiqué par la variable d'environnement GIT_PATH
#       sinon sur 'C:\\Program Files\\Git' 
#
#		Date: 21/08/2024
#
#		Auteur: David Castelain

import tkinter as tk
from tkinter import filedialog, messagebox
import subprocess
import logging
import os

# Configurer le logging
logging.basicConfig(filename='csvCompare_list1notin2.log', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')

def run_bash_script():
    # Récupérer le PATH de git
    git_path = os.getenv('GIT_PATH', 'C:\\Program Files\\Git')
    logging.debug(f"git_path : {git_path}")
    
    # Récupérer les valeurs des paramètres
    file1 = file1_var.get()
    num1 = num1_var.get()
    num2 = num2_var.get()
    file2 = file2_var.get()
    num3 = num3_var.get()
    num4 = num4_var.get()
    file3 = file3_var.get()

    # Log des paramètres
    logging.debug(f"Paramètres récupérés : file1={file1}, num1={num1}, num2={num2}, file2={file2}, num3={num3}, num4={num4}, file3={file3}")


    try:
        # Exécuter la commande
        logging.debug(f"subprocess.run : " + f"'{git_path}'\\bin\\bash.exe" + """ -c './list1notin2.sh "$0" "$1" "$2" "$3" "$4" "$5" "$6"'""" + f" '{file1}' {num1} {num2} '{file2}' {num3} {num4} '{file3}'")
        
        result = subprocess.run(f"{git_path}\\bin\\bash.exe" + """ -c './csvCompare_list1notin2.sh "$0" "$1" "$2" "$3" "$4" "$5" "$6"'""" + f" '{file1}' {num1} {num2} '{file2}' {num3} {num4} '{file3}'", check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        logging.info(f"Sortie standard : {result.stdout.decode()}")
        logging.info(f"Sortie d'erreur : {result.stderr.decode()}")
    except subprocess.CalledProcessError as e:
        logging.error(f"Erreur lors de l'exécution du script : {e}")
        logging.error(f"Sortie d'erreur : {e.stderr.decode()}")
        messagebox.showerror("Erreur", f"Erreur lors de l'exécution du script : {e}")
    

def browse_file(file_var):
    file_path = filedialog.askopenfilename()
    #file_path = file_path_tmp.replace(' ', '\\ ')
    file_var.set(file_path)
    logging.debug(f"Fichier sélectionné : {file_path}")

def browse_save_file(file_var):
    file_path = filedialog.asksaveasfilename()
    file_var.set(file_path)
    logging.debug(f"Nouveau fichier sélectionné : {file_path}")

# Créer la fenêtre principale
root = tk.Tk()
root.title("List lines of file1 not matching in file2")

# Variables pour stocker les valeurs des paramètres
file1_var = tk.StringVar()
num1_var = tk.IntVar()
num2_var = tk.IntVar()
file2_var = tk.StringVar()
num3_var = tk.IntVar()
num4_var = tk.IntVar()
file3_var = tk.StringVar()

# On prépare une grille de six lignes et 4 colonnes
# La première ligne cherchera à saturer l'espace restant dans la fenêtre.
root.grid_rowconfigure(0, weight=0)
root.grid_rowconfigure(1, weight=0)
root.grid_rowconfigure(2, weight=0)
root.grid_rowconfigure(3, weight=0)
root.grid_rowconfigure(4, weight=0)
root.grid_rowconfigure(5, weight=0)
root.grid_rowconfigure(6, weight=0)
root.grid_rowconfigure(7, weight=0)
root.grid_rowconfigure(8, weight=0)
root.grid_rowconfigure(9, weight=0)
root.grid_rowconfigure(10, weight=0)
root.grid_rowconfigure(11, weight=0)
root.grid_rowconfigure(12, weight=0)
root.grid_rowconfigure(13, weight=0)
root.grid_rowconfigure(14, weight=0)
root.grid_rowconfigure(15, weight=0)
root.grid_rowconfigure(16, weight=0)
root.grid_rowconfigure(17, weight=0)

# On force la taille des colonne avec le paramètre uniform. "same_group" est texte libre.
# Le fait que les 3 colonnes utilisent la même chaîne force la même taille. 
# Les paramètres weight servent uniquement pour que les colonnes utilisent 100% de la 
# largeur de la fenêtre.
root.grid_columnconfigure(0, weight=1, uniform="same_group")
root.grid_columnconfigure(1, weight=1, uniform="same_group")
root.grid_columnconfigure(2, weight=1, uniform="same_group")
        
default_pos_grid = {"padx": 10, "pady": 10, "sticky": "nsew"}
default_label_grid = {"padx": 10, "pady": 0, "sticky": "sw"}
      
#font1 = ('Times',22,'normal')

# Créer les éléments de l'interface
label_f1 = tk.Label(root, text="Fichier de référence:", anchor="sw")
label_f1.grid(row=0, column=0, columnspan=2, **default_label_grid)
entry_f1 = tk.Entry(root, textvariable=file1_var)
entry_f1.grid(row=1, column=0, columnspan=2, **default_pos_grid)
button_f1 = tk.Button(root, text="Parcourir", command=lambda: browse_file(file1_var))
button_f1.grid(row=1, column=2, **default_pos_grid)

label_ndc1 = tk.Label(root, text="Numéro de la colonne à comparer [1-100]:", anchor="sw")
label_ndc1.grid(row=2, column=0, columnspan=2, **default_label_grid)
box_ndc1 = tk.Spinbox(root, from_=1, to=100, textvariable=num1_var)
box_ndc1.grid(row=3, column=0, columnspan=2, **default_pos_grid)

label_ndl1 = tk.Label(root, text="Nombre de lignes d'entête [0-10]:", anchor="sw")
label_ndl1.grid(row=4, column=0, columnspan=2, **default_label_grid)
box_ndl1 = tk.Spinbox(root, from_=0, to=10, textvariable=num2_var)
box_ndl1.grid(row=5, column=0, columnspan=2, **default_pos_grid)

label_vide1 = tk.Label(root, text="", anchor="sw")
label_vide1.grid(row=6, column=0, columnspan=3, **default_label_grid)

label_f2 = tk.Label(root, text="Fichier à contrôler:", anchor="sw")
label_f2.grid(row=7, column=0, columnspan=2, **default_label_grid)
entry_f2 = tk.Entry(root, textvariable=file2_var)
entry_f2.grid(row=8, column=0, columnspan=2, **default_pos_grid)
button_f2 = tk.Button(root, text="Parcourir", command=lambda: browse_file(file2_var))
button_f2.grid(row=8, column=2, **default_pos_grid)


label_ndc2 = tk.Label(root, text="Numéro de la colonne à comparer [1-100]:", anchor="sw")
label_ndc2.grid(row=9, column=0, columnspan=2, **default_label_grid)
box_ndc2 = tk.Spinbox(root, from_=1, to=100, textvariable=num3_var)
box_ndc2.grid(row=10, column=0, columnspan=2, **default_pos_grid)

label_ndl2 = tk.Label(root, text="Nombre de lignes d'entête [0-10]:", anchor="sw")
label_ndl2.grid(row=11, column=0, columnspan=2, **default_label_grid)
box_ndl2 = tk.Spinbox(root, from_=0, to=10, textvariable=num4_var)
box_ndl2.grid(row=12, column=0, columnspan=2, **default_pos_grid)

label_vide2 = tk.Label(root, text="", anchor="sw")
label_vide2.grid(row=13, column=0, columnspan=3, **default_label_grid)

label_f3 = tk.Label(root, text="Fichier résultat avec les valeurs non trouvées:", anchor="sw")
label_f3.grid(row=14, column=0, columnspan=2, **default_label_grid)
entry_f3 = tk.Entry(root, textvariable=file3_var)
entry_f3.grid(row=15, column=0, columnspan=2, **default_pos_grid)
button_f3 = tk.Button(root, text="Parcourir/Créer", command=lambda: browse_save_file(file3_var))
button_f3.grid(row=15, column=2, **default_pos_grid)

label_vide3 = tk.Label(root, text="", anchor="sw")
label_vide3.grid(row=16, column=0, columnspan=3, **default_label_grid)

# Créer un bouton pour lancer le script
button_lancer = button = tk.Button(root, text="Lancer le script", command=run_bash_script)
button_lancer.grid(row=17, column=0, columnspan=3, sticky="nswe", padx=10, pady=5)


# Lancer la boucle principale de l'interface graphique
root.mainloop()