feat: ask and verify user inputs #1
@ -1,3 +1,6 @@
|
|||||||
|
"""
|
||||||
|
Module principal
|
||||||
|
"""
|
||||||
from dory_sort_out import sortout
|
from dory_sort_out import sortout
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|||||||
240
dory_sort_out.py
240
dory_sort_out.py
@ -1,68 +1,246 @@
|
|||||||
import time
|
"""
|
||||||
|
Sert a créer l'arborescence pour le dossier CNIG, renommer et ranger les .pdf
|
||||||
|
"""
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
from datetime import *
|
import glob
|
||||||
|
import shutil
|
||||||
|
from datetime import datetime
|
||||||
|
import openpyxl as xls
|
||||||
|
|
||||||
|
|
||||||
def testDate(date : str):
|
# Les noms de tous les dossier a créer
|
||||||
#Pattern pour vérifier qu'il y a bien 8 chiffres, 4pour l'année, 2 pour le mois, 2 pour le jour
|
FOLDERNAMES = [
|
||||||
#permet d'exclure les erreurs de frappes, comme les "." les " " ou les lettres
|
"0_Procedure",
|
||||||
pattern = r'^\d{4}\d{2}\d{2}$'
|
"1_Rapport_de_presentation",
|
||||||
|
"2_PADD",
|
||||||
|
"3_Reglement",
|
||||||
|
"4_Annexes",
|
||||||
|
"5_Orientations_amenagement",
|
||||||
|
"6_POA",
|
||||||
|
"7_Plans_de_secteur",
|
||||||
|
]
|
||||||
|
|
||||||
if re.match(pattern,date):
|
# Les mots clef associés à chaque dossier
|
||||||
|
KEYWORDS = {
|
||||||
|
"Jugement": FOLDERNAMES[0],
|
||||||
|
"Procedure": FOLDERNAMES[0],
|
||||||
|
"Rapport": FOLDERNAMES[1],
|
||||||
|
"PADD": FOLDERNAMES[2],
|
||||||
|
"Prescription": FOLDERNAMES[3],
|
||||||
|
"Reglement_graphique": FOLDERNAMES[3],
|
||||||
|
"Reglement": FOLDERNAMES[3],
|
||||||
|
"Orientations_amenagement": FOLDERNAMES[5],
|
||||||
|
"POA": FOLDERNAMES[6],
|
||||||
|
"Plan_de_secteur": FOLDERNAMES[7],
|
||||||
|
}
|
||||||
|
|
||||||
|
def test_date(date_input: str):
|
||||||
|
"""teste si la date donnée est valide"""
|
||||||
|
# Pattern pour vérifier qu'il y a bien 8 chiffres, 4pour l'année, 2 pour le mois, 2 pour le jour
|
||||||
|
# permet d'exclure les erreurs de frappes, comme les "." les " " ou les lettres
|
||||||
|
pattern = r"^\d{4}\d{2}\d{2}$"
|
||||||
|
|
||||||
|
if re.match(pattern, date_input):
|
||||||
try:
|
try:
|
||||||
datetime.strptime(date,"%Y%m%d")
|
datetime.strptime(date_input, "%Y%m%d")
|
||||||
return True
|
return True
|
||||||
except ValueError:
|
except ValueError:
|
||||||
print("Erreur dans le format de la date, veuillez la saisir comme suit AAAAMMJJ")
|
print(
|
||||||
|
"Erreur dans le format de la date, veuillez la saisir comme suit AAAAMMJJ"
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
else :
|
else:
|
||||||
print("Erreur de frappe, la date ne noit contenir que 8 chiffres")
|
print("Erreur de frappe, la date ne noit contenir que 8 chiffres")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def test_siren_insee(is_plu: bool, number: str):
|
||||||
def testSirenInsee(isPlu : bool, number : str):
|
"""teste si le numero Siren ou Insee donné est valide"""
|
||||||
if isPlu:
|
if is_plu:
|
||||||
if len(number) == 5 and number.isdigit():
|
if len(number) == 5 and number.isdigit():
|
||||||
return True
|
return True
|
||||||
else :
|
|
||||||
print("Le numero INSEE est invalide")
|
print("Le numero INSEE est invalide")
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
if len(number) == 9 and number.isdigit():
|
if len(number) == 9 and number.isdigit():
|
||||||
return True
|
return True
|
||||||
else :
|
|
||||||
print("Le numero siren est invalide")
|
|
||||||
return False
|
|
||||||
|
|
||||||
def sortout ():
|
print("Le numero siren est invalide")
|
||||||
isPlu = True
|
return False
|
||||||
|
|
||||||
#on demande si c'est un PLU ou un PLUi tant que la valeur de l'input ne correspond pas à ce que l'on attend
|
def create_folders(is_plu: bool, prefixe, suffixe):
|
||||||
|
"""Crée l'arborescence"""
|
||||||
|
main_path = prefixe + "_" + ("PLU" if is_plu else "PLUi") + "_" + suffixe
|
||||||
|
|
|||||||
|
|
||||||
|
try:
|
||||||
|
os.mkdir(main_path)
|
||||||
|
except FileExistsError:
|
||||||
|
print("Ce dossier suivant existe déjà : " + main_path)
|
||||||
|
return ""
|
||||||
|
|
||||||
|
os.mkdir(main_path + "/Donnees_geographiques")
|
||||||
|
os.mkdir(main_path + "/Pieces_ecrites")
|
||||||
|
main_path += "/Pieces_ecrites"
|
||||||
|
|
||||||
|
for folder_name in FOLDERNAMES:
|
||||||
|
try:
|
||||||
|
if (
|
||||||
|
not folder_name == "6_POA" and not folder_name == "7_Plans_de_secteur"
|
||||||
|
) or (
|
||||||
|
not is_plu
|
||||||
|
and (folder_name == "6_POA" or folder_name == "7_Plans_de_secteur")
|
||||||
|
):
|
||||||
|
os.mkdir(main_path + "/" + folder_name)
|
||||||
|
except FileExistsError:
|
||||||
|
print("Le dossier suivant existe déjà : " + folder_name)
|
||||||
|
|
||||||
|
return main_path
|
||||||
|
|
||||||
|
def correct_file_name(file):
|
||||||
|
"""
|
||||||
|
Corrige les erreurs de nomage des fichiers
|
||||||
|
espaces et tirets deviennent des underscore
|
||||||
|
"""
|
||||||
|
basename = os.path.basename(file)
|
||||||
|
correct_file = basename.replace(" ","_")
|
||||||
|
correct_file = basename.replace("-","_")
|
||||||
|
correct_file = os.path.join(os.path.dirname(file),correct_file)
|
||||||
|
os.rename(file,correct_file)
|
||||||
|
return correct_file
|
||||||
|
|
||||||
|
def sort_files(prefixe, suffixe, sort_path):
|
||||||
|
"""
|
||||||
|
Range les fichiers dans l'arborescence, selon des mots clefs
|
||||||
|
Renvoi un dictionaire avec tous les noms de fichiers trouvés et leur compte
|
||||||
|
"""
|
||||||
|
# cherche tous les fichiers pdf présents dans l'arborescence
|
||||||
|
# à partir du Current working directory,
|
||||||
|
# y compris ceux dans des dossiers
|
||||||
|
files = glob.glob(os.getcwd() + "/**/*.pdf", recursive=True)
|
||||||
|
|
||||||
|
#compte le nombre de fois mot clef apparait
|
||||||
|
keyword_count = {key: 0 for key in KEYWORDS}
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
no_keyword = True
|
||||||
|
|
||||||
|
#corrige les erreur de nommage de fichiers
|
||||||
|
file = correct_file_name(file)
|
||||||
|
|
||||||
|
for keyword, folder in KEYWORDS.items():
|
||||||
|
if keyword.lower() in file.lower():
|
||||||
|
|
||||||
|
keyword_count[keyword] +=1
|
||||||
|
filename = keyword
|
||||||
|
if keyword_count[keyword] > 1:
|
||||||
|
# Le nouveau nom du fichier
|
||||||
|
filename += "_" + str(keyword_count[keyword] - 1)
|
||||||
|
# Le dossier de destination du fichier
|
||||||
|
|
||||||
|
new_path = sort_path + "/" + folder
|
||||||
|
# Le nouveau nom du fichier
|
||||||
|
renamed = os.path.join(
|
||||||
|
os.path.dirname(file),
|
||||||
|
prefixe + "_" + filename + "_" + suffixe + ".pdf",)
|
||||||
|
|
||||||
|
os.rename(file, renamed)
|
||||||
|
shutil.move(renamed, new_path)
|
||||||
|
no_keyword = False
|
||||||
|
break
|
||||||
|
# si aucun mot clef n'a été trouvé dans le nom du fichier,
|
||||||
|
# on l'envoi dans le dossier Annexes
|
||||||
|
if no_keyword:
|
||||||
|
#on s'assure que le nom commence par une majuscule
|
||||||
|
filename = os.path.splitext(os.path.basename(file))[0].capitalize()
|
||||||
|
|
||||||
|
#on ajoute le nom du fichier dans le dictionnaire
|
||||||
|
if not filename in keyword_count:
|
||||||
|
keyword_count.update({filename:1})
|
||||||
|
else:
|
||||||
|
keyword_count[filename] += 1
|
||||||
|
filename += "_" + str(keyword_count[filename] - 1)
|
||||||
|
|
||||||
|
renamed = os.path.join(
|
||||||
|
os.path.dirname(file),
|
||||||
|
prefixe
|
||||||
|
+ "_"
|
||||||
|
+ filename
|
||||||
|
+ "_"
|
||||||
|
+ suffixe
|
||||||
|
+ ".pdf",
|
||||||
|
)
|
||||||
|
os.rename(file, renamed)
|
||||||
|
shutil.move(renamed, sort_path + "/" + FOLDERNAMES[4])
|
||||||
|
fabien.amarger
commented
Ca c'est risqué, si tu ajoutes une entrée dans Ca c'est risqué, si tu ajoutes une entrée dans `FOLDERNAMES` ton indice ne sera plus bon
pierre.gauthier
commented
Je me le suis permis parce que FOLDERNAMES est une constante et ne devrais pas changer à l'avenir, mais c'est vrai que mettre une const à la place du 4 serait plus propre Je me le suis permis parce que FOLDERNAMES est une constante et ne devrais pas changer à l'avenir, mais c'est vrai que mettre une const à la place du 4 serait plus propre
|
|||||||
|
|
||||||
|
return keyword_count
|
||||||
|
# return True
|
||||||
|
|
||||||
|
def error_report(data):
|
||||||
|
"""
|
||||||
|
Crée le rapport d'utilisation du script
|
||||||
|
"""
|
||||||
|
report = xls.Workbook()
|
||||||
|
report_worsheet = report.active
|
||||||
|
report_worsheet.title = "Compte rendu"
|
||||||
|
report_worsheet['A1'] = "Fichiers trouvés"
|
||||||
|
report_worsheet['B1'] = "Occurences"
|
||||||
|
report_worsheet['F1'] = "Dossiers"
|
||||||
|
report_worsheet['G1'] = "Fichiers contenus"
|
||||||
|
|
||||||
|
report_worsheet.column_dimensions['A'].width *= 3
|
||||||
|
report_worsheet.column_dimensions['B'].width *= 3
|
||||||
|
report_worsheet.column_dimensions['F'].width *= 3
|
||||||
|
report_worsheet.column_dimensions['G'].width *= 3
|
||||||
|
|
||||||
|
currrent_cell = 2
|
||||||
|
for key in data:
|
||||||
|
report_worsheet['A'+ str(currrent_cell)] = key
|
||||||
|
report_worsheet['B'+ str(currrent_cell)] = data.get(key)
|
||||||
|
currrent_cell+=1
|
||||||
|
|
||||||
|
report_worsheet['A'+str(3 + len(data.keys()))] = "Total fichiers"
|
||||||
|
report_worsheet['B'+str(3 + len(data.keys()))] = '=SUM(B2:B' + str(1 + len(data.keys())) + ')'
|
||||||
|
report.save("Rapport.xlsx")
|
||||||
|
|
||||||
|
def sortout():
|
||||||
|
"""Classe le dossier voulu selon les donées renseignées par l'utilisateur"""
|
||||||
|
is_plu = True
|
||||||
|
|
||||||
|
# demande si c'est un PLU ou un PLUi tant que l'input ne correspond pas à ce que l'on attend
|
||||||
while True:
|
while True:
|
||||||
answer = int(input("[1] - PLU \n[2] - PLUi \nQuel type de dossier est a étudier ? :"))
|
answer = int(
|
||||||
|
input("[1] - PLU \n[2] - PLUi \nQuel type de dossier est a étudier ? :")
|
||||||
|
)
|
||||||
|
|
||||||
if answer > 2 or answer < 1 :
|
if answer > 2 or answer < 1:
|
||||||
print("erreur dans la saisie du choix")
|
print("erreur dans la saisie du choix")
|
||||||
print("\033[A\033[K", end="")
|
# print("\033[A\033[K", end="") #supprime la dernière ligne
|
||||||
else:
|
else:
|
||||||
isPlU = answer == 1
|
is_plu = answer == 1
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# On demande le numero INSEE ou SIREN tant que l'input est invalide
|
||||||
while True:
|
while True:
|
||||||
print("numero INSEE : " if isPlU else "numero siren : ", end="")
|
print("numero INSEE (Format 5 chiffres): "
|
||||||
|
if is_plu else "numero siren (Format 9 chiffres): ", end="")
|
||||||
prefixe = input()
|
prefixe = input()
|
||||||
if(testSirenInsee(isPlu, prefixe)):
|
if test_siren_insee(is_plu, prefixe):
|
||||||
break
|
break
|
||||||
|
|
||||||
#On demande la date d'approbation tant que l'input est invalide
|
# On demande la date d'approbation tant que l'input est invalide
|
||||||
while True:
|
while True:
|
||||||
print("Date d'approbation (Format AAAAMMJJ): ", end="")
|
print("Date d'approbation (Format AAAAMMJJ): ", end="")
|
||||||
suffixe = input()
|
suffixe = input()
|
||||||
if(testDate(suffixe)):
|
if test_date(suffixe):
|
||||||
break
|
break
|
||||||
|
|
||||||
|
main_path = create_folders(is_plu, prefixe, suffixe)
|
||||||
|
|
||||||
#Chargement
|
donees_fichiers = sort_files(prefixe, suffixe, main_path)
|
||||||
|
|
||||||
|
error_report(donees_fichiers)
|
||||||
|
# Chargement
|
||||||
# for i in range(100):
|
# for i in range(100):
|
||||||
|
fabien.amarger
commented
tu peux supprimer cette partie j'imagine tu peux supprimer cette partie j'imagine
|
|||||||
# print(f"{i}%")
|
# print(f"{i}%")
|
||||||
# time.sleep(0.5)
|
# time.sleep(0.5)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user
je note la syntaxe, c'est un bon réflexe à prendre