#/usr/bin/perl
#-----------------------------------------------------------
<<DOC;
NOM : SALMON Estelle
Usage du programme : 
Ce programme va extraire le contenu textuel correspond aux titres et descriptions d'articles contenus dans des fils RSS au format XML. Il va également permettre l'étiquetage avec udpipe et treetagger.
En sortie de ce programme, nous retrouvons un fichier txt avec les données brutes, un fichier xml avec l'étiquetage de udpipe, un fichier txt avec l'étiquetage de udpipe et un fichier xml avec l'étiquetage de treetagger.

Pour lancer le programme : 
perl bao2_perl_regex.pl ../2021 3208
Il prend en arguments 2 éléments : 
	(1) le nom de l'arborescence 2021 contenant les fils RSS de l'année 2021,
	(2) le nom de la rubrique à traiter, ici 3208 pour A la une
DOC

#-----------------------------------------------------------

use utf8;
use strict;
binmode(STDOUT, ":encoding(UTF-8)");

#-----------------------------------------------------------

# on vérifie le bon nombre d'arguments donnés au programme pour le bon déroulement du script
if ($#ARGV != 1) {print "Il manque un argument à votre programme....\n";exit;} 

# le répertoire contenant l'arborescence est le premier argument donné et la rubrique est le deuxième argument
my $rep="$ARGV[0]";
my $RUBRIQUE="$ARGV[1]";

# on s'assure que le nom du répertoire ne se termine pas par un "/"
$rep=~ s/[\/]$//;

# création des fichiers de sortie et print des éléments indispensables pour la constuction du fichier XML (balises)
open my $out_txt, ">:encoding(UTF-8)","sortie_perl_bao2_texteComplet_$RUBRIQUE.txt";
open my $out_xml, ">:encoding(UTF-8)","pre_sortie_perl_bao2_$RUBRIQUE.xml";
print $out_xml "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<corpus>\n";

# déclaration des variables utilisées plus tard 
my %dico_des_titres=(); # table de hachage
my $nb_items=0;

#----------------------------------------

# on lance le sous-programme qui correspond à l'extraction
&parcoursarborescencefichiers($rep);

#----------------------------------------

# on print la fermeture de la balise racine pour le fichier XML et le nombre d'éléments traités pour la vérification du fonctionnement du script
# on ferme les fichiers de sortie
print $out_xml "</corpus>\n";
close $out_txt;
close $out_xml;
print "Nombre d'items traités : $nb_items \n";

#-----------------------------------------
#1. annoter avec udpipe le fichier corpus-titre-description.txt
&etiquetageUP;
#2. annoter avec treetagger le fichier corpus-titre-description.xml
&etiquetageTT;
#----------------------------------------------
exit;
#----------------------------------------------


#----------------------------------------------
# sous-programmes
#----------------------------------------------
sub etiquetageUP {
	#udpipe --tokenize --tag --parse udpipe_model file  > result_udpipe
	system("../distrib-udpipe-1.2.0-bin/udpipe-1.2.0-bin/bin-linux64/udpipe --tokenize --tag --parse --tokenizer=presegmented ../distrib-udpipe-1.2.0-bin/modeles/french-sequoia-ud-2.5-191206.udpipe sortie_perl_bao2_texteComplet_$RUBRIQUE.txt > sortie_perl_bao2_UD_conll_$RUBRIQUE.udpipe");
	system("perl ../distrib-udpipe-1.2.0-bin/udpipe2xml_maVersion.pl sortie_perl_bao2_UD_conll_$RUBRIQUE.udpipe");
}
#----------------------------------------------
sub etiquetageTT {
	system("../distrib-treetagger/tree-tagger -lemma -token -no-unknown -sgml ../distrib-treetagger/french-utf8.par  pre_sortie_perl_bao2_$RUBRIQUE.xml  >  sortie_perl_bao2_TT_$RUBRIQUE ");
	system("perl ../distrib-treetagger/treetagger2xml-utf8-global.pl sortie_perl_bao2_TT_$RUBRIQUE UTF8");
		
}
#----------------------------------------------
sub parcoursarborescencefichiers {
    # ici on vérifie que ce qui est donné en argument du sous-programme plus haut ($rep) est bien accessible et s'il l'est, on l'ouvre pour poursuivre
    my $path = shift(@_);
    opendir(DIR, $path) or die "can't open $path: $!\n";
    my @files = readdir(DIR);
    closedir(DIR);
    # pour chaque élément de ce qu'on trouve dans le répertoire, on va vérifier s'il s'agit d'un répertoire ou d'un fichier. 
    # Dans le premier cas, on lance la récursion. Dans le deuxième, on lance la suite du traitement. 
    foreach my $file (@files) {
		next if $file =~ /^\.\.?$/;
		$file = $path."/".$file;
		if (-d $file) {
			print "On entre dans le REPERTOIRE : $file \n";
			&parcoursarborescencefichiers($file);	# on lance la récursion puisque ce n'est pas un fichier !
			print "On sort du REPERTOIRE :  $file \n";
		}
		# si l'élément est un fichier on continue le traitement
		if (-f $file) {
			# on va poursuivre le traitement si le numéro de la rubrique renseigné lors du lancement 
			# du programme correspond à ce qu'on trouve dans le nom de notre fichier
			if ($file =~ /$RUBRIQUE.+\.xml$/) {
				print "Traitement du fichier $file \n";
				
				# ouverture du fichier en question (puisque nous avons un fichier par rubrique dans chaque répertoire)
				open my $input, "<:encoding(UTF-8)",$file;
				
				$/=undef;
				#  $/ est une variable spéciale qui contient une valeur qui décrit comment perl doit lire les données
				# par défaut elle contient \n (retour à la ligne)
				# quand il lit, perl regarde d'abord $/, c'est à dire à quel moment il arrête de lire le premier élément
				# perl va, par défaut, faire une lecture ligne par ligne
				# on veut lire toutes les données d'un coup, on va indéfinir la variable

				# la variable $ligne correspond à toutes les données du fichier en cours de traitement
				my $ligne=<$input> ;
				
				# on ferme le fichier puisque tout est contenu dans la variable
				close($input);
				
				# boucle while qui va nous aider à parcourir l'ensemble du texte 
				# pour sélectionner le titre ainsi que la description entre les balises correspondantes
				while ($ligne=~/<item><title>(.+?)<\/title>.+?<description>(.+?)<\/description>/gs) {
					my $titre=$1;
					my $description=$2;
					# on incrémente le compteur des items traités
					$nb_items++;
					
					# on va vérifier que le titre n'a pas déjà été rencontré pour éviter les doublons
					if (!(exists $dico_des_titres{$titre})) {
						# le $ désigne les valeurs particulières dans les tables de hachage
						# pour la clé "titre" dans la table, on donne comme valeur, la valeur contenue dans "description"
						# la table de hachage regroupe alors les titres (clés) et les descriptions (valeurs)
						$dico_des_titres{$titre}=$description;
						
						# on fait passer le titre et la description dans le sous-programme de nettoyage
						my $titre=&nettoyage($1);
						my $description=&nettoyage($2);
						
						# on écrit le résultat du traitement dans les différents fichiers de sortie en fonction du type de fichier
						print $out_txt "$titre \n";
						print $out_txt "$description \n";

						# segmentation titre et description avec le programme tokenize offert par treetagger
						my ($titreSEG,$descriptionSEG)=&segmentationTD($titre,$description);
						print $out_xml "<item><titre>\n$titreSEG\n</titre><description>\n$descriptionSEG\n</description></item>\n";
					}
				}
			}
		}
    }
}
#----------------------------------------------
sub segmentationTD {
	my ($arg1,$arg2)=@_;
	# 1. ecriture des données textuelles dans un fichier TOTO
	# 2. puis tokenizer TOTO
	# 3. puis recupérer les données 
	#-----------------------------------------------
	open my $tmp, ">:encoding(UTF-8)","tmp.txt";
	print $tmp $arg1;
	close $tmp;
	system("perl ../distrib-treetagger/tokenise-utf8.pl tmp.txt > tmp2.txt");
	undef $/;
	open my $tmp2, "<:encoding(UTF-8)","tmp2.txt";
	my $titresegmente=<$tmp2>;
	close $tmp2;
	#-----------------------------------------------
	open $tmp, ">:encoding(UTF-8)","tmp.txt";
	print $tmp $arg2;
	close $tmp;
	system("perl ../distrib-treetagger/tokenise-utf8.pl tmp.txt > tmp2.txt");
	open  $tmp2, "<:encoding(UTF-8)","tmp2.txt";
	my $descriptionsegmente=<$tmp2>;
	close $tmp2;
	$/="\n";
	#-----------------------------------------------
	return $titresegmente,$descriptionsegmente;
	}
#----------------------------------------------
sub nettoyage {
	# on sélectionne ce qui nous intéresse en vidant la liste des arguments donnés au sous-programme
	my $texte=shift @_;
	# on supprime les éléments qui nous gênent
	$texte=~s/(^<!\[CDATA\[)|(\]\]>$)//g;
	$texte.=".";
	$texte=~s/\.+$/\./;
	# ici, le choix a été fait de ne pas insérer d'entités puisque nous aurions résolu le problème en XML mais pas en txt
	# le fait de remplacer & par "et" nous permettra l'étiquetage de ce mot dans la deuxième phase du projet (puisque &amp; est considéré comme de la ponctuation)
	# le but est de remplacer ou de supprimer les entités de XML pour ne pas avoir de problème par la suite puisque en XML ces caractères ont une autre fonction
	$texte=~s/&/et/g;
	$texte=~s/<//g;
	$texte=~s/>//g;
	$texte=~s/'//g;
	$texte=~s/’/'/g;
	$texte=~s/"(.+?)"/«$1»/g;
	$texte=~s/“(.+?)”/«$1»/g;
	return $texte;
}
#----------------------------------------------
