def main(): """Partie principale du traitement. Transforme tous les fichiers PDF dans le répertoire désigné en fichiers texte. """ afficher_statut_traitement("Debut du traitement odj2txt") # Répertoire où les fichiers PDF sont enregistrés REPERTOIRE_PDF = "C:\\ContratsOuvertsMtl\\Ordres_du_jour\\PDF" if not os.path.exists(REPERTOIRE_PDF): raise ValueError("Le repertoire " + REPERTOIRE_PDF + " pour les fichier PDF n'existe pas.") # Répertoire où le fichier texte résultant sera sauvegardé REPERTOIRE_TXT = "C:\\ContratsOuvertsMtl\\Ordres_du_jour\\TXT" #Si le répertoire n'existe pas pour le fichier texte résultat, on le crée if not os.path.exists(REPERTOIRE_TXT): os.makedirs(REPERTOIRE_TXT) #Passer au travers des fichiers PDF et les convertir en .TXT for filename in os.listdir(REPERTOIRE_PDF): fichier_PDF = os.path.join(REPERTOIRE_PDF, filename) print("Traitement du fichier %s" % fichier_PDF) transformer_pdf_en_txt(fichier_PDF, REPERTOIRE_TXT) afficher_statut_traitement("Fin du traitement odj2txt") return None
def get_file(REPERTOIRE_PDF, lien_du_PDF): afficher_statut_traitement("Début du téléchargement de " + lien_du_PDF) # fichier_PDF = os.path.join(REPERTOIRE_PDF, "\\odf.pdf") ne marche pas avec os.path.join ??!!?? fichier_PDF = REPERTOIRE_PDF + "\\odj.pdf" fichier = wget.download(lien_du_PDF, fichier_PDF) afficher_statut_traitement("Fin du téléchargement de " + lien_du_PDF) return None
def get_file(REPERTOIRE_PDF, lien_du_PDF): afficher_statut_traitement("Début du téléchargement de " + lien_du_PDF) #fichier_PDF = os.path.join(REPERTOIRE_PDF, "\\odf.pdf") ne marche pas avec os.path.join ??!!?? fichier_PDF = REPERTOIRE_PDF + "\\odj.pdf" fichier = wget.download(lien_du_PDF, fichier_PDF) afficher_statut_traitement("Fin du téléchargement de " + lien_du_PDF) return None
def contrats_ouverts_mtl(): afficher_statut_traitement("Début du traitement principal") a_verifier = get_liens_a_verifier() print(a_verifier) #Passer au travers des pages web à vérifier for item in a_verifier: print() print(item) #Télécharger le(s) fichier(s) PDF de l'ordre du jour if get_ODJ(item[3]): #Extraire les contrats en format .csv odj2contrats(item) #item[1] = lien de la page source du PDF #Envoyer un message par Twitter informer_nouveaux_contrats() afficher_statut_traitement("Fin du traitement principal")
def get_ODJ(url): """Partie principale du traitement. Télécharger les nouveaux fichiers d'ordre du jour """ reponse = False # Répertoire de travail du script REPERTOIRE = "C:\\ContratsOuvertsMtl" # Répertoire où les fichiers PDF sont enregistrés REPERTOIRE_PDF = REPERTOIRE + "\\Ordres_du_jour\\PDF" # Début de l'hyperlien pour télécharger le fichier PDF de l'Ordre du jour # Le lien est donné en relatif dans le code HTML de la page LIEN_PREFIXE = "http://ville.montreal.qc.ca" afficher_statut_traitement("Début du traitement get_ODJ") # Scraper les liens des fichiers liens_PDF = get_liens_fichiers_ODJ(LIEN_PREFIXE, url) # Télécharger le fichier s'il n'a pas déjà été traité for lien in liens_PDF: if not est_lien_traite(REPERTOIRE, lien): get_file(REPERTOIRE_PDF, lien) ajouter_lien_traite(REPERTOIRE, lien) reponse = True afficher_statut_traitement("Fin du traitement get_ODJ") return reponse
def get_ODJ(url): """Partie principale du traitement. Télécharger les nouveaux fichiers d'ordre du jour """ reponse = False #Répertoire de travail du script REPERTOIRE = "C:\\ContratsOuvertsMtl" # Répertoire où les fichiers PDF sont enregistrés REPERTOIRE_PDF = REPERTOIRE + "\\Ordres_du_jour\\PDF" # Début de l'hyperlien pour télécharger le fichier PDF de l'Ordre du jour # Le lien est donné en relatif dans le code HTML de la page LIEN_PREFIXE = "http://ville.montreal.qc.ca" afficher_statut_traitement("Début du traitement get_ODJ") #Scraper les liens des fichiers liens_PDF = get_liens_fichiers_ODJ(LIEN_PREFIXE, url) #Télécharger le fichier s'il n'a pas déjà été traité for lien in liens_PDF: if not est_lien_traite(REPERTOIRE, lien): get_file(REPERTOIRE_PDF, lien) ajouter_lien_traite(REPERTOIRE, lien) reponse = True afficher_statut_traitement("Fin du traitement get_ODJ") return reponse
def odj2contrats(a_verifier): #Initialisation des variables instance = a_verifier[1] source = a_verifier[3] no_decision = "" pour = "" no_dossier = "" instance_reference = "" no_appel_offre = "" debut_no_appel_offre = "" fin_no_appel_offre = "" fournisseur = "" nbr_fournisseur = 0 depense_totale = "" texte_contrat = "" #Indiquer le début du traitement afficher_statut_traitement("Début du traitement odj2contrats") #Passer au travers des fichiers dans REPERTOIRE_TXT for filename in os.listdir(REPERTOIRE_TXT): fichier_TXT = os.path.join(REPERTOIRE_TXT, filename) print("Traitement du fichier %s" % fichier_TXT) #Enlever le BOM au début du fichier strip_bom(fichier_TXT) #Ouverture du fichier pour les résultats # if est_fichier_vide("C:\\ContratsOuvertsMtl\\contrats_traites.csv"): # contrats_traites = open("C:\\ContratsOuvertsMtl\\contrats_traites.csv", "a", encoding="utf-8") # fcontrats_traites.writerow(["instance", "date_rencontre", "no_decision", "no_dossier", "instance_reference", "no_appel_offres", "nbr_soumissions", "pour", "texte_contrat", "fournisseur", "source", "date_traitement"]) # contrats_traites.close() contrats_traites = open("C:\\ContratsOuvertsMtl\\contrats_traites.csv", "w", encoding="utf-8") fcontrats_traites = csv.writer(contrats_traites, delimiter=';') fcontrats_traites.writerow([ "instance", "date_rencontre", "no_decision", "titre", "no_dossier", "instance_reference", "no_appel_offres", "nbr_soumissions", "pour", "texte_contrat", "fournisseur", "montant", "type_contrat", "huis_clos", "source", "date_traitement" ]) #Passer au travers du fichier texte de l'ordre du jour with open( fichier_TXT, "r", encoding="utf-8", ) as f: for ligne in f: if isinstance(ligne, str): ligne.encode('utf8') else: unicode(ligne).encode('utf8') ligne.strip() if ligne: #Ne pas traiter les lignes vides ligne2 = epurer_ligne(ligne) print(ligne2) if not est_numero_de_page( ligne2 ): #Ne pas traiter les lignes qui donnes le numéro de page du PDF #Début d'une décision if est_no_decision(ligne2): #C'est une nouvelle décision, #écrire le dernier contrat dans le fichier contrats_traites.txt #Dans le traitement, sur la première décision, il n'y a encore rien à écrire if no_decision: print("--------") print(texte_contrat) no_appel_offre = getNo_appel_offres( texte_contrat) nbr_soumissions = getNbr_soumissions( texte_contrat) fournisseur = get_fournisseur(texte_contrat) nbr_fournisseur = get_nombre_fournisseurs( fournisseur, nbr_fournisseur) montant = get_montant(texte_contrat) type_contrat = get_type_contrat(texte_contrat) huis_clos = get_huis_clos(texte_contrat) titre = get_titre(instance, no_dossier, texte_contrat) texte_contrat = epurer_contrat( texte_contrat, no_decision, titre, pour, no_dossier) #Écrire le nom des champs dans le fichier contrats_traites.csv fcontrats_traites.writerow([ instance, DATE_RENCONTRE, no_decision, titre, no_dossier, instance_reference, no_appel_offre, nbr_soumissions, pour, texte_contrat, fournisseur, montant, type_contrat, huis_clos, STATUT, source, DATE_TRAITEMENT ]) #Réinitialiser les variables no_decision = get_no_decision( ligne2, instance) #Nouveau numéro de décision titre = "" pour = "" #Initaliser le pour no_dossier = "" #Initaliser le numéro de dossier instance_reference = "" #Initialiser l'instance référente du contrat no_appel_offre = "" #Initaliser le numéro d'appel d'offre debut_no_appel_offre = "" fin_no_appel_offre = "" fournisseur = "" montant = "" type_contrat = "", depense_totale = "" texte_contrat = "" #Initaliser le texte du contrat huis_clos = "" #L'instance référence du contrat if est_instance_reference(ligne2): instance_reference = set_instance_reference(ligne2) #La variable 'pour' est l'entité pour qui le contrat est adopté if est_instance_reference(ligne2): pour = set_instance_reference(ligne2) #Numéro de dossier if not no_dossier: if est_no_dossier(ligne2): no_dossier = get_no_dossier(ligne2) #Numéro de décision if est_no_decision(ligne2): no_decision = get_no_decision(ligne2, instance) ligne2 = ligne2.replace( no_decision, "" ) #Dans certains cas, le texte du contrat début sur la ligne du numéro de décision ligne2 = epurer_ligne(ligne2) #Texte du contrat if not texte_contrat: texte_contrat = ligne2 #C'est le début du texte du contrat, évite d'avoir un espace au début else: if not est_instance_reference(ligne2): if ligne2: texte_contrat = epurer_ligne( texte_contrat) + " " + ligne2 #Écrire le dernier contrat no_appel_offre = getNo_appel_offres(texte_contrat) nbr_soumissions = getNbr_soumissions(texte_contrat) fournisseur = get_fournisseur(texte_contrat) montant = get_montant(texte_contrat) texte_contrat = epurer_contrat(texte_contrat, no_decision, titre, pour, no_dossier) titre = get_titre(instance, no_dossier, texte_contrat) fcontrats_traites.writerow([ instance, DATE_RENCONTRE, no_decision, titre, no_dossier, instance_reference, no_appel_offre, nbr_soumissions, pour, texte_contrat, fournisseur, montant, type_contrat, huis_clos, STATUT, source, DATE_TRAITEMENT ]) #Indiquer que le traitement est terminé afficher_statut_traitement("Traitement termimé odj2contrats")
def transformer_pdf_en_txt(fichier_PDF, REPERTOIRE_TXT): afficher_statut_traitement("Début de transformer_pdf_en_txt") # Titre de la section où se retrouvent les contrats. TITRE_SECTION_20 = " Affaires contractuelles" # Titre de la section suivant celle où se retrouvent les contrats. TITRE_SECTION_30 = " Administration et finances" SECTION_APRES = [ " Administration et finances", "30.01 Reddition de comptes" "Réglementation", "Urbanisme", "Ressources humaines", "Information", "Motion des conseillers", "Autres sujets" ] prefixe_txt = os.path.splitext(os.path.basename(fichier_PDF))[0] fichier_TXT_temp = os.path.join(REPERTOIRE_TXT, prefixe_txt + '_temp.txt') fichier_TXT = os.path.join(REPERTOIRE_TXT, prefixe_txt + '.txt') odj_traites = open(fichier_TXT, "w") est_dans_section_affaires_contractuelles = False est_apres_section_affaires_contractuelles = False est_dans_section_suivante = False #Convertir le PDF en TXT commande = "" commande = commande + "c:\\contratsouvertsmtl\\pdftotext.exe -nopgbrk -enc UTF-8 " commande = commande + fichier_PDF commande = commande + " " commande = commande + fichier_TXT_temp subprocess.call(commande) #Traiter le fichier TXT pour ne garder que la section 20 - Affaires contractuelles with open(fichier_TXT_temp, 'r') as f: for ligne in f: #On vérifie si on est rendu à la section 20 Affaires contractuelles if not est_dans_section_affaires_contractuelles: if TITRE_SECTION_20 in ligne: est_dans_section_affaires_contractuelles = True else: #On est rendu à la section 30 Administration et finances, on arrête le traitement for item in SECTION_APRES: if item in ligne: #if ligne.endswith(item): est_apres_section_affaires_contractuelles = True if est_dans_section_affaires_contractuelles and not est_apres_section_affaires_contractuelles: # Ajouter la ligne dans le fichier fichier_TXT if not ligne.startswith("Page "): if ligne: odj_traites.writelines(ligne) os.remove(fichier_TXT_temp) odj_traites.close() afficher_statut_traitement("Fin de transformer_pdf_en_txt") return None
def odj2contrats(a_verifier): #Initialisation des variables instance = a_verifier[1] source = a_verifier[3] no_decision = "" pour = "" no_dossier = "" instance_reference = "" no_appel_offre = "" debut_no_appel_offre = "" fin_no_appel_offre = "" fournisseur = "" nbr_fournisseur = 0 depense_totale = "" texte_contrat = "" #Indiquer le début du traitement afficher_statut_traitement("Début du traitement odj2contrats") #Passer au travers des fichiers dans REPERTOIRE_TXT for filename in os.listdir(REPERTOIRE_TXT): fichier_TXT = os.path.join(REPERTOIRE_TXT, filename) print("Traitement du fichier %s" % fichier_TXT) #Enlever le BOM au début du fichier strip_bom(fichier_TXT) #Ouverture du fichier pour les résultats # if est_fichier_vide("C:\\ContratsOuvertsMtl\\contrats_traites.csv"): # contrats_traites = open("C:\\ContratsOuvertsMtl\\contrats_traites.csv", "a", encoding="utf-8") # fcontrats_traites.writerow(["instance", "date_rencontre", "no_decision", "no_dossier", "instance_reference", "no_appel_offres", "nbr_soumissions", "pour", "texte_contrat", "fournisseur", "source", "date_traitement"]) # contrats_traites.close() contrats_traites = open("C:\\ContratsOuvertsMtl\\contrats_traites.csv", "w", encoding="utf-8") fcontrats_traites = csv.writer(contrats_traites, delimiter = ';') fcontrats_traites.writerow(["instance", "date_rencontre", "no_decision", "titre", "no_dossier", "instance_reference", "no_appel_offres", "nbr_soumissions", "pour", "texte_contrat", "fournisseur", "montant", "type_contrat", "huis_clos", "source", "date_traitement"]) #Passer au travers du fichier texte de l'ordre du jour with open(fichier_TXT, "r", encoding = "utf-8", ) as f: for ligne in f: if isinstance(ligne, str): ligne.encode('utf8') else: unicode(ligne).encode('utf8') ligne.strip() if ligne: #Ne pas traiter les lignes vides ligne2 = epurer_ligne(ligne) print(ligne2) if not est_numero_de_page(ligne2): #Ne pas traiter les lignes qui donnes le numéro de page du PDF #Début d'une décision if est_no_decision(ligne2): #C'est une nouvelle décision, #écrire le dernier contrat dans le fichier contrats_traites.txt #Dans le traitement, sur la première décision, il n'y a encore rien à écrire if no_decision: print("--------") print(texte_contrat) no_appel_offre = getNo_appel_offres(texte_contrat) nbr_soumissions = getNbr_soumissions(texte_contrat) fournisseur = get_fournisseur(texte_contrat) nbr_fournisseur = get_nombre_fournisseurs(fournisseur, nbr_fournisseur) montant = get_montant(texte_contrat) type_contrat = get_type_contrat(texte_contrat) huis_clos = get_huis_clos(texte_contrat) titre = get_titre(instance, no_dossier, texte_contrat) texte_contrat = epurer_contrat(texte_contrat, no_decision, titre, pour, no_dossier) #Écrire le nom des champs dans le fichier contrats_traites.csv fcontrats_traites.writerow([instance, DATE_RENCONTRE, no_decision, titre, no_dossier, instance_reference, no_appel_offre, nbr_soumissions, pour, texte_contrat, fournisseur, montant, type_contrat, huis_clos, STATUT, source, DATE_TRAITEMENT]) #Réinitialiser les variables no_decision = get_no_decision(ligne2, instance) #Nouveau numéro de décision titre = "" pour = "" #Initaliser le pour no_dossier = "" #Initaliser le numéro de dossier instance_reference = "" #Initialiser l'instance référente du contrat no_appel_offre = "" #Initaliser le numéro d'appel d'offre debut_no_appel_offre = "" fin_no_appel_offre = "" fournisseur = "" montant = "" type_contrat = "", depense_totale = "" texte_contrat = "" #Initaliser le texte du contrat huis_clos = "" #L'instance référence du contrat if est_instance_reference(ligne2): instance_reference = set_instance_reference(ligne2) #La variable 'pour' est l'entité pour qui le contrat est adopté if est_instance_reference(ligne2): pour = set_instance_reference(ligne2) #Numéro de dossier if not no_dossier: if est_no_dossier(ligne2): no_dossier = get_no_dossier(ligne2) #Numéro de décision if est_no_decision(ligne2): no_decision = get_no_decision(ligne2, instance) ligne2 = ligne2.replace(no_decision,"") #Dans certains cas, le texte du contrat début sur la ligne du numéro de décision ligne2 = epurer_ligne(ligne2) #Texte du contrat if not texte_contrat: texte_contrat = ligne2 #C'est le début du texte du contrat, évite d'avoir un espace au début else: if not est_instance_reference(ligne2): if ligne2: texte_contrat = epurer_ligne(texte_contrat) + " " + ligne2 #Écrire le dernier contrat no_appel_offre = getNo_appel_offres(texte_contrat) nbr_soumissions = getNbr_soumissions(texte_contrat) fournisseur = get_fournisseur(texte_contrat) montant = get_montant(texte_contrat) texte_contrat = epurer_contrat(texte_contrat, no_decision, titre, pour, no_dossier) titre = get_titre(instance, no_dossier, texte_contrat) fcontrats_traites.writerow([instance, DATE_RENCONTRE, no_decision, titre, no_dossier, instance_reference, no_appel_offre, nbr_soumissions, pour, texte_contrat, fournisseur, montant, type_contrat, huis_clos, STATUT, source, DATE_TRAITEMENT]) #Indiquer que le traitement est terminé afficher_statut_traitement("Traitement termimé odj2contrats")
def informer_nouveaux_contrats(a_verifier): message = "" CONTRATS_TRAITES = "C:\\ContratsOuvertsMtl\\contrats_traites.csv" # 0 instance # 1 date_rencontre # 2 no_decision # 3 titre # 4 no_dossier # 5 instance_reference # 6 no_appel_offres # 7 nbr_soumissions # 8 pour # 9 texte_contrat # 10 fournisseur # 11 montant # 12 type_contrat # 13 huis_clos # 14 source # 15 date_traitement afficher_statut_traitement("Début du traitement informer_nouveaux_contrats") with open(CONTRATS_TRAITES, "r", encoding = "utf-8", ) as f: reader = csv.reader(f, delimiter = ";") for ligne in reader: #Ne pas considérer la 1re ligne du nom des champs if "instance" not in ligne: instance = ligne[0] date_rencontre = ligne[1] no_decision = ligne[2] titre = ligne[3] no_dossier = ligne[4] instance_reference = ligne[5] no_appel_offres = ligne[6] nbr_soumissions = ligne[7] pour = ligne[8] texte_contrat = ligne[9] fournisseur = ligne[10] montant = ligne[11] type_contrat = ligne[12] huis_clos = ligne[13] source = ligne[14] date_traitement = ligne[15] #S'il y a un montant, un fournisseur, un tire et le texte du contrat if montant and fournisseur and titre and texte_contrat: message = instance + " " + right(date_rencontre,5) + "|" + formatter_montant(montant) + " à " + fournisseur + "|" + titre + "|" + texte_contrat #S'il y a un montant et un fournisseur if montant and fournisseur and texte_contrat: message = instance + " " + right(date_rencontre,5) + "|" + formatter_montant(montant) + " à " + fournisseur + "|" + texte_contrat #Il y a seulement un fournisseur elif fournisseur and not titre and not montant and texte_contrat: message = instance + " " + right(date_rencontre,5) + "|Contrat à " + fournisseur + "|" + texte_contrat #Décision en huis clos elif "huis clos" in titre: message = instance + " " + right(date_rencontre,5) + "|Décision " + no_decision + " prise en huis clos." + "|" + texte_contrat else: message = instance + " " + right(date_rencontre,5) + "|" + texte_contrat if message and len(message) > 128: message = left(message, 128) + "..." message = message + " #polmtl" message = message.strip() if message is not " #polmtl" or right(message,9) is not ". #polmtl": print("----") print(message) envoyer_twit(message) afficher_statut_traitement("Fin du traitement informer_nouveaux_contrats")
def informer_nouveaux_contrats(a_verifier): message = "" CONTRATS_TRAITES = "C:\\ContratsOuvertsMtl\\contrats_traites.csv" # 0 instance # 1 date_rencontre # 2 no_decision # 3 titre # 4 no_dossier # 5 instance_reference # 6 no_appel_offres # 7 nbr_soumissions # 8 pour # 9 texte_contrat # 10 fournisseur # 11 montant # 12 type_contrat # 13 huis_clos # 14 source # 15 date_traitement afficher_statut_traitement( "Début du traitement informer_nouveaux_contrats") with open( CONTRATS_TRAITES, "r", encoding="utf-8", ) as f: reader = csv.reader(f, delimiter=";") for ligne in reader: #Ne pas considérer la 1re ligne du nom des champs if "instance" not in ligne: instance = ligne[0] date_rencontre = ligne[1] no_decision = ligne[2] titre = ligne[3] no_dossier = ligne[4] instance_reference = ligne[5] no_appel_offres = ligne[6] nbr_soumissions = ligne[7] pour = ligne[8] texte_contrat = ligne[9] fournisseur = ligne[10] montant = ligne[11] type_contrat = ligne[12] huis_clos = ligne[13] source = ligne[14] date_traitement = ligne[15] #S'il y a un montant, un fournisseur, un tire et le texte du contrat if montant and fournisseur and titre and texte_contrat: message = instance + " " + right( date_rencontre, 5 ) + "|" + formatter_montant( montant ) + " à " + fournisseur + "|" + titre + "|" + texte_contrat #S'il y a un montant et un fournisseur if montant and fournisseur and texte_contrat: message = instance + " " + right( date_rencontre, 5) + "|" + formatter_montant( montant ) + " à " + fournisseur + "|" + texte_contrat #Il y a seulement un fournisseur elif fournisseur and not titre and not montant and texte_contrat: message = instance + " " + right( date_rencontre, 5) + "|Contrat à " + fournisseur + "|" + texte_contrat #Décision en huis clos elif "huis clos" in titre: message = instance + " " + right( date_rencontre, 5 ) + "|Décision " + no_decision + " prise en huis clos." + "|" + texte_contrat else: message = instance + " " + right(date_rencontre, 5) + "|" + texte_contrat if message and len(message) > 128: message = left(message, 128) + "..." message = message + " #polmtl" message = message.strip() if message is not " #polmtl" or right(message, 9) is not ". #polmtl": print("----") print(message) envoyer_twit(message) afficher_statut_traitement("Fin du traitement informer_nouveaux_contrats")