1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#/usr/bin/perl
<<DOC; 
////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                    //
//  Nom : Hayoung SEO                                                                                 //
//  Date : Avril 2021                                                                                 //      
//  But : 1. Parcourir toute l'arborescence et extraire les contenus textuels de tous les fils RSS    //
//        2. Etiquetage via treetagger ET udpipe de tous les fichiers RSS                             // 
//  Stratégie pour l'étiquetage : global                                                              //
//  Entrée : 1. répertoire(racine) contenant tous les fichiers RSS                                    //
//           2. rubrique à traiter                                                                    //
//  Sortie : Un fichier au format txt + Un fichier au format XML                                      //
//  Usage : perl bao2_hayoung_seo.pl repertoire-a-parcourir rubrique                                  // 
//  Exemple d'usage : perl bao2_hayoung_seo.pl 2020 3208                                              //      
//                                                                                                    //
////////////////////////////////////////////////////////////////////////////////////////////////////////
DOC
#-----------------------------------------------------------
use strict;
use utf8;
use Timer::Simple;
my $t = Timer::Simple->new();
$t->start; # timer pour savoir le temps de traitement 
#-----------------------------------------------------------
my $rep="$ARGV[0]"; # repertoire à traiter 
my $rubrique ="$ARGV[1]"; # rubrique à traiter 
# on s'assure que le nom du répertoire ne se termine pas par un "/"
$rep=~ s/[\/]$//;
# Ouverture des fichiers txt et XML 
open my $OUT,">:encoding(utf8)","bao2_sortie_$rubrique.txt";
open my $OUTXML,">:encoding(utf8)","bao2_sortiexml_$rubrique.xml";
# Ecriture de l'en-tête du fichier XML
print $OUTXML "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n";
print $OUTXML "<corpus2020>\n";

my %dico_des_titres=();
my $compteur=0;
#----------------------------------------
# Appel du sous-programme 
&parcoursarborescencefichiers($rep);	#recurse!
#----------------------------------------
print $OUTXML "</corpus2020>\n";
# Fermeture des fichiers
close $OUT; 
close $OUTXML;
#----------------------------------------
# Appel du sous-programme d'etiquetage 
&etiquetagetreetagger;
&etiquetageudpipe;
#----------------------------------------
#----------------------------------------
print "Temps de traitement : ", $t->elapsed, " secondes\n";
exit;
#----------------------------------------------
# Sous-programme récursif 
sub parcoursarborescencefichiers {
    my $path = shift(@_);
    opendir(my $DIR, $path) or die "can't open $path: $!\n";
    # On lit et renvoie comme valeur la liste @files 
    my @files = readdir($DIR);
    closedir($DIR);
    # On va examiner un à un pour éviter de lire les fichiers cachés
	foreach my $file (@files) {
        # Si la condition est vrai on passe à l'itération suivante, on ne veut pas traiter 
        next if $file =~ /^\.\.?$/; # on ne lit pas les fichiers cachés (. ou .. ) sinon boucle infini 
        # S'il ne s'agit pas des fichiers cachés, on continue. On relance le parcours
        # Reécriture de localisation => on génère le nom relatif 
        $file = $path."/".$file; 
        # d : directory(repertoire)
        # S'il s'agit d'un répertoire…… 
        if (-d $file) {
            # Ce qu'on cherche n'est pas un répertoire mais un fichier donc on relance le parcours 
            # pour qu'on puisse arriver aux fichiers 
            &parcoursarborescencefichiers($file);	#recurse! 
            # Donc on va parcourir de nouveau, $path devient 2020/01 par exemple …  puis 2020/01/01… 
            # Finalement on va arriver à un fichier 
        }
        # f : file(fichier)
        # S'il s'agit d'un fichier…… 
		if (-f $file) {
            # On ne veut pas traiter les fichiers qui ne sont pas au format XML 
            # Donc l'extension doit être .xml 
			if ($file =~/$rubrique.+xml$/) {
                # Impression du traitement en cours dans la console 
				print $compteur++," Traitement de : ",$file,"\n";
                # Ouverture du fichier 
				open my $FIC,"<:encoding(utf8)",$file;
				$/=undef;   
				my $ligne=<$FIC>;
				close $FIC;
                # On va extraire les contenus textuels de titre et de description avec expression régulère
				while ($ligne=~/<item>.*?<title>(.+?)<\/title>.+?<description>(.+?)<\/description>/gs) {
					my $titre=$1; # on récupère le 1er zone de capture (1er parenthèse entre <title></title>)
					my $description=$2; # on récupère le 2eme zone de capture (2eme parenthèse)
					#$numberItem++;
                    # On évite de récuperer 2 fois la même information => utilisation de dictionnaire 
                    # Si le titre n'existe pas dans le dico_des_titres 
					if (!(exists $dico_des_titres{$titre})) { 
                        # On ajoute 
						$dico_des_titres{$titre}=$description ;
						# Appel du sous-programme de nettoyage 
						($titre,$description)=&nettoyage($titre,$description);
                        #--------------------------------------------------
                        # Pretraitement pour treetagger 
                        my ($titretokenisee, $descriptiontokenisee)=&pretraitement($titre, $description);
                        # Ecriture des fichiers de sortie 
                        # 1. Fichier au format txt 
						print $OUT $titre,"\n";
						print $OUT $description,"\n";
						print $OUT "\n";
                        # 2. Fichier au format XML 
						print $OUTXML "<item>\n";
						print $OUTXML "<titre>\n$titretokenisee</titre>\n";
						print $OUTXML "<description>\n$descriptiontokenisee</description>\n";
						print $OUTXML "</item>\n";
                        
                    
                    # Si le titre exsite, on ne fait rien
					}
				}
			}
		}
    }
}
#----------------------------------------------
# Sous-programme nettoyage 
sub nettoyage {
    # On récupère les arguments 
    my $titre = $_[0];
    my $description = $_[1];
    # Nettoyage ! 
    # On enlève <![CDATA[ et ]]>
	$titre=~s/^<!\[CDATA\[//;
	$titre=~s/\]\]>$//;
	$description=~s/^<!\[CDATA\[//;
	$description=~s/\]\]>$//;
    # On enlève ou on remplace 
    $description=~s/&lt;.+?&gt;//g; # &lt; est le code de < ,  &gt; est le code de >
    $description=~s/&#38;#39;/'/g; 
    $description=~s/&#38;#34;/"/g;
    $titre=~s/&lt;.+?&gt;//g;
    $titre=~s/&nbsp;/ /g;
    $description=~s/&nbsp;/ /g;
    # On ajoute un point à la fin du titre 
    # Pour la partie description il y a déjà le point à la fin => rien à faire
    $titre=~s/$/\./g;
    # S'il y a plusieur points => on ne laisse qu'un seul 
	$titre=~s/\.+$/\./g;
    return $titre,$description;
}
#----------------------------------------------
# Sous-programme tokenisation pour treetagger 
# renvoie le titre et le description étiquétés 
sub pretraitement {
    # argument géré par la liste @_
    my $titre=$_[0]; # titre est 1er argument passé
    my $description=$_[1]; # description est 2ème argument passé 
    #-------------------------------------
    # Etiquetage - titre 
    open my $ETIK, ">:encoding(utf8)", "temporaire.txt";
    print $ETIK $titre;
    close $ETIK;
    system("perl -f ./etiquetage/tokenise-utf8.pl temporaire.txt > testetik.txt");
    open my $TEMPO, "<:encoding(utf8)", "testetik.txt";
    # On fait une lecture globale
    $/=undef; 
    my $titre_etik=<$TEMPO>;
    close $TEMPO; 
    #-------------------------------------
    # Etiquetage - description 
    # On écrase précédent 
    # Et maintenant on ouvre avec description 
    open my $ETIK, ">:encoding(utf8)", "temporaire.txt";
    print $ETIK $description;
    close $ETIK;
    # description
    system("perl -f ./etiquetage/tokenise-utf8.pl temporaire.txt > testetik.txt");
    open my $TEMPO, "<:encoding(utf8)", "testetik.txt";
    $/=undef;
    my $description_etik=<$TEMPO>;
    close $TEMPO;
    unlink "testetik.txt", "temporaire.txt";
    return $titre_etik, $description_etik;
}
#----------------------------------------------
# Sous-programme etiquetage treetagger
sub etiquetagetreetagger {
    # -sgml : ne touche pas aux balises
    system("perl -f ./etiquetage/tokenise-utf8.pl bao2_sortiexml_$rubrique.xml | ./etiquetage/treetagger/tree-tagger ./etiquetage/treetagger/french-utf8.par -token -lemma -no-unknown -sgml > bao2_sortiexml_treetagger_$rubrique");
    # commande pour traiter &amp; (car treetagger l'annote &amp NOM ; PUN  - deux entrées différents - )
    # donc cela posera le pb pour la sortie xml => on ajoute le point virgule à la fin pour chaque &amp
    system("sed -i '' -e 's &amp \\&amp; g' bao2_sortiexml_treetagger_$rubrique");
    system("perl ./etiquetage/treetagger/treetagger2xml-utf8.pl bao2_sortiexml_treetagger_$rubrique utf8");
}
#----------------------------------------------
# Sous-programme etiquetage UDpipe 
sub etiquetageudpipe {
    # system : commande perl qui permet de lancer une commande Unix 
    # --tokenizer=parsegmented : on ne veut pas su'il sursegmente 
    system("./etiquetage/udpipe/udpipe-1.2.0-bin/bin-osx/udpipe --tokenize --tokenizer=parsegmented --tag --parse  ./etiquetage/udpipe/modeles/french-gsd-ud-2.5-191206.udpipe bao2_sortie_$rubrique.txt > bao2_sortie_udpipe_$rubrique.txt");
    # génération de la sortie au format xml également pour bao3 
    # system("perl ./etiquetage/udpipe/udpipe2xml.pl bao2_sortie_udpipe_$rubrique.txt")
}