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