/[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 512 by dpavlin, Mon May 15 18:27:15 2006 UTC revision 664 by dpavlin, Mon Sep 11 11:57:18 2006 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::Lookup 0.03;
11  use WebPAC::Input 0.03;  use WebPAC::Input 0.11;
12  use WebPAC::Store 0.03;  use WebPAC::Store 0.03;
13  use WebPAC::Normalize::XML;  use WebPAC::Normalize 0.11;
 use WebPAC::Normalize::Set;  
14  use WebPAC::Output::TT;  use WebPAC::Output::TT;
15    use WebPAC::Validate 0.06;
16    use WebPAC::Output::MARC;
17  use YAML qw/LoadFile/;  use YAML qw/LoadFile/;
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    
25    use Proc::Queue size => 1;
26    use POSIX ":sys_wait_h"; # imports WNOHANG
27    
28  =head1 NAME  =head1 NAME
29    
# Line 53  or C<type> from input Line 58  or C<type> from input
58    
59  path to YAML configuration file  path to YAML configuration file
60    
61  =item --force-set  =item --stats
62    
63    disable indexing, modify_* in configuration and dump statistics about field
64    and subfield usage for each input
65    
66  force conversion C<< normalize->path >> in C<config.yml> from  =item --validate path/to/validation_file
 C<.xml> to C<.pl>  
67    
68  =item --stats  turn on extra validation of imput records, see L<WebPAC::Validation>
69    
70    =item --marc-normalize conf/normalize/mapping.pl
71    
72    This option specifies normalisation file for MARC creation
73    
74    =item --marc-output out/marc/test.marc
75    
76    Optional path to output file
77    
78    =item --marc-lint
79    
80    By default turned on if C<--marc-normalize> is used. You can disable lint
81    messages with C<--no-marc-lint>.
82    
83    =item --marc-dump
84    
85    Force dump or input and marc record for debugging.
86    
87    =item --parallel 4
88    
89    Run databases in parallel (aproximatly same as number of processors in
90    machine if you want to use full load)
91    
92  disable indexing and dump statistics about field and subfield  =item --only-links
93  usage for each input  
94    Create just links
95    
96    =item --merge
97    
98    Create merged index of databases which have links
99    
100  =back  =back
101    
# Line 74  my $clean = 0; Line 108  my $clean = 0;
108  my $config = 'conf/config.yml';  my $config = 'conf/config.yml';
109  my $debug = 0;  my $debug = 0;
110  my $only_filter;  my $only_filter;
 my $force_set = 0;  
111  my $stats = 0;  my $stats = 0;
112    my $validate_path;
113    my ($marc_normalize, $marc_output);
114    my $marc_lint = 1;
115    my $marc_dump = 0;
116    my $parallel = 0;
117    my $only_links = 0;
118    my $merge = 0;
119    
120    my $log = _new WebPAC::Common()->_get_logger();
121    
122    my $hostname = `hostname`;
123    chomp($hostname);
124    $hostname =~ s/\..+$//;
125    if (-e "conf/$hostname.yml") {
126            $config = "conf/$hostname.yml";
127            $log->info("using host configuration file: $config");
128    }
129    
130  GetOptions(  GetOptions(
131          "limit=i" => \$limit,          "limit=i" => \$limit,
# Line 84  GetOptions( Line 134  GetOptions(
134          "one=s" => \$only_filter,          "one=s" => \$only_filter,
135          "only=s" => \$only_filter,          "only=s" => \$only_filter,
136          "config" => \$config,          "config" => \$config,
137          "debug" => \$debug,          "debug+" => \$debug,
         "force-set" => \$force_set,  
138          "stats" => \$stats,          "stats" => \$stats,
139            "validate=s" => \$validate_path,
140            "marc-normalize=s" => \$marc_normalize,
141            "marc-output=s" => \$marc_output,
142            "marc-lint!" => \$marc_lint,
143            "marc-dump!" => \$marc_dump,
144            "parallel=i" => \$parallel,
145            "only-links!" => \$only_links,
146            "merge" => \$merge,
147  );  );
148    
149  $config = LoadFile($config);  $config = LoadFile($config);
150    
151  print "config = ",Dumper($config) if ($debug);  #print "config = ",dump($config) if ($debug);
152    
153  die "no databases in config file!\n" unless ($config->{databases});  die "no databases in config file!\n" unless ($config->{databases});
154    
 my $log = _new WebPAC::Common()->_get_logger();  
155  $log->info( "-" x 79 );  $log->info( "-" x 79 );
156    
157    
158    my $estcmd_fh;
159    my $estcmd_path = './estcmd-merge.sh';
160    if ($merge) {
161            open($estcmd_fh, '>', $estcmd_path) || $log->logdie("can't open $estcmd_path: $!");
162            print $estcmd_fh 'cd /data/estraier/_node/ || exit 1',$/;
163            print $estcmd_fh 'sudo /etc/init.d/hyperestraier stop',$/;
164            $log->info("created merge batch file $estcmd_path");
165    }
166    
167    
168    my $validate;
169    $validate = new WebPAC::Validate(
170            path => $validate_path,
171    ) if ($validate_path);
172    
173    
174  my $use_indexer = $config->{use_indexer} || 'hyperestraier';  my $use_indexer = $config->{use_indexer} || 'hyperestraier';
175  if ($stats) {  if ($stats) {
176          $log->debug("option --stats disables update of indexing engine...");          $log->debug("option --stats disables update of indexing engine...");
# Line 106  if ($stats) { Line 179  if ($stats) {
179          $log->info("using $use_indexer indexing engine...");          $log->info("using $use_indexer indexing engine...");
180  }  }
181    
182    # disable indexing when creating marc
183    $use_indexer = undef if ($marc_normalize);
184    
185  my $total_rows = 0;  my $total_rows = 0;
186  my $start_t = time();  my $start_t = time();
187    
188    my @links;
189    
190    if ($parallel) {
191            $log->info("Using $parallel processes for speedup");
192            Proc::Queue::size($parallel);
193    }
194    
195  while (my ($database, $db_config) = each %{ $config->{databases} }) {  while (my ($database, $db_config) = each %{ $config->{databases} }) {
196    
197          my ($only_database,$only_input) = split(m#/#, $only_filter) if ($only_filter);          my ($only_database,$only_input) = split(m#/#, $only_filter) if ($only_filter);
198          next if ($only_database && $database !~ m/$only_database/i);          next if ($only_database && $database !~ m/$only_database/i);
199    
200          my $indexer;          if ($parallel) {
201                    my $f=fork;
202                    if(defined ($f) and $f==0) {
203                            $log->info("Created processes $$ for speedup");
204                    } else {
205                            next;
206                    }
207            }
208    
209            my $indexer;
210          if ($use_indexer) {          if ($use_indexer) {
211                  my $indexer_config = $config->{$use_indexer} || $log->logdie("can't find '$use_indexer' part in confguration");  
212                    my $cfg_name = $use_indexer;
213                    $cfg_name =~ s/\-.*$//;
214    
215                    my $indexer_config = $config->{$cfg_name} || $log->logdie("can't find '$cfg_name' part in confguration");
216                  $indexer_config->{database} = $database;                  $indexer_config->{database} = $database;
217                  $indexer_config->{clean} = $clean;                  $indexer_config->{clean} = $clean;
218                  $indexer_config->{label} = $db_config->{name};                  $indexer_config->{label} = $db_config->{name};
219    
220                    # force clean if database has links
221                    $indexer_config->{clean} = 1 if ($db_config->{links});
222    
223                  if ($use_indexer eq 'hyperestraier') {                  if ($use_indexer eq 'hyperestraier') {
224    
225                          # open Hyper Estraier database                          # open Hyper Estraier database
226                          use WebPAC::Output::Estraier '0.10';                          use WebPAC::Output::Estraier '0.10';
227                          $indexer = new WebPAC::Output::Estraier( %{ $indexer_config } );                          $indexer = new WebPAC::Output::Estraier( %{ $indexer_config } );
228                                    
229                    } elsif ($use_indexer eq 'hyperestraier-native') {
230    
231                            # open Hyper Estraier database
232                            use WebPAC::Output::EstraierNative;
233                            $indexer = new WebPAC::Output::EstraierNative( %{ $indexer_config } );
234    
235                            $use_indexer = 'hyperestraier';
236    
237                  } elsif ($use_indexer eq 'kinosearch') {                  } elsif ($use_indexer eq 'kinosearch') {
238    
239                          # open KinoSearch                          # open KinoSearch
# Line 144  while (my ($database, $db_config) = each Line 250  while (my ($database, $db_config) = each
250    
251    
252          #          #
253            # store Hyper Estraier links to other databases
254            #
255            if (ref($db_config->{links}) eq 'ARRAY' && $use_indexer) {
256                    foreach my $link (@{ $db_config->{links} }) {
257                            if ($use_indexer eq 'hyperestraier') {
258                                    if ($merge) {
259                                            print $estcmd_fh 'sudo -u www-data estcmd merge ' . $database . ' ' . $link->{to},$/;
260                                    } else {
261                                            $log->info("saving link $database -> $link->{to} [$link->{credit}]");
262                                            push @links, sub {
263                                                    $log->info("adding link $database -> $link->{to} [$link->{credit}]");
264                                                    $indexer->add_link(
265                                                            from => $database,
266                                                            to => $link->{to},
267                                                            credit => $link->{credit},
268                                                    );
269                                            };
270                                    }
271                            } else {
272                                    $log->warn("NOT IMPLEMENTED WITH $use_indexer: adding link $database -> $link->{to} [$link->{credit}]");
273                            }
274                    }
275            }
276            next if ($only_links);
277    
278    
279            #
280          # now WebPAC::Store          # now WebPAC::Store
281          #          #
282          my $abs_path = abs_path($0);          my $abs_path = abs_path($0);
# Line 188  while (my ($database, $db_config) = each Line 321  while (my ($database, $db_config) = each
321    
322                  die "I know only how to handle input types ", join(",", @supported_inputs), " not '$type'!\n" unless (grep(/$type/, @supported_inputs));                  die "I know only how to handle input types ", join(",", @supported_inputs), " not '$type'!\n" unless (grep(/$type/, @supported_inputs));
323    
324                  my $lookup = new WebPAC::Lookup(                  my $lookup;
325                          lookup_file => $input->{lookup},                  if ($input->{lookup}) {
326                  );                          $lookup = new WebPAC::Lookup(
327                                    lookup_file => $input->{lookup},
328                            );
329                            delete( $input->{lookup} );
330                    }
331    
332                  my $input_module = $config->{webpac}->{inputs}->{$type};                  my $input_module = $config->{webpac}->{inputs}->{$type};
333    
334                  $log->info("working on input '$input->{name}' in $input->{path} [type: $input->{type}] using $input_module lookup '$input->{lookup}'");                  $log->info("working on input '$input->{name}' in $input->{path} [type: $input->{type}] using $input_module",
335                            $input->{lookup} ? "lookup '$input->{lookup}'" : ""
336                    );
337    
338                    if ($stats) {
339                            # disable modification of records if --stats is in use
340                            delete($input->{modify_records});
341                            delete($input->{modify_file});
342                    }
343    
344                  my $input_db = new WebPAC::Input(                  my $input_db = new WebPAC::Input(
345                          module => $input_module,                          module => $input_module,
346                          code_page => $config->{webpac}->{webpac_encoding},                          encoding => $config->{webpac}->{webpac_encoding},
347                          limit => $limit || $input->{limit},                          limit => $limit || $input->{limit},
348                          offset => $offset,                          offset => $offset,
349                          lookup => $lookup,                          lookup_coderef => sub {
350                                    my $rec = shift || return;
351                                    $lookup->add( $rec );
352                            },
353                          recode => $input->{recode},                          recode => $input->{recode},
354                          stats => $stats,                          stats => $stats,
355                            modify_records => $input->{modify_records},
356                            modify_file => $input->{modify_file},
357                  );                  );
358                  $log->logdie("can't create input using $input_module") unless ($input);                  $log->logdie("can't create input using $input_module") unless ($input);
359    
360                  my $maxmfn = $input_db->open(                  my $maxmfn = $input_db->open(
361                          path => $input->{path},                          path => $input->{path},
362                          code_page => $input->{encoding},        # database encoding                          code_page => $input->{encoding},        # database encoding
363                            %{ $input },
364                  );                  );
365    
366                  my $n = new WebPAC::Normalize::XML(                  my @norm_array = ref($input->{normalize}) eq 'ARRAY' ?
367                  #       filter => { 'foo' => sub { shift } },                          @{ $input->{normalize} } : ( $input->{normalize} );
                         db => $db,  
                         lookup_regex => $lookup->regex,  
                         lookup => $lookup,  
                         prefix => $input->{name},  
                 );  
   
                 my $rules;  
                 my $normalize_path = $input->{normalize}->{path};  
368    
369                  if ($force_set) {                  if ($marc_normalize) {
370                          my $new_norm_path = $normalize_path;                          @norm_array = ( {
371                          $new_norm_path =~ s/\.xml$/.pl/;                                  path => $marc_normalize,
372                          if (-e $new_norm_path) {                                  output => $marc_output || 'out/marc/' . $database . '-' . $input->{name} . '.marc',
373                                  $log->debug("--force-set replaced $normalize_path with $new_norm_path");                          } );
                                 $normalize_path = $new_norm_path;  
                         } else {  
                                 $log->debug("--force-set failed on $new_norm_path, fallback to $normalize_path");  
                         }  
374                  }                  }
375    
376                  if ($normalize_path =~ m/\.xml$/i) {                  foreach my $normalize (@norm_array) {
                         $n->open(  
                                 tag => $input->{normalize}->{tag},  
                                 xml_file => $normalize_path,  
                         );  
                 } elsif ($normalize_path =~ m/\.(?:yml|yaml)$/i) {  
                         $n->open_yaml(  
                                 path => $normalize_path,  
                                 tag => $input->{normalize}->{tag},  
                         );  
                 } 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: $!";  
                 }  
377    
378                  foreach my $pos ( 0 ... $input_db->size ) {                          my $normalize_path = $normalize->{path} || $log->logdie("can't find normalize path in config");
379    
380                          my $row = $input_db->fetch || next;                          $log->logdie("Found '$normalize_path' as normalization file which isn't supported any more!") unless ( $normalize_path =~ m!\.pl$!i );
381    
382                          my $mfn = $row->{'000'}->[0];                          my $rules = read_file( $normalize_path ) or die "can't open $normalize_path: $!";
383    
384                          if (! $mfn || $mfn !~ m#^\d+$#) {                          $log->info("Using $normalize_path for normalization...");
                                 $log->warn("record $pos doesn't have valid MFN but '$mfn', using $pos");  
                                 $mfn = $pos;  
                                 push @{ $row->{'000'} }, $pos;  
                         }  
385    
386                                                            my $marc = new WebPAC::Output::MARC(
387                          my $ds;                                  path => $normalize->{output},
388                          if ($n) {                                  lint => $marc_lint,
389                                  $ds = $n->data_structure($row);                                  dump => $marc_dump,
390                          } else {                          ) if ($normalize->{output});
391                                  $ds = WebPAC::Normalize::Set::data_structure(  
392                            # reset position in database
393                            $input_db->seek(1);
394    
395                            foreach my $pos ( 0 ... $input_db->size ) {
396    
397                                    my $row = $input_db->fetch || next;
398    
399                                    my $mfn = $row->{'000'}->[0];
400    
401                                    if (! $mfn || $mfn !~ m#^\d+$#) {
402                                            $log->warn("record $pos doesn't have valid MFN but '$mfn', using $pos");
403                                            $mfn = $pos;
404                                            push @{ $row->{'000'} }, $pos;
405                                    }
406    
407    
408                                    if ($validate) {
409                                            if ( my $errors = $validate->validate_errors( $row, $input_db->dump ) ) {
410                                                    $log->error( "MFN $mfn validation error:\n",
411                                                            dump( $errors )
412                                                    );
413                                            }
414                                    }
415    
416                                    my $ds_config = dclone($db_config);
417    
418                                    # default values -> database key
419                                    $ds_config->{_} = $database;
420    
421                                    # current mfn
422                                    $ds_config->{_mfn} = $mfn;
423    
424                                    # attach current input
425                                    $ds_config->{input} = $input;
426    
427                                    my $ds = WebPAC::Normalize::data_structure(
428                                          row => $row,                                          row => $row,
429                                          rules => $rules,                                          rules => $rules,
430                                          lookup => $lookup->lookup_hash,                                          lookup => $lookup ? $lookup->lookup_hash : undef,
431                                            config => $ds_config,
432                                            marc_encoding => 'utf-8',
433                                  );                                  );
434    
435                                  $db->save_ds(                                  $db->save_ds(
# Line 278  while (my ($database, $db_config) = each Line 437  while (my ($database, $db_config) = each
437                                          ds => $ds,                                          ds => $ds,
438                                          prefix => $input->{name},                                          prefix => $input->{name},
439                                  ) if ($ds && !$stats);                                  ) if ($ds && !$stats);
440    
441                                    $indexer->add(
442                                            id => $input->{name} . "/" . $mfn,
443                                            ds => $ds,
444                                            type => $config->{$use_indexer}->{type},
445                                    ) if ($indexer && $ds);
446    
447                                    if ($marc) {
448                                            my $i = 0;
449    
450                                            while (my $fields = WebPAC::Normalize::_get_marc_fields( fetch_next => 1 ) ) {
451                                                    $marc->add(
452                                                            id => $mfn . ( $i ? "/$i" : '' ),
453                                                            fields => $fields,
454                                                            leader => WebPAC::Normalize::marc_leader(),
455                                                            row => $row,
456                                                    );
457                                                    $i++;
458                                            }
459    
460                                            $log->info("Created $i instances of MFN $mfn\n") if ($i > 1);
461                                    }
462    
463                                    $total_rows++;
464                          }                          }
465    
466                          $indexer->add(                          if ($validate) {
467                                  id => $input->{name} . "/" . $mfn,                                  my $errors = $validate->report;
468                                  ds => $ds,                                  $log->info("validation errors:\n$errors\n" ) if ($errors);
469                                  type => $config->{$use_indexer}->{type},                          }
                         ) if ($indexer);  
470    
471                          $total_rows++;                          $log->info("statistics of fields usage:\n", $input_db->stats) if ($stats);
                 }  
472    
473                  $log->info("statistics of fields usage:\n", $input_db->stats) if ($stats);                          # close MARC file
474                            $marc->finish if ($marc);
475    
476          };                  }
477    
478            }
479    
480          eval { $indexer->finish } if ($indexer && $indexer->can('finish'));          eval { $indexer->finish } if ($indexer && $indexer->can('finish'));
481    
# Line 302  while (my ($database, $db_config) = each Line 486  while (my ($database, $db_config) = each
486                  )                  )
487          );          );
488    
489          #  
490          # add Hyper Estraier links to other databases          # end forked process
491          #          if ($parallel) {
492          if (ref($db_config->{links}) eq 'ARRAY') {                  $log->info("parallel process $$ finished");
493                  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}]");  
                         }  
                 }  
494          }          }
495    
496  }  }
497    
498    if ($parallel) {
499            # wait all children to finish
500            sleep(1) while wait != -1;
501            $log->info("all parallel processes finished");
502    }
503    
504    #
505    # handle links or merge after indexing
506    #
507    
508    if ($merge) {
509            print $estcmd_fh 'sudo /etc/init.d/hyperestraier start',$/;
510            close($estcmd_fh);
511            chmod 0700, $estcmd_path || $log->warn("can't chmod 0700 $estcmd_path: $!");
512            system $estcmd_path;
513    } else {
514            foreach my $link (@links) {
515                    $log->logdie("coderef in link ", Dumper($link), " is ", ref($link), " and not CODE") unless (ref($link) eq 'CODE');
516                    $link->();
517            }
518    }

Legend:
Removed from v.512  
changed lines
  Added in v.664

  ViewVC Help
Powered by ViewVC 1.1.26