#/usr/bin/perl -w
<<DOC;
Marie Garrigue
Sandy Bonin
MARS 2010

 commande : perl bao1.pl 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
DOC
#-----------------------------------------------------------------------------------------------
#On appelle des modules

use XML::RSS;
use HTML::Entities;
#-----------------------------------------------------------------------------------------------
#On récupère, dans une variable "$rep", le nom du répertoire qui a été passé en paramètre au programme

my $rep="$ARGV[0]";
#On normalise l'écriture du nom du répertoire afin de s'assurer qu'il ne se termine pas par un "/"
$rep=~s/[\/]$//;
#On initialise une variable "$DUMPFULL1" qui va contenir le flux de sortie 1
my $DUMPFULL1="";
#On initialise une variable "$DUMPFULL2" qui va contenir le flux de sortie 2
my $DUMPFULL2="";
#-----------------------------------------------------------------------------------------------
#On ouvre en écriture le fichier de sortie 1

my $output1="resultat_bao1.txt";
if (!open (FILEOUT1,">$output1")) {die "Probleme lors de l'ouverture du fichier $output1"};
#On ouvre en écriture le fichier de sortie 2
my $output2="resultat_bao1.xml";
if (!open (FILEOUT2,">$output2")) {die "Probleme lors de l'ouverture du fichier $output2"};
#-----------------------------------------------------------------------------------------------
#On lance le parcours récursif via la procédure "parcoursarborescence" qui prend comme argument la variable "$rep"
#Il va parcourir le répertoire dont le nom a été passé en paramètre au programme

&parcoursarborescence($rep); #Récursivité
#-----------------------------------------------------------------------------------------------
#On formate le fichier de sortie 1 : On intègre le contenu de la variable "$DUMPFULL1"

print FILEOUT1 $DUMPFULL1;
#On ferme le fichier de sortie 1
close(FILEOUT1);
#On formate le fichier de sortie 2 : On écrit l'en-tête du fichier xml et on intègre, entre une balise ouvrante "<rss>" et sa balise fermante, le contenu de la variable "$DUMPFULL2"
print FILEOUT2 "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>\n";
print FILEOUT2 "<xml>\n";
print FILEOUT2 "<rss>".$DUMPFULL2."</rss>\n";
print FILEOUT2 "</xml>\n";
#On ferme le fichier de sortie 2
close(FILEOUT2);
#On sort du programme
exit;
#-----------------------------------------------------------------------------------------------
#PROCEDURES
#-----------------------------------------------------------------------------------------------
#On crée la procédure "parcoursarborescence"

sub parcoursarborescence {
#On utilise la variable prédéfinie "@_" (Aussi appelée Tableau spécial) afin de récupérer les arguments (Ici le nom du répertoire) passés en paramètre à la procédure
my $path=shift(@_);
#On ouvre le répertoire
opendir(DIR,$path) or die "Probleme lors de l'ouverture de $path: $!\n";
#On récupère le contenu du répertoire
my @contenurep=readdir(DIR);
#On ferme le répertoire
closedir(DIR);
#Pour chaque élément contenu dans le répertoire, on vérifie son type (Fichier ou Répertoire)
foreach my $element(@contenurep) {
#On passe au suivant si l'élément contient un point ou deux points
next if $element=~/^\.\.?$/;
#On affecte à la variable "$element" le chemin complet de l'élément
$element=$path."/".$element;
#Si l'élément est un répertoire, on effectue les opérations suivantes
if (-d $element) {
#On relance le parcours via la procédure "parcoursarborescence" qui prend comme argument la variable "$element"
&parcoursarborescence($element); #Récursivité
}
#Si l'élément est un fichier, on effectue les opérations suivantes
if (-f $element) {
#On lance la procédure "filtrage" qui prend comme argument la variable "$element"
&filtrage($element);
}
}
}
#-----------------------------------------------------------------------------------------------
#On crée la procédure "filtrage"

sub filtrage {
#On affecte à la variable "$element" le contenu de la variable passée en paramètre à la procédure
my $element=shift;
#Si le fichier fait parti de la rubrique "International", on effectue les opérations suivantes
if ($element=~/0,2-3210,1-0,0.xml/) {
#On crée une variable "$rss"
my $rss=new XML::RSS;
#On crée une variable vide "$TEXTEDUFIL"
my $TEXTEDUFIL="";
#On ajoute à la suite du contenu de la variable "$TEXTEDUFIL" une balise ouvrante "<file>" qui a un attribut "id" dont la valeur est le contenu de la variable "$element"
$TEXTEDUFIL.="<file id=\"$element\">\n";
#On met les articles contenus dans le fichier dans la variable "$rss"
$rss->parsefile($element);
#On crée un compteur "$nombrearticles" qui va contenir le nombre d'articles présents dans le fichier et on l'initialise à 0
my $nombrearticles=0;
#Pour chaque article dans la variable "$rss", on effectue les opérations suivantes
foreach my $item (@{$rss->{'items'}}) {
#On met le contenu de la balise "<title>" de l'article dans une variable "$title"
my $title=$item->{'title'};
#On lance la procédure "nettoyage" qui prend comme argument la variable "$title"
$title=&nettoyage($title);
#Si la table de hachage "$dicoarticles" contient déjà la clé contenue dans la variable "$title" et si la variable "$title" n'est pas vide, on effectue les opérations suivantes
if ((!(exists($dicoarticles{$title})))&&($title ne "")) {
#On incrémente le compteur "$nombrearticles"
$nombrearticles++;
#On ajoute à la suite du contenu de la variable "$TEXTEDUFIL" une balise ouvrante "<article>" qui a un attribut "id" dont la valeur est le numéro de l'article
$TEXTEDUFIL.="<article id=\"$nombrearticles\">\n";
#On ajoute à la suite de la variable "$TEXTEDUFIL" la balise ouvrante "<title>", le contenu de la variable "$title" et la balise fermante "</title>"
$TEXTEDUFIL.="<title>".$title."</title>\n";
#On ajoute à la suite de la variable "$DUMPFULL1" le contenu de la variable "$title"
$DUMPFULL1.=$title."\n";
#On met le contenu de la balise "description" dans une variable "$description"
my $description=$item->{'description'};
#On lance la procédure "nettoyage" qui prend comme argument la variable "$description"
$description=&nettoyage($description);
#On ajoute à la suite de la variable "$TEXTEDUFIL" la balise ouvrante "<description>", le contenu de la variable "$description", la balise fermante "</description>" et la balise fermante "</article>"
$TEXTEDUFIL.="<description>".$description."</description>\n</article>\n";
#On ajoute à la suite de la variable "$DUMPFULL1" le contenu de la variable "$description"
$DUMPFULL1.=$description."\n";
#On ajoute à la table de hachage "$dicoarticles" la clé "$title" qui a pour valeur "1"
$dicoarticles{$title}=1;
}
#Sinon, on effectue les opérations suivantes
else {
#On incrémente la valeur de la clé "$title" contenu dans la table de hachage "$dicoarticles"
$dicoarticles{$title}++;
}
}
#On ajoute à la suite de la variable "$DUMPFULL2" le contenu de la variable "$TEXTEDUFIL" et la balise fermante "</file>"
$DUMPFULL2.=$TEXTEDUFIL."</file>\n";
}
}
#-----------------------------------------------------------------------------------------------
#On crée la procédure "nettoyage"

sub nettoyage {
#On affecte à une variable "$nett" le contenu de la variable passée en paramètre à la procédure
my $nett=shift;
#On utilise le module HTML::Entities afin de décoder les entités html
$nett=HTML::Entities::decode($nett);
#On remplace le caractère "&" par la chaîne de caractères "and"
$nett=~s/&/ and /g;
#On supprime les balises html
$nett=~s/<(.+)>//g;
#On remplace les espaces qui se suivent par un seul espace
$nett=~s/[ ]+/ /g;
#Si le contenu de la variable "$nett" se termine par un caractère alphanumérique ou par des guillemets, on effectue les opérations suivantes
if ($nett=~/[[:alnum:]"]$/) {
#On ajoute un point à la fin du contenu de la variable "$nett"
$nett.=".";
}
#On remplace la chaîne de caractères "Retrouvez l'ensemble des dépêches sur http://www.lemonde.fr" par rien
if ($nett eq "Retrouvez l'ensemble des dépêches sur http://www.lemonde.fr") {$nett=""};
#On retourne le contenu de la variable "$nett"
return $nett;
}