IMPORTANT: added -z option to rebuild_zebra.pl
[koha.git] / misc / migration_tools / rebuild_zebra.pl
1 #!/usr/bin/perl
2
3 use strict;
4
5 use C4::Context;
6 use Getopt::Long;
7 use File::Temp qw/ tempdir /;
8 use File::Path;
9 use C4::Biblio;
10 use C4::AuthoritiesMarc;
11
12
13 # script that checks zebradir structure & create directories & mandatory files if needed
14 #
15 #
16
17 $|=1; # flushes output
18
19 # limit for database dumping
20 my $directory;
21 my $skip_export;
22 my $keep_export;
23 my $reset;
24 my $biblios;
25 my $authorities;
26 my $noxml;
27 my $noshadow;
28 my $do_munge;
29 my $want_help;
30 my $as_xml;
31 my $process_zebraqueue;
32 my $result = GetOptions(
33     'd:s'           => \$directory,
34     'reset'         => \$reset,
35     's'             => \$skip_export,
36     'k'             => \$keep_export,
37     'b'             => \$biblios,
38     'noxml'         => \$noxml,
39     'w'             => \$noshadow,
40     'munge-config'  => \$do_munge,
41     'a'             => \$authorities,
42     'h|help'        => \$want_help,
43         'x'                             => \$as_xml,
44     'z'             => \$process_zebraqueue,
45 );
46
47
48 if (not $result or $want_help) {
49     print_usage();
50     exit 0;
51 }
52
53 if (not $biblios and not $authorities) {
54     my $msg = "Must specify -b or -a to reindex bibs or authorities\n";
55     $msg   .= "Please do '$0 --help' to see usage.\n";
56     die $msg;
57 }
58
59 if ($authorities and $as_xml) {
60     my $msg = "Cannot specify both -a and -x\n";
61     $msg   .= "Please do '$0 --help' to see usage.\n";
62     die $msg;
63 }
64
65 if ($process_zebraqueue and ($skip_export or $reset)) {
66     my $msg = "Cannot specify -r or -s if -z is specified\n";
67     $msg   .= "Please do '$0 --help' to see usage.\n";
68     die $msg;
69 }
70
71 if ($noshadow) {
72     $noshadow = ' -n ';
73 }
74 my $use_tempdir = 0;
75 unless ($directory) {
76     $use_tempdir = 1;
77     $directory = tempdir(CLEANUP => ($keep_export ? 0 : 1));
78
79
80
81 my $biblioserverdir = C4::Context->zebraconfig('biblioserver')->{directory};
82 my $authorityserverdir = C4::Context->zebraconfig('authorityserver')->{directory};
83
84 my $kohadir = C4::Context->config('intranetdir');
85 my $dbh = C4::Context->dbh;
86 my ($biblionumbertagfield,$biblionumbertagsubfield) = &GetMarcFromKohaField("biblio.biblionumber","");
87 my ($biblioitemnumbertagfield,$biblioitemnumbertagsubfield) = &GetMarcFromKohaField("biblioitems.biblioitemnumber","");
88
89 print "Zebra configuration information\n";
90 print "================================\n";
91 print "Zebra biblio directory      = $biblioserverdir\n";
92 print "Zebra authorities directory = $authorityserverdir\n";
93 print "Koha directory              = $kohadir\n";
94 print "BIBLIONUMBER in :     $biblionumbertagfield\$$biblionumbertagsubfield\n";
95 print "BIBLIOITEMNUMBER in : $biblioitemnumbertagfield\$$biblioitemnumbertagsubfield\n";
96 print "================================\n";
97
98 if ($do_munge) {
99     munge_config();
100 }
101
102 $dbh->{AutoCommit} = 0; # don't autocommit - want a consistent view of the zebraqueue table
103
104 if ($authorities) {
105     #
106     # exporting authorities
107     #
108     my $num_authorities_exported = 0;
109     my $num_authorities_deleted = 0;
110     if ($skip_export) {
111         print "====================\n";
112         print "SKIPPING authorities export\n";
113         print "====================\n";
114     } else {
115         print "====================\n";
116         print "exporting authorities\n";
117         print "====================\n";
118         mkdir "$directory" unless (-d $directory);
119         mkdir "$directory/authorities" unless (-d "$directory/authorities");
120         if ($process_zebraqueue) {
121             my $sth = select_zebraqueue_records('authority', 'deleted');
122             mkdir "$directory/del_authorities" unless (-d "$directory/del_authorities");
123             $num_authorities_deleted = generate_deleted_marc_records('authority', $sth, "$directory/del_authorities", $as_xml);
124             mark_zebraqueue_done('authority', 'deleted');
125             $sth = select_zebraqueue_records('authority', 'updated');
126             mkdir "$directory/upd_authorities" unless (-d "$directory/upd_authorities");
127             $num_authorities_exported = export_marc_records('authority', $sth, "$directory/upd_authorities", $as_xml, $noxml);
128             mark_zebraqueue_done('authority', 'updated');
129         } else {
130             my $sth = select_all_authorities();
131             $num_authorities_exported = export_marc_records('authority', $sth, "$directory/authorities", $as_xml, $noxml);
132         }
133     }
134     
135     #
136     # and reindexing everything
137     #
138     print "====================\n";
139     print "REINDEXING zebra\n";
140     print "====================\n";
141         my $record_fmt = ($as_xml) ? 'marcxml' : 'iso2709' ;
142     if ($process_zebraqueue) {
143         do_indexing('authority', 'delete', "$directory/del_authorities", $reset, $noshadow, $record_fmt) 
144             if $num_authorities_deleted;
145         do_indexing('authority', 'update', "$directory/upd_authorities", $reset, $noshadow, $record_fmt)
146             if $num_authorities_exported;
147     } else {
148         do_indexing('authority', 'update', "$directory/authorities", $reset, $noshadow, $record_fmt)
149             if $num_authorities_exported;
150     }
151
152 } else {
153     print "skipping authorities\n";
154 }
155
156 $dbh->commit(); # commit changes to zebraqueue, if any
157
158 #################################################################################################################
159 #                        BIBLIOS 
160 #################################################################################################################
161
162 if ($biblios) {
163     #
164     # exporting biblios
165     #
166     my $num_biblios_exported = 0;
167     my $num_biblios_deleted = 0;
168     if ($skip_export) {
169         print "====================\n";
170         print "SKIPPING biblio export\n";
171         print "====================\n";
172     } else {
173         print "====================\n";
174         print "exporting biblios\n";
175         print "====================\n";
176         mkdir "$directory" unless (-d $directory);
177         if ($process_zebraqueue) {
178             my $sth = select_zebraqueue_records('biblio', 'deleted');
179             mkdir "$directory/del_biblios" unless (-d "$directory/del_biblios");
180             $num_biblios_deleted = generate_deleted_marc_records('biblio', $sth, "$directory/del_biblios", $as_xml);
181             mark_zebraqueue_done('biblio', 'deleted');
182             $sth = select_zebraqueue_records('biblio', 'updated');
183             mkdir "$directory/upd_biblios" unless (-d "$directory/upd_biblios");
184             $num_biblios_exported = export_marc_records('biblio', $sth, "$directory/upd_biblios", $as_xml, $noxml);
185             mark_zebraqueue_done('biblio', 'updated');
186         } else {
187             mkdir "$directory/biblios" unless (-d "$directory/biblios");
188             my $sth = select_all_biblios();
189             $num_biblios_exported = export_marc_records('biblio', $sth, "$directory/biblios", $as_xml, $noxml);
190         }
191     }
192     
193     #
194     # and reindexing everything
195     #
196         print "====================\n";
197     print "REINDEXING zebra\n";
198     print "====================\n";
199         my $record_fmt = ($as_xml) ? 'marcxml' : 'iso2709' ;
200     if ($process_zebraqueue) {
201         do_indexing('biblio', 'delete', "$directory/del_biblios", $reset, $noshadow, $record_fmt)
202             if $num_biblios_deleted;
203         do_indexing('biblio', 'update', "$directory/upd_biblios", $reset, $noshadow, $record_fmt)
204             if $num_biblios_exported;
205     } else {
206         do_indexing('biblio', 'update', "$directory/biblios", $reset, $noshadow, $record_fmt)
207             if $num_biblios_exported;
208     }
209 } else {
210     print "skipping biblios\n";
211 }
212
213 $dbh->commit(); # commit changes to zebraqueue, if any
214
215 print "====================\n";
216 print "CLEANING\n";
217 print "====================\n";
218 if ($keep_export) {
219     print "NOTHING cleaned : the export $directory has been kept.\n";
220     print "You can re-run this script with the -s ";
221     if ($use_tempdir) {
222         print " and -d $directory parameters";
223     } else {
224         print "parameter";
225     }
226     print "\n";
227     print "if you just want to rebuild zebra after changing the record.abs\n";
228     print "or another zebra config file\n";
229 } else {
230     unless ($use_tempdir) {
231         # if we're using a temporary directory
232         # created by File::Temp, it will be removed
233         # automatically.
234         rmtree($directory, 0, 1);
235         print "directory $directory deleted\n";
236     }
237 }
238
239 sub select_zebraqueue_records {
240     my ($record_type, $update_type) = @_;
241
242     my $server = ($record_type eq 'biblio') ? 'biblioserver' : 'authorityserver';
243     my $op = ($update_type eq 'deleted') ? 'recordDelete' : 'specialUpdate';
244
245     my $sth = $dbh->prepare("SELECT DISTINCT biblio_auth_number 
246                              FROM zebraqueue
247                              WHERE server = ?
248                              AND   operation = ?
249                              AND   done = 0");
250     $sth->execute($server, $op);
251     return $sth;
252 }
253
254 sub mark_zebraqueue_done {
255     my ($record_type, $update_type) = @_;
256
257     my $server = ($record_type eq 'biblio') ? 'biblioserver' : 'authorityserver';
258     my $op = ($update_type eq 'deleted') ? 'recordDelete' : 'specialUpdate';
259
260     if ($op eq 'recordDelete') {
261         my $sth = $dbh->prepare("UPDATE zebraqueue SET done = 1
262                                  WHERE id IN (
263                                     SELECT id FROM (
264                                         SELECT z1.id
265                                         FROM zebraqueue z1
266                                         JOIN zebraqueue z2 ON z2.biblio_auth_number = z1.biblio_auth_number
267                                         WHERE z1.done = 0
268                                         AND   z1.server = ?
269                                         AND   z2.done = 0
270                                         AND   z2.server = ?
271                                         AND   z1.operation = ?
272                                     ) d2
273                                  )
274                                 ");
275         $sth->execute($server, $server, $op); # if we've deleted a record, any prior specialUpdates are void
276     } else {
277         my $sth = $dbh->prepare("UPDATE zebraqueue SET done = 1
278                                  WHERE server = ?
279                                  AND   operation = ?
280                                  AND   done = 0");
281         $sth->execute($server, $op); 
282     }
283 }
284
285 sub select_all_authorities {
286     my $sth = $dbh->prepare("select authid from auth_header");
287     $sth->execute();
288     return $sth;
289 }
290
291 sub select_all_biblios {
292     my $sth = $dbh->prepare("SELECT biblionumber FROM biblioitems ORDER BY biblionumber");
293     $sth->execute();
294     return $sth;
295 }
296
297 sub export_marc_records {
298     my ($record_type, $sth, $directory, $as_xml, $noxml) = @_;
299
300     my $num_exported = 0;
301     open (OUT, ">:utf8 ", "$directory/exported_records") or die $!;
302     my $i = 0;
303     while (my ($record_number) = $sth->fetchrow_array) {
304         print ".";
305         print "\r$i" unless ($i++ %100);
306         my ($marc) = get_corrected_marc_record($record_type, $record_number, $noxml);
307         if (defined $marc) {
308             # FIXME - when more than one record is exported and $as_xml is true,
309             # the output file is not valid XML - it's just multiple <record> elements
310             # strung together with no single root element.  zebraidx doesn't seem
311             # to care, though, at least if you're using the GRS-1 filter.  It does
312             # care if you're using the DOM filter, which requires valid XML file(s).
313             print OUT ($as_xml) ? $marc->as_xml_record() : $marc->as_usmarc();
314             $num_exported++;
315         }
316     }
317     print "\nRecords exported: $num_exported\n";
318     close OUT;
319     return $num_exported;
320 }
321
322 sub generate_deleted_marc_records {
323     my ($record_type, $sth, $directory, $as_xml) = @_;
324
325     my $num_exported = 0;
326     open (OUT, ">:utf8 ", "$directory/exported_records") or die $!;
327     my $i = 0;
328     while (my ($record_number) = $sth->fetchrow_array) {
329         print "\r$i" unless ($i++ %100);
330         print ".";
331
332         my $marc = MARC::Record->new();
333         if ($record_type eq 'biblio') {
334             fix_biblio_ids($marc, $record_number, $record_number);
335         } else {
336             fix_authority_id($marc, $record_number);
337         }
338         if (C4::Context->preference("marcflavour") eq "UNIMARC") {
339             fix_unimarc_100($marc);
340         }
341
342         print OUT ($as_xml) ? $marc->as_xml_record() : $marc->as_usmarc();
343         $num_exported++;
344     }
345     print "\nRecords exported: $num_exported\n";
346     close OUT;
347     return $num_exported;
348     
349
350 }
351
352 sub get_corrected_marc_record {
353     my ($record_type, $record_number, $noxml) = @_;
354
355     my $marc = get_raw_marc_record($record_type, $record_number, $noxml); 
356
357     if (defined $marc) {
358         fix_leader($marc);
359         if ($record_type eq 'biblio') {
360             my $succeeded = fix_biblio_ids($marc, $record_number);
361             return unless $succeeded;
362         } else {
363             fix_authority_id($marc, $record_number);
364         }
365         if (C4::Context->preference("marcflavour") eq "UNIMARC") {
366             fix_unimarc_100($marc);
367         }
368     }
369
370     return $marc;
371 }
372
373 sub get_raw_marc_record {
374     my ($record_type, $record_number, $noxml) = @_;
375   
376     my $marc; 
377     if ($record_type eq 'biblio') {
378         if ($noxml) {
379             my $fetch_sth = $dbh->prepare_cached("SELECT marc FROM biblioitems WHERE biblionumber = ?");
380             $fetch_sth->execute($record_number);
381             if (my ($blob) = $fetch_sth->fetchrow_array) {
382                 $marc = MARC::Record->new_from_usmarc($blob);
383             } else {
384                 warn "failed to retrieve biblio $record_number";
385             }
386             $fetch_sth->finish();
387         } else {
388             eval { $marc = GetMarcBiblio($record_number); };
389             if ($@) {
390                 warn "failed to retrieve biblio $record_number";
391                 return;
392             }
393         }
394     } else {
395         eval { $marc = GetAuthority($record_number); };
396         if ($@) {
397             warn "failed to retrieve authority $record_number";
398             return;
399         }
400     }
401     return $marc;
402 }
403
404 sub fix_leader {
405     # FIXME - this routine is suspect
406     # It blanks the Leader/00-05 and Leader/12-16 to
407     # force them to be recalculated correct when
408     # the $marc->as_usmarc() or $marc->as_xml() is called.
409     # But why is this necessary?  It would be a serious bug
410     # in MARC::Record (definitely) and MARC::File::XML (arguably) 
411     # if they are emitting incorrect leader values.
412     my $marc = shift;
413
414     my $leader = $marc->leader;
415     substr($leader,  0, 5) = '     ';
416     substr($leader, 10, 7) = '22     ';
417     $marc->leader(substr($leader, 0, 24));
418 }
419
420 sub fix_biblio_ids {
421     # FIXME - it is essential to ensure that the biblionumber is present,
422     #         otherwise, Zebra will choke on the record.  However, this
423     #         logic belongs in the relevant C4::Biblio APIs.
424     my ($marc, $biblionumber) = @_;
425     my $biblioitemnumber;
426     if (@_) {
427         $biblioitemnumber = shift;
428     } else {    
429         my $sth = $dbh->prepare(
430             "SELECT biblioitemnumber FROM biblioitems WHERE biblionumber=?");
431         $sth->execute($biblionumber);
432         ($biblioitemnumber) = $sth->fetchrow_array;
433         $sth->finish;
434         unless ($biblioitemnumber) {
435             warn "failed to get biblioitemnumber for biblio $biblionumber";
436             return 0;
437         }
438     }
439
440     # FIXME - this is cheating on two levels
441     # 1. C4::Biblio::_koha_marc_update_bib_ids is meant to be an internal function
442     # 2. Making sure that the biblionumber and biblioitemnumber are correct and
443     #    present in the MARC::Record object ought to be part of GetMarcBiblio.
444     #
445     # On the other hand, this better for now than what rebuild_zebra.pl used to
446     # do, which was duplicate the code for inserting the biblionumber 
447     # and biblioitemnumber
448     C4::Biblio::_koha_marc_update_bib_ids($marc, '', $biblionumber, $biblioitemnumber);
449
450     return 1;
451 }
452
453 sub fix_authority_id {
454     # FIXME - as with fix_biblio_ids, the authid must be present
455     #         for Zebra's sake.  However, this really belongs
456     #         in C4::AuthoritiesMarc.
457     my ($marc, $authid) = @_;
458     unless ($marc->field('001') and $marc->field('001')->data() eq $authid){
459         $marc->delete_field($marc->field('001'));
460         $marc->insert_fields_ordered(MARC::Field->new('001',$authid));
461     }
462 }
463
464 sub fix_unimarc_100 {
465     # FIXME - again, if this is necessary, it belongs in C4::AuthoritiesMarc.
466     my $marc = shift;
467
468     my $string;
469     if ( length($marc->subfield( 100, "a" )) == 35 ) {
470         $string = $marc->subfield( 100, "a" );
471         my $f100 = $marc->field(100);
472         $marc->delete_field($f100);
473     }
474     else {
475         $string = POSIX::strftime( "%Y%m%d", localtime );
476         $string =~ s/\-//g;
477         $string = sprintf( "%-*s", 35, $string );
478     }
479     substr( $string, 22, 6, "frey50" );
480     unless ( length($marc->subfield( 100, "a" )) == 35 ) {
481         $marc->delete_field($marc->field(100));
482         $marc->insert_grouped_field(MARC::Field->new( 100, "", "", "a" => $string ));
483     }
484 }
485
486 sub do_indexing {
487     my ($record_type, $op, $record_dir, $reset_index, $noshadow, $record_format) = @_;
488
489     my $zebra_server  = ($record_type eq 'biblio') ? 'biblioserver' : 'authorityserver';
490     my $zebra_db_name = ($record_type eq 'biblio') ? 'biblios' : 'authorities';
491     my $zebra_config  = C4::Context->zebraconfig($zebra_server)->{'config'};
492     my $zebra_db_dir  = C4::Context->zebraconfig($zebra_server)->{'directory'};
493
494     system("zebraidx -c $zebra_config -g $record_format -d $zebra_db_name init") if $reset_index;
495     system("zebraidx -c $zebra_config $noshadow -g $record_format -d $zebra_db_name $op $record_dir");
496     system("zebraidx -c $zebra_config -g $record_format -d $zebra_db_name commit") unless $noshadow;
497
498 }
499
500 sub print_usage {
501     print <<_USAGE_;
502 $0: reindex MARC bibs and/or authorities in Zebra.
503
504 Use this batch job to reindex all biblio or authority
505 records in your Koha database.  This job is useful
506 only if you are using Zebra; if you are using the 'NoZebra'
507 mode, this job should not be used.
508
509 Parameters:
510     -b                      index bibliographic records
511
512     -a                      index authority records
513
514     -z                      select only updated and deleted
515                             records marked in the zebraqueue
516                             table.  Cannot be used with -r
517                             or -s.
518
519     -r                      clear Zebra index before
520                             adding records to index
521
522     -d                      Temporary directory for indexing.
523                             If not specified, one is automatically
524                             created.  The export directory
525                             is automatically deleted unless
526                             you supply the -k switch.
527
528     -k                      Do not delete export directory.
529
530     -s                      Skip export.  Used if you have
531                             already exported the records 
532                             in a previous run.
533
534     -noxml                  index from ISO MARC blob
535                             instead of MARC XML.  This
536                             option is recommended only
537                             for advanced user.
538
539     -x                      export and index as xml instead of is02709 (biblios only).
540                             use this if you might have records > 99,999 chars,
541                                                         
542     -w                      skip shadow indexing for this batch
543
544     -munge-config           Deprecated option to try
545                             to fix Zebra config files.
546     --help or -h            show this message.
547 _USAGE_
548 }
549
550 # FIXME: the following routines are deprecated and 
551 # will be removed once it is determined whether
552 # a script to fix Zebra configuration files is 
553 # actually needed.
554 sub munge_config {
555 #
556 # creating zebra-biblios.cfg depending on system
557 #
558
559 # getting zebraidx directory
560 my $zebraidxdir;
561 foreach (qw(/usr/local/bin/zebraidx
562         /opt/bin/zebraidx
563         /usr/bin/zebraidx
564         )) {
565     if ( -f $_ ) {
566         $zebraidxdir=$_;
567     }
568 }
569
570 unless ($zebraidxdir) {
571     print qq|
572     ERROR: could not find zebraidx directory
573     ERROR: Either zebra is not installed,
574     ERROR: or it's in a directory I don't checked.
575     ERROR: do a which zebraidx and edit this file to add the result you get
576 |;
577     exit;
578 }
579 $zebraidxdir =~ s/\/bin\/.*//;
580 print "Info : zebra is in $zebraidxdir \n";
581
582 # getting modules directory
583 my $modulesdir;
584 foreach (qw(/usr/local/lib/idzebra-2.0/modules/mod-grs-xml.so
585             /usr/local/lib/idzebra/modules/mod-grs-xml.so
586             /usr/lib/idzebra/modules/mod-grs-xml.so
587             /usr/lib/idzebra-2.0/modules/mod-grs-xml.so
588         )) {
589     if ( -f $_ ) {
590         $modulesdir=$_;
591     }
592 }
593
594 unless ($modulesdir) {
595     print qq|
596     ERROR: could not find mod-grs-xml.so directory
597     ERROR: Either zebra is not properly compiled (libxml2 is not setup and you don t have mod-grs-xml.so,
598     ERROR: or it's in a directory I don't checked.
599     ERROR: find where mod-grs-xml.so is and edit this file to add the result you get
600 |;
601     exit;
602 }
603 $modulesdir =~ s/\/modules\/.*//;
604 print "Info: zebra modules dir : $modulesdir\n";
605
606 # getting tab directory
607 my $tabdir;
608 foreach (qw(/usr/local/share/idzebra/tab/explain.att
609             /usr/local/share/idzebra-2.0/tab/explain.att
610             /usr/share/idzebra/tab/explain.att
611             /usr/share/idzebra-2.0/tab/explain.att
612         )) {
613     if ( -f $_ ) {
614         $tabdir=$_;
615     }
616 }
617
618 unless ($tabdir) {
619     print qq|
620     ERROR: could not find explain.att directory
621     ERROR: Either zebra is not properly compiled,
622     ERROR: or it's in a directory I don't checked.
623     ERROR: find where explain.att is and edit this file to add the result you get
624 |;
625     exit;
626 }
627 $tabdir =~ s/\/tab\/.*//;
628 print "Info: tab dir : $tabdir\n";
629
630 #
631 # AUTHORITIES creating directory structure
632 #
633 my $created_dir_or_file = 0;
634 if ($authorities) {
635     print "====================\n";
636     print "checking directories & files for authorities\n";
637     print "====================\n";
638     unless (-d "$authorityserverdir") {
639         system("mkdir -p $authorityserverdir");
640         print "Info: created $authorityserverdir\n";
641         $created_dir_or_file++;
642     }
643     unless (-d "$authorityserverdir/lock") {
644         mkdir "$authorityserverdir/lock";
645         print "Info: created $authorityserverdir/lock\n";
646         $created_dir_or_file++;
647     }
648     unless (-d "$authorityserverdir/register") {
649         mkdir "$authorityserverdir/register";
650         print "Info: created $authorityserverdir/register\n";
651         $created_dir_or_file++;
652     }
653     unless (-d "$authorityserverdir/shadow") {
654         mkdir "$authorityserverdir/shadow";
655         print "Info: created $authorityserverdir/shadow\n";
656         $created_dir_or_file++;
657     }
658     unless (-d "$authorityserverdir/tab") {
659         mkdir "$authorityserverdir/tab";
660         print "Info: created $authorityserverdir/tab\n";
661         $created_dir_or_file++;
662     }
663     unless (-d "$authorityserverdir/key") {
664         mkdir "$authorityserverdir/key";
665         print "Info: created $authorityserverdir/key\n";
666         $created_dir_or_file++;
667     }
668     
669     unless (-d "$authorityserverdir/etc") {
670         mkdir "$authorityserverdir/etc";
671         print "Info: created $authorityserverdir/etc\n";
672         $created_dir_or_file++;
673     }
674     
675     #
676     # AUTHORITIES : copying mandatory files
677     #
678     # the record model, depending on marc flavour
679     unless (-f "$authorityserverdir/tab/record.abs") {
680         if (C4::Context->preference("marcflavour") eq "UNIMARC") {
681             system("cp -f $kohadir/etc/zebradb/marc_defs/unimarc/authorities/record.abs $authorityserverdir/tab/record.abs");
682             print "Info: copied record.abs for UNIMARC\n";
683         } else {
684             system("cp -f $kohadir/etc/zebradb/marc_defs/marc21/authorities/record.abs $authorityserverdir/tab/record.abs");
685             print "Info: copied record.abs for USMARC\n";
686         }
687         $created_dir_or_file++;
688     }
689     unless (-f "$authorityserverdir/tab/sort-string-utf.chr") {
690         system("cp -f $kohadir/etc/zebradb/lang_defs/fr/sort-string-utf.chr $authorityserverdir/tab/sort-string-utf.chr");
691         print "Info: copied sort-string-utf.chr\n";
692         $created_dir_or_file++;
693     }
694     unless (-f "$authorityserverdir/tab/word-phrase-utf.chr") {
695         system("cp -f $kohadir/etc/zebradb/lang_defs/fr/sort-string-utf.chr $authorityserverdir/tab/word-phrase-utf.chr");
696         print "Info: copied word-phase-utf.chr\n";
697         $created_dir_or_file++;
698     }
699     unless (-f "$authorityserverdir/tab/auth1.att") {
700         system("cp -f $kohadir/etc/zebradb/authorities/etc/bib1.att $authorityserverdir/tab/auth1.att");
701         print "Info: copied auth1.att\n";
702         $created_dir_or_file++;
703     }
704     unless (-f "$authorityserverdir/tab/default.idx") {
705         system("cp -f $kohadir/etc/zebradb/etc/default.idx $authorityserverdir/tab/default.idx");
706         print "Info: copied default.idx\n";
707         $created_dir_or_file++;
708     }
709     
710     unless (-f "$authorityserverdir/etc/ccl.properties") {
711 #         system("cp -f $kohadir/etc/zebradb/ccl.properties ".C4::Context->zebraconfig('authorityserver')->{ccl2rpn});
712         system("cp -f $kohadir/etc/zebradb/ccl.properties $authorityserverdir/etc/ccl.properties");
713         print "Info: copied ccl.properties\n";
714         $created_dir_or_file++;
715     }
716     unless (-f "$authorityserverdir/etc/pqf.properties") {
717 #         system("cp -f $kohadir/etc/zebradb/pqf.properties ".C4::Context->zebraconfig('authorityserver')->{ccl2rpn});
718         system("cp -f $kohadir/etc/zebradb/pqf.properties $authorityserverdir/etc/pqf.properties");
719         print "Info: copied pqf.properties\n";
720         $created_dir_or_file++;
721     }
722     
723     #
724     # AUTHORITIES : copying mandatory files
725     #
726     unless (-f C4::Context->zebraconfig('authorityserver')->{config}) {
727     open ZD,">:utf8 ",C4::Context->zebraconfig('authorityserver')->{config};
728     print ZD "
729 # generated by KOHA/misc/migration_tools/rebuild_zebra.pl 
730 profilePath:\${srcdir:-.}:$authorityserverdir/tab/:$tabdir/tab/:\${srcdir:-.}/tab/
731
732 encoding: UTF-8
733 # Files that describe the attribute sets supported.
734 attset: auth1.att
735 attset: explain.att
736 attset: gils.att
737
738 modulePath:$modulesdir/modules/
739 # Specify record type
740 iso2709.recordType:grs.marcxml.record
741 recordType:grs.xml
742 recordId: (auth1,Local-Number)
743 storeKeys:1
744 storeData:1
745
746
747 # Lock File Area
748 lockDir: $authorityserverdir/lock
749 perm.anonymous:r
750 perm.kohaadmin:rw
751 register: $authorityserverdir/register:4G
752 shadow: $authorityserverdir/shadow:4G
753
754 # Temp File area for result sets
755 setTmpDir: $authorityserverdir/tmp
756
757 # Temp File area for index program
758 keyTmpDir: $authorityserverdir/key
759
760 # Approx. Memory usage during indexing
761 memMax: 40M
762 rank:rank-1
763     ";
764         print "Info: creating zebra-authorities.cfg\n";
765         $created_dir_or_file++;
766     }
767     
768     if ($created_dir_or_file) {
769         print "Info: created : $created_dir_or_file directories & files\n";
770     } else {
771         print "Info: file & directories OK\n";
772     }
773     
774 }
775 if ($biblios) {
776     print "====================\n";
777     print "checking directories & files for biblios\n";
778     print "====================\n";
779     
780     #
781     # BIBLIOS : creating directory structure
782     #
783     unless (-d "$biblioserverdir") {
784         system("mkdir -p $biblioserverdir");
785         print "Info: created $biblioserverdir\n";
786         $created_dir_or_file++;
787     }
788     unless (-d "$biblioserverdir/lock") {
789         mkdir "$biblioserverdir/lock";
790         print "Info: created $biblioserverdir/lock\n";
791         $created_dir_or_file++;
792     }
793     unless (-d "$biblioserverdir/register") {
794         mkdir "$biblioserverdir/register";
795         print "Info: created $biblioserverdir/register\n";
796         $created_dir_or_file++;
797     }
798     unless (-d "$biblioserverdir/shadow") {
799         mkdir "$biblioserverdir/shadow";
800         print "Info: created $biblioserverdir/shadow\n";
801         $created_dir_or_file++;
802     }
803     unless (-d "$biblioserverdir/tab") {
804         mkdir "$biblioserverdir/tab";
805         print "Info: created $biblioserverdir/tab\n";
806         $created_dir_or_file++;
807     }
808     unless (-d "$biblioserverdir/key") {
809         mkdir "$biblioserverdir/key";
810         print "Info: created $biblioserverdir/key\n";
811         $created_dir_or_file++;
812     }
813     unless (-d "$biblioserverdir/etc") {
814         mkdir "$biblioserverdir/etc";
815         print "Info: created $biblioserverdir/etc\n";
816         $created_dir_or_file++;
817     }
818     
819     #
820     # BIBLIOS : copying mandatory files
821     #
822     # the record model, depending on marc flavour
823     unless (-f "$biblioserverdir/tab/record.abs") {
824         if (C4::Context->preference("marcflavour") eq "UNIMARC") {
825             system("cp -f $kohadir/etc/zebradb/marc_defs/unimarc/biblios/record.abs $biblioserverdir/tab/record.abs");
826             print "Info: copied record.abs for UNIMARC\n";
827         } else {
828             system("cp -f $kohadir/etc/zebradb/marc_defs/marc21/biblios/record.abs $biblioserverdir/tab/record.abs");
829             print "Info: copied record.abs for USMARC\n";
830         }
831         $created_dir_or_file++;
832     }
833     unless (-f "$biblioserverdir/tab/sort-string-utf.chr") {
834         system("cp -f $kohadir/etc/zebradb/lang_defs/fr/sort-string-utf.chr $biblioserverdir/tab/sort-string-utf.chr");
835         print "Info: copied sort-string-utf.chr\n";
836         $created_dir_or_file++;
837     }
838     unless (-f "$biblioserverdir/tab/word-phrase-utf.chr") {
839         system("cp -f $kohadir/etc/zebradb/lang_defs/fr/sort-string-utf.chr $biblioserverdir/tab/word-phrase-utf.chr");
840         print "Info: copied word-phase-utf.chr\n";
841         $created_dir_or_file++;
842     }
843     unless (-f "$biblioserverdir/tab/bib1.att") {
844         system("cp -f $kohadir/etc/zebradb/biblios/etc/bib1.att $biblioserverdir/tab/bib1.att");
845         print "Info: copied bib1.att\n";
846         $created_dir_or_file++;
847     }
848     unless (-f "$biblioserverdir/tab/default.idx") {
849         system("cp -f $kohadir/etc/zebradb/etc/default.idx $biblioserverdir/tab/default.idx");
850         print "Info: copied default.idx\n";
851         $created_dir_or_file++;
852     }
853     unless (-f "$biblioserverdir/etc/ccl.properties") {
854 #         system("cp -f $kohadir/etc/zebradb/ccl.properties ".C4::Context->zebraconfig('biblioserver')->{ccl2rpn});
855         system("cp -f $kohadir/etc/zebradb/ccl.properties $biblioserverdir/etc/ccl.properties");
856         print "Info: copied ccl.properties\n";
857         $created_dir_or_file++;
858     }
859     unless (-f "$biblioserverdir/etc/pqf.properties") {
860 #         system("cp -f $kohadir/etc/zebradb/pqf.properties ".C4::Context->zebraconfig('biblioserver')->{ccl2rpn});
861         system("cp -f $kohadir/etc/zebradb/pqf.properties $biblioserverdir/etc/pqf.properties");
862         print "Info: copied pqf.properties\n";
863         $created_dir_or_file++;
864     }
865     
866     #
867     # BIBLIOS : copying mandatory files
868     #
869     unless (-f C4::Context->zebraconfig('biblioserver')->{config}) {
870     open ZD,">:utf8 ",C4::Context->zebraconfig('biblioserver')->{config};
871     print ZD "
872 # generated by KOHA/misc/migrtion_tools/rebuild_zebra.pl 
873 profilePath:\${srcdir:-.}:$biblioserverdir/tab/:$tabdir/tab/:\${srcdir:-.}/tab/
874
875 encoding: UTF-8
876 # Files that describe the attribute sets supported.
877 attset:bib1.att
878 attset:explain.att
879 attset:gils.att
880
881 modulePath:$modulesdir/modules/
882 # Specify record type
883 iso2709.recordType:grs.marcxml.record
884 recordType:grs.xml
885 recordId: (bib1,Local-Number)
886 storeKeys:1
887 storeData:1
888
889
890 # Lock File Area
891 lockDir: $biblioserverdir/lock
892 perm.anonymous:r
893 perm.kohaadmin:rw
894 register: $biblioserverdir/register:4G
895 shadow: $biblioserverdir/shadow:4G
896
897 # Temp File area for result sets
898 setTmpDir: $biblioserverdir/tmp
899
900 # Temp File area for index program
901 keyTmpDir: $biblioserverdir/key
902
903 # Approx. Memory usage during indexing
904 memMax: 40M
905 rank:rank-1
906     ";
907         print "Info: creating zebra-biblios.cfg\n";
908         $created_dir_or_file++;
909     }
910     
911     if ($created_dir_or_file) {
912         print "Info: created : $created_dir_or_file directories & files\n";
913     } else {
914         print "Info: file & directories OK\n";
915     }
916     
917 }
918 }