Exemple #1
0
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()
Exemple #2
0
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')
Exemple #3
0
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')
Exemple #4
0
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()
Exemple #5
0
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]))
Exemple #6
0
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))
Exemple #7
0
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))
Exemple #8
0
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')
Exemple #9
0
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
Exemple #10
0
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))
Exemple #11
0
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)