/[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 493 by dpavlin, Sun May 14 13:42:48 2006 UTC revision 606 by dpavlin, Tue Aug 1 13:59:47 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.07;
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;
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 42  limit loading to 100 records Line 47  limit loading to 100 records
47    
48  remove database and Hyper Estraier index before indexing  remove database and Hyper Estraier index before indexing
49    
50  =item --only=database_name  =item --only=database_name/input_filter
51    
52  reindex just single database (legacy name is --one)  reindex just single database (legacy name is --one)
53    
54    C</input_filter> is optional part which can be C<name>
55    or C<type> from input
56    
57  =item --config conf/config.yml  =item --config conf/config.yml
58    
59  path to YAML configuration file  path to YAML configuration file
60    
61  =item --force-set  =item --stats
62    
63    disable indexing and dump statistics about field and subfield
64    usage for each input
65    
66    =item --validate path/to/validation_file
67    
68    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  force conversion C<normalize->path> in C<config.yml> from  =item --marc-lint
79  C<.xml> to C<.pl>  
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  =back  =back
93    
# Line 65  my $limit; Line 99  my $limit;
99  my $clean = 0;  my $clean = 0;
100  my $config = 'conf/config.yml';  my $config = 'conf/config.yml';
101  my $debug = 0;  my $debug = 0;
102  my $only_db_name;  my $only_filter;
103  my $force_set = 0;  my $stats = 0;
104    my $validate_path;
105    my ($marc_normalize, $marc_output);
106    my $marc_lint = 1;
107    my $marc_dump = 0;
108    
109    my $parallel = 0;
110    
111  GetOptions(  GetOptions(
112          "limit=i" => \$limit,          "limit=i" => \$limit,
113          "offset=i" => \$offset,          "offset=i" => \$offset,
114          "clean" => \$clean,          "clean" => \$clean,
115          "one=s" => \$only_db_name,          "one=s" => \$only_filter,
116          "only=s" => \$only_db_name,          "only=s" => \$only_filter,
117          "config" => \$config,          "config" => \$config,
118          "debug" => \$debug,          "debug+" => \$debug,
119          "force-set" => \$force_set,          "stats" => \$stats,
120            "validate=s" => \$validate_path,
121            "marc-normalize=s" => \$marc_normalize,
122            "marc-output=s" => \$marc_output,
123            "marc-lint!" => \$marc_lint,
124            "marc-dump!" => \$marc_dump,
125            "parallel=i" => \$parallel,
126  );  );
127    
128  $config = LoadFile($config);  $config = LoadFile($config);
129    
130  print "config = ",Dumper($config) if ($debug);  print "config = ",dump($config) if ($debug);
131    
132  die "no databases in config file!\n" unless ($config->{databases});  die "no databases in config file!\n" unless ($config->{databases});
133    
134  my $log = _new WebPAC::Common()->_get_logger();  my $log = _new WebPAC::Common()->_get_logger();
135    $log->info( "-" x 79 );
136    
137    my $validate;
138    $validate = new WebPAC::Validate(
139            path => $validate_path,
140    ) if ($validate_path);
141    
142  my $use_indexer = $config->{use_indexer} || 'hyperestraier';  my $use_indexer = $config->{use_indexer} || 'hyperestraier';
143  $log->info("using $use_indexer indexing engine...");  if ($stats) {
144            $log->debug("option --stats disables update of indexing engine...");
145            $use_indexer = undef;
146    } else {
147            $log->info("using $use_indexer indexing engine...");
148    }
149    
150    # disable indexing when creating marc
151    $use_indexer = undef if ($marc_normalize);
152    
153  my $total_rows = 0;  my $total_rows = 0;
154  my $start_t = time();  my $start_t = time();
155    
156    my @links;
157    my $indexer;
158    
159    if ($parallel) {
160            $log->info("Using $parallel processes for speedup");
161            Proc::Queue::size($parallel);
162    }
163    
164  while (my ($database, $db_config) = each %{ $config->{databases} }) {  while (my ($database, $db_config) = each %{ $config->{databases} }) {
165    
166          next if ($only_db_name && $database !~ m/$only_db_name/i);          my ($only_database,$only_input) = split(m#/#, $only_filter) if ($only_filter);
167            next if ($only_database && $database !~ m/$only_database/i);
168    
169          my $indexer;          if ($parallel) {
170                    my $f=fork;
171                    if(defined ($f) and $f==0) {
172                            $log->info("Created processes $$ for speedup");
173                    } else {
174                            next;
175                    }
176            }
177    
178          my $indexer_config = $config->{$use_indexer} || $log->logdie("can't find '$use_indexer' part in confguration");          if ($use_indexer) {
179          $indexer_config->{database} = $database;                  my $indexer_config = $config->{$use_indexer} || $log->logdie("can't find '$use_indexer' part in confguration");
180          $indexer_config->{clean} = $clean;                  $indexer_config->{database} = $database;
181          $indexer_config->{label} = $db_config->{name};                  $indexer_config->{clean} = $clean;
182                    $indexer_config->{label} = $db_config->{name};
183          # important: clean database just once!  
184          $clean = 0;                  if ($use_indexer eq 'hyperestraier') {
185    
186          if ($use_indexer eq 'hyperestraier') {                          # open Hyper Estraier database
187                            use WebPAC::Output::Estraier '0.10';
188                  # open Hyper Estraier database                          $indexer = new WebPAC::Output::Estraier( %{ $indexer_config } );
189                  use WebPAC::Output::Estraier '0.10';                  
190                  $indexer = new WebPAC::Output::Estraier( %{ $indexer_config } );                  } elsif ($use_indexer eq 'kinosearch') {
191            
192          } elsif ($use_indexer eq 'kinosearch') {                          # open KinoSearch
193                            use WebPAC::Output::KinoSearch;
194                  # open KinoSearch                          $indexer_config->{clean} = 1 unless (-e $indexer_config->{index_path});
195                  use WebPAC::Output::KinoSearch;                          $indexer = new WebPAC::Output::KinoSearch( %{ $indexer_config } );
                 $indexer_config->{clean} = 1 unless (-e $indexer_config->{index_path});  
                 $indexer = new WebPAC::Output::KinoSearch( %{ $indexer_config } );  
196    
197          } else {                  } else {
198                  $log->logdie("unknown use_indexer: $use_indexer");                          $log->logdie("unknown use_indexer: $use_indexer");
199                    }
200    
201                    $log->logide("can't continue without valid indexer") unless ($indexer);
202          }          }
203    
         $log->logide("can't continue without valid indexer") unless ($indexer);  
204    
205          #          #
206          # now WebPAC::Store          # now WebPAC::Store
# Line 135  while (my ($database, $db_config) = each Line 211  while (my ($database, $db_config) = each
211          my $db_path = $config->{webpac}->{db_path} . '/' . $database;          my $db_path = $config->{webpac}->{db_path} . '/' . $database;
212    
213          if ($clean) {          if ($clean) {
214                  $log->info("creating new database $database in $db_path");                  $log->info("creating new database '$database' in $db_path");
215                  rmtree( $db_path ) || $log->warn("can't remove $db_path: $!");                  rmtree( $db_path ) || $log->warn("can't remove $db_path: $!");
216          } else {          } else {
217                  $log->debug("working on $database in $db_path");                  $log->info("working on database '$database' in $db_path");
218          }          }
219    
220          my $db = new WebPAC::Store(          my $db = new WebPAC::Store(
# Line 165  while (my ($database, $db_config) = each Line 241  while (my ($database, $db_config) = each
241    
242          foreach my $input (@inputs) {          foreach my $input (@inputs) {
243    
244                    next if ($only_input && ($input->{name} !~ m#$only_input#i && $input->{type} !~ m#$only_input#i));
245    
246                  my $type = lc($input->{type});                  my $type = lc($input->{type});
247    
248                  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));
249    
250                  my $lookup = new WebPAC::Lookup(                  my $lookup;
251                          lookup_file => $input->{lookup},                  if ($input->{lookup}) {
252                  );                          $lookup = new WebPAC::Lookup(
253                                    lookup_file => $input->{lookup},
254                            );
255                            delete( $input->{lookup} );
256                    }
257    
258                  my $input_module = $config->{webpac}->{inputs}->{$type};                  my $input_module = $config->{webpac}->{inputs}->{$type};
259    
260                  $log->info("working on input '$input->{path}' [$input->{type}] using $input_module lookup '$input->{lookup}'");                  $log->info("working on input '$input->{name}' in $input->{path} [type: $input->{type}] using $input_module",
261                            $input->{lookup} ? "lookup '$input->{lookup}'" : ""
262                    );
263    
264                  my $input_db = new WebPAC::Input(                  my $input_db = new WebPAC::Input(
265                          module => $input_module,                          module => $input_module,
266                          code_page => $config->{webpac}->{webpac_encoding},                          encoding => $config->{webpac}->{webpac_encoding},
267                          limit => $limit || $input->{limit},                          limit => $limit || $input->{limit},
268                          offset => $offset,                          offset => $offset,
269                          lookup => $lookup,                          lookup_coderef => sub {
270                                    my $rec = shift || return;
271                                    $lookup->add( $rec );
272                            },
273                          recode => $input->{recode},                          recode => $input->{recode},
274                            stats => $stats,
275                            modify_records => $input->{modify_records},
276                  );                  );
277                  $log->logdie("can't create input using $input_module") unless ($input);                  $log->logdie("can't create input using $input_module") unless ($input);
278    
279                  my $maxmfn = $input_db->open(                  my $maxmfn = $input_db->open(
280                          path => $input->{path},                          path => $input->{path},
281                          code_page => $input->{encoding},        # database encoding                          code_page => $input->{encoding},        # database encoding
282                            %{ $input },
283                  );                  );
284    
285                  my $n = new WebPAC::Normalize::XML(                  my @norm_array = ref($input->{normalize}) eq 'ARRAY' ?
286                  #       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};  
287    
288                  if ($force_set) {                  if ($marc_normalize) {
289                          my $new_norm_path = $normalize_path;                          @norm_array = ( {
290                          $new_norm_path =~ s/\.xml$/.pl/;                                  path => $marc_normalize,
291                          if (-e $new_norm_path) {                                  output => $marc_output || 'out/marc/' . $database . '-' . $input->{name} . '.marc',
292                                  $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");  
                         }  
293                  }                  }
294    
295                  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: $!";  
                 }  
296    
297                  foreach my $pos ( 0 ... $input_db->size ) {                          my $normalize_path = $normalize->{path} || $log->logdie("can't find normalize path in config");
298    
299                          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 );
300    
301                          my $mfn = $row->{'000'}->[0];                          my $rules = read_file( $normalize_path ) or die "can't open $normalize_path: $!";
302    
303                          if (! $mfn || $mfn !~ m#^\d+$#) {                          $log->info("Using $normalize_path for normalization...");
304                                  $log->warn("record $pos doesn't have valid MFN but '$mfn', using $pos");  
305                                  $mfn = $pos;                          my $marc = new WebPAC::Output::MARC(
306                                  push @{ $row->{'000'} }, $pos;                                  path => $normalize->{output},
307                          }                                  lint => $marc_lint,
308                                    dump => $marc_dump,
309                            ) if ($normalize->{output});
310    
311                            # reset position in database
312                            $input_db->seek(1);
313    
314                            foreach my $pos ( 0 ... $input_db->size ) {
315    
316                                    my $row = $input_db->fetch || next;
317    
318                                    my $mfn = $row->{'000'}->[0];
319    
320                                    if (! $mfn || $mfn !~ m#^\d+$#) {
321                                            $log->warn("record $pos doesn't have valid MFN but '$mfn', using $pos");
322                                            $mfn = $pos;
323                                            push @{ $row->{'000'} }, $pos;
324                                    }
325    
326    
327                                    if ($validate) {
328                                            my @errors = $validate->validate_errors( $row );
329                                            $log->error( "MFN $mfn validation errors:\n", join("\n", @errors) ) if (@errors);
330                                    }
331    
332                                    my $ds_config = dclone($db_config);
333    
334                                    # default values -> database key
335                                    $ds_config->{_} = $database;
336    
337                          my $ds = $n ? $n->data_structure($row) :                                  # current mfn
338                                  WebPAC::Normalize::Set::data_structure(                                  $ds_config->{_mfn} = $mfn;
339    
340                                    # attach current input
341                                    $ds_config->{input} = $input;
342    
343                                    my $ds = WebPAC::Normalize::data_structure(
344                                          row => $row,                                          row => $row,
345                                          rules => $rules,                                          rules => $rules,
346                                          lookup => $lookup->lookup_hash,                                          lookup => $lookup ? $lookup->lookup_hash : undef,
347                                            config => $ds_config,
348                                            marc_encoding => 'utf-8',
349                                  );                                  );
350    
351                          $indexer->add(                                  $db->save_ds(
352                                  id => $input->{name} . "/" . $mfn,                                          id => $mfn,
353                                  ds => $ds,                                          ds => $ds,
354                                  type => $config->{$use_indexer}->{type},                                          prefix => $input->{name},
355                          );                                  ) if ($ds && !$stats);
356    
357                                    $indexer->add(
358                                            id => $input->{name} . "/" . $mfn,
359                                            ds => $ds,
360                                            type => $config->{$use_indexer}->{type},
361                                    ) if ($indexer && $ds);
362    
363                                    if ($marc) {
364                                            my $i = 0;
365    
366                                            while (my $fields = WebPAC::Normalize::_get_marc_fields( fetch_next => 1 ) ) {
367                                                    $marc->add(
368                                                            id => $mfn . ( $i ? "/$i" : '' ),
369                                                            fields => $fields,
370                                                            leader => WebPAC::Normalize::marc_leader(),
371                                                            row => $row,
372                                                    );
373                                                    $i++;
374                                            }
375    
376                                            $log->info("Created $i instances of MFN $mfn\n") if ($i > 1);
377                                    }
378    
379                                    $total_rows++;
380                            }
381    
382                            $log->info("statistics of fields usage:\n", $input_db->stats) if ($stats);
383    
384                            # close MARC file
385                            $marc->finish if ($marc);
386    
                         $total_rows++;  
387                  }                  }
388    
389          };          }
390    
391          eval { $indexer->finish } if ($indexer->can('finish'));          eval { $indexer->finish } if ($indexer && $indexer->can('finish'));
392    
393          my $dt = time() - $start_t;          my $dt = time() - $start_t;
394          $log->info("$total_rows records indexed in " .          $log->info("$total_rows records ", $indexer ? "indexed " : "",
395                  sprintf("%.2f sec [%.2f rec/sec]",                  sprintf("in %.2f sec [%.2f rec/sec]",
396                          $dt, ($total_rows / $dt)                          $dt, ($total_rows / $dt)
397                  )                  )
398          );          );
# Line 272  while (my ($database, $db_config) = each Line 400  while (my ($database, $db_config) = each
400          #          #
401          # add Hyper Estraier links to other databases          # add Hyper Estraier links to other databases
402          #          #
403          if (ref($db_config->{links}) eq 'ARRAY') {          if (ref($db_config->{links}) eq 'ARRAY' && $use_indexer) {
404                  foreach my $link (@{ $db_config->{links} }) {                  foreach my $link (@{ $db_config->{links} }) {
405                          if ($use_indexer eq 'hyperestraier') {                          if ($use_indexer eq 'hyperestraier') {
406                                  $log->info("adding link $database -> $link->{to} [$link->{credit}]");                                  $log->info("saving link $database -> $link->{to} [$link->{credit}]");
407                                  $indexer->add_link(                                  push @links, {
408                                          from => $database,                                          from => $database,
409                                          to => $link->{to},                                          to => $link->{to},
410                                          credit => $link->{credit},                                          credit => $link->{credit},
411                                  );                                  };
412                          } else {                          } else {
413                                  $log->warn("NOT IMPLEMENTED WITH $use_indexer: adding link $database -> $link->{to} [$link->{credit}]");                                  $log->warn("NOT IMPLEMENTED WITH $use_indexer: adding link $database -> $link->{to} [$link->{credit}]");
414                          }                          }
415                  }                  }
416          }          }
417    
418            # end forked process
419            if ($parallel) {
420                    $log->info("parallel process $$ finished");
421                    exit(0);
422            }
423    
424    }
425    
426    if ($parallel) {
427            # wait all children to finish
428            sleep(1) while wait != -1;
429            $log->info("all parallel processes finished");
430    }
431    
432    foreach my $link (@links) {
433            $log->info("adding link $link->{from} -> $link->{to} [$link->{credit}]");
434            $indexer->add_link( %{ $link } );
435  }  }
436    

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

  ViewVC Help
Powered by ViewVC 1.1.26