koha-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Koha-cvs] koha/misc/cronjobs build_browser_and_cloud.pl n...


From: paul poulain
Subject: [Koha-cvs] koha/misc/cronjobs build_browser_and_cloud.pl n...
Date: Fri, 09 Mar 2007 15:44:20 +0000

CVSROOT:        /sources/koha
Module name:    koha
Changes by:     paul poulain <tipaul>   07/03/09 15:44:20

Added files:
        misc/cronjobs  : build_browser_and_cloud.pl notifyMailsOp.pl 
                         result.txt test_zebra_delete.pl update_items.pl 
                         zebraqueue_start.pl 

Log message:
        rel_3_0 moved to HEAD (introducing new files)

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/koha/misc/cronjobs/build_browser_and_cloud.pl?cvsroot=koha&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/koha/misc/cronjobs/notifyMailsOp.pl?cvsroot=koha&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/koha/misc/cronjobs/result.txt?cvsroot=koha&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/koha/misc/cronjobs/test_zebra_delete.pl?cvsroot=koha&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/koha/misc/cronjobs/update_items.pl?cvsroot=koha&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/koha/misc/cronjobs/zebraqueue_start.pl?cvsroot=koha&rev=1.2

Patches:
Index: build_browser_and_cloud.pl
===================================================================
RCS file: build_browser_and_cloud.pl
diff -N build_browser_and_cloud.pl
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ build_browser_and_cloud.pl  9 Mar 2007 15:44:20 -0000       1.2
@@ -0,0 +1,1502 @@
+#!/usr/bin/perl
+# small script that builds the tag cloud
+
+use strict;
+
+use C4::Koha;
+use C4::Context;
+use C4::Biblio;
+use Date::Calc;
+use Time::HiRes qw(gettimeofday);
+use ZOOM;
+use MARC::File::USMARC;
+use Getopt::Long;
+my ( $input_marc_file, $number) = ('',0);
+my ($version, $confirm,$test_parameter,$field,$batch,$max_digits,$cloud_tag);
+GetOptions(
+       'c' => \$confirm,
+       'h' => \$version,
+       'f:s' => \$field,
+       'b' =>\$batch,
+       'm:s' => \$max_digits,
+       't:s' => \$cloud_tag,
+);
+
+if ($version || (!$confirm)) {
+    print <<EOF
+    This script rebuilds the catalogue browser & the tag cloud
+    run the script with -c to execute it.
+    Parameters :
+    -b to run in batch mode, without any output
+    -f TTTs to define the MARC tag/subfield to use for building nav (676a in 
UNIMARC for dewey for example) If not defined, the browser table won't be 
modified.
+    -c to confirm & run the script.
+    -m to tell how many digits have to be used for browser (usually : 3, the 
1st 3 dewey digits for example)
+    -t TTT to define the MARC fields/subfield to use to fill the tag cloud. If 
not defined, the cloud table won't be filled.
+     
+     example :
+     export PERL5LIB=/path/to/koha;export 
KOHA_CONF=/etc/koha.xml;./build_browser_and_cloud.pl -b -f 676a -t 606 -c
+EOF
+;
+die;
+}
+
+##################################
+#
+# MAIN PARAMETERS
+#
+###################################
+
+$field =~ /(\d\d\d)(.?)/;
+my $browser_tag = $1;
+my $browser_subfield = $2;
+die "no cloud or browser field/subfield defined : nothing to do !" unless 
$browser_tag or $cloud_tag;
+
+my $dbh = C4::Context->dbh;
+my $starttime = time();
+
+my $i=0;
+$|=1; # flushes output
+my $starttime = gettimeofday;
+
+##################################
+#
+# Parse all the database.
+#
+###################################
+#FIXME : could be improved to get directly only biblios that have to be 
updated.
+
+my $sth = $dbh->prepare("select biblionumber from biblioitems");
+$sth->execute;
+# the result hash for the browser table
+my %browser_result;
+
+# the result hash for the cloud table
+my %cloud_result;
+while ((my ($biblionumber)= $sth->fetchrow)) {
+    $i++;
+    print "." unless $batch;
+    #now, parse the record, extract the item fields, and store them in 
somewhere else.
+    my $Koharecord = GetMarcBiblio($biblionumber);
+    # deal with BROWSER part
+    if ($browser_tag) { 
+        foreach my $browsed_field 
($Koharecord->subfield($browser_tag,$browser_subfield)) {
+            $browsed_field =~ s/\.//g;
+            my $upto = 
length($browsed_field)<=$max_digits?length($browsed_field):$max_digits;
+            for (my $i=1;$i <= $upto;$i++) {
+                $browser_result{substr($browsed_field,0,$i)}->{value}++;
+                $browser_result{substr($browsed_field,0,$i)}->{endnode}=1;
+            }
+        }
+    }
+    #deal with CLOUD part
+    if ($cloud_tag) {
+        foreach ($Koharecord->field($cloud_tag)) {
+            my $line;
+            foreach ($_->subfields()) {
+                next if $_->[0]=~ /\d/;
+                $line .= $_->[1].' ';
+            }
+            $line =~ s/ $//;
+            $cloud_result{$line}++;
+        }
+    }
+
+    my $timeneeded = gettimeofday - $starttime;
+    print "$i in $timeneeded s\n" unless ($i % 50  or $batch);
+}
+
+# fills the browser table
+if ($browser_tag) {
+    # read existing classification table is possible
+    my $classification;
+    if (C4::Context->preference('opaclanguages') eq 'en' && $browser_tag eq 
'676' & $browser_subfield eq 'a') {
+        $classification = dewey_french();
+    }
+    
+    # calculate end node...
+    foreach (keys %browser_result) {
+        my $father = substr($_,0,-1);
+        $browser_result{$father}->{notendnode}=1;
+    }
+    $dbh->do("truncate browser");
+    my $sth = $dbh->prepare("insert into browser 
(level,classification,description,number,endnode) values (?,?,?,?,?)");
+    foreach (keys %browser_result) {
+        
$sth->execute(length($_),$_,$classification->{$_}?$classification->{$_}:"classification
 $_",$browser_result{$_}->{value},$browser_result{$_}->{notendnode}?0:1);
+    }
+}
+
+# fills the cloud (tags) table
+if ($cloud_tag) {
+    $dbh->do("truncate tags");
+    my $sth = $dbh->prepare("insert into tags (entry,weight) values (?,?)");
+    foreach (keys %cloud_result) {
+        $sth->execute($_,$cloud_result{$_});
+    }
+}
+# $dbh->do("unlock tables");
+my $timeneeded = time() - $starttime;
+print "$i records done in $timeneeded seconds\n" unless $batch;
+
+
+sub dewey_french {
+return {
+    "0" => "Généralités (Ouvrages généraux (encyclopédies, 
bibliographies, etc.) et informatique)",
+    "00" => "Savoir et communication",
+    "001.42" => "Collecte, agencement, analyse des données",
+    "003" => "Systémique, systèmes",
+    "003.1" => "Identification de système",
+    "003.2" => "Prévisions. Futurologie",
+    "003.3" => "Modélisation par ordinateur",
+    "003.5" => "Théorie de la communication et du contrôle. Cybernétique. 
Stabilité des systèmes",
+    "003.52" => "Théorie de la perception",
+    "003.54" => "Théorie de l'information. Théorie du codage",
+    "003.56" => "Théorie de la décision",
+    "003.7" => "Types de systèmes",
+    "003.71" => "A grande échelle",
+    "003.74" => "Linéaires",
+    "003.75" => "Non linéaires",
+    "003.76" => "Stochastiques",
+    "003.78" => "A paramètres distribués",
+    "003.8" => "Selon leur relation avec le temps",
+    "003.83" => "Utilisant des unités de temps discrètes",
+    "003.85" => "Dynamiques",
+    "003.857" => "Chaotiques. Théorie du chaos",
+    "004" => "Informatique, traitement des données : principes, matériel, 
architecture, traitements, réseaux, périphériques",
+    "004.015 1" => "Principes mathématiques",
+    "004.019" => "Interaction homme-machine",
+    "004.026" => "Droit de l'informatique",
+    "004.1" => "Types spécifiques d'ordinateurs : généralités",
+    "004.16" => "Micro-ordinateurs",
+    "004.165" => "Micro-ordinateurs",
+    "004.19" => "Calculatrices électroniques",
+    "004.2" => "Analyse et conception des systèmes. Architecture des 
ordinateurs. Évaluation des performances",
+    "004.21" => "Analyse et conception des systèmes. Conduite de projets",
+    "004.22" => "Architecture des ordinateurs",
+    "004.24" => "Évaluation des performances",
+    "004.25" => "Analyse et conception des systèmes, architecture des 
ordinateurs, évaluation des performances d'ordinateurs spécifiques",
+    "004.3" => "Modes de traitement",
+    "004.33" => "Traitement en temps réel",
+    "004.35" => "Multitraitement ; traitement en parallèle",
+    "004.36" => "Traitement réparti. Client-serveur",
+    "004.5" => "Stockage des données",
+    "004.53" => "Mémoire interne",
+    "004.56" => "Mémoire externe",
+    "004.563" => "Disques magnétiques",
+    "004.565" => "Mémoires optiques (CD-ROM)",
+    "004.6" => "Interfaçage et communications. Télématique",
+    "004.61" => "Interfaçage et communications pour des types particuliers 
d'ordinateurs",
+    "004.62" => "Protocoles d'interfaçage et communications",
+    "004.64" => "Équipements (à bande de base, à bande large, modems, 
câbles en fibre optique, contrôleurs de périphériques en général)",
+    "004.65" => "Architecture et conception des réseaux de communication",
+    "004.66" => "Mode transmission des données, modes de communication des 
données (par paquets, multiplexage, ..)",
+    "004.67" => "Réseaux étendus (WAN)",
+    "004.678" => "Internet",
+    "004.68" => "Réseaux locaux (LAN). Intranet",
+    "004.69" => "Télématique",
+    "004.692" => "Courrier électronique",
+    "004.696" => "Vidéotex",
+    "004.7" => "Périphériques",
+    "004.71" => "pour des types particuliers d'ordinateurs",
+    "004.716" => "Pour micro-ordinateurs",
+    "004.75" => "Combinant entrée et sortie (terminaux)",
+    "004.76" => "D'entrée (claviers, lecteurs de cartes)",
+    "004.77" => "De sortie (COM, moniteur, imprimantes)",
+    "005" => "Informatique : programmation, logiciels, données, sécurité, 
SGBD",
+    "005.1" => "Algorithmique. Programmation",
+    "005.11" => "Méthodes de programmation",
+    "005.112" => "Modulaire",
+    "005.113" => "Structurée",
+    "005.114" => "Fonctionnelle",
+    "005.115" => "Logique",
+    "005.117" => "Orientée objet",
+    "005.12" => "Analyse et conception de logiciels",
+    "005.13" => "Langages de programmation",
+    "005.133" => "Langages de programmation particuliers",
+    "005.136" => "Langages machine, assembleur",
+    "005.14" => "Vérification, test, mesures, mise au point (débogage)",
+    "005.16" => "Maintenance des programmes et des logiciels",
+    "005.2" => "Programmation par types d'ordinateurs",
+    "005.3" => "Logiciels. Génie logiciel",
+    "005.368 4" => "Logiciels pour interfaces utilisateurs particulières",
+    "005.369" => "Progiciels",
+    "005.37" => "Logiciels pour systèmes d'exploitation particuliers",
+    "005.376" => "Logiciels pour applications clients-serveurs, groupware",
+    "005.4" => "Programmation et logiciels de systèmes",
+    "005.42" => "Programmation des systèmes",
+    "005.43" => "Logiciels de systèmes. Systèmes d'exploitation",
+    "005.434" => "Programmation du traitement",
+    "005.435" => "Programmation de la mémoire virtuelle",
+    "005.44" => "Logiciels de systèmes, SE pour différents types 
d'ordinateurs",
+    "005.45" => "Traducteurs de langages de programmation",
+    "005.452" => "Interpréteurs",
+    "005.453" => "Compilateurs",
+    "005.456" => "Assembleurs",
+    "005.6" => "Microprogrammation et microprogrammes. Microprocesseurs",
+    "005.7" => "Organisation des données",
+    "005.71" => "Transmission des données",
+    "005.713" => "Logiciels de transmission",
+    "005.713 6" => "Logiciels de transmission pour micro-ordinateurs",
+    "005.72" => "Préparation des données. Formats d'enregistrement. 
Encodages. Codes correcteurs",
+    "005.73" => "Structure des données",
+    "005.74" => "Fichiers et bases de données",
+    "005.740 65" => "Gestion électronique de documents, édition 
électronique",
+    "005.741" => "Organisation, modes d'accès. Tri et fusion",
+    "005.742" => "Index. Répertoires",
+    "005.746" => "Compression de données",
+    "005.75" => "Types de bases de données",
+    "005.8" => "Sécurité des données",
+    "005.82" => "Cryptage des données",
+    "005.84" => "Virus",
+    "005.86" => "Restauration des données",
+    "006" => "Méthodes particulières et application de l'informatique, IA, 
multimédia",
+    "006.3" => "Intelligence Artificielle",
+    "006.31" => "Apprentissage par ordinateur (EAO)",
+    "006.32" => "Réseaux neuronaux",
+    "006.33" => "Systèmes experts",
+    "006.35" => "Traitement du langage naturel",
+    "006.37" => "Vision artificielle",
+    "006.4" => "Reconnaissance de formes",
+    "006.42" => "Reconnaissance optique de formes",
+    "006.424" => "Reconnaissance optique de caractères",
+    "006.425" => "Reconnaissance optique de l'écriture",
+    "006.45" => "Reconnaissance acoustique de formes",
+    "006.454" => "Reconnaissance de la parole",
+    "006.5" => "Synthèse de sons par ordinateur",
+    "006.54" => "Synthèse de la parole",
+    "006.6" => "Infographie",
+    "006.62" => "sortie en infographie",
+    "006.66" => "Programmation (langages, logiciels)",
+    "006.67" => "Programmation pour ordinateurs particuliers",
+    "006.676" => "Programmation pour micro-ordinateurs",
+    "006.68" => "Programmes",
+    "006.693" => "Graphisme en 3 dimensions",
+    "006.696" => "Animation. Morphing",
+    "006.7" => "Multimédias",
+    "006.76" => "Programmation (langages, logiciels)",
+    "006.77" => "Programmation pour ordinateurs particuliers",
+    "006.78" => "Programmes",
+    "01" => "Bibliographies",
+    "02" => "économie et science de l'information",
+    "03" => "Encyclopédies générales",
+    "04" => "La vingtième édition n'attribue aucun sujet à ces indices",
+    "05" => "Publications en série et périodiques généraux et leurs index",
+    "06" => "Organisations générales et muséologie",
+    "07" => "Médias d'information: journalisme et édition",
+    "08" => "Recueils généraux et collections générales",
+    "09" => "Manuscrits et livres rares",
+    "1" => "Philosophie, parapsychologie et occultisme, psychologie",
+    "10" => "Généralités",
+    "101" => "Nature et méthode de la philosophie",
+    "11" => "Métaphysique",
+    "111" => "Métaphysique générale, ontologie",
+    "113" => "Création, cosmologie",
+    "114" => "Espace",
+    "115" => "Temps",
+    "116" => "Mouvement",
+    "117" => "Matière",
+    "118" => "Force",
+    "119" => "Quantité, nombre",
+    "12" => "Épistémologie, causalité, genre humain",
+    "122" => "Causalité",
+    "123" => "Liberté et nécessité",
+    "124" => "Téléologie",
+    "125" => "Finitude",
+    "128" => "Âme",
+    "129" => "Destinée de l'âme. Immortalité",
+    "13" => "Phénomènes paranormaux, parapsychologie, vie de l'esprit, 
philosophie de la culture",
+    "133" => "Sciences occultes",
+    "14" => "Écoles et courants philosophiques, (typologie) systèmes 
philosophiques",
+    "141" => "Systèmes philosophiques",
+    "15" => "Psychologie",
+    "159" => "Psychologie. Sciences cognitives. Psychopathologie",
+    "16" => "Logique",
+    "161" => "Logique",
+    "162" => "Raisonnement",
+    "164" => "Logique symbolique",
+    "165" => "Épistémologie",
+    "167" => "Méthodologie de la recherche",
+    "168" => "Méthode scientifique",
+    "17" => "Éthique (philosophie morale)",
+    "171" => "Morale individuelle",
+    "172" => "Morale sociale",
+    "173" => "Morale familiale",
+    "174" => "Morale professionnelle. Déontologie",
+    "175" => "Morale des divertissements",
+    "176" => "Morale sexuelle",
+    "177" => "Moralité et relations humaines",
+    "178" => "Morale et tempérance",
+    "179" => "Questions diverses",
+    "18" => "Philosophie ancienne, médiévale, orientale",
+    "181" => "Philisophie orientale",
+    "19" => "Philosophie occidentale moderne",
+    "2" => "Religion",
+    "20" => "Généralités",
+    "200" => "Généralités sur les religions",
+    "201" => "Christianisme : généralités",
+    "21" => "Religion naturelle",
+    "211" => "Dieu. Déisme, théisme, athéisme",
+    "212" => "Panthéisme",
+    "213" => "Création",
+    "214" => "Providence. Prédétermination",
+    "215" => "Religion et science, raison et révélation. L'Église et la 
science",
+    "216" => "Bien et mal",
+    "217" => "Devoirs de l'homme envers Dieu",
+    "218" => "Immortalité. Au-delà",
+    "219" => "Anthropomorphisme. Analogies et correspondances",
+    "22" => "Bible",
+    "221" => "Ancien testament (canon juif)",
+    "222" => "Ancien testament (canon chrétien) : livres historiques",
+    "223" => "Ancien testament (canon chrétien) : livres poétiques",
+    "224" => "Ancien testament (canon chrétien) : Prophètes",
+    "225" => "Nouveau testament",
+    "226" => "Évangiles. Actes des apôtres",
+    "227" => "Épîtres",
+    "228" => "Apocalypse",
+    "229" => "Livres deutérocanoniques. Apocryphes. Pseudépigraphes",
+    "23" => "Théologie dogmatique, théologie chrétienne",
+    "231" => "Dieu",
+    "232" => "Christologie",
+    "233" => "Anthropologie religieuse",
+    "234" => "Sotériologie. Doctrine du salut, grâce, foi",
+    "235" => "Anges. Pneumatologie. Saints",
+    "236" => "Eschatologie",
+    "237" => "Vie future",
+    "238" => "Symboles de la Foi : catéchismes, credos, confessions de foi",
+    "239" => "Théologie polémique. Défense de la Foi",
+    "24" => "Théologie morale et dévotion chrétiennes",
+    "241" => "Théologie morale. Morale chrétienne",
+    "242" => "Méditations",
+    "243" => "Prière. Lecture de la Bible",
+    "244" => "Lectures religieuses",
+    "245" => "Hymnes chrétiens",
+    "246" => "Art et symbolisme chrétiens",
+    "247" => "Mobilier ecclésiastique",
+    "248" => "Théologie ascétique et mystique. Piété, spiritualité",
+    "249" => "Culte domestique, dévotions familiales",
+    "25" => "Église locale et ordres religieux chrétiens",
+    "251" => "Homilétique. Histoire et théorie de la prédication",
+    "252" => "Sermons",
+    "253" => "Visites pastorales. Direction d'âmes",
+    "254" => "État et condition des prêtres",
+    "255" => "Confréries et congrégations laïques",
+    "256" => "Oeuvres paroissiales",
+    "257" => "Enseignement",
+    "258" => "Bienfaisance",
+    "259" => "Autres oeuvres",
+    "26" => "Théologie sociale chrétienne, ecclésiologie",
+    "261" => "Relations de l'Église chrétienne avec le monde",
+    "262" => "Organisation ecclésiastique",
+    "263" => "Dimanche",
+    "264" => "Liturgie chrétienne",
+    "265" => "Sacrements chrétiens",
+    "266" => "Missions chrétiennes",
+    "267" => "Associations et communautés religieuses chrétiennes",
+    "268" => "Catéchisation",
+    "269" => "Retraites, conversions, réveils, prosélytisme",
+    "27" => "Histoire et géographie de l'église chrétienne",
+    "271" => "Ordres religieux. Vie monastique",
+    "272" => "Persécutions des chrétiens",
+    "273" => "Hérésies et schismes",
+    "276" => "Patrologie",
+    "28" => "Confessions et sectes chrétiennes",
+    "281" => "Églises primitives et Églises orientales",
+    "282" => "Église catholique romaine",
+    "283" => "Églises épiscopaliennes nationales (anglicanisme)",
+    "284" => "Églises protestantes continentales",
+    "285" => "Églises protestantes britanniques (puritains, presbytériens, 
etc.)",
+    "286" => "Anabaptistes, mennonites, baptistes, aventistes",
+    "287" => "Méthodistes",
+    "288" => "Antitrinitaires, sociniens",
+    "289" => "Autres sectes et églises chrétiennes",
+    "29" => "Autres religions et religion comparée",
+    "291" => "Histoire comparée des religions",
+    "292" => "Religion des Grecs et des Romains anciens. Mythologie classique",
+    "293" => "Religions anciennes des Scandinaves, Baltes et Slaves",
+    "294" => "Bouddhisme, brahmanisme, hindouïsme",
+    "295" => "Religions perses",
+    "296" => "Judaïsme",
+    "297" => "Islam",
+    "298" => "Mouvements religieux récents et contemporains",
+    "299" => "Autres religions",
+    "3" => "Sciences humaines et sociales",
+    "30" => "Sociologie et anthropologie (301 à 307)",
+    "300" => "Généralités (300.1 à 300.9)",
+    "303" => "Méthode des sciences sociales",
+    "304" => "Questions sociales en général. Critique sociale",
+    "308" => "Sociographie",
+    "31" => "Statistiques générales",
+    "311" => "Statistique",
+    "312" => "Statistique de la population",
+    "314" => "Démographie",
+    "316" => "Sociologie",
+    "32" => "Science politique",
+    "321" => "Formes de l'organisation politique",
+    "322" => "Clergés et États",
+    "323" => "Politique intérieure",
+    "324" => "Élections",
+    "325" => "Migrations et colonisations",
+    "326" => "Esclavage, travail forcé",
+    "327" => "Relations internationales",
+    "328" => "Parlements. Gouvernement représentatif",
+    "329" => "Partis politiques",
+    "33" => "Économie",
+    "331" => "Économie du travail",
+    "332" => "Économie de la terre et de la propriété, du logement, 
régionale",
+    "334" => "Entreprises. Systèmes coopératifs",
+    "336" => "Économie financière. Systèmes monétaire et bancaire",
+    "338" => "Politique économique. Planification. Conjoncture. Secteurs de 
l'économie",
+    "339" => "Commerce. Économie mondiale",
+    "34" => "Droit",
+    "341" => "International",
+    "342" => "Public, constitutionnel et administratif",
+    "343" => "Pénal",
+    "344" => "Pénal militaire",
+    "347" => "Civil",
+    "348" => "Canonique et ecclésiastique",
+    "349" => "Autres branches du droit (travail, social, foncier, de 
l'environnement)",
+    "35" => "Administration publique. Science militaire",
+    "351" => "Missions et activités de l'administration publique",
+    "352" => "Administration locale",
+    "353" => "Administrations départementales, provinciales",
+    "354" => "Gouvernement central",
+    "355" => "Art militaire. Polémologie. Organisation des forces armées",
+    "356" => "Infanterie et logistique",
+    "357" => "Cavalerie",
+    "358" => "Artillerie. Forces aériennes",
+    "359" => "Forces navales",
+    "36" => "Problèmes et services sociaux",
+    "364" => "Problèmes sociaux. Aide sociale",
+    "365" => "Droit au logement",
+    "366" => "Droit de la consommation",
+    "368" => "Assurances",
+    "369" => "Assurance sociale",
+    "37" => "Éducation",
+    "371" => "Organisation des systèmes éducatifs",
+    "372" => "Éducation pré-scolaire et enseignement du premier degré",
+    "373" => "Enseignement général",
+    "374" => "Formation permanente",
+    "376" => "Écoles spéciales (handicapés, groupes sociaux particuliers, 
etc.)",
+    "377" => "Enseignement technique",
+    "378" => "Enseignement supérieur",
+    "379" => "Loisirs éducatifs",
+    "38" => "Commerce, communications, transports",
+    "39" => "Coutumes et folklore et étiquette",
+    "391" => "Costume, parures, ornements",
+    "392" => "Coutumes relatives à la vie privée (naissance, mariage, 
cuisine, etc.)",
+    "393" => "Rites funéraires",
+    "394" => "Vie publique",
+    "395" => "Cérémonial, étiquette, savoir-vivre",
+    "396" => "Condition féminine",
+    "398" => "Folklore",
+    "4" => "Langues (langues parlées et écrites, grammaires, dictionnaires)",
+    "40" => "Généralités",
+    "41" => "Linguistique",
+    "42" => "Anglais",
+    "43" => "Allemand et autres langues germaniques",
+    "44" => "Français et autres langues romanes",
+    "45" => "Italien, roumain et langues rhéto-romanes",
+    "46" => "Espagnol et portugais",
+    "47" => "Latin et autres langues italiques",
+    "48" => "Grec et autres langues helléniques",
+    "49" => "Autres langues",
+    "5" => "Sciences de la nature et mathématiques",
+    "50" => "Généralités",
+    "51" => "Mathématiques",
+    "510.1" => "Fondements des mathématiques. Philosophie des mathématiques",
+    "511" => "Principes généraux",
+    "511.2" => "Systèmes mathématiques",
+    "511.3" => "Logique, automates, langages formels, récurrence, 
décidabilité. opérateurs logiques",
+    "511.32" => "Ensembles. Algèbre de Boole",
+    "511.322" => "Nombres transfinis",
+    "511.33" => "Relations, treillis, systèmes et structures ordonnés",
+    "511.35" => "Théorie de la récursivité. Fonctions récursives",
+    "511.4" => "Approximation et développements",
+    "511.5" => "Théorie des graphes. Construction des graphes",
+    "511.6" => "Analyse combinatoire",
+    "511.8" => "Modèles mathématiques et simulation. Algorithmes",
+    "512" => "Algèbre, théorie des nombres",
+    "512.2" => "Groupes et théorie des groupes",
+    "512.3" => "Corps : théorie des corps, théorie de Galois",
+    "512.4" => "Anneaux, domaines d'intégrité, idéaux. Dilatation. Modules. 
Radicaux",
+    "512.5" => "Algèbres linéaire, multilinéaire, multidimensionnelle",
+    "512.52" => "Espaces vectoriels",
+    "512.55" => "Algèbres et groupes topologiques, algèbres et groupes 
connexes",
+    "512.56" => "Algèbres différentielles et des différences",
+    "512.57" => "Algèbres-quotients (Clifford, extérieure, spineurs, 
tensorielle, ...)",
+    "512.7" => "Théorie des nombres. Treillis",
+    "512.72" => "Théorie des nombres de fractions continuées",
+    "512.9" => "Fondements de l'algèbre",
+    "512.94" => "Théorie des équations",
+    "512.943" => "Déterminants et matrices ",
+    "512.944" => "Théorie des formes. Théorie des invariants algébriques",
+    "512.96" => "Algèbre des fonctions sans équation. Fonctions 
rationnelles",
+    "512.97" => "Inégalités",
+    "514" => "Topologie",
+    "514.2" => "algébrique",
+    "514.3" => "des espaces. Topologie métrique",
+    "514.7" => "analytique",
+    "514.72" => "différentielle. Foliations",
+    "514.74" => "Analyse globale",
+    "514.742" => "Fractales",
+    "515" => "Analyse",
+    "515.2" => "Généralités",
+    "515.24" => "Suites et séries. Processus infinis",
+    "515.243" => "Séries. Séries infinies. Sommabilité",
+    "515.243 2" => "Séries de puissances",
+    "515.243 3" => "Analyse de Fourier, analyse harmonique. Analyse par 
ondelettes",
+    "515.25" => "Équations et fonctions",
+    "515.3" => "Calcul différentiel. Équations différentielles",
+    "515.33" => "Calcul différentiel",
+    "515.35" => "Équations différentielles",
+    "515.352" => "Ordinaires",
+    "515.353" => "Aux dérivées partielles",
+    "515.354" => "Linéaires",
+    "515.355" => "Non linéaires",
+    "515.4" => "Calcul intégral. Équations intégrales",
+    "515.42" => "Théorie de la mesure et de l'intégration. Théorie 
ergodique",
+    "515.43" => "Calcul intégral. Intégration. Sommabilité",
+    "515.45" => "Équations intégrales",
+    "515.46" => "Inégalités intégrales",
+    "515.5" => "Fonctions spéciales",
+    "515.52" => "Intégrales eulériennes (p. ex. fonctions gamma, fonctions 
bêta)",
+    "515.53" => "Fonctions harmoniques",
+    "515.54" => "Fonctions de Mathieu",
+    "515.55" => "Polynômes orthogonaux",
+    "515.56" => "Fonction zêta",
+    "515.6" => "Autres méthodes analytiques",
+    "515.62" => "Calcul des différences finies. Problèmes aux limites",
+    "515.623" => "Différentiation numérique",
+    "515.624" => "Intégration numérique",
+    "515.625" => "Équations de la différence",
+    "515.63" => "Analyse vectorielle, tensorielle, spinorielle. Calcul 
vectoriel et tensoriel",
+    "515.64" => "Calcul des variations. Théorie mathématique de la commande",
+    "515.7" => "Analyse fonctionnelle",
+    "515.72" => "Calcul opérationnel",
+    "515.723" => "Transformées (opérateurs intégraux)",
+    "515.724" => "Théorie de l'opérateur",
+    "515.724 2" => "Opérateurs différentiels",
+    "515.73" => "Espaces vectoriels topologiques. Espaces linéaires 
topologiques",
+    "515.74" => "Fonctionnelles",
+    "515.782" => "Théorie de la distribution. Dualité. Espaces",
+    "515.784" => "Théorie de la valorisation",
+    "515.785" => "Analyse harmonique abstraite. Analyse des groupes de 
Fourier",
+    "515.8" => "Fonctions de variables réelles",
+    "515.83" => "Fonctions d'une variable réelle",
+    "515.84" => "Fonctions de plusieurs variables réelles",
+    "515.9" => "Fonctions de variables complexes",
+    "515.93" => "Surfaces de Riemann",
+    "515.94" => "Espaces analytiques, à n-dimensions, de Teichmüller",
+    "515.983" => "Fonctions elliptiques",
+    "515.984" => "Fonction thêta",
+    "516" => "Géométrie",
+    "516.1" => "Généralités. Géométrie métrique. Transformations. 
Automorphismes",
+    "516.2" => "Euclidienne",
+    "516.3" => "Analytiques",
+    "516.35" => "Algébrique",
+    "516.352" => "Courbes et surfaces sur des plans projectifs et affines. 
Théorie des courbes",
+    "516.353" => "Variétés algébriques de grandes dimensions",
+    "516.36" => "Géométrie différentielle et intégrale. Surfaces. Courbes. 
Variétés différentiables",
+    "516.362" => "Géométrie intégrale (géométrie globalement 
différentielle)",
+    "516.363" => "Géométrie différentielle locale et intrinsèque",
+    "516.37" => "Géométries différentielles métriques",
+    "516.4" => "Affine",
+    "516.5" => "Projective",
+    "516.6" => "Descriptive abstraite",
+    "516.9" => "Non euclidiennes",
+    "519" => "Probabilités, Statistiques mathématiques, Mathématiques 
appliquées",
+    "519.2" => "Stochastiques, probabilités géométriques, hasard..",
+    "519.23" => "Processus stochastiques",
+    "519.24" => "Distributions de probabilités. Probabilités descriptives",
+    "519.28" => "Sujets particuliers",
+    "519.282" => "Trajets aléatoires. Méthode de Monte-Carlo",
+    "519.287" => "Attentes et prédictions",
+    "519.3" => "Théorie des jeux. Optimisation mathématique",
+    "519.4" => "Analyse numérique appliquée.",
+    "519.5" => "Mathématiques statistiques. Méthodes paramétriques et non 
paramétriques",
+    "519.502 462" => "Statistiques pour ingénieurs",
+    "519.52" => "Théorie de l'échantillonnage",
+    "519.53" => "Statistique descriptive. Analyse de population",
+    "519.532" => "Distribution par fréquence",
+    "519.533" => "Mesure de tendance centrale. Médiane, moyenne, mode",
+    "519.534" => "Mesure de déviation",
+    "519.535" => "Analyse multivariée. Analyse de la structure latente",
+    "519.535 4" => "Analyse factorielle",
+    "519.536" => "Analyse de régression",
+    "519.537" => "Analyse de corrélation",
+    "519.538" => "Analyse de variance et de covariance",
+    "519.54" => "Inférence statistique",
+    "519.542" => "Théorie de la décision. Théorie bayésienne de la 
décision",
+    "519.544" => "Théorie de l'estimation",
+    "519.55" => "Séries chronologiques",
+    "519.56" => "Vérification des hypothèses (p. ex. vérification de c ²)",
+    "519.7" => "Programmation",
+    "519.8" => "Sujets particuliers",
+    "519.82" => "Théorie des files d'attente. Embouteillage. Réservation",
+    "519.83" => "Inventaire. Gestion des stocks et des approvisionnements",
+    "519.84" => "Succès des parcours",
+    "519.85" => "Modélisation des phénomènes biologiques, écologiques ou 
sociologiques",
+    "519.86" => "Contrôle de la qualité. Autres ajustements statistiques",
+    "52" => "Astronomie, Astrophysique, Recherche spatiale, Géodésie",
+    "520.9" => "Histoire de l'astronomie",
+    "521" => "Mécanique céleste",
+    "521.1" => "Gravitation",
+    "521.3" => "Orbites",
+    "522" => "Observation",
+    "523" => "Les corps célestes",
+    "523.01" => "Astrophysique",
+    "523.1" => "L'univers : l'espace, les galaxies, les quasars",
+    "523.111" => "L'espace",
+    "523.112" => "Les galaxies",
+    "523.113" => "La Voie lactée. La matière interstellaire",
+    "523.115" => "Les quasars",
+    "523.12" => "Cosmogonie",
+    "523.2" => "Le système solaire (généralités)",
+    "523.3" => "La lune",
+    "523.4" => "Les planètes et leurs satellites",
+    "523.44" => "Les astéroïdes",
+    "523.5" => "Les météorites. Le vent solaire",
+    "523.6" => "Les comètes",
+    "523.7" => "Le soleil",
+    "523.8" => "Les étoiles",
+    "523.9" => "Éclipses, conjonctions, occultations (en général)",
+    "525" => "La Terre",
+    "525.1" => "Constantes et dimensions",
+    "525.3" => "Orbite et mouvements",
+    "526" => "Géodésie. Topographie. Arpentage. Photogrammétrie. 
Cartographie",
+    "526.1" => "Géodésie. (généralités)",
+    "526.8" => "Cartographie",
+    "526.9" => "Observation de la Terre",
+    "526.982" => "Photogrammétrie",
+    "528" => "Éphémérides",
+    "529" => "Chronologie. Calendriers. Horloge",
+    "529.3" => "Calendriers",
+    "529.7" => "Mesure du temps",
+    "53" => "Physique",
+    "530.1" => "Physique théorique. Physique mathématique",
+    "530.11" => "Théorie de la relativité",
+    "530.12" => "Mécanique quantique",
+    "530.13" => "Mécanique statistique",
+    "530.14" => "Théories des champs et théories ondulatoires",
+    "530.141" => "Théories électromagnétiques de la matière",
+    "530.15" => "Physique mathématique",
+    "530.4" => "États de la matières",
+    "530.41" => "Physique de l'état solide. Physique de la matière 
condensée",
+    "530.42" => "Physique de l'état liquide. Superfluidité",
+    "530.43" => "Physique de l'état gazeux",
+    "530.44" => "Physique des plasmas",
+    "530.47" => "États de la matière",
+    "530.8" => "Mesures",
+    "531" => "Mécanique générale, Mécanique des corps solides et rigides",
+    "531.1" => "Dynamique, statique, physique des particules",
+    "531.11" => "Dynamique (p. ex. écoulement, rhéologie)",
+    "531.112" => "Cinématique",
+    "531.113" => "Cinétique",
+    "531.113 3" => "Ondes (p. ex. ondes de choc)",
+    "531.113 4" => "Rhéologie. Friction et viscosité",
+    "531.14" => "Masse et gravité. Densité",
+    "531.16" => "Mécanique des particules",
+    "531.163" => "Dynamique des particules",
+    "531.2" => "Statique des solides. Inertie",
+    "531.3" => "Dynamique des solides",
+    "531.32" => "Vibrations. Oscillations. Mouvement pendulaire",
+    "531.33" => "Ondes",
+    "531.35" => "Forces centrifuges et centripètes",
+    "531.38" => "Déformation et contraintes",
+    "531.4" => "Friction et viscosité des solides",
+    "531.5" => "Masse et gravité des solides. Projectiles. Loi de la chute 
des corps",
+    "531.6" => "Énergie. Moment. Travail",
+    "532" => "Mécaniques des fluides et des liquides",
+    "532.02" => "Statique, inertie",
+    "532.05" => "Dynamique",
+    "532.051" => "Écoulement. Vitesse, viscosité",
+    "532.059" => "Ondes. Mouvement tourbillonnaire. Cavitation",
+    "532.2" => "Hydrostatique",
+    "532.4" => "Masse, densité, poids spécifique",
+    "532.5" => "Hydrodynamique",
+    "532.51" => "Écoulement",
+    "532.57" => "Vitesse",
+    "532.58" => "Viscosité et friction. Élasticité et compressibilité",
+    "532.59" => "Ondes. Mouvement tourbillonnaire. Cavitation",
+    "533" => "Mécanique des gaz",
+    "533.1" => "Statique. Masse, densité, poids spécifique",
+    "533.2" => "Dynamique",
+    "533.21" => "Écoulement",
+    "533.27" => "Vitesse",
+    "533.28" => "Viscosité. Friction. Élasticité et compressibilité",
+    "533.29" => "Ondes. Mouvement tourbillonnaire. Cavitation",
+    "533.5" => "Vide",
+    "533.6" => "Aéromécanique",
+    "533.7" => "Théorie cinétique des gaz",
+    "534" => "Acoustique, Vibration",
+    "534.1" => "Génération du son",
+    "534.2" => "Transmission du son",
+    "534.3" => "Caractéristiques du son. Effet Doppler",
+    "534.5" => "Vibrations sonores",
+    "535" => "Lumière, Optique",
+    "535.01" => "Régions spectrales",
+    "535.1" => "Théories",
+    "535.2" => "Optique physique",
+    "535.22" => "Intensité lumineuse",
+    "535.24" => "Vitesse de la lumière",
+    "535.3" => "Transmission, absorption, émission de la lumière",
+    "535.32" => "Optique géométrique",
+    "535.323" => "Réflexion",
+    "535.324" => "Réfraction",
+    "535.326" => "Absorption",
+    "535.35" => "Luminescence",
+    "535.4" => "Dispersion, interférence, diffraction de la lumière",
+    "535.5" => "Faisceaux lumineux",
+    "535.52" => "Polarisation",
+    "535.6" => "Couleur",
+    "535.8" => "Spectroscopie",
+    "535.84" => "Spectroscopie infrarouge, chromatique, ultraviolette,. Raman",
+    "536" => "Thermodynamique, Chaleur",
+    "536.1" => "Théories",
+    "536.2" => "Transfert de chaleur",
+    "536.3" => "Rayonnement",
+    "536.4" => "Effets de la chaleur sur la matière",
+    "536.41" => "Dilatation. Contraction. Coefficients de dilatation. 
Relations pression-volume-température",
+    "536.42" => "Fusion. Solidification. Point de fusion. Surfusion",
+    "536.44" => "Vaporisation et condensation, sublimation, incandescence",
+    "536.5" => "Température",
+    "536.6" => "Capacité thermique et chaleur spécifique. Calorimétrie",
+    "536.7" => "Thermodynamique",
+    "536.71" => "cycle de Carnot, loi de Joule, équations de Maxwell",
+    "536.73" => "Entropie",
+    "537" => "Electricité, Electronique, Electromagnétisme, 
Electrodynamique",
+    "537.1" => "Théories",
+    "537.12" => "Théories des ondes",
+    "537.123" => "Théories des micro-ondes",
+    "537.125" => "Théories des guides d'ondes",
+    "537.14" => "Théorie corpusculaire",
+    "537.2" => "Électrostatique",
+    "537.21" => "Charge et potentiel électriques. Triboélectricité",
+    "537.24" => "Diélectricité, électrets",
+    "537.5" => "Électronique, électronique quantique",
+    "537.52" => "Décharges disruptives",
+    "537.53" => "Décharges d'électrons dans des tubes à gaz raréfiés et à
 vide",
+    "537.532" => "Ionisation des gaz. Balistique des électrons",
+    "537.534" => "Électronique des ondes radio et des micro-ondes. 
Spectroscopie",
+    "537.535" => "Rayons X et rayons gamma (plus de 1017 Hz)",
+    "537.535 7" => "Spectroscopie. Spectroscopie Mössbauer",
+    "537.54" => "Phénomènes photoélectriques (p. ex. photoconductivité, 
photoémissivité, photovoltaïsme)",
+    "537.56" => "Optique électronique et ionique",
+    "537.6" => "Électrodynamique. Thermoélectricité",
+    "537.62" => "Conduction. Résistance. Conductivité. Résistivité",
+    "537.622" => "Semiconductivité. Semi-conducteurs",
+    "537.623" => "Supraconductivité et supraconducteurs",
+    "537.624" => "Effets thermiques des courants",
+    "537.65" => "Thermoélectricité",
+    "537.67" => "Électrodynamique quantique",
+    "538" => "Magnétisme",
+    "538.3" => "Propriétés magnétiques. Phénomènes magnétiques",
+    "538.36" => "Résonance magnétique. Résonance magnétique nucléaire",
+    "538.4" => "Substances magnétiques. Aimants naturels. Induction 
magnétique",
+    "538.7" => "Géomagnétisme",
+    "539" => "Nature physique de la matière, Physique moderne",
+    "539.1" => "Structure de la matière",
+    "539.12" => "Structure moléculaire",
+    "539.14" => "Structure atomique",
+    "539.2" => "Rayonnement. Spectre électromagnétique. Ondes et radiations 
électromagnétiques",
+    "539.6" => "Relations atome-atome, molécule-molécule. Spectre 
moléculaire et vibratoire",
+    "539.7" => "Physique atomique et nucléaire",
+    "539.72" => "Physique des particules. Antiparticules, particules 
relativistes",
+    "539.721 67" => "Quarks",
+    "539.721 7" => "Photons",
+    "539.722" => "Radiations ionisantes",
+    "539.722 2" => "Rayons X et gamma",
+    "539.722 3" => "Rayons cosmiques",
+    "539.723" => "Noyau et atome considéré comme des particules",
+    "539.723 2" => "Noyaux. Deutérons. Particules a",
+    "539.723 4" => "Ions lourds",
+    "539.725" => "Caractéristiques des particules",
+    "539.73" => "Accélération des particules. Bombardement, faisceaux de 
particules",
+    "539.737" => "Accélération de particules particulières",
+    "539.74" => "Structure nucléaire, des isotopes et des nucléides, 
modèles",
+    "539.744" => "Interprétation spectroscopique",
+    "539.75" => "Réactions et interactions nucléaires",
+    "539.752" => "Radioactivité naturelle",
+    "539.753" => "Radioactivité artificielle",
+    "539.754" => "Interactions fondamentales",
+    "539.756" => "Réactions photonucléaires",
+    "539.757" => "Collision",
+    "539.758" => "Diffusion",
+    "539.76" => "Physique des hautes énergies. Réaction en chaîne",
+    "539.762" => "Fission nucléaire",
+    "539.764" => "Fusion nucléaire",
+    "539.77" => "Détection et mesure de particules et de la radioactivité",
+    "54" => "Chimie, Cristallographie, Mineralogie",
+    "540.11" => "Théories antiques et médiévales. Alchimie. Théorie du 
phlogistique",
+    "541" => "Chimie physique et théorique",
+    "541.042" => "États de la matière",
+    "541.042 1" => "Chimie de l'état solide",
+    "541.042 2" => "Chimie de l'état liquide",
+    "541.042 3" => "Chimie de l'état gazeux",
+    "541.042 4" => "Chimie des plasmas",
+    "541.2" => "Chimie théorique",
+    "541.22" => "Structure moléculaire",
+    "541.24" => "Structure atomique. Organisation spatiale. Loi de 
périodicité des éléments (tables périodiques : 546.8)",
+    "541.26" => "Stoechiométrie",
+    "541.28" => "Chimie quantique. Orbitales moléculaires et atomiques. 
Spectroscopie à résonance magnétique",
+    "541.3" => "Chimie physique",
+    "541.33" => "Chimie des surfaces",
+    "541.34" => "Chimie des solutions",
+    "541.345" => "Chimie des colloïdes. Gels, mousses, hydrosols, aérosols",
+    "541.348" => "Composants des solutions (solvants, solutés, précipités)",
+    "541.35" => "Photochimie et chimiluminescence",
+    "541.351" => "Transformations de l'énergie",
+    "541.353" => "Réactions photochimiques dues à des radiations 
particulières. Rayonnement infrarouge. Lumière visible. Rayonnement 
ultraviolet",
+    "541.36" => "Thermochimie et thermodynamique",
+    "541.37" => "Électrochimie. Électrolyse. Magnétochimie",
+    "541.38" => "Radiochimie (chimie nucléaire)",
+    "541.39" => "Réactions, synthèses, équilibres chimiques. Catalyse",
+    "542" => "Chimie expérimentale",
+    "543" => "Chimie analytique",
+    "544" => "Analyse qualitative",
+    "545" => "Analyse quantitative",
+    "546" => "Chimie minérale et inorganique",
+    "546.2" => "L'hydrogène et ses composés",
+    "546.22" => "L'eau",
+    "546.24" => "Les acides",
+    "546.3" => "Les métaux, leurs composés et leurs mélanges. Les alliages",
+    "546.31" => "Les éléments métalliques",
+    "546.32" => "Les bases",
+    "546.34" => "Les sels",
+    "546.38" => "Métaux alcalins",
+    "546.39" => "Métaux alcalino-terreux",
+    "546.4" => "Groupe 3B",
+    "546.5" => "Groupe 4B",
+    "546.6" => "Groupe 8",
+    "546.7" => "Groupe 5A",
+    "546.8" => "Table périodique",
+    "547" => "Chimie organique",
+    "547.01" => "Hydrocarbures",
+    "547.02" => "Composés halogènes",
+    "547.03" => "Composés oxygénés et hydroxylés",
+    "547.031" => "Alcools",
+    "547.035" => "Éthers",
+    "547.036" => "Aldéhydes et cétones",
+    "547.037" => "Acides",
+    "547.038" => "Esters ",
+    "547.04" => "Composés azotés",
+    "547.05" => "Composés organométalliques",
+    "547.06" => "Composés sulfurés",
+    "547.07" => "Composés phosphorés",
+    "547.08" => "Composés siliciés",
+    "547.1" => "Chimie organique physique et théorique",
+    "547.2" => "Synthèse et réactions classiques",
+    "547.21" => "Alkylation, acylation, aromatisation",
+    "547.22" => "Addition et substitution halogénées et hydroxylées",
+    "547.223" => "Halogénation",
+    "547.225" => "Hydrolyse et saponification",
+    "547.23" => "Oxydation et réduction",
+    "547.24" => "Estérification",
+    "547.25" => "Amination et diazotisation",
+    "547.26" => "Nitration et nitrosation",
+    "547.27" => "Sulfonation",
+    "547.28" => "Polymérisation et condensation",
+    "547.29" => "Fermentation",
+    "547.3" => "Chimie organique analytique",
+    "547.4" => "Composés aliphatiques",
+    "547.41" => "Hydrocarbures",
+    "547.5" => "Composés cycliques",
+    "547.59" => "Composés hétérocycliques",
+    "547.6" => "Composés aromatiques",
+    "547.61" => "Hydrocarbures",
+    "547.62" => "Composés halogénés",
+    "547.63" => "Composés oxygénés et hydroxylés",
+    "547.7" => "Composés macromoléculaires et composés connexes",
+    "547.71" => "Terpènes et huiles essentielles. Camphres",
+    "547.72" => "Alcaloïdes",
+    "547.73" => "Stéroïdes et hormones",
+    "547.74" => "Vitamines",
+    "547.75" => "Protéines. Acides aminés",
+    "547.76" => "Antibiotiques",
+    "547.77" => "Lipides",
+    "547.78" => "Hydrates de carbone",
+    "547.79" => "Acides nucléiques",
+    "547.8" => "Autres substances organiques",
+    "547.82" => "Substances fossiles",
+    "547.83" => "Pétrole",
+    "547.84" => "Polymères, élastomères",
+    "547.86" => "Colorants et pigments",
+    "547.869" => "Pigments",
+    "548" => "Cristallographie",
+    "548.3" => "Chimique. Isomorphisme, polymorphisme, pseudomorphisme",
+    "548.5" => "Croissance des cristaux",
+    "548.7" => "Mathématique",
+    "548.8" => "Physique et structurale",
+    "548.81" => "Structurale. Cristallographie géométrique, réseaux de 
cristaux",
+    "548.83" => "De la diffraction",
+    "548.84" => "Propriétés mécaniques des cristaux",
+    "548.85" => "Propriétés électriques, électroniques, magnétiques des 
cristaux",
+    "548.86" => "Propriétés thermiques des cristaux",
+    "548.9" => "Cristallographie optique",
+    "549" => "Minéralogie",
+    "549.1" => "Identification minéralogique",
+    "549.11" => "Formations minéralogiques",
+    "549.12" => "Minéralogie physique",
+    "549.13" => "Minéralogie chimique",
+    "549.18" => "Minéralogie cristallographique",
+    "549.2" => "Éléments naturels",
+    "549.3" => "Sulfures, sulfosels, minéraux connexes",
+    "549.4" => "Halogénures",
+    "549.5" => "Oxydes",
+    "549.6" => "Silicates",
+    "549.7" => "Autres minéraux",
+    "549.9" => "Répartition géographique des minéraux",
+    "55" => "Sciences de la terre, Géologie, Météorologie",
+    "550.22" => "Coupes et cartes géologiques",
+    "551" => "Géologie générale",
+    "551.028" => "Télédétection",
+    "551.1" => "Géophysique",
+    "551.11" => "Géophysique interne",
+    "551.112" => "Le noyau terrestre",
+    "551.116" => "Le manteau terrestre",
+    "551.12" => "Géophysique interne",
+    "551.13" => "L'écorce terrestre. Le magma",
+    "551.136" => "La tectonique des plaques",
+    "551.2" => "Géodynamique interne. Processus endogènes : volcans, 
séismes, phénomènes thermiques",
+    "551.21" => "Volcanisme : phénomènes volcaniques, volcans, éruptions",
+    "551.22" => "Sismologie",
+    "551.23" => "Phénomènes thermiques. Gaz.",
+    "551.3" => "Phénomènes de surfaces, processus exogènes et leurs agents",
+    "551.302" => "Érosion",
+    "551.303" => "Transport et dépôts de matière. Sédimentation",
+    "551.304" => "Les sédiments",
+    "551.305" => "Formation du sol",
+    "551.307" => "Mouvements de masses",
+    "551.31" => "Action de la glace, glaciologie",
+    "551.35" => "Action des eaux",
+    "551.36" => "Action des eaux marines",
+    "551.37" => "Action du vent",
+    "551.4" => "Géomorphologie",
+    "551.415" => "Des zones arides",
+    "551.42" => "Des îles",
+    "551.43" => "Des zones élevées",
+    "551.45" => "Des régions planes et des côtes",
+    "551.453" => "Des régions planes",
+    "551.457" => "Des littoraux",
+    "551.46" => "Océanographie. Hydrographie marine. Topographie sous-marine. 
Fonds marins",
+    "551.460 8" => "Géologie et géomorphologie sous-marines",
+    "551.48" => "Hydrologie. Hydrographie des eaux douces. Cycle hydrologique",
+    "551.49" => "Hydrologie souterraine",
+    "551.5" => "Météorologie",
+    "551.56" => "Électricité et optique atmosphériques. Phénomènes 
optiques",
+    "551.6" => "Climatologie",
+    "551.7" => "Géologie historique. Paléogéographie. Stratigraphie",
+    "551.701" => "Méthodes de datation",
+    "551.71" => "Précambrien",
+    "551.712" => "Archéen",
+    "551.72" => "Paléozoïque",
+    "551.723" => "Cambrien",
+    "551.75" => "Carbonifère. Permien",
+    "551.76" => "Mésozoïque (ère secondaire)",
+    "551.762" => "Trias",
+    "551.766" => "Jurassique",
+    "551.77" => "Crétacé",
+    "551.78" => "Cénozoïque (ère tertiaire)",
+    "551.782" => "Paléogène",
+    "551.783" => "Paléocène",
+    "551.784" => "Éocène",
+    "551.785" => "Oligocène",
+    "551.786" => "Néogène",
+    "551.787" => "Miocène",
+    "551.788" => "Pliocène",
+    "551.79" => "Ère quaternaire",
+    "551.792" => "Pléistocène",
+    "551.793" => "Postglaciaire",
+    "551.8" => "Géologie structurale. Tectonique",
+    "551.81" => "Stratification",
+    "551.82" => "Orogénie",
+    "551.86" => "Synclinaux et anticlinaux",
+    "551.87" => "Failles, dislocations",
+    "551.88" => "Intrusions",
+    "551.9" => "Géochimie",
+    "552" => "Roches",
+    "552.1" => "Eruptives ou ignées",
+    "552.2" => "Volcaniques",
+    "552.3" => "Plutoniques",
+    "552.4" => "Métamorphiques",
+    "552.5" => "Sédimentaires",
+    "552.58" => "Carbonatées",
+    "552.8" => "Pétrologie microscopique (lames minces)",
+    "553" => "Géologie économique, Minéraux, Formation et gisements de 
minerais",
+    "553.2" => "Matières carbonées",
+    "553.25" => "Charbon",
+    "553.28" => "Pétrole et gaz naturel",
+    "553.3" => "Fer",
+    "553.4" => "Métaux non ferreux",
+    "553.5" => "Pierres à bâtir",
+    "553.8" => "Pierres précieuses",
+    "554" => "Géologie de l'Europe",
+    "554.4" => "Géologie de la France",
+    "555" => "Géologie des autres continents",
+    "559" => "Géologie des autres continents",
+    "559.8" => "Géologie de l'Arctique et de l'Antarctique",
+    "559.9" => "Géologie extra-terrestre",
+    "559.92" => "Géologie des planètes",
+    "56" => "Paléonthologie, Paléozoologie",
+    "560" => "Paléontologie. Fossiles",
+    "560.12" => "Classification des fossiles",
+    "560.17" => "Paléontologie stratigraphique",
+    "560.171" => "Archéen et précambrien",
+    "560.172" => "Ère primaire",
+    "560.176" => "Ère secondaire",
+    "560.178" => "Ères tertiaire et quaternaire",
+    "560.45" => "Paléoécologie",
+    "560.9" => "Aspects historiques et géographiques",
+    "560.944" => "Paléontologie de la France",
+    "561" => "Paléobotanique",
+    "562" => "Paléozoologie systématique : invertébrés",
+    "563" => "Paléozoologie systématique : protozoaires, parazoaires, 
coelentérés, échinodermes, phylums apparentés",
+    "564" => "Paléozoologie systématique : mollusques",
+    "565" => "Paléozoologie systématique : autres invertébrés",
+    "566" => "Paléozoologie systématique : vertébrés",
+    "567" => "Paléozoologie systématique : vertébrés à sang froid, 
poissons fossiles",
+    "567.9" => "Reptiles",
+    "567.91" => "Dinosaures",
+    "568" => "Paléozoologie systématique : oiseaux fossiles",
+    "569" => "Mammifères fossiles",
+    "569.9" => "Hominiens",
+    "57" => "Sciences de la vie, Biologie",
+    "570" => "Généralités. Manuels en plusieurs volumes",
+    "571" => "Physiologie générale",
+    "572" => "Biochimie",
+    "573" => "Physiologie animale",
+    "575" => "Physiologie végétale",
+    "576" => "Génétique. Évolution",
+    "577" => "Écologie",
+    "578" => "Histoire naturelle des organismes",
+    "579" => "Micro-organismes. Champignons. Algues",
+    "58" => "Botanique",
+    "580" => "Généralités",
+    "581" => "Botanique générale",
+    "582" => "Botanique non taxonomique",
+    "583" => "Angiospermes dicotylédones",
+    "584" => "Angiospermes monocotylédones",
+    "585" => "Gymnospermes",
+    "587" => "Cryptogames vasculaires",
+    "588" => "Bryophytes",
+    "59" => "Zoologie",
+    "590" => "Généralités. Manuels en plusieurs volumes",
+    "591" => "Zoologie générale",
+    "592" => "Invertébrés",
+    "593" => "Invertébrés marins et des zones littorales",
+    "594" => "Mollusques. Molluscoïdes",
+    "595" => "Arthropodes",
+    "596" => "Chordés",
+    "597" => "Poissons. Vertébrés à sang froid",
+    "598" => "Oiseaux",
+    "599" => "Mammifères",
+    "599,2" => "Primates",
+    "6" => "Sciences appliquées",
+    "60" => "Généralités",
+    "61" => "Sciences médicales. Médecine",
+    "611" => "Anatomie humaine, Cytologie, Histologie",
+    "611.01" => "Anatomie générale",
+    "611.013" => "Embryologie. Développement du foetus",
+    "611.018" => "Cytologie. Histologie",
+    "611.1" => "Anatomie systématique. Étude des organes",
+    "611.3" => "Organes de l'appareil digestif",
+    "611.34" => "Intestins",
+    "611.347" => "Gros intestin",
+    "611.8" => "Système nerveux. Organes des sens",
+    "612" => "Physiologie humaine",
+    "612.1" => "Sang. Système circulatoire",
+    "612.2" => "Respiration. Système respiratoire",
+    "612.3" => "Alimentation. Digestion. Nutrition",
+    "612.4" => "Sécrétion. Excrétion",
+    "612.6" => "Reproduction. Croissance. Développement",
+    "612.7" => "Fonctions motrices. Organes locomoteurs. Voix. Peau",
+    "612.8" => "Système nerveux. Organes des sens",
+    "613" => "Santé",
+    "613.04" => "Santé des divers groupes de population",
+    "613.1" => "Facteurs dus à l'environnement",
+    "613.2" => "Diététique",
+    "613.8" => "Alcoolisme, usage de stupéfiants, tabagisme",
+    "613.9" => "Hygiène sexuelle et contraception",
+    "614" => "Hygiène publique",
+    "614.5" => "Politique de prévention des épidémies",
+    "614.547" => "Maladies sexuellement transmissibles",
+    "614.599 3" => "Maladies du système immunitaire",
+    "614.599 392" => "Sida",
+    "614.599 94" => "Cancers",
+    "615" => "Thérapeutique, Pharmacologie, Toxicologie",
+    "615.1" => "Pharmacologie",
+    "615.2" => "Médicaments d'origine inorganique",
+    "615.3" => "Médicaments d'origine organique",
+    "615.328" => "Vitamines",
+    "615.329" => "Antibiotiques",
+    "615.36" => "Hormones",
+    "615.39" => "Gammaglobulines",
+    "615.5" => "Thérapeutique",
+    "615.531" => "Allopathie",
+    "615.532" => "Homéopathie",
+    "615.535" => "Naturopathie",
+    "615.542" => "Pédiatrie",
+    "615.547" => "Gériatrie",
+    "615.58" => "Chimiothérapie",
+    "615.7" => "Pharmacodynamique",
+    "615.8" => "Thérapies particulières",
+    "615.9" => "Toxicologie générale",
+    "616" => "Pathologie, Médecine clinique",
+    "616.071" => "Étiologie",
+    "616.1" => "Pathologie spéciale",
+    "616.9" => "Maladies infectieuses",
+    "62" => "Génie et activités connexes",
+    "620" => "Généralités",
+    "620.004" => "Conception, essais, mesures, qualité, maintenance, 
entretien",
+    "620.004 6" => "Maintenance, entretien",
+    "620.1" => "Mécanique et matériaux",
+    "620.11" => "Matériaux",
+    "620.112" => "Résistance des matériaux",
+    "620.116" => "Mécanique appliquée aux divers types de matériaux",
+    "620.118" => "Mécanique appliquée aux Matériaux composites",
+    "620.16" => "Mécanique appliquée aux divers types de métaux",
+    "620.192" => "Polymères",
+    "620.2" => "Acoustique appliquée",
+    "620.23" => "Bruit et lutte contre le bruit",
+    "620.3" => "Vibrations mécaniques",
+    "620.37" => "Effets des vibrations. Lutte contre les vibrations",
+    "620.4" => "Technologie de types particuliers",
+    "620.43" => "Technologie des particules fines",
+    "620.44" => "Technologie de surface",
+    "620.46" => "Télécontrôle",
+    "621" => "Ingénierie et physique appliquée, Génie mécanique et civil, 
Électrotechnique",
+    "621.3" => "Électronique. Généralités",
+    "621.31" => "Production, transformation, stockage, distribution de 
l'énergie électrique",
+    "621.312" => "Production, transformation, stockage de l'énergie 
électrique",
+    "621.319" => "Distribution de l'énergie électrique",
+    "621.319 2" => "Circuits électriques",
+    "621.319 3" => "Composants et équipements électriques",
+    "621.34" => "Électromagnétisme. Electroaimants",
+    "621.366" => "Laser",
+    "621.367" => "Photo-optique. Traitement de l'image. Traitement des 
données optiques",
+    "621.369 2" => "Fibre optique",
+    "621.37" => "Tests et mesures électriques",
+    "621.38" => "Électronique. Technologie des communications",
+    "621.381 3" => "Électronique des micro-ondes",
+    "621.381 31" => "Propagation et transmission",
+    "621.381 5" => "Composants et circuits électroniques",
+    "621.381 51" => "Tubes à électrons",
+    "621.381 52" => "Semi-conducteurs : diodes, transistors",
+    "621.381 53" => "Circuits imprimés",
+    "621.381 532" => "Convertisseurs, filtres",
+    "621.381 533" => "Oscillateurs",
+    "621.381 534" => "Amplificateurs",
+    "621.381 536" => "Modems",
+    "621.382" => "Télécommunications. Téléphonie. Radiocommunication. 
Télévision. Vidéo",
+    "621.382 1" => "Réseaux de communication",
+    "621.382 2" => "Théorie de l'information. Traitement du signal",
+    "621.382 23" => "Analyse et théorie du signal",
+    "621.382 24" => "Bruit et interférence",
+    "621.382 4" => "Antennes",
+    "621.382 7" => "Communications optiques (laser)",
+    "621.382 75" => "Communications par fibres optiques",
+    "621.384" => "Radiocommunication",
+    "621.384 11" => "Propagation et transmission des ondes. Interférences",
+    "621.384 5" => "Radiotéléphonie",
+    "621.384 56" => "Téléphones cellulaires",
+    "621.384 8" => "Radar",
+    "621.385" => "Téléphonie",
+    "621.388" => "Ingéniérie de la télévision",
+    "621.388 1" => "Propagation et transmission des ondes",
+    "621.388 33" => "Vidéo : technologie, enregistrement",
+    "621.389" => "Enregistrement du son",
+    "621.395" => "Circuits logiques informatiques (VLSI)",
+    "621.397" => "Stockage des données",
+    "621.397 3" => "Mémoires internes",
+    "621.397 32" => "Mémoires à semi-conducteurs",
+    "621.397 6" => "Mémoires externes",
+    "621.398" => "Matériels d'interfaces et de communication. 
Périphériques",
+    "621.48" => "Ingénierie nucléaire",
+    "621.483" => "centrales nucléaires",
+    "621.8" => "Conversion et transmission de l'énergie mécanique",
+    "624" => "Génie civil",
+    "624.17" => "Analyse et conception des structures",
+    "628.5" => "Lutte contre les nuisances industrielles",
+    "629" => "Autres branches de la technologie",
+    "629.11" => "Technologie du transport aérien",
+    "629.2" => "Technologie des véhicules motorisés. Automobiles",
+    "629.8" => "Automatique",
+    "629.801" => "Principes. Conception logique",
+    "629.82" => "Systèmes à boucle ouverte",
+    "629.83" => "Systèmes à boucle fermée (feed-back)",
+    "629.831 2" => "Théorie de l'automation. Commande optimale. Stabilité. 
Commande robuste",
+    "629.832" => "Systèmes de contrôle et de régulation automatiques 
linéaires",
+    "629.832 3" => "Systèmes asservis. Servosystèmes",
+    "629.836" => "Systèmes de contrôle et de régulation automatiques non 
linéaires",
+    "629.89" => "Commande informatisée",
+    "629.892" => "Robots",
+    "629.895" => "Commande informatisée de processus. Système de commande 
optimale. Système de commande à entrée stochastique",
+    "63" => "Agriculture, Exploitation de la faune et de la flore",
+    "630" => "Généralités",
+    "631" => "Techniques agricoles",
+    "631.4" => "Science du sol. Pédologie",
+    "631.42" => "Fertilité, acidité, alcalinité",
+    "631.8" => "Fertilisants. Amendements du sol",
+    "632" => "Maladies et ennemis des plantes. Pathologie et parasitologie des 
plantes",
+    "632.1" => "Dommages dus à l'environnement",
+    "632.19" => "Pollution",
+    "632.32" => "Maladies bactériennes",
+    "632.4" => "Maladies fongiques",
+    "632.5" => "Plantes nuisibles aux autres plantes",
+    "632.6" => "Animaux nuisibles aux plantes (sauf insectes)",
+    "632.7" => "Insectes nuisibles aux plantes",
+    "632.8" => "Maladies virales",
+    "632.9" => "Lutte contre les maladies et les ennemis des plantes",
+    "633" => "Plantes de culture",
+    "633.1" => "Céréales",
+    "633.3" => "Légumes",
+    "633.5" => "Textiles",
+    "633.6" => "A sucre, à sirop, à fécule",
+    "633.7" => "Alcaloïdes",
+    "633.8" => "A usage industriel. Plantes médicinales",
+    "634" => "Arboriculture. Sylviculture. Vergers, fruits, forêts",
+    "634.9" => "Sylviculture",
+    "635" => "Horticulture",
+    "635.051" => "Plantes à fleurs en général",
+    "635.1" => "Légumes. Potagers",
+    "635.9" => "Plantes ornementales et décoratives",
+    "638" => "Élevage d'insectes : apiculture, sériciculture",
+    "638.1" => "Apiculture",
+    "639" => "Chasse, pêche, aquaculture",
+    "639.3" => "Aquaculture",
+    "64" => "Économie domestique et vie familiale",
+    "65" => "Gestion des entreprises et services connexes",
+    "66" => "Génie chimique et techniques connexes, chimie industrielle",
+    "660" => "Généralités",
+    "660.6" => "Biotechnologies",
+    "660.63" => "Génie biochimique",
+    "660.65" => "Génie génétique",
+    "661" => "Technologie chimique industrielle",
+    "661.03" => "Composés inorganiques",
+    "661.2" => "Acides",
+    "661.3" => "Bases",
+    "661.4" => "Sels",
+    "661.8" => "Chimie organique",
+    "662" => "Technologie des explosifs et des combustibles",
+    "662.62" => "Charbon",
+    "663" => "Industrie des boissons",
+    "664" => "Aliments et conserves",
+    "665" => "Huiles, graisses, cires, gaz industriels",
+    "665.5" => "Technologie du pétrole",
+    "665.7" => "Gaz naturel",
+    "666" => "Verre, céramiques",
+    "667" => "Nettoyage, couleurs, revêtements de surface",
+    "667.2" => "Colorants et pigments",
+    "667.6" => "Peintures",
+    "667.7" => "Vernis, laques",
+    "667.9" => "Revêtements et enduits",
+    "668" => "Autres produits organiques",
+    "668.1" => "Agents tensioactifs",
+    "668.14" => "Détergents et agents mouillants",
+    "668.3" => "Adhésifs",
+    "668.4" => "Matières plastiques",
+    "668.416" => "Plastiques renforcés",
+    "668.42" => "Plastiques polymères",
+    "668.5" => "Parfums et cosmétiques",
+    "668.9" => "Polymères",
+    "669" => "Métallurgie",
+    "67" => "Fabrication industrielle, Industries de transformation",
+    "672" => "Fer, acier, alliages ferreux",
+    "672.3" => "Traitement des fer, acier et alliages ferreux",
+    "673" => "Métaux non ferreux",
+    "676" => "Pâte à papier et papier",
+    "677" => "Textiles",
+    "678" => "Élastomères",
+    "678.2" => "Caoutchouc",
+    "678.7" => "Élastomères synthétiques",
+    "68" => "Industries de produits finis ou assemblés",
+    "69" => "Bâtiments, Construction",
+    "7" => "Arts et loisirs",
+    "70" => "Généralités",
+    "71" => "Urbanisme et aménagement paysager",
+    "711" => "Aménagement du territoire. Urbanisme. Planification régionale 
urbaine et rurale",
+    "712" => "Architecture paysagère. Dessins et aménagements des parcs et 
jardins",
+    "718" => "Cimetières",
+    "719" => "Protection de la nature et des paysages",
+    "72" => "Architecture",
+    "721" => "Programmation. Dessin. Projet",
+    "725" => "Constructions publiques",
+    "726" => "Architecture religieuse",
+    "727" => "Édifices à but éducatifs, scientifiques et culturels",
+    "728" => "Architecture domestique. Habitat",
+    "73" => "Sculpture et autres arts plastiques. Statuaire",
+    "736" => "Glyptique. Sigillographie",
+    "737" => "Numismatique",
+    "738" => "Céramique et poterie d'art",
+    "739" => "Arts des métaux",
+    "74" => "Dessin, arts décoratifs et mineurs",
+    "741" => "Dessin en général",
+    "742" => "Perspective",
+    "743" => "Anatomique",
+    "744" => "Linéaire et technique. Lettrage. Inscriptions",
+    "745" => "Arts décoratifs. Artisanat",
+    "746" => "Travaux d'aiguille. Broderie",
+    "747" => "Décoration intérieure",
+    "748" => "Art du verre",
+    "749" => "Mobilier d'art",
+    "75" => "Peinture (par artiste)",
+    "76" => "Gravure, arts graphiques, estampes",
+    "761" => "Techniques en relief",
+    "762" => "Techniques en creux",
+    "763" => "Techniques à plat. Lithographie",
+    "766" => "Arts graphiques appliqués. Publicité",
+    "77" => "Photographie et photographies",
+    "771" => "Équipement photographique",
+    "772" => "Substances inorganiques et phénomènes physiques",
+    "773" => "Substances organiques",
+    "774" => "Procédés photomécaniques",
+    "776" => "Photolithographie",
+    "777" => "Photogravure",
+    "778" => "Applications de la photographie. Reprographie. Cinéma",
+    "78" => "Musique",
+    "781" => "Théorie musicale",
+    "782" => "Dramatique. Opéra",
+    "783" => "Sacrée",
+    "784" => "Vocale",
+    "785" => "Instrumentale",
+    "786" => "Pour instruments à clavier",
+    "787" => "Pour instruments à cordes",
+    "788" => "Pour instruments à vent",
+    "789" => "Pour instruments à percussion",
+    "79" => "Art du spectacle, loisirs et sports, jeux",
+    "791" => "Divertissements publics et spectacles. Cinéma",
+    "792" => "Arts de la scène",
+    "793" => "Danse. Jeux de société",
+    "794" => "Jeux de table, de réflexion et de hasard",
+    "796" => "Sports",
+    "797" => "Sports aquatiques et aériens",
+    "798" => "Équitation",
+    "799" => "Pêche et chasse sportives. Tir sportif",
+    "8" => "Littérature, rhétorique et art d'écrire",
+    "80" => "Généralités",
+    "801" => "Linguistique générale",
+    "802" => "Anglais",
+    "803" => "Langues germaniques",
+    "804" => "Français",
+    "805" => "Italien. Roumain. Romanche, rhétique",
+    "806" => "Langues ibériques",
+    "807" => "Langues classiques (latin, grec)",
+    "808" => "Langues slaves et baltes",
+    "809" => "Langues orientales, africaines et autres langues",
+    "81" => "Littérature américaine de langue anglaise",
+    "82" => "Autres littératures de langue anglaise",
+    "83" => "Littérature germanique",
+    "839" => "De langue néerlandaise et scandinaves",
+    "84" => "Littérature de langue française",
+    "849" => "Littérature provençale",
+    "85" => "Littérature des langues italienne, roumaine et rhéto-romane",
+    "859" => "Littérature roumaine et de langues romanes orientales",
+    "86" => "Littératures des langues espagnole et portugaise",
+    "869" => "Littérature de langue portugaise",
+    "87" => "Littérature latine",
+    "871" => "Classique",
+    "873" => "Médiévale",
+    "875" => "Grecque classique",
+    "877" => "Littérature byzantine",
+    "88" => "Littérature des langues helléniques. Littérature grecque 
classique",
+    "881" => "Littérature slave",
+    "882" => "Littérature russe",
+    "884" => "Littérature polonaise",
+    "885" => "Littérature tchèque et slovaque",
+    "886" => "Littérature des langues balkaniques",
+    "888" => "Littérature des langues baltes",
+    "89" => "Littératures des autres langues",
+    "891" => "Littératures indiennes, perses, celtiques",
+    "892" => "Littératures des langues sémitiques",
+    "893" => "Littératures des langues hamitiques",
+    "894" => "Littératures des langues ouralo-altaïques, caucasiennes, inuit 
et dravidiennes",
+    "895" => "Littératures d'Extrême-Orient et d'Asie du Sud-Est",
+    "896" => "Littératures des langues africaines",
+    "897" => "Littératures des langues amérindiennes du Nord",
+    "898" => "Littératures des langues amérindiennes du Sud",
+    "899" => "Littératures des langues austronésiennes et australasiennes, 
malayo-polynésiennes",
+    "9" => "Archéologie, Histoire et Géographie",
+    "90" => "Généralités",
+    "902" => "Archéologie",
+    "903" => "Préhistoire",
+    "904" => "Antiquités, vestiges culturels",
+    "908" => "Monographies locales et régionales",
+    "91" => "Géographie",
+    "911" => "générale et théorique",
+    "912" => "Cartes et plans",
+    "913" => "Régionale",
+    "914" => "De l'Europe",
+    "915" => "De l'Asie",
+    "916" => "De l'Afrique",
+    "917" => "De l'Amérique du Nord et centrale",
+    "918" => "De l'Amérique du Sud",
+    "919" => "De l'Océanie et des régions polaires",
+    "92" => "Biographies générales, généalogie, emblèmes",
+    "929" => "Biographie",
+    "929.5" => "Généalogie",
+    "929.6" => "Héraldique",
+    "93" => "Histoire générale du monde ancien (I-V° siècle)",
+    "931" => "Histoire ancienne",
+    "932" => "Égypte ancienne",
+    "933" => "Histoire juive",
+    "934" => "Inde ancienne",
+    "935" => "Orient ancien",
+    "936" => "Europe ancienne (Germains, Celtes, Scandinaves, etc.)",
+    "937" => "Rome ancienne",
+    "938" => "Grèce ancienne",
+    "939" => "Histoire ancienne, autres parties du monde",
+    "94" => "Histoire générale de l'Europe, Europe de l'Ouest",
+    "941" => "des îles britanniques, sauf l'Angleterre",
+    "942" => "de l'Angleterre",
+    "943" => "des pays germaniques et de l'empire austro-hongrois",
+    "944" => "de la France",
+    "945" => "de l'Italie",
+    "946" => "de la péninsule ibérique",
+    "947" => "de l'ex-URSS",
+    "948" => "des pays nordiques",
+    "949" => "de Islande, Pays-Bas, Belgique, Suisse, Grèce, pays 
balkaniques",
+    "95" => "Histoire générale de l'Asie, Extrême Orient",
+    "951" => "de la Chine, de la Corée et de la Mongolie",
+    "952" => "du Japon et de Taïwan",
+    "953" => "des États arabes",
+    "954" => "du sous-continent indien",
+    "955" => "de l'Iran",
+    "956" => "de la Turquie et du Moyen-Orient",
+    "957" => "de l'ex-URSS asiatique",
+    "958" => "de l'Afghanistan",
+    "959" => "de l'Asie du Sud-Est",
+    "96" => "Histoire générale de l'Afrique",
+    "961" => "de la Tunisie et de la Lybie",
+    "962" => "de l'Égypte et du Soudan",
+    "963" => "de l'Éthiopie",
+    "964" => "du Maroc",
+    "965" => "de l'Algérie",
+    "966" => "de l'Afrique occidentale sub-saharienne",
+    "967" => "de l'Afrique équatoriale et centrale",
+    "968" => "de l'Afrique méridionale",
+    "969" => "des îles africaines",
+    "97" => "Histoire générale de l'Amérique du Nord et centrale",
+    "971" => "du Canada",
+    "972" => "du Mexique, de l'Amérique centrale et des Caraïbes",
+    "973" => "des États-Unis d'Amérique",
+    "98" => "Histoire générale de l'Amérique du Sud",
+    "981" => "du Brésil",
+    "982" => "de l'Argentine",
+    "983" => "du Chili",
+    "984" => "de la Bolivie",
+    "985" => "du Pérou",
+    "986" => "de la Colombie et de l'Équateur",
+    "987" => "du Vénézuela",
+    "988" => "des Guyanes",
+    "989" => "du Paraguay et de l'Uruguay",
+    "99" => "Histoire générale des autres parties du monde",
+    "991" => "de l'archipel malais",
+    "992" => "de Sumatra, Java et Bali",
+    "993" => "de l'Australasie et de la Mélanasie",
+    "994" => "de l'Australie",
+    "995" => "de la Nouvelle-Guinée",
+    "996" => "de la Polynésie et Micronésie",
+    "998" => "de l'Arctique",
+    "999" => "de l'Antarctique",
+}
+;
+}
\ No newline at end of file

Index: notifyMailsOp.pl
===================================================================
RCS file: notifyMailsOp.pl
diff -N notifyMailsOp.pl
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ notifyMailsOp.pl    9 Mar 2007 15:44:20 -0000       1.2
@@ -0,0 +1,212 @@
+use strict;
+use C4::Context;
+use C4::Date;
+use Mail::Sendmail;  # comment out if not doing e-mail notices
+use Getopt::Long;
+use C4::Circulation::Circ2;
+# use C4::Members;
+#  this module will notify only the mail case
+# Now it's only programmed for ouest provence, you can modify it for yourself
+# sub function for get all notifications are not sends
+sub GetNotifys {
+#      my($branch) = @_;
+       my $dbh = C4::Context->dbh;
+       my $sth=$dbh->prepare("SELECT DISTINCT notifys.borrowernumber , 
borrowers.surname , borrowers.firstname , borrowers.title AS borrower_title , 
categories.category_type AS categorycode , borrowers.email , 
borrowers.contacttitle , borrowers.contactname , borrowers.contactfirstname ,
+       notifys.notify_level , notifys.method
+       FROM notifys,borrowers,categories WHERE 
(notifys.borrowernumber=borrowers.borrowernumber) AND (notifys.notify_send_date 
IS NULL) AND (borrowers.categorycode = categories.categorycode)");
+       
+       $sth->execute();
+               my @getnotifys;
+               my $i=0;
+               while (my $data=$sth->fetchrow_hashref){
+                       $getnotifys[$i]=$data;
+                       $i++;   
+               }
+               $sth->finish;
+               return(@getnotifys);
+
+}
+
+sub GetBorrowerNotifys{
+       my ($borrowernumber) = @_;
+       my $dbh = C4::Context->dbh;
+       my @getnotifys2;
+       my $sth2=$dbh->prepare("SELECT 
notifys.itemnumber,notifys.notify_level,biblio.title ,itemtypes.description,
+                       issues.date_due
+                       FROM notifys,biblio,items,itemtypes,biblioitems,issues 
+                       WHERE
+                       (items.itemnumber=notifys.itemnumber
+                       AND biblio.biblionumber=items.biblionumber)
+                       AND (itemtypes.itemtype=biblioitems.itemtype AND 
biblioitems.biblionumber=biblio.biblionumber)
+                       AND
+                       (notifys.borrowernumber=issues.borrowernumber AND 
notifys.itemnumber=issues.itemnumber)
+                       AND
+                       issues.returndate IS NULL
+                       AND
+                       notifys.borrowernumber=?
+                       AND notify_send_date IS NULL");
+                       $sth2->execute($borrowernumber);
+                       my $j=0;
+                       while (my $data2=$sth2->fetchrow_hashref){
+                               $getnotifys2[$j]=$data2;
+                               $j++;
+                       }
+                       $sth2->finish;
+                       return(@getnotifys2);
+
+}
+
+sub GetOverduerules{
+       my($category,$notify_level) = @_;
+       my $dbh = C4::Context->dbh;
+       my $sth=$dbh->prepare("SELECT 
letter".$notify_level.",debarred".$notify_level." FROM overduerules WHERE 
categorycode=?");
+       $sth->execute($category);
+       my (@overduerules)=$sth->fetchrow_array;
+       $sth->finish;
+       return(@overduerules);
+
+}
+
+sub GetLetter{
+
+       my($letterid) = @_;
+       my $dbh = C4::Context->dbh;
+       my $sth=$dbh->prepare("SELECT title,content FROM letter WHERE code=?");
+       $sth->execute($letterid);
+       my (@getletter)=$sth->fetchrow_array;
+       $sth->finish;
+       return(@getletter);
+
+}
+
+sub UpdateBorrowerDebarred{
+       my($borrowernumber) = @_;
+       my $dbh = C4::Context->dbh;
+       my $sth=$dbh->prepare("UPDATE borrowers SET debarred='1' WHERE 
borrowernumber=?");
+       $sth->execute($borrowernumber);
+       $sth->finish;
+       return 1;
+}
+
+sub UpdateNotifySendDate{
+       my($borrowernumber,$itemnumber,$notifyLevel) = @_;
+       my $dbh = C4::Context->dbh;
+       my $sth=$dbh->prepare("UPDATE notifys SET notify_send_date=now() 
+       WHERE borrowernumber=? AND itemnumber=? AND notify_send_date IS NULL 
AND notify_level=?");
+       $sth->execute($borrowernumber,$itemnumber,$notifyLevel);
+       $sth->finish;
+       return 1;
+
+}
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
# # # # # # # # # # # # 
+
+# work with get notifys
+my $smtpserver = 'smtp.yoursmtpserver'; # your smtp server (the server who 
sent mails)
+my $from = 'address@hidden'; # all the mails sent to the borrowers will appear 
coming from here.
+
+
+# initiate file for wrong_mails
+my $outfile = 'wrong_mails.txt';
+open( OUT, ">$outfile" );
+binmode(OUT, 'utf8');
+
+my @getnofifys = GetNotifys();
+foreach my $num (@getnofifys) {
+       my %notify;     
+#      if we have a method mail, we check witch mail letter we launch
+       if ($num->{'method'} eq 'mail'){
+               my ($letterid,$debarred) = 
GetOverduerules($num->{'categorycode'},$num->{'notify_level'});
+#                      now, we get the letter associated to letterid
+                       my($title,$content) = GetLetter($letterid);
+                       my $email = $num->{'email'};
+                       #my $email = 'address@hidden';
+                       my $mailtitle = $title; # the title of the mails
+# Work with the adult category code
+                               if ($num->{'categorycode'} eq 'A') {
+       #                       now deal with $content
+                                       $content =~ 
s/\<<borrowers.title>\>/$num->{'borrower_title'}/g ;
+                                       $content =~ 
s/\<<borrowers.surname>\>/$num->{'surname'}/g ;
+                                       $content =~ 
s/\<<borrowers.firstname>\>/$num->{'firstname'}/g ;
+                                       
+                                       my 
@getborrowernotify=GetBorrowerNotifys($num->{'borrowernumber'});
+                                       my $overdueitems;
+                                       foreach my $notif(@getborrowernotify){
+                                               my 
$date=format_date($notif->{'date_due'});
+                                               if ($notif->{'notify_level'} eq 
$num->{'notify_level'}){
+                                               $overdueitems .= " - 
<b>".$notif->{'title'}."</b>" ;
+                                               $overdueitems .= "  ( 
".$notif->{'description'}." )  " ;
+                                               $overdueitems .= "emprunté le 
:".$date;
+                                               $overdueitems .= "<br>";
+                                               
+# FIXME at this time, the program consider the mail is send (in 
notify_send_date) but with no real check must be improved , we don't know if 
the mail was really to a real adress, and if there is a problem, we don't know 
how to return the notification to koha...
+       
UpdateNotifySendDate($num->{'borrowernumber'},$notif->{'itemnumber'},$num->{'notify_level'});
+}
+                                       }
+                               # if we don't have overdueitem replace content 
by nonotifys value, deal with it later
+                                       if ($overdueitems){     
+                                       $content =~ 
s/\<<items.content>\>/$overdueitems/g;
+                               }
+                               else {
+                               $content = 'nonotifys';
+                               }
+                       }
+# Work with the child category code (we add the parents infos)
+                               if ($num->{'categorycode'} eq 'C') {
+                                       $content =~ 
s/\<<borrowers.contacttitle>\>/$num->{'contacttitle'}/g ;
+                                       $content =~ 
s/\<<borrowers.contactname>\>/$num->{'contactname'}/g ;
+                                       $content =~ 
s/\<<borrowers.contactfirstname>\>/$num->{'contactfirstname'}/g ;
+                                       $content =~ 
s/\<<borrowers.title>\>/$num->{'borrower_title'}/g ;
+                                       $content =~ 
s/\<<borrowers.surname>\>/$num->{'surname'}/g ;
+                                       $content =~ 
s/\<<borrowers.firstname>\>/$num->{'firstname'}/g ;
+                                       
+                                       my 
@getborrowernotify=GetBorrowerNotifys($num->{'borrowernumber'});
+                                       my $overdueitems;
+                                       foreach my $notif(@getborrowernotify){
+                                               my 
$date=format_date($notif->{'date_due'});
+                                               
+                                               $overdueitems .= " - 
<b>".$notif->{'title'}."</b>" ;
+                                               $overdueitems .= "  ( 
".$notif->{'description'}." )  " ;
+                                               $overdueitems .= "emprunté le 
:".$date;
+                                               $overdueitems .= "<br>";
+# FIXME at this time, the program consider the mail is send (in 
notify_send_date) but with no real check must be improved ...
+                               
UpdateNotifySendDate($num->{'borrowernumber'},$notif->{'itemnumber'},$num->{'notify_level'});
+                                               }
+                                       
+                                       if ($overdueitems){
+                                               $content =~ 
s/\<<items.content>\>/$overdueitems/g;
+                                       }
+                                       else {
+                                       $content = 'nonotifys';
+                                       }
+                               }
+# initiate the send mail
+
+#       decoding mailtitle for lisibility of mailtitle (bug with utf-8 values, 
so decoding it)
+        utf8::decode($mailtitle);
+
+                       my $mailtext = $content;
+                               unshift @{$Mail::Sendmail::mailcfg{'smtp'}} , 
$smtpserver;
+#                                         set your own mail server name here
+                                       my %mail = ( To      => $email,
+                                                               From    => 
$from,
+                                                               Subject => 
$mailtitle,
+                                                               Message => 
$mailtext,
+                                                               'content-type' 
=> 'text/html; charset="utf-8"',
+                                       );
+                               # if we don't have any content for the mail, we 
don't launch mail, but notify it in a file
+                                       if ($mailtext ne 'nonotifys') {
+                                       sendmail(%mail);
+                                       }
+                                       else {
+                                       print OUT $email ;
+                                       }
+                                       
+# now deal with the debarred mode
+#              if ($debarred eq 1) {
+#              à ajouter : si le lecteur est en mode debarred, ajouter la 
fonction qui nous permettra cela
+#              UpdateBorrowerDebarred($num->{'borrowernumber'});
+#              }
+       close(OUT);
+       }
+}

Index: result.txt
===================================================================
RCS file: result.txt
diff -N result.txt

Index: test_zebra_delete.pl
===================================================================
RCS file: test_zebra_delete.pl
diff -N test_zebra_delete.pl
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ test_zebra_delete.pl        9 Mar 2007 15:44:20 -0000       1.1
@@ -0,0 +1,77 @@
+#!/usr/bin/perl
+use C4::Context;
+use C4::Biblio;
+
+use strict;
+
+my $Zconn=C4::Context->Zconn('biblioserver', 0, 1);
+my $Zpackage = $Zconn->package();
+$Zpackage->option(action => 'recordDelete');
+$Zpackage->option(record => '<?xml version="1.0" encoding="UTF-8"?>
+<record
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+ xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/ 
standards/marcxml/schema/MARC21slim.xsd"
+ xmlns="http://www.loc.gov/MARC21/slim";>
+
+ <leader>00577    a2200193   4500</leader>
+ <controlfield tag="005">19980415162006.0</controlfield>
+ <datafield tag="035" ind1=" " ind2=" ">
+   <subfield code="a">TOB*M*9074254</subfield>
+ </datafield>
+ <datafield tag="090" ind1=" " ind2=" ">
+   <subfield code="9">8</subfield>
+   <subfield code="a">8</subfield>
+ </datafield>
+ <datafield tag="100" ind1=" " ind2=" ">
+   <subfield code="a">19910405d1976       y1frea0103    ba</subfield>
+ </datafield>
+ <datafield tag="101" ind1="0" ind2=" ">
+   <subfield code="a">fre</subfield>
+ </datafield>
+ <datafield tag="200" ind1="1" ind2=" ">
+   <subfield code="a">Lune vole fJacqueline Held, et Claude Held</subfield>
+   <subfield code="g">illustrations d\' Yvan Pommaux</subfield>
+   <subfield code="b">LIVR</subfield>
+ </datafield>
+ <datafield tag="210" ind1=" " ind2=" ">
+   <subfield code="c">Ecole des loisirs</subfield>
+   <subfield code="d">cop. 1976</subfield>
+ </datafield>
+ <datafield tag="215" ind1=" " ind2=" ">
+   <subfield code="a">20p</subfield>
+ </datafield>
+ <datafield tag="225" ind1="0" ind2=" ">
+   <subfield code="a">Chanterime</subfield>
+ </datafield>
+ <datafield tag="309" ind1=" " ind2=" ">
+   <subfield code="a">Migration GEAC</subfield>
+ </datafield>
+ <datafield tag="700" ind1=" " ind2="1">
+   <subfield code="a">Held</subfield>
+   <subfield code="b">Jacqueline</subfield>
+   <subfield code="9">187392</subfield>
+ </datafield>
+ <datafield tag="913" ind1="0" ind2="0">
+   <subfield code="a">HELLVOL99000</subfield>
+ </datafield>
+ <datafield tag="949" ind1=" " ind2=" ">
+   <subfield code="a">MIRMJE</subfield>
+   <subfield code="a">ISTISP</subfield>
+ </datafield>
+ <datafield tag="995" ind1=" " ind2=" ">
+   <subfield code="a">IST</subfield>
+   <subfield code="c">IST</subfield>
+   <subfield code="f">9991088063</subfield>
+   <subfield code="k">P HEL</subfield>
+   <subfield code="m">2004-06-22</subfield>
+   <subfield code="v">2.9</subfield>
+   <subfield code="r">LIVR</subfield>
+   <subfield code="s">14</subfield>
+   <subfield code="b">J</subfield>
+   <subfield code="9">16</subfield>
+ </datafield>
+</record>');
+$Zpackage->send("update");
+$Zpackage->send('commit');
+$Zpackage->destroy();
+$Zconn->destroy();

Index: update_items.pl
===================================================================
RCS file: update_items.pl
diff -N update_items.pl
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ update_items.pl     9 Mar 2007 15:44:20 -0000       1.1
@@ -0,0 +1,183 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use C4::Context;
+use C4::Biblio;
+use MARC::Record;
+
+use Getopt::Long;
+my $USAGE = "
+USAGE: update_items.pl -[options]
+
+OPTIONS:
+ -today                                Items with a modified timestamp today
+ -biblionumber <integer>       One biblionumber to update
+ -itemnumber <integer>         One itemnumber to update
+
+DEVELOPMENT OPTIONS:
+
+EXAMPLES:
+\$ ./update_items.pl -today
+[ update items modified today ]
+
+\$ ./update_items.pl -biblionumber 2
+[ update items for biblionumber 2 ]
+";
+my ($today_only,$biblionumber_to_update,$itemnumber_to_update,$help);
+GetOptions(
+       'today' => \$today_only,
+       'biblionumber:o' => \$biblionumber_to_update,
+       'itemnumber:o' => \$itemnumber_to_update,
+       'h' => \$help,
+);
+
+if ($h) {
+    print $USAGE."\n";
+    exit;
+}
+
+# This script can be run from cron or on the command line. It updates
+# a zebra index with modifications for the period covered or the 
+# biblionumber or itemnumber specified.
+#
+# You will need to customize this for your installation
+# I hope that the comments will help -- Josha Ferraro <address@hidden>
+my $dbh = C4::Context->dbh;
+
+# Get the date, used both for filename and for period we're updating
+my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
+$year +=1900;
+$mon +=1;
+# nice to zero-pad these dates
+my $pad_mday= sprintf("%0*d", "2",$mday);
+my $pad_mon = sprintf("%0*d", "2",$mon);
+
+# FIXME: we should define a syspref for 'how often to run this script'
+my $period = "$year-$pad_mon-$pad_mday%"; # today only - you'll want to 
customize this bit
+print "period: $period\n";
+my $date = "$year$mon$mday$hour$min$sec";
+
+# This is the file that zebra will use to update the index at the end of this 
script
+my $filename = "records.$date.iso2709";
+my $biblioserverdir = C4::Context->zebraconfig('biblioserver')->{directory};
+
+# check that directory exist, otherwise create.
+unless (-d "$biblioserverdir/specialUpdate") {
+    system("mkdir -p $biblioserverdir/specialUpdate");
+    print "Info: created $biblioserverdir/specialUpdate\n";
+    $created_dir_or_file++;
+}
+
+my $outfile = "$biblioserverdir/specialUpdate/$filename";
+
+# open a filehandle for writing records -- notice it's UTF-8
+open OUT,">utf8",$outfile or die "can't open filehandle\n";
+
+# if there aren't any changes, and all we're doing is updating things from 
today, don't bother
+print "counting first\n";
+my $countitems_sth = $dbh->prepare("SELECT COUNT(*) FROM items WHERE timestamp 
LIKE ?");
+$countitems_sth->execute($period);
+my $number_of_items = $countitems_sth->fetchrow();
+unless ($number_of_items) {
+       print "no recent items to update\n";
+       exit if $today_only;
+}
+
+# get all the relevant biblionumbers, we're gonna update every item in these 
biblionumbers
+print "finding biblionumbers\n";
+my $biblionumber_sth;
+if ($today_only) {
+       $biblionumber_sth = $dbh->prepare("SELECT DISTINCT 
biblioitems.biblionumber FROM biblioitems LEFT JOIN items ON 
(biblioitems.biblionumber=items.biblionumber) WHERE items.timestamp LIKE ? AND 
biblioitems.marcxml IS NOT NULL");
+       $biblionumber_sth->execute($period) or die "problem with query\n";
+}
+elsif ($biblionumber_to_update) {
+       $biblionumber_sth = $dbh->prepare("SELECT biblionumber FROM biblioitems 
WHERE marcxml IS NOT NULL AND biblionumber=?");
+       $biblionumber_sth->execute($biblionumber_to_update) or die "problem 
with query\n";
+}
+my $count;
+
+print "fetching marc and items data, updating\n";
+# for each itemnumber, find the biblionumber, get all the items data for that 
biblio,
+# update all the items data in biblioitems.marc, and finally, index it in zebra
+
+#
+# 1st : find where some informations are hidden : itemnumber, date_due, 
popularity
+#
+my ($itemnumberTag,$itemnumberSubfield) = 
MARCfind_marc_from_kohafield($dbh,"items.itemnumber","");
+my ($date_dueTag,$date_dueSubfield) = 
MARCfind_marc_from_kohafield($dbh,"items.issues","");
+my (
+while (my $biblionumber=$biblionumber_sth->fetchrow) {
+       $count++;
+
+       # get this biblio's MARC record
+    my $record = MARCgetbiblio($biblionumber);
+
+       # delete all existing items data from this record FIXME: 952 shouldn't 
be hardcoded
+       for my $field_to_del ($record->field("952")) {
+               my $del_count = $record->delete_field($field_to_del);
+               print "deleted $del_count fields";
+       }
+       # Find out the itemnumbers this biblio has
+       my $itemnumbers_sth = $dbh->prepare("SELECT itemnumber FROM items WHERE 
biblionumber=?");
+       $itemnumbers_sth->execute($biblionumber);
+       
+       # for each of the items, get all the item data
+       while (my $data = $itemnumbers_sth->fetchrow_hashref) {
+               my $itemnumber = $data->{itemnumber};
+               my $item_data_sth = $dbh->prepare("SELECT * FROM items WHERE 
itemnumber=?");
+               $item_data_sth->execute($data->{itemnumber});
+               my $item_data_hashref = $item_data_sth->fetchrow_hashref();
+               
+               # create a new MARC::Field object and put a date_due in it 
(from issues table)
+               my $date_due_sth = $dbh->prepare("SELECT date_due FROM issues 
WHERE itemnumber=? AND returndate IS NULL");
+               $date_due_sth->execute($itemnumber);
+               my ($date_due) = $date_due_sth->fetchrow();
+               $date_due = "0000-00-00" unless ($date_due);
+
+               # FIXME: this should use Frameworks!!! -- I'll do it soon -- JF
+               my $items_field = MARC::Field->new( 952, " ", " ", "2" => 
$date_due, );
+
+               # put all the data into our MARC::Record field, based on the 
Koha2MARC mappings
+               for my $label (keys %$item_data_hashref) {
+                       if ($item_data_hashref->{$label}) {
+                               my $find_tag_subfield_sth = 
$dbh->prepare("SELECT tagfield,tagsubfield FROM marc_subfield_structure WHERE 
kohafield=?");
+                               $find_tag_subfield_sth->execute("items.$label");
+                               my ($tag,$subfield) = 
$find_tag_subfield_sth->fetchrow;
+                               if ($tag) {
+                                       $items_field->add_subfields($subfield 
=> $item_data_hashref->{$label} ) unless (!$item_data_hashref->{$label});
+                                       print "added: $label ($tag $subfield): 
$item_data_hashref->{$label}";
+                               }
+                               else {
+                                       # You probably want to update your 
mappings if you see anything here ... but
+                                       # in some cases it's safe to ignore 
these warnings
+                                       print "WARN: no items.$label mapping 
found: $item_data_hashref->{$label}\n";
+                               }
+                       }
+               }
+               # now update our original record, appending this field
+               $record->insert_fields_ordered($items_field);
+       }
+       # at this point, we have an up-to-date MARC record
+       # put it back in biblioitems.marc
+       my $put_back_sth = $dbh->prepare("UPDATE biblioitems SET marc=? WHERE 
biblionumber=?");
+       $put_back_sth->execute($record->as_usmarc(),$biblionumber);
+
+       # schedule it for a zebra index update FIXME: we need better error 
handling
+       print OUT $record->as_usmarc(); 
+}
+# FIXME: add time taken
+print "finished with $count items in\n";
+# now we're ready to index this change in Zebra and commit it
+# FIXME: these dirs shouldn't be hardcoded and sudo probably isn't what you use
+chdir "/koha/zebradb/biblios/tab";
+my $error = system("sudo zebraidx -g iso2709 -c /koha/etc/zebra-biblios.cfg -d 
biblios update $outfile");
+if ($error) {
+       die "update operation failed";
+}
+$error = system("sudo zebraidx -g iso2709 -c /koha/etc/zebra-biblios.cfg 
commit");
+
+if ($error) {
+       die "commit operation failed";
+}
+
+`sudo mv $outfile $outfile.finished`;

Index: zebraqueue_start.pl
===================================================================
RCS file: zebraqueue_start.pl
diff -N zebraqueue_start.pl
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ zebraqueue_start.pl 9 Mar 2007 15:44:20 -0000       1.2
@@ -0,0 +1,153 @@
+#!/usr/bin/perl
+# script that starts the zebraquee
+#  Written by TG on 01/08/2006
+use strict;
+
+
+use C4::Context;
+use C4::Biblio;
+use C4::Search;
+use C4::AuthoritiesMarc;
+use XML::Simple;
+use utf8;
+### ZEBRA SERVER UPDATER
+##Uses its own database handle
+my $dbh=C4::Context->dbh;
+my $readsth=$dbh->prepare("select id,biblio_auth_number,operation,server from 
zebraqueue");
+#my $delsth=$dbh->prepare("delete from zebraqueue where id =?");
+
+
+#AGAIN:
+
+#my $wait=C4::Context->preference('zebrawait') || 120;
+my $verbose = 1;
+print "starting with verbose=$verbose\n" if $verbose;
+
+my ($id,$biblionumber,$operation,$server,$marcxml);
+
+$readsth->execute;
+while (($id,$biblionumber,$operation,$server)=$readsth->fetchrow){
+    print "read in queue : $id : biblio $biblionumber for $operation on 
$server\n" if $verbose;
+    my $ok;
+    eval{
+        # if the operation is a deletion, zebra requires that we give it the 
xml.
+        # as it is no more in the SQL db, retrieve it from zebra itself.
+        # may sound silly, but that's the way zebra works ;-)
+           if ($operation =~ /delete/) {
+              # 1st read the record in zebra
+            my $Zconn=C4::Context->Zconn($server, 0, 1,'','xml');
+            my $query = $Zconn->search_pqf( '@attr 1=Local-Number 
'.$biblionumber);
+            # then, delete the record
+               
$ok=zebrado($query->record(0)->render(),$operation,$server,$biblionumber);
+        # if it's an add or a modif
+        } else {
+            # get the XML
+            if ($server eq "biblioserver") {
+                my $marc = GetMarcBiblio($biblionumber);
+                $marcxml = $marc->as_xml_record() if $marc;
+            } elsif ($server eq "authorityserver") {
+                $marcxml 
=C4::AuthoritiesMarc::XMLgetauthority($dbh,$biblionumber);
+            }
+            if ($verbose) {
+                if ($marcxml) {
+                    print "XML read : $marcxml\n" if $verbose >1;
+                } else {
+                # workaround for zebra bug needing a XML even for deletion
+                $marcxml= "<dummy/>";
+                    print "unable to read MARCxml\n" if $verbose;
+                }
+            }
+            # check it's XML, just in case
+            eval {
+                my $hashed=XMLin($marcxml);
+            }; ### is it a proper xml? broken xml may crash ZEBRA- slow but 
safe
+            ## it's Broken XML-- Should not reach here-- but if it does -lets 
protect ZEBRA
+            if ($@){
+                warn $@;
+                my $delsth=$dbh->prepare("delete from zebraqueue where id =?");
+                $delsth->execute($id);
+                next;
+            }
+            # ok, we have everything, do the operation in zebra !
+            $ok=zebrado($marcxml,$operation,$server);
+        }
+    };
+    print "ZEBRAopserver returned : $ok \n" if $verbose;
+    if ($ok ==1) {
+        $dbh=C4::Context->dbh;
+        my $delsth;
+        # if it's a deletion, we can delete every request on this biblio : in 
case the user
+        # did a modif (or item deletion) just before biblio deletion, there 
are some specialUpdage
+        # that are pending and can't succeed, as we don't have the XML anymore
+        # so, delete everything for this biblionumber
+        if ($operation eq 'delete_record') {
+            print "deleting biblio deletion $biblionumber\n" if $verbose;
+            $delsth =$dbh->prepare("delete from zebraqueue where 
biblio_auth_number =?");
+            $delsth->execute($biblionumber);
+        # if it's not a deletion, delete every pending specialUpdate for this 
biblionumber
+        # in case the user add biblio, then X items, before this script runs
+        # this avoid indexing X+1 times where just 1 is enough.
+        } else {
+            print "deleting special date for $biblionumber\n" if $verbose;
+            $delsth =$dbh->prepare("delete from zebraqueue where 
biblio_auth_number =? and operation='specialUpdate'");
+            $delsth->execute($biblionumber);
+        }
+    }
+}
+
+sub zebrado {
+    
+    ###Accepts a $server variable thus we can use it to update  biblios, 
authorities or other zebra dbs
+    my ($record,$op,$server,$biblionumber)address@hidden;
+    
+    my @port;
+    
+    my $tried=0;
+    my $recon=0;
+    my $reconnect=0;
+#    $record=Encode::encode("UTF-8",$record);
+    my $shadow=$server."shadow";
+    $op = 'recordDelete' if $op eq 'delete_record';
+reconnect:
+    
+    my $Zconn=C4::Context->Zconn($server, 0, 1);
+    if ($record){
+        print "updating $op on $biblionumber for server $server\n $record\n" 
if $verbose;
+        my $Zpackage = $Zconn->package();
+        $Zpackage->option(action => $op);
+        $Zpackage->option(record => $record);
+#          $Zpackage->option(recordIdOpaque => $biblionumber) if $biblionumber;
+retry:
+        $Zpackage->send("update");
+        my($error, $errmsg, $addinfo, $diagset) = $Zconn->error_x();
+        if ($error==10007 && $tried<3) {## timeout --another 30 looonng 
seconds for this update
+            print "error 10007\n" if $verbose;
+            sleep 1;   ##  wait a sec!
+            $tried=$tried+1;
+            goto "retry";
+        }elsif ($error==2 && $tried<2) {## timeout --temporary zebra error 
!whatever that means
+            print "error 2\n" if $verbose;
+            sleep 2;   ##  wait two seconds!
+            $tried=$tried+1;
+            goto "retry";
+        }elsif($error==10004 && $recon==0){##Lost connection -reconnect
+            print "error 10004\n" if $verbose;
+            sleep 1;   ##  wait a sec!
+            $recon=1;
+            $Zpackage->destroy();
+            $Zconn->destroy();
+            goto "reconnect";
+        }elsif ($error){
+        #      warn "Error-$server   $op  /errcode:, $error, 
/MSG:,$errmsg,$addinfo \n";       
+            print "error $error\n" if $verbose;
+            $Zpackage->destroy();
+            $Zconn->destroy();
+            return 0;
+        }
+        $Zpackage->send('commit');
+#     $Zpackage->destroy();
+#     $Zconn->destroy();
+    return 1;
+    }
+    return 0;
+}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]