Version fonctionnelle

This commit is contained in:
David Castex 2025-03-07 15:40:37 +01:00
parent dde2b39958
commit 61adf4a972

View File

@ -4,15 +4,48 @@
# ----- INSTALLATION DE PIP ET CONTROLE MODULES -----
# Repris depuis script Banbou
import subprocess
def check_and_update_pip():
# Vérifier s'il existe une version plus récente de pip
try:
result = subprocess.run(['pip', 'install', '--upgrade', 'pip', '--disable-pip-version-check'], capture_output=True, text=True)
if result.returncode == 0:
print("pip a été mis à jour avec succès.") #TODO bizarre, c'est affiché alors qu'il n'y avait pas d'internet
except subprocess.CalledProcessError:
print("La mise à jour de pip a échoué.")
# Lancer le code deux fois
for _ in range(2):
check_and_update_pip()
# Liste des bibliothèques à vérifier et installer
bibliotheques = ['csv', 'os', 're', 'shutil', 'sys', 'openpyxl']
for bibliotheque in bibliotheques:
try:
__import__(bibliotheque)
except ImportError:
# Installer la bibliothèque
print(f"{bibliotheque} n'est pas installée. Installation en cours...")
subprocess.check_call(['pip', 'install', bibliotheque])
print(f"{bibliotheque} a été installée avec succès.")
import os # getcwd(), walk()
import openpyxl # gestion et manipulation de fichier Open XML
import re # RegEx
from shutil import copyfile # copie de fichiers
# REPRESENTATION DES DONNEES
class _Fichier:
def __init__(self,
nom_original="Pas de nom original",
@ -62,50 +95,6 @@ class _Fichier:
# TODO : gerer la casse des extensions pour que le controle se fasse
## TODO Mettre les init de dico à vide {} plutot ??
class _Catalogue:
def __init__(self,
necessaires,
auxiliaires,
non_conformes
):
self.necessaires = necessaires # - son dictionnaire de fichiers nécessaires avec pour clé l'extention
# de chaque fichier - dico de paire string : _Fichier
self.auxiliaires = auxiliaires # - son dictionnaire de fichiers auxiliaires avec pour clé l'extention
# de chaque fichier - dico de paire string : _Fichier
self.non_conformes = non_conformes # - son dictionnaire de fichiers non-conformes avec pour clé l'extention
# de chaque fichier - dico de paire string : _Fichier
# PB : Pour le moment cette facon de representer des groupes de fichiers
# ne gèrent pas le fait qu'il y ai plusieurs fichiers avec la meme extension,
# en effet, je ne peux pas avoir plusieurs clés avec la meme extension
def afficher(self):
"""Affiche le catalogue dans la sortie standard
Affiche aussi un message si pour chaque dictionnaire vide
"""
if self.necessaires: # TODO renvoie False si dico = {} ou alors dois je écrire if necessaires == {}
print("fichiers nécessaires :".center(28))
for fichier in self.necessaires.values():
print(" ", fichier.nom, fichier.extension)
else:
print("Pas de Nécessaires".center(28))
if self.auxiliaires:
print("fichiers auxiliaires :".center(28))
for fichier in self.auxiliaires.values():
print(" ", fichier.nom, fichier.extension)
else:
print("Pas d'Auxiliaires".center(28))
if self.non_conformes:
print("fichiers non conformes :".center(28))
for fichier in self.non_conformes.values():
print(" ", fichier.non_conformes)
else:
print("Pas de Non-conformes".center(28))
class _Projet:
def __init__(self,
nom="Pas de nom",
@ -117,11 +106,14 @@ class _Projet:
projection="Inconnu",
encodage="Inconnu"):
self.nom = nom # - son nom - string
self.necessaires = necessaires
self.auxiliaires = auxiliaires
self.non_conformes = non_conformes
self.necessaires = necessaires # - son dictionnaire de fichiers nécessaires avec pour clé l'extention
# de chaque fichier - dico de paire string : _Fichier
self.auxiliaires = auxiliaires # - son dictionnaire de fichiers nécessaires avec pour clé l'extention
# de chaque fichier - dico de paire string : _Fichier
self.non_conformes = non_conformes # - son dictionnaire de fichiers nécessaires avec pour clé l'extention
# de chaque fichier - dico de paire string : _Fichier
self.nb_fichiers = nb_fichiers # - son nombre de fichiers - entier
self.conformite = conformite # - sa conformité - bool
self.conformite = conformite # - sa conformité - string
self.projection = projection # - sa projection géodésique - string // ou énumération --> voir Constantes
self.encodage = encodage # - son type d'encodage prévu dans QGIS string
# /* pour ce script, ce devrait être forcement "UTF8" */
@ -137,13 +129,12 @@ class _Projet:
print("necessaires :".center(16), self.necessaires)
print("auxiliaires :".center(16), self.auxiliaires)
print("non_conformes :".center(16), self.non_conformes)
#self.catalogue.afficher()
def cataloguer(self, fichier):
"""Catalogue le fichier dans le projet
La méthode ajoute le fichier suivant son extension
dans un des dictionnaires du catalogue
dans un des dictionnaires du projet
"""
match fichier.implication:
case "Necessaire":
@ -164,7 +155,7 @@ class _Projet:
chaine = df.readline()
df.close()
#cherche le motif : "Ligne qui commence par PROJCS["
# puis suivi de caracteres
# puis suivi de 0 ou plusieurs caracteres
#puis suivi de Lambert_93"
motif = re.findall('^PROJCS[[]".*Lambert_93"', chaine)
print("motif = ", motif)
@ -226,9 +217,13 @@ class _Projet:
if nb_controles_OK == 3:
self.conformite = "Conforme"
def copier(self):
"""Copie les fichiers du projets
"""
pass
# TODO :
# DEFINITIONS DE FONCTIONS
def formatter(chaine):
"""Formate selon nomenclature.
@ -318,7 +313,6 @@ for dossier_courant, list_sousdossiers, list_fichiers in os.walk(racine):
# Fin Pour
# /* Ici la liste des _Fichiers doit être correctement remplie */
#TEST affichage de la liste de fichier
# initialiser un dictionnaire de _Projets avec comme clé leurs noms respectifs
print("Init Dictionnaire des Projets\n")
@ -371,27 +365,23 @@ for projet in dico.values():
# --produire le rapport
# créer un classeur Excel
# TODO pour le moment je vais partir sur un modele deja ecrit que j'ouvre
# Contrainte : l'opérateur doit placer le modèle dans le même dossier racine que le present script
# Contrainte : l'opérateur doit placer le modèle dans le même dossier que le script
classeur = openpyxl.load_workbook("modele_VISA_DORY.xlsx")
feuille = classeur.active
# /* Note : peut être utiliser un modèle pré-config */
# --mettre en page la première feuille du classeur
# inserer une image
# écrire les nom des colonnes
# écrire les formules de colorations auto des colonnes
cell = feuille["A2"]
cell.value = "Dossier : "+ racine.name
# Pour chaque projet du dictionnaire Faire
ligne_courante = 4
for nom_projet, projet in dico.items():
# --completer la feuille avec les infos du projet courant
# /* Note : Chaque ligne de la feuille correspond à un projet */
# /* Utiliser la config fournie en Constante */
# écrire le nom du projet
cell = feuille["A"+str(ligne_courante)]
cell.value = nom_projet
print(cell.value)
#print(cell.value)
# écrire le type d'extention
cell = feuille["B"+str(ligne_courante)]
if "shp" in projet.necessaires:
@ -402,15 +392,19 @@ for nom_projet, projet in dico.items():
for extension in projet.non_conformes:
cell.value = extension.upper()
print(cell.value)
# écrire le nombre de fichiers du projet
cell = feuille["C"+str(ligne_courante)]
cell.value = projet.nb_fichiers
# écrire l'encodage
cell = feuille["D"+str(ligne_courante)]
cell.value = projet.encodage
# écrire la projection
cell = feuille["E"+str(ligne_courante)]
cell.value = projet.projection
# écrire la validité (conformité)
cell = feuille["F"+str(ligne_courante)]
if projet.conformite in "Conforme":
@ -463,8 +457,24 @@ except FileExistsError as erreur:
print(erreur)
# --peupler le dossier "Travail"
# Pour Chaque projet du dictionnaire Faire
dossier_cible = "Travail"
for projet in dico.values():
# copier les fichiers des projets conforme dans le dossier "01"
# copier les fichiers des projets non-conformes dans le dossier "02"
if projet.conformite in "Conforme":
for fichier in projet.necessaires.values():
#print("chemin : ".center(30), fichier.chemin)
#print("nom : ".center(30), fichier.nom + "." + fichier.extension)
copyfile(fichier.chemin, "Travail\\01-Donnees_Valides\\"+fichier.nom+"."+fichier.extension)
for fichier in projet.auxiliaires.values():
copyfile(fichier.chemin, "Travail\\01-Donnees_Valides\\"+fichier.nom+"."+fichier.extension)
else:
for fichier in projet.necessaires.values():
copyfile(fichier.chemin, "Travail\\02-Donnees_Invalides\\"+fichier.nom+"."+fichier.extension)
for fichier in projet.auxiliaires.values():
copyfile(fichier.chemin, "Travail\\02-Donnees_Invalides\\"+fichier.nom+"."+fichier.extension)
for fichier in projet.non_conformes.values():
copyfile(fichier.chemin, "Travail\\02-Donnees_Invalides\\"+fichier.nom+"."+fichier.extension)
# Fin Pour
# /* Ici les dossiers doivent être correctement produit et remplie */