#!/usr/bin/python3
#-----------------------------------------------------------
# Ligne de commande : python3 BAO2.py dossier_arborescence rubrique
#-----------------------------------------------------------
# Remarque préalable : les nouvelles modifications apportées 
# par rapport au script de la BAO précédente seront sous la forme suivante :

### --- DEBUT DE LA MODIFICATION --- ###
# Modification
### --- FIN DE LA MODIFICATION --- ###
#-----------------------------------------------------------
# Les bibliothèques

# Importation des bibliothèques
import sys
import re
import os
import shutil
#-----------------------------------------------------------
# Expression régulière afin de trouver les éléments titre et description
# .+? permet à l'expression de ne pas avoir un comportement "gourmand"

regex_item = re.compile("<item><title>(.+?)<\/title>.+?<description>(.+?)<\/description>")
#-----------------------------------------------------------
# Les fonctions

# Fonction de nettoyage du texte permettant d'enlever les CDATA présents pour des sections 
# qui ne devaient pas être reconnus comme balisage
def nettoyage(texte) :
    textclean = re.sub("<!\[CDATA\[(.*?)\]\]>", "\\1", texte)
    textclean += "."
    textclean = re.sub("\.+$", ".", texteclean)
    return textclean

# Fonction permettant d'extraire les informations sur un (seul) fichier RSS
# et d'écrire dans le fichier txt chaque titre et description suivi d'une séparation
# et d'écrire dans le fichier xml chaque titre et description entouré de balises
def extract_un_fil(fichier_rss, fichier_txt, fichier_xml):
    # on lit le fichier RSS
    with open(fichier_rss, "r", encoding="utf-8") as input_rss:
        lignes = input_rss.readlines()
        texte = "".join(lignes)
        # pour chaque élément matché (deux groupes)
        for m in re.finditer(regex_item, texte): 
            # pour éviter les doublons, on crée une variable globale sans doublons de type liste 
            global l_sans_doublons
            # si le titre n'est pas déjà dans la liste
            # alors on écrit dans nos fichiers txt et xml
            # (on considère qu'un article est un doublon si son titre est identique)
            if m.group(1) not in l_sans_doublons:
                # on l'ajoute dans la liste
                l_sans_doublons.append(m.group(1))
                #global nb_item
                #nb_item += 1
                titre_net = nettoyage(m.group(1))
                description_net = nettoyage(m.group(2))
                output_txt.write(f"{titre_net}\n{description_net}\n")
                output_txt.write("-----------------------------\n")
                ### --- DEBUT DE LA MODIFICATION --- ###
                titre_seg, description_seg = segmentationTD(titre_net), segmentationTD(description_net)
                item_xml = f"<item>\n<titre>\n{titre_seg}\n</titre>\n<description>\n{description_seg}\n</description>\n</item>\n"
                output_xml.write(item_xml)
                ### --- FIN DE LA MODIFICATION --- ###

# Fonction de parcours d'arborescence permettant de parcourir tous les fichiers RSS xml
# selon la rubrique choisie
def parcours_arborescence_fichiers(repertoire, rubrique, fichier_txt, fichier_xml):
    if not os.path.isdir(repertoire) :
        print( "Le chemin n'exite pas !" )
    else : 
        # pour tous les fichiers du répertoire
        for fichier in os.listdir(repertoire):
            # on joint le chemin
            f = os.path.join(repertoire, fichier)
            # si le fichier est un dossier, on continue récursivement le parcours
            # sur les dossiers de ce nouveau répertoire
            if os.path.isdir(f):
                parcours_arborescence_fichiers(f, rubrique, fichier_txt, fichier_xml)
            # si le fichier on est un fichier RSS avec la bonne rubrique
            if os.path.isfile(f) and f.endswith(".xml") and rubrique in f:
                extract_un_fil(f, fichier_txt, fichier_xml)

### --- DEBUT DE LA MODIFICATION --- ###
# Nouvelles fonctions

def segmentationTD(texte):
    tmp1 = open("fichier_tampon3.txt", "w")
    tmp1.write(texte)
    tmp1.close()
    os.system("perl ./Ressources_treetagger/tokenise-utf8.pl fichier_tampon3.txt > fichier_tampon4.txt")
    tmp2=open("fichier_tampon4.txt","r")
    texte_seg=tmp2.read()
    tmp2.close()
    return texte_seg

# Un sous-programme qui prend en entrée le precorpus XML créé par segmentationTD
def etiquetage_TreeTagger():
    # Etiquetage TreeTagger avec les ressources Treetagger et le precorpus xml
	os.system(f"./Ressources_treetagger/tree-tagger.exe -lemma -token -no-unknown -sgml ./Ressources_treetagger/french-utf8.par python-precorpus-titre-description-{rubrique}.xml > python-corpus-titre-description-{rubrique}")
	# Conversion du résultat TreeTagger au format xml avec un programme de conversion donné déjà créé
    os.system(f"perl ./Ressources_treetagger/treetagger2xml-utf8-meilleur.pl python-corpus-titre-description-{rubrique} UTF8")
    
# Un sous-programme qui prend en entrée un texte brut contenant un titre et une description
def etiquetage_UDPipe():
    # Etiquetage UDPipe avec les ressources UDPipe et le corpus txt
	os.system(f"./UDpipe/udpipe-1.2.0-bin/bin-win64/udpipe.exe --tokenize --tag --parse --tokenizer=presegmented ./UDpipe/modeles/french-sequoia-ud-2.5-191206.udpipe python-corpus-titre-description-{rubrique}.txt > python-corpus-titre-description-{rubrique}.udpipe")
    # Comme pour perl, on lance le script "udpipe2xml-version-sans-titrevsdescription-v2.pl" 
    # pour avoir un fichier conll sous forme xml
	# Ce fichier sera utile pour nos deux prochaines boîtes à outils
    os.system(f"perl ./distrib-udpipe-1.2.0-bin/udpipe2xml-version-sans-titrevsdescription-v2.pl corpus-annotation-ud-{RUBRIQUE}.udpipe")


### --- FIN DE LA MODIFICATION --- ###

# Fonction principale (contrairement à python, la fonction principale 
# doit obligatoirement être après toutes les sous-fonctions crées)
if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("Nombre d'arguments incorrects !\n La bonne commande est par exemple : python3 BAO1.py 2021 3208")
    else:
        # on prend les arguments donnés au programme
        # les fichiers de sorties ont un nom prédéfini
        repertoire = sys.argv[1];
        rubrique = sys.argv[2];
        fichier_txt = f"python-corpus-titre-description-{rubrique}.txt";
        fichier_xml = f"python-precorpus-titre-description-{rubrique}.xml";
        # on écrit dans les fichiers txt et xml en n'oubliant pas l'entête et les balises <corpus>
        with open(fichier_txt, "w", encoding="utf-8") as output_txt:
            with open(fichier_xml, "w", encoding="utf-8") as output_xml:
                header = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<corpus>\n"
                output_xml.write(header)
                # on retrouve nos variables globales ici
                l_sans_doublons = []
                #nb_item = 0
                parcours_arborescence_fichiers(repertoire, rubrique, fichier_txt, fichier_xml)
                output_xml.write("</corpus>\n")
                #print(nb_item)
                
                ### --- DEBUT DE LA MODIFICATION --- ###
                etiquetage_TreeTagger()
                etiquetage_UDPipe()
                # On supprime les tampons
                os.remove("fichier_tampon3.txt")
                os.remove("fichier_tampon4.txt")
                # On met les fichiers de sortie dans le dossier de sortie BAO2 dédié
                # On s'assure que si les fichiers existent, on les supprime avant de laisser place aux nouveaux 
                # (produit une erreur sinon)
                if os.path.exists(f"./BAO2/{fichier_txt}"):
                    os.remove(f"./BAO2/{fichier_txt}")
                if os.path.exists(f"./BAO2/{fichier_xml}"):
                    os.remove(f"./BAO2/{fichier_xml}")
                shutil.move(fichier_txt, "BAO2")
                shutil.move(fichier_xml, "BAO2")
                ### --- FIN DE LA MODIFICATION --- ###