4 #use warnings; FIXME - Bug 2505
8 use File::Temp qw/ tempdir /;
11 use C4::AuthoritiesMarc;
13 use Koha::RecordProcessor;
17 # script that checks zebradir structure & create directories & mandatory files if needed
21 $|=1; # flushes output
22 # If the cron job starts us in an unreadable dir, we will break without
24 chdir $ENV{HOME} if (!(-r '.'));
38 my $process_zebraqueue;
39 my $do_not_clear_zebraqueue;
43 my $verbose_logging = 0;
44 my $zebraidx_log_opt = " -v none,fatal,warn ";
45 my $result = GetOptions(
50 'I|skip-index' => \$skip_index,
51 'nosanitize' => \$nosanitize,
55 'munge-config' => \$do_munge,
57 'h|help' => \$want_help,
59 'y' => \$do_not_clear_zebraqueue,
60 'z' => \$process_zebraqueue,
62 'length:i' => \$length,
63 'offset:i' => \$offset,
64 'v+' => \$verbose_logging,
68 if (not $result or $want_help) {
73 if (not $biblios and not $authorities) {
74 my $msg = "Must specify -b or -a to reindex bibs or authorities\n";
75 $msg .= "Please do '$0 --help' to see usage.\n";
79 if ( !$as_xml and $nosanitize ) {
80 my $msg = "Cannot specify both -no_xml and -nosanitize\n";
81 $msg .= "Please do '$0 --help' to see usage.\n";
85 if ($process_zebraqueue and ($skip_export or $reset)) {
86 my $msg = "Cannot specify -r or -s if -z is specified\n";
87 $msg .= "Please do '$0 --help' to see usage.\n";
91 if ($process_zebraqueue and $do_not_clear_zebraqueue) {
92 my $msg = "Cannot specify both -y and -z\n";
93 $msg .= "Please do '$0 --help' to see usage.\n";
101 # -v is for verbose, which seems backwards here because of how logging is set
102 # on the CLI of zebraidx. It works this way. The default is to not log much
103 if ($verbose_logging >= 2) {
104 $zebraidx_log_opt = '-v none,fatal,warn,all';
108 unless ($directory) {
110 $directory = tempdir(CLEANUP => ($keep_export ? 0 : 1));
114 my $biblioserverdir = C4::Context->zebraconfig('biblioserver')->{directory};
115 my $authorityserverdir = C4::Context->zebraconfig('authorityserver')->{directory};
117 my $kohadir = C4::Context->config('intranetdir');
118 my $bib_index_mode = C4::Context->config('zebra_bib_index_mode') || 'grs1';
119 my $auth_index_mode = C4::Context->config('zebra_auth_index_mode') || 'dom';
121 my $dbh = C4::Context->dbh;
122 my ($biblionumbertagfield,$biblionumbertagsubfield) = &GetMarcFromKohaField("biblio.biblionumber","");
123 my ($biblioitemnumbertagfield,$biblioitemnumbertagsubfield) = &GetMarcFromKohaField("biblioitems.biblioitemnumber","");
125 if ( $verbose_logging ) {
126 print "Zebra configuration information\n";
127 print "================================\n";
128 print "Zebra biblio directory = $biblioserverdir\n";
129 print "Zebra authorities directory = $authorityserverdir\n";
130 print "Koha directory = $kohadir\n";
131 print "BIBLIONUMBER in : $biblionumbertagfield\$$biblionumbertagsubfield\n";
132 print "BIBLIOITEMNUMBER in : $biblioitemnumbertagfield\$$biblioitemnumbertagsubfield\n";
133 print "================================\n";
140 my $tester = XML::LibXML->new();
143 index_records('authority', $directory, $skip_export, $skip_index, $process_zebraqueue, $as_xml, $noxml, $nosanitize, $do_not_clear_zebraqueue, $verbose_logging, $zebraidx_log_opt, $authorityserverdir);
145 print "skipping authorities\n" if ( $verbose_logging );
149 index_records('biblio', $directory, $skip_export, $skip_index, $process_zebraqueue, $as_xml, $noxml, $nosanitize, $do_not_clear_zebraqueue, $verbose_logging, $zebraidx_log_opt, $biblioserverdir);
151 print "skipping biblios\n" if ( $verbose_logging );
155 if ( $verbose_logging ) {
156 print "====================\n";
158 print "====================\n";
161 print "NOTHING cleaned : the export $directory has been kept.\n";
162 print "You can re-run this script with the -s ";
164 print " and -d $directory parameters";
169 print "if you just want to rebuild zebra after changing the record.abs\n";
170 print "or another zebra config file\n";
172 unless ($use_tempdir) {
173 # if we're using a temporary directory
174 # created by File::Temp, it will be removed
176 rmtree($directory, 0, 1);
177 print "directory $directory deleted\n";
181 # This checks to see if the zebra directories exist under the provided path.
182 # If they don't, then zebra is likely to spit the dummy. This returns true
183 # if the directories had to be created, false otherwise.
184 sub check_zebra_dirs {
185 my ($base) = shift() . '/';
186 my $needed_repairing = 0;
187 my @dirs = ( '', 'key', 'register', 'shadow', 'tmp' );
188 foreach my $dir (@dirs) {
189 my $bdir = $base . $dir;
191 $needed_repairing = 1;
192 mkdir $bdir || die "Unable to create '$bdir': $!\n";
193 print "$0: needed to create '$bdir'\n";
196 return $needed_repairing;
197 } # ---------- end of subroutine check_zebra_dirs ----------
200 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) = @_;
202 my $num_records_exported = 0;
204 my $need_reset = check_zebra_dirs($server_dir);
206 print "$0: found broken zebra server directories: forcing a rebuild\n";
209 if ($skip_export && $verbose_logging) {
210 print "====================\n";
211 print "SKIPPING $record_type export\n";
212 print "====================\n";
214 if ( $verbose_logging ) {
215 print "====================\n";
216 print "exporting $record_type\n";
217 print "====================\n";
219 mkdir "$directory" unless (-d $directory);
220 mkdir "$directory/$record_type" unless (-d "$directory/$record_type");
221 if ($process_zebraqueue) {
222 my $entries = select_zebraqueue_records($record_type, 'deleted');
223 mkdir "$directory/del_$record_type" unless (-d "$directory/del_$record_type");
224 $records_deleted = generate_deleted_marc_records($record_type, $entries, "$directory/del_$record_type", $as_xml);
225 mark_zebraqueue_batch_done($entries);
226 $entries = select_zebraqueue_records($record_type, 'updated');
227 mkdir "$directory/upd_$record_type" unless (-d "$directory/upd_$record_type");
228 $num_records_exported = export_marc_records_from_list($record_type,
229 $entries, "$directory/upd_$record_type", $as_xml, $noxml, $records_deleted);
230 mark_zebraqueue_batch_done($entries);
232 my $sth = select_all_records($record_type);
233 $num_records_exported = export_marc_records_from_sth($record_type, $sth, "$directory/$record_type", $as_xml, $noxml, $nosanitize);
234 unless ($do_not_clear_zebraqueue) {
235 mark_all_zebraqueue_done($record_type);
241 # and reindexing everything
244 if ($verbose_logging) {
245 print "====================\n";
246 print "SKIPPING $record_type indexing\n";
247 print "====================\n";
250 if ( $verbose_logging ) {
251 print "====================\n";
252 print "REINDEXING zebra\n";
253 print "====================\n";
255 my $record_fmt = ($as_xml) ? 'marcxml' : 'iso2709' ;
256 if ($process_zebraqueue) {
257 do_indexing($record_type, 'adelete', "$directory/del_$record_type", $reset, $noshadow, $record_fmt, $zebraidx_log_opt)
258 if %$records_deleted;
259 do_indexing($record_type, 'update', "$directory/upd_$record_type", $reset, $noshadow, $record_fmt, $zebraidx_log_opt)
260 if $num_records_exported;
262 do_indexing($record_type, 'update', "$directory/$record_type", $reset, $noshadow, $record_fmt, $zebraidx_log_opt)
263 if ($num_records_exported or $skip_export);
269 sub select_zebraqueue_records {
270 my ($record_type, $update_type) = @_;
272 my $server = ($record_type eq 'biblio') ? 'biblioserver' : 'authorityserver';
273 my $op = ($update_type eq 'deleted') ? 'recordDelete' : 'specialUpdate';
275 my $sth = $dbh->prepare("SELECT id, biblio_auth_number
281 $sth->execute($server, $op);
282 my $entries = $sth->fetchall_arrayref({});
285 sub mark_all_zebraqueue_done {
286 my ($record_type) = @_;
288 my $server = ($record_type eq 'biblio') ? 'biblioserver' : 'authorityserver';
290 my $sth = $dbh->prepare("UPDATE zebraqueue SET done = 1
293 $sth->execute($server);
296 sub mark_zebraqueue_batch_done {
299 $dbh->{AutoCommit} = 0;
300 my $sth = $dbh->prepare("UPDATE zebraqueue SET done = 1 WHERE id = ?");
302 foreach my $id (map { $_->{id} } @$entries) {
305 $dbh->{AutoCommit} = 1;
308 sub select_all_records {
309 my $record_type = shift;
310 return ($record_type eq 'biblio') ? select_all_biblios() : select_all_authorities();
313 sub select_all_authorities {
314 my $strsth=qq{SELECT authid FROM auth_header};
315 $strsth.=qq{ WHERE $where } if ($where);
316 $strsth.=qq{ LIMIT $length } if ($length && !$offset);
317 $strsth.=qq{ LIMIT $offset,$length } if ($length && $offset);
318 my $sth = $dbh->prepare($strsth);
323 sub select_all_biblios {
324 my $strsth = qq{ SELECT biblionumber FROM biblioitems };
325 $strsth.=qq{ WHERE $where } if ($where);
326 $strsth.=qq{ LIMIT $length } if ($length && !$offset);
327 $strsth.=qq{ LIMIT $offset,$length } if ($offset);
328 my $sth = $dbh->prepare($strsth);
333 sub include_xml_wrapper {
335 my $record_type = shift;
337 return 0 unless $as_xml;
338 return 1 if $record_type eq 'biblio' and $bib_index_mode eq 'dom';
339 return 1 if $record_type eq 'authority' and $auth_index_mode eq 'dom';
344 sub export_marc_records_from_sth {
345 my ($record_type, $sth, $directory, $as_xml, $noxml, $nosanitize) = @_;
347 my $num_exported = 0;
348 open my $fh, '>:encoding(UTF-8) ', "$directory/exported_records" or die $!;
349 if (include_xml_wrapper($as_xml, $record_type)) {
350 # include XML declaration and root element
351 print {$fh} '<?xml version="1.0" encoding="UTF-8"?><collection>';
354 my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField("items.itemnumber",'');
355 while (my ($record_number) = $sth->fetchrow_array) {
356 print "." if ( $verbose_logging );
357 print "\r$i" unless ($i++ %100 or !$verbose_logging);
359 my $marcxml = $record_type eq 'biblio'
360 ? GetXmlBiblio( $record_number )
361 : GetAuthorityXML( $record_number );
362 if ($record_type eq 'biblio'){
363 my @items = GetItemsInfo($record_number);
365 my $record = MARC::Record->new;
366 $record->encoding('UTF-8');
368 foreach my $item (@items){
369 my $record = Item2Marc($item, $record_number);
370 push @itemsrecord, $record->field($itemtag);
372 $record->insert_fields_ordered(@itemsrecord);
373 my $itemsxml = $record->as_xml_record();
375 substr($marcxml, 0, length($marcxml)-10) .
376 substr($itemsxml, index($itemsxml, "</leader>\n", 0) + 10);
379 # extra test to ensure that result is valid XML; otherwise
380 # Zebra won't parse it in DOM mode
382 my $doc = $tester->parse_string($marcxml);
385 warn "Error exporting record $record_number ($record_type): $@\n";
389 $marcxml =~ s!<\?xml version="1.0" encoding="UTF-8"\?>\n!!;
390 print {$fh} $marcxml;
395 my ($marc) = get_corrected_marc_record($record_type, $record_number, $noxml);
400 $rec = $marc->as_xml_record(C4::Context->preference('marcflavour'));
402 my $doc = $tester->parse_string($rec);
405 die "invalid XML: $@";
407 $rec =~ s!<\?xml version="1.0" encoding="UTF-8"\?>\n!!;
409 $rec = $marc->as_usmarc();
415 warn "Error exporting record $record_number ($record_type) ".($noxml ? "not XML" : "XML");
416 warn "... specific error is $@" if $verbose_logging;
420 print "\nRecords exported: $num_exported\n" if ( $verbose_logging );
421 print {$fh} '</collection>' if (include_xml_wrapper($as_xml, $record_type));
423 return $num_exported;
426 sub export_marc_records_from_list {
427 my ($record_type, $entries, $directory, $as_xml, $noxml, $records_deleted) = @_;
429 my $num_exported = 0;
430 open my $fh, '>:encoding(UTF-8)', "$directory/exported_records" or die $!;
431 if (include_xml_wrapper($as_xml, $record_type)) {
432 # include XML declaration and root element
433 print {$fh} '<?xml version="1.0" encoding="UTF-8"?><collection>';
437 # Skip any deleted records. We check for this anyway, but this reduces error spam
438 my %found = %$records_deleted;
439 foreach my $record_number ( map { $_->{biblio_auth_number} }
440 grep { !$found{ $_->{biblio_auth_number} }++ }
442 print "." if ( $verbose_logging );
443 print "\r$i" unless ($i++ %100 or !$verbose_logging);
444 my ($marc) = get_corrected_marc_record($record_type, $record_number, $noxml);
449 $rec = $marc->as_xml_record(C4::Context->preference('marcflavour'));
450 $rec =~ s!<\?xml version="1.0" encoding="UTF-8"\?>\n!!;
452 $rec = $marc->as_usmarc();
458 warn "Error exporting record $record_number ($record_type) ".($noxml ? "not XML" : "XML");
462 print "\nRecords exported: $num_exported\n" if ( $verbose_logging );
463 print {$fh} '</collection>' if (include_xml_wrapper($as_xml, $record_type));
465 return $num_exported;
468 sub generate_deleted_marc_records {
469 my ($record_type, $entries, $directory, $as_xml) = @_;
471 my $records_deleted = {};
472 open my $fh, '>:encoding(UTF-8)', "$directory/exported_records" or die $!;
473 if (include_xml_wrapper($as_xml, $record_type)) {
474 # include XML declaration and root element
475 print {$fh} '<?xml version="1.0" encoding="UTF-8"?><collection>';
478 foreach my $record_number (map { $_->{biblio_auth_number} } @$entries ) {
479 print "\r$i" unless ($i++ %100 or !$verbose_logging);
480 print "." if ( $verbose_logging );
482 my $marc = MARC::Record->new();
483 if ($record_type eq 'biblio') {
484 fix_biblio_ids($marc, $record_number, $record_number);
486 fix_authority_id($marc, $record_number);
488 if (C4::Context->preference("marcflavour") eq "UNIMARC") {
489 fix_unimarc_100($marc);
494 $rec = $marc->as_xml_record(C4::Context->preference('marcflavour'));
495 $rec =~ s!<\?xml version="1.0" encoding="UTF-8"\?>\n!!;
497 $rec = $marc->as_usmarc();
501 $records_deleted->{$record_number} = 1;
503 print "\nRecords exported: $i\n" if ( $verbose_logging );
504 print {$fh} '</collection>' if (include_xml_wrapper($as_xml, $record_type));
506 return $records_deleted;
511 sub get_corrected_marc_record {
512 my ($record_type, $record_number, $noxml) = @_;
514 my $marc = get_raw_marc_record($record_type, $record_number, $noxml);
518 if ($record_type eq 'authority') {
519 fix_authority_id($marc, $record_number);
520 } elsif ($record_type eq 'biblio' && C4::Context->preference('IncludeSeeFromInSearches')) {
521 my $normalizer = Koha::RecordProcessor->new( { filters => 'EmbedSeeFromHeadings' } );
522 $marc = $normalizer->process($marc);
524 if (C4::Context->preference("marcflavour") eq "UNIMARC") {
525 fix_unimarc_100($marc);
532 sub get_raw_marc_record {
533 my ($record_type, $record_number, $noxml) = @_;
536 if ($record_type eq 'biblio') {
538 my $fetch_sth = $dbh->prepare_cached("SELECT marc FROM biblioitems WHERE biblionumber = ?");
539 $fetch_sth->execute($record_number);
540 if (my ($blob) = $fetch_sth->fetchrow_array) {
541 $marc = MARC::Record->new_from_usmarc($blob);
543 warn "error creating MARC::Record from $blob";
546 # failure to find a bib is not a problem -
547 # a delete could have been done before
548 # trying to process a record update
550 $fetch_sth->finish();
553 eval { $marc = GetMarcBiblio($record_number, 1); };
555 # here we do warn since catching an exception
556 # means that the bib was found but failed
558 warn "error retrieving biblio $record_number";
563 eval { $marc = GetAuthority($record_number); };
565 warn "error retrieving authority $record_number";
573 # FIXME - this routine is suspect
574 # It blanks the Leader/00-05 and Leader/12-16 to
575 # force them to be recalculated correct when
576 # the $marc->as_usmarc() or $marc->as_xml() is called.
577 # But why is this necessary? It would be a serious bug
578 # in MARC::Record (definitely) and MARC::File::XML (arguably)
579 # if they are emitting incorrect leader values.
582 my $leader = $marc->leader;
583 substr($leader, 0, 5) = ' ';
584 substr($leader, 10, 7) = '22 ';
585 $marc->leader(substr($leader, 0, 24));
589 # FIXME - it is essential to ensure that the biblionumber is present,
590 # otherwise, Zebra will choke on the record. However, this
591 # logic belongs in the relevant C4::Biblio APIs.
593 my $biblionumber = shift;
594 my $biblioitemnumber;
596 $biblioitemnumber = shift;
598 my $sth = $dbh->prepare(
599 "SELECT biblioitemnumber FROM biblioitems WHERE biblionumber=?");
600 $sth->execute($biblionumber);
601 ($biblioitemnumber) = $sth->fetchrow_array;
603 unless ($biblioitemnumber) {
604 warn "failed to get biblioitemnumber for biblio $biblionumber";
609 # FIXME - this is cheating on two levels
610 # 1. C4::Biblio::_koha_marc_update_bib_ids is meant to be an internal function
611 # 2. Making sure that the biblionumber and biblioitemnumber are correct and
612 # present in the MARC::Record object ought to be part of GetMarcBiblio.
614 # On the other hand, this better for now than what rebuild_zebra.pl used to
615 # do, which was duplicate the code for inserting the biblionumber
616 # and biblioitemnumber
617 C4::Biblio::_koha_marc_update_bib_ids($marc, '', $biblionumber, $biblioitemnumber);
622 sub fix_authority_id {
623 # FIXME - as with fix_biblio_ids, the authid must be present
624 # for Zebra's sake. However, this really belongs
625 # in C4::AuthoritiesMarc.
626 my ($marc, $authid) = @_;
627 unless ($marc->field('001') and $marc->field('001')->data() eq $authid){
628 $marc->delete_field($marc->field('001'));
629 $marc->insert_fields_ordered(MARC::Field->new('001',$authid));
633 sub fix_unimarc_100 {
634 # FIXME - again, if this is necessary, it belongs in C4::AuthoritiesMarc.
638 if ( length($marc->subfield( 100, "a" )) == 36 ) {
639 $string = $marc->subfield( 100, "a" );
640 my $f100 = $marc->field(100);
641 $marc->delete_field($f100);
644 $string = POSIX::strftime( "%Y%m%d", localtime );
646 $string = sprintf( "%-*s", 35, $string );
648 substr( $string, 22, 6, "frey50" );
649 unless ( length($marc->subfield( 100, "a" )) == 36 ) {
650 $marc->delete_field($marc->field(100));
651 $marc->insert_grouped_field(MARC::Field->new( 100, "", "", "a" => $string ));
656 my ($record_type, $op, $record_dir, $reset_index, $noshadow, $record_format, $zebraidx_log_opt) = @_;
658 my $zebra_server = ($record_type eq 'biblio') ? 'biblioserver' : 'authorityserver';
659 my $zebra_db_name = ($record_type eq 'biblio') ? 'biblios' : 'authorities';
660 my $zebra_config = C4::Context->zebraconfig($zebra_server)->{'config'};
661 my $zebra_db_dir = C4::Context->zebraconfig($zebra_server)->{'directory'};
663 system("zebraidx -c $zebra_config $zebraidx_log_opt -g $record_format -d $zebra_db_name init") if $reset_index;
664 system("zebraidx -c $zebra_config $zebraidx_log_opt $noshadow -g $record_format -d $zebra_db_name $op $record_dir");
665 system("zebraidx -c $zebra_config $zebraidx_log_opt -g $record_format -d $zebra_db_name commit") unless $noshadow;
671 $0: reindex MARC bibs and/or authorities in Zebra.
673 Use this batch job to reindex all biblio or authority
674 records in your Koha database. This job is useful
675 only if you are using Zebra; if you are using the 'NoZebra'
676 mode, this job should not be used.
679 -b index bibliographic records
681 -a index authority records
683 -z select only updated and deleted
684 records marked in the zebraqueue
685 table. Cannot be used with -r
688 -r clear Zebra index before
689 adding records to index
691 -d Temporary directory for indexing.
692 If not specified, one is automatically
693 created. The export directory
694 is automatically deleted unless
695 you supply the -k switch.
697 -k Do not delete export directory.
699 -s Skip export. Used if you have
700 already exported the records
703 -noxml index from ISO MARC blob
704 instead of MARC XML. This
705 option is recommended only
708 -x export and index as xml instead of is02709 (biblios only).
709 use this if you might have records > 99,999 chars,
711 -nosanitize export biblio/authority records directly from DB marcxml
712 field without sanitizing records. It speed up
713 dump process but could fail if DB contains badly
714 encoded records. Works only with -x,
716 -w skip shadow indexing for this batch
718 -y do NOT clear zebraqueue after indexing; normally,
719 after doing batch indexing, zebraqueue should be
720 marked done for the affected record type(s) so that
721 a running zebraqueue_daemon doesn't try to reindex
722 the same records - specify -y to override this.
723 Cannot be used with -z.
725 -v increase the amount of logging. Normally only
726 warnings and errors from the indexing are shown.
727 Use log level 2 (-v -v) to include all Zebra logs.
729 --length 1234 how many biblio you want to export
730 --offset 1243 offset you want to start to
731 example: --offset 500 --length=500 will result in a LIMIT 500,1000 (exporting 1000 records, starting by the 500th one)
732 note that the numbers are NOT related to biblionumber, that's the intended behaviour.
733 --where let you specify a WHERE query, like itemtype='BOOK'
734 or something like that
736 --munge-config Deprecated option to try
737 to fix Zebra config files.
738 --help or -h show this message.
742 # FIXME: the following routines are deprecated and
743 # will be removed once it is determined whether
744 # a script to fix Zebra configuration files is
748 # creating zebra-biblios.cfg depending on system
751 # getting zebraidx directory
753 foreach (qw(/usr/local/bin/zebraidx
762 unless ($zebraidxdir) {
764 ERROR: could not find zebraidx directory
765 ERROR: Either zebra is not installed,
766 ERROR: or it's in a directory I don't checked.
767 ERROR: do a which zebraidx and edit this file to add the result you get
771 $zebraidxdir =~ s/\/bin\/.*//;
772 print "Info : zebra is in $zebraidxdir \n";
774 # getting modules directory
776 foreach (qw(/usr/local/lib/idzebra-2.0/modules/mod-grs-xml.so
777 /usr/local/lib/idzebra/modules/mod-grs-xml.so
778 /usr/lib/idzebra/modules/mod-grs-xml.so
779 /usr/lib/idzebra-2.0/modules/mod-grs-xml.so
786 unless ($modulesdir) {
788 ERROR: could not find mod-grs-xml.so directory
789 ERROR: Either zebra is not properly compiled (libxml2 is not setup and you don t have mod-grs-xml.so,
790 ERROR: or it's in a directory I don't checked.
791 ERROR: find where mod-grs-xml.so is and edit this file to add the result you get
795 $modulesdir =~ s/\/modules\/.*//;
796 print "Info: zebra modules dir : $modulesdir\n";
798 # getting tab directory
800 foreach (qw(/usr/local/share/idzebra/tab/explain.att
801 /usr/local/share/idzebra-2.0/tab/explain.att
802 /usr/share/idzebra/tab/explain.att
803 /usr/share/idzebra-2.0/tab/explain.att
812 ERROR: could not find explain.att directory
813 ERROR: Either zebra is not properly compiled,
814 ERROR: or it's in a directory I don't checked.
815 ERROR: find where explain.att is and edit this file to add the result you get
819 $tabdir =~ s/\/tab\/.*//;
820 print "Info: tab dir : $tabdir\n";
823 # AUTHORITIES creating directory structure
825 my $created_dir_or_file = 0;
827 if ( $verbose_logging ) {
828 print "====================\n";
829 print "checking directories & files for authorities\n";
830 print "====================\n";
832 unless (-d "$authorityserverdir") {
833 system("mkdir -p $authorityserverdir");
834 print "Info: created $authorityserverdir\n";
835 $created_dir_or_file++;
837 unless (-d "$authorityserverdir/lock") {
838 mkdir "$authorityserverdir/lock";
839 print "Info: created $authorityserverdir/lock\n";
840 $created_dir_or_file++;
842 unless (-d "$authorityserverdir/register") {
843 mkdir "$authorityserverdir/register";
844 print "Info: created $authorityserverdir/register\n";
845 $created_dir_or_file++;
847 unless (-d "$authorityserverdir/shadow") {
848 mkdir "$authorityserverdir/shadow";
849 print "Info: created $authorityserverdir/shadow\n";
850 $created_dir_or_file++;
852 unless (-d "$authorityserverdir/tab") {
853 mkdir "$authorityserverdir/tab";
854 print "Info: created $authorityserverdir/tab\n";
855 $created_dir_or_file++;
857 unless (-d "$authorityserverdir/key") {
858 mkdir "$authorityserverdir/key";
859 print "Info: created $authorityserverdir/key\n";
860 $created_dir_or_file++;
863 unless (-d "$authorityserverdir/etc") {
864 mkdir "$authorityserverdir/etc";
865 print "Info: created $authorityserverdir/etc\n";
866 $created_dir_or_file++;
870 # AUTHORITIES : copying mandatory files
872 # the record model, depending on marc flavour
873 unless (-f "$authorityserverdir/tab/record.abs") {
874 if (C4::Context->preference("marcflavour") eq "UNIMARC") {
875 system("cp -f $kohadir/etc/zebradb/marc_defs/unimarc/authorities/record.abs $authorityserverdir/tab/record.abs");
876 print "Info: copied record.abs for UNIMARC\n";
878 system("cp -f $kohadir/etc/zebradb/marc_defs/marc21/authorities/record.abs $authorityserverdir/tab/record.abs");
879 print "Info: copied record.abs for USMARC\n";
881 $created_dir_or_file++;
883 unless (-f "$authorityserverdir/tab/sort-string-utf.chr") {
884 system("cp -f $kohadir/etc/zebradb/lang_defs/fr/sort-string-utf.chr $authorityserverdir/tab/sort-string-utf.chr");
885 print "Info: copied sort-string-utf.chr\n";
886 $created_dir_or_file++;
888 unless (-f "$authorityserverdir/tab/word-phrase-utf.chr") {
889 system("cp -f $kohadir/etc/zebradb/lang_defs/fr/sort-string-utf.chr $authorityserverdir/tab/word-phrase-utf.chr");
890 print "Info: copied word-phase-utf.chr\n";
891 $created_dir_or_file++;
893 unless (-f "$authorityserverdir/tab/auth1.att") {
894 system("cp -f $kohadir/etc/zebradb/authorities/etc/bib1.att $authorityserverdir/tab/auth1.att");
895 print "Info: copied auth1.att\n";
896 $created_dir_or_file++;
898 unless (-f "$authorityserverdir/tab/default.idx") {
899 system("cp -f $kohadir/etc/zebradb/etc/default.idx $authorityserverdir/tab/default.idx");
900 print "Info: copied default.idx\n";
901 $created_dir_or_file++;
904 unless (-f "$authorityserverdir/etc/ccl.properties") {
905 # system("cp -f $kohadir/etc/zebradb/ccl.properties ".C4::Context->zebraconfig('authorityserver')->{ccl2rpn});
906 system("cp -f $kohadir/etc/zebradb/ccl.properties $authorityserverdir/etc/ccl.properties");
907 print "Info: copied ccl.properties\n";
908 $created_dir_or_file++;
910 unless (-f "$authorityserverdir/etc/pqf.properties") {
911 # system("cp -f $kohadir/etc/zebradb/pqf.properties ".C4::Context->zebraconfig('authorityserver')->{ccl2rpn});
912 system("cp -f $kohadir/etc/zebradb/pqf.properties $authorityserverdir/etc/pqf.properties");
913 print "Info: copied pqf.properties\n";
914 $created_dir_or_file++;
918 # AUTHORITIES : copying mandatory files
920 unless (-f C4::Context->zebraconfig('authorityserver')->{config}) {
921 open my $zd, '>:encoding(UTF-8)' ,C4::Context->zebraconfig('authorityserver')->{config};
923 # generated by KOHA/misc/migration_tools/rebuild_zebra.pl
924 profilePath:\${srcdir:-.}:$authorityserverdir/tab/:$tabdir/tab/:\${srcdir:-.}/tab/
927 # Files that describe the attribute sets supported.
932 modulePath:$modulesdir/modules/
933 # Specify record type
934 iso2709.recordType:grs.marcxml.record
936 recordId: (auth1,Local-Number)
942 lockDir: $authorityserverdir/lock
945 register: $authorityserverdir/register:4G
946 shadow: $authorityserverdir/shadow:4G
948 # Temp File area for result sets
949 setTmpDir: $authorityserverdir/tmp
951 # Temp File area for index program
952 keyTmpDir: $authorityserverdir/key
954 # Approx. Memory usage during indexing
958 print "Info: creating zebra-authorities.cfg\n";
959 $created_dir_or_file++;
962 if ($created_dir_or_file) {
963 print "Info: created : $created_dir_or_file directories & files\n";
965 print "Info: file & directories OK\n";
970 if ( $verbose_logging ) {
971 print "====================\n";
972 print "checking directories & files for biblios\n";
973 print "====================\n";
977 # BIBLIOS : creating directory structure
979 unless (-d "$biblioserverdir") {
980 system("mkdir -p $biblioserverdir");
981 print "Info: created $biblioserverdir\n";
982 $created_dir_or_file++;
984 unless (-d "$biblioserverdir/lock") {
985 mkdir "$biblioserverdir/lock";
986 print "Info: created $biblioserverdir/lock\n";
987 $created_dir_or_file++;
989 unless (-d "$biblioserverdir/register") {
990 mkdir "$biblioserverdir/register";
991 print "Info: created $biblioserverdir/register\n";
992 $created_dir_or_file++;
994 unless (-d "$biblioserverdir/shadow") {
995 mkdir "$biblioserverdir/shadow";
996 print "Info: created $biblioserverdir/shadow\n";
997 $created_dir_or_file++;
999 unless (-d "$biblioserverdir/tab") {
1000 mkdir "$biblioserverdir/tab";
1001 print "Info: created $biblioserverdir/tab\n";
1002 $created_dir_or_file++;
1004 unless (-d "$biblioserverdir/key") {
1005 mkdir "$biblioserverdir/key";
1006 print "Info: created $biblioserverdir/key\n";
1007 $created_dir_or_file++;
1009 unless (-d "$biblioserverdir/etc") {
1010 mkdir "$biblioserverdir/etc";
1011 print "Info: created $biblioserverdir/etc\n";
1012 $created_dir_or_file++;
1016 # BIBLIOS : copying mandatory files
1018 # the record model, depending on marc flavour
1019 unless (-f "$biblioserverdir/tab/record.abs") {
1020 if (C4::Context->preference("marcflavour") eq "UNIMARC") {
1021 system("cp -f $kohadir/etc/zebradb/marc_defs/unimarc/biblios/record.abs $biblioserverdir/tab/record.abs");
1022 print "Info: copied record.abs for UNIMARC\n";
1024 system("cp -f $kohadir/etc/zebradb/marc_defs/marc21/biblios/record.abs $biblioserverdir/tab/record.abs");
1025 print "Info: copied record.abs for USMARC\n";
1027 $created_dir_or_file++;
1029 unless (-f "$biblioserverdir/tab/sort-string-utf.chr") {
1030 system("cp -f $kohadir/etc/zebradb/lang_defs/fr/sort-string-utf.chr $biblioserverdir/tab/sort-string-utf.chr");
1031 print "Info: copied sort-string-utf.chr\n";
1032 $created_dir_or_file++;
1034 unless (-f "$biblioserverdir/tab/word-phrase-utf.chr") {
1035 system("cp -f $kohadir/etc/zebradb/lang_defs/fr/sort-string-utf.chr $biblioserverdir/tab/word-phrase-utf.chr");
1036 print "Info: copied word-phase-utf.chr\n";
1037 $created_dir_or_file++;
1039 unless (-f "$biblioserverdir/tab/bib1.att") {
1040 system("cp -f $kohadir/etc/zebradb/biblios/etc/bib1.att $biblioserverdir/tab/bib1.att");
1041 print "Info: copied bib1.att\n";
1042 $created_dir_or_file++;
1044 unless (-f "$biblioserverdir/tab/default.idx") {
1045 system("cp -f $kohadir/etc/zebradb/etc/default.idx $biblioserverdir/tab/default.idx");
1046 print "Info: copied default.idx\n";
1047 $created_dir_or_file++;
1049 unless (-f "$biblioserverdir/etc/ccl.properties") {
1050 # system("cp -f $kohadir/etc/zebradb/ccl.properties ".C4::Context->zebraconfig('biblioserver')->{ccl2rpn});
1051 system("cp -f $kohadir/etc/zebradb/ccl.properties $biblioserverdir/etc/ccl.properties");
1052 print "Info: copied ccl.properties\n";
1053 $created_dir_or_file++;
1055 unless (-f "$biblioserverdir/etc/pqf.properties") {
1056 # system("cp -f $kohadir/etc/zebradb/pqf.properties ".C4::Context->zebraconfig('biblioserver')->{ccl2rpn});
1057 system("cp -f $kohadir/etc/zebradb/pqf.properties $biblioserverdir/etc/pqf.properties");
1058 print "Info: copied pqf.properties\n";
1059 $created_dir_or_file++;
1063 # BIBLIOS : copying mandatory files
1065 unless (-f C4::Context->zebraconfig('biblioserver')->{config}) {
1066 open my $zd, '>:encoding(UTF-8)', C4::Context->zebraconfig('biblioserver')->{config};
1068 # generated by KOHA/misc/migrtion_tools/rebuild_zebra.pl
1069 profilePath:\${srcdir:-.}:$biblioserverdir/tab/:$tabdir/tab/:\${srcdir:-.}/tab/
1072 # Files that describe the attribute sets supported.
1077 modulePath:$modulesdir/modules/
1078 # Specify record type
1079 iso2709.recordType:grs.marcxml.record
1081 recordId: (bib1,Local-Number)
1087 lockDir: $biblioserverdir/lock
1090 register: $biblioserverdir/register:4G
1091 shadow: $biblioserverdir/shadow:4G
1093 # Temp File area for result sets
1094 setTmpDir: $biblioserverdir/tmp
1096 # Temp File area for index program
1097 keyTmpDir: $biblioserverdir/key
1099 # Approx. Memory usage during indexing
1103 print "Info: creating zebra-biblios.cfg\n";
1104 $created_dir_or_file++;
1107 if ($created_dir_or_file) {
1108 print "Info: created : $created_dir_or_file directories & files\n";
1110 print "Info: file & directories OK\n";