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);
303 print " There was some pb getting authority : ".$authid."\n";
308 print "\r$i" unless ($i++ %100);
309 # # remove leader length, that could be wrong, it will be calculated automatically by as_usmarc
310 # # otherwise, if it's wron, zebra will fail miserabily (and never index what is after the failing record)
311 my $leader=$record->leader;
312 substr($leader,0,5)=' ';
313 substr($leader,10,7)='22 ';
314 $record->leader(substr($leader,0,24));
315 print OUT $record->as_usmarc;
321 # and reindexing everything
323 print "====================\n";
324 print "REINDEXING zebra\n";
325 print "====================\n";
326 system("zebraidx -c ".C4::Context->zebraconfig('authorityserver')->{config}." -g iso2709 -d authorities init") if ($reset);
327 system("zebraidx -c ".C4::Context->zebraconfig('authorityserver')->{config}." -g iso2709 -d authorities update $directory/authorities");
328 system("zebraidx -c ".C4::Context->zebraconfig('authorityserver')->{config}." -g iso2709 -d authorities commit");
330 print "skipping authorities\n";
332 #################################################################################################################
334 #################################################################################################################
337 print "====================\n";
338 print "checking directories & files for biblios\n";
339 print "====================\n";
342 # BIBLIOS : creating directory structure
344 unless (-d "$biblioserverdir") {
345 system("mkdir -p $biblioserverdir");
346 print "Info: created $biblioserverdir\n";
347 $created_dir_or_file++;
349 unless (-d "$biblioserverdir/lock") {
350 mkdir "$biblioserverdir/lock";
351 print "Info: created $biblioserverdir/lock\n";
352 $created_dir_or_file++;
354 unless (-d "$biblioserverdir/register") {
355 mkdir "$biblioserverdir/register";
356 print "Info: created $biblioserverdir/register\n";
357 $created_dir_or_file++;
359 unless (-d "$biblioserverdir/shadow") {
360 mkdir "$biblioserverdir/shadow";
361 print "Info: created $biblioserverdir/shadow\n";
362 $created_dir_or_file++;
364 unless (-d "$biblioserverdir/tab") {
365 mkdir "$biblioserverdir/tab";
366 print "Info: created $biblioserverdir/tab\n";
367 $created_dir_or_file++;
369 unless (-d "$biblioserverdir/key") {
370 mkdir "$biblioserverdir/key";
371 print "Info: created $biblioserverdir/key\n";
372 $created_dir_or_file++;
374 unless (-d "$biblioserverdir/etc") {
375 mkdir "$biblioserverdir/etc";
376 print "Info: created $biblioserverdir/etc\n";
377 $created_dir_or_file++;
381 # BIBLIOS : copying mandatory files
383 # the record model, depending on marc flavour
384 unless (-f "$biblioserverdir/tab/record.abs") {
385 if (C4::Context->preference("marcflavour") eq "UNIMARC") {
386 system("cp -f $kohadir/misc/zebra/record_biblios_unimarc.abs $biblioserverdir/tab/record.abs");
387 print "Info: copied record.abs for UNIMARC\n";
389 system("cp -f $kohadir/misc/zebra/record_biblios_usmarc.abs $biblioserverdir/tab/record.abs");
390 print "Info: copied record.abs for USMARC\n";
392 $created_dir_or_file++;
394 unless (-f "$biblioserverdir/tab/sort-string-utf.chr") {
395 system("cp -f $kohadir/misc/zebra/sort-string-utf_french.chr $biblioserverdir/tab/sort-string-utf.chr");
396 print "Info: copied sort-string-utf.chr\n";
397 $created_dir_or_file++;
399 unless (-f "$biblioserverdir/tab/word-phrase-utf.chr") {
400 system("cp -f $kohadir/misc/zebra/sort-string-utf_french.chr $biblioserverdir/tab/word-phrase-utf.chr");
401 print "Info: copied word-phase-utf.chr\n";
402 $created_dir_or_file++;
404 unless (-f "$biblioserverdir/tab/bib1.att") {
405 system("cp -f $kohadir/misc/zebra/bib1_biblios.att $biblioserverdir/tab/bib1.att");
406 print "Info: copied bib1.att\n";
407 $created_dir_or_file++;
409 unless (-f "$biblioserverdir/tab/default.idx") {
410 system("cp -f $kohadir/misc/zebra/default.idx $biblioserverdir/tab/default.idx");
411 print "Info: copied default.idx\n";
412 $created_dir_or_file++;
414 unless (-f "$biblioserverdir/etc/ccl.properties") {
415 # system("cp -f $kohadir/misc/zebra/ccl.properties ".C4::Context->zebraconfig('biblioserver')->{ccl2rpn});
416 system("cp -f $kohadir/misc/zebra/ccl.properties $biblioserverdir/etc/ccl.properties");
417 print "Info: copied ccl.properties\n";
418 $created_dir_or_file++;
420 unless (-f "$biblioserverdir/etc/pqf.properties") {
421 # system("cp -f $kohadir/misc/zebra/pqf.properties ".C4::Context->zebraconfig('biblioserver')->{ccl2rpn});
422 system("cp -f $kohadir/misc/zebra/pqf.properties $biblioserverdir/etc/pqf.properties");
423 print "Info: copied pqf.properties\n";
424 $created_dir_or_file++;
428 # BIBLIOS : copying mandatory files
430 unless (-f C4::Context->zebraconfig('biblioserver')->{config}) {
431 open ZD,">:utf8 ",C4::Context->zebraconfig('biblioserver')->{config};
433 # generated by KOHA/misc/migrtion_tools/rebuild_zebra.pl
434 profilePath:\${srcdir:-.}:$biblioserverdir/tab/:$tabdir/tab/:\${srcdir:-.}/tab/
437 # Files that describe the attribute sets supported.
442 modulePath:$modulesdir/modules/
443 # Specify record type
444 iso2709.recordType:grs.marcxml.record
446 recordId: (bib1,Local-Number)
452 lockDir: $biblioserverdir/lock
457 register: $biblioserverdir/register:4G
458 shadow: $biblioserverdir/shadow:4G
460 # Temp File area for result sets
461 setTmpDir: $biblioserverdir/tmp
463 # Temp File area for index program
464 keyTmpDir: $biblioserverdir/key
466 # Approx. Memory usage during indexing
470 print "Info: creating zebra-biblios.cfg\n";
471 $created_dir_or_file++;
474 if ($created_dir_or_file) {
475 print "Info: created : $created_dir_or_file directories & files\n";
477 print "Info: file & directories OK\n";
485 print "====================\n";
486 print "SKIPPING biblio export\n";
487 print "====================\n";
489 print "====================\n";
490 print "exporting biblios\n";
491 print "====================\n";
492 mkdir "$directory" unless (-d $directory);
493 mkdir "$directory/biblios" unless (-d "$directory/biblios");
494 open(OUT,">:utf8 ","$directory/biblios/export") or die $!;
495 my $dbh=C4::Context->dbh;
498 $sth=$dbh->prepare("select biblionumber,marc from biblioitems order by biblionumber $limit");
501 while (my ($biblionumber,$marc) = $sth->fetchrow) {
503 $record=MARC::Record->new_from_usmarc($marc);
504 my $record_correct=1;
505 next unless $record->field($biblionumbertagfield);
506 if ($biblionumbertagfield eq '001') {
507 unless ($record->field($biblionumbertagfield)->data()) {
510 # if the field where biblionumber is already exist, just update it, otherwise create it
511 if ($record->field($biblionumbertagfield)) {
512 $field = $record->field($biblionumbertagfield);
513 $field->update($biblionumber);
516 $newfield = MARC::Field->new( $biblionumbertagfield, $biblionumber);
517 $record->append_fields($newfield);
521 unless ($record->subfield($biblionumbertagfield,$biblionumbertagsubfield)) {
524 # if the field where biblionumber is already exist, just update it, otherwise create it
525 if ($record->field($biblionumbertagfield)) {
526 $field = $record->field($biblionumbertagfield);
527 $field->add_subfields($biblionumbertagsubfield => $biblionumber);
530 $newfield = MARC::Field->new( $biblionumbertagfield,'','', $biblionumbertagsubfield => $biblionumber);
531 $record->append_fields($newfield);
534 # warn "FIXED BIBLIONUMBER".$record->as_formatted;
536 unless ($record->subfield($biblioitemnumbertagfield,$biblioitemnumbertagsubfield)) {
538 # warn "INCORRECT BIBLIOITEMNUMBER :".$record->as_formatted;
540 # if the field where biblionumber is already exist, just update it, otherwise create it
541 if ($record->field($biblioitemnumbertagfield)) {
542 $field = $record->field($biblioitemnumbertagfield);
543 if ($biblioitemnumbertagfield <10) {
544 $field->update($biblionumber);
546 $field->add_subfields($biblioitemnumbertagsubfield => $biblionumber);
550 if ($biblioitemnumbertagfield <10) {
551 $newfield = MARC::Field->new( $biblioitemnumbertagfield, $biblionumber);
553 $newfield = MARC::Field->new( $biblioitemnumbertagfield,'','', $biblioitemnumbertagsubfield => $biblionumber);
555 $record->insert_grouped_field($newfield);
557 # warn "FIXED BIBLIOITEMNUMBER".$record->as_formatted;
559 my $leader=$record->leader;
560 substr($leader,0,5)=' ';
561 substr($leader,10,7)='22 ';
562 $record->leader(substr($leader,0,24));
563 print OUT $record->as_usmarc();
567 $sth=$dbh->prepare("select biblionumber from biblioitems order by biblionumber $limit");
570 while (my ($biblionumber) = $sth->fetchrow) {
573 $record = GetMarcBiblio($biblionumber);
576 print " There was some pb getting biblio : #".$biblionumber."\n";
579 # warn $record->as_formatted;
580 # die if $record->subfield('090','9') eq 11;
582 # check that biblionumber & biblioitemnumber are stored in the MARC record, otherwise, add them & update the biblioitems.marcxml data.
583 my $record_correct=1;
584 next unless $record->field($biblionumbertagfield);
585 if ($biblionumbertagfield eq '001') {
586 unless ($record->field($biblionumbertagfield)->data()) {
589 # if the field where biblionumber is already exist, just update it, otherwise create it
590 if ($record->field($biblionumbertagfield)) {
591 $field = $record->field($biblionumbertagfield);
592 $field->update($biblionumber);
595 $newfield = MARC::Field->new( $biblionumbertagfield, $biblionumber);
596 $record->append_fields($newfield);
600 unless ($record->subfield($biblionumbertagfield,$biblionumbertagsubfield)) {
603 # if the field where biblionumber is already exist, just update it, otherwise create it
604 if ($record->field($biblionumbertagfield)) {
605 $field = $record->field($biblionumbertagfield);
606 $field->add_subfields($biblionumbertagsubfield => $biblionumber);
609 $newfield = MARC::Field->new( $biblionumbertagfield,'','', $biblionumbertagsubfield => $biblionumber);
610 $record->append_fields($newfield);
613 # warn "FIXED BIBLIONUMBER".$record->as_formatted;
615 unless ($record->subfield($biblioitemnumbertagfield,$biblioitemnumbertagsubfield)) {
617 # warn "INCORRECT BIBLIOITEMNUMBER :".$record->as_formatted;
619 # if the field where biblionumber is already exist, just update it, otherwise create it
620 if ($record->field($biblioitemnumbertagfield)) {
621 $field = $record->field($biblioitemnumbertagfield);
622 if ($biblioitemnumbertagfield <10) {
623 $field->update($biblionumber);
625 $field->add_subfields($biblioitemnumbertagsubfield => $biblionumber);
629 if ($biblioitemnumbertagfield <10) {
630 $newfield = MARC::Field->new( $biblioitemnumbertagfield, $biblionumber);
632 $newfield = MARC::Field->new( $biblioitemnumbertagfield,'','', $biblioitemnumbertagsubfield => $biblionumber);
634 $record->insert_grouped_field($newfield);
636 # warn "FIXED BIBLIOITEMNUMBER".$record->as_formatted;
638 unless ($record_correct) {
639 my $update_xml = $dbh->prepare("update biblioitems set marcxml=? where biblionumber=?");
640 warn "UPDATING $biblionumber (missing biblionumber or biblioitemnumber in MARC record : ".$record->as_xml;
641 $update_xml->execute($record->as_xml,$biblionumber);
644 print "\r$i" unless ($i++ %100);
645 # remove leader length, that could be wrong, it will be calculated automatically by as_usmarc
646 # otherwise, if it's wron, zebra will fail miserabily (and never index what is after the failing record)
647 my $leader=$record->leader;
648 substr($leader,0,5)=' ';
649 substr($leader,10,7)='22 ';
650 $record->leader(substr($leader,0,24));
651 print OUT $record->as_usmarc();
658 # and reindexing everything
660 print "====================\n";
661 print "REINDEXING zebra\n";
662 print "====================\n";
663 system("zebraidx -g iso2709 -c ".C4::Context->zebraconfig('biblioserver')->{config}." -d biblios init") if ($reset);
664 system("zebraidx -g iso2709 -c ".C4::Context->zebraconfig('biblioserver')->{config}." -d biblios update $directory/biblios");
665 system("zebraidx -g iso2709 -c ".C4::Context->zebraconfig('biblioserver')->{config}." -d biblios commit");
667 print "skipping biblios\n";
670 print "====================\n";
672 print "====================\n";
674 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";
676 system("rm -rf $directory");
677 print "directory $directory deleted\n";