﻿#!/usr/bin/perl
use Unicode::String qw(utf8);
use XML::RSS;

<<DOC; 
Thomas MORAINE, Francesca ERVAS, Ardas KHALSA 
FEVRIER 2012
BAO1 - SOLUTION 2 : BIBLIOTHEQUE XML::RSS
usage : perl scriptarborescence.pl repertoire-a-parcourir
Le programme prend en entrée des flux RSS et fait des operations suivantes : un traitement de nettoyage, filtrage et encodage.
En sortie il produit:
	-un fichier au format texte contenant les flux RSS avec sur chaque ligne le titre et le resume de l'article
	-un fichier au format XML contenant les flux RSS avec un numero attribue a l'article en ordre croissant, le nom du fichier, la date, le titre de l'article et le resume de l'article
Les fichiers de sorties sont organise par leur rubrique. 
DOC 

#on va utiliser une bibliotheque qui nous va permettre de recuperer des elements d'un fichier rss
#----------------------------------------------------------------------------------------------------------
#                         L'ENCODAGE & CREATION DE FICHIERS DE SORTIE
#----------------------------------------------------------------------------------------------------------
#Definition de variable de quelle sorte qu'elle contient l'information "utf-8" 
my $encodagesortie="utf-8";

#On va créer des fichiers de sorties et les stocker dans deux fichiers, on force l'encodage de sortie (utf-8)
open(OUT1,">:encoding($encodagesortie)","SORTIE.txt"); 
open(OUT2,">:encoding($encodagesortie)","SORTIE.xml"); 

#----------------------------------------------------------------------------------------------------------
#							TRAITEMENT DU REPERTOIRE
#----------------------------------------------------------------------------------------------------------

#La première fois qu'on declare une variable on utilise my, la variable est $rep qui prendra la valeur de l'argument
my $rep="$ARGV[0]";

#On s'assure que le nom du repertoire ne se termine pas par un "/"
$rep=~ s/[\/]$//;

#Initialisation d'une variable pour traiter le numero qui correspond à la rubrique

#Initialisation d'une variable pour traiter le nom de la rubrique

#Declaration des hash pour enregistrer les titres et un pour les resumes
my %dico1=();
my %dico2=();

#Initialisation des variables pour stocker les lignes extraites, 1 pour le texte, 2 pour le XML
my $DUMPFULL1="";
my $DUMPFULL2="";

#On initialise une variable contenant le flux de sortie pour le fichier txt 
my $output1="SORTIE.txt";

#S'il n'ouvre pas on arrête le programme
if (!open (FILEOUT1,">:encoding($encodagesortie)", $output1)) { die "Pb a l'ouverture du fichier $output1"};

#On initialise une variable contenant le flux de sortie pour le fichier xml
my $output2="SORTIE.xml";

#S'il n'ouvre pas on arrête le programme
if (!open (FILEOUT2,">:encoding($encodagesortie)",$output2)) { die "Pb a l'ouverture du fichier $output2"};

#Un compteur pour attribuer un numéro à chaque fichier
my $i=0;
#----------------------------------------

&parcoursarborescencefichiers($rep);	#recurse!

#----------------------------------------

#On precise le format de sortie à partir des infos suivantes : 
print FILEOUT1 $DUMPFULL1;
close(FILEOUT);
print FILEOUT2 "<?xml version=\"1.0\" encoding=\"$encodagesortie\" ?>\n";
print FILEOUT2 "<PARCOURS>\n";
print FILEOUT2 "<NOM>ERVAS, KHALSA, MORAINE</NOM>\n";
print FILEOUT2 "<FILTRAGE>\n".$DUMPFULL2."\n</FILTRAGE>\n";
print FILEOUT2 "</PARCOURS>\n";
close(FILEOUT2);
exit;

#----------------------------------------------------------------------------------------------------------
#					LES PROCEDURES POUR PARCOURIR L'ARBORESCENCE
#----------------------------------------------------------------------------------------------------------

#subroutine pour le script :
sub parcoursarborescencefichiers {
	
    #Je pense...mnt on est dans le repertoire de l'arborescence
    my $path = shift(@_);
    
    #On ouvre un "directory" repertoire qui s'appèle path, si on arrive pas l'ouvrir on interrompt le programme
    opendir(DIR, $path) or die "can't open $path: $!\n";
    
    #On ouvre les fichier pour les lire
    my @files = readdir(DIR);
    closedir(DIR);
    
    #Pour chaque fichier on a une liste/array
    foreach my $file (@files) {
    	
        #Ensuite, si...
        next if $file =~ /^\.\.?$/;
        $file = $path."/".$file;
        if (-d $file) {
            &parcoursarborescencefichiers($file);	#recurse!
        }
        if (-f $file) {
	    #Si le fichier a une extension xml on applique les choses suivantes:
            if ($file=~/\.xml$/) {
		#-------------------------------------------------
		#       TRAITEMENT a realiser sur chaque fichier
		#-------------------------------------------------
		$i++;
		#On va recupérer l'encodage dans chaque fichier RSS :
		#(avec l'option -I sur mac, -i sur windows)
		my $encodage=`file -I $file | cut -d= -f2`; 
				
		#Une commande qui travaille sur les chaînes de caractères : 
		#On va aussi supprimer les eventuels retours à la ligne :
		chomp($encodage); 
		
		#Création d'une variable pour instancier un objet RSS
		my $rss=new XML::RSS;
		
		#On stocke les résultats de "parsefile" dans la variable $rss
		$rss->parsefile($file);
		my $date=$rss->{'channel'}->{'pubDate'};
		if (uc($encodage) ne "UTF-8") {
		    utf8($date);
		};
		
		#On écrit dans le fichier de sortie .xml les informations suivantes:
		$DUMPFULL2.="<FICHIER num=\"$i\">\n";
		$DUMPFULL2.="<DATE>$date</DATE>\n";
		$DUMPFULL2.="<ARTICLES>\n";
		#Un compteur pour attribuer un numero a chaque article
		my $j=0;
		#Une boucle pour recupérer les elements d'item
		foreach my $item (@{$rss->{'items'}}) {
		    my $titre=$item->{'title'};
		    my $resume=$item->{'description'};
		    if (uc($encodage) ne "UTF-8") {
			utf8($titre);
			utf8($resume);
		    }
		    #On va nettoyer le titre et le résumé :
		    $titre = &nettoietexte($titre);
		    $resume = &nettoietexte($resume);
		    #S'il y a un titre dans le premier flux dans dico1 
			#qui n'est pas le même que le deuxième flux, on traite :
		    if ((!(exists($dico1{$titre}))) && ($titre ne "")) {
		    #Incrémentation du compteur :
			$j++;
			
			#On concatène dans dumpfull dans le fichier .txt :
			$dico1{$titre}=1;
			$DUMPFULL1.="$titre";
			$DUMPFULL2.="<ARTICLE num=\"$j\"><TITRE>$titre</TITRE>";
		    }
		    #Sinon il n'y a pas de titre, on écrit rien :
		    else {
			$titre="";
		    }
		    #S'il n'y a pas déjà le même résumé dans dico2 
			#et le résumé qu'on traite n'est pas vide, on continue :
		    if (!(exists($dico2{$resume})) && ($resume ne "")) { 
			$dico2{$resume}=1;
			$DUMPFULL1.="$resume";
			$DUMPFULL2.="<RESUME>$resume</RESUME></ARTICLE>\n";
			}
		    else {
			$resume="";
		    }
		    #On concatène dans le fichier .xml les informations :
		    #if (!exists($titre ne "") && ($resume ne "")) {
		    	#$DUMPFULL2.=""
		    #}
		    #else{
		    #$DUMPFULL2.="<ARTICLE num=\"$j\"><TITRE>$titre</TITRE><RESUME>
			$resume</RESUME></ARTICLE>\n";
		    #}
		}
		#On ferme les dernières balises dans le fichier de sortie :
		$DUMPFULL2.="</ARTICLES>\n</FICHIER>\n";
		#--------------------------------------------------
		#        fin de traitement du fichier
		#--------------------------------------------------
	    }
	}
    }
}

#----------------------------------------------------------------------------------------------------------
#							NETTOYAGE DU TEXTE
#----------------------------------------------------------------------------------------------------------

#On nettoie le texte, on remplace certains elements par d'autres 
sub nettoietexte { 
    #Shift prend la 1ere valeur de la liste (eng= array) et l'enlève (shifts it off) et retourne une valeur de la liste, moins la première valeur, on se balade dans le texte
    my $texte=shift; 
    $texte =~ s/&lt;/</g; #On remplace &lt par l'element correspondant
    $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;/&/g;
    $texte =~ s/&amp;#39;/'/g;
    $texte =~ s/&#39;/'/g;
    $texte =~ s/&#38;#34;/"/g;
    $texte =~ s/&amp;#34;/"/g;
    $texte =~ s/&#34;/"/g;
    $texte =~ s/&#91;/[/g;
    $texte =~ s/&#93;/]/g;
    $texte =~ s/<[^>]+>//g; #On supprime les balises fermantes
    $texte =~ s/&nbsp;//g; #On supprime les blancs
    return $texte;
}


