#/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
#-----------------------------------------------------------
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 duplucation 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 initialise une variable qui va contenir l'ensemble des contenus de tous les fichiers (une version XML et texte brut)
my $global_xml="<?xml version='1.0' encoding='UTF-8' ?>\n<PARCOURS>\n";
my $global_texte="";
#----------------------------------------
# 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 bao1-1");
system("mkdir bao1-1/fichiers_xml bao1-1/fichiers_txt");
# création de fichiers globaux XML et texte brut
open (GLOBAL_XML, ">:encoding(utf8)", "bao1-1/fichiers_xml/global_xml.xml");
open (GLOBAL_TXT, ">:encoding(utf8)", "bao1-1/fichiers_txt/global_txt.txt");
#----------------------------------------
&parcoursarborescencefichiers($rep); # appel du sous-programme qui s'exécutera de façon récursive
#----------------------------------------

# variable de compteur utilisée dans la construction des fichiers globaux
my $j=1;
# 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 bao1-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)", "bao1-1/fichiers_xml/".$xml);# nécessaire ?
    print THEME1 "</THEME>\n</PARCOURS>\n";
	# on ferme les fichiers (un par un)
    close(THEME1);
	# ouverture de chacun des fichiers (rubriques) en lecture
    open (THEME1, "<:encoding(utf8)", "bao1-1/fichiers_xml/".$xml);
	# on parcourt le contenu de chaque fichier que l'on concatène dans le fichier global XML
    while (my $ligne=<THEME1>) {
		# on lit la dernière ligne du fichier XML
        $ligne_fin=`tail -1 bao1-1/fichiers_xml/$xml`;
		# on ne conserve pas la dernière ligne (<PARCOURS>) ni les trois premières lignes sinon problème de document mal formé
        if ($j>3 and $ligne ne $ligne_fin) {
            $global_xml.=$ligne;
        }
        $j++;
    }
    $j=1;
    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 bao1-1/fichiers_txt/`;
foreach my $txt (@nom_fichier_txt) {
    chomp $txt;
    open (THEME2, ">>:encoding(utf8)", "bao1-1/fichiers_txt/".$txt);# nécessaire ?
    close(THEME2);
    open (THEME2, "<:encoding(utf8)", "bao1-1/fichiers_txt/".$txt);
    while (my $ligne=<THEME2>) {
        $ligne_fin=`tail -1 bao1-1/fichiers_txt/$txt`;
        $global_texte.=$ligne;
        if ($ligne eq $ligne_fin) {
            $global_texte.="\n\n";
        }
    }
    close(THEME2);
}
# on inscrit tous les contenus dans les fichiers globaux (sans oublier de fermer la balise racine du document glabal XML)
print GLOBAL_XML $global_xml."</PARCOURS>";
print GLOBAL_TXT $global_texte;
close (GLOBAL_XML);
close (GLOBAL_TXT);
# 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);
			# 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=~m/<title>(.+?) - LeMonde.fr<\/title>|Le Monde.fr : (.+?)<\/title>/i) { ############################# ou $texte=~/(.+?) - LeMonde.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 "bao1-1/fichiers_xml/".$theme_clear.".xml") {
							open (THEME1, ">>:encoding(utf8)", "bao1-1/fichiers_xml/".$theme_clear.".xml");
							open (THEME2, ">>:encoding(utf8)", "bao1-1/fichiers_txt/".$theme_clear.".txt");
							$i++;
						}
						#  sinon on crée le fichier XML associée à cette rubrique
						else {
							open (THEME1, ">:encoding(utf8)", "bao1-1/fichiers_xml/".$theme_clear.".xml");
							open (THEME2, ">:encoding(utf8)", "bao1-1/fichiers_txt/".$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\" ?>\n";
							print THEME1 "<PARCOURS>\n";
							print THEME1 "<NOM>Loïc</NOM>\n";
							print THEME1 "<THEME theme='".$theme_clear."'>\n";
							$i++;
						}
                    }
                }
                else {
                    # 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 sauvegarde ces résultats insérés dans un balisage XML
							$DUMPFULL1.="<item number='".$dicoTheme{$theme_clear}."'>\n<titre>".$recup.".</titre>\n";
							$DUMPFULL2.=$recup.". \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} and $recup2 ne "") {
							$dicoDescription{$recup2}++;
							$DUMPFULL1.="<description>".$recup2."</description>\n</item>\n";
							$DUMPFULL2.=$recup2." \n";
						}
						else {
							$DUMPFULL1.="<description>-</description>\n</item>\n";
							$DUMPFULL2.="";
						}
                    }
                }
        	}
			# 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 remplace l'esperluette par son codage en entité XML
    $extraction=~s/&/&amp;/g;
	# on renvoie le titre ou la description nettoyé
    return $extraction;
}
#----------------------------------------------
