/[webpac2]/trunk/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 /trunk/run.pl

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

revision 504 by dpavlin, Sun May 14 22:24:18 2006 UTC revision 1164 by dpavlin, Sat Apr 25 14:46:42 2009 UTC
# Line 4  use strict; Line 4  use strict;
4    
5  use Cwd qw/abs_path/;  use Cwd qw/abs_path/;
6  use File::Temp qw/tempdir/;  use File::Temp qw/tempdir/;
 use Data::Dumper;  
7  use lib './lib';  use lib './lib';
8    
9  use WebPAC::Common 0.02;  use WebPAC::Common 0.02;
10  use WebPAC::Lookup;  use WebPAC::Parser 0.08;
11  use WebPAC::Input 0.03;  use WebPAC::Input 0.16;
12  use WebPAC::Store 0.03;  use WebPAC::Store 0.15;
13  use WebPAC::Normalize::XML;  use WebPAC::Normalize 0.22;
 use WebPAC::Normalize::Set;  
14  use WebPAC::Output::TT;  use WebPAC::Output::TT;
15  use YAML qw/LoadFile/;  use WebPAC::Validate 0.11;
16    use WebPAC::Output::MARC;
17    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/;
23    use Storable qw/dclone/;
24    use Pod::Usage qw/pod2usage/;
25    use LWP::Simple;
26    
27    use POSIX ":sys_wait_h"; # imports WNOHANG
28    
29  =head1 NAME  =head1 NAME
30    
# Line 26  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 42  limit loading to 100 records Line 48  limit loading to 100 records
48    
49  remove database and Hyper Estraier index before indexing  remove database and Hyper Estraier index before indexing
50    
51  =item --only=database_name  =item --only=database_name/input_filter
52    
53  reindex just single database (legacy name is --one)  reindex just single database (legacy name is --one)
54    
55    C</input_filter> is optional part which can be C<name>
56    or C<type> from input
57    
58  =item --config conf/config.yml  =item --config conf/config.yml
59    
60  path to YAML configuration file  path to YAML configuration file
61    
62  =item --force-set  =item --stats
63    
64    disable indexing, modify_* in configuration and dump statistics about field
65    and subfield usage for each input
66    
67    =item --validate path/to/validation_file
68    
69    turn on extra validation of imput records, see L<WebPAC::Validation>
70    
71    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    =item --validate-delimiters path/to/validate_delimiters_file
75    
76    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    =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
85    
86  force conversion C<normalize->path> in C<config.yml> from  By default turned on if normalisation file has C<marc*> directives. You can disable lint
87  C<.xml> to C<.pl>  messages with C<--no-marc-lint>.
88    
89    =item --marc-dump
90    
91    Force dump or input and marc record for debugging.
92    
93    =item --parallel 4
94    
95    Run databases in parallel (aproximatly same as number of processors in
96    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    
# Line 63  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_db_name;  my $only_filter;
121  my $force_set = 0;  my $stats = 0;
122    my $validate_path;
123    my $validate_delimiters_path;
124    my $marc_generate = 1;
125    my $marc_lint = 1;
126    my $marc_dump = 0;
127    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,
137          "offset=i" => \$offset,          "offset=i" => \$offset,
138          "clean" => \$clean,          "clean" => \$clean,
139          "one=s" => \$only_db_name,          "one=s" => \$only_filter,
140          "only=s" => \$only_db_name,          "only=s" => \$only_filter,
141          "config" => \$config,          "config=s" => \$config_path,
142          "debug" => \$debug,          "debug+" => \$debug,
143          "force-set" => \$force_set,          "stats" => \$stats,
144            "validate=s" => \$validate_path,
145            "validate-delimiters=s" => \$validate_delimiters_path,
146            "marc-generate!" => \$marc_generate,
147            "marc-lint!" => \$marc_lint,
148            "marc-dump!" => \$marc_dump,
149            "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 = ",Dumper($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  my $log = _new WebPAC::Common()->_get_logger();  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    
168    $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;
187    $validate = new WebPAC::Validate(
188            delimiters => $config->webpac('delimiters'),
189    ) if ($validate_path || $validate_delimiters_path);
190    
191    my $use_indexer = $config->use_indexer;
192    $stats ||= $validate;
193    if ($stats) {
194            $log->debug("disabled indexing for stats collection");
195            $use_indexer = undef;
196    } elsif ( $use_indexer ) {
197            $log->info("using $use_indexer indexing engine...");
198    }
199    
200    # parse normalize files and create source files for lookup and normalization
201    
202    my ($only_database,$only_input) = split(m#/#, $only_filter) if $only_filter;
203    
204  my $use_indexer = $config->{use_indexer} || 'hyperestraier';  my $parser = new WebPAC::Parser(
205  $log->info("using $use_indexer indexing engine...");          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  while (my ($database, $db_config) = each %{ $config->{databases} }) {  my @links;
214    
215    if ($parallel) {
216            eval 'use Proc::Queue size => 1;';
217            die $@ if $@;
218            $log->info("Using $parallel processes for speedup");
219            Proc::Queue::size($parallel);
220    }
221    
222          next if ($only_db_name && $database !~ m/$only_db_name/i);  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    
234            next if ($only_database && $database !~ m/$only_database/i);
235    
236            if ($parallel) {
237                    my $f=fork;
238                    if(defined ($f) and $f==0) {
239                            $log->info("Created processes $$ for speedup");
240                    } else {
241                            next;
242                    }
243            }
244    
245          my $indexer;          my $indexer;
246            if ($use_indexer && $parser->have_rules( 'search', $database )) {
247    
248          my $indexer_config = $config->{$use_indexer} || $log->logdie("can't find '$use_indexer' part in confguration");                  my $cfg_name = $use_indexer;
249          $indexer_config->{database} = $database;                  $cfg_name =~ s/\-.*$//;
250          $indexer_config->{clean} = $clean;  
251          $indexer_config->{label} = $db_config->{name};                  my $indexer_config = $config->get( $cfg_name ) || $log->logdie("can't find '$cfg_name' part in confguration");
252                    $indexer_config->{database} = $database;
253          if ($use_indexer eq 'hyperestraier') {                  $indexer_config->{clean} = $clean;
254                    $indexer_config->{label} = $db_config->{name};
255                  # open Hyper Estraier database  
256                  use WebPAC::Output::Estraier '0.10';                  # force clean if database has links
257                  $indexer = new WebPAC::Output::Estraier( %{ $indexer_config } );                  $indexer_config->{clean} = 1 if ($db_config->{links});
258            
259          } elsif ($use_indexer eq 'kinosearch') {                  if ($use_indexer eq 'hyperestraier') {
260    
261                            # open Hyper Estraier database
262                            require WebPAC::Output::Estraier;
263                            $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') {
272    
273                            die "no longer supported";
274    
275                    } else {
276                            $log->logdie("unknown use_indexer: $use_indexer");
277                    }
278    
279                    $log->logdie("can't continue without valid indexer") unless ($indexer);
280            }
281    
                 # open KinoSearch  
                 use WebPAC::Output::KinoSearch;  
                 $indexer_config->{clean} = 1 unless (-e $indexer_config->{index_path});  
                 $indexer = new WebPAC::Output::KinoSearch( %{ $indexer_config } );  
282    
283          } else {          #
284                  $log->logdie("unknown use_indexer: $use_indexer");          # 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    
         $log->logide("can't continue without valid indexer") unless ($indexer);  
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    
317    
318            #
319            # prepare output
320            #
321            my @outputs = force_array( $db_config->{output}, sub {
322                    $log->error("Database $database doesn't have any outputs defined. Do you want to remove it from configuration?" );
323            } );
324    
325          my $db_path = $config->{webpac}->{db_path} . '/' . $database;          my @output_modules;
326    
327          if ($clean) {          foreach my $output ( @outputs ) {
                 $log->info("creating new database $database in $db_path");  
                 rmtree( $db_path ) || $log->warn("can't remove $db_path: $!");  
         } else {  
                 $log->debug("working on $database in $db_path");  
         }  
328    
329          my $db = new WebPAC::Store(  #warn '## output = ',dump( $output );
330                  path => $db_path,  
331                  database => $database,                  my $module = $output->{module} || $log->logdie("need module in output section of $database");
332                  debug => $debug,                  $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    
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                    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 ($only_input && ($input_name !~ m#$only_input#i && $input->{type} !~ 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                    if ( ! $input_module ) {
394                            if ( grep(/$type/, $config->webpac('inputs')) ) {
395                                    $input_module = $config->webpac('inputs')->{$type};
396                            } else {
397                                    $log->logdie("I know only how to handle input types ", join(",", $config->webpac('inputs') ), " not '$type'!" );
398                            }
399                    }
400    
401                  my $lookup = new WebPAC::Lookup(                  my @lookups = $parser->have_lookup_create($database, $input);
402                          lookup_file => $input->{lookup},  
403                    $log->info("working on $database/$input_name with $input_module on $input->{path}",
404                            @lookups ? " creating lookups: ".join(", ", @lookups) : ""
405                  );                  );
406    
407                  my $input_module = $config->{webpac}->{inputs}->{$type};                  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                  $log->info("working on input '$input->{path}' [$input->{type}] using $input_module lookup '$input->{lookup}'");                  if ( $mirror ) {
414                            my $path = $input->{path} || die "no input path in ",dump( $input );
415                            $log->info( "mirror ", $path, " ", -s $path, " bytes" );
416    
417                            $log->warn( "$path not modified" )
418                                    if mirror( "$mirror/$path", $path ) == RC_NOT_MODIFIED;
419                    }
420    
421                  my $input_db = new WebPAC::Input(                  my $input_db = new WebPAC::Input(
422                          module => $input_module,                          module => $input_module,
                         code_page => $config->{webpac}->{webpac_encoding},  
423                          limit => $limit || $input->{limit},                          limit => $limit || $input->{limit},
424                          offset => $offset,                          offset => $offset,
                         lookup => $lookup,  
425                          recode => $input->{recode},                          recode => $input->{recode},
426                            stats => $stats,
427                            modify_records => $input->{modify_records},
428                            modify_file => $input->{modify_file},
429                            input_config => $input,
430                  );                  );
431                  $log->logdie("can't create input using $input_module") unless ($input);                  $log->logdie("can't create input using $input_module") unless ($input);
432    
433                    if (defined( $input->{lookup} )) {
434                            $log->warn("$database/$input_name has depriciated lookup definition, removing it...");
435                            delete( $input->{lookup} );
436                    }
437    
438                    my $lookup_coderef;
439    
440                    if (@lookups) {
441    
442                            my $rules = $parser->lookup_create_rules($database, $input) || $log->logdie("no rules found for $database/$input");
443    
444                            $lookup_coderef = sub {
445                                    my $rec = shift || die "need rec!";
446                                    my $mfn = $rec->{'000'}->[0] || die "need mfn in 000";
447    
448                                    WebPAC::Normalize::data_structure(
449                                            row => $rec,
450                                            rules => $rules,
451                                            config => create_ds_config( $db_config, $database, $input, $mfn ),
452                                    );
453    
454                                    #warn "current lookup: ", dump(WebPAC::Normalize::_get_lookup());
455                            };
456    
457                            WebPAC::Normalize::_set_lookup( undef );
458    
459                            $log->debug("created lookup_coderef using:\n$rules");
460    
461                    };
462    
463                    my $lookup_jar;
464    
465                  my $maxmfn = $input_db->open(                  my $maxmfn = $input_db->open(
466                          path => $input->{path},                          path => $input->{path},
467                          code_page => $input->{encoding},        # database encoding                          input_encoding => $input->{encoding},   # database encoding
468                  );                          lookup_coderef => $lookup_coderef,
469                            lookup => $lookup_jar,
470                            %{ $input },
471                            load_row => sub {
472                                    my $a = shift;
473                                    return $store->load_row(
474                                            database => $database,
475                                            input => $input_name,
476                                            id => $a->{id},
477                                    );
478                            },
479                            save_row => sub {
480                                    my $a = shift;
481                                    return $store->save_row(
482                                            database => $database,
483                                            input => $input_name,
484                                            id => $a->{id},
485                                            row => $a->{row},
486                                    );
487                            },
488    
                 my $n = new WebPAC::Normalize::XML(  
                 #       filter => { 'foo' => sub { shift } },  
                         db => $db,  
                         lookup_regex => $lookup->regex,  
                         lookup => $lookup,  
                         prefix => $input->{name},  
489                  );                  );
490    
491                  my $rules;                  my $lookup_data = WebPAC::Normalize::_get_lookup();
                 my $normalize_path = $input->{normalize}->{path};  
492    
493                  if ($force_set) {                  if (defined( $lookup_data->{$database}->{$input_name} )) {
494                          my $new_norm_path = $normalize_path;                          $log->debug("created following lookups: ", sub { dump( $lookup_data ) } );
495                          $new_norm_path =~ s/\.xml$/.pl/;  
496                          if (-e $new_norm_path) {                          foreach my $key (keys %{ $lookup_data->{$database}->{$input_name} }) {
497                                  $log->debug("--force-set replaced $normalize_path with $new_norm_path");                                  $store->save_lookup(
498                                  $normalize_path = $new_norm_path;                                          database => $database,
499                          } else {                                          input => $input_name,
500                                  $log->debug("--force-set failed on $new_norm_path, fallback to $normalize_path");                                          key => $key,
501                                            data => $lookup_data->{$database}->{$input_name}->{$key},
502                                    );
503                          }                          }
504                  }                  }
505    
506                  if ($normalize_path =~ m/\.xml$/i) {                  my $report_fh;
507                          $n->open(                  if ($stats || $validate) {
508                                  tag => $input->{normalize}->{tag},                          my $path = "out/report/${database}-${input_name}.txt";
509                                  xml_file => $normalize_path,                          open($report_fh, '>', $path) || $log->logdie("can't open $path: $!");
510                          );  
511                  } elsif ($normalize_path =~ m/\.(?:yml|yaml)$/i) {                          print $report_fh "Report for database '$database' input '$input_name' records ",
512                          $n->open_yaml(                                  $offset || 1, "-", $limit || $input->{limit} || $maxmfn, "\n\n";
513                                  path => $normalize_path,                          $log->info("Generating report file $path");
514                                  tag => $input->{normalize}->{tag},  
515                            if ( $validate ) {
516                                    $validate->read_validate_file( $validate->fill_in( $validate_path, database => $database, input => $input_name ) ) if ( $validate_path );
517                                    $validate->read_validate_delimiters_file( $validate->fill_in( $validate_delimiters_path, database => $database, input => $input_name ) ) if ( $validate_delimiters_path );
518                            }
519                    }
520    
521                    my $marc;
522                    if ($marc_generate && $parser->have_rules( 'marc', $database, $input_name )) {
523                            $marc = new WebPAC::Output::MARC(
524                                    path => "out/marc/${database}-${input_name}.marc",
525                                    lint => $marc_lint,
526                                    dump => $marc_dump,
527                          );                          );
                 } elsif ($normalize_path =~ m/\.(?:pl)$/i) {  
                         $n = undef;  
                         $log->info("using WebPAC::Normalize::Set to process $normalize_path");  
                         $rules = read_file( $normalize_path ) or die "can't open $normalize_path: $!";  
528                  }                  }
529    
530                    my $rules = $parser->normalize_rules($database,$input_name);
531                    $log->logwarn("no normalize rules for $database/$input_name") unless $rules;
532    
533                    $log->debug("parsed normalize rules:\n$rules");
534    
535                    # reset position in database
536                    $input_db->seek(1);
537    
538                    # generate name of config key for indexer (strip everything after -)
539                    my $indexer_config = $use_indexer;
540                    $indexer_config =~ s/^(\w+)-?.*$/$1/g if ($indexer_config);
541    
542                    my $lookup_hash;
543                    my $depends = $parser->depends($database,$input_name);
544            
545                    if ($depends) {
546                            $log->debug("$database/$input_name depends on: ", dump($depends)) if ($depends);
547                            $log->logdie("parser->depends didn't return HASH") unless (ref($depends) eq 'HASH');
548    
549                            foreach my $db (keys %$depends) {
550                                    foreach my $i (keys %{$depends->{$db}}) {
551                                            foreach my $k (keys %{$depends->{$db}->{$i}}) {
552                                                    my $t = time();
553                                                    $log->debug("loading lookup $db/$i");
554                                                    $lookup_hash->{$db}->{$i}->{$k} = $store->load_lookup(
555                                                            database => $db,
556                                                            input => $i,
557                                                            key => $k,
558                                                    );
559                                                    $log->debug(sprintf("lookup $db/$i took %.2fs", time() - $t));
560                                            }
561                                    }
562                            }
563    
564                            $log->debug("lookup_hash = ", sub { dump( $lookup_hash ) });
565                    }
566    
567    
568                    # setup input name for all output filters
569                    foreach my $out ( @output_modules ) {
570                            if ( $out->can('input') ) {
571                                    $out->input( $input_name );
572                            } else {
573                                    $log->warn("output filter ",ref($out)," doesn't support input name");
574                            }
575                    }
576    
577    
578                  foreach my $pos ( 0 ... $input_db->size ) {                  foreach my $pos ( 0 ... $input_db->size ) {
579    
580                          my $row = $input_db->fetch || next;                          my $row = $input_db->fetch || next;
581    
582                            $total_rows++;
583    
584                          my $mfn = $row->{'000'}->[0];                          my $mfn = $row->{'000'}->[0];
585    
586                          if (! $mfn || $mfn !~ m#^\d+$#) {                          if (! $mfn || $mfn !~ m{^\d+$}) {
587                                  $log->warn("record $pos doesn't have valid MFN but '$mfn', using $pos");                                  $log->warn("record $pos doesn't have valid MFN but '$mfn', using $pos");
588                                  $mfn = $pos;                                  $mfn = $pos;
589                                  push @{ $row->{'000'} }, $pos;                                  push @{ $row->{'000'} }, $pos;
590                          }                          }
591    
592                          my $ds = $n ? $n->data_structure($row) :  
593                                  WebPAC::Normalize::Set::data_structure(                          if ($validate) {
594                                    if ( my $errors = $validate->validate_rec( $row, $input_db->dump_ascii ) ) {
595                                            $log->error( "MFN $mfn validation error:\n",
596                                                    $validate->report_error( $errors )
597                                            );
598                                    }
599                                    next;   # validation doesn't create any output
600                            }
601    
602                            if ($rules) {
603    
604                                    my $ds = WebPAC::Normalize::data_structure(
605                                          row => $row,                                          row => $row,
606                                          rules => $rules,                                          rules => $rules,
607                                          lookup => $lookup->lookup_hash,                                          lookup => $lookup_hash,
608                                            config => create_ds_config( $db_config, $database, $input, $mfn ),
609                                            marc_encoding => 'utf-8',
610                                            load_row_coderef => sub {
611                                                    my ($database,$input,$mfn) = @_;
612    #warn "### load_row($database,$input,$mfn) from data_structure\n";
613                                                    return $store->load_row(
614                                                            database => $database,
615                                                            input => $input,
616                                                            id => $mfn,
617                                                    );
618                                            },
619                                  );                                  );
620    
621                          $indexer->add(                                  $log->debug("ds = ", sub { dump($ds) });
622                                  id => $input->{name} . "/" . $mfn,  
623                                  ds => $ds,                                  if ( $ds ) {
624                                  type => $config->{$use_indexer}->{type},  
625                          );                                          $store->save_ds(
626                                                    database => $database,
627                                                    input => $input_name,
628                                                    id => $mfn,
629                                                    ds => $ds,
630                                            ) if !$stats;
631    
632                                            $indexer->add(
633                                                    id => "${input_name}/${mfn}",
634                                                    ds => $ds,
635                                                    type => $config->get($indexer_config)->{type},
636                                            ) if $indexer;
637    
638                                            foreach my $out ( @output_modules ) {
639                                                    $out->add( $mfn, $ds ) if $out->can('add');
640                                            }
641    
642                                    } else {
643                                            $log->warn("record $pos didn't produce any output after normalization rules!") unless $marc;
644                                    }
645                            }
646    
647                            if ($marc) {
648                                    my $i = 0;
649    
650                                    while (my $fields = WebPAC::Normalize::MARC::_get_marc_fields( fetch_next => 1 ) ) {
651                                            $marc->add(
652                                                    id => $mfn . ( $i ? "/$i" : '' ),
653                                                    fields => $fields,
654                                                    leader => WebPAC::Normalize::MARC::_get_marc_leader(),
655                                                    row => $row,
656                                            );
657                                            $i++;
658                                    }
659    
660                                    $log->info("Created $i instances of MFN $mfn\n") if ($i > 1);
661                            }
662    
                         $total_rows++;  
663                  }                  }
664    
665          };                  if ($validate) {
666                            my $errors = $validate->report;
667                            if ($errors) {
668                                    $log->info("validation errors:\n$errors\n" );
669                                    print $report_fh "$errors\n" if ($report_fh);
670                            }
671    
672                            print $report_fh "\nAll possible subfields/delimiter templates:\n", $validate->delimiters_templates( report => 1, current_input => 1 ), "\n\n";
673    
674                            # must be last thing that touches $validate for this input
675                            $validate->reset;
676                    }
677    
678          eval { $indexer->finish } if ($indexer->can('finish'));                  if ($stats) {
679                            my $s = $input_db->stats;
680                            $log->info("statistics of fields usage:\n$s");
681                            print $report_fh "Statistics of fields usage:\n$s" if ($report_fh);
682                    }
683    
684                    # close MARC file
685                    $marc->finish if ($marc);
686    
687                    # close report
688                    close($report_fh) if ($report_fh);
689            }
690    
691            $indexer->finish if $indexer && $indexer->can('finish');
692    
693            foreach my $out ( @output_modules ) {
694                    $out->finish if $out->can('finish');
695            }
696    
697          my $dt = time() - $start_t;          my $dt = time() - $start_t;
698          $log->info("$total_rows records indexed in " .          $log->info("$total_rows records ", $indexer ? "indexed " : "",
699                  sprintf("%.2f sec [%.2f rec/sec]",                  sprintf("in %.2f sec [%.2f rec/sec]",
700                          $dt, ($total_rows / $dt)                          $dt, ($total_rows / $dt)
701                  )                  )
702          );          );
703    
704          #  
705          # add Hyper Estraier links to other databases          # end forked process
706          #          if ($parallel) {
707          if (ref($db_config->{links}) eq 'ARRAY') {                  $log->info("parallel process $$ finished");
708                  foreach my $link (@{ $db_config->{links} }) {                  exit(0);
                         if ($use_indexer eq 'hyperestraier') {  
                                 $log->info("adding link $database -> $link->{to} [$link->{credit}]");  
                                 $indexer->add_link(  
                                         from => $database,  
                                         to => $link->{to},  
                                         credit => $link->{credit},  
                                 );  
                         } else {  
                                 $log->warn("NOT IMPLEMENTED WITH $use_indexer: adding link $database -> $link->{to} [$link->{credit}]");  
                         }  
                 }  
709          }          }
710    
711  }  }
712    
713    if ($parallel) {
714            # wait all children to finish
715            sleep(1) while wait != -1;
716            $log->info("all parallel processes finished");
717    }
718    
719    # save new delimiters if needed
720    $validate->save_delimiters_templates if ( $validate_delimiters_path );
721    
722    #
723    # handle links or merge after indexing
724    #
725    
726    if ($merge) {
727            print $estcmd_fh 'sudo /etc/init.d/hyperestraier start',$/;
728            close($estcmd_fh);
729            chmod 0700, $estcmd_path || $log->warn("can't chmod 0700 $estcmd_path: $!");
730            system $estcmd_path;
731    } else {
732            foreach my $link (@links) {
733                    $log->logdie("coderef in link ", Dumper($link), " is ", ref($link), " and not CODE") unless (ref($link) eq 'CODE');
734                    $link->();
735            }
736    }

Legend:
Removed from v.504  
changed lines
  Added in v.1164

  ViewVC Help
Powered by ViewVC 1.1.26