#/usr/bin/perl
use Unicode::String qw(utf8); # on insère le module Unicode::String
use HTML::Entities; # on insère le module HTML::Entities
use utf8; # on précise l'encodage utilisé dans le programme
use open qw/:std :utf8/; # on ouvre tous les fichiers encodés en UTF-8

<<DOC;
Loïc Dumonet - Amélie Martin - Yuan Wei :
MAI 2013
 usage : perl parcours-arborescence-fichiers1 repertoire-a-parcourir
 Le programme prend en entrée le nom du répertoire contenant les fichiers
 à traiter
 Le programme construit en sortie un fichier XML structuré les titres et descriptions issus du filtrage d'un flux RSS:
<PARCOURS><THEME theme=nom rubrique><FILTRAGE><TITRE>contenu</TITRE><DESCRIPTION>contenu</DESCRIPTION></FILTRAGE></THEME></PARCOURS>
DOC
#-----------------------------------------------------------
# on récupère le nom du dossier ou du fichier passé en argument
my $rep="$ARGV[0]";
# on s'assure que le nom du répertoire ne se termine pas par un "/"
$rep=~ s/[\/]$//;
# on déclare les tableaux associatifs permettant de traiter la duplication des contenus
my %dicoDescription=();
my %dicoTitre=();
# on déclare les tableaux associatifs permettant de numéroter les ficheirs et les item traités
my %dicoTheme=();
my %dicoThemeFile=();
#----------------------------------------
# on envoie une instruction au système (unix) pour créer les dossiers où seront stockés les sorties XML et texte brut
system("mkdir bao2-1");
system("mkdir bao2-1/fichiers_xml bao2-1/fichiers_txt");

#----------------------------------------
&parcoursarborescencefichiers($rep); # appel du sous-programme qui s'exécutera de façon récursive
#----------------------------------------

# on insère les balises de fermeture pour chacun des fichiers xml construits par le programme
#  on parcourt le dossier contenant les sorties XML en exécutant une commande unix dont le résultat sera rangé dans une variable
my @nom_fichier_xml=`ls bao2-1/fichiers_xml/`;
# on récupère chaque fichier dans une liste
foreach my $xml (@nom_fichier_xml) {
    # on supprime le saut de ligne inséré automatiquement à la fin des noms de fichiers lorsqu'on exécute la commande 'ls'
    chomp $xml;
    # on ouvre chacun d'eux en concaténation pour y insérer les balises fermantes manquantes (sinon le document XML sera mal formé)
    open (THEME1, ">>:encoding(utf8)", "bao2-1/fichiers_xml/".$xml) or die "Erreur lors de l'ouverture du fichier $xml : $!";
    print THEME1 "</THEME>\n</PARCOURS>\n";
	# on ferme les fichiers (un par un)
    close(THEME1);
}
# même manipulation avec les sorties texte brut pour fermer les fichiers ouverts créés par le programme
my @nom_fichier_txt=`ls bao2-1/fichiers_txt/`;
foreach my $txt (@nom_fichier_txt) {
    chomp $txt;
    open (THEME2, ">>:encoding(utf8)", "bao2-1/fichiers_txt/".$txt); or die "Erreur lors de l'ouverture du fichier $txt : $!";
    close(THEME2);
}
# on sort du programme	
exit;
#----------------------------------------------
# déclaration du sous-programme 'parcoursarborescencefichiers'
sub parcoursarborescencefichiers {
    # on crée une variable qui va contenir le chemin absolu ddu dossier contenant les fichiers qui vont être traités
    my $path = shift(@_);
    # ouverture du dossier via la variable précédente
    opendir(DIR, $path) or die "can't open $path: $!\n";
    # on crée une liste qui va contenir les éléments (noms des fichiers et/ou répertoires) contenus dans ce répertoire
    my @files = readdir(DIR);
    # on ferme le répertoire exploré
    closedir(DIR);
    # pour chaque élément :
    foreach my $file (@files) {
    # (on ne prend pas en compte les éléments cachés : fichiers ou dossiers commençant par un ou deux points; on passe à l'élément suivant)
	next if $file =~ /^\.\.?$/;
	# on indique le chemin absolu du premier élément traité
	$file = $path."/".$file;
	# si l'élément est une répertoire, on recommence la procédure précédente
	if (-d $file) {
	    &parcoursarborescencefichiers($file);	#recurse!
	}
	# si c'est un fichier, on commence le traitement
	if (-f $file) {
        # on initialise une variable qui contiendra le flux de sortie xml et une autre pour les sorties en texte brut
        my $DUMPFULL1="";
        my $DUMPFULL2="";
		# on initialise une variable pour identifer le début d'un fichier (récupération du nom de la rubrique)
        $i=1;
        # on crée une variable qui contiendra le contenu du fichier XML traité
		my $texte="";
		# on ne traite que les fichiers XML, qui ne commencent pas par un 'f' (contenu inutile pour le traitement), et qui ne sont pas vides
		if ($file=~/^[^f]+\.xml$/ && !(-z $file)) {
			# ouverture du fichier XML
            open (FILE, $file);
            # on récupère l'encodage contenu dans la première ligne d'un fichier XML après l'attribut 'encoding'
            $firstline=<FILE>;
            if ($firstline=~/encoding=['"]([^\"']+)['"]/) {
            # on isole l'encodage seul (sans ls guillemets)
                $encodage=$1;
            }
            close(FILE);
            # ouverture du fichier dans cet encodage pour éviter les problèmes d'affichage
            open (FILE, "<:encoding($encodage)", $file) or die "Erreur lors de l'ouverture du fichier $file : $!";
			# on parcourt les lignes du fichier et on supprime les sauts de lignes
			while (my $ligne=<FILE>) {
				$ligne=~s/\n//g;
				$texte.=$ligne;
		    }
            close (FILE);
			# on cherche les items contenant une balise '<title>' et une balise '<description>'
		    while ($texte=~/(<item>|<channel>)<title>(.+?)<\/title>.+?<description>(.+?)<\/description>/g) {
				if ($i==1) {
                    if ($texte=~/<title>(.+?) - LeMonde.fr<\/title>|Le Monde.fr : (.+?)<\/title>/i) {
						# on récupère le résultat de l'expression régulière
						$rub=$&;
						# on supprime tout sauf le nom de la rubrique
						$rub=~s/<title>| |-|LeMonde\.fr<\/title>|Le|Monde\.fr : |<\/title>//gi;
						$theme=$rub;
						$theme_clear=$theme;
						# on supprime les éventuels espaces
						$theme_clear=~s/ /_/g;
						# on unifie la rubrique économie écrite avec deux représentations différentes (initiale avec et sans accent)
						if ($theme_clear eq "Economie") {
                            $theme_clear="Économie";
                        }
						# si le fichier XML de la rubrique traitée existe
						#  on ouvre le fichier XML en concaténation
						if (-e "bao2-1/fichiers_xml/".$theme_clear.".xml") {
							open (THEME1, ">>:encoding(utf8)", "bao2-1/fichiers_xml/".$theme_clear.".xml") or die "Erreur lors de l'ouverture du fichier $theme_clear.xml : $!";
							open (THEME2, ">>:encoding(utf8)", "bao2-1/fichiers_txt/".$theme_clear.".txt") or die "Erreur lors de l'ouverture du fichier $theme_clear.txt : $!";
							$i++;
						}
						#  sinon on crée le fichier XML associée à cette rubrique
						else {
							open (THEME1, ">:encoding(utf8)", "bao2-1/fichiers_xml/".$theme_clear.".xml") or die "Erreur lors de l'ouverture du fichier $theme_clear.xml : $!";
							open (THEME2, ">:encoding(utf8)", "bao2-1/fichiers_txt/".$theme_clear.".txt") or die "Erreur lors de l'ouverture du fichier $theme_clear.txt : $!";
							# on inscrit dans chacun des fichiers XML et texte brut les informations suivantes (ouverture d'un document XML)
							print THEME2 "Thème : $theme_clear. \n";
							print THEME1 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n";
							print THEME1 "<PARCOURS>\n";
							print THEME1 "<NOM>Loïc</NOM>\n";
							print THEME1 "<THEME theme='".$theme_clear."'>\n";
							$i++;
						}
                    }
                }
                else {
					# on crée deux fichiers textes auxiliaires, un pour le titre et un pour la description
					open (TEMP, ">:encoding(utf8)", "templates.txt");
					open (TEMP1, ">:encoding(utf8)", "templates1.txt");
					# On précise l'encodage en UTF-8
                    if (uc($encodage) ne ("UTF-8")) {
						utf8($3);
						utf8($2);
					}
					# on traite le contenu textuel du titre
                    if ($2 ne "") {
						# on numérote chaque item
                        if (!exists $dicoTheme{$theme_clear}) {
                        $dicoTheme{$theme_clear}=1;
                        }
                        else {
                        $dicoTheme{$theme_clear}++;
                        }
						# on nettoie le texte grâce au sous-programme 'entite'
						my $recup=&entite($2);
						# si le titre traité n'existe pas dans la table de hashage alors on le traite
						if (!exists $dicoTitre{$recup}) {
							$dicoTitre{$recup}++;
							# on inscrit le contenu du titre dans un fichier texte auxiliaire
							print TEMP $recup;
							#export PATH=$PWD:$PATH
							# le contenu de ce fichier va être étiqueter par tree tagger
							system("perl tt/cmd/tree-tagger-french-utf8 templates.txt > templates-tt.txt");
							# on crée une sortie XML étiquetée grâce au petit programme treetagger2xml-utf8.pl
							system("perl tt/treetagger2xml-utf8.pl templates-tt.txt utf-8");
							# on range dans une variable le contenu de la sortie produite
							$contenu_titre_xml=`cat templates-tt.txt.xml`;
							$contenu_titre_txt=`cat templates-tt.txt`;
							# on sauvegarde ces résultats insérés dans un balisage XML
							$DUMPFULL1.="<item number='".$dicoTheme{$theme_clear}."'>\n<titre>\n".$contenu_titre_xml."</titre>\n";
							$DUMPFULL2.=$contenu_titre_txt."\n";
						}
						# sinon pas de traitement (balises vide)
						else {
							$DUMPFULL1.="<item number='".$dicoTheme{$theme_clear}."'>\n<titre>-</titre>\n";
							$DUMPFULL2.="";
						}
                    }
					# Même procédure pour la description
                    if ($3 ne "") {
						my $recup2=&entite($3);
						if (!exists $dicoDescription{$recup2}) {
							$dicoDescription{$recup2}++;
							print TEMP1 $recup2;
							#export PATH=$PWD:$PATH
							system("perl tt/cmd/tree-tagger-french-utf8 templates1.txt > templates-tt.txt");
							system("perl tt/treetagger2xml-utf8.pl templates-tt.txt utf-8");
							$contenu_description_xml=`cat templates-tt.txt.xml`;
							$contenu_description_txt=`cat templates-tt.txt`;
							$DUMPFULL1.="<description>\n".$contenu_description_xml."</description>\n</item>\n";
							$DUMPFULL2.=$contenu_description_txt."\n";
						}
						else {
							$DUMPFULL1.="<description>-</description>\n</item>\n";
							$DUMPFULL2.="";
						}
					}
					# fermeture des fichiers textes auxiliaires
					close (TEMP);
					close (TEMP1);
				}
				# on numérote le nombre de fichiers par rubrique
				if (!exists $dicoThemeFile{$theme_clear}) {
					$dicoThemeFile{$theme_clear}=1;
				}
				else {
					$dicoThemeFile{$theme_clear}++;
				}
				# on insère dans les fichiers XML et texte brut finaux ces différentes données avec le balisage XML
				print THEME1 "<FILTRAGE file='".$dicoThemeFile{$theme_clear}."' name='".$file."'>\n".$DUMPFULL1."</FILTRAGE>\n";
				print THEME2 $DUMPFULL2;
			}
		# on réinitialise la variable d'identification du début de fichier
	    $i=0;
		}
    }
}

# sous-programme de nettoyage :
sub entite {
    # décodage d'entités HTML/XML via le module HTML::Entities
    my $extraction=HTML::Entities::decode(HTML::Entities::decode(shift(@_)));
    # suppression des balises inutiles ainsi que des éléments inutiles
    $extraction=~s/<p>|<\/p>|<a[^<]+>|<img[^<]+\/>|<\/a>|<!\[CDATA\[|\]\]>|<br\/>//g;
    # suppression des éventuels sauts de ligne selon le système d'exploitation utilisé
    $extraction=~s/[\xA0\xa0\x0A\x0a\x0D\x0d]//g;
    # on renvoie le titre ou la description nettoyé
    return $extraction;
}
#----------------------------------------------

