4 #use warnings; FIXME - Bug 2505
8 use File::Temp qw/ tempdir /;
11 use C4::AuthoritiesMarc;
13 use Koha::RecordProcessor;
16 # script that checks zebradir structure & create directories & mandatory files if needed
20 $|=1; # flushes output
21 # If the cron job starts us in an unreadable dir, we will break without
23 chdir $ENV{HOME} if (!(-r '.'));
39 my $process_zebraqueue;
40 my $do_not_clear_zebraqueue;
45 my $run_user = (getpwuid($<))[0];
47 my $verbose_logging = 0;
48 my $zebraidx_log_opt = " -v none,fatal,warn ";
49 my $result = GetOptions(
50 'daemon' => \$daemon_mode,
51 'sleep:i' => \$daemon_sleep,
56 'I|skip-index' => \$skip_index,
57 'nosanitize' => \$nosanitize,
61 'munge-config' => \$do_munge,
63 'h|help' => \$want_help,
65 'y' => \$do_not_clear_zebraqueue,
66 'z' => \$process_zebraqueue,
68 'length:i' => \$length,
69 'offset:i' => \$offset,
70 'v+' => \$verbose_logging,
71 'run-as-root' => \$run_as_root,
74 if (not $result or $want_help) {
79 if( not defined $run_as_root and $run_user eq 'root') {
80 my $msg = "Warning: You are running this script as the user 'root'.\n";
81 $msg .= "If this is intentional you must explicitly specify this using the -run-as-root switch\n";
82 $msg .= "Please do '$0 --help' to see usage.\n";
86 if ( !$as_xml and $nosanitize ) {
87 my $msg = "Cannot specify both -no_xml and -nosanitize\n";
88 $msg .= "Please do '$0 --help' to see usage.\n";
92 if ($process_zebraqueue and ($skip_export or $reset)) {
93 my $msg = "Cannot specify -r or -s if -z is specified\n";
94 $msg .= "Please do '$0 --help' to see usage.\n";
98 if ($process_zebraqueue and $do_not_clear_zebraqueue) {
99 my $msg = "Cannot specify both -y and -z\n";
100 $msg .= "Please do '$0 --help' to see usage.\n";
113 # incompatible flags handled above: help, reset, and do_not_clear_zebraqueue
114 if ($skip_export or $keep_export or $skip_index or
115 $where or $length or $offset) {
116 my $msg = "Cannot specify -s, -k, -I, -where, -length, or -offset with -daemon.\n";
117 $msg .= "Please do '$0 --help' to see usage.\n";
122 $process_zebraqueue = 1;
125 if (not $biblios and not $authorities) {
126 my $msg = "Must specify -b or -a to reindex bibs or authorities\n";
127 $msg .= "Please do '$0 --help' to see usage.\n";
132 # -v is for verbose, which seems backwards here because of how logging is set
133 # on the CLI of zebraidx. It works this way. The default is to not log much
134 if ($verbose_logging >= 2) {
135 $zebraidx_log_opt = '-v none,fatal,warn,all';
139 unless ($directory) {
141 $directory = tempdir(CLEANUP => ($keep_export ? 0 : 1));
145 my $biblioserverdir = C4::Context->zebraconfig('biblioserver')->{directory};
146 my $authorityserverdir = C4::Context->zebraconfig('authorityserver')->{directory};
148 my $kohadir = C4::Context->config('intranetdir');
149 my $bib_index_mode = C4::Context->config('zebra_bib_index_mode') || 'grs1';
150 my $auth_index_mode = C4::Context->config('zebra_auth_index_mode') || 'dom';
152 my $dbh = C4::Context->dbh;
153 my ($biblionumbertagfield,$biblionumbertagsubfield) = &GetMarcFromKohaField("biblio.biblionumber","");
154 my ($biblioitemnumbertagfield,$biblioitemnumbertagsubfield) = &GetMarcFromKohaField("biblioitems.biblioitemnumber","");
156 if ( $verbose_logging ) {
157 print "Zebra configuration information\n";
158 print "================================\n";
159 print "Zebra biblio directory = $biblioserverdir\n";
160 print "Zebra authorities directory = $authorityserverdir\n";
161 print "Koha directory = $kohadir\n";
162 print "BIBLIONUMBER in : $biblionumbertagfield\$$biblionumbertagsubfield\n";
163 print "BIBLIOITEMNUMBER in : $biblioitemnumbertagfield\$$biblioitemnumbertagsubfield\n";
164 print "================================\n";
171 my $tester = XML::LibXML->new();
175 do_one_pass() if ( zebraqueue_not_empty() );
183 if ( $verbose_logging ) {
184 print "====================\n";
186 print "====================\n";
189 print "NOTHING cleaned : the export $directory has been kept.\n";
190 print "You can re-run this script with the -s ";
192 print " and -d $directory parameters";
197 print "if you just want to rebuild zebra after changing the record.abs\n";
198 print "or another zebra config file\n";
200 unless ($use_tempdir) {
201 # if we're using a temporary directory
202 # created by File::Temp, it will be removed
204 rmtree($directory, 0, 1);
205 print "directory $directory deleted\n";
211 index_records('authority', $directory, $skip_export, $skip_index, $process_zebraqueue, $as_xml, $noxml, $nosanitize, $do_not_clear_zebraqueue, $verbose_logging, $zebraidx_log_opt, $authorityserverdir);
213 print "skipping authorities\n" if ( $verbose_logging );
217 index_records('biblio', $directory, $skip_export, $skip_index, $process_zebraqueue, $as_xml, $noxml, $nosanitize, $do_not_clear_zebraqueue, $verbose_logging, $zebraidx_log_opt, $biblioserverdir);
219 print "skipping biblios\n" if ( $verbose_logging );
223 # Check the zebra update queue and return true if there are records to process
224 # This routine will handle each of -ab, -a, or -b, but in practice we force
225 # -ab when in daemon mode.
226 sub zebraqueue_not_empty {
229 if ($authorities && $biblios) {
230 $where_str = 'done = 0;';
232 $where_str = 'server = "biblioserver" AND done = 0;';
234 $where_str = 'server = "authorityserver" AND done = 0;';
237 $dbh->prepare( 'SELECT COUNT(*) FROM zebraqueue WHERE ' . $where_str );
240 my $count = $query->fetchrow_arrayref->[0];
241 print "queued records: $count\n" if $verbose_logging > 0;
245 # This checks to see if the zebra directories exist under the provided path.
246 # If they don't, then zebra is likely to spit the dummy. This returns true
247 # if the directories had to be created, false otherwise.
248 sub check_zebra_dirs {
249 my ($base) = shift() . '/';
250 my $needed_repairing = 0;
251 my @dirs = ( '', 'key', 'register', 'shadow', 'tmp' );
252 foreach my $dir (@dirs) {
253 my $bdir = $base . $dir;
255 $needed_repairing = 1;
256 mkdir $bdir || die "Unable to create '$bdir': $!\n";
257 print "$0: needed to create '$bdir'\n";
260 return $needed_repairing;
261 } # ---------- end of subroutine check_zebra_dirs ----------
264 my ($record_type, $directory, $skip_export, $skip_index, $process_zebraqueue, $as_xml, $noxml, $nosanitize, $do_not_clear_zebraqueue, $verbose_logging, $zebraidx_log_opt, $server_dir) = @_;
266 my $num_records_exported = 0;
268 my $need_reset = check_zebra_dirs($server_dir);
270 print "$0: found broken zebra server directories: forcing a rebuild\n";
273 if ($skip_export && $verbose_logging) {
274 print "====================\n";
275 print "SKIPPING $record_type export\n";
276 print "====================\n";
278 if ( $verbose_logging ) {
279 print "====================\n";
280 print "exporting $record_type\n";
281 print "====================\n";
283 mkdir "$directory" unless (-d $directory);
284 mkdir "$directory/$record_type" unless (-d "$directory/$record_type");
285 if ($process_zebraqueue) {
286 my $entries = select_zebraqueue_records($record_type, 'deleted');
287 mkdir "$directory/del_$record_type" unless (-d "$directory/del_$record_type");
288 $records_deleted = generate_deleted_marc_records($record_type, $entries, "$directory/del_$record_type", $as_xml);
289 mark_zebraqueue_batch_done($entries);
290 $entries = select_zebraqueue_records($record_type, 'updated');
291 mkdir "$directory/upd_$record_type" unless (-d "$directory/upd_$record_type");
292 $num_records_exported = export_marc_records_from_list($record_type,
293 $entries, "$directory/upd_$record_type", $as_xml, $noxml, $records_deleted);
294 mark_zebraqueue_batch_done($entries);
296 my $sth = select_all_records($record_type);
297 $num_records_exported = export_marc_records_from_sth($record_type, $sth, "$directory/$record_type", $as_xml, $noxml, $nosanitize);
298 unless ($do_not_clear_zebraqueue) {
299 mark_all_zebraqueue_done($record_type);
305 # and reindexing everything
308 if ($verbose_logging) {
309 print "====================\n";
310 print "SKIPPING $record_type indexing\n";
311 print "====================\n";
314 if ( $verbose_logging ) {
315 print "====================\n";
316 print "REINDEXING zebra\n";
317 print "====================\n";
319 my $record_fmt = ($as_xml) ? 'marcxml' : 'iso2709' ;
320 if ($process_zebraqueue) {
321 do_indexing($record_type, 'adelete', "$directory/del_$record_type", $reset, $noshadow, $record_fmt, $zebraidx_log_opt)
322 if %$records_deleted;
323 do_indexing($record_type, 'update', "$directory/upd_$record_type", $reset, $noshadow, $record_fmt, $zebraidx_log_opt)
324 if $num_records_exported;
326 do_indexing($record_type, 'update', "$directory/$record_type", $reset, $noshadow, $record_fmt, $zebraidx_log_opt)
327 if ($num_records_exported or $skip_export);
333 sub select_zebraqueue_records {
334 my ($record_type, $update_type) = @_;
336 my $server = ($record_type eq 'biblio') ? 'biblioserver' : 'authorityserver';
337 my $op = ($update_type eq 'deleted') ? 'recordDelete' : 'specialUpdate';
339 my $sth = $dbh->prepare("SELECT id, biblio_auth_number
345 $sth->execute($server, $op);
346 my $entries = $sth->fetchall_arrayref({});
349 sub mark_all_zebraqueue_done {
350 my ($record_type) = @_;
352 my $server = ($record_type eq 'biblio') ? 'biblioserver' : 'authorityserver';
354 my $sth = $dbh->prepare("UPDATE zebraqueue SET done = 1
357 $sth->execute($server);
360 sub mark_zebraqueue_batch_done {
363 $dbh->{AutoCommit} = 0;
364 my $sth = $dbh->prepare("UPDATE zebraqueue SET done = 1 WHERE id = ?");
366 foreach my $id (map { $_->{id} } @$entries) {
369 $dbh->{AutoCommit} = 1;
372 sub select_all_records {
373 my $record_type = shift;
374 return ($record_type eq 'biblio') ? select_all_biblios() : select_all_authorities();
377 sub select_all_authorities {
378 my $strsth=qq{SELECT authid FROM auth_header};
379 $strsth.=qq{ WHERE $where } if ($where);
380 $strsth.=qq{ LIMIT $length } if ($length && !$offset);
381 $strsth.=qq{ LIMIT $offset,$length } if ($length && $offset);
382 my $sth = $dbh->prepare($strsth);
387 sub select_all_biblios {
388 my $strsth = qq{ SELECT biblionumber FROM biblioitems };
389 $strsth.=qq{ WHERE $where } if ($where);
390 $strsth.=qq{ LIMIT $length } if ($length && !$offset);
391 $strsth.=qq{ LIMIT $offset,$length } if ($offset);
392 my $sth = $dbh->prepare($strsth);
397 sub include_xml_wrapper {
399 my $record_type = shift;
401 return 0 unless $as_xml;
402 return 1 if $record_type eq 'biblio' and $bib_index_mode eq 'dom';
403 return 1 if $record_type eq 'authority' and $auth_index_mode eq 'dom';
408 sub export_marc_records_from_sth {
409 my ($record_type, $sth, $directory, $as_xml, $noxml, $nosanitize) = @_;
411 my $num_exported = 0;
412 open my $fh, '>:encoding(UTF-8) ', "$directory/exported_records" or die $!;
413 if (include_xml_wrapper($as_xml, $record_type)) {
414 # include XML declaration and root element
415 print {$fh} '<?xml version="1.0" encoding="UTF-8"?><collection>';
418 my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField("items.itemnumber",'');
419 while (my ($record_number) = $sth->fetchrow_array) {
420 print "." if ( $verbose_logging );
421 print "\r$i" unless ($i++ %100 or !$verbose_logging);
423 my $marcxml = $record_type eq 'biblio'
424 ? GetXmlBiblio( $record_number )
425 : GetAuthorityXML( $record_number );
426 if ($record_type eq 'biblio'){
427 my @items = GetItemsInfo($record_number);
429 my $record = MARC::Record->new;
430 $record->encoding('UTF-8');
432 foreach my $item (@items){
433 my $record = Item2Marc($item, $record_number);
434 push @itemsrecord, $record->field($itemtag);
436 $record->insert_fields_ordered(@itemsrecord);
437 my $itemsxml = $record->as_xml_record();
439 substr($marcxml, 0, length($marcxml)-10) .
440 substr($itemsxml, index($itemsxml, "</leader>\n", 0) + 10);
443 # extra test to ensure that result is valid XML; otherwise
444 # Zebra won't parse it in DOM mode
446 my $doc = $tester->parse_string($marcxml);
449 warn "Error exporting record $record_number ($record_type): $@\n";
453 $marcxml =~ s!<\?xml version="1.0" encoding="UTF-8"\?>\n!!;
454 print {$fh} $marcxml;
459 my ($marc) = get_corrected_marc_record($record_type, $record_number, $noxml);
464 $rec = $marc->as_xml_record(C4::Context->preference('marcflavour'));
466 my $doc = $tester->parse_string($rec);
469 die "invalid XML: $@";
471 $rec =~ s!<\?xml version="1.0" encoding="UTF-8"\?>\n!!;
473 $rec = $marc->as_usmarc();
479 warn "Error exporting record $record_number ($record_type) ".($noxml ? "not XML" : "XML");
480 warn "... specific error is $@" if $verbose_logging;
484 print "\nRecords exported: $num_exported\n" if ( $verbose_logging );
485 print {$fh} '</collection>' if (include_xml_wrapper($as_xml, $record_type));
487 return $num_exported;
490 sub export_marc_records_from_list {
491 my ($record_type, $entries, $directory, $as_xml, $noxml, $records_deleted) = @_;
493 my $num_exported = 0;
494 open my $fh, '>:encoding(UTF-8)', "$directory/exported_records" or die $!;
495 if (include_xml_wrapper($as_xml, $record_type)) {
496 # include XML declaration and root element
497 print {$fh} '<?xml version="1.0" encoding="UTF-8"?><collection>';
501 # Skip any deleted records. We check for this anyway, but this reduces error spam
502 my %found = %$records_deleted;
503 foreach my $record_number ( map { $_->{biblio_auth_number} }
504 grep { !$found{ $_->{biblio_auth_number} }++ }
506 print "." if ( $verbose_logging );
507 print "\r$i" unless ($i++ %100 or !$verbose_logging);
508 my ($marc) = get_corrected_marc_record($record_type, $record_number, $noxml);
513 $rec = $marc->as_xml_record(C4::Context->preference('marcflavour'));
514 $rec =~ s!<\?xml version="1.0" encoding="UTF-8"\?>\n!!;
516 $rec = $marc->as_usmarc();
522 warn "Error exporting record $record_number ($record_type) ".($noxml ? "not XML" : "XML");
526 print "\nRecords exported: $num_exported\n" if ( $verbose_logging );
527 print {$fh} '</collection>' if (include_xml_wrapper($as_xml, $record_type));
529 return $num_exported;
532 sub generate_deleted_marc_records {
533 my ($record_type, $entries, $directory, $as_xml) = @_;
535 my $records_deleted = {};
536 open my $fh, '>:encoding(UTF-8)', "$directory/exported_records" or die $!;
537 if (include_xml_wrapper($as_xml, $record_type)) {
538 # include XML declaration and root element
539 print {$fh} '<?xml version="1.0" encoding="UTF-8"?><collection>';
542 foreach my $record_number (map { $_->{biblio_auth_number} } @$entries ) {
543 print "\r$i" unless ($i++ %100 or !$verbose_logging);
544 print "." if ( $verbose_logging );
546 my $marc = MARC::Record->new();
547 if ($record_type eq 'biblio') {
548 fix_biblio_ids($marc, $record_number, $record_number);
550 fix_authority_id($marc, $record_number);
552 if (C4::Context->preference("marcflavour") eq "UNIMARC") {
553 fix_unimarc_100($marc);
558 $rec = $marc->as_xml_record(C4::Context->preference('marcflavour'));
559 $rec =~ s!<\?xml version="1.0" encoding="UTF-8"\?>\n!!;
561 $rec = $marc->as_usmarc();
565 $records_deleted->{$record_number} = 1;
567 print "\nRecords exported: $i\n" if ( $verbose_logging );
568 print {$fh} '</collection>' if (include_xml_wrapper($as_xml, $record_type));
570 return $records_deleted;
575 sub get_corrected_marc_record {
576 my ($record_type, $record_number, $noxml) = @_;
578 my $marc = get_raw_marc_record($record_type, $record_number, $noxml);
582 if ($record_type eq 'authority') {
583 fix_authority_id($marc, $record_number);
584 } elsif ($record_type eq 'biblio' && C4::Context->preference('IncludeSeeFromInSearches')) {
585 my $normalizer = Koha::RecordProcessor->new( { filters => 'EmbedSeeFromHeadings' } );
586 $marc = $normalizer->process($marc);
588 if (C4::Context->preference("marcflavour") eq "UNIMARC") {
589 fix_unimarc_100($marc);
596 sub get_raw_marc_record {
597 my ($record_type, $record_number, $noxml) = @_;
600 if ($record_type eq 'biblio') {
602 my $fetch_sth = $dbh->prepare_cached("SELECT marc FROM biblioitems WHERE biblionumber = ?");
603 $fetch_sth->execute($record_number);
604 if (my ($blob) = $fetch_sth->fetchrow_array) {
605 $marc = MARC::Record->new_from_usmarc($blob);
607 warn "error creating MARC::Record from $blob";
610 # failure to find a bib is not a problem -
611 # a delete could have been done before
612 # trying to process a record update
614 $fetch_sth->finish();
617 eval { $marc = GetMarcBiblio($record_number, 1); };
619 # here we do warn since catching an exception
620 # means that the bib was found but failed
622 warn "error retrieving biblio $record_number";
627 eval { $marc = GetAuthority($record_number); };
629 warn "error retrieving authority $record_number";
637 # FIXME - this routine is suspect
638 # It blanks the Leader/00-05 and Leader/12-16 to
639 # force them to be recalculated correct when
640 # the $marc->as_usmarc() or $marc->as_xml() is called.
641 # But why is this necessary? It would be a serious bug
642 # in MARC::Record (definitely) and MARC::File::XML (arguably)
643 # if they are emitting incorrect leader values.
646 my $leader = $marc->leader;
647 substr($leader, 0, 5) = ' ';
648 substr($leader, 10, 7) = '22 ';
649 $marc->leader(substr($leader, 0, 24));
653 # FIXME - it is essential to ensure that the biblionumber is present,
654 # otherwise, Zebra will choke on the record. However, this
655 # logic belongs in the relevant C4::Biblio APIs.
657 my $biblionumber = shift;
658 my $biblioitemnumber;
660 $biblioitemnumber = shift;
662 my $sth = $dbh->prepare(
663 "SELECT biblioitemnumber FROM biblioitems WHERE biblionumber=?");
664 $sth->execute($biblionumber);
665 ($biblioitemnumber) = $sth->fetchrow_array;
667 unless ($biblioitemnumber) {
668 warn "failed to get biblioitemnumber for biblio $biblionumber";
673 # FIXME - this is cheating on two levels
674 # 1. C4::Biblio::_koha_marc_update_bib_ids is meant to be an internal function
675 # 2. Making sure that the biblionumber and biblioitemnumber are correct and
676 # present in the MARC::Record object ought to be part of GetMarcBiblio.
678 # On the other hand, this better for now than what rebuild_zebra.pl used to
679 # do, which was duplicate the code for inserting the biblionumber
680 # and biblioitemnumber
681 C4::Biblio::_koha_marc_update_bib_ids($marc, '', $biblionumber, $biblioitemnumber);
686 sub fix_authority_id {
687 # FIXME - as with fix_biblio_ids, the authid must be present
688 # for Zebra's sake. However, this really belongs
689 # in C4::AuthoritiesMarc.
690 my ($marc, $authid) = @_;
691 unless ($marc->field('001') and $marc->field('001')->data() eq $authid){
692 $marc->delete_field($marc->field('001'));
693 $marc->insert_fields_ordered(MARC::Field->new('001',$authid));
697 sub fix_unimarc_100 {
698 # FIXME - again, if this is necessary, it belongs in C4::AuthoritiesMarc.
702 if ( length($marc->subfield( 100, "a" )) == 36 ) {
703 $string = $marc->subfield( 100, "a" );
704 my $f100 = $marc->field(100);
705 $marc->delete_field($f100);
708 $string = POSIX::strftime( "%Y%m%d", localtime );
710 $string = sprintf( "%-*s", 35, $string );
712 substr( $string, 22, 6, "frey50" );
713 unless ( length($marc->subfield( 100, "a" )) == 36 ) {
714 $marc->delete_field($marc->field(100));
715 $marc->insert_grouped_field(MARC::Field->new( 100, "", "", "a" => $string ));
720 my ($record_type, $op, $record_dir, $reset_index, $noshadow, $record_format, $zebraidx_log_opt) = @_;
722 my $zebra_server = ($record_type eq 'biblio') ? 'biblioserver' : 'authorityserver';
723 my $zebra_db_name = ($record_type eq 'biblio') ? 'biblios' : 'authorities';
724 my $zebra_config = C4::Context->zebraconfig($zebra_server)->{'config'};
725 my $zebra_db_dir = C4::Context->zebraconfig($zebra_server)->{'directory'};
727 system("zebraidx -c $zebra_config $zebraidx_log_opt -g $record_format -d $zebra_db_name init") if $reset_index;
728 system("zebraidx -c $zebra_config $zebraidx_log_opt $noshadow -g $record_format -d $zebra_db_name $op $record_dir");
729 system("zebraidx -c $zebra_config $zebraidx_log_opt -g $record_format -d $zebra_db_name commit") unless $noshadow;
735 $0: reindex MARC bibs and/or authorities in Zebra.
737 Use this batch job to reindex all biblio or authority
738 records in your Koha database.
742 -b index bibliographic records
744 -a index authority records
746 -daemon Run in daemon mode. The program will loop checking
747 for entries on the zebraqueue table, processing
748 them incrementally if present, and then sleep
749 for a few seconds before repeating the process
750 Checking the zebraqueue table is done with a cheap
751 SQL query. This allows for near realtime update of
752 the zebra search index with low system overhead.
753 Use -sleep to control the checking interval.
755 Daemon mode implies -z, -a, -b. The program will
756 refuse to start if options are present that do not
757 make sense while running as an incremental update
758 daemon (e.g. -r or -offset).
760 -sleep 10 Seconds to sleep between checks of the zebraqueue
761 table in daemon mode. The default is 5 seconds.
763 -z select only updated and deleted
764 records marked in the zebraqueue
765 table. Cannot be used with -r
768 -r clear Zebra index before
769 adding records to index. Implies -w.
771 -d Temporary directory for indexing.
772 If not specified, one is automatically
773 created. The export directory
774 is automatically deleted unless
775 you supply the -k switch.
777 -k Do not delete export directory.
779 -s Skip export. Used if you have
780 already exported the records
783 -noxml index from ISO MARC blob
784 instead of MARC XML. This
785 option is recommended only
788 -x export and index as xml instead of is02709 (biblios only).
789 use this if you might have records > 99,999 chars,
791 -nosanitize export biblio/authority records directly from DB marcxml
792 field without sanitizing records. It speed up
793 dump process but could fail if DB contains badly
794 encoded records. Works only with -x,
796 -w skip shadow indexing for this batch
798 -y do NOT clear zebraqueue after indexing; normally,
799 after doing batch indexing, zebraqueue should be
800 marked done for the affected record type(s) so that
801 a running zebraqueue_daemon doesn't try to reindex
802 the same records - specify -y to override this.
803 Cannot be used with -z.
805 -v increase the amount of logging. Normally only
806 warnings and errors from the indexing are shown.
807 Use log level 2 (-v -v) to include all Zebra logs.
809 --length 1234 how many biblio you want to export
810 --offset 1243 offset you want to start to
811 example: --offset 500 --length=500 will result in a LIMIT 500,1000 (exporting 1000 records, starting by the 500th one)
812 note that the numbers are NOT related to biblionumber, that's the intended behaviour.
813 --where let you specify a WHERE query, like itemtype='BOOK'
814 or something like that
816 --munge-config Deprecated option to try
817 to fix Zebra config files.
819 --run-as-root explicitily allow script to run as 'root' user
821 --help or -h show this message.
825 # FIXME: the following routines are deprecated and
826 # will be removed once it is determined whether
827 # a script to fix Zebra configuration files is
831 # creating zebra-biblios.cfg depending on system
834 # getting zebraidx directory
836 foreach (qw(/usr/local/bin/zebraidx
845 unless ($zebraidxdir) {
847 ERROR: could not find zebraidx directory
848 ERROR: Either zebra is not installed,
849 ERROR: or it's in a directory I don't checked.
850 ERROR: do a which zebraidx and edit this file to add the result you get
854 $zebraidxdir =~ s/\/bin\/.*//;
855 print "Info : zebra is in $zebraidxdir \n";
857 # getting modules directory
859 foreach (qw(/usr/local/lib/idzebra-2.0/modules/mod-grs-xml.so
860 /usr/local/lib/idzebra/modules/mod-grs-xml.so
861 /usr/lib/idzebra/modules/mod-grs-xml.so
862 /usr/lib/idzebra-2.0/modules/mod-grs-xml.so
869 unless ($modulesdir) {
871 ERROR: could not find mod-grs-xml.so directory
872 ERROR: Either zebra is not properly compiled (libxml2 is not setup and you don t have mod-grs-xml.so,
873 ERROR: or it's in a directory I don't checked.
874 ERROR: find where mod-grs-xml.so is and edit this file to add the result you get
878 $modulesdir =~ s/\/modules\/.*//;
879 print "Info: zebra modules dir : $modulesdir\n";
881 # getting tab directory
883 foreach (qw(/usr/local/share/idzebra/tab/explain.att
884 /usr/local/share/idzebra-2.0/tab/explain.att
885 /usr/share/idzebra/tab/explain.att
886 /usr/share/idzebra-2.0/tab/explain.att
895 ERROR: could not find explain.att directory
896 ERROR: Either zebra is not properly compiled,
897 ERROR: or it's in a directory I don't checked.
898 ERROR: find where explain.att is and edit this file to add the result you get
902 $tabdir =~ s/\/tab\/.*//;
903 print "Info: tab dir : $tabdir\n";
906 # AUTHORITIES creating directory structure
908 my $created_dir_or_file = 0;
910 if ( $verbose_logging ) {
911 print "====================\n";
912 print "checking directories & files for authorities\n";
913 print "====================\n";
915 unless (-d "$authorityserverdir") {
916 system("mkdir -p $authorityserverdir");
917 print "Info: created $authorityserverdir\n";
918 $created_dir_or_file++;
920 unless (-d "$authorityserverdir/lock") {
921 mkdir "$authorityserverdir/lock";
922 print "Info: created $authorityserverdir/lock\n";
923 $created_dir_or_file++;
925 unless (-d "$authorityserverdir/register") {
926 mkdir "$authorityserverdir/register";
927 print "Info: created $authorityserverdir/register\n";
928 $created_dir_or_file++;
930 unless (-d "$authorityserverdir/shadow") {
931 mkdir "$authorityserverdir/shadow";
932 print "Info: created $authorityserverdir/shadow\n";
933 $created_dir_or_file++;
935 unless (-d "$authorityserverdir/tab") {
936 mkdir "$authorityserverdir/tab";
937 print "Info: created $authorityserverdir/tab\n";
938 $created_dir_or_file++;
940 unless (-d "$authorityserverdir/key") {
941 mkdir "$authorityserverdir/key";
942 print "Info: created $authorityserverdir/key\n";
943 $created_dir_or_file++;
946 unless (-d "$authorityserverdir/etc") {
947 mkdir "$authorityserverdir/etc";
948 print "Info: created $authorityserverdir/etc\n";
949 $created_dir_or_file++;
953 # AUTHORITIES : copying mandatory files
955 # the record model, depending on marc flavour
956 unless (-f "$authorityserverdir/tab/record.abs") {
957 if (C4::Context->preference("marcflavour") eq "UNIMARC") {
958 system("cp -f $kohadir/etc/zebradb/marc_defs/unimarc/authorities/record.abs $authorityserverdir/tab/record.abs");
959 print "Info: copied record.abs for UNIMARC\n";
961 system("cp -f $kohadir/etc/zebradb/marc_defs/marc21/authorities/record.abs $authorityserverdir/tab/record.abs");
962 print "Info: copied record.abs for USMARC\n";
964 $created_dir_or_file++;
966 unless (-f "$authorityserverdir/tab/sort-string-utf.chr") {
967 system("cp -f $kohadir/etc/zebradb/lang_defs/fr/sort-string-utf.chr $authorityserverdir/tab/sort-string-utf.chr");
968 print "Info: copied sort-string-utf.chr\n";
969 $created_dir_or_file++;
971 unless (-f "$authorityserverdir/tab/word-phrase-utf.chr") {
972 system("cp -f $kohadir/etc/zebradb/lang_defs/fr/sort-string-utf.chr $authorityserverdir/tab/word-phrase-utf.chr");
973 print "Info: copied word-phase-utf.chr\n";
974 $created_dir_or_file++;
976 unless (-f "$authorityserverdir/tab/auth1.att") {
977 system("cp -f $kohadir/etc/zebradb/authorities/etc/bib1.att $authorityserverdir/tab/auth1.att");
978 print "Info: copied auth1.att\n";
979 $created_dir_or_file++;
981 unless (-f "$authorityserverdir/tab/default.idx") {
982 system("cp -f $kohadir/etc/zebradb/etc/default.idx $authorityserverdir/tab/default.idx");
983 print "Info: copied default.idx\n";
984 $created_dir_or_file++;
987 unless (-f "$authorityserverdir/etc/ccl.properties") {
988 # system("cp -f $kohadir/etc/zebradb/ccl.properties ".C4::Context->zebraconfig('authorityserver')->{ccl2rpn});
989 system("cp -f $kohadir/etc/zebradb/ccl.properties $authorityserverdir/etc/ccl.properties");
990 print "Info: copied ccl.properties\n";
991 $created_dir_or_file++;
993 unless (-f "$authorityserverdir/etc/pqf.properties") {
994 # system("cp -f $kohadir/etc/zebradb/pqf.properties ".C4::Context->zebraconfig('authorityserver')->{ccl2rpn});
995 system("cp -f $kohadir/etc/zebradb/pqf.properties $authorityserverdir/etc/pqf.properties");
996 print "Info: copied pqf.properties\n";
997 $created_dir_or_file++;
1001 # AUTHORITIES : copying mandatory files
1003 unless (-f C4::Context->zebraconfig('authorityserver')->{config}) {
1004 open my $zd, '>:encoding(UTF-8)' ,C4::Context->zebraconfig('authorityserver')->{config};
1006 # generated by KOHA/misc/migration_tools/rebuild_zebra.pl
1007 profilePath:\${srcdir:-.}:$authorityserverdir/tab/:$tabdir/tab/:\${srcdir:-.}/tab/
1010 # Files that describe the attribute sets supported.
1015 modulePath:$modulesdir/modules/
1016 # Specify record type
1017 iso2709.recordType:grs.marcxml.record
1019 recordId: (auth1,Local-Number)
1025 lockDir: $authorityserverdir/lock
1028 register: $authorityserverdir/register:4G
1029 shadow: $authorityserverdir/shadow:4G
1031 # Temp File area for result sets
1032 setTmpDir: $authorityserverdir/tmp
1034 # Temp File area for index program
1035 keyTmpDir: $authorityserverdir/key
1037 # Approx. Memory usage during indexing
1041 print "Info: creating zebra-authorities.cfg\n";
1042 $created_dir_or_file++;
1045 if ($created_dir_or_file) {
1046 print "Info: created : $created_dir_or_file directories & files\n";
1048 print "Info: file & directories OK\n";
1053 if ( $verbose_logging ) {
1054 print "====================\n";
1055 print "checking directories & files for biblios\n";
1056 print "====================\n";
1060 # BIBLIOS : creating directory structure
1062 unless (-d "$biblioserverdir") {
1063 system("mkdir -p $biblioserverdir");
1064 print "Info: created $biblioserverdir\n";
1065 $created_dir_or_file++;
1067 unless (-d "$biblioserverdir/lock") {
1068 mkdir "$biblioserverdir/lock";
1069 print "Info: created $biblioserverdir/lock\n";
1070 $created_dir_or_file++;
1072 unless (-d "$biblioserverdir/register") {
1073 mkdir "$biblioserverdir/register";
1074 print "Info: created $biblioserverdir/register\n";
1075 $created_dir_or_file++;
1077 unless (-d "$biblioserverdir/shadow") {
1078 mkdir "$biblioserverdir/shadow";
1079 print "Info: created $biblioserverdir/shadow\n";
1080 $created_dir_or_file++;
1082 unless (-d "$biblioserverdir/tab") {
1083 mkdir "$biblioserverdir/tab";
1084 print "Info: created $biblioserverdir/tab\n";
1085 $created_dir_or_file++;
1087 unless (-d "$biblioserverdir/key") {
1088 mkdir "$biblioserverdir/key";
1089 print "Info: created $biblioserverdir/key\n";
1090 $created_dir_or_file++;
1092 unless (-d "$biblioserverdir/etc") {
1093 mkdir "$biblioserverdir/etc";
1094 print "Info: created $biblioserverdir/etc\n";
1095 $created_dir_or_file++;
1099 # BIBLIOS : copying mandatory files
1101 # the record model, depending on marc flavour
1102 unless (-f "$biblioserverdir/tab/record.abs") {
1103 if (C4::Context->preference("marcflavour") eq "UNIMARC") {
1104 system("cp -f $kohadir/etc/zebradb/marc_defs/unimarc/biblios/record.abs $biblioserverdir/tab/record.abs");
1105 print "Info: copied record.abs for UNIMARC\n";
1107 system("cp -f $kohadir/etc/zebradb/marc_defs/marc21/biblios/record.abs $biblioserverdir/tab/record.abs");
1108 print "Info: copied record.abs for USMARC\n";
1110 $created_dir_or_file++;
1112 unless (-f "$biblioserverdir/tab/sort-string-utf.chr") {
1113 system("cp -f $kohadir/etc/zebradb/lang_defs/fr/sort-string-utf.chr $biblioserverdir/tab/sort-string-utf.chr");
1114 print "Info: copied sort-string-utf.chr\n";
1115 $created_dir_or_file++;
1117 unless (-f "$biblioserverdir/tab/word-phrase-utf.chr") {
1118 system("cp -f $kohadir/etc/zebradb/lang_defs/fr/sort-string-utf.chr $biblioserverdir/tab/word-phrase-utf.chr");
1119 print "Info: copied word-phase-utf.chr\n";
1120 $created_dir_or_file++;
1122 unless (-f "$biblioserverdir/tab/bib1.att") {
1123 system("cp -f $kohadir/etc/zebradb/biblios/etc/bib1.att $biblioserverdir/tab/bib1.att");
1124 print "Info: copied bib1.att\n";
1125 $created_dir_or_file++;
1127 unless (-f "$biblioserverdir/tab/default.idx") {
1128 system("cp -f $kohadir/etc/zebradb/etc/default.idx $biblioserverdir/tab/default.idx");
1129 print "Info: copied default.idx\n";
1130 $created_dir_or_file++;
1132 unless (-f "$biblioserverdir/etc/ccl.properties") {
1133 # system("cp -f $kohadir/etc/zebradb/ccl.properties ".C4::Context->zebraconfig('biblioserver')->{ccl2rpn});
1134 system("cp -f $kohadir/etc/zebradb/ccl.properties $biblioserverdir/etc/ccl.properties");
1135 print "Info: copied ccl.properties\n";
1136 $created_dir_or_file++;
1138 unless (-f "$biblioserverdir/etc/pqf.properties") {
1139 # system("cp -f $kohadir/etc/zebradb/pqf.properties ".C4::Context->zebraconfig('biblioserver')->{ccl2rpn});
1140 system("cp -f $kohadir/etc/zebradb/pqf.properties $biblioserverdir/etc/pqf.properties");
1141 print "Info: copied pqf.properties\n";
1142 $created_dir_or_file++;
1146 # BIBLIOS : copying mandatory files
1148 unless (-f C4::Context->zebraconfig('biblioserver')->{config}) {
1149 open my $zd, '>:encoding(UTF-8)', C4::Context->zebraconfig('biblioserver')->{config};
1151 # generated by KOHA/misc/migrtion_tools/rebuild_zebra.pl
1152 profilePath:\${srcdir:-.}:$biblioserverdir/tab/:$tabdir/tab/:\${srcdir:-.}/tab/
1155 # Files that describe the attribute sets supported.
1160 modulePath:$modulesdir/modules/
1161 # Specify record type
1162 iso2709.recordType:grs.marcxml.record
1164 recordId: (bib1,Local-Number)
1170 lockDir: $biblioserverdir/lock
1173 register: $biblioserverdir/register:4G
1174 shadow: $biblioserverdir/shadow:4G
1176 # Temp File area for result sets
1177 setTmpDir: $biblioserverdir/tmp
1179 # Temp File area for index program
1180 keyTmpDir: $biblioserverdir/key
1182 # Approx. Memory usage during indexing
1186 print "Info: creating zebra-biblios.cfg\n";
1187 $created_dir_or_file++;
1190 if ($created_dir_or_file) {
1191 print "Info: created : $created_dir_or_file directories & files\n";
1193 print "Info: file & directories OK\n";