/[webpac2]/branches/Sack/run.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /branches/Sack/run.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 606 by dpavlin, Tue Aug 1 13:59:47 2006 UTC revision 1246 by dpavlin, Wed Jul 22 09:23:36 2009 UTC
# Line 7  use File::Temp qw/tempdir/; Line 7  use File::Temp qw/tempdir/;
7  use lib './lib';  use lib './lib';
8    
9  use WebPAC::Common 0.02;  use WebPAC::Common 0.02;
10  use WebPAC::Lookup 0.03;  use WebPAC::Parser 0.08;
11  use WebPAC::Input 0.07;  use WebPAC::Input 0.16;
12  use WebPAC::Store 0.03;  use WebPAC::Store 0.15;
13  use WebPAC::Normalize 0.11;  use WebPAC::Normalize 0.22;
14  use WebPAC::Output::TT;  #use WebPAC::Output::TT;
15  use WebPAC::Validate;  use WebPAC::Validate 0.11;
16  use WebPAC::Output::MARC;  use WebPAC::Output::MARC;
17  use YAML qw/LoadFile/;  use WebPAC::Config;
18  use Getopt::Long;  use Getopt::Long;
19  use File::Path;  use File::Path;
20  use Time::HiRes qw/time/;  use Time::HiRes qw/time/;
21  use File::Slurp;  use File::Slurp;
22  use Data::Dump qw/dump/;  use Data::Dump qw/dump/;
23  use Storable qw/dclone/;  use Storable qw/dclone/;
24    use Pod::Usage qw/pod2usage/;
25    use LWP::Simple qw//;
26    
 use Proc::Queue size => 1;  
27  use POSIX ":sys_wait_h"; # imports WNOHANG  use POSIX ":sys_wait_h"; # imports WNOHANG
28    
29  =head1 NAME  =head1 NAME
# Line 31  run.pl - start WebPAC indexing Line 32  run.pl - start WebPAC indexing
32    
33  B<this command will probably go away. Don't get used to it!>  B<this command will probably go away. Don't get used to it!>
34    
35  Options:  =head1 OPTIONS
36    
37  =over 4  =over 4
38    
# Line 60  path to YAML configuration file Line 61  path to YAML configuration file
61    
62  =item --stats  =item --stats
63    
64  disable indexing and dump statistics about field and subfield  disable indexing, modify_* in configuration and dump statistics about field
65  usage for each input  and subfield usage for each input
66    
67  =item --validate path/to/validation_file  =item --validate path/to/validation_file
68    
69  turn on extra validation of imput records, see L<WebPAC::Validation>  turn on extra validation of imput records, see L<WebPAC::Validation>
70    
71  =item --marc-normalize conf/normalize/mapping.pl  You can use special variables C<$database> and $C<$input> in this parametar
72    like C<--validate 'conf/validate/$database-$input'> to construct filename
73    
74  This option specifies normalisation file for MARC creation  =item --validate-delimiters path/to/validate_delimiters_file
75    
76  =item --marc-output out/marc/test.marc  this option is used with C<--validate> to turn on extra validation of
77    delimiters. If file is non existant, it will be created on first run.
78    
79  Optional path to output file  =item --marc-generate
80    
81    Generate MARC file. This will automatically be on if file contains C<marc*> directives.
82    You can use this option as C<--no-marc-generate> to disable MARC generation.
83    
84  =item --marc-lint  =item --marc-lint
85    
86  By default turned on if C<--marc-normalize> is used. You can disable lint  By default turned on if normalisation file has C<marc*> directives. You can disable lint
87  messages with C<--no-marc-lint>.  messages with C<--no-marc-lint>.
88    
89  =item --marc-dump  =item --marc-dump
# Line 89  Force dump or input and marc record for Line 95  Force dump or input and marc record for
95  Run databases in parallel (aproximatly same as number of processors in  Run databases in parallel (aproximatly same as number of processors in
96  machine if you want to use full load)  machine if you want to use full load)
97    
98    =item --only-links
99    
100    Create just links
101    
102    =item --merge
103    
104    Create merged index of databases which have links
105    
106    =item --mirror http://www.example.com
107    
108    Tries to download input path files from mirror URI
109    
110  =back  =back
111    
112  =cut  =cut
# Line 97  my $offset; Line 115  my $offset;
115  my $limit;  my $limit;
116    
117  my $clean = 0;  my $clean = 0;
118  my $config = 'conf/config.yml';  my $config_path;
119  my $debug = 0;  my $debug = 0;
120  my $only_filter;  my $only_filter;
121  my $stats = 0;  my $stats = 0;
122  my $validate_path;  my $validate_path;
123  my ($marc_normalize, $marc_output);  my $validate_delimiters_path;
124    my $marc_generate = 1;
125  my $marc_lint = 1;  my $marc_lint = 1;
126  my $marc_dump = 0;  my $marc_dump = 0;
   
127  my $parallel = 0;  my $parallel = 0;
128    my $only_links = 0;
129    my $merge = 0;
130    my $mirror;
131    my $help;
132    
133    my $log = _new WebPAC::Common()->_get_logger();
134    
135  GetOptions(  GetOptions(
136          "limit=i" => \$limit,          "limit=i" => \$limit,
# Line 114  GetOptions( Line 138  GetOptions(
138          "clean" => \$clean,          "clean" => \$clean,
139          "one=s" => \$only_filter,          "one=s" => \$only_filter,
140          "only=s" => \$only_filter,          "only=s" => \$only_filter,
141          "config" => \$config,          "config=s" => \$config_path,
142          "debug+" => \$debug,          "debug+" => \$debug,
143          "stats" => \$stats,          "stats" => \$stats,
144          "validate=s" => \$validate_path,          "validate=s" => \$validate_path,
145          "marc-normalize=s" => \$marc_normalize,          "validate-delimiters=s" => \$validate_delimiters_path,
146          "marc-output=s" => \$marc_output,          "marc-generate!" => \$marc_generate,
147          "marc-lint!" => \$marc_lint,          "marc-lint!" => \$marc_lint,
148          "marc-dump!" => \$marc_dump,          "marc-dump!" => \$marc_dump,
149          "parallel=i" => \$parallel,          "parallel=i" => \$parallel,
150            "only-links!" => \$only_links,
151            "merge" => \$merge,
152            "mirror=s" => \$mirror,
153            "help" => \$help,
154  );  );
155    
156  $config = LoadFile($config);  $marc_generate = 0 if ( $validate_delimiters_path );
157    
158  print "config = ",dump($config) if ($debug);  pod2usage(-verbose => 2) if ($help);
159    
160  die "no databases in config file!\n" unless ($config->{databases});  my $config = new WebPAC::Config( path => $config_path );
161    
162    WebPAC::Normalize::_debug( $debug - 1 ) if $debug > 1;
163    
164    #print "config = ",dump($config) if ($debug);
165    
166    die "no databases in config file!\n" unless ($config->databases);
167    
 my $log = _new WebPAC::Common()->_get_logger();  
168  $log->info( "-" x 79 );  $log->info( "-" x 79 );
169    
170    my $log_file = 'log';
171    
172    if (-e $log_file ) {    # && -s $log_file > 5 * 1024 * 1024) {
173            $log->info("moved old log with ", -s $log_file, " bytes to '${log_file}.old'");
174            rename $log_file, "${log_file}.old" || $log->logwarn("can't rename $log_file to ${log_file}.old: $!");
175    }
176    
177    my $estcmd_fh;
178    my $estcmd_path = './estcmd-merge.sh';
179    if ($merge) {
180            open($estcmd_fh, '>', $estcmd_path) || $log->logdie("can't open $estcmd_path: $!");
181            print $estcmd_fh 'cd /data/estraier/_node/ || exit 1',$/;
182            print $estcmd_fh 'sudo /etc/init.d/hyperestraier stop',$/;
183            $log->info("created merge batch file $estcmd_path");
184    }
185    
186  my $validate;  my $validate;
187  $validate = new WebPAC::Validate(  $validate = new WebPAC::Validate(
188          path => $validate_path,          delimiters => $config->webpac('delimiters'),
189  ) if ($validate_path);  ) if ($validate_path || $validate_delimiters_path);
190    
191  my $use_indexer = $config->{use_indexer} || 'hyperestraier';  my $use_indexer = $config->use_indexer;
192    $stats ||= $validate;
193  if ($stats) {  if ($stats) {
194          $log->debug("option --stats disables update of indexing engine...");          $log->debug("disabled indexing for stats collection");
195          $use_indexer = undef;          $use_indexer = undef;
196  } else {  } elsif ( $use_indexer ) {
197          $log->info("using $use_indexer indexing engine...");          $log->info("using $use_indexer indexing engine...");
198  }  }
199    
200  # disable indexing when creating marc  # parse normalize files and create source files for lookup and normalization
201  $use_indexer = undef if ($marc_normalize);  
202    my ($only_database,$only_input) = split(m#/#, $only_filter) if $only_filter;
203    
204    my $parser = new WebPAC::Parser(
205            config => $config,
206            only_database => $only_database,
207            only_input => $only_input,
208    );
209    
210  my $total_rows = 0;  my $total_rows = 0;
211  my $start_t = time();  my $start_t = time();
212    
213  my @links;  my @links;
 my $indexer;  
214    
215  if ($parallel) {  if ($parallel) {
216            eval 'use Proc::Queue size => 1;';
217            die $@ if $@;
218          $log->info("Using $parallel processes for speedup");          $log->info("Using $parallel processes for speedup");
219          Proc::Queue::size($parallel);          Proc::Queue::size($parallel);
220  }  }
221    
222  while (my ($database, $db_config) = each %{ $config->{databases} }) {  sub create_ds_config {
223            my ($db_config, $database, $input, $mfn) = @_;
224            my $c = dclone( $db_config );
225            $c->{_} = $database || $log->logconfess("need database");
226            $c->{_mfn} = $mfn || $log->logconfess("need mfn");
227            $c->{input} = $input || $log->logconfess("need input");
228            return $c;
229    }
230    
231    foreach my $database ( sort keys %{ $config->databases } ) {
232            my $db_config = $config->databases->{$database};
233    
         my ($only_database,$only_input) = split(m#/#, $only_filter) if ($only_filter);  
234          next if ($only_database && $database !~ m/$only_database/i);          next if ($only_database && $database !~ m/$only_database/i);
235    
236          if ($parallel) {          if ($parallel) {
# Line 175  while (my ($database, $db_config) = each Line 242  while (my ($database, $db_config) = each
242                  }                  }
243          }          }
244    
245          if ($use_indexer) {          my $indexer;
246                  my $indexer_config = $config->{$use_indexer} || $log->logdie("can't find '$use_indexer' part in confguration");          if ($use_indexer && $parser->have_rules( 'search', $database )) {
247    
248                    my $cfg_name = $use_indexer;
249                    $cfg_name =~ s/\-.*$//;
250    
251                    my $indexer_config = $config->get( $cfg_name ) || $log->logdie("can't find '$cfg_name' part in confguration");
252                  $indexer_config->{database} = $database;                  $indexer_config->{database} = $database;
253                  $indexer_config->{clean} = $clean;                  $indexer_config->{clean} = $clean;
254                  $indexer_config->{label} = $db_config->{name};                  $indexer_config->{label} = $db_config->{name};
255    
256                    # force clean if database has links
257                    $indexer_config->{clean} = 1 if ($db_config->{links});
258    
259                  if ($use_indexer eq 'hyperestraier') {                  if ($use_indexer eq 'hyperestraier') {
260    
261                          # open Hyper Estraier database                          # open Hyper Estraier database
262                          use WebPAC::Output::Estraier '0.10';                          require WebPAC::Output::Estraier;
263                          $indexer = new WebPAC::Output::Estraier( %{ $indexer_config } );                          $indexer = new WebPAC::Output::Estraier( %{ $indexer_config } );
264                                    
265                    } elsif ($use_indexer eq 'hyperestraier-native') {
266    
267                            # open Hyper Estraier database
268                            require WebPAC::Output::EstraierNative;
269                            $indexer = new WebPAC::Output::EstraierNative( %{ $indexer_config } );
270    
271                  } elsif ($use_indexer eq 'kinosearch') {                  } elsif ($use_indexer eq 'kinosearch') {
272    
273                          # open KinoSearch                          die "no longer supported";
                         use WebPAC::Output::KinoSearch;  
                         $indexer_config->{clean} = 1 unless (-e $indexer_config->{index_path});  
                         $indexer = new WebPAC::Output::KinoSearch( %{ $indexer_config } );  
274    
275                  } else {                  } else {
276                          $log->logdie("unknown use_indexer: $use_indexer");                          $log->logdie("unknown use_indexer: $use_indexer");
277                  }                  }
278    
279                  $log->logide("can't continue without valid indexer") unless ($indexer);                  $log->logdie("can't continue without valid indexer") unless ($indexer);
280          }          }
281    
282    
283          #          #
284            # store Hyper Estraier links to other databases
285            #
286            if (ref($db_config->{links}) eq 'ARRAY' && $use_indexer) {
287                    foreach my $link (@{ $db_config->{links} }) {
288                            if ($use_indexer eq 'hyperestraier') {
289                                    if ($merge) {
290                                            print $estcmd_fh 'sudo -u www-data estcmd merge ' . $database . ' ' . $link->{to},$/;
291                                    } else {
292                                            $log->info("saving link $database -> $link->{to} [$link->{credit}]");
293                                            push @links, sub {
294                                                    $log->info("adding link $database -> $link->{to} [$link->{credit}]");
295                                                    $indexer->add_link(
296                                                            from => $database,
297                                                            to => $link->{to},
298                                                            credit => $link->{credit},
299                                                    );
300                                            };
301                                    }
302                            } else {
303                                    $log->warn("NOT IMPLEMENTED WITH $use_indexer: adding link $database -> $link->{to} [$link->{credit}]");
304                            }
305                    }
306            }
307            next if ($only_links);
308    
309    
310            #
311          # now WebPAC::Store          # now WebPAC::Store
312          #          #
313          my $abs_path = abs_path($0);          my $store = new WebPAC::Store({
314          $abs_path =~ s#/[^/]*$#/#;                  debug => $debug,
315            });
316    
         my $db_path = $config->{webpac}->{db_path} . '/' . $database;  
317    
318          if ($clean) {          #
319                  $log->info("creating new database '$database' in $db_path");          # prepare output
320                  rmtree( $db_path ) || $log->warn("can't remove $db_path: $!");          #
321          } else {          my @outputs = force_array( $db_config->{output}, sub {
322                  $log->info("working on database '$database' in $db_path");                  $log->error("Database $database doesn't have any outputs defined. Do you want to remove it from configuration?" );
323            } );
324    
325            my @output_modules;
326    
327            foreach my $output ( @outputs ) {
328    
329    #warn '## output = ',dump( $output );
330    
331                    my $module = $output->{module} || $log->logdie("need module in output section of $database");
332                    $module = 'WebPAC::Output::' . $module unless $module =~ m/::/;
333            
334                    $log->debug("loading output module $module");
335                    eval "require $module";
336    
337                    # add database to arugemnts for output filter
338                    $output->{database} = $database;
339                    $output->{clean} = $clean;
340    
341                    $log->debug("calling $module->new(",dump( $output ),")");
342                    my $out = new $module->new( $output );
343                    if ( $out->init ) {
344                            push @output_modules, $out;
345                    } else {
346                            $log->warn("SKIPPED $module");
347                    }
348          }          }
349    
         my $db = new WebPAC::Store(  
                 path => $db_path,  
                 database => $database,  
                 debug => $debug,  
         );  
   
350    
351          #          #
352          # now, iterate through input formats          # now, iterate through input formats
353          #          #
354    
355          my @inputs;  
356          if (ref($db_config->{input}) eq 'ARRAY') {          my @inputs = force_array( $db_config->{input}, sub {
                 @inputs = @{ $db_config->{input} };  
         } elsif ($db_config->{input}) {  
                 push @inputs, $db_config->{input};  
         } else {  
357                  $log->info("database $database doesn't have inputs defined");                  $log->info("database $database doesn't have inputs defined");
358          }          } );
359    
360          my @supported_inputs = keys %{ $config->{webpac}->{inputs} };          if ( -e 'out/debug' ) { # FIXME flag?
361                    my $out;
362                    foreach my $i ( @inputs ) {
363                            warn dump( $i );
364                            next unless defined $i->{normalize};
365                            warn dump( $i->{normalize} );
366                            foreach my $normalize ( @{ $i->{normalize} } ) {
367                                    my $path = $normalize->{path};
368                                    $out .= qq/\n##\n## $path\n##\n\n/;
369                                    $out .= read_file( $path );
370                            }
371                    }
372                    my $all = "out/debug/all-normalize.pl";
373                    write_file( $all, $out );
374                    warn "### all normalize for this input saved to: $all";
375            };
376    
377          foreach my $input (@inputs) {          foreach my $input (@inputs) {
378    
379                  next if ($only_input && ($input->{name} !~ m#$only_input#i && $input->{type} !~ m#$only_input#i));                  my $input_name = $input->{name} || $log->logdie("input without a name isn't valid: ",dump($input));
380    
381                    if ( $input->{skip} ) {
382                            $log->info("skip $input_name");
383                            next;
384                    }
385    
386                    next if defined $only_input && $input_name !~ m#$only_input#i;
387    
388                  my $type = lc($input->{type});                  my $type = lc($input->{type});
389    
390                  die "I know only how to handle input types ", join(",", @supported_inputs), " not '$type'!\n" unless (grep(/$type/, @supported_inputs));                  # FIXME check if input module exists
391                    my $input_module = $input->{module};
392    
393                  my $lookup;                  if ( ! $input_module ) {
394                  if ($input->{lookup}) {                          if ( grep(/$type/, $config->webpac('inputs')) ) {
395                          $lookup = new WebPAC::Lookup(                                  $input_module = $config->webpac('inputs')->{$type};
396                                  lookup_file => $input->{lookup},                          } else {
397                          );                                  $log->logdie("I know only how to handle input types ", join(",", $config->webpac('inputs') ), " not '$type'!" );
398                          delete( $input->{lookup} );                          }
399                  }                  }
400    
401                  my $input_module = $config->{webpac}->{inputs}->{$type};                  my @lookups = $parser->have_lookup_create($database, $input);
402    
403                  $log->info("working on input '$input->{name}' in $input->{path} [type: $input->{type}] using $input_module",                  $log->info("working on $database/$input_name with $input_module on $input->{path}",
404                          $input->{lookup} ? "lookup '$input->{lookup}'" : ""                          @lookups ? " creating lookups: ".join(", ", @lookups) : ""
405                  );                  );
406    
407                    if ($stats) {
408                            # disable modification of records if --stats is in use
409                            delete($input->{modify_records});
410                            delete($input->{modify_file});
411                    }
412    
413                    if ( $mirror ) {
414                            my $path = $input->{path} || die "no input path in ",dump( $input );
415    
416                            my $base = $path;
417                            $base =~ s{/[^/]+$}{};
418                            mkpath $base unless -e $base;
419    
420                            my $rc = LWP::Simple::mirror( "$mirror/$path", $path );
421                            if (LWP::Simple::is_error( $rc )) {
422                                    die "can't mirror $mirror/$path -> $path [$rc]";
423                            } else {
424                                    $log->info( "mirror ", $path, " [$rc] ", -s $path, " bytes" );
425                            }
426                            
427                    }
428    
429                  my $input_db = new WebPAC::Input(                  my $input_db = new WebPAC::Input(
430                          module => $input_module,                          module => $input_module,
                         encoding => $config->{webpac}->{webpac_encoding},  
431                          limit => $limit || $input->{limit},                          limit => $limit || $input->{limit},
432                          offset => $offset,                          offset => $offset,
                         lookup_coderef => sub {  
                                 my $rec = shift || return;  
                                 $lookup->add( $rec );  
                         },  
433                          recode => $input->{recode},                          recode => $input->{recode},
434                          stats => $stats,                          stats => $stats,
435                          modify_records => $input->{modify_records},                          modify_records => $input->{modify_records},
436                            modify_file => $input->{modify_file},
437                            input_config => $input,
438                  );                  );
439                  $log->logdie("can't create input using $input_module") unless ($input);                  $log->logdie("can't create input using $input_module") unless ($input);
440    
441                    if (defined( $input->{lookup} )) {
442                            $log->warn("$database/$input_name has depriciated lookup definition, removing it...");
443                            delete( $input->{lookup} );
444                    }
445    
446                    my $lookup_coderef;
447    
448                    if (@lookups) {
449    
450                            my $rules = $parser->lookup_create_rules($database, $input) || $log->logdie("no rules found for $database/$input");
451    
452                            $lookup_coderef = sub {
453                                    my $rec = shift || die "need rec!";
454                                    my $mfn = $rec->{'000'}->[0] || die "need mfn in 000";
455    
456                                    WebPAC::Normalize::data_structure(
457                                            row => $rec,
458                                            rules => $rules,
459                                            config => create_ds_config( $db_config, $database, $input, $mfn ),
460                                    );
461    
462                                    #warn "current lookup: ", dump(WebPAC::Normalize::_get_lookup());
463                            };
464    
465                            WebPAC::Normalize::_set_lookup( undef );
466    
467                            $log->debug("created lookup_coderef using:\n$rules");
468    
469                    };
470    
471                    my $lookup_jar;
472    
473                  my $maxmfn = $input_db->open(                  my $maxmfn = $input_db->open(
474                          path => $input->{path},                          path => $input->{path},
475                          code_page => $input->{encoding},        # database encoding                          input_encoding => $input->{encoding},   # database encoding
476                            lookup_coderef => $lookup_coderef,
477                            lookup => $lookup_jar,
478                          %{ $input },                          %{ $input },
479                            load_row => sub {
480                                    my $a = shift;
481                                    return $store->load_row(
482                                            database => $database,
483                                            input => $input_name,
484                                            id => $a->{id},
485                                    );
486                            },
487                            save_row => sub {
488                                    my $a = shift;
489                                    return $store->save_row(
490                                            database => $database,
491                                            input => $input_name,
492                                            id => $a->{id},
493                                            row => $a->{row},
494                                    );
495                            },
496    
497                  );                  );
498    
499                  my @norm_array = ref($input->{normalize}) eq 'ARRAY' ?                  my $lookup_data = WebPAC::Normalize::_get_lookup();
500                          @{ $input->{normalize} } : ( $input->{normalize} );  
501                    if (defined( $lookup_data->{$database}->{$input_name} )) {
502                            $log->debug("created following lookups: ", sub { dump( $lookup_data ) } );
503    
504                  if ($marc_normalize) {                          foreach my $key (keys %{ $lookup_data->{$database}->{$input_name} }) {
505                          @norm_array = ( {                                  $store->save_lookup(
506                                  path => $marc_normalize,                                          database => $database,
507                                  output => $marc_output || 'out/marc/' . $database . '-' . $input->{name} . '.marc',                                          input => $input_name,
508                          } );                                          key => $key,
509                                            data => $lookup_data->{$database}->{$input_name}->{$key},
510                                    );
511                            }
512                  }                  }
513    
514                  foreach my $normalize (@norm_array) {                  my $report_fh;
515                    if ($stats || $validate) {
516                            my $out_report = 'out/report'; # FIXME move to config
517                            mkpath $out_report unless -e $out_report;
518                            my $path = "$out_report/${database}-${input_name}.txt";
519                            open($report_fh, '>', $path) || $log->logdie("can't open $path: $!");
520    
521                            print $report_fh "Report for database '$database' input '$input_name' records ",
522                                    $offset || 1, "-", $limit || $input->{limit} || $maxmfn, "\n\n";
523                            $log->info("Generating report file $path");
524    
525                            if ( $validate ) {
526                                    $validate->read_validate_file( $validate->fill_in( $validate_path, database => $database, input => $input_name ) ) if ( $validate_path );
527                                    $validate->read_validate_delimiters_file( $validate->fill_in( $validate_delimiters_path, database => $database, input => $input_name ) ) if ( $validate_delimiters_path );
528                            }
529                    }
530    
531                          my $normalize_path = $normalize->{path} || $log->logdie("can't find normalize path in config");                  my $marc;
532                    if ($marc_generate && $parser->have_rules( 'marc', $database, $input_name )) {
533                            
534                            my $out_marc = 'out/marc'; # FIXME move to config
535                            mkpath $out_marc unless -e $out_marc;
536    
537                          $log->logdie("Found '$normalize_path' as normalization file which isn't supported any more!") unless ( $normalize_path =~ m!\.pl$!i );                          $marc = new WebPAC::Output::MARC(
538                                    path => "$out_marc/${database}-${input_name}.marc",
539                                    lint => $marc_lint,
540                                    dump => $marc_dump,
541                            );
542                    }
543    
544                          my $rules = read_file( $normalize_path ) or die "can't open $normalize_path: $!";                  my $rules = $parser->normalize_rules($database,$input_name);
545                    if ( ! $rules ) {
546                            $log->logwarn("no normalize rules for $database/$input_name", $input_db->input_module->can('normalize') ? " using normalize from input module" : '');
547                            next;
548                    }
549    
550                          $log->info("Using $normalize_path for normalization...");                  $log->debug("parsed normalize rules:\n$rules");
551    
552                          my $marc = new WebPAC::Output::MARC(                  # reset position in database
553                                  path => $normalize->{output},                  $input_db->seek(1);
                                 lint => $marc_lint,  
                                 dump => $marc_dump,  
                         ) if ($normalize->{output});  
554    
555                          # reset position in database                  # generate name of config key for indexer (strip everything after -)
556                          $input_db->seek(1);                  my $indexer_config = $use_indexer;
557                    $indexer_config =~ s/^(\w+)-?.*$/$1/g if ($indexer_config);
558    
559                    my $lookup_hash;
560                    my $depends = $parser->depends($database,$input_name);
561            
562                    if ($depends) {
563                            $log->debug("$database/$input_name depends on: ", dump($depends)) if ($depends);
564                            $log->logdie("parser->depends didn't return HASH") unless (ref($depends) eq 'HASH');
565    
566                            foreach my $db (keys %$depends) {
567                                    foreach my $i (keys %{$depends->{$db}}) {
568                                            foreach my $k (keys %{$depends->{$db}->{$i}}) {
569                                                    my $t = time();
570                                                    $log->debug("loading lookup $db/$i");
571                                                    $lookup_hash->{$db}->{$i}->{$k} = $store->load_lookup(
572                                                            database => $db,
573                                                            input => $i,
574                                                            key => $k,
575                                                    );
576                                                    $log->debug(sprintf("lookup $db/$i took %.2fs", time() - $t));
577                                            }
578                                    }
579                            }
580    
581                          foreach my $pos ( 0 ... $input_db->size ) {                          $log->debug("lookup_hash = ", sub { dump( $lookup_hash ) });
582                    }
583    
                                 my $row = $input_db->fetch || next;  
584    
585                                  my $mfn = $row->{'000'}->[0];                  # setup input name for all output filters
586                    foreach my $out ( @output_modules ) {
587                            if ( $out->can('input') ) {
588                                    $out->input( $input_name );
589                            } else {
590                                    $log->warn("output filter ",ref($out)," doesn't support input name");
591                            }
592                    }
593    
                                 if (! $mfn || $mfn !~ m#^\d+$#) {  
                                         $log->warn("record $pos doesn't have valid MFN but '$mfn', using $pos");  
                                         $mfn = $pos;  
                                         push @{ $row->{'000'} }, $pos;  
                                 }  
594    
595                    foreach my $pos ( 0 ... $input_db->size ) {
596    
597                                  if ($validate) {                          my $row = $input_db->fetch || next;
                                         my @errors = $validate->validate_errors( $row );  
                                         $log->error( "MFN $mfn validation errors:\n", join("\n", @errors) ) if (@errors);  
                                 }  
598    
599                                  my $ds_config = dclone($db_config);                          $total_rows++;
600    
601                                  # default values -> database key                          my $mfn = $row->{'000'}->[0];
                                 $ds_config->{_} = $database;  
602    
603                                  # current mfn                          if (! $mfn || $mfn !~ m{^\d+$}) {
604                                  $ds_config->{_mfn} = $mfn;                                  $log->warn("record $pos doesn't have valid MFN but '$mfn', using $pos");
605                                    $mfn = $pos;
606                                    push @{ $row->{'000'} }, $pos;
607                            }
608    
609                            foreach my $out ( @output_modules ) {
610                                    $out->add_row( $mfn, $row ) if $out->can('add_row');
611                            }
612    
613                            if ($validate) {
614                                    if ( my $errors = $validate->validate_rec( $row, $input_db->dump_ascii ) ) {
615                                            $log->error( "MFN $mfn validation error:\n",
616                                                    $validate->report_error( $errors )
617                                            );
618                                    }
619                                    next;   # validation doesn't create any output
620                            }
621    
622                            my $ds;
623    
624                                  # attach current input                          if ($rules) {
                                 $ds_config->{input} = $input;  
625    
626                                  my $ds = WebPAC::Normalize::data_structure(                                  $ds = WebPAC::Normalize::data_structure(
627                                          row => $row,                                          row => $row,
628                                          rules => $rules,                                          rules => $rules,
629                                          lookup => $lookup ? $lookup->lookup_hash : undef,                                          lookup => $lookup_hash,
630                                          config => $ds_config,                                          config => create_ds_config( $db_config, $database, $input, $mfn ),
631                                          marc_encoding => 'utf-8',                                          marc_encoding => 'utf-8',
632                                            load_row_coderef => sub {
633                                                    my ($database,$input,$mfn) = @_;
634    #warn "### load_row($database,$input,$mfn) from data_structure\n";
635                                                    return $store->load_row(
636                                                            database => $database,
637                                                            input => $input,
638                                                            id => $mfn,
639                                                    );
640                                            },
641                                  );                                  );
642    
643                                  $db->save_ds(                          } elsif ( $input_db->input_module->can('normalize') ) {
644                                    $ds = $input_db->input_module->normalize( $mfn );
645                            }
646    
647                            if ( $ds ) {
648                                    $log->debug("ds = ", sub { dump($ds) });
649    
650                                    $store->save_ds(
651                                            database => $database,
652                                            input => $input_name,
653                                          id => $mfn,                                          id => $mfn,
654                                          ds => $ds,                                          ds => $ds,
655                                          prefix => $input->{name},                                  ) if !$stats;
                                 ) if ($ds && !$stats);  
656    
657                                  $indexer->add(                                  $indexer->add(
658                                          id => $input->{name} . "/" . $mfn,                                          id => "${input_name}/${mfn}",
659                                          ds => $ds,                                          ds => $ds,
660                                          type => $config->{$use_indexer}->{type},                                          type => $config->get($indexer_config)->{type},
661                                  ) if ($indexer && $ds);                                  ) if $indexer;
662    
663                                  if ($marc) {                                  foreach my $out ( @output_modules ) {
664                                          my $i = 0;                                          $out->add( $mfn, $ds ) if $out->can('add');
665                                    }
666    
667                                          while (my $fields = WebPAC::Normalize::_get_marc_fields( fetch_next => 1 ) ) {                          } else {
668                                                  $marc->add(                                  $log->warn("record $pos didn't produce any output after normalization rules!") unless $marc;
669                                                          id => $mfn . ( $i ? "/$i" : '' ),                          }
670                                                          fields => $fields,                          if ($marc) {
671                                                          leader => WebPAC::Normalize::marc_leader(),                                  my $i = 0;
                                                         row => $row,  
                                                 );  
                                                 $i++;  
                                         }  
672    
673                                          $log->info("Created $i instances of MFN $mfn\n") if ($i > 1);                                  while (my $fields = WebPAC::Normalize::MARC::_get_marc_fields( fetch_next => 1 ) ) {
674                                            $marc->add(
675                                                    id => $mfn . ( $i ? "/$i" : '' ),
676                                                    fields => $fields,
677                                                    leader => WebPAC::Normalize::MARC::_get_marc_leader(),
678                                                    row => $row,
679                                            );
680                                            $i++;
681                                  }                                  }
682    
683                                  $total_rows++;                                  $log->info("Created $i instances of MFN $mfn\n") if ($i > 1);
684                            }
685    
686                    }
687    
688                    if ($validate) {
689                            my $errors = $validate->report;
690                            if ($errors) {
691                                    $log->info("validation errors:\n$errors\n" );
692                                    print $report_fh "$errors\n" if ($report_fh);
693                          }                          }
694    
695                          $log->info("statistics of fields usage:\n", $input_db->stats) if ($stats);                          print $report_fh "\nAll possible subfields/delimiter templates:\n", $validate->delimiters_templates( report => 1, current_input => 1 ), "\n\n";
696    
697                          # close MARC file                          # must be last thing that touches $validate for this input
698                          $marc->finish if ($marc);                          $validate->reset;
699                    }
700    
701                    if ($stats) {
702                            my $s = $input_db->stats;
703                            $log->info("statistics of fields usage:\n$s");
704                            print $report_fh "Statistics of fields usage:\n$s" if ($report_fh);
705                  }                  }
706    
707                    # close MARC file
708                    $marc->finish if ($marc);
709    
710                    # close report
711                    close($report_fh) if ($report_fh);
712          }          }
713    
714          eval { $indexer->finish } if ($indexer && $indexer->can('finish'));          $indexer->finish if $indexer && $indexer->can('finish');
715    
716            foreach my $out ( @output_modules ) {
717                    $out->finish if $out->can('finish');
718            }
719    
720          my $dt = time() - $start_t;          my $dt = time() - $start_t;
721          $log->info("$total_rows records ", $indexer ? "indexed " : "",          $log->info("$total_rows records ", $indexer ? "indexed " : "",
# Line 397  while (my ($database, $db_config) = each Line 724  while (my ($database, $db_config) = each
724                  )                  )
725          );          );
726    
         #  
         # add Hyper Estraier links to other databases  
         #  
         if (ref($db_config->{links}) eq 'ARRAY' && $use_indexer) {  
                 foreach my $link (@{ $db_config->{links} }) {  
                         if ($use_indexer eq 'hyperestraier') {  
                                 $log->info("saving link $database -> $link->{to} [$link->{credit}]");  
                                 push @links, {  
                                         from => $database,  
                                         to => $link->{to},  
                                         credit => $link->{credit},  
                                 };  
                         } else {  
                                 $log->warn("NOT IMPLEMENTED WITH $use_indexer: adding link $database -> $link->{to} [$link->{credit}]");  
                         }  
                 }  
         }  
727    
728          # end forked process          # end forked process
729          if ($parallel) {          if ($parallel) {
# Line 429  if ($parallel) { Line 739  if ($parallel) {
739          $log->info("all parallel processes finished");          $log->info("all parallel processes finished");
740  }  }
741    
742  foreach my $link (@links) {  # save new delimiters if needed
743          $log->info("adding link $link->{from} -> $link->{to} [$link->{credit}]");  $validate->save_delimiters_templates if ( $validate_delimiters_path );
         $indexer->add_link( %{ $link } );  
 }  
744    
745    #
746    # handle links or merge after indexing
747    #
748    
749    if ($merge) {
750            print $estcmd_fh 'sudo /etc/init.d/hyperestraier start',$/;
751            close($estcmd_fh);
752            chmod 0700, $estcmd_path || $log->warn("can't chmod 0700 $estcmd_path: $!");
753            system $estcmd_path;
754    } else {
755            foreach my $link (@links) {
756                    $log->logdie("coderef in link ", Dumper($link), " is ", ref($link), " and not CODE") unless (ref($link) eq 'CODE');
757                    $link->();
758            }
759    }

Legend:
Removed from v.606  
changed lines
  Added in v.1246

  ViewVC Help
Powered by ViewVC 1.1.26