1. <<DOC;
  2. Uyên-To DOAN-RABIER
  3. Ruixin HE
  4. Mohamed Sofiane KERROUA
  5.  
  6. BàO - Xml::Rss
  7.  
  8. En utilisant des expressions régulières et le module Xml::Rss, produit en sortie des fichiers contenant les résumés de fils rss
  9. contenus dans des fichiers xml dans une arborescence donnée.
  10.  
  11. usage : bao1_xmlrss.pl nom_du_répertoire
  12.  
  13. DOC
  14.  
  15. #/usr/bin/perl
  16. #use strict;
  17. #use warnings;
  18. use Unicode::String qw(utf8);
  19. use XML::RSS;
  20.  
  21. #-----------------------------------------------------------
  22. # Procédure principale
  23. #-----------------------------------------------------------
  24. #Les fichiers sont créés dans un répertoire "resultat"
  25. mkdir(resultat);
  26.  
  27. #-----------------------------------------------------------
  28. # on initialise une variable $rep contenant le flux de sortie
  29. my $rep="$ARGV[0]";
  30. # on s'assure que le nom du répertoire ne se termine pas par un "/"
  31. $rep=~ s/[\/]$//;
  32.  
  33. #-----------------------------------------------------------
  34. # Initialisation d'un tableau de hash évitant la répétition du contenu des fils rss
  35. my %tabcontenu = ();
  36. &parcoursarborescencefichiers($rep);    #recurse!
  37.  
  38. #-----------------------------------------------------------
  39. $cheminrep ="./resultat";
  40. # On ouvre le répertoire "résultat" contenant les fichiers de sortie xml et txt
  41. # On ajoute à chaque fichier xml la balise fermante </file>
  42. # On convertit chaque fichier txt en iso-8859-1 et on le place dans le dossier cordial
  43. opendir(DIRS,$cheminrep) or die "can't open $cheminrep: $!\n";
  44. my @files = readdir(DIRS);
  45. closedir(DIRS);
  46. foreach my $fichier(@files){
  47.     next if $fichier =~ /^\.\.?$/;
  48.             # A chaque fichier xml crée en sortie on ajoute la balise fermante </file>
  49.             if($fichier =~/\.xml$/){
  50.                 open(OUT,">>:encoding(utf-8)","./resultat/$fichier");
  51.                 print OUT "</file>\n";
  52.                 close(OUT);
  53.             }
  54. }
  55.  
  56. exit; # Fin du programme
  57.  
  58. #-----------------------------------------------------------
  59. # Procédure "parcoursarborescencefichiers"
  60. # Parcours une arborescence et traite chaque fichier xml contenant des fils rss
  61. # Donnée : un répértoire passer en paramètre par valeur
  62. # Résultats : - le résultat du traitement au format txt
  63. #             - le résultat du traitement au format xml
  64. #             - le résultat du traitement au format xml avec un étiquetage réalisé tree-tagger
  65. sub parcoursarborescencefichiers {
  66. #-----------------------------------------------------------
  67. # Récupération du répertoire et ouverture du répertoire
  68.     my $path = shift(@_);
  69.     opendir(DIR, $path) or die "can't open $path: $!\n";
  70.     my @files = readdir(DIR);
  71.     closedir(DIR);
  72.  
  73. #-----------------------------------------------------------
  74. # Traitement de chaque fichier contenu dans le répertoire
  75.     foreach my $file (@files) {
  76.         next if $file =~ /^\.\.?$/;
  77.         $file = $path."/".$file;
  78. # Si on tombe sur un répertoire on relance la procédure
  79.         if (-d $file) {
  80.             &parcoursarborescencefichiers($file);   #recurse!
  81.         }
  82.        
  83. #-----------------------------------------------------------       
  84. # Traitement du fichier
  85.         if (-f $file) {
  86. # Si le fichier est un fichier xml et si ce fichier xml n'est pas un fichier ne contenant pas fils rss on le traite
  87.             if(($file=~/\.xml$/) && ($file!~/\/fil.+\.xml$/) && ($file !~/0,2-3404,1-0,0\.xml$/)){
  88.            
  89. # Initialisation des différentes variables
  90.             my $encodage = "";
  91.             my $encodagesortie="utf-8";
  92.             my $texte="";
  93.  
  94. #-----------------------------------------------------------
  95. # Si le fichier est vide pas de traitement         
  96.             if(-z $file){
  97.                 print "$file est vide pas de traitement\n";
  98.             }else{
  99.            
  100. #-----------------------------------------------------------
  101. # Détection de l'encodage du fichier
  102.                 open(FIC,$file);
  103.                 while (my $ligne=<FIC>) {
  104.                     $ligne =~ s/\n//g;
  105.                     if($ligne =~/(iso-8859-1|utf-8)/ig){
  106.                         $encodage = $1;
  107.                     }
  108.                 }
  109.                 close(FIC);
  110.                
  111. #-----------------------------------------------------------
  112. # Initialisation de la méthode du module xml::rss              
  113.                 my $rss=new XML::RSS;
  114.                 eval {$rss->parsefile($file); };
  115.                 if( $@ ) {
  116.                     $@ =~ s/at \/.*?$//s;               # remove module line number
  117.                     print STDERR "\nERROR in '$file':\n$@\n";
  118.                 } else {
  119.                
  120. #-----------------------------------------------------------
  121. # Détection de la rubrique avec la méthode du module xml::rss, dans le cas ou il n'y a pas de rubrique ou classe le fichier dans les non-classés               
  122.                     my $rubrique=$rss->{'channel'}->{'title'};
  123.                     $rubrique=~s/é/e/gi;
  124.                     $rubrique=~s/è/e/gi;
  125.                     $rubrique=~s/ê/e/gi;
  126.                     $rubrique=~s/à/a/gi;
  127.                     $rubrique=~ s/Le ?Monde.fr ?://;
  128.                     $rubrique=~s/ ?- ?Le ?Monde\.fr//;
  129.                     $rubrique=~s/es$/e/i;
  130.                     $rubrique=~ s/ //g;
  131.                     $rubrique=uc($rubrique);
  132.                    
  133.                     if($rubrique eq ""){
  134.                     $rubrique = "NONCLASSE";
  135.                     }
  136.  
  137. #-----------------------------------------------------------
  138. # Création des fichiers de sortie                  
  139.                     open(OUT1,">>:encoding($encodagesortie)","./resultat/$rubrique.txt");
  140.                     open(OUT2,">>:encoding($encodagesortie)","./resultat/$rubrique.xml");
  141.  
  142. #-----------------------------------------------------------
  143. # Ajout des entêtes dans le fichier de sortie xml                  
  144.                     if(-z OUT2){
  145.                         print OUT2 "<?xml version=\"1.0\" encoding=\"$encodagesortie\" ?>\n";
  146.                         print OUT2 "<file>\n";
  147.                         print OUT2 "<name>$rubrique</name>\n";
  148.                     }
  149.                    
  150. #-----------------------------------------------------------
  151. # Détection de la date à l'aide des méthodes du module xml::rss, ajout de la date dans le fichier de sortie xml    
  152. # Ajout de la balise items dans le fichier de sortie xml               
  153.                     my $date=$rss->{'channel'}->{'pubDate'};
  154.                     print OUT2 "<date>$date</date>\n";
  155.                     print OUT2 "<items>\n";
  156.  
  157. #-----------------------------------------------------------
  158. # Détection du titre et du résumé du fils rss à l'aide des méthodes du module xml::xmlrss                      
  159.                     foreach my $item (@{$rss->{'items'}}) {
  160.                         my $titre=$item->{'title'};
  161.                         my $resume=$item->{'description'};
  162.  
  163. #-----------------------------------------------------------
  164. # Test sur le titre du fil rss, si il est déjà contenu dans le tableau de hash on ne le traite pas
  165.                         my $test=$titre;
  166.                         if(!exists $tabcontenu{$test}){
  167.                        
  168. #-----------------------------------------------------------
  169. # Appel de la fonction "nettoietexte" avec comme paramétres le titre et le résumé
  170.                             $titre=&nettoietexte($titre);
  171.                             $resume=&nettoietexte($resume);
  172.                            
  173. #-----------------------------------------------------------
  174. # Conversion du titre et du résumé en utf-8 si l'encodage du fichier en entrée ne l'est pas
  175.                             if (uc($encodage) ne "UTF-8") {utf8($titre);utf8($resume);}
  176.                            
  177. #-----------------------------------------------------------
  178. # On ajoute dans les différents fichiers le titre et le résumé
  179.                             print OUT1 "Titre : $titre \n";
  180.                             print OUT1 "Resume : $resume \n";;
  181.                             print OUT2 "<item><title>$titre</title><abstract>$resume</abstract></item>\n";
  182.                                                
  183. #-----------------------------------------------------------
  184. # On ajoute dans le tableau de hash le titre du fil rss
  185.                             $tabcontenu{$test}++;
  186.                             }
  187.                         }
  188.                        
  189. #-----------------------------------------------------------               
  190. # Fermeture de la balise items dans le fichier xml, fermeture des fichiers
  191.                     print OUT2 "</items>\n";
  192.                     close(OUT1);
  193.                     close(OUT2);
  194.                     }
  195.                 }
  196.             }
  197.         }
  198.     }
  199. } # Fin "parcoursarborescencefichiers"
  200.  
  201.  
  202. #-----------------------------------------------------------
  203. # Fonction "nettoietexte"
  204. # Nettoie un texte de ses entités xml
  205. # Donnée : une chaîne de caractère contenant des entités xml
  206. # Résultat : la chaîne de caractères nettoyée de ses entités xml
  207. sub nettoietexte {
  208.     my $texte=shift;
  209.     $texte =~ s/&lt;/</g;
  210.     $texte =~ s/&gt;/>/g;
  211.     $texte =~ s/<a href[^>]+>//g;
  212.     $texte =~ s/<img[^>]+>//g;
  213.     $texte =~ s/<\/a>//g;
  214.     $texte =~ s/&#38;#39;/'/g;
  215.     $texte =~ s/&#38;#34;/"/g;
  216.     $texte =~ s/&#233;/é/g;
  217.     $texte =~ s/&#234;/ê/g;
  218.     $texte =~ s/<[^>]+>//g;
  219.     $texte =~ s/&nbsp;/ /g;
  220.     $texte=~s/&#39;/'/g;
  221.     $texte=~s/&#34;/"/g;
  222.     $texte=~s/&amp;#39;/'/g;
  223.     $texte=~s/&amp;#34;/"/g;
  224.     return $texte;
  225. } # Fin "nettoietexte"
  226.