def ranger_texte_xml(chemin_base, cidTexte, nature_attendue=None): # Lecture brute du fichier XML texte/version chemin_texte_version = os.path.join(chemin_base, 'texte', 'version', cidTexte + '.xml') if not os.path.exists(chemin_texte_version): raise Exception() f_version = open(chemin_texte_version, 'r') soup_version = BeautifulSoup(f_version.read(), 'xml') version_META = soup_version.find('META') version_META_COMMUN = version_META.find('META_COMMUN') version_META_SPEC = version_META.find('META_SPEC') version_META_TEXTE_CHRONICLE = version_META_SPEC.find( 'META_TEXTE_CHRONICLE') version_META_TEXTE_VERSION = version_META_SPEC.find('META_TEXTE_VERSION') version_NATURE = version_META_COMMUN.find('NATURE').text version_CID = version_META_TEXTE_CHRONICLE.find('CID').text version_NOR = version_META_TEXTE_CHRONICLE.find('NOR').text version_DATE_TEXTE = version_META_TEXTE_CHRONICLE.find('DATE_TEXTE').text version_DATE_PUBLI = version_META_TEXTE_CHRONICLE.find('DATE_PUBLI').text version_TITRE = version_META_TEXTE_VERSION.find('TITRE').text version_TITREFULL = version_META_TEXTE_VERSION.find('TITREFULL').text version_DATE_DEBUT = version_META_TEXTE_VERSION.find('DATE_DEBUT').text version_DATE_FIN = version_META_TEXTE_VERSION.find('DATE_FIN').text version_ETAT = version_META_TEXTE_VERSION.find('ETAT').text # Lecture brute du fichier XML texte/struct chemin_texte_struct = os.path.join(chemin_base, 'texte', 'struct', cidTexte + '.xml') if not os.path.exists(chemin_texte_struct): raise Exception() f_struct = open(chemin_texte_struct, 'r') soup_struct = BeautifulSoup(f_struct.read(), 'xml') struct_META = soup_struct.find('META') struct_META_COMMUN = struct_META.find('META_COMMUN') struct_META_SPEC = struct_META.find('META_SPEC') struct_META_TEXTE_CHRONICLE = struct_META_SPEC.find('META_TEXTE_CHRONICLE') struct_META_TEXTE_VERSION = struct_META_SPEC.find('META_TEXTE_VERSION') struct_VERSIONS = soup_struct.find('VERSIONS') struct_STRUCT = soup_struct.find('STRUCT') struct_NATURE = struct_META_COMMUN.find('NATURE').text struct_CID = struct_META_TEXTE_CHRONICLE.find('CID').text struct_NOR = struct_META_TEXTE_CHRONICLE.find('NOR').text struct_DATE_TEXTE = struct_META_TEXTE_CHRONICLE.find('DATE_TEXTE').text struct_DATE_PUBLI = struct_META_TEXTE_CHRONICLE.find('DATE_PUBLI').text struct_VERSION = struct_VERSIONS.find_all('VERSION') struct_VERSION_etat = struct_VERSION[0]['etat'] struct_LIEN_TXT = struct_VERSION[0].find('LIEN_TXT') struct_LIEN_TXT_id = struct_LIEN_TXT['id'] struct_LIEN_TXT_debut = struct_LIEN_TXT['debut'] struct_LIEN_TXT_fin = struct_LIEN_TXT['fin'] struct_LIEN_ART = struct_STRUCT.find_all('LIEN_ART') struct_LIEN_SECTION_TA = struct_STRUCT.find_all('LIEN_SECTION_TA') # Traitements de base version_DATE_TEXTE = normalise_date(version_DATE_TEXTE) version_DATE_PUBLI = normalise_date(version_DATE_PUBLI) version_DATE_DEBUT = normalise_date(version_DATE_DEBUT) version_DATE_FIN = normalise_date(version_DATE_FIN) struct_DATE_TEXTE = normalise_date(struct_DATE_TEXTE) struct_DATE_PUBLI = normalise_date(struct_DATE_PUBLI) # Vérifications if not cidTexte == version_CID: raise Exception() if nature_attendue and not version_NATURE == nature_attendue.upper( ) or not struct_NATURE == nature_attendue.upper(): raise Exception() if not version_DATE_TEXTE == struct_DATE_TEXTE: raise Exception() if not version_DATE_PUBLI == struct_DATE_PUBLI: raise Exception() if not len( struct_VERSION ) == 1: # texte/version ne peut avoir qu’une seule version, donc texte/struct également et elles doivent correspondre raise Exception() # Enregistrement du Texte # TODO gérer les mises à jour try: entree_texte = Texte.get(Texte.cid == version_CID) except: entree_texte = Texte.create( cid=version_CID.upper(), nor=version_NOR.upper(), nature=version_NATURE.lower(), date_publi=version_DATE_PUBLI, date_texte=version_DATE_TEXTE, ) # Enregistrement de la Version_texte d’autorité # TODO gérer les mises à jour try: entree_version_texte = Version_texte.get( Version_texte.texte == entree_texte) except: entree_version_texte = Version_texte.create( texte=entree_texte, titre=version_TITRE, titre_long=version_TITREFULL, etat_juridique=version_ETAT.lower(), debut=version_DATE_DEBUT, fin=version_DATE_FIN, base=None) # Recensement des dates de changement dates_changement = set([version_DATE_DEBUT, version_DATE_FIN]) ensemble_versions_sections = set() ensemble_articles = set() # Ajouter récursivement les sections et articles dates_changement, ensemble_versions_section, ensemble_articles = ranger_sections_xml( chemin_base, struct_LIEN_SECTION_TA, struct_LIEN_ART, entree_texte, entree_version_texte, None, None, dates_changement, ensemble_versions_sections, ensemble_articles, cidTexte, 1) print('') # Créer les versions de textes dates_changement = list(dates_changement) dates_changement.sort(cmp=comp_infini) for i in range(len(dates_changement) - 1): # TODO gérer les mises à jour Version_texte.create(texte=entree_texte, titre=version_TITRE, titre_long=version_TITREFULL, etat_juridique=version_ETAT.lower(), debut=dates_changement[i], fin=dates_changement[i + 1], base=entree_version_texte)
def ranger_texte_xml(chemin_base, cidTexte, nature_attendue=None): # Lecture brute du fichier XML texte/version chemin_texte_version = os.path.join(chemin_base, 'texte', 'version', cidTexte + '.xml') if not os.path.exists(chemin_texte_version): raise Exception() f_version = open(chemin_texte_version, 'r') soup_version = BeautifulSoup(f_version.read(), 'xml') version_META = soup_version.find('META') version_META_COMMUN = version_META.find('META_COMMUN') version_META_SPEC = version_META.find('META_SPEC') version_META_TEXTE_CHRONICLE = version_META_SPEC.find('META_TEXTE_CHRONICLE') version_META_TEXTE_VERSION = version_META_SPEC.find('META_TEXTE_VERSION') version_NATURE = version_META_COMMUN.find('NATURE').text version_CID = version_META_TEXTE_CHRONICLE.find('CID').text version_NOR = version_META_TEXTE_CHRONICLE.find('NOR').text version_DATE_TEXTE = version_META_TEXTE_CHRONICLE.find('DATE_TEXTE').text version_DATE_PUBLI = version_META_TEXTE_CHRONICLE.find('DATE_PUBLI').text version_TITRE = version_META_TEXTE_VERSION.find('TITRE').text version_TITREFULL = version_META_TEXTE_VERSION.find('TITREFULL').text version_DATE_DEBUT = version_META_TEXTE_VERSION.find('DATE_DEBUT').text version_DATE_FIN = version_META_TEXTE_VERSION.find('DATE_FIN').text version_ETAT = version_META_TEXTE_VERSION.find('ETAT').text # Lecture brute du fichier XML texte/struct chemin_texte_struct = os.path.join(chemin_base, 'texte', 'struct', cidTexte + '.xml') if not os.path.exists(chemin_texte_struct): raise Exception() f_struct = open(chemin_texte_struct, 'r') soup_struct = BeautifulSoup(f_struct.read(), 'xml') struct_META = soup_struct.find('META') struct_META_COMMUN = struct_META.find('META_COMMUN') struct_META_SPEC = struct_META.find('META_SPEC') struct_META_TEXTE_CHRONICLE = struct_META_SPEC.find('META_TEXTE_CHRONICLE') struct_META_TEXTE_VERSION = struct_META_SPEC.find('META_TEXTE_VERSION') struct_VERSIONS = soup_struct.find('VERSIONS') struct_STRUCT = soup_struct.find('STRUCT') struct_NATURE = struct_META_COMMUN.find('NATURE').text struct_CID = struct_META_TEXTE_CHRONICLE.find('CID').text struct_NOR = struct_META_TEXTE_CHRONICLE.find('NOR').text struct_DATE_TEXTE = struct_META_TEXTE_CHRONICLE.find('DATE_TEXTE').text struct_DATE_PUBLI = struct_META_TEXTE_CHRONICLE.find('DATE_PUBLI').text struct_VERSION = struct_VERSIONS.find_all('VERSION') struct_VERSION_etat = struct_VERSION[0]['etat'] struct_LIEN_TXT = struct_VERSION[0].find('LIEN_TXT') struct_LIEN_TXT_id = struct_LIEN_TXT['id'] struct_LIEN_TXT_debut = struct_LIEN_TXT['debut'] struct_LIEN_TXT_fin = struct_LIEN_TXT['fin'] struct_LIEN_ART = struct_STRUCT.find_all('LIEN_ART') struct_LIEN_SECTION_TA = struct_STRUCT.find_all('LIEN_SECTION_TA') # Traitements de base version_DATE_TEXTE = normalise_date(version_DATE_TEXTE) version_DATE_PUBLI = normalise_date(version_DATE_PUBLI) version_DATE_DEBUT = normalise_date(version_DATE_DEBUT) version_DATE_FIN = normalise_date(version_DATE_FIN) struct_DATE_TEXTE = normalise_date(struct_DATE_TEXTE) struct_DATE_PUBLI = normalise_date(struct_DATE_PUBLI) # Vérifications if not cidTexte == version_CID: raise Exception() if nature_attendue and not version_NATURE == nature_attendue.upper() or not struct_NATURE == nature_attendue.upper(): raise Exception() if not version_DATE_TEXTE == struct_DATE_TEXTE: raise Exception() if not version_DATE_PUBLI == struct_DATE_PUBLI: raise Exception() if not len(struct_VERSION) == 1: # texte/version ne peut avoir qu’une seule version, donc texte/struct également et elles doivent correspondre raise Exception() # Enregistrement du Texte # TODO gérer les mises à jour try: entree_texte = Texte.get(Texte.cid == version_CID) except: entree_texte = Texte.create( cid=version_CID.upper(), nor=version_NOR.upper(), nature=version_NATURE.lower(), date_publi=version_DATE_PUBLI, date_texte=version_DATE_TEXTE, ) # Enregistrement de la Version_texte d’autorité # TODO gérer les mises à jour try: entree_version_texte = Version_texte.get(Version_texte.texte == entree_texte) except: entree_version_texte = Version_texte.create( texte=entree_texte, titre=version_TITRE, titre_long=version_TITREFULL, etat_juridique=version_ETAT.lower(), debut=version_DATE_DEBUT, fin=version_DATE_FIN, base=None ) # Recensement des dates de changement dates_changement = set([version_DATE_DEBUT, version_DATE_FIN]) ensemble_versions_sections = set() ensemble_articles = set() # Ajouter récursivement les sections et articles dates_changement, ensemble_versions_section, ensemble_articles = ranger_sections_xml(chemin_base, struct_LIEN_SECTION_TA, struct_LIEN_ART, entree_texte, entree_version_texte, None, None, dates_changement, ensemble_versions_sections, ensemble_articles, cidTexte, 1) print('') # Créer les versions de textes dates_changement = list(dates_changement) dates_changement.sort(cmp=comp_infini) for i in range(len(dates_changement) - 1): # TODO gérer les mises à jour Version_texte.create( texte=entree_texte, titre=version_TITRE, titre_long=version_TITREFULL, etat_juridique=version_ETAT.lower(), debut=dates_changement[i], fin=dates_changement[i+1], base=entree_version_texte )
def creer_historique_texte(texte, format, dossier, cache): # Créer le dossier si besoin nom = texte[0] cid = texte[1] sousdossier = '.' path(dossier).mkdir_p() path(os.path.join(dossier, 'codes')).mkdir_p() path(os.path.join(dossier, 'constitutions')).mkdir_p() path(os.path.join(dossier, 'lois')).mkdir_p() path(os.path.join(dossier, 'décrets')).mkdir_p() path(os.path.join(dossier, 'ordonnances')).mkdir_p() if texte[2]: identifiant, tmp1 = normalisation_code(nom) dossier = os.path.join(dossier, 'codes', identifiant) sousdossier = '.' path(dossier).mkdir_p() path(os.path.join(dossier, sousdossier)).mkdir_p() chemin_base = chemin_texte(cid, True) fichier = os.path.join(dossier, sousdossier, nom+'.md') # Créer le dépôt Git if not os.path.exists(os.path.join(dossier,'.git')): subprocess.Popen(['git', 'init'], cwd=dossier) else: subprocess.Popen(['git', 'checkout', '--', sousdossier], cwd=dossier) if os.path.exists(fichier): raise Exception('Fichier existant : la mise à jour de fichiers existants n’est pas encore prise en charge.') # Vérifier que les articles ont été transformés en Markdown ou les créer le cas échéant creer_markdown_texte(texte, cache) # Sélection des versions du texte versions_texte = Version_texte.select().where(Version_texte.texte == texte[1]) # Pour chaque version # - rechercher les sections et articles associés # - créer le fichier texte au format demandé # - commiter le fichier for (i_version,version_texte) in enumerate(versions_texte): # Passer les versions 'nulles' if version_texte.base is None: continue # Sélectionner les versions d’articles et sections présentes dans cette version de texte, c’est-à-dire celles créées avant et détruites après (ou jamais) articles = \ Article.select() \ .where( (Article.texte == cid) \ & (Article.debut <= version_texte.debut) \ & ((Article.fin >= version_texte.fin)|(Article.fin == None)) \ ) versions_sections = \ Version_section.select() \ .where( (Version_section.texte == cid) \ & (Version_section.debut <= version_texte.debut) \ & ((Version_section.fin >= version_texte.fin)|(Version_section.fin == None)) \ ) # Créer l’en-tête date_fr = '{} {} {}'.format(version_texte.debut.day, MOIS2[int(version_texte.debut.month)], version_texte.debut.year) if version_texte.debut.day == 1: date_fr = '1er {} {}'.format(MOIS2[int(version_texte.debut.month)], version_texte.debut.year) contenu = nom + '\n' \ + '\n' \ + '- Date de consolidation : '+date_fr+'\n' \ + '- [Lien permanent Légifrance](http://legifrance.gouv.fr/affichCode.do?cidTexte='+cid+'&dateTexte='+str(version_texte.debut.year)+'{:02d}'.format(version_texte.debut.month)+'{:02d}'.format(version_texte.debut.day)+')\n' \ + '\n' \ + '\n' # Créer les sections (donc tout le texte) contenu = creer_sections(contenu, 1, None, versions_sections, articles, version_texte, cid, cache) # Enregistrement du fichier f_texte = open(fichier, 'w') f_texte.write(contenu.encode('utf-8')) f_texte.close() # Exécuter Git subprocess.call(['git', 'add', os.path.join(sousdossier, nom+'.md')], cwd=dossier) subprocess.call(['git', 'commit', '--author="Législateur <>"', '--date="'+str(version_texte.debut)+'T00:00:00Z"', '-m', 'Version consolidée au {}'.format(date_fr), '-q', '--no-status'], cwd=dossier) if version_texte.fin == None: logger.info('Version {} enregistrée (du {} à maintenant)'.format(i_version, version_texte.debut)) else: logger.info('Version {} enregistrée (du {} au {})'.format(i_version, version_texte.debut, version_texte.fin))
def creer_historique_texte(texte, format, dossier, cache): # Créer le dossier si besoin nom = texte[0] cid = texte[1] sousdossier = '.' path(dossier).mkdir_p() path(os.path.join(dossier, 'codes')).mkdir_p() path(os.path.join(dossier, 'constitutions')).mkdir_p() path(os.path.join(dossier, 'lois')).mkdir_p() path(os.path.join(dossier, 'décrets')).mkdir_p() path(os.path.join(dossier, 'ordonnances')).mkdir_p() if texte[2]: identifiant, tmp1 = normalisation_code(nom) dossier = os.path.join(dossier, 'codes', identifiant) sousdossier = '.' path(dossier).mkdir_p() path(os.path.join(dossier, sousdossier)).mkdir_p() chemin_base = chemin_texte(cid, True) fichier = os.path.join(dossier, sousdossier, nom + '.md') # Créer le dépôt Git if not os.path.exists(os.path.join(dossier, '.git')): subprocess.Popen(['git', 'init'], cwd=dossier) else: subprocess.Popen(['git', 'checkout', '--', sousdossier], cwd=dossier) if os.path.exists(fichier): raise Exception( 'Fichier existant : la mise à jour de fichiers existants n’est pas encore prise en charge.' ) # Vérifier que les articles ont été transformés en Markdown ou les créer le cas échéant creer_markdown_texte(texte, cache) # Sélection des versions du texte versions_texte = Version_texte.select().where( Version_texte.texte == texte[1]) # Pour chaque version # - rechercher les sections et articles associés # - créer le fichier texte au format demandé # - commiter le fichier for (i_version, version_texte) in enumerate(versions_texte): # Passer les versions 'nulles' if version_texte.base is None: continue # Sélectionner les versions d’articles et sections présentes dans cette version de texte, c’est-à-dire celles créées avant et détruites après (ou jamais) articles = \ Article.select() \ .where( (Article.texte == cid) \ & (Article.debut <= version_texte.debut) \ & ((Article.fin >= version_texte.fin)|(Article.fin == None)) \ ) versions_sections = \ Version_section.select() \ .where( (Version_section.texte == cid) \ & (Version_section.debut <= version_texte.debut) \ & ((Version_section.fin >= version_texte.fin)|(Version_section.fin == None)) \ ) # Créer l’en-tête date_fr = '{} {} {}'.format(version_texte.debut.day, MOIS2[int(version_texte.debut.month)], version_texte.debut.year) if version_texte.debut.day == 1: date_fr = '1er {} {}'.format(MOIS2[int(version_texte.debut.month)], version_texte.debut.year) contenu = nom + '\n' \ + '\n' \ + '- Date de consolidation : '+date_fr+'\n' \ + '- [Lien permanent Légifrance](http://legifrance.gouv.fr/affichCode.do?cidTexte='+cid+'&dateTexte='+str(version_texte.debut.year)+'{:02d}'.format(version_texte.debut.month)+'{:02d}'.format(version_texte.debut.day)+')\n' \ + '\n' \ + '\n' # Créer les sections (donc tout le texte) contenu = creer_sections(contenu, 1, None, versions_sections, articles, version_texte, cid, cache) # Enregistrement du fichier f_texte = open(fichier, 'w') f_texte.write(contenu.encode('utf-8')) f_texte.close() # Exécuter Git subprocess.call(['git', 'add', os.path.join(sousdossier, nom + '.md')], cwd=dossier) subprocess.call([ 'git', 'commit', '--author="Législateur <>"', '--date="' + str(version_texte.debut) + 'T00:00:00Z"', '-m', 'Version consolidée au {}'.format(date_fr), '-q', '--no-status' ], cwd=dossier) if version_texte.fin == None: logger.info('Version {} enregistrée (du {} à maintenant)'.format( i_version, version_texte.debut)) else: logger.info('Version {} enregistrée (du {} au {})'.format( i_version, version_texte.debut, version_texte.fin))