6 use C4::AuthoritiesMarc;
10 # script that checks zebradir structure & create directories & mandatory files if needed
14 $|=1; # flushes output
16 # limit for database dumping
17 my $limit;# = "LIMIT 1";
35 $directory = "export" unless $directory;
38 my $biblioserverdir = C4::Context->zebraconfig('biblioserver')->{directory};
39 my $authorityserverdir = C4::Context->zebraconfig('authorityserver')->{directory};
41 my $kohadir = C4::Context->config('intranetdir');
42 my $dbh = C4::Context->dbh;
43 my ($biblionumbertagfield,$biblionumbertagsubfield) = &GetMarcFromKohaField("biblio.biblionumber","");
44 my ($biblioitemnumbertagfield,$biblioitemnumbertagsubfield) = &GetMarcFromKohaField("biblioitems.biblioitemnumber","");
46 print "some informations\n";
47 print "=================\n";
48 print "Zebra biblio directory =>$biblioserverdir\n";
49 print "Zebra authorities directory =>$authorityserverdir\n";
50 print "Koha directory =>$kohadir\n";
51 print "BIBLIONUMBER in : $biblionumbertagfield\$$biblionumbertagsubfield\n";
52 print "BIBLIOITEMNUMBER in : $biblioitemnumbertagfield\$$biblioitemnumbertagsubfield\n";
53 print "=================\n";
55 # creating zebra-biblios.cfg depending on system
58 # getting zebraidx directory
60 foreach (qw(/usr/local/bin/zebraidx
69 unless ($zebraidxdir) {
71 ERROR: could not find zebraidx directory
72 ERROR: Either zebra is not installed,
73 ERROR: or it's in a directory I don't checked.
74 ERROR: do a which zebraidx and edit this file to add the result you get
78 $zebraidxdir =~ s/\/bin\/.*//;
79 print "Info : zebra is in $zebraidxdir \n";
81 # getting modules directory
83 foreach (qw(/usr/local/lib/idzebra-2.0/modules/mod-grs-xml.so
84 /usr/local/lib/idzebra/modules/mod-grs-xml.so
85 /usr/lib/idzebra/modules/mod-grs-xml.so
86 /usr/lib/idzebra-2.0/modules/mod-grs-xml.so
93 unless ($modulesdir) {
95 ERROR: could not find mod-grs-xml.so directory
96 ERROR: Either zebra is not properly compiled (libxml2 is not setup and you don t have mod-grs-xml.so,
97 ERROR: or it's in a directory I don't checked.
98 ERROR: find where mod-grs-xml.so is and edit this file to add the result you get
102 $modulesdir =~ s/\/modules\/.*//;
103 print "Info: zebra modules dir : $modulesdir\n";
105 # getting tab directory
107 foreach (qw(/usr/local/share/idzebra/tab/explain.att
108 /usr/local/share/idzebra-2.0/tab/explain.att
109 /usr/share/idzebra/tab/explain.att
110 /usr/share/idzebra-2.0/tab/explain.att
119 ERROR: could not find explain.att directory
120 ERROR: Either zebra is not properly compiled,
121 ERROR: or it's in a directory I don't checked.
122 ERROR: find where explain.att is and edit this file to add the result you get
126 $tabdir =~ s/\/tab\/.*//;
127 print "Info: tab dir : $tabdir\n";
130 # AUTHORITIES creating directory structure
132 my $created_dir_or_file = 0;
134 print "====================\n";
135 print "checking directories & files for authorities\n";
136 print "====================\n";
137 unless (-d "$authorityserverdir") {
138 system("mkdir -p $authorityserverdir");
139 print "Info: created $authorityserverdir\n";
140 $created_dir_or_file++;
142 unless (-d "$authorityserverdir/lock") {
143 mkdir "$authorityserverdir/lock";
144 print "Info: created $authorityserverdir/lock\n";
145 $created_dir_or_file++;
147 unless (-d "$authorityserverdir/register") {
148 mkdir "$authorityserverdir/register";
149 print "Info: created $authorityserverdir/register\n";
150 $created_dir_or_file++;
152 unless (-d "$authorityserverdir/shadow") {
153 mkdir "$authorityserverdir/shadow";
154 print "Info: created $authorityserverdir/shadow\n";
155 $created_dir_or_file++;
157 unless (-d "$authorityserverdir/tab") {
158 mkdir "$authorityserverdir/tab";
159 print "Info: created $authorityserverdir/tab\n";
160 $created_dir_or_file++;
162 unless (-d "$authorityserverdir/key") {
163 mkdir "$authorityserverdir/key";
164 print "Info: created $authorityserverdir/key\n";
165 $created_dir_or_file++;
168 unless (-d "$authorityserverdir/etc") {
169 mkdir "$authorityserverdir/etc";
170 print "Info: created $authorityserverdir/etc\n";
171 $created_dir_or_file++;
175 # AUTHORITIES : copying mandatory files
177 # the record model, depending on marc flavour
178 unless (-f "$authorityserverdir/tab/record.abs") {
179 if (C4::Context->preference("marcflavour") eq "UNIMARC") {
180 system("cp -f $kohadir/misc/zebra/record_authorities_unimarc.abs $authorityserverdir/tab/record.abs");
181 print "Info: copied record.abs for UNIMARC\n";
183 system("cp -f $kohadir/misc/zebra/record_authorities_usmarc.abs $authorityserverdir/tab/record.abs");
184 print "Info: copied record.abs for USMARC\n";
186 $created_dir_or_file++;
188 unless (-f "$authorityserverdir/tab/sort-string-utf.chr") {
189 system("cp -f $kohadir/misc/zebra/sort-string-utf_french.chr $authorityserverdir/tab/sort-string-utf.chr");
190 print "Info: copied sort-string-utf.chr\n";
191 $created_dir_or_file++;
193 unless (-f "$authorityserverdir/tab/word-phrase-utf.chr") {
194 system("cp -f $kohadir/misc/zebra/sort-string-utf_french.chr $authorityserverdir/tab/word-phrase-utf.chr");
195 print "Info: copied word-phase-utf.chr\n";
196 $created_dir_or_file++;
198 unless (-f "$authorityserverdir/tab/auth1.att") {
199 system("cp -f $kohadir/misc/zebra/bib1_authorities.att $authorityserverdir/tab/auth1.att");
200 print "Info: copied auth1.att\n";
201 $created_dir_or_file++;
203 unless (-f "$authorityserverdir/tab/default.idx") {
204 system("cp -f $kohadir/misc/zebra/default.idx $authorityserverdir/tab/default.idx");
205 print "Info: copied default.idx\n";
206 $created_dir_or_file++;
209 unless (-f "$authorityserverdir/etc/ccl.properties") {
210 # system("cp -f $kohadir/misc/zebra/ccl.properties ".C4::Context->zebraconfig('authorityserver')->{ccl2rpn});
211 system("cp -f $kohadir/misc/zebra/ccl.properties $authorityserverdir/etc/ccl.properties");
212 print "Info: copied ccl.properties\n";
213 $created_dir_or_file++;
215 unless (-f "$authorityserverdir/etc/pqf.properties") {
216 # system("cp -f $kohadir/misc/zebra/pqf.properties ".C4::Context->zebraconfig('authorityserver')->{ccl2rpn});
217 system("cp -f $kohadir/misc/zebra/pqf.properties $authorityserverdir/etc/pqf.properties");
218 print "Info: copied pqf.properties\n";
219 $created_dir_or_file++;
223 # AUTHORITIES : copying mandatory files
225 unless (-f C4::Context->zebraconfig('authorityserver')->{config}) {
226 open ZD,">:utf8 ",C4::Context->zebraconfig('authorityserver')->{config};
228 # generated by KOHA/misc/migration_tools/rebuild_zebra.pl
229 profilePath:\${srcdir:-.}:$authorityserverdir/tab/:$tabdir/tab/:\${srcdir:-.}/tab/
232 # Files that describe the attribute sets supported.
237 modulePath:$modulesdir/modules/
238 # Specify record type
239 iso2709.recordType:grs.marcxml.record
241 recordId: (auth1,Local-Number)
247 lockDir: $authorityserverdir/lock
252 register: $authorityserverdir/register:4G
253 shadow: $authorityserverdir/shadow:4G
255 # Temp File area for result sets
256 setTmpDir: $authorityserverdir/tmp
258 # Temp File area for index program
259 keyTmpDir: $authorityserverdir/key
261 # Approx. Memory usage during indexing
265 print "Info: creating zebra-authorities.cfg\n";
266 $created_dir_or_file++;
269 if ($created_dir_or_file) {
270 print "Info: created : $created_dir_or_file directories & files\n";
272 print "Info: file & directories OK\n";
276 # exporting authorities
279 print "====================\n";
280 print "SKIPPING authorities export\n";
281 print "====================\n";
283 print "====================\n";
284 print "exporting authorities\n";
285 print "====================\n";
286 mkdir "$directory" unless (-d $directory);
287 mkdir "$directory/authorities" unless (-d "$directory/authorities");
288 open(OUT,">:utf8","$directory/authorities/authorities.iso2709") or die $!;
289 my $dbh=C4::Context->dbh;
291 $sth=$dbh->prepare("select authid,marc from auth_header $limit");
294 while (my ($authid,$record) = $sth->fetchrow) {
295 # FIXME : we retrieve the iso2709 record. if the GetAuthority (that uses the XML) fails
296 # due to some MARC::File::XML failure, then try the iso2709,
297 # (add authid & authtype if needed)
300 $record = GetAuthority($authid);
302 # force authid in case it's not here, otherwise, zebra will die on this authority
303 unless ($record->field('001')){
304 $record->insert_fields_ordered(MARC::Field->new('001',$authid));
307 print " There was some pb getting authority : ".$authid."\n";
312 print "\r$i" unless ($i++ %100);
313 # # remove leader length, that could be wrong, it will be calculated automatically by as_usmarc
314 # # otherwise, if it's wron, zebra will fail miserabily (and never index what is after the failing record)
315 my $leader=$record->leader;
316 substr($leader,0,5)=' ';
317 substr($leader,10,7)='22 ';
318 $record->leader(substr($leader,0,24));
319 print OUT $record->as_usmarc;
325 # and reindexing everything
327 print "====================\n";
328 print "REINDEXING zebra\n";
329 print "====================\n";
330 system("zebraidx -c ".C4::Context->zebraconfig('authorityserver')->{config}." -g iso2709 -d authorities init") if ($reset);
331 system("zebraidx -c ".C4::Context->zebraconfig('authorityserver')->{config}." -g iso2709 -d authorities update $directory/authorities");
332 system("zebraidx -c ".C4::Context->zebraconfig('authorityserver')->{config}." -g iso2709 -d authorities commit");
334 print "skipping authorities\n";
336 #################################################################################################################
338 #################################################################################################################
341 print "====================\n";
342 print "checking directories & files for biblios\n";
343 print "====================\n";
346 # BIBLIOS : creating directory structure
348 unless (-d "$biblioserverdir") {
349 system("mkdir -p $biblioserverdir");
350 print "Info: created $biblioserverdir\n";
351 $created_dir_or_file++;
353 unless (-d "$biblioserverdir/lock") {
354 mkdir "$biblioserverdir/lock";
355 print "Info: created $biblioserverdir/lock\n";
356 $created_dir_or_file++;
358 unless (-d "$biblioserverdir/register") {
359 mkdir "$biblioserverdir/register";
360 print "Info: created $biblioserverdir/register\n";
361 $created_dir_or_file++;
363 unless (-d "$biblioserverdir/shadow") {
364 mkdir "$biblioserverdir/shadow";
365 print "Info: created $biblioserverdir/shadow\n";
366 $created_dir_or_file++;
368 unless (-d "$biblioserverdir/tab") {
369 mkdir "$biblioserverdir/tab";
370 print "Info: created $biblioserverdir/tab\n";
371 $created_dir_or_file++;
373 unless (-d "$biblioserverdir/key") {
374 mkdir "$biblioserverdir/key";
375 print "Info: created $biblioserverdir/key\n";
376 $created_dir_or_file++;
378 unless (-d "$biblioserverdir/etc") {
379 mkdir "$biblioserverdir/etc";
380 print "Info: created $biblioserverdir/etc\n";
381 $created_dir_or_file++;
385 # BIBLIOS : copying mandatory files
387 # the record model, depending on marc flavour
388 unless (-f "$biblioserverdir/tab/record.abs") {
389 if (C4::Context->preference("marcflavour") eq "UNIMARC") {
390 system("cp -f $kohadir/misc/zebra/record_biblios_unimarc.abs $biblioserverdir/tab/record.abs");
391 print "Info: copied record.abs for UNIMARC\n";
393 system("cp -f $kohadir/misc/zebra/record_biblios_usmarc.abs $biblioserverdir/tab/record.abs");
394 print "Info: copied record.abs for USMARC\n";
396 $created_dir_or_file++;
398 unless (-f "$biblioserverdir/tab/sort-string-utf.chr") {
399 system("cp -f $kohadir/misc/zebra/sort-string-utf_french.chr $biblioserverdir/tab/sort-string-utf.chr");
400 print "Info: copied sort-string-utf.chr\n";
401 $created_dir_or_file++;
403 unless (-f "$biblioserverdir/tab/word-phrase-utf.chr") {
404 system("cp -f $kohadir/misc/zebra/sort-string-utf_french.chr $biblioserverdir/tab/word-phrase-utf.chr");
405 print "Info: copied word-phase-utf.chr\n";
406 $created_dir_or_file++;
408 unless (-f "$biblioserverdir/tab/bib1.att") {
409 system("cp -f $kohadir/misc/zebra/bib1_biblios.att $biblioserverdir/tab/bib1.att");
410 print "Info: copied bib1.att\n";
411 $created_dir_or_file++;
413 unless (-f "$biblioserverdir/tab/default.idx") {
414 system("cp -f $kohadir/misc/zebra/default.idx $biblioserverdir/tab/default.idx");
415 print "Info: copied default.idx\n";
416 $created_dir_or_file++;
418 unless (-f "$biblioserverdir/etc/ccl.properties") {
419 # system("cp -f $kohadir/misc/zebra/ccl.properties ".C4::Context->zebraconfig('biblioserver')->{ccl2rpn});
420 system("cp -f $kohadir/misc/zebra/ccl.properties $biblioserverdir/etc/ccl.properties");
421 print "Info: copied ccl.properties\n";
422 $created_dir_or_file++;
424 unless (-f "$biblioserverdir/etc/pqf.properties") {
425 # system("cp -f $kohadir/misc/zebra/pqf.properties ".C4::Context->zebraconfig('biblioserver')->{ccl2rpn});
426 system("cp -f $kohadir/misc/zebra/pqf.properties $biblioserverdir/etc/pqf.properties");
427 print "Info: copied pqf.properties\n";
428 $created_dir_or_file++;
432 # BIBLIOS : copying mandatory files
434 unless (-f C4::Context->zebraconfig('biblioserver')->{config}) {
435 open ZD,">:utf8 ",C4::Context->zebraconfig('biblioserver')->{config};
437 # generated by KOHA/misc/migrtion_tools/rebuild_zebra.pl
438 profilePath:\${srcdir:-.}:$biblioserverdir/tab/:$tabdir/tab/:\${srcdir:-.}/tab/
441 # Files that describe the attribute sets supported.
446 modulePath:$modulesdir/modules/
447 # Specify record type
448 iso2709.recordType:grs.marcxml.record
450 recordId: (bib1,Local-Number)
456 lockDir: $biblioserverdir/lock
461 register: $biblioserverdir/register:4G
462 shadow: $biblioserverdir/shadow:4G
464 # Temp File area for result sets
465 setTmpDir: $biblioserverdir/tmp
467 # Temp File area for index program
468 keyTmpDir: $biblioserverdir/key
470 # Approx. Memory usage during indexing
474 print "Info: creating zebra-biblios.cfg\n";
475 $created_dir_or_file++;
478 if ($created_dir_or_file) {
479 print "Info: created : $created_dir_or_file directories & files\n";
481 print "Info: file & directories OK\n";
489 print "====================\n";
490 print "SKIPPING biblio export\n";
491 print "====================\n";
493 print "====================\n";
494 print "exporting biblios\n";
495 print "====================\n";
496 mkdir "$directory" unless (-d $directory);
497 mkdir "$directory/biblios" unless (-d "$directory/biblios");
498 open(OUT,">:utf8 ","$directory/biblios/export") or die $!;
499 my $dbh=C4::Context->dbh;
502 $sth=$dbh->prepare("select biblionumber,marc from biblioitems order by biblionumber $limit");
505 while (my ($biblionumber,$marc) = $sth->fetchrow) {
507 $record=MARC::Record->new_from_usmarc($marc);
508 my $record_correct=1;
509 # skip uncorrect records : isn't this bogus, as just after we reintroduce biblionumber if it's missing ?
510 # FIXME next unless $record->field($biblionumbertagfield);
511 # check if biblionumber is present, otherwise, add it on the fly
512 if ($biblionumbertagfield eq '001') {
513 unless ($record->field($biblionumbertagfield)->data()) {
516 # if the field where biblionumber is already exist, just update it, otherwise create it
517 if ($record->field($biblionumbertagfield)) {
518 $field = $record->field($biblionumbertagfield);
519 $field->update($biblionumber);
522 $newfield = MARC::Field->new( $biblionumbertagfield, $biblionumber);
523 $record->append_fields($newfield);
527 unless ($record->subfield($biblionumbertagfield,$biblionumbertagsubfield)) {
530 # if the field where biblionumber is already exist, just update it, otherwise create it
531 if ($record->field($biblionumbertagfield)) {
532 $field = $record->field($biblionumbertagfield);
533 $field->add_subfields($biblionumbertagsubfield => $biblionumber);
536 $newfield = MARC::Field->new( $biblionumbertagfield,'','', $biblionumbertagsubfield => $biblionumber);
537 $record->append_fields($newfield);
540 # warn "FIXED BIBLIONUMBER".$record->as_formatted;
542 unless ($record->subfield($biblioitemnumbertagfield,$biblioitemnumbertagsubfield)) {
544 # warn "INCORRECT BIBLIOITEMNUMBER :".$record->as_formatted;
546 # if the field where biblionumber is already exist, just update it, otherwise create it
547 if ($record->field($biblioitemnumbertagfield)) {
548 $field = $record->field($biblioitemnumbertagfield);
549 if ($biblioitemnumbertagfield <10) {
550 $field->update($biblionumber);
552 $field->add_subfields($biblioitemnumbertagsubfield => $biblionumber);
556 if ($biblioitemnumbertagfield <10) {
557 $newfield = MARC::Field->new( $biblioitemnumbertagfield, $biblionumber);
559 $newfield = MARC::Field->new( $biblioitemnumbertagfield,'','', $biblioitemnumbertagsubfield => $biblionumber);
561 $record->insert_grouped_field($newfield);
563 # warn "FIXED BIBLIOITEMNUMBER".$record->as_formatted;
565 my $leader=$record->leader;
566 substr($leader,0,5)=' ';
567 substr($leader,10,7)='22 ';
568 $record->leader(substr($leader,0,24));
569 print OUT $record->as_usmarc();
573 $sth=$dbh->prepare("select biblionumber from biblioitems order by biblionumber $limit");
576 while (my ($biblionumber) = $sth->fetchrow) {
579 $record = GetMarcBiblio($biblionumber);
582 print " There was some pb getting biblio : #".$biblionumber."\n";
586 # warn $record->as_formatted;
587 # die if $record->subfield('090','9') eq 11;
589 # check that biblionumber & biblioitemnumber are stored in the MARC record, otherwise, add them & update the biblioitems.marcxml data.
590 my $record_correct=1;
591 # skip uncorrect records : isn't this bogus, as just after we reintroduce biblionumber if it's missing ?
592 # FIXME next unless $record->field($biblionumbertagfield);
593 # check if biblionumber is present, otherwise, add it on the fly
594 if ($biblionumbertagfield eq '001') {
595 unless ($record->field($biblionumbertagfield)->data()) {
598 # if the field where biblionumber is already exist, just update it, otherwise create it
599 if ($record->field($biblionumbertagfield)) {
600 $field = $record->field($biblionumbertagfield);
601 $field->update($biblionumber);
604 $newfield = MARC::Field->new( $biblionumbertagfield, $biblionumber);
605 $record->append_fields($newfield);
609 unless ($record->subfield($biblionumbertagfield,$biblionumbertagsubfield)) {
612 # if the field where biblionumber is already exist, just update it, otherwise create it
613 if ($record->field($biblionumbertagfield)) {
614 $field = $record->field($biblionumbertagfield);
615 $field->add_subfields($biblionumbertagsubfield => $biblionumber);
618 $newfield = MARC::Field->new( $biblionumbertagfield,'','', $biblionumbertagsubfield => $biblionumber);
619 $record->append_fields($newfield);
622 # warn "FIXED BIBLIONUMBER".$record->as_formatted;
624 unless ($record->subfield($biblioitemnumbertagfield,$biblioitemnumbertagsubfield)) {
626 # warn "INCORRECT BIBLIOITEMNUMBER :".$record->as_formatted;
628 # if the field where biblionumber is already exist, just update it, otherwise create it
629 if ($record->field($biblioitemnumbertagfield)) {
630 $field = $record->field($biblioitemnumbertagfield);
631 if ($biblioitemnumbertagfield <10) {
632 $field->update($biblionumber);
634 $field->add_subfields($biblioitemnumbertagsubfield => $biblionumber);
638 if ($biblioitemnumbertagfield <10) {
639 $newfield = MARC::Field->new( $biblioitemnumbertagfield, $biblionumber);
641 $newfield = MARC::Field->new( $biblioitemnumbertagfield,'','', $biblioitemnumbertagsubfield => $biblionumber);
643 $record->insert_grouped_field($newfield);
645 # warn "FIXED BIBLIOITEMNUMBER".$record->as_formatted;
647 unless ($record_correct) {
648 my $update_xml = $dbh->prepare("update biblioitems set marcxml=? where biblionumber=?");
649 warn "UPDATING $biblionumber (missing biblionumber or biblioitemnumber in MARC record : ".$record->as_xml;
650 $update_xml->execute($record->as_xml,$biblionumber);
653 print "\r$i" unless ($i++ %100);
654 # remove leader length, that could be wrong, it will be calculated automatically by as_usmarc
655 # otherwise, if it's wron, zebra will fail miserabily (and never index what is after the failing record)
656 my $leader=$record->leader;
657 substr($leader,0,5)=' ';
658 substr($leader,10,7)='22 ';
659 $record->leader(substr($leader,0,24));
660 print OUT $record->as_usmarc();
667 # and reindexing everything
669 print "====================\n";
670 print "REINDEXING zebra\n";
671 print "====================\n";
672 system("zebraidx -g iso2709 -c ".C4::Context->zebraconfig('biblioserver')->{config}." -d biblios init") if ($reset);
673 system("zebraidx -g iso2709 -c ".C4::Context->zebraconfig('biblioserver')->{config}." -d biblios update $directory/biblios");
674 system("zebraidx -g iso2709 -c ".C4::Context->zebraconfig('biblioserver')->{config}." -d biblios commit");
676 print "skipping biblios\n";
679 print "====================\n";
681 print "====================\n";
683 print "NOTHING cleaned : the $directory has been kept. You can re-run this script with the -s parameter if you just want to rebuild zebra after changing the record.abs or another zebra config file\n";
685 system("rm -rf $directory");
686 print "directory $directory deleted\n";