#/usr/bin/perl
<<DOC; 
Votre Nom : Anna Colli
FEVRIER 2022
 usage : perl parcours-arborescence-fichiers repertoire-a-parcourir
 Le programme prend en entrée le nom du répertoire contenant les fichiers
 à traiter
 Le programme construit en sortie un fichier structuré contenant sur chaque
 ligne le nom du fichier et le résultat du filtrage :
<FICHIER><NOM>du fichier</NOM></FICHIER><CONTENU>du filtrage</CONTENU></FICHIER>
DOC
#-----------------------------------------------------------
use utf8;
use strict;
binmode(STDOUT, ":encoding(UTF-8)");
#-----------------------------------------------------------
# Ce programme s'utilise ainsi :
# perl parcours-arborescence.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
#-----------------------------------------------------------
#on recupere le répértoire qu'on veut traiter
my $rep="$ARGV[0]";
#on recupere la rubrique qu'on veut traiter
my $rubrique="$ARGV[1]";
# on s'assure que le nom du répertoire ne se termine pas par un "/"
$rep=~ s/[\/]$//;

#pour produire un fichier txt où sauvegarder les résultats
open my $output_txt , ">:encoding(UTF-8)" , "finaltxt.txt";
#pour produire un fichier xml où sauvegarder les résultats
open my $output_xml , ">:encoding(UTF-8)" , "finalxml.xml";
#avec l'en-tete et la première balise <corpus>
print $output_xml "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<corpus>\n";

#pour enlever les doublons:
#création d'un dictionnaire 
my %dico_titres=();
#----------------------------------------
&parcoursarborescencefichiers($rep);	#recurse!
#----------------------------------------
#pour la dernière balise du fichier xml 
print $output_xml "</corpus>\n";
#----------------------------------------
close $output_txt;
close $output_xml;
#----------------------------------------
exit;
#----------------------------------------
#----------------------------------------
sub parcoursarborescencefichiers {
    my $path = shift(@_);
   #j'ouvre un répértoire
    opendir(DIR, $path) or die "can't open $path: $!\n";
    #je lis le répertoire que j'ai ouvert à travers la fonction readdir
    #et je le stocke dans une variable de type liste (@files)
    my @files = readdir(DIR);
    #je ferme l'arborescence 
    closedir(DIR);
    #boucle pour controler tous les éléments contenus dans la variable
    #> il faut faire attention à ne pas traiter les élémenta
    #avec "." ou ".." 
   	foreach my $file (@files) {
   		#donc, si je trouve (grâce à une regex et à la fonction next) 
   		#un élément qui ressemble 
   		#à . ou .. je passe au suivant
		next if $file =~ /^\.\.?$/;
		#à chaque fois que je reouvre une ressource 
		#je compose son chemin complet > le . symbolise la concaténation 
		$file = $path."/".$file;
		if (-d $file) {
		#-d permet de tester si l'élément qu'on est en traint de traiter est un dossier
		#si c'est le cas, on lance la commande d'une facon recursive 
			print "On entre dans le REPERTOIRE : $file \n";
	   		&parcoursarborescencefichiers($file);	
	   		print "On sort dans le REPERTOIRE : $file \n";
		}
		if (-f $file) {
# -f permet de tester que l'élément qu'on est en train de traiter est bien un fichier 
#on controle que le fichier soit bien en xml et qu'il appartient à la rubrique à laquelle on s'intéresse
			if ($file =~ /$rubrique.+\.xml$/) {
				print "Traitement du fichier $file \n";
				#ouverture du fichier qu'on est en train de traiter 
				#il est stocké dans la variable $file
	  			open my $input , "<:encoding(UTF-8)",$file;
	  			#undef permet de réinitialiser la valeur d'une variable. On réinitialise la variable $ qui
	  			#indique comment lire un fichier et qui par défaut contient "\n". Je change la manière dont
	  			#perl lit les fichiers pour lire les données tout d'un coup 
	  			$/=undef;
	  			#lecture intétgrale du fichier à travers "< >". Cela permet de lire tout le fichier et
	  			#insérer le contenu dans une liste 
	  			my $ligne=<$input>;
	  			close($input);
	  			#si la ligne correspond à la structure de titre + description...
	  			while($ligne=~/<item><title>(.+?)<\/title>.+?<description>(.+?)<\/description>/gs) {
	  				#le titre correspond au premier contenu textuel (premier couple de () )
					my $titre=$1;
					#la description correspond au deuxième contenu textuel (deuxième couple de () )
					my $description=$2;
					#je controle si l'article a déjà été repéré en appliquant le traitement seulement sur les fichiers qu'il n'a pas encore rencontré
					#en effet, très souvent les articles apparaissent dans plusieurs rubriques au meme temps
					if (!(exists $dico_titres{$titre})) {
						print "article jamais vu \n";
						#je matche le titre avec la description dans le dictionnaire
						$dico_titres{$titre}=$description;
						#nettoyage du texte des balises CDATA
						my ($titreBis,$descriptionBis)=&nettoyage($titre,$description);
						#remplissage txt
						print $output_txt "$titreBis \n";
						print $output_txt "$descriptionBis \n";
						print $output_txt "----------------------------\n";
						#remplissage XML
						print $output_xml "<item><titre>$titreBis</titre><description>$descriptionBis</description></item>\n";
					}
					else{
						#si on déjà traité l'article, on passe au suivant
						print "article déjà vu, DOUBLON! \n"
					}
				}
	  		}	
    	}
 	}	
}
sub nettoyage {
				#avec shift @_ j'attrappe le première argument donné
				#à la fonction donc le $titre
				my $TIT = shift @_; 
				#avec un deuxième @_ j'attrappe le deuxième argument
				#donné à la fonction qui est maintenant devenu le premier
				my $DES = shift @_; 
				#nettoyage: je substitue avec rien (//) tout ce qui n'est pas texte utile
				#c'est à dire toutes les balises <![CDATA[****]]>
				#nettoyage 2: nettoyage des entités & et &nbsp
				$TIT =~ s/<!\[CDATA\[//;
				$TIT =~s /\]\]>//;
				$TIT =~s /[a-z]*&nbsp;//;
				$TIT=~s /&nbsp;//;
				$TIT=~s /&/E/;
				$TIT=~s /&amp/E/;
				$DES =~s /<!\[CDATA\[//;
				$DES =~s /\]\]>//;
				$DES =~s /[a-z]*&nbsp;//;
				$DES=~s /&nbsp;/ /;
				return $TIT,$DES;
}
