def creer_markdown_texte(texte, cache): # Informations de base cid = texte[1] articles = Article.select(Article.id).where(Article.texte == cid) chemin_base = os.path.join(cache, 'bases-xml', chemin_texte(cid)) # Créer le répertoire de cache path(os.path.join(cache, 'markdown')).mkdir_p() path(os.path.join(cache, 'markdown', cid)).mkdir_p() for article in articles: # Si la markdownisation a déjà été faite, passer chemin_markdown = os.path.join(cache, 'markdown', cid, article.id + '.md') if os.path.exists(chemin_markdown): continue # Lecture du fichier chemin_article = os.path.join(chemin_base, 'article', decompose_cid(article.id) + '.xml') f_article = open(chemin_article, 'r') soup = BeautifulSoup(f_article.read(), 'bases-xml') f_article.close() contenu = soup.find('BLOC_TEXTUEL').find('CONTENU').text.strip() # Logique de transformation en Markdown lignes = [l.strip() for l in contenu.split('\n')] contenu = '\n'.join(lignes) # - Retrait des <br/> en début et fin (cela semble être enlevé par BeautifulSoup) if all([lignes[l].startswith(('<br/>', r'<br />')) for l in range(0, len(lignes))]): lignes[i] = re.sub(r'^<br ?/> *', r'', lignes[i]) if all([lignes[l].endswith(('<br/>', r'<br />')) for l in range(0, len(lignes))]): lignes[i] = re.sub(r' *<br ?/>$', r'', lignes[i]) contenu = '\n'.join(lignes) # - Markdownisation des listes numérotées ligne_liste = [ False ] * len(lignes) for i in range(len(lignes)): if re.match(r'(?:\d+[°\.\)-]|[\*-]) ', lignes[i]): ligne_liste[i] = True lignes[i] = re.sub(r'^(\d+)([°\.\)-]) +', r'\1. ', lignes[i]) lignes[i] = re.sub(r'^([\*-]) +', r'- ', lignes[i]) contenu = '\n'.join(lignes) # - Création d’alinea séparés, sauf pour les listes contenu = lignes[0] for i in range(1, len(lignes)): if ligne_liste[i]: contenu = contenu + '\n' + lignes[i] else: contenu = contenu + '\n\n' + lignes[i] # Enregistrement f_markdown = open(chemin_markdown, 'w') f_markdown.write(contenu.encode('utf-8')) f_markdown.close()
def lire_code_xml(cle, cache): if not cle[2]: return cidTexte = cle[1] chemin_base = os.path.join(cache, 'bases-xml', chemin_texte(cidTexte)) if not os.path.exists(chemin_base): raise Exception() # Lire les informations sur le texte ranger_texte_xml(chemin_base, cidTexte, 'code')
def creer_markdown_texte(texte, cache): # Informations de base cid = texte[1] articles = Article.select(Article.id).where(Article.texte == cid) chemin_base = os.path.join(cache, 'bases-xml') if os.path.exists(os.path.join(chemin_base, chemin_texte(cid, True, True))): chemin_base = os.path.join(chemin_base, chemin_texte(cid, True, True)) elif os.path.exists( os.path.join(chemin_base, chemin_texte(cid, True, False))): chemin_base = os.path.join(chemin_base, chemin_texte(cid, True, False)) elif os.path.exists( os.path.join(chemin_base, chemin_texte(cid, False, True))): chemin_base = os.path.join(chemin_base, chemin_texte(cid, False, True)) elif os.path.exists( os.path.join(chemin_base, chemin_texte(cid, False, False))): chemin_base = os.path.join(chemin_base, chemin_texte(cid, False, False)) elif os.path.exists( os.path.join(chemin_base, chemin_texte(cid, True, True) + '.xml')): chemin_base = os.path.join(chemin_base, chemin_texte(cid, True, True)) elif os.path.exists( os.path.join(chemin_base, chemin_texte(cid, True, False) + '.xml')): chemin_base = os.path.join(chemin_base, chemin_texte(cid, True, False)) elif os.path.exists( os.path.join(chemin_base, chemin_texte(cid, False, True) + '.xml')): chemin_base = os.path.join(chemin_base, chemin_texte(cid, False, True)) elif os.path.exists( os.path.join(chemin_base, chemin_texte(cid, False, False) + '.xml')): chemin_base = os.path.join(chemin_base, chemin_texte(cid, False, False)) else: raise Exception() # Créer le répertoire de cache path(os.path.join(cache, 'markdown')).mkdir_p() path(os.path.join(cache, 'markdown', cid)).mkdir_p() for article in articles: # Si la markdownisation a déjà été faite, passer chemin_markdown = os.path.join(cache, 'markdown', cid, article.id + '.md') if os.path.exists(chemin_markdown): continue # Lecture du fichier chemin_article = os.path.join(chemin_base, 'article', decompose_cid(article.id) + '.xml') f_article = open(chemin_article, 'r') soup = BeautifulSoup(f_article.read(), 'xml') f_article.close() contenu = soup.find('BLOC_TEXTUEL').find('CONTENU').text.strip() # Logique de transformation en Markdown lignes = [l.strip() for l in contenu.split('\n')] contenu = '\n'.join(lignes) # - Retrait des <br/> en début et fin (cela semble être enlevé par BeautifulSoup) if all([ lignes[l].startswith(('<br/>', r'<br />')) for l in range(0, len(lignes)) ]): lignes[i] = re.sub(r'^<br ?/> *', r'', lignes[i]) if all([ lignes[l].endswith(('<br/>', r'<br />')) for l in range(0, len(lignes)) ]): lignes[i] = re.sub(r' *<br ?/>$', r'', lignes[i]) contenu = '\n'.join(lignes) # - Markdownisation des listes numérotées ligne_liste = [False] * len(lignes) for i in range(len(lignes)): if re.match(r'(?:\d+[°\.\)-]|[\*-]) ', lignes[i]): ligne_liste[i] = True lignes[i] = re.sub(r'^(\d+)([°\.\)-]) +', r'\1. ', lignes[i]) lignes[i] = re.sub(r'^([\*-]) +', r'- ', lignes[i]) contenu = '\n'.join(lignes) # - Création d’alinea séparés, sauf pour les listes contenu = lignes[0] for i in range(1, len(lignes)): if ligne_liste[i]: contenu = contenu + '\n' + lignes[i] else: contenu = contenu + '\n\n' + lignes[i] # Enregistrement f_markdown = open(chemin_markdown, 'w') f_markdown.write(contenu.encode('utf-8')) f_markdown.close()
def creer_historique_texte(texte, format, dossier, cache, bdd): # Connexion à la base de données db = legi.utils.connect_db(bdd) # Créer le dossier si besoin sousdossier = '.' cid = texte[1] nom = texte[0] or cid Path(dossier).mkdir_p() entree_texte = db.one(""" SELECT id, nature, titre, titrefull, etat, date_debut, date_fin FROM textes_versions WHERE id = '{0}' """.format(cid)) if entree_texte[1].lower() in ('code', 'loi', 'ordonnance'): if not os.path.exists( os.path.join(dossier, entree_texte[1].lower() + 's')): os.makedirs(os.path.join(dossier, entree_texte[1].lower() + 's')) sousdossier = entree_texte[1].lower() + 's' elif entree_texte[1].lower() == 'decret': if not os.path.exists(os.path.join(dossier, u'décrets')): os.makedirs(os.path.join(dossier, u'décrets')) sousdossier = 'décrets' elif entree_texte[1].lower() == 'arrete': if not os.path.exists(os.path.join(dossier, u'arrêtés')): os.makedirs(os.path.join(dossier, u'arrêtés')) sousdossier = 'arrêtés' if texte[2]: identifiant, nom_fichier = normalisation_code(nom) sousdossier = os.path.join('codes', identifiant) Path(os.path.join(dossier, sousdossier)).mkdir_p() chemin_base = chemin_texte(cid, True) else: sousdossier = os.path.join(sousdossier, nom) nom_fichier = cid dossier = os.path.join(dossier, sousdossier) sousdossier = '.' if not os.path.exists(dossier): os.makedirs(dossier) fichier = os.path.join(dossier, nom_fichier + '.md') # Créer le dépôt Git if not os.path.exists(os.path.join(dossier, '.git')): subprocess.call(['git', 'init'], cwd=dossier) else: subprocess.call(['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, db, cache) # Sélection des versions du texte versions_texte_db = db.all(""" SELECT debut FROM sommaires WHERE cid = '{0}' UNION SELECT fin FROM sommaires WHERE cid = '{0}' """.format(cid, cid)) dates_texte = [] versions_texte = [] for vt in versions_texte_db: vt = vt[0] if isinstance(vt, basestring): vt = datetime.date(*(time.strptime(vt, '%Y-%m-%d')[0:3])) dates_texte.append(vt) for i in range(0, len(dates_texte) - 1): debut = dates_texte[i] fin = dates_texte[i + 1] versions_texte.append((debut, fin)) sql_texte = "cid = '{0}'".format(cid) # 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 sql = sql_texte + " AND debut <= '{0}' AND ( fin >= '{1}' OR fin == '2999-01-01' )".format( version_texte[0], version_texte[1]) # Créer l’en-tête date_fr = '{} {} {}'.format(version_texte[0].day, MOIS2[int(version_texte[0].month)], version_texte[0].year) if version_texte[0].day == 1: date_fr = '1er {} {}'.format(MOIS2[int(version_texte[0].month)], version_texte[0].year) contenu = nom + '\n' \ + '\n' \ + '- Date de consolidation : ' + date_fr + '\n' \ + '- [Lien permanent Légifrance](https://www.legifrance.gouv.fr/affichCode.do?cidTexte=' + cid + '&dateTexte=' + str(version_texte[0].year) + '{:02d}'.format(version_texte[0].month) + '{:02d}'.format(version_texte[0].day) + ')\n' \ + '\n' \ + '\n' # Enregistrement du fichier if format['organisation'] != 'fichier-unique': f_texte = open('README.md', 'w') f_texte.write(contenu.encode('utf-8')) f_texte.close() # Retrait des fichiers des anciennes versions subprocess.call('rm *.md', cwd=dossier, shell=True) # Créer les sections (donc tout le texte) contenu = creer_sections(contenu, 1, None, version_texte, sql, [], format, dossier, db, cache) # Enregistrement du fichier if format['organisation'] == 'fichier-unique': f_texte = open(fichier, 'w') f_texte.write(contenu.encode('utf-8')) f_texte.close() # Exécuter Git date_base_legi = '{} {} {} {}:{}:{}'.format('18', 'juillet', '2014', '11', '30', '10') # TODO changer cela subprocess.call(['git', 'add', '.'], cwd=dossier) subprocess.call([ 'git', 'commit', '--author="Législateur <>"', '--date="' + str(version_texte[0]) + 'T00:00:00Z"', '-m', 'Version consolidée au {}\n\nVersions :\n- base LEGI : {}\n- programme Archéo Lex : {}' .format(date_fr, date_base_legi, version_archeolex), '-q', '--no-status' ], cwd=dossier) if version_texte[1] == None: logger.info('Version {} enregistrée (du {} à maintenant)'.format( i_version + 1, version_texte[0])) else: logger.info('Version {} enregistrée (du {} au {})'.format( i_version + 1, version_texte[0], version_texte[1]))
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 sousdossier = '.' cid = texte[1] nom = texte[0] or cid path(dossier).mkdir_p() entree_texte = Texte.get(Texte.cid == cid) if entree_texte.nature in ('code', 'loi', 'ordonnance'): if not os.path.exists(os.path.join(dossier, entree_texte.nature + 's')): os.makedirs(os.path.join(dossier, entree_texte.nature + 's')) sousdossier = entree_texte.nature + 's' elif entree_texte.nature == 'decret': if not os.path.exists(os.path.join(dossier, u'décrets')): os.makedirs(os.path.join(dossier, u'décrets')) sousdossier = 'décrets' elif entree_texte.nature == 'arrete': if not os.path.exists(os.path.join(dossier, u'arrêtés')): os.makedirs(os.path.join(dossier, u'arrêtés')) sousdossier = 'arrêtés' if texte[2]: identifiant, nom_fichier = normalisation_code(nom) sousdossier = os.path.join('codes', identifiant) path(os.path.join(dossier, sousdossier)).mkdir_p() chemin_base = chemin_texte(cid, True) else: sousdossier = os.path.join(sousdossier, nom) nom_fichier = cid dossier = os.path.join(dossier, sousdossier) sousdossier = '.' if not os.path.exists(dossier): os.makedirs(dossier) fichier = os.path.join(dossier, nom_fichier + '.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 date_base_legi = '{} {} {} {}:{}:{}'.format('18', 'juillet', '2014', '11', '30', '10') # TODO changer cela subprocess.call( ['git', 'add', os.path.join(sousdossier, nom_fichier + '.md')], cwd=dossier) subprocess.call([ 'git', 'commit', '--author="Législateur <>"', '--date="' + str(version_texte.debut) + 'T00:00:00Z"', '-m', 'Version consolidée au {}\n\nVersions :\n- base LEGI : {}\n- programme Archéo Lex : {}' .format(date_fr, date_base_legi, version_archeolex), '-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 lire_code_xml(cle, cache): cidTexte = cle[1] chemin_base = os.path.join(cache, 'bases-xml') if os.path.exists( os.path.join(chemin_base, chemin_texte(cidTexte, True, True))): chemin_base = os.path.join(chemin_base, chemin_texte(cidTexte, True, True)) elif os.path.exists( os.path.join(chemin_base, chemin_texte(cidTexte, True, False))): chemin_base = os.path.join(chemin_base, chemin_texte(cidTexte, True, False)) elif os.path.exists( os.path.join(chemin_base, chemin_texte(cidTexte, False, True))): chemin_base = os.path.join(chemin_base, chemin_texte(cidTexte, False, True)) elif os.path.exists( os.path.join(chemin_base, chemin_texte(cidTexte, False, False))): chemin_base = os.path.join(chemin_base, chemin_texte(cidTexte, False, False)) elif os.path.exists( os.path.join(chemin_base, chemin_texte(cidTexte, True, True) + '.xml')): chemin_base = os.path.join(chemin_base, chemin_texte(cidTexte, True, True)) elif os.path.exists( os.path.join(chemin_base, chemin_texte(cidTexte, True, False) + '.xml')): chemin_base = os.path.join(chemin_base, chemin_texte(cidTexte, True, False)) elif os.path.exists( os.path.join(chemin_base, chemin_texte(cidTexte, False, True) + '.xml')): chemin_base = os.path.join(chemin_base, chemin_texte(cidTexte, False, True)) elif os.path.exists( os.path.join(chemin_base, chemin_texte(cidTexte, False, False) + '.xml')): chemin_base = os.path.join(chemin_base, chemin_texte(cidTexte, False, False)) else: raise Exception() # Lire les informations sur le texte ranger_texte_xml(chemin_base, cidTexte, 'code')
def lire_code_xml(base, cle, livraison, cache): if not cle[2]: return if livraison not in ['fondation','tout'] and \ not isinstance(livraison, datetime): livraison = datetime.strptime(livraison, '%Y%m%d-%H%M%S') # TODO !! test entree_livraison = Livraison.create( date=datetime(2015, 1, 7, 14, 45, 52), type='fondation', base='LEGI', precedent=None, fondation=None ) entree_livraison = Livraison.create( date=datetime(2015, 1, 7, 23, 2, 6), type='miseajour', base='LEGI', precedent=entree_livraison, fondation=entree_livraison ) # Obtenir la livraison cidTexte = cle[1] if livraison == 'fondation': entree_livraison = Livraison.select(). \ where(Livraison.type == 'fondation'). \ order_by(Livraison.date.desc()).limit(1) elif livraison == 'tout': entree_livraison = Livraison.select(). \ order_by(Livraison.date.desc()).limit(1) else: entree_livraison = Livraison.get(Livraison.date == livraison) # Construire le chemin de base if entree_livraison.type == 'fondation': date_fond = entree_livraison.date.strftime('%Y%m%d-%H%M%S') else: date_fond = entree_livraison.fondation.strftime('%Y%m%d-%H%M%S') chemin_base = os.path.join(cache, 'bases-xml') chemin_fond = os.path.join(chemin_base, date_fond) # Parcourir les livraisons en sens croissant while entree_livraison: # Chemin de la livraison date_majo = entree_livraison.date.strftime('%Y%m%d-%H%M%S') if entree_livraison.type == 'fondation': chemin_majo = os.path.join(chemin_fond, 'fond-' + date_majo) else: chemin_majo = os.path.join(chemin_fond, 'majo-' + date_majo) # Chemin du texte chemin = os.path.join(chemin_majo, chemin_texte(cidTexte)) if not os.path.exists(chemin): raise Exception() # Lire les informations sur le texte ranger_texte_xml(entree_livraison, base, chemin, cidTexte, 'code') # Ouvrir la livraison suivante try: entree_livraison = Livraison.get(Livraison.suivante == entree_livraison) except Livraison.DoesNotExist: entree_livraison = None
def creer_historique_texte(texte, format, dossier, cache, bdd): # Connexion à la base de données db = legi.utils.connect_db(bdd) # Créer le dossier si besoin sousdossier = '.' id = texte nom = texte Path(dossier).mkdir_p() entree_texte = db.one(""" SELECT id, nature, titre, titrefull, etat, date_debut, date_fin, num, cid FROM textes_versions WHERE id = '{0}' """.format(id)) cid = entree_texte[8] if entree_texte[1] in natures.keys(): if not os.path.exists( os.path.join(dossier, natures[entree_texte[1]] + 's')): os.makedirs(os.path.join(dossier, natures[entree_texte[1]] + 's')) sousdossier = natures[entree_texte[1]] + 's' if entree_texte[1] and (entree_texte[1] in natures.keys()) and entree_texte[7]: identifiant = natures[entree_texte[1]] + ' ' + entree_texte[7] identifiant = identifiant.replace(' ', '_') nom_fichier = identifiant sousdossier = os.path.join(natures[entree_texte[1]] + 's', identifiant) Path(os.path.join(dossier, sousdossier)).mkdir_p() chemin_base = chemin_texte(id, entree_texte[1] == 'CODE') elif entree_texte[1] and (entree_texte[1] in natures.keys()) and entree_texte[2]: identifiant = entree_texte[2][0].lower() + entree_texte[2][1:].replace( ' ', '_') nom_fichier = identifiant sousdossier = os.path.join(natures[entree_texte[1]] + 's', identifiant) Path(os.path.join(dossier, sousdossier)).mkdir_p() chemin_base = chemin_texte(id, entree_texte[1] == 'CODE') else: raise Exception('Type bizarre ou inexistant') sousdossier = os.path.join(sousdossier, nom) nom_fichier = id dossier = os.path.join(dossier, sousdossier) sousdossier = '.' if not os.path.exists(dossier): os.makedirs(dossier) fichier = os.path.join(dossier, nom_fichier + '.md') # Créer le dépôt Git if not os.path.exists(os.path.join(dossier, '.git')): subprocess.call(['git', 'init'], cwd=dossier) else: subprocess.call(['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((None, cid, None, None), db, cache) # Sélection des versions du texte versions_texte_db = db.all(""" SELECT debut, fin FROM sommaires WHERE cid = '{0}' """.format(cid)) dates_texte = [] dates_fin_texte = [] versions_texte = [] for vers in versions_texte_db: vt = vers[0] if isinstance(vt, basestring): vt = datetime.date(*(time.strptime(vt, '%Y-%m-%d')[0:3])) dates_texte.append(vt) vt = vers[1] if isinstance(vt, basestring): vt = datetime.date(*(time.strptime(vt, '%Y-%m-%d')[0:3])) dates_fin_texte.append(vt) versions_texte = sorted(set(dates_texte).union(set(dates_fin_texte))) sql_texte = "cid = '{0}'".format(cid) versions_texte = sorted(list(set(versions_texte))) # 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 if i_version >= len(versions_texte) - 1: break debut = versions_texte[i_version] fin = versions_texte[i_version + 1] sql = sql_texte + " AND debut <= '{0}' AND ( fin >= '{1}' OR fin == '2999-01-01' OR etat == 'VIGUEUR' )".format( debut, fin) # Créer l’en-tête date_fr = '{} {} {}'.format(debut.day, MOIS2[int(debut.month)], debut.year) if debut.day == 1: date_fr = '1er {} {}'.format(MOIS2[int(debut.month)], debut.year) contenu = nom + '\n' \ + '\n' \ + '- Date de consolidation : ' + date_fr + '\n' \ + '- [Lien permanent Légifrance](https://www.legifrance.gouv.fr/affichCode.do?cidTexte=' + cid + '&dateTexte=' + debut.isoformat().replace('-','') + ')\n' \ + '\n' \ + '\n' # Enregistrement du fichier if format['organisation'] != 'fichier-unique': f_texte = open('README.md', 'w') f_texte.write(contenu.encode('utf-8')) f_texte.close() # Retrait des fichiers des anciennes versions subprocess.call('rm *.md', cwd=dossier, shell=True) # Créer les sections (donc tout le texte) contenu = creer_sections(contenu, 1, None, (debut, fin), sql, [], format, dossier, db, cache) # Enregistrement du fichier if format['organisation'] == 'fichier-unique': f_texte = open(fichier, 'w') f_texte.write(contenu.encode('utf-8')) f_texte.close() # Exécuter Git date_base_legi = '{} {} {} {}:{}:{}'.format('18', 'juillet', '2014', '11', '30', '10') # TODO changer cela subprocess.call(['git', 'add', '.'], cwd=dossier) #subprocess.call(['git', 'commit', '--author="Législateur <>"', '--date="' + str(debut) + 'T00:00:00Z"', '-m', 'Version consolidée au {}\n\nVersions :\n- base LEGI : {}\n- programme Archéo Lex : {}'.format(date_fr, date_base_legi, version_archeolex), '-q', '--no-status'], cwd=dossier) subprocess.call([ 'git', 'commit', '--author="Législateur <>"', '--date="' + str(debut) + 'T00:00:00Z"', '-m', 'Version consolidée au {}'.format(date_fr), '-q', '--no-status' ], cwd=dossier) if fin == None or str(fin) == '2999-01-01': logger.info('Version {} enregistrée (du {} à maintenant)'.format( i_version + 1, debut)) else: logger.info('Version {} enregistrée (du {} au {})'.format( i_version + 1, debut, fin))
def creer_historique_texte(texte, format, dossier, cache, bdd): # Constantes paris = timezone( 'Europe/Paris' ) # Connexion à la base de données db = legi.utils.connect_db(bdd) # Créer le dossier si besoin sousdossier = '.' id = texte nom = texte # Flags: 1) s’il y a des versions en vigueur future, 2) si la première version est une vigueur future futur = False futur_debut = False # Obtenir la date de la base LEGI last_update = db.one(""" SELECT value FROM db_meta WHERE key = 'last_update' """) last_update_jour = datetime.date(*(time.strptime(last_update, '%Y%m%d-%H%M%S')[0:3])) last_update = paris.localize( datetime.datetime(*(time.strptime(last_update, '%Y%m%d-%H%M%S')[0:6])) ) logger.info('Dernière mise à jour de la base LEGI : {}'.format(last_update.isoformat())) Path(dossier).mkdir_p() entree_texte = db.one(""" SELECT id, nature, titre, titrefull, etat, date_debut, date_fin, num, cid, mtime FROM textes_versions WHERE id = '{0}' """.format(id)) if entree_texte == None: entree_texte = db.one(""" SELECT id, nature, titre, titrefull, etat, date_debut, date_fin, num, cid, mtime FROM textes_versions WHERE cid = '{0}' """.format(id)) if entree_texte == None: raise Exception('Pas de texte avec cet ID ou CID') cid = entree_texte[8] mtime = entree_texte[9] if entree_texte[1] in natures.keys(): if not os.path.exists(os.path.join(dossier, natures[entree_texte[1]]+'s')): os.makedirs(os.path.join(dossier, natures[entree_texte[1]]+'s')) sousdossier = natures[entree_texte[1]]+'s' mise_a_jour = True if entree_texte[1] and (entree_texte[1] in natures.keys()) and entree_texte[7]: identifiant = natures[entree_texte[1]]+' '+entree_texte[7] identifiant = identifiant.replace(' ','_') nom_fichier = identifiant sousdossier = os.path.join(natures[entree_texte[1]]+'s', identifiant) if not os.path.exists(os.path.join(dossier, sousdossier)): mise_a_jour = False Path(os.path.join(dossier, sousdossier)).mkdir_p() chemin_base = chemin_texte(id, entree_texte[1] == 'CODE') elif entree_texte[1] and (entree_texte[1] in natures.keys()) and entree_texte[2]: identifiant = entree_texte[2][0].lower()+entree_texte[2][1:].replace(' ','_') nom_fichier = identifiant sousdossier = os.path.join(natures[entree_texte[1]]+'s', identifiant) if not os.path.exists(os.path.join(dossier, sousdossier)): mise_a_jour = False Path(os.path.join(dossier, sousdossier)).mkdir_p() chemin_base = chemin_texte(id, entree_texte[1] == 'CODE') else: raise Exception('Type bizarre ou inexistant') sousdossier = os.path.join(sousdossier, nom) nom_fichier = id dossier = os.path.join(dossier, sousdossier) sousdossier = '.' if not os.path.exists(dossier): os.makedirs(dossier) fichier = os.path.join(dossier, nom_fichier + '.md') # Créer le dépôt Git avec comme branche maîtresse 'texte' ou 'articles' branche = 'texte' if format['organisation'] == 'repertoires-simple': branche = 'articles' if not os.path.exists(os.path.join(dossier, '.git')): subprocess.call(['git', 'init'], cwd=dossier) subprocess.call(['git', 'symbolic-ref', 'HEAD', 'refs/heads/'+branche], cwd=dossier) else: subprocess.call(['git', 'checkout', '--', sousdossier], cwd=dossier) date_reprise_git = None reset_hash = '' if mise_a_jour: tags = subprocess.check_output(['git', 'tag', '-l'], cwd=dossier) tags = strip(tags).split('\n') date_maj_git = False if len(tags) == 0: raise Exception('Pas de tag de la dernière mise à jour') date_maj_git = paris.localize( datetime.datetime(*(time.strptime(tags[-1], '%Y%m%d-%H%M%S')[0:6])) ) logger.info('Dernière mise à jour du dépôt : {}'.format(date_maj_git.isoformat())) if int(time.mktime(date_maj_git.timetuple())) >= mtime: logger.info('Pas de mise à jour disponible') return # Obtention de la première date qu’il faudra mettre à jour date_reprise_git = db.one(""" SELECT date_debut FROM articles WHERE cid = '{0}' AND mtime > {1} """.format(cid,int(time.mktime(date_maj_git.timetuple())))) # Lecture des versions en vigueur dans le dépôt Git try: if subprocess.check_output(['git', 'rev-parse', '--verify', 'futur-'+branche], cwd=dossier): subprocess.call(['git', 'checkout', 'futur-'+branche], cwd=dossier) except subprocess.CalledProcessError: pass versions_git = strip(subprocess.check_output(['git', 'log', '--oneline'], cwd=dossier).decode('utf-8')).split('\n') for log_version in versions_git: for m, k in MOIS.items(): log_version = log_version.replace( m, k ) m = re.match(r'^([0-9a-f]+) .* ([0-9]+)(?:er)? ([0-9]+) ([0-9]+)$', log_version.encode('utf-8')) if not m: raise Exception('Version non reconnue dans le dépôt Git') date = '{0:04d}-{1:02d}-{2:02d}'.format(int(m.group(4)), int(m.group(3)), int(m.group(2))) reset_hash = m.group(1) if date < date_reprise_git: break reset_hash = '' if reset_hash: if date_reprise_git <= last_update_jour.strftime('%Y-%m-%d'): subprocess.call(['git', 'checkout', branche], cwd=dossier) try: if subprocess.check_output(['git', 'rev-parse', '--verify', 'futur-'+branche], cwd=dossier): subprocess.call(['git', 'branch', '-D', 'futur-'+branche], cwd=dossier) except subprocess.CalledProcessError: pass subprocess.call(['git', 'reset', '--hard', reset_hash], cwd=dossier) else: subprocess.call(['git', 'branch', '-m', 'texte', 'junk'], cwd=dossier) subprocess.call(['git', 'checkout', '--orphan', branche], cwd=dossier) subprocess.call(['git', 'branch', '-D', 'junk'], cwd=dossier) # Vérifier que les articles ont été transformés en Markdown ou les créer le cas échéant creer_markdown_texte((None, cid, None, None), db, cache) # Sélection des versions du texte versions_texte_db = db.all(""" SELECT debut, fin FROM sommaires WHERE cid = '{0}' ORDER BY debut """.format(cid)) dates_texte = [] dates_fin_texte = [] versions_texte = [] for vers in versions_texte_db: vt = vers[0] if isinstance(vt, basestring): vt = datetime.date(*(time.strptime(vt, '%Y-%m-%d')[0:3])) if date_reprise_git and vt.strftime('%Y-%m-%d') < date_reprise_git: continue dates_texte.append( vt ) vt = vers[1] if isinstance(vt, basestring): vt = datetime.date(*(time.strptime(vt, '%Y-%m-%d')[0:3])) dates_fin_texte.append( vt ) versions_texte = sorted(set(dates_texte).union(set(dates_fin_texte))) sql_texte = "cid = '{0}'".format(cid) versions_texte = sorted(list(set(versions_texte))) # 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 if i_version >= len(versions_texte)-1: break debut = versions_texte[i_version] fin = versions_texte[i_version+1] debut_datetime = paris.localize( datetime.datetime( debut.year, debut.month, debut.day ) ) if not futur and debut > last_update_jour: if i_version == 0: subprocess.call(['git', 'symbolic-ref', 'HEAD', 'refs/heads/futur-'+branche], cwd=dossier) if not reset_hash: futur_debut = True else: subprocess.call(['git', 'checkout', '-b', 'futur-'+branche], cwd=dossier) futur = True sql = sql_texte + " AND debut <= '{0}' AND ( fin >= '{1}' OR fin == '2999-01-01' OR etat == 'VIGUEUR' )".format(debut,fin) # Créer l’en-tête date_fr = '{} {} {}'.format(debut.day, MOIS2[int(debut.month)], debut.year) if debut.day == 1: date_fr = '1er {} {}'.format(MOIS2[int(debut.month)], debut.year) contenu = nom + '\n' \ + '\n' \ + '- Date de consolidation : ' + date_fr + '\n' \ + '- [Lien permanent Légifrance](https://www.legifrance.gouv.fr/affichCode.do?cidTexte=' + cid + '&dateTexte=' + debut.isoformat().replace('-','') + ')\n' \ + '\n' \ + '\n' # Enregistrement du fichier if format['organisation'] != 'fichier-unique': f_texte = open('README.md', 'w') f_texte.write(contenu.encode('utf-8')) f_texte.close() # Retrait des fichiers des anciennes versions subprocess.call('rm *.md', cwd=dossier, shell=True) # Créer les sections (donc tout le texte) contenu = creer_sections(contenu, 1, None, (debut,fin), sql, [], format, dossier, db, cache) # Enregistrement du fichier if format['organisation'] == 'fichier-unique': f_texte = open(fichier, 'w') f_texte.write(contenu.encode('utf-8')) f_texte.close() # Exécuter Git subprocess.call(['git', 'add', '.'], cwd=dossier) #subprocess.call(['git', 'commit', '--author="Législateur <>"', '--date="' + str(debut_datetime) + '"', '-m', 'Version consolidée au {}\n\nVersions :\n- base LEGI : {}\n- programme Archéo Lex : {}'.format(date_fr, date_base_legi, version_archeolex), '-q', '--no-status'], cwd=dossier) subprocess.call(['git', 'commit', '--author="Législateur <>"', '--date="' + str(debut_datetime) + '"', '-m', 'Version consolidée au {}'.format(date_fr), '-q', '--no-status'], cwd=dossier, env={ 'GIT_COMMITTER_DATE': last_update.isoformat(), 'GIT_COMMITTER_NAME': 'Législateur'.encode('utf-8'), 'GIT_COMMITTER_EMAIL': '' }) if fin == None or str(fin) == '2999-01-01': logger.info('Version {} enregistrée (du {} à maintenant)'.format(i_version+1, debut)) else: logger.info('Version {} enregistrée (du {} au {})'.format(i_version+1, debut, fin)) if futur and not futur_debut: subprocess.call(['git', 'checkout', branche], cwd=dossier) # Optimisation du dossier git subprocess.call(['git', 'gc', '--aggressive'], cwd=dossier) subprocess.call('rm -rf .git/hooks .git/refs/heads .git/refs/tags .git/logs .git/COMMIT_EDITMSG .git/branches', cwd=dossier, shell=True) subprocess.call('chmod -x .git/config', cwd=dossier, shell=True) # Ajout du tag de date éditoriale subprocess.call(['git', 'tag', last_update.strftime('%Y%m%d-%H%M%S')], cwd=dossier) # Suppression du cache subprocess.call('rm -rf markdown/{0}'.format(cid), cwd=cache, shell=True)