#!/bin/bash
# Initialisation des variables pour les options
programme=$(basename $0)
substitut=$(echo $programme | sed 's/./ /g')
version='1.2.2'
modif='21/02/2022'
function usage
{
echo "Usage : $programme -s sid -q requête [ -p (début:fin|[124]week) ] "
echo " $substitut [ -b [WOS:]base ]* [ -f champs ]* [ -t CH:[AD] ] "
echo " $substitut [ -n notices ] [ -c cookies ] [ -i ]"
echo " $programme -h "
}
function aide
{
cat << EOT
Usage
=====
$programme -s sid -q requête [ -p (début:fin|[124]week) ]
$substitut [ -b [WOS:]base ]* [ -f champs ]* [ -t CH:[AD] ]
$substitut [ -n notices ] [ -c cookies.txt ] [ -i ]
$programme -h
Options principales
===================
-h affiche cette aide
-p limite la recherche dans la base de données à la période indiquée
sous forme aaaa-mm-jj:aaaa-mm-jj (e.g., “2000-01-01:2020-07-31”)
ou sous forme “1week”, “2week” ou “4week”
-q fournit la requête à envoyer (entre simples ou doubles quotes si
elle contient des espaces ou des caractères spéciaux)
-s indique le jeton d’authentification “SID” obtenu avec le programme
d’authentification à l’API WoS
Autres options
==============
-b limite la recherche à une ou plusieurs bases (e.g. “WOS:SCI”).
Cette option est répétitive et “WOS:” est facultatif (par défaut,
la recherche se fait sur l’ensemble du WoS)
-c indique le nom du fichier qui recevra les cookies (“cookies.txt”
par défaut)
-f limite les champs présents dans les notices téléchargées. Cette
option est répétitive (par défaut, tous les champs sont présents)
-i ajoute dans la réponse de l’API la liste des identifiants WoS des
notices retournées (5 par défaut ou valeur de l’option “-n”)
-n indique le nombre de notices, entre 1 et 100, à retourner (5 par
défaut)
-t trie les résultats sur un champ (nom abrégé à 2 majuscules) de
façon croissante (A) ou décroissante (D) ou par pertinene (RS)
forcément décroissante
EOT
exit 0
}
function nettoie
{
if [[ -f search$$.xml ]]
then
rm -f search$$.xml
fi
}
# Déclaration explicite du tableau “bases”
declare -a bases
declare -a champs
# Options
while getopts b:c:f:hin:p:q:r:s:t: i
do
case $i in
b) bases+=($OPTARG);;
c) cookie=$OPTARG;;
f) champs+=($OPTARG);;
h) aide;;
i) recid=1;;
n) nrec=$OPTARG;;
p) span=$OPTARG;;
q) query=$OPTARG;;
s) sid=$OPTARG;;
t) tri=$OPTARG;;
\?) echo >&2
usage >&2
exit 1;;
esac
done
# Vérification des options
if [[ -z $sid || -z $query ]]
then
echo "Erreur : option(s) manquante(s)" >&2
echo "" >&2
usage >&2
echo ""
exit 2
fi
if [[ -z $cookie ]]
then
cookie='cookies.txt'
fi
if [[ ! $nrec ]]
then
nrec=5
else
if [[ $nrec =~ ^[1-9][0-9]*$ ]]
then
if [[ $nrec -lt 1 || $nrec -gt 100 ]]
then
echo "Erreur : l’argument de l’option “-n” doit être un entier entre 1 et 100" >&2
exit 2
fi
else
echo "Erreur : l’argument de l’option “-n” doit être un entier entre 1 et 100" >&2
exit 2
fi
fi
# Vérification de la présence des programmes
# “curl” et “xmllint”
for i in curl xmllint
do
prog=$(which $i 2> /dev/null)
if [[ -z $prog ]]
then
echo "" >&2
echo "Erreur : programme “$i” introuvable. Vérifier \$PATH." >&2
echo "" >&2
exit 2
fi
done
# Nettoyage en cas d’arrêt prématuré
trap nettoie HUP INT QUIT TERM
# Génération du fichier SOAP
cat << EOT > search$$.xml
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:woksearch="http://woksearch.v3.wokmws.thomsonreuters.com">
<soapenv:Header/>
<soapenv:Body>
<woksearch:search>
<queryParameters>
<databaseId>WOS</databaseId>
<userQuery>$query</userQuery>
EOT
# Cas de l’option “-b”
# valeurs possibles : SCI, SSCI, AHCI, ISTP, ISSHP, IC, CCR, BSCI, BHCI et ESCI
if [[ ${#bases[@]} -gt 0 ]]
then
for i in ${bases[@]}
do
if [[ $i =~ ^[A-Z]+:[A-Z]+$ ]]
then
coll=${i%:*}
edit=${i#*:}
else
coll='WOS'
edit=$i
fi
echo " <editions>" >> search$$.xml
echo " <collection>$coll</collection>" >> search$$.xml
echo " <edition>$edit</edition>" >> search$$.xml
echo " </editions>" >> search$$.xml
done
fi
if [[ -n $span ]]
then
regex="[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])"
if [[ $span =~ ^$regex:$regex$ ]]
then
begin=${span%:*}
end=${span#*:}
# Vérification de la validité de chaque date
for i in $begin $end
do
day=$(date -d $i 2> /dev/null)
if [[ -z $day ]]
then
echo ""
echo "Erreur : date “$i” invalide" >&2
nettoie
exit 4
fi
done
echo " <timeSpan>" >> search$$.xml
echo " <begin>$begin</begin>" >> search$$.xml
echo " <end>$end</end>" >> search$$.xml
echo " </timeSpan>" >> search$$.xml
elif [[ $span =~ ^[124]week$ ]]
then
echo " <symbolicTimeSpan>$span</symbolicTimeSpan>" >> search$$.xml
else
echo ""
echo "Erreur : argument incorrect pour l’option “-p”" >&2
nettoie
exit 4
fi
fi
cat << EOT >> search$$.xml
<queryLanguage>en</queryLanguage>
</queryParameters>
<retrieveParameters>
<firstRecord>1</firstRecord>
<count>$nrec</count>
EOT
# Cas de l'option “-t”
# Valeurs possibles : AU, CF, CG, CW, CV, LC, LD, PG, PY, RS, SO, TC et VL
# Valeurs possibles : (AU|CF|CG|CW|CV|LC|LD|PG|PY|RS|SO|TC|VL)
if [[ -n $tri ]]
then
if [[ ! $tri =~ ^(AU|CF|CG|CW|CV|LC|LD|PG|PY|SO|VL):[AD]$ && ! $tri =~ ^(RS|TC):D$ ]]
then
echo "Erreur : argument incorrect pour pour l’option “-t”" >&2
exit 4
fi
nom=${tri%%:*}
sens=${tri#*:}
echo " <sortField>" >> search$$.xml
echo " <name>$nom</name>" >> search$$.xml
echo " <sort>$sens</sort>" >> search$$.xml
echo " </sortField>" >> search$$.xml
fi
# Cas de l’option “-f”
# Valeurs possibles : UID, pub_info, names, full_name, titles, contributor,
# language, doctypes, conf_title, conf_date, conf_host, conf_locations, sponsors,
# keywords, keywords_plus, abstract, addresses, organizations, reprint_contact,
# email_addr, grant, fund_text, refs, address_spec, headings, subjects, identifiers,
# page, book_chapters et ids
if [[ ${#champs[@]} -gt 0 ]]
then
ns='Fields'
echo " <viewField>" >> search$$.xml
echo " <collectionName>WOS</collectionName>" >> search$$.xml
for item in ${champs[@]}
do
while [[ -n $item ]]
do
deb=${item%%,*}
fin=${item#*,}
echo " <fieldName>$deb</fieldName>" >> search$$.xml
if [[ $deb = $fin ]]
then
item=""
else
item=$fin
fi
done
done
echo " </viewField>" >> search$$.xml
else
ns='FullRecord'
fi
if [[ $recid -gt 0 ]]
then
echo " <option>" >> search$$.xml
echo " <key>RecordIDs</key>" >> search$$.xml
echo " <value>On</value>" >> search$$.xml
echo " </option>" >> search$$.xml
fi
cat << EOT >> search$$.xml
<option>
<key>targetNamespace</key>
<value>http://scientific.thomsonreuters.com/schema/wok5.4/public/$ns</value>
</option>
</retrieveParameters>
</woksearch:search>
</soapenv:Body>
</soapenv:Envelope>
EOT
out='WosApiOut.txt'
err='WosApiErr.txt'
curl -X POST -d @search$$.xml -b $cookie -c $cookies -v 'http://search.webofknowledge.com/esti/wokmws/ws/WokSearch?wsdl' \
-H "Cookie: SID=$sid" 2> $err | xmllint -format - > $out
qid=$(perl -ne 'print "$1" if m|<queryId>(.+?)</queryId>|;' $out)
if [[ -n $qid ]]
then
rec=$(perl -ne 'print "$1" if m|<recordsFound>(.+?)</recordsFound>|;' $out)
max=$(perl -ne 'print "$1" if m|<recordsSearched>(.+?)</recordsSearched>|;' $out)
echo " "
echo "Numéro de requête (queryId) : $qid "
if [[ $rec -gt 1 ]]
then
echo "$rec notices trouvées sur un total de $max notices "
else
echo "$rec notice trouvée sur un total de $max notices "
fi
echo " "
else
msg=$(perl -ne 'print "$1" if m|<faultstring>(.+?)</faultstring>|;' $out)
if [[ -n $msg ]]
then
echo " "
echo "Erreur : $msg "
echo " "
else
echo " "
echo "Erreur indéterminée. "
echo "Voir fichier “$err”. "
echo " "
fi
fi
nettoie
exit 0