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

<<DOC; 
Thomas MORAINE, Francesca ERVAS, Ardas KHALSA  
FEVRIER 2012
usage : perl scriptarborescence.pl repertoire-a-parcourir
BAO 2
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 résumé de l'article
	-un fichier au format XML contenant les flux RSS avec un numéro attribué à l'article en ordre croissant, le nom du fichier, la date, le titre de l'article et le résumé de l'article
	-un fichier pour le traitement de Cordial et le traitement d'etiquetage de Treetagger		
Les fichiers de sorties sont organise par leur rubrique.
DOC


#------------------------------------------------------------------------------------------
#							CREATION D'UN REPERTOIRE POUR LES FICHIERS DE SORTIE
#-------------------------------------------------------------------------------------

# On va créer un repertoire pour stocker les fichiers de sortie.  En utilisant "use strict" cette instruction renvoie faux si on n'inclut pas d'etoile, parce que l'étoile est ambigu (ça pourrait être compris comme une chaine plutot qu'un repertoire)
mkdir (*RESULTATS);

#-------------------------------------------------------------------------------------------
#							INITIALISATION DES VARIABLES
#-------------------------------------------------------------------------------------------
# On utilise my pour declarer une variable, la variable est $rep qui prendra la valeur de l'argument qui est le premier fichier en ligne de commande, c'est à dire ce programme :
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 numéro de la rubrique :
my $numero="";
#Initialisation d'une variable pour traiter le nom de la rubrique :
my $rubrique="";
#Déclaration des tableaux hash pour enregistrer les titres (1) et les résumés (2) :
my %dico1=();
my %dico2=();
#Initialisation des variables pour stocker les lignes extraites : 
#Format .txt (1) et .xml (2) et treetagger(3)
my $DUMPFULL1="";
my $DUMPFULL2="";
my $DUMPFULL3="";
#Un compteur pour attribuer un numéro à chaque fichier :
my $i=0;
#--------------------------------------------------------------------------------------------
#					LE CHOIX DE LA RUBRIQUE
#--------------------------------------------------------------------------------------------
print "Voici les numeros des rubriques a traiter \n";
print " 0 : A la une\n 1 : International\n 2 : Europe\n 3 : Livres\n 4 : Opinions\n 5 : Cinema\n 6 : Planete\n 7 : Technologies\n 8 : Politique\n 9 : Culture\n 10: Economie\n 11 : Societe\n ALL:* \n\n Quel est votre choix?  ";

# On recupere le choix tapé au clavier et on le stocke dans une variable : 
my $choix_rubrique = <STDIN>;

#On supprime le dernier caractère de retour à la ligne dans le cas ou il y en a un :
chomp($choix_rubrique);

#On va créer des conditions pour attribuer des valeurs au choix de l'utilisateur. 
#Si le choix de l'utilisateur est equivalent a 0 on attribue les valeurs suivantes:
if ($choix_rubrique eq 0){ $numero="3208"; $rubrique="a_la_une";} 
	
elsif ($choix_rubrique eq 1){$numero="3210";$rubrique="international";}
	
elsif ($choix_rubrique eq 2){$numero="3214";$rubrique="europe";}
	
elsif ($choix_rubrique eq 3){$numero="3260";$rubrique="livres";}
	
elsif ($choix_rubrique eq 4){$numero="3232";$rubrique="opinions";}

elsif ($choix_rubrique eq 5){$numero="3476";$rubrique="cinema";}
	
elsif ($choix_rubrique eq 6){$numero="32344";$rubrique="planete";}
	
elsif ($choix_rubrique eq 7){$numero="651865";$rubrique="technologies";}

elsif ($choix_rubrique eq 8){$numero="823353";$rubrique="politique";}

elsif ($choix_rubrique eq 9){$numero="3546";$rubrique="culture";}

elsif ($choix_rubrique eq 10){$numero="3234";$rubrique="economie";}

elsif ($choix_rubrique eq 11){$numero="3224";$rubrique="societe";}

elsif ($choix_rubrique eq "*"){$numero="ALL";$rubrique="toutes_les_rubriques";}
	
# Si ce qui est recuperé n'est pas reconnaissable, on demande à nouveau le choix de l'utilisateur :
else{ 
	print "Je n'ai pas compris.\n"; 
	}  
#--------------------------------------------------------------------------------------------
#					CREATION DE FICHIERS DE SORTIES AVEC L'ENCODAGE IMPOSE
#--------------------------------------------------------------------------------------------
# On initialise une variable contenant le flux de sortie pour le fichier .txt :
my $output1="$rubrique.txt";

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

# On initialise une variable contenant le flux de sortie pour le fichier du traitement treetagger :
my $output3="$rubrique.-treetagger.xml";

# Définition de variable de telle sorte qu'elle contient l'information "utf-8" :
my $encodagesortieXML="utf-8";
# Pour le traitement CORDIAL sur les fichiers .txt on veut l'encodage en ISO :
my $encodagesortieTXT="iso-8859-1";

# On va créer des fichiers de sorties et on va les stocker dans des fichiers, on force l'encodage de sortie (utf-8) :
if (!open(FILEOUT1,">:encoding($encodagesortieTXT)",$output1)) { die "Pb a l'ouverture du fichier $output1.txt"};
if (!open(FILEOUT2,">:encoding($encodagesortieXML)",$output2)) { die "Pb a l'ouverture du fichier $output2.xml"};
if (!open(FILEOUT3,">:encoding($encodagesortieXML)",$output3)) { die "Pb a l'ouverture du fichier $output3.-treetagger.xml"};

# On écrit dans le fichier treetagger (balises XML) :
print FILEOUT3 "<?xml version=\"1.0\" encoding=\"$encodagesortieXML\" ?>\n";
print FILEOUT3 "<ETIQUETAGE rubrique=\"".$rubrique."\">\n";
print FILEOUT3 "<FICHIER numero=\"$numero\">\n";	
#----------------------------------------

&parcoursarborescencefichiers($rep,$numero);	#Appel à la routine indiquée par l'operateur & 

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

# On écrit dans le fichier texte (pas de balises) et on le ferme :
print FILEOUT1 $DUMPFULL1;
close(FILEOUT1);

# On écrit dans le fichier .xml :
print FILEOUT2 "<?xml version=\"1.0\" encoding=\"$encodagesortieXML\" ?>\n";
print FILEOUT2 "<PARCOURS>\n";
print FILEOUT2 "<NOM>ERVAS, KHALSA, MORAINE</NOM>\n";
print FILEOUT2 "<FILTRAGE rubrique=\"".$rubrique."\" numero=\"$numero\">\n".$DUMPFULL2."\n</FILTRAGE>\n";

# Fermeture des fichiers 
print FILEOUT2 "</PARCOURS>\n";
print FILEOUT3 "</FICHIER>\n";
print FILEOUT3 "</ETIQUETAGE>";
close(FILEOUT2);
close(FILEOUT3);
exit;	
#-----------Les sub routines-----------------------------------
#-------------------------------------------------------------------------------------------
#					LES PROCEDURES POUR PARCOURIR L'ARBORESCENCE
#-------------------------------------------------------------------------------------------

# Subroutine pour le script :
sub parcoursarborescencefichiers {
	
    # On va stocker le tableau des arguments ici :
    my ($path, $numero) = @_;
    
    # 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 stocke le contenu du repertoire dans le tableau files :
    my @files = readdir(DIR);
    closedir(DIR);
    
    # Pour chaque fichier on a une liste/array :
    foreach my $file (@files) {
        # Ensuite, on ne va pas traiter les fichiers commencant par .
        next if $file =~ /^\.\.?$/;
        
        # On recupère le chemin d'accès complèt au fichier :
        $file = $path."/".$file;
        
        # On verifie si $file est un repertoire plutot qu'un fichier et on relance la procedure :
        if (-d $file) {
	    
	    # On relance le sous-programme sur $file :
            &parcoursarborescencefichiers($file, $numero);	
        }
        # On verifie si $file est plutot un fichier qu'un repertoire :
        if (-f $file) {
	    
	    # Si le fichier a une extension .xml on applique les choses suivantes :
            if ($file=~/\.xml$/) {
            	
            	# Initialisation de la variable, si file est un fichier :
		my $filef="";
		
		# Traitement pour toutes les rubriques :
		if ($numero eq "ALL") { 
		    $filef=$file;
		}
		
		# Traitement d'une seule rubrique :
		else {
		    if ($file=~/0,2-$numero,1-0,0\.xml$/) {
			$filef=$file;
		    }
		} 
		print "FICHIER TRAITE : $filef \n";
		next if ($filef eq "");
		
		#-------------------------------------------------
		#       TRAITEMENT à realiser sur chaque fichier
		#-------------------------------------------------
		
		$i++;
		
		# On va detecter l'encodage dans chaque fichier RSS/ sur une machine MAC c'est -I, sur d'autres (par exemple WINDOWS) ce serait -i :
		my $encodage=`file -i $file | cut -d= -f2`; 
		
		# Une commande qui travaille sur les chaines de caracteres, supprime les eventuels retour à la ligne, on va créer une ligne :
		chomp($encodage); 
		
		# Initialisation de la méthode du module XML::RSS 
		my $rss=new XML::RSS;
		
		# On stocke les reésultats de parsefile dans la variable $rss, detection de la date à l'aide de la bibliothèque XML::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 infos suivantes :
		$DUMPFULL2.="<FICHIER num=\"$i\">\n";
		$DUMPFULL2.="<DATE>$date</DATE>\n";
		$DUMPFULL2.="<ARTICLES>\n";
		print FILEOUT3 "<DATE>$date</DATE>\n";
		
		# Un compteur pour attribuer un numéro à chaque article :
		my $j=0;
		
		# Une boucle pour recupérer les élements 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);
		    }
		    #----------------------------------------
		    # L'appel de la routine qui 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 et 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 (fichier texte), on ne met pas de retour à la ligne pour que le fichier soit moins gros :
			$dico1{$titre}=1;
			$DUMPFULL1.="Titre: $titre";
			$DUMPFULL2.="<ARTICLE num=\"$j\"><TITRE>$titre</TITRE>";
		    }
		    
		    # Si non, 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: $resume\n";
			$DUMPFULL2.="<RESUME>$resume</RESUME></ARTICLE>\n";
			
		    }
		    else {
			$resume="";
		    }
		    #--------------------------------------------------
		    #        traitement d'etiquetage
		    #--------------------------------------------------
		    
		    # Appel à la fonction &etiquetage avec les paramètres titre, résumé :
		    my ($titreetiquete, $texteetiquete) =&etiquetage ($titre, $resume);
		    
		    # On ajoute dans le fichier treetagger le titre et le résumeé :
		    print FILEOUT3 "$titreetiquete$texteetiquete\n";
		}
		# On ferme les dernières balises dans le fichier de sortie :
		$DUMPFULL2.="</ARTICLES>\n</FICHIER>\n";
		#--------------------------------------------------
		#        fin de traitement du fichier
		#--------------------------------------------------
	    } 
	} 
    }
}
print "fin de fichier";
#------------------------------------------------------------------------------------------
#							TRAITEMENT DE TREETAGGER
#-----------------------------------------------------------------------------------------
# Sub-routine (sous-programme/fonction) pour l'etiquettage du programme treetagger :
sub etiquetage {
    # @_ la liste de paraèetres d'entrée dans cette sub-routine :
    my ($titre,$texte)=@_;
    
    # TRAITEMENT POUR LE TITRE    
    my $codage="utf-8";
    my $tmptag="texteaetiqueter.txt";
    open (TMPFILE,">:encoding(utf-8)", $tmptag);
    print TMPFILE $titre;
    close(TMPFILE);
    
    # Avec la fonction 'tokenise' on produit un fichier avec un mot sur chaque ligne
    # Ensuite on aura pour chaque mot (lemma) sa forme et sa catégorie
    # On n'oublie pas de préciser la version de perl dont on a besoin 
    system("perl tokenise-utf8.pl $tmptag | tree-tagger.exe french-utf8.par -lemma -token -no-unknown -sgml > treetagger.txt");
    
    # On transforme le fichier de sortie en structure XML :
    system("perl treetagger2xml-utf8.pl treetagger.txt $codage ");
    
    # Lecture du resultat tagge en .xml :
    open(OUT,"<:encoding(utf-8)","treetagger.txt.xml");
    my $firstline=<OUT>;
    my $titreetiquete="";
    while (my $l=<OUT>) {
	$titreetiquete.=$l;
    }
    close(OUT);
    
    # TRAITEMENT POUR LE RESUME
    open (TMPFILE,">:encoding(utf-8)", $tmptag);
    print TMPFILE $texte;
    close(TMPFILE);
    
    system("perl tokenise-utf8.pl $tmptag | tree-tagger.exe french-utf8.par -lemma -token -no-unknown -sgml > treetagger.txt");
    system("perl treetagger2xml-utf8.pl treetagger.txt $codage");
    
    # Lecture du résultat taggé en .xml :
    open(OUT,"<:encoding(utf-8)","treetagger.txt.xml");
    my $firstline=<OUT>;
    my $texteetiquete="";
    while (my $l=<OUT>) {
	$texteetiquete.=$l;
    }
    close(OUT);
    
    # On renvoie les résultats :
    return ($titreetiquete,$texteetiquete);
    
}
# Fin d'etiquetage
    
#----------------------------------------------------------------------------
#							NETTOYAGE DU TEXTE
#----------------------------------------------------------------------------
# On nettoie le texte, on remplace certains elements par d'autres :
sub nettoietexte { 
    # Shift prend la première 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; # On renvoie la valeur du texte avec les symboles nettoyés 
}
