correction et ajout de fichiers de test

La partie 'analyse' du programme est fonctionnelle
Ajout de fichiers intentionellement erronés dans
le repertoire de test
This commit is contained in:
David Castex 2025-03-03 22:29:36 +01:00
parent dfd0c8850c
commit c9bfc721d3
22 changed files with 3646 additions and 3489 deletions

View File

@ -9,6 +9,9 @@ NOTES :
pas de problème, car je n'exécute pas QGIS. Je n'ai pas encore trouvé
comment désactiver cette option dans Git.
VOIR : mettre core.autocrlf à false pour avoir un comportement normal
(checkout-as-is, commit-as-is).
David.

View File

@ -1 +1 @@
PROJCS["RGF_1993_Lambert_93",GEOGCS["GCS_RGF_1993",DATUM["D_RGF_1993",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",700000.0],PARAMETER["False_Northing",6600000.0],PARAMETER["Central_Meridian",3.0],PARAMETER["Standard_Parallel_1",49.0],PARAMETER["Standard_Parallel_2",44.0],PARAMETER["Latitude_Of_Origin",46.5],UNIT["Meter",1.0]]
DADADADAPROJCS["RGF_1991_Lambert_93",GEOGCS["GCS_RGF_1993",DATUM["D_RGF_1993",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",700000.0],PARAMETER["False_Northing",6600000.0],PARAMETER["Central_Meridian",3.0],PARAMETER["Standard_Parallel_1",49.0],PARAMETER["Standard_Parallel_2",44.0],PARAMETER["Latitude_Of_Origin",46.5],UNIT["Meter",1.0]]

View File

@ -2,9 +2,12 @@
# Voir algorithme.txt pour plus de détails et commentaires
import os # getcwd(),
## TODO : voir le pb des dicos qui auraient plusieurs fois les memes clés (se qui n'est pas possible) à cause de plusieurs fichiers qui auraient la meme extension
@ -43,42 +46,199 @@ class _Fichier:
# "Non-conforme",
# "A-ignorer"}
def afficher(self):
"""Affiche dans la sortie standard les éléments du fichier
"""
print("nom : ".center(16), self.nom)
print("nom orig : ".center(16), self.nom_original)
print("ext : ".center(16), self.extension)
print("chemin : ".center(16), self.chemin)
print("implication :".center(16), self.implication)
def impliquer(self):
"""Définir l'implication d'un fichier
Les fichiers nécessaires sont indispensables sinon l'importation
de la couche échoue.
Les fichiers optionels (ou auxiliaires) contiennent des données
supplémentaires lors de l'importation.
Les fichiers non conformes pourraient être importer dans QGIS. Mais,
ne sont pas conformes au cahier des charges.
Les fichiers ignorés ne fonctionnent pas dans QGIS.
L'implication est définie en fonction de l'extension du fichier.
"""
match self.extension:
case "dbf" | "cpg" | "prj" | "shx" | "shp":
self.implication = "Necessaire"
case "qix" | "qmd" | "qml":
self.implication = "Auxiliaire"
case "gpkg" | "sqlite":
self.implication = "Non-conforme"
case _:
self.implication = "A-ignorer"
# 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="Pas de dico",
auxiliaires="Pas de dico",
non_conformes="Pas de dico"):
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",
catalogue="Pas de catalogue",
necessaires = {},
auxiliaires = {},
non_conformes = {},
nb_fichiers=0,
conformite=False,
conformite="Non conforme",
projection="Pas de projection",
encodage="Pas d'encodage"):
self.nom = nom # - son nom - string
self.catalogue = catalogue # - son catalogue - _Catalogue
self.necessaires = necessaires
self.auxiliaires = auxiliaires
self.non_conformes = non_conformes
self.nb_fichiers = nb_fichiers # - son nombre de fichiers - entier
self.conformite = conformite # - sa conformité - bool
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" */
def afficher(self):
"""Affiche dans la sortie standard le contenu d'un projet
"""
print("nom : ".center(16), self.nom)
print("nb fichiers :".center(16), self.nb_fichiers)
print("conformité :".center(16), self.conformite)
print("projection :".center(16), self.projection)
print("encodage :".center(16), self.encodage)
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
"""
match fichier.implication:
case "Necessaire":
self.necessaires[fichier.extension] = fichier
case "Auxiliaire":
self.auxiliaires[fichier.extension] = fichier
case "Non-conforme":
self.non_conformes[fichier.extension] = fichier
def lire_projection(self):
"""Récupère la projection des données géomatiques définie.
Lis la première ligne du fichier *.PRJ du projet
et controle la présence de la chaine "RGF_1993_Lambert_93"
"""
if "prj" in self.necessaires:
df = open(self.necessaires["prj"].chemin)
chaine = df.readline()
df.close()
if "RGF_1993_Lambert_93" in chaine:
self.projection = "LAMBERT93"
else:
print(projet.nom, " : pas de PRJ trouvé --> pas de projection définie")
def lire_encodage(self):
"""Récupère l'encodage prévu pour les fichiers dans QGIS
Lis la première ligne du fichier *.CPG du projet
et controle la présence de la chaine "UTF-8"
"""
if "cpg" in self.necessaires:
df = open(self.necessaires["cpg"].chemin)
chaine = df.readline()
#print("encod lu : ", chaine)
df.close()
if "UTF-8" in chaine:
self.encodage = "UTF8"
else:
print(projet.nom, " : pas de CPG trouvé --> pas d'encodage définie")
def valider(self):
"""Valide la conformité du projet
Controle si les 5 fichiers differents nécessaires sont présents.
Controle si la projection est correcte (pour le moment Lambert93).
Controle si l'encodage défini pour l'import dans QGIS est bien UTF8.
Si ces 3 controles sont OK, alors le projet est défini comme valide.
"""
nb_controles_OK = 0
# Controle présences fichiers
valide = [False, False, False, False, False]
for extension in self.necessaires.keys():
match extension:
case "dbf":
valide[0] = True
case "cpg":
valide[1] = True
case "prj" :
valide[2] = True
case "shx" :
valide[3] = True
case "shp" :
valide[4] = True
if valide[0] and valide[1] and valide[2] and valide[3] and valide[4]:
nb_controles_OK += 1
# Controle projection
if self.projection == "LAMBERT93":
nb_controles_OK += 1
# Controle encodage
if self.encodage == "UTF8":
nb_controles_OK += 1
# Si les 3 controles sont OK ALors le projet est conforme
if nb_controles_OK == 3:
self.conformite = "Conforme"
# DEFINITIONS DE FONCTIONS
@ -118,32 +278,6 @@ def formatter(chaine):
def impliquer(fichier):
"""Définir l'implication d'un fichier
Les fichiers nécessaires sont indispensables sinon l'importation
de la couche échoue.
Les fichiers optionels (ou auxiliaires) contiennent des données
supplémentaires lors de l'importation.
Les fichiers non conformes pourraient être importer dans QGIS. Mais,
ne sont pas conformes au cahier des charges.
Les fichiers ignorés ne fonctionnent pas dans QGIS.
L'implication est définie en fonction de l'extension du fichier.
"""
resultat = fichier
match fichier.extension:
case "dbf" | "cpg" | "prj" | "shx" | "shp":
resultat.implication = "Necessaire"
case "qix" | "qmd" | "qml":
resultat.implication = "Auxiliaire"
case "qpkg" | "sqlite":
resultat.implication = "Non-conforme"
case _:
resultat.implication = "A-ignorer"
return resultat
# DEBUT DU PROGRAMME
@ -151,7 +285,7 @@ liste = [] # - une liste des fichiers list _Fichier
dico = {} # - un dictionnaire des projets avec pour clé le nom de chaque projet
# dico de paire string : Entité Projet
racine = os.getcwd() # - un chemin absolue vers le repertoire racine à traiter string
print(racine)
print("Racine : ".center(18), racine)
@ -159,7 +293,7 @@ print(racine)
# Si il y a PAS un dossier de traitement dans le working directory Alors
pas_de_dossier = True
for a in os.scandir("./"):
for a in os.scandir():
if a.is_dir():
#il y a un dossier
pas_de_dossier = False
@ -175,64 +309,84 @@ else:
# --analyser le dossier
# initialiser une liste de _Fichiers
liste = []
liste = []
# Pour Chaque fichier des dossiers et sous dossiers à explorer Faire
for dossier_courant, list_dossiers, list_fichiers in os.walk(racine):
for dossier_courant, list_sousdossiers, list_fichiers in os.walk(racine): ##TODO voir la fonction fwalk qui renvoie un 4-tuple(dirpath, dirnames, filenames, dirfd), and it supports dir_fd
for fichier_courant in list_fichiers:
# --lire, analyser chaque fichier et peupler la liste
# initialiser un _Fichier
ce_Fichier = _Fichier()
# lire son chemin
ce_Fichier.chemin = fichier_courant
ce_Fichier.chemin = dossier_courant + "\\" + fichier_courant
# déterminer son nom original et son extension
# lire le nom original
# lire son extension
ce_Fichier.nom_original, ce_Fichier.extension = ce_Fichier.chemin.split(".")
ce_Fichier.nom_original, ce_Fichier.extension = fichier_courant.split(".")
# formatter et écrire le nom
ce_Fichier.nom = formatter(ce_Fichier.nom_original)
# déterminer son implication
ce_Fichier = impliquer(ce_Fichier) # TODO impliquer(), A VOIR si je peux passer juste l'implicatin et non l'ojbet en entier
ce_Fichier.impliquer()
# ajouter le _Fichier à la liste
liste.append(ce_Fichier)
# Fin Pour
# /* Ici la liste des _Fichiers doit être correctement remplie */
#TEST affichage de la liste de fichier
for a in liste:
a.afficher()
print("\n\n")
os.system("pause")
# initialiser un dictionnaire de _Projets avec comme clé leurs noms respectifs
print("Init Dico\n")
dico = {}
# Pour Chaque fichier de la liste Faire
for fichier_courant in liste:
if fichier_courant.implication not in "A-ignorer":
# --associer le fichier courant à un projet du dictionnaire
# /* Vérifier que le projet existe déjà dans le dico */
# Si le nom du fichier courant n'est pas dans le dico Alors
if fichier_courant.nom not in dico:
# initialiser un _Projet
projet = _Projet()
projet.necessaires = {}
projet.auxiliaires = {}
projet.non_conformes = {}
projet.nom = fichier_courant.nom
print("création clé : ", projet.nom)
# ajouter le nom comme clé dans le dictionnaire
# associer le projet à cette clé
dico[projet.nom] = projet
#test contenu du dico
# Fin Si
# cataloguer le fichier dans le projet concerné
projet.cataloguer(fichier_courant)
# il y a un fichier de plus au projet
projet.nb_fichiers += 1
else:
# sinon le fichier est a ignorer
print("Ignoré : ".center(16), fichier_courant.nom_original)
# Fin Pour
# Pour Chaque projet du dictionnaire Faire
for projet in dico.values():
# --analyser et completer les infos du projet courant
# /* conformité, projection, encodage etc */
# lire la projection du projet courant
projet.lire_projection()
# lire l'encodage du projet courant
projet.lire_encodage()
# Si tous les fichiers nécessaires sont présents ET
# la projection est correcte ET
# l'encodage est correct Alors
# passer le projet à conforme
projet.valider()
# Fin Si
# Fin Pour
# /* Ici le dictionnaire des _Projets doit être correctement remplie */
os.system("pause")
# --produire le rapport
# créer un classeur Excel
# /* Note : peut être utiliser un modèle pré-config */