#/usr/bin/perl
<<DOC; 
Nom -- Elise LINCKER
Date -- MARS 2021

Traitement -- parcours d'une arborescence de fichiers (fil RSS)
			  extraction du contenu textuel des balises TITLE et DESCRIPTION avec les expressions régulières
			  nettoyage du contenu textuel

Utilisation du programme -- perl bao1_regexp.pl REPERTOIRE_A_PARCOURIR RUBRIQUE_A_TRAITER
Entrée -- le nom du répertoire-racine contenant les fichiers à traiter
		  et le nom de la rubrique à traiter parmi ces fichiers
Sortie -- un fichier au format txt
		  un fichier au format xml
DOC
#-----------------------------------------------------------
use strict;
use utf8;
use Timer::Simple;
# on instancie un timer commencant à 0.0s par défaut
my $t = Timer::Simple->new();
# on lance le timer
$t->start;

#-----------------------------------------------------------
# on récupère le nom du répertoire racine de l'arborescence à traiter
my $rep="$ARGV[0]";
# on récupère le nom de la rubrique à traiter
my $rubrique ="$ARGV[1]";

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

# déclaration-initialisation des fichiers de sortie
open my $OUT,">:encoding(utf8)","BAO1_regexp_sortie_$rubrique.txt";
open my $OUTXML,">:encoding(utf8)","BAO1_regexp_sortieXML_$rubrique.xml";

# dans le fichier XML, écritute de l'en-tête XML et ouverture de la balise racine
print $OUTXML "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n";
print $OUTXML "<articles rubrique=\"$rubrique\">\n";

# initialisation de compteurs et d'une table de hachage
my %dico_des_titres=();
my $numberItem=0;
my $nbFile=0;

#----------------------------------------
# on déclenche la procédure parcoursarborescencefichiers (récursivité !) en prenant 
# comme argument le nom du répertoire racine par lequel on doit commencer le parcours
&parcoursarborescencefichiers($rep);

#----------------------------------------
# dans le fichier XML, fermeture de la balise racine
print $OUTXML "</articles>\n";

# fermeture des fichiers de sortie
close $OUT;
close $OUTXML;

print "Nb item : $numberItem \n";
# affichage du temps écoulé depuis le lancement du programme
print "Time so far: ", $t->elapsed, " seconds\n";

# fin de l'exécution du programme
exit;

#----------------------------------------------
# procédure parcoursarborescencefichiers
# on accède au contenu du dossier dans lequel on se trouve
sub parcoursarborescencefichiers {

	# on récupère l'argument passé à la procédure (le nom de dossier)
	my $path = shift(@_);
	
	# ouverture du répertoire avec la fonction perl opendir :
	# elle prend comme arguments : le nom du répertoire à ouvrir 
	# + un descripteur, qui va être à partir de maintenant le moyen d'accéder au répertoire qu'on a ouvert
	opendir(my $DIRhandle, $path) or die "can't open $path: $!\n";
	
	# lecture du répertoire avec la fonction perl readdir :
	# elle prend comme argument le descripteur du répertoire qu'on vient d'ouvrir
	# et renvoie comme valeur la liste des fichiers contenus dans le répertoire
	# on stocke cette liste dans @files
	my @files = readdir($DIRhandle);

	# fermeture du répertoire
	closedir($DIRhandle);

	# pour chaque élément contenu dans le répertoire (ficher ou répertoire)
	foreach my $file (@files) {
		# on passe au fichier suivant s'il s'agit d'un répertoire caché
		next if $file =~ /^\.\.?$/;

		# reconstruction du chemin relatif de l'élément traité $file
		$file = $path."/".$file;
		# "." est un opérateur de concaténation : "2020"."/"."01" => "2020/01"

		# on teste le statut du fichier avec les opérateurs -d et - f
		
		# -d ---> true si $file est un répertoire 
		if (-d $file) {
			# on relance la procédure parcoursarborescencefichiers sur le répertoire $file
			&parcoursarborescencefichiers($file);	# recursivité !
		}
		
		# -f ---> true si $file est un fichier
		if (-f $file) {

			# on veut récupérer des fichiers XML RSS et une seule rubrique en particuler :
			# si le nom du fichier correspond au nom de la RUBRIQUE qu'on veut traiter
			# ET se termine par l'EXTENSION .xml ---> ON TRAITE LE FICHIER !
			if ($file =~/$rubrique.+xml$/) {
			
				# incrémentation du compteur de fichiers + message dans le terminal du fichier traité
				print $nbFile++," Traitement de : ",$file,"\n";

				# **************** TRAITEMENT DE LA BAO 1 : PERL REGEPX ****************
				# ****************     EXTRACTION DU CONTENU TEXTUEL    ****************

				# ouverture et lecture du fichier jusqu'à la fin en une seule fois
				open my $fic,"<:encoding(utf8)",$file;
				$/=undef;     #ou $\=""
				my $textelu=<$fic>;
				# fermeture du fichier
				close $fic;

				# boucle qui extrait les titres et descriptions à l'aide des expressions régulières
				while ($textelu=~/<item>.*?<title>(.+?)<\/title>.+?<description>(.+?)<\/description>/sg) {
					# initialisation des variables $titre et $description pour traiter les titres et descriptions séparément 
					my $titre=$1;
					my $description=$2;

					# incrémentation du compteur d'items
					$numberItem++;

					# appel de la procédure de nettoyage 
					($titre,$description)=&nettoyage($titre,$description);

					# si le titre n'existe pas dans la table de hachage $dico_des_titres, 
					if (!(exists $dico_des_titres{$titre})) { 
						# alors ce n'est pas un doublon : on ajoute le titre et sa description à la table de hachage
						$dico_des_titres{$titre}=$description ;

						# Ecriture des résultats dans les fichiers de sortie
						print $OUT "$titre\n";
						print $OUT "$description\n";
						print $OUT "--------------------\n";
						print $OUTXML "\t<item>\n";
						print $OUTXML "\t\t<titre>$titre</titre>\n";
						print $OUTXML "\t\t<description>$description</description>\n";
						print $OUTXML "\t</item>\n";
					}
					
					# si le titre est déjà dans $dico_des_titres, on ne fait rien
				}
			}
		}
    }
}

#----------------------------------------------
# procédure nettoyage
sub nettoyage {
    #my $titre=shift(@_); autre solution en vidant la liste des arguments du programmes...
    #my $description=shift(@_);
    my $titre = $_[0];
    my $description = $_[1];
	$titre=~s/^<!\[CDATA\[//;
	$titre=~s/\]\]>$//;
	$description=~s/^<!\[CDATA\[//;
	$description=~s/\]\]>$//;
    $description=~s/&lt;.+?&gt;//g;
    $description=~s/&#38;#39;/'/g;
    $description=~s/&#38;#34;/"/g;
	$description=~s/’/'/g;
	$description=~s/\s\s+/ /g;
    $titre=~s/&lt;.+?&gt;//g;
    $titre=~s/&#38;#39;/'/g;
    $titre=~s/&#38;#34;/"/g;
	$titre=~s/’/'/g;
	$titre=~s/\s\s+/ /g;
    $titre=~s/$/\./g;
	$titre=~s/\.+$/\./g;
    return $titre,$description;
}
