Ajout fonction test_remplir_visa
ajout differents tests
This commit is contained in:
parent
ef876b7a69
commit
a38d1ae453
399
banbou.py
399
banbou.py
@ -1,7 +1,7 @@
|
|||||||
## Script Banbou pour le prétraitement des données des dossiers de recollement
|
## Script Banbou pour le prétraitement des données des dossiers de recollement
|
||||||
## de fibre optique.
|
## de fibre optique.
|
||||||
|
|
||||||
import os, shutil, datetime
|
import os, shutil, datetime, openpyxl
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -240,6 +240,183 @@ def controller_projection(id_point, point_x, point_y):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def remplir_VISA(modele, projet):
|
||||||
|
"""
|
||||||
|
Complète le Visa du projet à partir d'un fichier modele.
|
||||||
|
|
||||||
|
Controle le nb de fichiers de chaque catégorie et notifie.
|
||||||
|
Parcours la liste de notifications du projet et ajoute chaque
|
||||||
|
notification dans la feuille concerné du classeur
|
||||||
|
A défaut, une notification de la liste qui n'a pas de catégorie
|
||||||
|
avec sa propre feuille sera ajoutée à la première feuille (FRONT)
|
||||||
|
|
||||||
|
Enregistre le Visa dans le repertoire de Travail
|
||||||
|
Contraintes :
|
||||||
|
- le modele du VISA soit être NÉCESSAIREMENT dans le même
|
||||||
|
dossier que le script. TODO : traité l'exception si fichier non trouvé
|
||||||
|
- le modele du VISA NE doit PAS avoir eu de modification notable
|
||||||
|
dans son design ( emplacements des cellules utilisées pour
|
||||||
|
notifier, nom des feuilles, etc)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Masques Binaires représentants les controles de chaques catégorie traitées
|
||||||
|
# les bits sont allumés à chaque position où un test existe
|
||||||
|
FAIL_CSV = 7 # Explication : il existe pour le moment 3 tests pour les CSVs donc : "0000 0000 0000 0111"
|
||||||
|
FAIL_DWG = 16 # un seul test pour les DWGs : "0000 0000 0001 0000"
|
||||||
|
FAIL_PDF = 256 # un seul test pour les PDFs : "0000 0001 0000 0000"
|
||||||
|
FAIL_INFO = 4096 # un seul test pour les fiches infos : "0001 0000 0000 0000"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# creation d'un workbook à partir d'un modele
|
||||||
|
classeur = openpyxl.load_workbook(modele)
|
||||||
|
|
||||||
|
|
||||||
|
## definition personnalisé vers chaque feuille du classeur
|
||||||
|
FRONT = wb[wb.sheetnames[0]]
|
||||||
|
PDF = wb[wb.sheetnames[1]]
|
||||||
|
CSV = wb[wb.sheetnames[2]]
|
||||||
|
DWG = wb[wb.sheetnames[3]]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# feuille = classeur.active
|
||||||
|
|
||||||
|
# cell = feuille["A2"]
|
||||||
|
# cell.value = "Dossier : "+ racine.name
|
||||||
|
|
||||||
|
## NOTE: cell est la cellule courante dans la feuille
|
||||||
|
## Ainsi cell = 'A1'
|
||||||
|
|
||||||
|
# Nom dossier
|
||||||
|
# Date de reception
|
||||||
|
# Date Visa
|
||||||
|
FRONT['C1'] = f'Analyse : {projet.nom}\nDate de réception :\nDate visa : {projet.date}'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: factoriser les instructions ci dessous --> faire une fonction
|
||||||
|
|
||||||
|
# FRONT DWG
|
||||||
|
# Je ne peux pas controler automatiquement la projection du DWG (c'est un binaire illisible hors de AutoCAD)
|
||||||
|
# J'ajoute automatiquement la mention comme dans le script précedent.
|
||||||
|
FRONT['C3'] = f"{projet.nb_dwgs} fichier(s) DWG présent(s).\nProjection de tous les fichiers DWG : RFG93-CC43 (EPSG:3943)."
|
||||||
|
|
||||||
|
# Controle le nb de fichiers DWG
|
||||||
|
if projet.nb_dwgs == 0:
|
||||||
|
projet.controles |= 2**4 # allume le bit 5ième bit
|
||||||
|
FRONT['C3'] = "Pas de fichier DWG présent."
|
||||||
|
|
||||||
|
# Regarde si des fails ont été détectés sur les DWGs
|
||||||
|
fail = projet.controles & FAIL_DWG # operation logique avec le masque
|
||||||
|
# notifie en consequence
|
||||||
|
if fail :
|
||||||
|
FRONT['B3'] = "FAIL"
|
||||||
|
FRONT['B3'].fill = PatternFill("solid", start_color="FF4343")
|
||||||
|
else :
|
||||||
|
FRONT['B3'] = "OK"
|
||||||
|
FRONT['B3'].fill = PatternFill("solid", start_color="52BE80") # ancien vert "68D000"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# FRONT PDF
|
||||||
|
FRONT['C4'] = f"{projet.nb_pdfs} fichier(s) PDF présent(s)."
|
||||||
|
|
||||||
|
# Controle le nb de fichiers PDF
|
||||||
|
if projet.nb_pdfs == 0:
|
||||||
|
projet.controles |= 2**8 # allume le 9ième bit
|
||||||
|
FRONT['C4'] = "Pas de fichier PDF présent."
|
||||||
|
|
||||||
|
# Regarde si des fails ont été détectés sur les PDFs
|
||||||
|
fail = projet.controles & FAIL_PDF
|
||||||
|
# notifie en consequence
|
||||||
|
if fail :
|
||||||
|
FRONT['B4'] = "FAIL"
|
||||||
|
FRONT['B4'].fill = PatternFill("solid", start_color="FF4343")
|
||||||
|
else :
|
||||||
|
FRONT['B4'] = "OK"
|
||||||
|
FRONT['B4'].fill = PatternFill("solid", start_color="52BE80")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# FRONT CSV
|
||||||
|
FRONT['C5'] = f"{projet.nb_points} point(s) en RFG93-CC43 (EPSG:3943)."
|
||||||
|
|
||||||
|
# Controle le nb de fichiers CSV
|
||||||
|
if projet.nb_csvs == 0:
|
||||||
|
projet.controles |= 2**0 # allume le 1er bit
|
||||||
|
FRONT['C5'] = "Pas de fichier CSV présent."
|
||||||
|
|
||||||
|
# Regarde si des fails ont été détectés sur les CSVs
|
||||||
|
fail = projet.controles & FAIL_CSV
|
||||||
|
# notifie en consequence
|
||||||
|
if fail :
|
||||||
|
FRONT['B5'] = "FAIL"
|
||||||
|
FRONT['B5'].fill = PatternFill("solid", start_color="FF4343")
|
||||||
|
else :
|
||||||
|
FRONT['B5'] = "OK"
|
||||||
|
FRONT['B5'].fill = PatternFill("solid", start_color="52BE80")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# FRONT FICHE INFO TOPOLOGIE
|
||||||
|
FRONT['C6'] = f"{projet.nb_releves} fiche(s) Info. présente(s)."
|
||||||
|
|
||||||
|
# Controle le nb de fichiers Fiche Topologique
|
||||||
|
if projet.nb_releves == 0:
|
||||||
|
projet.controles |= 2**12 # allume le 13ième bit
|
||||||
|
FRONT['C6'] = "Pas de fiche d'Info. Topologie présente."
|
||||||
|
|
||||||
|
# Regarde si des fails ont été détectés sur les CSVs
|
||||||
|
fail = projet.controles & FAIL_CSV
|
||||||
|
# notifie en consequence
|
||||||
|
if fail :
|
||||||
|
FRONT['B6'] = "FAIL"
|
||||||
|
FRONT['B6'].fill = PatternFill("solid", start_color="FF4343")
|
||||||
|
else :
|
||||||
|
FRONT['B6'] = "OK"
|
||||||
|
FRONT['B6'].fill = PatternFill("solid", start_color="52BE80")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Notifier dans les autres Feuilles
|
||||||
|
|
||||||
|
# lignes en cours à remplir pour chaque feuille
|
||||||
|
# initialisé aux lignes où on va commencer à notifier
|
||||||
|
A = 2 # "B2" # Pour la feuille PDF
|
||||||
|
B = 2 # "B2" # Pour la feuille CSV
|
||||||
|
C = 2 # "B2" # Pour la feuille DWG
|
||||||
|
D = 11 # "C11" # Pour la feuille FRONT
|
||||||
|
|
||||||
|
cell = "" # cellule courante qui va être notifier
|
||||||
|
|
||||||
|
for notif in projet.notifs :
|
||||||
|
match notif.categorie :
|
||||||
|
case "PDF" :
|
||||||
|
cell = PDF["B"+str(A)]
|
||||||
|
A += 1
|
||||||
|
case "CSV" :
|
||||||
|
cell = CSV["B"+str(B)]
|
||||||
|
B += 1
|
||||||
|
case "DWG" :
|
||||||
|
cell = DWG["B"+ str(C)]
|
||||||
|
C += 1
|
||||||
|
case _:
|
||||||
|
cell = FRONT["C"+str(D)]
|
||||||
|
D += 1
|
||||||
|
|
||||||
|
cell.value = notif.texte
|
||||||
|
|
||||||
|
|
||||||
|
# Ici le VISA doit être correctement rempli
|
||||||
|
# on sauvegarde dans un fichier le classeur
|
||||||
|
classeur.save(f"Travail\\{projet.nom}_VISA.xlsx")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -261,7 +438,7 @@ class _Fichier:
|
|||||||
self.extension = extension # - son extension
|
self.extension = extension # - son extension
|
||||||
self.nom = nom # - son nom formaté
|
self.nom = nom # - son nom formaté
|
||||||
self.implication = implication # - son implication dans le projet
|
self.implication = implication # - son implication dans le projet
|
||||||
self.taille = taille
|
self.taille = taille # taille en octets
|
||||||
|
|
||||||
|
|
||||||
def afficher(self):
|
def afficher(self):
|
||||||
@ -291,6 +468,8 @@ class _Fichier:
|
|||||||
ce_Fichier.chemin = dossier + "\\" + fichier
|
ce_Fichier.chemin = dossier + "\\" + fichier
|
||||||
# déterminer son nom original et son extension
|
# déterminer son nom original et son extension
|
||||||
ce_Fichier.nom_original, ce_Fichier.extension = fichier.split(".", maxsplit=1) # maxsplit permet de spliter qu'une fois au cas ou on a plusieurs . dans le nom de fichier)
|
ce_Fichier.nom_original, ce_Fichier.extension = fichier.split(".", maxsplit=1) # maxsplit permet de spliter qu'une fois au cas ou on a plusieurs . dans le nom de fichier)
|
||||||
|
# lettrer les extensions en minuscule
|
||||||
|
ce_Fichier.extension = ce_Fichier.extension.casefold()
|
||||||
# formatter et écrire le nom
|
# formatter et écrire le nom
|
||||||
ce_Fichier.nom = formatter(ce_Fichier.nom_original)
|
ce_Fichier.nom = formatter(ce_Fichier.nom_original)
|
||||||
# déterminer son implication
|
# déterminer son implication
|
||||||
@ -333,10 +512,13 @@ class _Projet:
|
|||||||
rapport="Pas de fichier",
|
rapport="Pas de fichier",
|
||||||
nb_shemas=0,
|
nb_shemas=0,
|
||||||
nb_releves=0,
|
nb_releves=0,
|
||||||
nb_csv=0,
|
nb_csvs=0,
|
||||||
|
points=[],
|
||||||
|
nb_points=0,
|
||||||
nb_dwgs=0,
|
nb_dwgs=0,
|
||||||
nb_points = 0,
|
nb_pdfs=0,
|
||||||
notifs=[]):
|
notifs=[],
|
||||||
|
controles=0):
|
||||||
self.nom = nom # nom du projet
|
self.nom = nom # nom du projet
|
||||||
self.date = date # date du traitement
|
self.date = date # date du traitement
|
||||||
self.racine = racine # chemin racine du projet
|
self.racine = racine # chemin racine du projet
|
||||||
@ -346,11 +528,13 @@ class _Projet:
|
|||||||
self.rapport = rapport # chemin vers le visa
|
self.rapport = rapport # chemin vers le visa
|
||||||
self.nb_shemas = nb_shemas # nb de plans de la mise en place
|
self.nb_shemas = nb_shemas # nb de plans de la mise en place
|
||||||
self.nb_releves = nb_releves # nb de rapports de relevés topo
|
self.nb_releves = nb_releves # nb de rapports de relevés topo
|
||||||
self.nb_csv = nb_csv # nb de fichiers CSV
|
self.nb_csvs = nb_csvs # nb de fichiers CSV
|
||||||
|
self.points = points # liste des points du CSV
|
||||||
|
self.nb_points = nb_points # nb de points des CSVs TODO: REDONDANT avec len(points)
|
||||||
self.nb_dwgs = nb_dwgs # nb de fichiers DWG
|
self.nb_dwgs = nb_dwgs # nb de fichiers DWG
|
||||||
self.nb_pdfs = nb_pdfs # nb de fichiers PDF
|
self.nb_pdfs = nb_pdfs # nb de fichiers PDF
|
||||||
self.nb_points = nb_points # nb de points des CSVs
|
|
||||||
self.notifs = notifs # liste contenant les notifs du VISA
|
self.notifs = notifs # liste contenant les notifs du VISA
|
||||||
|
self.controles = controles # variable drapeau contenant toutes les validations de controles (voir Document pour plus d'info sur sa représentation)
|
||||||
|
|
||||||
|
|
||||||
def enraciner(self):
|
def enraciner(self):
|
||||||
@ -394,9 +578,11 @@ class _Projet:
|
|||||||
|
|
||||||
def nommer(self):
|
def nommer(self):
|
||||||
"""
|
"""
|
||||||
met à jour l'attribut 'nom' en composant un nom.
|
Met à jour l'attribut 'nom' en composant un nom.
|
||||||
|
|
||||||
Le nom est constitué du nom du dossier racine et de la date
|
Le nom est constitué du nom du dossier racine et de la date
|
||||||
courante formatté.
|
courante formatté.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.nom = f"{os.path.basename(os.getcwd())}_{self.date}"
|
self.nom = f"{os.path.basename(os.getcwd())}_{self.date}"
|
||||||
|
|
||||||
@ -426,6 +612,7 @@ class _Projet:
|
|||||||
for fichier in self.fichiers:
|
for fichier in self.fichiers:
|
||||||
source = fichier.chemin
|
source = fichier.chemin
|
||||||
print(f"\nsource : {source}")
|
print(f"\nsource : {source}")
|
||||||
|
|
||||||
# lors du peuplement préfixer et suffixer les noms des fichiers concernés comme suit : "Plan_nomfichierdwg.dwg" et "Point_nomfichiercsv_IN.csv"
|
# lors du peuplement préfixer et suffixer les noms des fichiers concernés comme suit : "Plan_nomfichierdwg.dwg" et "Point_nomfichiercsv_IN.csv"
|
||||||
# Confirmation par Audrey qu'il n'y a nécessairement qu'un fichier CSV par projet --> Le script s'occupe de le renommer.
|
# Confirmation par Audrey qu'il n'y a nécessairement qu'un fichier CSV par projet --> Le script s'occupe de le renommer.
|
||||||
# Mais parfois il peut y avoir plusieurs DWGs dont un seul est utile --> PASS -- Je laisse l'opérateur choisir lequel utiliser et le renommer manuellement.
|
# Mais parfois il peut y avoir plusieurs DWGs dont un seul est utile --> PASS -- Je laisse l'opérateur choisir lequel utiliser et le renommer manuellement.
|
||||||
@ -433,6 +620,10 @@ class _Projet:
|
|||||||
case "csv":
|
case "csv":
|
||||||
dest = self.racine + "\\" + travail + "\\" + "Point_" + fichier.nom + "_IN" + "." + fichier.extension
|
dest = self.racine + "\\" + travail + "\\" + "Point_" + fichier.nom + "_IN" + "." + fichier.extension
|
||||||
|
|
||||||
|
|
||||||
|
case "dwg":
|
||||||
|
dest = self.racine + "\\" + travail + "\\" + "Plan_" + fichier.nom + "." + fichier.extension
|
||||||
|
|
||||||
case _:
|
case _:
|
||||||
dest = self.racine + "\\" + travail + "\\" + fichier.nom + "." + fichier.extension
|
dest = self.racine + "\\" + travail + "\\" + fichier.nom + "." + fichier.extension
|
||||||
|
|
||||||
@ -445,70 +636,136 @@ class _Projet:
|
|||||||
print(f"\nLe fichier {fichier.nom + fichier.extension} existe déjà.")
|
print(f"\nLe fichier {fichier.nom + fichier.extension} existe déjà.")
|
||||||
#TODO :
|
#TODO :
|
||||||
# Confirmation par Audrey qu'il n'y a necessairement qu'un fichier CSV par projet --> On peut le renommer.
|
# Confirmation par Audrey qu'il n'y a necessairement qu'un fichier CSV par projet --> On peut le renommer.
|
||||||
# Mais parfois il peut y avoir plusieurs DWGs dont un seul est utile --> PASS -- Je laisse l'opérateur choisir lequel utiliser et le renommer manuellement.
|
# Mais parfois il peut y avoir plusieurs DWGs dont un seul est utile --> PASS -- Je laisse l'opérateur choisir lequel utiliser et le renommer manuellement. EDIT : Nathalie prefere que tous les fichier DWG soient préfixé avec Plan_
|
||||||
#TODO : verifier aussi la longueur des noms de fichiers. Notifier si nécessaire
|
#TODO : verifier aussi la longueur des noms de fichiers. Notifier si nécessaire
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def formatter_vers_ArcGIS(self, fichier):
|
def formatter_vers_ArcGIS(self, fichier_entree, fichier_sortie):
|
||||||
"""
|
"""
|
||||||
Lit et formatte un fichier CSV pour son importation dans ArcGIS.
|
Lit et formatte un fichier CSV pour son importation dans ArcGIS.
|
||||||
|
|
||||||
Lit la 1ère ligne et s'assure de la présence des titres de colonnes,
|
Lit la 1ère ligne et s'assure de la présence des titres de colonnes,
|
||||||
formatte cette 1ère ligne, supprime les lignes vides puis change le séparateur d'élements en
|
formatte cette 1ère ligne.
|
||||||
',' -- séparateur adapté pour ArcGIS --
|
Supprime les lignes vides.
|
||||||
|
Change le séparateur décimal ',' en '.' (necessaire car sinon je ne peux convertir les strings en float)
|
||||||
Notifie si nécessaire les points de controles qui ne passent pas.
|
Notifie si nécessaire les points de controles qui ne passent pas.
|
||||||
Renomme le fichier formatté en "Point_fichier_IN.csv"
|
Met à jour l'attribut nb_points
|
||||||
Contraintes :
|
Contraintes :
|
||||||
- Le fichier CSV NÉCESSITE des ';' comme séparateur d'élements.
|
- Le fichier CSV NÉCESSITE des ';' comme séparateur d'élements. (Normalement c'est toujours le cas de toutes façon)
|
||||||
- Le fichier doit avoir exactement 5 colonnes.
|
- Le fichier doit avoir exactement 5 colonnes. TODO : vois si plus de souplesse avec le catchage de paramètres restants
|
||||||
param user_input: nom complet d'un fichier csv
|
param user_input: nom complet d'un fichier csv
|
||||||
return: Le nombre de points du csv
|
|
||||||
"""
|
"""
|
||||||
# titres des colonnes correctement formattés.
|
# titres des colonnes correctement formattés.
|
||||||
titres = "id_point;TYPE;X;Y;Z"
|
titres = "id_point;TYPE;X;Y;Z\n"
|
||||||
|
|
||||||
# On va traiter ligne par ligne le fichier, puis cette ligne sera ajouté
|
sortie = [titres] # le fichier de sortie ( representé comme une liste de lignes ) contient un premiere ligne de titre
|
||||||
# a une liste. Finalement, on écrasera chaque ligne du fichier avec cette liste
|
|
||||||
df = open(fichier)
|
|
||||||
sortie = []
|
|
||||||
|
|
||||||
# analyser la premier ligne et formatter cette ligne
|
|
||||||
|
df = open(fichier_entree, "r")
|
||||||
ligne = df.readline()
|
ligne = df.readline()
|
||||||
|
|
||||||
|
# analyser la premiere ligne et formatter cette ligne
|
||||||
# Si le premier mot est un nombre Alors il manque les titres, dans
|
# Si le premier mot est un nombre Alors il manque les titres, dans
|
||||||
# ce cas insérer une ligne.
|
# ce cas insérer une ligne.
|
||||||
mots = ligne.split(sep=";", maxsplit=1)
|
mots = ligne.split(sep=";", maxsplit=1)
|
||||||
if mots[0].isalpha():
|
print(f"Mots[0] = {mots[0]}")
|
||||||
|
|
||||||
|
|
||||||
|
if mots[0].isnumeric():
|
||||||
#insérer ligne
|
#insérer ligne
|
||||||
sortie.append(titres)
|
|
||||||
else:
|
|
||||||
sortie.append(ligne)
|
sortie.append(ligne)
|
||||||
|
self.nb_points += 1
|
||||||
|
|
||||||
# la tête de lecture du descripteur de fichier ne reset pas sa position
|
# la tête de lecture du descripteur de fichier ne reset pas sa position
|
||||||
# donc on peut continuer le parcours des lignes directement
|
# donc on peut continuer le parcours des lignes directement
|
||||||
for ligne_courante in df :
|
for ligne_courante in df :
|
||||||
# enlever les espaces
|
|
||||||
ligne_courante = ligne_courante.replace(" ", "")
|
|
||||||
# si la ligne n'est pas vides alors
|
|
||||||
# TODO : changer le match en if ligne_courante not in ["", ";;;;"]:
|
|
||||||
match ligne_courante:
|
|
||||||
case "" | ";;;;":
|
|
||||||
pass
|
|
||||||
case _:
|
|
||||||
# controler la projection de ce point
|
|
||||||
id_point, type_, point_x, point_y, *autres = ligne_courante.split(sep=";")
|
|
||||||
projection = controller_projection(id_point, float(point_x), float(point_y))
|
|
||||||
#TODO: notifier si pas bonne projection
|
|
||||||
|
|
||||||
# puis ajouter la ligne a la liste
|
courant = self.lire_ligne(ligne_courante)
|
||||||
sortie.append(ligne_courante)
|
sortie.append(courant)
|
||||||
# compter ce point
|
# compter ce point
|
||||||
|
if courant not in "":
|
||||||
self.nb_points += 1
|
self.nb_points += 1
|
||||||
|
|
||||||
df.close()
|
df.close()
|
||||||
|
|
||||||
# je reouvre le descripteur en mode w only pour ecrire le fichier
|
# je reouvre le descripteur en mode w only pour ecrire le fichier
|
||||||
|
df = open(fichier_sortie, "w")
|
||||||
|
# écriture
|
||||||
|
for ligne in sortie:
|
||||||
|
print(f"{ligne}")
|
||||||
|
df.write(ligne) # NOTE: write()
|
||||||
|
|
||||||
df
|
df.close()
|
||||||
|
|
||||||
|
|
||||||
|
def lire_ligne(self, ligne):
|
||||||
|
"""
|
||||||
|
Analyse une chaine de caractère (concrètement, une ligne du CSV)/
|
||||||
|
|
||||||
|
remplace les séparateurs décimaux ',' par '.'
|
||||||
|
Notifie si nécessaire les points de controles qui ne passent pas.
|
||||||
|
Met à jour l'attribut nb_points
|
||||||
|
Met à jour la variable de controles
|
||||||
|
Contraintes :
|
||||||
|
- Le fichier CSV NÉCESSITE des ';' comme séparateur d'élements.
|
||||||
|
:return: une chaine de carac formatté pour ArcGIS
|
||||||
|
"""
|
||||||
|
print(f'ligne : "{ligne}"')
|
||||||
|
# enlever les espaces
|
||||||
|
ligne = ligne.replace(" ", "")
|
||||||
|
ligne = ligne.replace(",", ".")
|
||||||
|
# si la ligne n'est pas vides alors
|
||||||
|
# TODO : changer le match en if ligne not in ["", ";;;;"]:
|
||||||
|
match ligne:
|
||||||
|
case "" | ";;;;" |";;;;\n"| ";;;" | ";;;\n" | "\n":
|
||||||
|
ligne = ""
|
||||||
|
case _:
|
||||||
|
# controler la projection de ce point
|
||||||
|
id_point, type_, point_x, point_y, point_z, *autres = ligne.split(sep=";")
|
||||||
|
print(f"Typage point X : {type(point_x)}")
|
||||||
|
|
||||||
|
#PRINT de controle
|
||||||
|
print(f"ID:{id_point}, TYPE:{type_}, X:{point_x}, Y:{point_y}, Z:{point_z}, *autres={autres}")
|
||||||
|
|
||||||
|
projection = controller_projection(id_point, float(point_x), float(point_y))
|
||||||
|
# notifier si pas bonne projection
|
||||||
|
if projection in "Mauvaise projection":
|
||||||
|
incident = _Notification("CSV", f"Point ID {id_point} : Mauvaise projection")
|
||||||
|
self.notifs.append(incident)
|
||||||
|
self.controles |= 2**2
|
||||||
|
|
||||||
|
return ligne
|
||||||
|
# TODO: afficher dans la sortie standard le point
|
||||||
|
|
||||||
|
|
||||||
|
def controler_longueur_noms(self):
|
||||||
|
"""
|
||||||
|
controle la longueur des noms des fichiers du projet.
|
||||||
|
|
||||||
|
Notifie si necessaire les noms trop longs
|
||||||
|
"""
|
||||||
|
for fichier in self.fichiers:
|
||||||
|
match fichier.extension:
|
||||||
|
case "dwg":
|
||||||
|
if len(fichier.nom) > 30 :
|
||||||
|
self.notifier("DWG", f'"{fichier.nom}" : Nom trop long.')
|
||||||
|
case "csv" :
|
||||||
|
if len(fichier.nom) > 45 :
|
||||||
|
self.notifier("CSV", f'"{fichier.nom}" : Nom trop long.')
|
||||||
|
case "pdf" :
|
||||||
|
if len(fichier.nom) > 45 :
|
||||||
|
self.notifier("PDF", f'"{fichier.nom}" : Nom trop long.')
|
||||||
|
case _:
|
||||||
|
if len(fichier.nom) > 45 :
|
||||||
|
self.notifier("FRONT", f'"{fichier.nom}" : Nom trop long.')
|
||||||
|
|
||||||
|
def notifier(self, categorie, texte):
|
||||||
|
"""
|
||||||
|
Ajoute une notification au _Projet
|
||||||
|
"""
|
||||||
|
incident = _Notification( categorie, texte)
|
||||||
|
self.notifs.append(incident)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -519,50 +776,50 @@ class _Notification:
|
|||||||
def __init__(self,
|
def __init__(self,
|
||||||
categorie="Pas de catégorie",
|
categorie="Pas de catégorie",
|
||||||
texte="Pas de texte"):
|
texte="Pas de texte"):
|
||||||
self.categorie = categorie
|
self.categorie = categorie # vu comme une énumération de l'ensemble {"CSV", "DWG", "PDF", "FRONT"} seule ces valeurs sont donc possible et traité par le script
|
||||||
self.texte = texte
|
self.texte = texte
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------------- #
|
# # -------------------------------------------------------------------------- #
|
||||||
# -------------------------------------------------------------------------- #
|
# # -------------------------------------------------------------------------- #
|
||||||
# MAIN
|
# # MAIN
|
||||||
|
|
||||||
racine = os.getcwd()
|
# racine = os.getcwd()
|
||||||
print("\nRépertoire courant : ".center(18), racine)
|
# print("\nRépertoire courant : ".center(18), racine)
|
||||||
|
|
||||||
# --recupérer le chemin du dossier à traiter
|
# # --recupérer le chemin du dossier à traiter
|
||||||
pas_de_dossier = True
|
# pas_de_dossier = True
|
||||||
|
|
||||||
for a in os.scandir():
|
# for a in os.scandir():
|
||||||
print("\ncourant scandir() = ", a.name.ljust(25), " ", a.is_dir())
|
# print("\ncourant scandir() = ", a.name.ljust(25), " ", a.is_dir())
|
||||||
if a.is_dir():
|
# if a.is_dir():
|
||||||
#il y a un dossier
|
# #il y a un dossier
|
||||||
pas_de_dossier = False
|
# pas_de_dossier = False
|
||||||
print(f"\nDossier à Traiter trouvé : {a.name}")
|
# print(f"\nDossier à Traiter trouvé : {a.name}")
|
||||||
racine = a
|
# racine = a
|
||||||
|
|
||||||
if pas_de_dossier:
|
# if pas_de_dossier:
|
||||||
print("\nPas de dossier trouvé...\nFin de programme.\n")
|
# print("\nPas de dossier trouvé...\nFin de programme.\n")
|
||||||
os.system("pause")
|
# os.system("pause")
|
||||||
exit()
|
# exit()
|
||||||
|
|
||||||
# Création entité projet et maj de ses attributs
|
# # Création entité projet et maj de ses attributs
|
||||||
projet = _Projet()
|
# projet = _Projet()
|
||||||
|
|
||||||
projet.dater()
|
# projet.dater()
|
||||||
|
|
||||||
projet.nommer()
|
# projet.nommer()
|
||||||
# controle de la longueur du nom du projet
|
# # controle de la longueur du nom du projet
|
||||||
if len(projet.nom) >=46 :
|
# if len(projet.nom) >=46 :
|
||||||
print(f"\n{projet.nom} est un nom de dossier trop long (+ de 46 caractères). Veuillez raccourcir son nom\nFin de programme.\n")
|
# print(f"\n{projet.nom} est un nom de dossier trop long (+ de 46 caractères). Veuillez raccourcir son nom\nFin de programme.\n")
|
||||||
os.system("pause")
|
# os.system("pause")
|
||||||
exit()
|
# exit()
|
||||||
|
|
||||||
projet.enraciner()
|
# projet.enraciner()
|
||||||
|
|
||||||
projet.rapport = f"{racine}\\Visa_lot_2.xlsx"
|
# projet.rapport = f"{racine}\\Visa_lot_2.xlsx"
|
||||||
|
|
||||||
projet.fichiers = creer_liste(projet.racine)
|
# projet.fichiers = creer_liste(projet.racine)
|
||||||
|
|
||||||
|
|||||||
10
test/JEUXDONNEES/dossier01/fichier01_ENTREE.csv
Normal file
10
test/JEUXDONNEES/dossier01/fichier01_ENTREE.csv
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
ID_POINTS;Type;x;a;w
|
||||||
|
1007;TACE;1604957.07;2169690.34;715.80
|
||||||
|
1008;TEIC;1604959.44;2169692.70;716.01
|
||||||
|
1009;TEIC;1604960.25;2169693.85;716.07
|
||||||
|
1010;TEIC;1604959.70;2169694.24;715.99
|
||||||
|
1011;TEIC;1604958.87;2169693.10;715.94
|
||||||
|
1012;TACC;1604959.57;2169693.47;715.94
|
||||||
|
1014;RCIC;1604957.15;2169690.71;715.39
|
||||||
|
1016;RCCC;1604958.09;2169691.76;715.58
|
||||||
|
1018;RCIC;1604959.06;2169692.91;715.58
|
||||||
|
9
test/JEUXDONNEES/dossier01/fichier02_ENTREE.csv
Normal file
9
test/JEUXDONNEES/dossier01/fichier02_ENTREE.csv
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
1007;TACE;1604957.07;2169690.34;715.80
|
||||||
|
1008;TEIC;1604959.44;2169692.70;716.01
|
||||||
|
1009;TEIC;1604960.25;2169693.85;716.07
|
||||||
|
1010;TEIC;1604959.70;2169694.24;715.99
|
||||||
|
1011;TEIC;1604958.87;2169693.10;715.94
|
||||||
|
1012;TACC;1604959.57;2169693.47;715.94
|
||||||
|
1014;RCIC;1604957.15;2169690.71;715.39
|
||||||
|
1016;RCCC;1604958.09;2169691.76;715.58
|
||||||
|
1018;RCIC;1604959.06;2169692.91;715.58
|
||||||
|
21
test/JEUXDONNEES/dossier01/fichier03_ENTREE.csv
Normal file
21
test/JEUXDONNEES/dossier01/fichier03_ENTREE.csv
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
id_point;TYPE;X;Y;Z
|
||||||
|
|
||||||
|
1007;TACE;1604957.07;2169690.34;715.80
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1008;TEIC;1604959.44;2169692.70;716.01
|
||||||
|
1009;TEIC;1604960.25;2169693.85;716.07
|
||||||
|
1010;TEIC;1604959.70;2169694.24;715.99
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;;;;
|
||||||
|
;;;
|
||||||
|
1011;TEIC;1604958.87;2169693.10;715.94
|
||||||
|
1012;TACC;1604959.57;2169693.47;715.94
|
||||||
|
1014;RCIC;1604957.15;2169690.71;715.39
|
||||||
|
1016;RCCC;1604958.09;2169691.76;715.58
|
||||||
|
1018;RCIC;1604959.06;2169692.91;715.58
|
||||||
|
;;;
|
||||||
|
Can't render this file because it has a wrong number of fields in line 15.
|
18
test/JEUXDONNEES/dossier01/fichier04_ENTREE.csv
Normal file
18
test/JEUXDONNEES/dossier01/fichier04_ENTREE.csv
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
id_point;TYPE;X;Y;Z
|
||||||
|
1001;TEIC;1585702.06;2185080.612;466.282
|
||||||
|
1002;TEIC;1585702.468;2185080.582;466.41
|
||||||
|
1003;TEIC;1585702.586;2185081.047;466.6
|
||||||
|
1004;TACC;1585702.456;2185080.899;466.892
|
||||||
|
1005;RCIC;1585702.4207;2185081.2221;466.884
|
||||||
|
1006;RCCC;1585702.459;2185081.647;466.878
|
||||||
|
1007;RCIC;1585702.451;2185081.735;466.876
|
||||||
|
1008;RCCC;1585702.365;2185081.808;466.896
|
||||||
|
1009;RCIC;1585701.73;2185082.136;466.91
|
||||||
|
1010;RCCC;1585700.807;2185082.299;466.931
|
||||||
|
1011;RCIC;1585700.563;2185082.289;466.945
|
||||||
|
1012;RCCC;1585700.363;2185082.184;466.956
|
||||||
|
1013;RCIC;1585700.192;2185081.784;466.938
|
||||||
|
1014;TACE;1585700.012;2185081.135;467.347
|
||||||
|
1015;TEIE;1585699.952;2185081.673;466.758
|
||||||
|
1016;TEIE;1585699.725;2185080.689;466.741
|
||||||
|
1017;TEIE;1585700;2185080.592;466.733
|
||||||
|
1119
test/JEUXDONNEES/dossier01/fichier05_ENTREE.csv
Normal file
1119
test/JEUXDONNEES/dossier01/fichier05_ENTREE.csv
Normal file
File diff suppressed because it is too large
Load Diff
18
test/JEUXDONNEES/dossier01/fichier06_ENTREE.csv
Normal file
18
test/JEUXDONNEES/dossier01/fichier06_ENTREE.csv
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
id_point;TYPE;X;Y;Z
|
||||||
|
1001;TEIC;1585702,06;2185080,612;466,282
|
||||||
|
1002;TEIC;1585702,468;2185080,582;466,41
|
||||||
|
1003;TEIC;1585702,586;2185081,047;466,6
|
||||||
|
1004;TACC;1585702,456;2185080,899;466,892
|
||||||
|
1005;RCIC;1585702,4207;2185081,2221;466,884
|
||||||
|
1006;RCCC;1585702,459;2185081,647;466,878
|
||||||
|
1007;RCIC;1585702,451;2185081,735;466,876
|
||||||
|
1008;RCCC;1585702,365;2185081,808;466,896
|
||||||
|
1009;RCIC;1585701,73;2185082,136;466,91
|
||||||
|
1010;RCCC;1585700,807;2185082,299;466,931
|
||||||
|
1011;RCIC;1585700,563;2185082,289;466,945
|
||||||
|
1012;RCCC;1585700,363;2185082,184;466,956
|
||||||
|
1013;RCIC;1585700,192;2185081,784;466,938
|
||||||
|
1014;TACE;1585700,012;2185081,135;467,347
|
||||||
|
1015;TEIE;1585699,952;2185081,673;466,758
|
||||||
|
1016;TEIE;1585699,725;2185080,689;466,741
|
||||||
|
1017;TEIE;1585700;2185080,592;466,733
|
||||||
|
BIN
test/JEUXDONNEES/dossier02/modele_visa.xlsx
Normal file
BIN
test/JEUXDONNEES/dossier02/modele_visa.xlsx
Normal file
Binary file not shown.
99
test/test_projet_formatter_vers_ArcGIS.py
Normal file
99
test/test_projet_formatter_vers_ArcGIS.py
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
from banbou import _Projet
|
||||||
|
import banbou
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# TODO : Faire une phase d'initialisation générale (un SetUp) de mes objets
|
||||||
|
# Puis une phase de Clean des fichiers créés.
|
||||||
|
|
||||||
|
# chaque test à son fichier CSV numeroté dans le dossier "dossier01"
|
||||||
|
|
||||||
|
# J'ai pas mocker les fichiers etc, j'ai donc mis en place un jeu de fichiers dédiés a ces tests
|
||||||
|
|
||||||
|
def test_formate_la_premiere_ligne(mocker):
|
||||||
|
|
||||||
|
sut = banbou._Projet()
|
||||||
|
sut.nb_points = 0
|
||||||
|
|
||||||
|
entree = r"C:\Users\David_Castex\Documents\DATAS\GITDAV\NEOBANBOU\test\JEUXDONNEES\dossier01\fichier01_ENTREE.csv"
|
||||||
|
sortie = r"C:\Users\David_Castex\Documents\DATAS\GITDAV\NEOBANBOU\test\JEUXDONNEES\dossier01\fichier01_SORTIE.csv"
|
||||||
|
|
||||||
|
sut.formatter_vers_ArcGIS(entree, sortie)
|
||||||
|
|
||||||
|
expected_value = 9
|
||||||
|
|
||||||
|
assert sut.nb_points == expected_value
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_ajoute_titres_manquants(mocker):
|
||||||
|
|
||||||
|
sut = banbou._Projet()
|
||||||
|
sut.nb_points = 0
|
||||||
|
|
||||||
|
entree = r"C:\Users\David_Castex\Documents\DATAS\GITDAV\NEOBANBOU\test\JEUXDONNEES\dossier01\fichier02_ENTREE.csv"
|
||||||
|
sortie = r"C:\Users\David_Castex\Documents\DATAS\GITDAV\NEOBANBOU\test\JEUXDONNEES\dossier01\fichier02_SORTIE.csv"
|
||||||
|
|
||||||
|
sut.formatter_vers_ArcGIS(entree, sortie)
|
||||||
|
|
||||||
|
expected_value = 9
|
||||||
|
|
||||||
|
assert sut.nb_points == expected_value
|
||||||
|
|
||||||
|
def test_supprime_lignes_vides(mocker):
|
||||||
|
|
||||||
|
sut = banbou._Projet()
|
||||||
|
sut.nb_points = 0
|
||||||
|
|
||||||
|
entree = r"C:\Users\David_Castex\Documents\DATAS\GITDAV\NEOBANBOU\test\JEUXDONNEES\dossier01\fichier03_ENTREE.csv"
|
||||||
|
sortie = r"C:\Users\David_Castex\Documents\DATAS\GITDAV\NEOBANBOU\test\JEUXDONNEES\dossier01\fichier03_SORTIE.csv"
|
||||||
|
|
||||||
|
sut.formatter_vers_ArcGIS(entree, sortie)
|
||||||
|
|
||||||
|
expected_value = 9
|
||||||
|
|
||||||
|
assert sut.nb_points == expected_value
|
||||||
|
|
||||||
|
def test_ajoute_correctement_les_points(mocker):
|
||||||
|
|
||||||
|
sut = banbou._Projet()
|
||||||
|
sut.nb_points = 0
|
||||||
|
|
||||||
|
entree = r"C:\Users\David_Castex\Documents\DATAS\GITDAV\NEOBANBOU\test\JEUXDONNEES\dossier01\fichier04_ENTREE.csv"
|
||||||
|
sortie = r"C:\Users\David_Castex\Documents\DATAS\GITDAV\NEOBANBOU\test\JEUXDONNEES\dossier01\fichier04_SORTIE.csv"
|
||||||
|
|
||||||
|
sut.formatter_vers_ArcGIS(entree, sortie)
|
||||||
|
|
||||||
|
expected_value = 17
|
||||||
|
|
||||||
|
assert sut.nb_points == expected_value
|
||||||
|
|
||||||
|
def test_ajoute_correctement_les_points_fichier_complexe(mocker):
|
||||||
|
|
||||||
|
sut = banbou._Projet()
|
||||||
|
sut.nb_points = 0
|
||||||
|
|
||||||
|
entree = r"C:\Users\David_Castex\Documents\DATAS\GITDAV\NEOBANBOU\test\JEUXDONNEES\dossier01\fichier05_ENTREE.csv"
|
||||||
|
sortie = r"C:\Users\David_Castex\Documents\DATAS\GITDAV\NEOBANBOU\test\JEUXDONNEES\dossier01\fichier05_SORTIE.csv"
|
||||||
|
|
||||||
|
sut.formatter_vers_ArcGIS(entree, sortie)
|
||||||
|
|
||||||
|
expected_value = 1118
|
||||||
|
|
||||||
|
assert sut.nb_points == expected_value
|
||||||
|
|
||||||
|
def test_fichier_avec_sep_decimal_virgule():
|
||||||
|
|
||||||
|
# NOTE: pas a traiter, car c'est transparent pour ArcGIS que le séparateur décimal soit une virgule ou un point.
|
||||||
|
# mais je fait passer quand même le test pour voir si
|
||||||
|
sut = banbou._Projet()
|
||||||
|
sut.nb_points = 0
|
||||||
|
|
||||||
|
entree = r"C:\Users\David_Castex\Documents\DATAS\GITDAV\NEOBANBOU\test\JEUXDONNEES\dossier01\fichier06_ENTREE.csv"
|
||||||
|
sortie = r"C:\Users\David_Castex\Documents\DATAS\GITDAV\NEOBANBOU\test\JEUXDONNEES\dossier01\fichier06_SORTIE.csv"
|
||||||
|
|
||||||
|
sut.formatter_vers_ArcGIS(entree, sortie)
|
||||||
|
|
||||||
|
expected_value = 17
|
||||||
|
|
||||||
|
assert sut.nb_points == expected_value
|
||||||
22
test/test_projet_notifier.py
Normal file
22
test/test_projet_notifier.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
from banbou import _Projet
|
||||||
|
import banbou
|
||||||
|
|
||||||
|
|
||||||
|
def test_notifier_correctement(mocker):
|
||||||
|
|
||||||
|
sut = _Projet()
|
||||||
|
|
||||||
|
sut.notifs = []
|
||||||
|
|
||||||
|
sut.notifier("CSV", "Incident de trop 01.")
|
||||||
|
sut.notifier("DWG", "Encore un incident 02.")
|
||||||
|
sut.notifier("FRONT", "Ce nom est pas correct 03.")
|
||||||
|
|
||||||
|
assert sut.notifs[0].categorie == "CSV"
|
||||||
|
assert sut.notifs[0].texte == "Incident de trop 01."
|
||||||
|
|
||||||
|
assert sut.notifs[1].categorie == "DWG"
|
||||||
|
assert sut.notifs[1].texte == "Encore un incident 02."
|
||||||
|
|
||||||
|
assert sut.notifs[2].categorie == "FRONT"
|
||||||
|
assert sut.notifs[2].texte == "Ce nom est pas correct 03."
|
||||||
@ -7,7 +7,7 @@ import banbou, os, shutil
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_doit_copier_les_fichiers_necessaires(mocker):
|
def test_ne_doit_copier_que_les_fichiers_necessaires(mocker):
|
||||||
|
|
||||||
dossier = r"C:\Users\David_Castex\Documents\DATAS\GITDAV\NEOBANBOU\test\JEUXDONNEES\DIS_AXR08_PT802161"
|
dossier = r"C:\Users\David_Castex\Documents\DATAS\GITDAV\NEOBANBOU\test\JEUXDONNEES\DIS_AXR08_PT802161"
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ def test_doit_copier_les_fichiers_necessaires(mocker):
|
|||||||
|
|
||||||
# valeurs attendues
|
# valeurs attendues
|
||||||
sous_dossier_attendue = [] # pas de sous dossier
|
sous_dossier_attendue = [] # pas de sous dossier
|
||||||
fichiers_attendues = ['DIS.pdf', 'DIS_AXR08_PT802161.dwg', 'DIS_AXR08_PT802161.pdf', 'Point_DIS_AXR08_PT802161_IN.csv']
|
fichiers_attendues = ['DIS.pdf', 'DIS_AXR08_PT802161.pdf', 'Plan_DIS_AXR08_PT802161.dwg', 'Point_DIS_AXR08_PT802161_IN.csv']
|
||||||
|
|
||||||
|
|
||||||
# Ici j'efface le dossier de "Travail" pour pas interférer avec les autres tests,
|
# Ici j'efface le dossier de "Travail" pour pas interférer avec les autres tests,
|
||||||
|
|||||||
27
test/test_remplir_visa.py
Normal file
27
test/test_remplir_visa.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
from banbou import remplir_VISA
|
||||||
|
import banbou
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_notifie_correctement_le_visa(mocker):
|
||||||
|
|
||||||
|
# donnée du projet utilisé
|
||||||
|
# projet.nom
|
||||||
|
# projet.date
|
||||||
|
# projet.nb_dwgs
|
||||||
|
# projet.controles
|
||||||
|
# projet.nb_pdfs
|
||||||
|
# projet.nb_csvs
|
||||||
|
# projet.nb_releves
|
||||||
|
# projet.notifs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
modele = r"C:\Users\David_Castex\Documents\DATAS\GITDAV\NEOBANBOU\test\JEUXDONNEES\dossier02\modele_visa.xlsx"
|
||||||
|
|
||||||
|
|
||||||
|
# ENCOURS
|
||||||
|
# remplir_VISA(modele, projet)
|
||||||
|
pass
|
||||||
Loading…
Reference in New Issue
Block a user