Newer
Older
harvest-corpus / outils / stats-corpus / statsCorpus.pl
#!/usr/bin/perl


# Déclaration des pragmas
use strict;
use utf8;
use open qw/:std :utf8/;

# Appel des modules externes de base
use Encode qw(decode_utf8 encode_utf8 is_utf8);
use Getopt::Long;

# Appel des modules spécifiques à l'application
## use URI::Encode qw(uri_encode uri_decode);
## use LWP::Simple;
use JSON;
## use Text::Unidecode;

my ($programme) = $0 =~ m|^(?:.*/)?(.+)|;

my $version   = "1.6.1";
my $dateModif = "26 Mars 2018";

# Variables
my $aide        = 0;
my $corpus      = "";
my $logfile     = "";
my $metadata    = "";
my $prefixe     = "";
my $repertoire  = "";
my $sortie      = "";

eval	{
	$SIG{__WARN__} = sub {usage(1);};
	GetOptions(
		"corpus=s"      => \$corpus,
		"help"          => \$aide,
		"logfile=s"     => \$logfile,
		"metadonnees=s" => \$metadata,
		"prefixe=s"     => \$prefixe,
		"repertoire=s"  => \$repertoire,
		"sortie=s"      => \$sortie,
		);
	};
$SIG{__WARN__} = sub {warn $_[0];};
# “ machin ”
if ( $aide ) {
	print "Programme : \n    “$programme”, version $version ($dateModif)\n";
	print "    Permet de faire des statistiques sur les fichiers extraits d’ISTEX en utilisant le fichier \n";
	print "    de métadonnées “logRequete.txt” (cf. l’option “-v” du programme “harvestCorpus.pl”) ou les \n";
	print "    fichiers de métadonnées JSON correspondants aux documents extraits. \n";
	print "    Si les fichiers XML éditeurs ont été extraits, il permet aussi de vérifier s’ils ont ou non \n";
	print "    les documents sous forme de texte structuré. \n";
	print "\nUsage : \n    $programme -l logfile -c fichier.corpus [ -r répertoireXML ] [ -s sortie ]\n";
	print "    $programme -m répertoireJSON [ -r répertoireXML ] [ -s sortie ]\n";
	print "    $programme -h\n";
	print "\nOptions : \n";
	print "    -l  indique le nom du fichier “logfile” contenant les métadonnées ISTEX au format JSON \n";
	print "        créé par l’option “-v” du programme “harvestCorpus.pl”. \n";
	print "        Par défaut, ce fichier s’appelle “logRequete.txt” et se trouve dans le répertoire des \n";
	print "        fichiers déchargés depuis le serveur ISTEX. \n";
	print "    -c  indique le nom du fichier “.corpus” généré par le programme “harvestCorpus.pl” permettant \n";
	print "        de faire le lien entre l’identifiant ISTEX d’un document et le nom des fichiers \n";
	print "        extraits correspondants.\n";
	print "    -h  affiche cette aide. \n";
	print "    -m  indique le répertoire où se trouve les fichiers de métadonnées au format JSON déchargés \n";
	print "        par le programme “harvestCorpus.pl”.\n";
# 	print "    -p  indique le préfixe utilisé au début du nom des fichiers déchargés par le programme \n";
# 	print "        “harvestCorpus.pl”. \n";
	print "    -r  indique le répertoire où se trouve les fichiers XML éditeurs obtenus à partir des \n";
	print "        fichiers ZIP déchargés par le programme “harvestCorpus.pl”. Si les fichiers XML sont \n";
	print "        dans le même répertoire que les fichiers JSON, l’option “-m” seule suffit. \n";
	print "    -s  indique le nom du fichier de sortie. Sinon, la sortie se fait sur la sortie standard. \n";
	print "\nExemples : \n";
	print "    $programme -l Arthropodes/logRequete.txt -c Arthropodes_v2b.corpus -r Arthropodes\n";
	print "    $programme -m Vieillissement -r Vieillissement -s Vieil.tsv \n";
	print "    $programme -m Vieillissement -s Vieil.tsv                     (identique au précédent)\n\n";

	exit 0;
	}

usage(2) if not $logfile and (not $metadata or not -d $metadata);

my $format = "";
my $json   = "";
my $racine = "";
my $num    = 0;
my $total  = 0;
my %racine = ();

if ( $corpus ) {
	open(TAB, "<:utf8", $corpus) or die "$!,";
	while(<TAB>) {
		if ( /^(ark|id) /o ) {
			chomp;
			s/\r//go;	# Au cas où ...
			my ($type, $id, $com, $nom) = split(/\s+/);
			if ( $type eq 'ark' and $id !~ /^ark:/o ) {
				$id = "ark:$id";
				}
			$racine{$id} = $nom;
			}
		}
	close TAB;
	}

my %nom = (
	"elsevier" => "Elsevier",
	"wiley" => "Wiley",
	"springer-journals" => "Springer (journals)",
	"oup" => "OUP",
	"cambridge" => "Cambridge",
	"sage" => "Sage",
	"bmj" => "BMJ",
	"springer-ebooks" => "Springer (e-books)",
	"iop" => "IOP",
	"nature" => "Nature",
	"rsc-journals" => "RSC (journals)",
	"degruyter-journals" => "Degruyter (journals)",
	"ecco" => "ECCO",
	"edp-sciences" => "EDP Sciences",
	"emerald" => "Emerald",
	"brill-journals" => "Brill (journals)",
	"eebo" => "EEBO",
	"rsc-ebooks" => "RSC (e-books)",
	"brill-hacco" => "Brill HACCO",
	"gsl" => "GSL",
	"numerique-premium" => "Numérique Premium",
	);

if ( $sortie ) {
	open(OUT, ">:utf8", $sortie) or die "\"$sortie\" : $!,";
	}
else	{
	open(OUT, ">&STDOUT") or die "$!,";
	binmode(OUT, ">:utf8");
	}
print OUT "\x{FEFF}Identifiant ISTEX\tARK\tNom de fichier\tÉditeur\tScore qualité\tVersion PDF";
print OUT "\tXML structuré\tDate de publication\tTitre\tRevue\tISSN\te-ISSN\tType de publication";
print OUT "\tType de document\tCatégories WoS\tCatégories Science-Metrix\tCatégories Scopus\t";
print OUT "Catégories INIST\n";

if ( $logfile ) {
	open(INP, "<:raw", $logfile) or die "$!,";
	while(<INP>) {
		if ( /^# (\w+_?\d+)/ ) {
			$racine = $1;
			next;
			}
		elsif ( /^#/ ) {
			next;
			}
		$json .= $_;
		if ( /^\}/o ) {
			my $perl = decode_json $json;
			my %top = %{$perl};
			if ( defined $top{'total'} ) {
				$total = $top{'total'};
				if ( $total > 0 ) {
					$format = sprintf("%%0%dd", length($total) + 1);
					}
				}
			if ( defined $top{'hits'} ) {
				my @hits = @{$top{'hits'}};
				foreach my $hit (@hits) {
					traite($hit);
					}
				}
			else	{
				traite($perl);
				}
			$json = "";
			}
		}
	}
elsif ( $metadata ) {
	opendir(DIR, $metadata) or die "$!,";
	my @fichiers = sort grep(/\.json$/, readdir DIR);
	closedir DIR;
	foreach my $fichier (@fichiers) {
		($racine) = $fichier =~ /^(.+)\.json\z/o;
		open(JSN, "<:raw", "$metadata/$fichier") or die "$!,";
		while(<JSN>) {
			$json .= $_;
			if ( /^\}/o ) {
				my $perl = decode_json $json;
				traite($perl);
				$json = "";
				}
			}
		close JSN;
		}
	}


exit 0;


sub usage
{
print STDERR "Usage : $programme -l logfile -c fichier.corpus [ -r répertoireXML ] [ -s sortie ] \n";
print STDERR "        $programme -m répertoireJSON [ -r répertoireXML ] [ -s sortie ] \n";
print STDERR "        $programme -h \n";

exit shift;
}

sub traite
{
my $ref = shift;

$num ++;
my $fichier = undef;
my $xml     = undef;
my %hit = %{$ref};
my $id = $hit{'id'};
my $ark = $hit{'arkIstex'};
if ( $racine ) {
	$fichier = $racine;
	$racine = "";
	}
elsif ( $racine{$ark} ) {
	$fichier = $racine{$ark};
	}
elsif ( $racine{$id} ) {
	$fichier = $racine{$id};
	}
elsif ( $prefixe ) {
	$fichier = "$prefixe" . sprintf($format, $num);
	}
if ( defined $fichier ) {
	if ( $repertoire ) {
		$xml = "$repertoire/$fichier.xml";
		}
	elsif ( $metadata ) {
		$xml = "$metadata/$fichier.xml";
		}
	}
else	{
	$fichier = "Nom de fichier inconnu";
	}
my $titre = $hit{'title'};
my $corpusName = $hit{'corpusName'};
my $nom = $corpusName;
if ( $nom{$nom} ) {
	$nom = $nom{$nom};
	}
my $date = "";
if ( $hit{'copyrightDate'} ) {
	$date = $hit{'copyrightDate'};
	}
elsif ( $hit{'publicationDate'} ) {
	$date = $hit{'publicationDate'};
	}
my $langues = "";
if ( defined $hit{'language'} ) {
	$langues = join(" ; ", @{$hit{'language'}});
	}
my $wos           = "";
my $scienceMetrix = "";
my $scopus        = "";
my $inist         = "";
if ( defined $hit{'categories'} ) {
	my %categories = %{$hit{'categories'}};
	if ( defined $categories{'wos'} ) {
		$wos = join(" ; ", @{$categories{'wos'}});
		}
	if ( defined $categories{'scienceMetrix'} ) {
		$scienceMetrix = join(" ; ", @{$categories{'scienceMetrix'}});
		}
	if ( defined $categories{'scopus'} ) {
		$scopus = join(" ; ", @{$categories{'scopus'}});
		}
	if ( defined $categories{'inist'} ) {
		$inist = join(" ; ", @{$categories{'inist'}});
		}
	}
my $genre = "";
if ( defined $hit{'genre'} ) {
	$genre = join(", ", @{$hit{'genre'}});
	}
my $pdfVersion = "";
my $score = "";
if ( defined $hit{'qualityIndicators'} ) {
	my %indicateurs = %{$hit{'qualityIndicators'}};
	if ( defined $indicateurs{'pdfVersion'} ) {
		$pdfVersion = $indicateurs{'pdfVersion'};
		}
	if ( defined $indicateurs{'score'} ) {
		$score = $indicateurs{'score'};
		}
	}
my $revue = "";
my $issn  = "";
my $eissn = "";
my $dt    = "";
if ( defined $hit{'host'} ) {
	my %host = %{$hit{'host'}};
	if ( defined $host{'title'} ) {
		$revue = $host{'title'}
		}
	if ( defined $host{'issn'} ) {
		$issn = join("/", @{$host{'issn'}});
		}
	if ( defined $host{'eissn'} ) {
		$eissn = join("/", @{$host{'eissn'}});
		}
	if ( defined $host{'genre'} ) {
		$dt = join(", ", @{$host{'genre'}});
		}
	}
my $structure = "Absent";
if ( defined $xml and -f $xml ) {
	$structure = "Non";
	my $texte = "";
	open(XML, "<:utf8", $xml) or die "$!,";
	while(<XML>) {
		tr/\n\r/ /s;
		$texte .= $_;
		}
	close XML;
	if ( $corpusName eq 'bmj' or
	     $corpusName =~ /^brill-/o or
	     $corpusName eq 'cambridge' or
	     $corpusName =~ /^degruyter-/o or
	     $corpusName eq 'edp-sciences' or
	     $corpusName eq 'emerald' or
	     $corpusName eq 'gsl' or
	     $corpusName eq 'numerique-premium' or
	     $corpusName eq 'oup' ) {
		$structure = "Oui" if $texte =~ m{<body>.+</(sec|p)>.*</body>}o;
		}
	elsif ( $corpusName eq 'ecco' ) {
		$structure = "Oui" if $texte =~ /<p>\s*<wd\b/o;
		}
	elsif ( $corpusName eq 'elsevier' ) {
		$structure = "Oui" if $texte =~ /<body>\s*<ce:sections>\s*<ce:section>/oi;
		}
	elsif ( $corpusName eq 'iop' ) {
		$structure = "Oui" if $texte =~ /<body( .+?)?>\s*<sec-level1\b/o;
		}
	elsif ( $corpusName eq 'nature' ) {
		$structure = "Oui" if $texte =~ m|<bdy>|o;
		$structure = "Non" if $texte =~ m|<bdy/>|o;
		}
	elsif ( $corpusName =~ /^rsc-/o ) {
		$structure = "Oui" if $texte =~ m|<art-body>\s*<section |o;
		}
	elsif ( $corpusName eq 'sage' ) {
		if ( $texte =~ /<body>\s*<full_text\b/o ) {
			$structure = "Non"
			}
		elsif ( $texte =~ m{<body>.+</(sec|p)>.*</body>}o ) {
			$structure = "Oui";
			}
		}
	elsif ( $corpusName =~ /^springer-/o ) {
		$structure = "Non" if $texte =~ m|<NoBody\b|o;
		}
	elsif ( $corpusName eq 'wiley' ) {
		$structure = "Oui" if $texte =~ /<body( .+?)?>\s*<section\b/oi;
		}
	else	{
		$structure = "Indéterminé";
		}
	}
print OUT "$id\t$ark\t$fichier\t$nom\t$score\t$pdfVersion\t$structure\t$date\t$titre";
print OUT "\t$revue\t$issn\t$eissn\t$dt\t$genre\t$wos\t$scienceMetrix\t$scopus\t$inist\n";
}