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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
#/usr/bin/perl
<<DOC; 
-------------------------------------------------------------------------
Nom : Aurore LESSIEUX & Corentin VIALAR
Date : AVRIL 2020
Action : parcours une arborescence de fil RSS, extrait, nettoie et étiquete (avec TreeTagger et Talismane) les contenus textuels des titres et des descriptions en utilisant l arborescence du fichier XML avec la bibliothèque perl XML::RSS.

Commande de lancement : perl bao2_v-perl_xmlrss.pl REPERTOIRE_A_PARCOURIR RUBRIQUE_A_EXTRAIRE

ENTREE : le programme prend en entrée le nom du pertoire contenant les fichiers à traiter + la rubrique 
SORTIE : le programme crée en sortie 3 fichiers :
		- Un fichier au format texte brute (pareil à BAO1)
		- Un fichier au format texte brute (txt), contenant le texte issu du fitrage étiqueté avec Talismane
		- Un fichier structuré au format XML, contenant le contenu textuel du sultat du filtrage étiqueté avec TreeTagger :			
			<BAO_2>
				<NOM>du fichier</NOM>
				<fichiers>contenu du filtrage étiqueté avec TreeTagger</fichiers>
			</BAO_2>
-------------------------------------------------------------------------
DOC
#----------------------------------------------------------------------
#Appel de la bibliothèque XML::RSS
use XML::RSS;
#Utilisation de XML::RSS :
my $rss=new XML::RSS;

#On récupère dans 2 variables les arguments passés au programme :
my $rep="$ARGV[0]";	#pour le répertoire à traiter
my $rubrique = "$ARGV[1]";	#la rubrique souhaitée

#variable qui prendra l'ensemble des titres et descriptions pour l'étiquetage avec Talismane :
my $titre_desc_global = "";

# on s'assure que le nom du répertoire ne se termine pas par un "/"
$rep=~ s/[\/]$//;

#-----------------------------------------------------------

#on déclare et ouvre les fichiers de sortie en mode écriture :
open(OUT,">:encoding(utf8)", "BAO2_sortie_$rubrique.txt"); 
open(OUTXML, ">:encoding(utf8)", "BAO2_sortiexml_$rubrique.xml");
open(OUTTALISMANE, ">:encoding(utf8)", "BAO2_sortietalisman_$rubrique.txt");

#on écrit la tête du fichier XML :
print OUTXML "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
print OUTXML "<BAO_2>\n"; #Déclaration de la racine
#les auteurs
print OUTXML "\t<auteur>Aurore LESSIEUX</auteur>\n"; 
print OUTXML "\t<auteur>Corentin VIALAR</auteur>\n";
print OUTXML "\t<NOM>Rubrique : $rubrique</NOM>\n";

#l'ensemble des données extraites
print OUTXML "<fichiers>\n";

#on initialise un compteur et une table de hachage (dictionnaire en python) pour traiter les éventuels doublons :
my %dico_des_titres =();
my $i = 0;


#-----------------------------------------------------------
#Appel d'un sous-programme qui va parcourir l'arborescence de manière récursive :
#on passe le repertoire contenant les fichiers à traitées en argument du sous-programme
&parcoursarborescencefichiers($rep);

#sous-programme qui étiquete un fichier global contenant l'ensemble des titres et des descriptions avec Talismane :
&etiquetageTALISMANE($titre_desc_global);
#-----------------------------------------------------------
#fermeture des fichiers :
close(OUT); #fermeture du fichier texte
close(OUTTALISMANE); #fermeture du fichier Talismane

print OUTXML "\t</fichiers>\n";
print OUTXML "</BAO_2>\n";
close(OUTXML); #fermeture du fichier XML

exit;

#-----------------------------------------------------------

#Le sous-programme qui prend en argument le répertoire à traiter:
#(sous-programmemme récursif)
sub parcoursarborescencefichiers {
	#---on récupère la racine du chemin
	#shift prend le premier élément de la liste et le renvoie :
	my $path = shift(@_);
	
	#---ouverture du contenue du répertoire :
	#on sait que la racine est un dossier donc utilisation d'"opendir"
	opendir(DIR, $path) or die "can't open $path: $!\n";
	
	#---lecture du répertoire :
	#renvoie une liste de ressource du répertoire
	my @files = readdir(DIR);#examiner la liste de ressource
	
	#fermeture du répertoire :
	closedir(DIR);
	
	#boucle sur chacun des éléments de la liste des ressources du répertoire:
	foreach my $file (@files) {	
		#on passe au fichier suivant si le fichier est caché : "." ou ".." ; sinon on risque de créer une boucle sur le répertoire courant
		next if $file =~ /^\.\.?$/;
		
		#reconstruction du chemin relatif où l'on se trouve :
		$file = $path."/".$file;
		
		#si le chemin relatif conduit à un répertoire :
		# -d permet de vérifier que $file est un répertoire
		if (-d $file) {	
			#si on est dans un répertoire, on recommence toute la procédure avec un nouveau chemin passé en argument :
			&parcoursarborescencefichiers($file);	#recurse!
		}
		
		#si le chemin relatif conduit à un fichier :
		#-f permet de vérifier que $fil est un fichier
		if (-f $file) {	
			#----------TRAITEMENT à réaliser sur chaque fichier----------------------------------------------
			
			#---Lecture du fichier :
			#si le fichier a une EXTENSION XML et la RUBRIQUE passé en argument au programme :
			if ($file =~/$rubrique.+\.xml$/) {
				#incrémentation du compteur, message dans la console :
				print $i++, "Traitement de :", $file, "\n";
				print "##------------------------------------------##\n";
				
#---BAO1 : perl - XML::RSS-----------------------------------------------------------------------------
				#---on parse le fichier :
				eval {$rss->parsefile($file);};
				#si il y a eu erreur
				if( $@ ) {     
					$@ =~ s/at \/.*?$//s; # remove module line number
					print STDERR "\nERROR in '$file':\n$@\n";
				}
				
				#---Extraction :
				else {
					foreach my $item (@{$rss->{'items'}}) {
						#on extrait le titre
						my $titre = $item->{'title'};
						#on extrait la description
						my $description = $item->{'description'};			

#------------------------------------------------------------------------------------------------------	
					
						#---Traitement des doublons :
						#si le titre n'existe pas dans le dictionnaire $dico_des_titres :
						if (!(exists $dico_des_titres{$titre} )) {
							#alors il n'y a pas de doublon et on effectue le traitement suivant :
						
							#on ajoute le titre et la description au dictionnaire
							$dico_des_titres{$titre}=$description ; 
									
							#---Nettoyage du texte :
							#A l'aide d'un autre sous-programme on nettoie les "cochonneries" des contenues textuelles qu'on a extrait
							($titre, $description) = &nettoyage($titre, $description);
						
#------BAO2 : Etiquetage avec TreeTagger---------------------------------------------------
							#---Concaténation des titres et descriptions nettoyés (pour le sous-programme d'étiquetage avec Talismane :
						
							$titre_desc_global = $titre_desc_global.$titre."\n";
							$titre_desc_global = $titre_desc_global.$description."\n";

							#---Etiquetage du texte : avec TreeTagger > on renvoit à une procédure
							my($titre_POS, $description_POS) = &etiquetage($titre, $description);

							#Ecriture des fichiers de sortie :
							#------------VERSION TXT---------------------
							print OUT "TITRE : ", $titre,"\n";
							print OUT "DESCRIPTION :", $description,"\n";
							print OUT "-------\n";
						
							#------------VERSION XML---------------------
							print OUTXML "\t\t<item>\n" ;
							print OUTXML "\t\t\t<titre>$titre_POS</titre>\n";
							print OUTXML "\t\t\t<description>$description_POS</description>\n";
							print OUTXML "\t\t</item>\n";
						
							#message dans la console :
							print "$file est le", $i++,"\n";
						
							#si le titre existe déjà dans le dictionnaire, on ne fait rien
						}
					}
				}
			}
		}
	}
}
#--------------BAO2 : Etiquetage avec Talismane-------------------------------------
sub etiquetageTALISMANE {
	my $titre_desc_global = $_[0];
	#---Etiquettage du texte : avec Talismane > utilisation de la variable $titre_desc_global :
	#création et ouverture en mode écriture d'un fichier temporaire qui va prendre le contenu textuel :
	open (TALIS, ">:encoding(utf8)", "bao2_talismane_temporaire.txt");
	print TALIS $titre_desc_global;
	close TALIS;
				
	#commande système ; on fait appel à un script java pour étiqueter le contenu textuel avec Talismane :
	system ("java -Xmx1G -Dconfig.file=../TALISMANE/talismane-fr-5.0.4.conf -jar ../TALISMANE/talismane-core-5.1.2.jar --analyse --sessionId=fr --encoding=UTF8 --inFile=bao2_talismane_temporaire.txt --outFile=bao2_talismane_temporaire.tal");
				
	#---ouverture du fichier avec les résultats étiquetés avec Talismane :
	open (TEMP, "<:encoding(utf8)", "bao2_talismane_temporaire.tal");
	#la variable resultat_talismane prend pour valeur le contenu du fichier
	$resultat_talismane = <TEMP>;
	close TEMP;
				
	#---intégration de l'étiquetage Talismane dans le fichier Talismane final :
	print OUTTALISMANE $resultat_talismane;	
}

#--------------------------------------------------------------------------------

#le sous programme qui nettoie le contenu textuel extrait :
#Entrée : 2 variables textuelles
#Sortie : les 2 variables textuelles nettoyées
sub nettoyage {
	#récupérer ce qui a été passé en argument au programme : @ARGV 
	my $titre = $_[0];
	my $description = $_[1];
	
	#---Nettoyage :
	#enlever les structures [CDATA[ ... ]]	
	$description=~s/^<;!\[CDATA\[//;
	$description=~s/\]\]&gt;$//;
	$titre=~s/^<;!\[CDATA\[//;
	$titre=~s/\]\]&gt;$//;
	
	#rempalcer le code par des guillemets simples :
	$description =~s/&#38;#39;/'/g;
	$titre =~s/&#38;#39;/'/g;
	
	#remplacer le code par des guillemets doubles :
	$description =~s/&#38;#34;/"/g;
	$titre =~s/&#38;#34;/"/g;
	
	#suppresion des balises
	$description =~s/&lt;.+?&gt;//g ;
	$titre =~s/&lt;.+?&gt;//g ;
	
	#remplacer & par "et":
	$description =~s/&/et/g ;
	$titre =~s/&/et/g ;
	
	#rajouter un point à la fin des titres
	$titre=~s/$/\./g;
	
	#renvoyer le contenu textuel nettoyé :
	return $titre, $description;
}


#---------------------------------------------------
#sous-programme pour étiqueter le contenu textuel des titres et des descriptions avec TreeTagger :
#Entrée : 2 variables textuelles ($titre et $description)
#Sortie : les 2 variables textuelles étiquetés avec TreeTagger au format XML
sub etiquetage {
	#répération des variables mises en argument :
	my $titre = $_[0];
	my $description = $_[1];
	
	#---Traitement de TITRE :
	#création et ouverture en écriture d'un fichier temporaire où l'on met la chaîne à traiter :
	open (TEMP, ">:encoding(utf8)", "temporaire.txt");
	print TEMP $titre;
	close TEMP;
	
	#---Tokenisation + Etiquettage TreeTagger de temporaire.txt > fic_tagg.txt.pos
	#on fait appel à un autre script perl pour tokeniser puis tagger en POS TreeTagger le contenu du fichier temporaire.
	#sortie des résultats dans le fichier fic_tagg.txt.pos
	#commande système = on invoque la fenêtre de traitement et on envoie la commande au système pour qu'il l'exécute :
	system ("perl -f tokenise-utf8.pl  temporaire.txt  |./tree-tagger.exe french-oral-utf-8.par -token -lemma -no-unknown > fic_tagg.txt.pos");
	
	#---Mise en forme XML de l'étiquetage :
	#mise en application d'un second script perl pour mettre le résultat de l'étiquetage au format XML:
	system ("perl treetagger2xml-utf8.pl fic_tagg.txt.pos utf8");
	
	#ouverture en lecture du fichier avec le résultat :
	open (TAGG, "<:encoding(utf8)", "fic_tagg.txt.pos.xml");
	#lecture du fichier dans sa globalité
	$/=undef;
	#la variable $titre_etik_XML prend comme valeur le contenu du fichier
	my $titre_etik_XML = <TAGG>;
	close TAGG;
	
	
	#---Traitement de DESCRIPTION :
	#on refait la même chose pour la description :
	open (TEMP, ">:encoding(utf8)", "temporaire.txt");
	print TEMP $description;
	close TEMP;
	
	system ("perl -f tokenise-utf8.pl  temporaire.txt  |./tree-tagger.exe french-oral-utf-8.par -token -lemma -no-unknown > fic_tagg.txt.pos");
	system ("perl treetagger2xml-utf8.pl fic_tagg.txt.pos utf8");
	
	open (TAGG, "<:encoding(utf8)", "fic_tagg.txt.pos.xml");
	$/=undef;
	my $description_etik_XML = <TAGG>;
	close TAGG;
	
	#---Nettoyage des résultats : on retire les balises ouvrante et fermantes de la déclaration XML :
	$titre_etik_XML =~s/<\?xm[^>]+>//;
	$description_etik_XML =~s/<\?xm[^>]+>//;
	
	#on retourne le résultat :
	return $titre_etik_XML, $description_etik_XML;
	
}