﻿#!/usr/bin/perl
<<DOC; 
 Charlène DENIS & Larisa NADEL
 JUIN 2012
 usage : perl parcours-arborescence-fichiers repertoire-a-parcourir
 Le programme prend en entrée le nom du répertoire contenant les fichiers
 à traiter qui sont les fils RSS.
 Il en extrait l'information textuelle et l'enregistre dans une sortie texte brut et une sortie xml.
 Pour chaque article d'émission RSS, on obtient un élément xml qui comporte deux sous-éléments : le titre et la description.
 <article><abstract>titre de l'article</abstract><description>contenu</description></article>
DOC

#-----------------------------------------------------------------------

#On utilise la bibliothèque Unicode::String avec le module utf8
use Unicode::String qw(utf8); 

#-------------------------CHOIX DU RÉPERTOIRE---------------------------

#On récupère le nom du répertoire à parcourir
my $rep="$ARGV[0]";
#On enlève le slash final éventuel	
$rep=~ s/[\/]$//;
	
#------------------------DEFINITION DES VARIABLES-----------------------

#Dans les variables DUMPFULL on va stocker les résultats d'extraction
my $DUMPFULL_XML="";	
my $DUMPFULL_TXT="";
#Les variables $n_article et $i sont des compteurs
my $n_article=0;
my $i=0;
#Les variables %titleDic et %descrDic sont des tableaux associatifs permettant d'éviter les doublons entre les articles extraits	
my %titleDic=();	
my %descrDic=();

my $encodagesortiexml="utf-8";
my $encodagesortietxt="iso-8859-1";	

#------------------------OUVERTURE DES FICHIERS DE SORTIE-----------------

#On ouvre le fichier de sortie xml
open (FILEOUT_XML,">:encoding($encodagesortiexml)","sort1.1.xml") or die "pb ouverture fichier $!";

#On ouvre le fichier de sortie txt
open (FILEOUT_TXT,">:encoding($encodagesortietxt)","sort1.1.txt") or die "pb ouverture fichier $!";	

#On lance la fonction parcoursarborescencefichiers qui permet de parcourir le répertoire qu'on lui donne en entrée
#Cette fonction sera initialisée plus bas car Perl le permet
#Si cette fonction trouve un dossier, elle l'ouvre et continue de parcourir ce répertoire de manière récursive 
#Si cette fonction trouve un fichier, elle effectue l'extraction
&parcoursarborescencefichiers($rep);
	
#On formate la sortie : fichier xml avec en-tête et on intègre le contenu de la variable contenant le filtrage réalisé par la fonction 
print FILEOUT_XML "<?xml version=\"1.0\" encoding=\"$encodagesortiexml\" ?>\n";
print FILEOUT_XML "<PARCOURS>\n";
print FILEOUT_XML "<NOM>Denis, Nadel</NOM>\n";
print FILEOUT_XML "<FILTRAGE>".$DUMPFULL_XML."</FILTRAGE>\n";
print FILEOUT_XML "</PARCOURS>\n";
#On ferme
close(FILEOUT_XML);	
print FILEOUT_TXT $DUMPFULL_TXT;
close(FILEOUT_TXT);
#On sort
exit;	

#------------------------PARCOURS DES FILS RSS--------------------------

#On initialise la fonction parcoursarborescencefichiers 
sub parcoursarborescencefichiers {

	#La variable prédéfinie de Perl @_ stocke les arguments passés à la fonction
	#On récupère le seul argument contenu dans cette liste grâce à la fonction shift()
	my $path = shift(@_);
    	opendir(DIR, $path) or die "can't open $path: $!\n";

	#La liste @files contient ce qu'on trouve dans le répertoire    	
	my @files = readdir(DIR);	
    	closedir(DIR);

	#On teste chaque élément de cette liste	
    	foreach my $file (@files) {	
		next if $file =~ /^\.\.?$/;	
		$file = $path."/".$file;

		#Si c'est un dossier : on le parcourt de façon récursive	
		if (-d $file) {		
			&parcoursarborescencefichiers($file);	
	}	
		#Si c'est un fichier : on extrait le contenu
		if (-f $file) {	

#------------------------TRAITEMENT DU FILTRAGE--------------------------
			
			#Ce traitement ne s'applique qu'aux fichiers xml
			if ($file=~/\.xml$/) {	
				print $i++,"\n";

				#On vérifie l'encodage grâce à la commande shell file
				my $encodage=`file -i $file | cut -d= -f2`;

				#La fonction chomp très utile permet d'enlever les éventuels retours à la ligne : on l'utilisera partout ! 
				chomp($encodage); 
				print "ENCODAGE: $encodage \n";
				
				#On ouvre le fichier en mode lecture grâce au <:	
				open (FILEIN, "<:encoding($encodage)",$file);
				my $texte="";

				#Et on le lit ligne par ligne
				while (my $ligne=<FILEIN>){
					chomp($ligne);
					#Par une expression régulière, on supprime les espaces entre les balises 	
					$ligne=~ s/> *</></g;
					#On concatène toutes les lignes dans la variable $texte 
					$texte.=$ligne;
				}
				
				#Tout d'abord, on extrait par un regexp l'information de publication du fichier
				$texte=~/<channel>.+?<pubDate>(.+?)<\/pubDate>/;
				my $donnees=$1;

				#Et on commence à enregistrer dans $DUMPFULL_XML les balises xml qui sortiront dans le fichier final
				$DUMPFULL_XML.="<FILE numero=\"$i\"><DATE>$donnees<\/DATE><ARTICLES>";

				#A chaque fois que le programme trouve une correspondance entre le contenu de la variable $texte et le patron défini par l'expression régulière suivante, il en extrait les parties nécessaires 
				while ($texte=~/<item>.+?<title>(.+?)<\/title>.+?<description>(.+?)<\/description>.+?<pubDate>(.+?)<\/pubDate>/g)
				{

					#On stocke ces informations nécessaires dans les variables suivantes
					my $titre=$1;
					my $description=$2;										
					
					#On applique une fonction de nettoyage du texte sur le contenu de ces variables
					$titre=&nettoieText($titre);
					$description=&nettoieText($description);
					#$donnees=&nettoieText($donnees);

					#On incrémente le compteur 
					$n_article++;

					#Le n° d'article est enregistré dans $DUMPFULL_XML comme argument de l'élément article 
					$DUMPFULL_XML.="<article numero=\"$n_article\">\n";
				        
					#Si l'encodage trouvé n'est pas de l'utf8, on le convertit en utf8 
					if (uc($encodage) ne "UTF-8") {utf8($titre);utf8($description);}

					#On détecte les doublons entre les titres et les contenus des articles
					#Si c'est nouveau, on l'ajoute
					if (!(exists($titleDic{$titre}))) {
				    		$DUMPFULL_XML.="<abstract>$titre</abstract>";
				    		$DUMPFULL_TXT.=$titre."\n";
				    		$titleDic{$titre}++;
					}
					#Si non, on remplace par un vide
					else {
				   		$titleDic{$titre}++;
				    		$DUMPFULL_XML.="<abstract>-</abstract>\n";
					}
					#Encore une fois, si c'est nouveau, on l'ajoute...
					if (!(exists($descDic{$description}))) {
				    		$DUMPFULL_XML.="<description>$description</description>\n";
					    	$DUMPFULL_TXT.=$description."\n";
						$descDic{$description}++;
					}
					#Et si non, on remplace par un vide
					else {
				    		$descDic{$description}++;
				    		$DUMPFULL_XML.="<description>-</description>\n";
					}
					
					#Si le fichier contenait des articles, on ajoute </article>
					if ($texte=~/<\/item>/){
					    $DUMPFULL_XML.="</article>";
					    }
					
				}
				#Finalement, les balises fermantes sont ajoutées
				$DUMPFULL_XML.="</ARTICLES></FILE>";
		}
		close (FILEIN);
	}
    }
}

#------------------------FONCTION DE NETTOYAGE---------------------------

#Initialisation de la fonction fournie pour le nettoyage du texte
sub nettoieText {
    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;
    $texte=~s/]]>//g;
    return $texte;
}
