#!/usr/bin/perl use strict; #use warnings; use Timer::Simple; # IL FAUT INSTALLER LE MODULE TIMER::SIMPLE # sudo cpan # install Timer::Simple # on ne travaille qu'en utf-8 use open qw/ :std :encoding(UTF-8)/; # on instancie un timer commencant à 0.0s par défaut my $t = Timer::Simple->new(); # on lance le timer $t->start; # -------------------------------------------------------------------------------- # $ARGV[0] = repertoire dans lequel chercher les fichiers xml rss # $ARGV[1] = code de la catégorie # -------------------------------------------------------------------------------- # on recupere le premier argument (repertoire) my $folder = $ARGV[0]; # on recupere le second argument (code de la catégorie) my $code = $ARGV[1]; # liste de tous les fichiers xml rss correspondant à la catégorie (reference anonyme à un array) my $xmls = []; my $categories = {3208 => "une", 3210 => "international", 3214 => "europe", 3224 => "societe", 3232 => "idees", 3234 => "economie", 3236 => "actualite_medias", 3242 => "sport", 3244 => "planete", 3246 => "culture", 3260 => "livres", 3476 => "cinema", 3546 => "voyage", 6518 => "technologies", 8233 => "politique", "env_sciences" => "sciences"}; # si le code de la categorie est introuvable, on met fin au script die "Code de categorie introuvable !\n" unless exists($categories->{$code}); # on ouvre les deux fichiers de resultats open my $output_xml, ">:encoding(utf-8)", "$categories->{$code}.xml" or die "$!"; open my $output_txt, ">:encoding(utf-8)", "$categories->{$code}.txt" or die "$!"; # écriture de l'en-tete du fichier xml de sortie print $output_xml "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; print $output_xml "<root>\n"; # on fait appel à la subroutine parcourir &parcourir($folder); # on parse les fichiers xml rss &parsefiles; sub parcourir{ # on recupere l'argument de la subroutine my $folder = shift @_; # on supprime le / final si il existe $folder =~ s/\/$//; # on recupere les fichiers et dossier du repertoire opendir(DIR, $folder); # on liste tous les fichiers et dossiers du repertoire my @files = readdir(DIR); # on ferme le repertoire closedir(DIR); # pour chaque fichier/dossier foreach my $file(@files){ next if $file =~ /^\.\.?$/; # on constitue le chemin d'acces complet du fichier/dossier my $f = $folder."/".$file; # si c'est un dossier, on fait appel à la récursivité if (-d $f){ &parcourir($f); } # si c'est un fichier xml rss, on va appliquer un traitement XML::RSS # on l'ajoute au tableau @$xmls if (-f $f && $f =~ /$code.*\.xml/){ push @$xmls, $f; } } } sub parsefiles{ # reference anonyme sur hash (dictionnaire) ayant pour clé le titre et la description concaténés my $titres_descriptions = {}; # pour chaque fichier xml rss correspondant à la catégorie foreach my $file(@$xmls){ open my $input, "<:encoding(UTF-8)","$file" or die "$!"; undef $/; my $ligne=<$input>; # lecture globale car $/ n'a plus de valeur while ($ligne=~/<item><title>(.+?)<\/title>.+?<description>(.+?)<\/description>/gs) { # l'option s dans la recherche permet de tenir compte des \n my $titre=&nettoyage($1); my $description=&nettoyage($2); my $xml_file = $file; my $date = format_date($file); # on ajoute le titre et la description dans le hash en tant que clé et ayant la valeur 1 par défaut my $title_desc = $titre."||".$description."||".$xml_file; # on vérifie grace au test unless qu'il n'existe pas de doublons $titres_descriptions->{$title_desc} = $date unless exists($titres_descriptions->{$title_desc}); } close $input; } my $compteur = 1; foreach my $key(sort { $titres_descriptions->{$a} <=> $titres_descriptions->{$b} or $a cmp $b } keys %$titres_descriptions){ # on recupere le titre et la description avec split avec comme séparateur || # $t_d[0] = titre # $t_d[1] = description # $t_d[2] = fichier xml my @t_d = split(/\|\|/, $key); # on écrit les données dans le fichier xml avec numero, date, et fichier pour l'item en question son titre et sa description print $output_xml "<item numero=\"$compteur\" date=\"$titres_descriptions->{$key}\" fichier=\"$t_d[2]\"><titre>$t_d[0]</titre>\n"; print $output_xml "<description>$t_d[1]</description>\n</item>\n"; # on ecrit les données dans le fichier txt print $output_txt "$t_d[0]\n"; print $output_txt "$t_d[1]\n"; $compteur++; } # fin du fichier xml print $output_xml "</root>\n"; # on ferme les fichiers de sortie close $output_xml; close $output_txt; # temps écoulé depuis le lancement du programme print "time so far: ", $t->elapsed, " seconds\n"; } sub nettoyage { # quand on lance une procédure # perl range les arguments de la procédure dans une liste spéciale # qui s'appelle @_ my $texte=shift @_; $texte=~s/<!\[CDATA\[//g; $texte=~s/\]\]>//g; $texte =~s/&nbsp/ /g; # ajout du point en fin de chaîne $texte=~s/$/\./g; $texte=~s/\.+$/\./g; return $texte; } sub format_date{ my $file = shift; $file =~ m/(\d+)\/(\d+)\/(\d+)\//; return $1.$2.$3; }