diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..05cbfb9 --- /dev/null +++ b/__init__.py @@ -0,0 +1,10 @@ +""" +Module principal +""" +from dory_sort_out import sortout + +def main(): + sortout() + +if __name__ == "__main__": + main() diff --git a/dory_sort_out.py b/dory_sort_out.py new file mode 100644 index 0000000..b15ad4e --- /dev/null +++ b/dory_sort_out.py @@ -0,0 +1,248 @@ +""" +Sert a créer l'arborescence pour le dossier CNIG, renommer et ranger les .pdf +""" +import os +import re +import glob +import shutil +from datetime import datetime +import openpyxl as xls + + +# Les noms de tous les dossier a créer +FOLDERNAMES = [ + "0_Procedure", + "1_Rapport_de_presentation", + "2_PADD", + "3_Reglement", + "4_Annexes", + "5_Orientations_amenagement", + "6_POA", + "7_Plans_de_secteur", +] + +# 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: + datetime.strptime(date_input, "%Y%m%d") + return True + except ValueError: + print( + "Erreur dans le format de la date, veuillez la saisir comme suit AAAAMMJJ" + ) + return False + else: + print("Erreur de frappe, la date ne noit contenir que 8 chiffres") + return False + +def test_siren_insee(is_plu: bool, number: str): + """teste si le numero Siren ou Insee donné est valide""" + if is_plu: + if len(number) == 5 and number.isdigit(): + return True + + print("Le numero INSEE est invalide") + return False + else: + if len(number) == 9 and number.isdigit(): + return True + + print("Le numero siren est invalide") + return False + +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]) + + 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: + answer = int( + input("[1] - PLU \n[2] - PLUi \nQuel type de dossier est a étudier ? :") + ) + + if answer > 2 or answer < 1: + print("erreur dans la saisie du choix") + # print("\033[A\033[K", end="") #supprime la dernière ligne + else: + is_plu = answer == 1 + break + + # On demande le numero INSEE ou SIREN tant que l'input est invalide + while True: + print("numero INSEE (Format 5 chiffres): " + if is_plu else "numero siren (Format 9 chiffres): ", end="") + prefixe = input() + if test_siren_insee(is_plu, prefixe): + break + + # On demande la date d'approbation tant que l'input est invalide + while True: + print("Date d'approbation (Format AAAAMMJJ): ", end="") + suffixe = input() + if test_date(suffixe): + break + + main_path = create_folders(is_plu, prefixe, suffixe) + + donees_fichiers = sort_files(prefixe, suffixe, main_path) + + error_report(donees_fichiers) + # Chargement + # for i in range(100): + # print(f"{i}%") + # time.sleep(0.5) + # if i <100: + # print("\033[A\033[K", end="")