﻿#!/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 les bibliothèques Unicode::String avec le module utf8 et XML::RSS, une bibliothèque spécifique à Perl qui permet de traiter des fils RSS
use Unicode::String qw(utf8);
use XML::RSS;

#-------------------------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/[\/]$//;	

#Dans les variables DUMPFULL on va stocker les résultats d'extraction
my $DUMPFULL_XML="";	
my $DUMPFULL_TXT="";	

#La variable $i est un compteur
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.2.xml") or die "pb ouverture fichier $!";

my $output2="sort1.2.txt";	#on cree une variable qui contiendra la sortie en format txt
open (FILEOUT_TXT,">:encoding($encodagesortietxt)","sort1.2.txt") or die "pb ouverture fichier $!";	

&parcoursarborescencefichiers($rep);	#recurse! : on lance le parcours recursif de l'arbre des fils
#on formate la sortie : fichier XML avec en-tete et on integre le contenu de la variable contenant le filtrage
print FILEOUT_XML "<?xml version=\"1.0\" encoding=\"$encodagesortiexml\" ?>";
print FILEOUT_XML "<PARCOURS>";
print FILEOUT_XML "<NOM>Denis, Ivanova, Nadel</NOM>";
print FILEOUT_XML "<FILTRAGE>".$DUMPFULL_XML."</FILTRAGE>";
print FILEOUT_XML "</PARCOURS>";
#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."\n";

				#On crée un ouvel objet de la bibliothèque XML::RSS
				my $rss=new XML::RSS;

				#Dans la variable $rss, on enregistre les résultats du parsing du fil RSS
				$rss->parsefile($file);

				#On récupère l'information qui se trouve sous le noeud 'pubDate' en définissant le chemin qui permet d'y arriver   
				my $donnees=$rss->{'channel'}->{'pubDate'};
				
				#On vérifie l'encodage et on convertit les données en utf8 si besoin
				if (uc($encodage) ne "UTF8") {utf8($donnees)};
				$donnees=&nettoieText($donnees);
				$DUMPFULL_XML.="<FILE numero=\"$i\">";
				$DUMPFULL_XML.="<DATE>$donnees</DATE>";
				$DUMPFULL_XML.="<ARTICLES>\n";
				
				#La variable $n_article est le compteur des articles dans chaque fichier
				my $n_article=0;

				#Dans cette variante de Bào1, on remplace la boucle while par la boucle foreach afin de parcourir le fichier
				#Pour chaque élément "item" on récupère le titre et la description
				foreach my $item (@{$rss->{'items'}}) {
					my $titre=$item->{'title'};
					my $description=$item->{'description'};
					
					if (uc($encodage) ne "UTF8") {utf8($titre);utf8($description);};
					$titre=&nettoieText($titre);
					$description=&nettoieText($description);
					$n_article++;
					$DUMPFULL_XML.="<article numero=\"$n_article\">";

					#On vérifie les doublons	
					if (!(exists($titleDic{$titre}))) {
				    		$DUMPFULL_XML.="<abstract>$titre</abstract>";
				    		$DUMPFULL_TXT.="Titre: $titre\n";
				    		$titleDic{$titre}++;
					}
					#Si non, on remplace par un vide
					else {
				   		$titleDic{$titre}++;
				    		$DUMPFULL_XML.="<abstract>-</abstract>";
					}
					#Encore une fois, si c'est nouveau, on l'ajoute...
					if (!(exists($descDic{$description}))) {
				    		$DUMPFULL_XML.="<description>$description</description>";
					    	$DUMPFULL_TXT.="Resume: $description\n";
						$descDic{$description}++;
					}
					#Et si non, on remplace par un vide
					else {
				    		$descDic{$description}++;
				    		$DUMPFULL_XML.="<description>-</description>";}

					$DUMPFULL_XML.="</article>";

					}; #Ferme foreach item
				$DUMPFULL_XML.="</ARTICLES></FILE>";
				}; # Ferme if xml
			}; #Ferme -f file
		}; #Ferme foreach file
	} #Ferme sub parcours

#---------------------------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;
    $texte=~s/&/and/;
    return $texte;
}
