<<DOC;
Uyên-To DOAN-RABIER
Ruixin HE
Mohamed Sofiane KERROUA

BàO - Xpath

En utilisant des expression régulière et le module Xpath, produit en sortie des fichiers contenant les résumés de fils rss 
contenus dans des fichiers xml dans une arborescence donnée. 

usage : bao1_xpath.pl nom_du_répertoire

DOC

#/usr/bin/perl
#use strict;
#use warnings;
use Unicode::String qw(utf8);
use XML::XPath;

#-----------------------------------------------------------
# Procédure principale
#-----------------------------------------------------------
#Les fichiers sont créés dans un répertoire "resultat"
mkdir(resultat); 

#-----------------------------------------------------------
# on initialise une variable $rep contenant le flux de sortie 
my $rep="$ARGV[0]";
# on s'assure que le nom du répertoire ne se termine pas par un "/"
$rep=~ s/[\/]$//;

#-----------------------------------------------------------
# Initialisation d'un tableau de hash évitant la répétition du contenu des fils rss
my %tabcontenu = ();
&parcoursarborescencefichiers($rep);	#recurse!

#-----------------------------------------------------------
$cheminrep ="./resultat";
# On ouvre le répertoire "résultat" contenant les fichiers de sortie xml et txt
# On ajoute à chaque fichier xml la balise fermante </file>
# On convertit chaque fichier txt en iso-8859-1 et on le place dans le dossier cordial
opendir(DIRS,$cheminrep) or die "can't open $cheminrep: $!\n";
my @files = readdir(DIRS);
closedir(DIRS);
foreach my $fichier(@files){
	next if $fichier =~ /^\.\.?$/;
			# A chaque fichier xml crée en sortie on ajoute la balise fermante </file>
			if($fichier =~/\.xml$/){
				open(OUT,">>:encoding(utf-8)","./resultat/$fichier");
				print OUT "</file>\n";
				close(OUT);
			}
}

exit; # Fin du programme

#-----------------------------------------------------------
# Procédure "parcoursarborescencefichiers"
# Parcours une arborescence et traite chaque fichier xml contenant des fils rss 
# Donnée : un répértoire passé en paramétre par valeur
# Résultats : - le résultat du traitement au format txt
#			  - le résultat du traitement au format xml
#             - le résultat du traitement au format xml avec un étiquetage réalisé tree-tagger
sub parcoursarborescencefichiers {
#-----------------------------------------------------------
# Récupération du répertoire et ouverture du répertoire
    my $path = shift(@_);
    opendir(DIR, $path) or die "can't open $path: $!\n";
    my @files = readdir(DIR);
    closedir(DIR);
	
#-----------------------------------------------------------
# Traitement de chaque fichier contenu dans le répertoire
    foreach my $file (@files) {
		next if $file =~ /^\.\.?$/;
		$file = $path."/".$file;
# Si on tombe sur un répertoire on relance la procédure
		if (-d $file) {
			&parcoursarborescencefichiers($file);	#recurse!
		}
		
#-----------------------------------------------------------		
# Traitement du fichier	
		if (-f $file) {
# Si le fichier est un fichier xml et si ce fichier xml n'est pas un fichier ne contenant pas fils rss on le traite
			if(($file=~/\.xml$/) && ($file!~/\/fil.+\.xml$/) && ($file !~/0,2-3404,1-0,0\.xml$/)){
			
# Initialisation des différentes variables
			my $encodage = "";
			my $encodagesortie="utf-8";
			my $texte="";

#-----------------------------------------------------------
# Si le fichier est vide pas de traitement			
			if(-z $file){
				print "$file est vide pas de traitement\n";
			}else{
			
#-----------------------------------------------------------
# Détection de l'encodage du fichier
			    open(FIC,$file);
				while (my $ligne=<FIC>) {
					$ligne =~ s/\n//g;
					if($ligne =~/(iso-8859-1|utf-8)/ig){
						$encodage = $1;
					}
				}
				close(FIC);

#-----------------------------------------------------------
# Détection de la rubrique en mettant le texte sur une ligne, dans le cas ou il n'y a pas de rubrique ou classe le fichier dans les non-classés				
				open(FILE,"<:encoding($encodage)", $file);
				my $texte="";
				while (my $ligne=<FILE>) {
					$ligne =~ s/\n//g;
					$ligne =~ s/\r//g;
					$texte .= $ligne;
			    }
				
				if($texte =~/<channel><title>([^<]+)<\/title>/ig){
					$rubrique = $1;
					$rubrique=~s/é/e/gi;
					$rubrique=~s/è/e/gi;
					$rubrique=~s/ê/e/gi;
					$rubrique=~s/à/a/gi;
					$rubrique=~ s/Le ?Monde.fr ?://;
					$rubrique=~s/ ?- ?Le ?Monde\.fr//;
					$rubrique=~s/es$/e/i;
					$rubrique=~ s/ //g;
					$rubrique=uc($rubrique);
				}
				
				close(FILE);
				if($rubrique eq ""){
					$rubrique = "NONCLASSE";
				}
				
#-----------------------------------------------------------
# Création des fichiers de sortie
				open(OUT1,">>:encoding(utf-8)","./resultat/$rubrique.txt");
				open(OUT2,">>:encoding(utf-8)","./resultat/$rubrique.xml");

#-----------------------------------------------------------
# Ajout des entêtes et de la balise item dans le fichier de sortie xml	
				if(-z OUT2){
					print OUT2 "<?xml version=\"1.0\" encoding=\"$encodagesortie\" ?>\n";
					print OUT2 "<file>\n";
					print OUT2 "<name>$ARGV[0]</name>\n";
				}

				print OUT2 "<items>\n";

#-----------------------------------------------------------
# Initialisation de la méthode du module xml::xpath
				my $input_file= $file;
				my $xp = XML::XPath->new( filename => $input_file ) or die "big trouble";
				
#-----------------------------------------------------------
# Détection de la date à l'aide des méthodes du module xml::xpath, ajout de la date dans le fichier de sortie xml
				my $date = "";
				my $date_path="//channel";
				foreach my $date_noeud ( $xp->find($date_path)->get_nodelist ) {
					$date=$date_noeud->find('pubDate')->string_value;
				}
				print OUT2 "<date>$date</date>\n";
				
#-----------------------------------------------------------
# Détection du titre et du résumé du fils rss à l'aide des méthodes du module xml::xpath
				my $search_path.="//item";
				foreach my $noeud ( $xp->find($search_path)->get_nodelist ) {
					my $titre=$noeud->find('title')->string_value;
					my $resume=$noeud->find('description')->string_value;
					
#-----------------------------------------------------------
# Appel de la fonction "nettoietexte" avec comme paramétres le titre et le résumé
	                $titre=&nettoietexte($titre);
	                $resume=&nettoietexte($resume);
					my $test=$titre;
					
#-----------------------------------------------------------
# Conversion du titre et du résumé en utf-8 si l'encodage du fichier en entrée ne l'est pas
					if (uc($encodage) ne "UTF-8") {utf8($titre);utf8($resume);}
					
#-----------------------------------------------------------
# Test sur le titre du fil rss, si il est déjà contenu dans le tableau de hash on ne le traite pas
					if(!exists $tabcontenu{$test}){
							
#-----------------------------------------------------------
# On ajoute dans les différents fichiers le titre et le résumé
					        print OUT1 "Titre : $titre \n";
					        print OUT1 "Resume : $resume \n";
					        print OUT2 "<item><title>$titre</title><abstract>$resume</abstract></item>\n";
							       
#-----------------------------------------------------------
# On ajoute dans le tableau de hash le titre du fil rss
							$tabcontenu{$test}++;
					}
				}
				
#-----------------------------------------------------------
# Fermeture de la balise items dans le fichier xml, fermeture des fichiers
				print OUT2 "</items>\n";
				close(OUT1);
				close(OUT2);
			}
		}
		}
	}
} # Fin "parcoursarborescencefichiers"


#-----------------------------------------------------------
# Fonction "nettoietexte"
# Nettoie un texte de ses entités xml
# Donnée : une chaîne de caractère contenant des entités xml
# Résultat : la chaîne de caractères nettoyée de ses entités xml
sub nettoietexte {
    my $texte=shift;
    $texte =~ s/&lt;/</g;
    $texte =~ s/&gt;/>/g;
    $texte =~ s/<a href[^>]+>//g;
    $texte =~ s/<img[^>]+>//g;
    $texte =~ s/<\/a>//g;
    $texte =~ s/&#38;#39;/'/g;
    $texte =~ s/&#38;#34;/"/g;
    $texte =~ s/&#233;/é/g;
    $texte =~ s/&#234;/ê/g;
    $texte =~ s/<[^>]+>//g;
    $texte =~ s/&nbsp;/ /g;
    $texte=~s/&#39;/'/g;
    $texte=~s/&#34;/"/g;
    $texte=~s/&amp;#39;/'/g;
    $texte=~s/&amp;#34;/"/g;
    return $texte;
} # Fin "nettoietexte"