/[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 335 by dpavlin, Sat Dec 31 14:00:36 2005 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;
14  use WebPAC::Output::TT;  use WebPAC::Output::TT;
15  use WebPAC::Output::Estraier 0.08;  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/;
21    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 40  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 --one=database_name  =item --only=database_name/input_filter
51    
52    reindex just single database (legacy name is --one)
53    
54  reindex just single database  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 --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    =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  =back  =back
93    
94  =cut  =cut
# Line 58  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 $one_db_name;  my $only_filter;
103    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" => \$one_db_name,          "one=s" => \$only_filter,
116            "only=s" => \$only_filter,
117          "config" => \$config,          "config" => \$config,
118          "debug" => \$debug,          "debug+" => \$debug,
119            "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();
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';
143    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();
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 ($one_db_name && $database !~ m/$one_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 $log = _new WebPAC::Common()->_get_logger();          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          #          if ($use_indexer) {
179          # open Hyper Estraier database                  my $indexer_config = $config->{$use_indexer} || $log->logdie("can't find '$use_indexer' part in confguration");
180          #                  $indexer_config->{database} = $database;
181                    $indexer_config->{clean} = $clean;
182                    $indexer_config->{label} = $db_config->{name};
183    
184                    if ($use_indexer eq 'hyperestraier') {
185    
186                            # open Hyper Estraier database
187                            use WebPAC::Output::Estraier '0.10';
188                            $indexer = new WebPAC::Output::Estraier( %{ $indexer_config } );
189                    
190                    } elsif ($use_indexer eq 'kinosearch') {
191    
192                            # open KinoSearch
193                            use WebPAC::Output::KinoSearch;
194                            $indexer_config->{clean} = 1 unless (-e $indexer_config->{index_path});
195                            $indexer = new WebPAC::Output::KinoSearch( %{ $indexer_config } );
196    
197          my $est_config = $config->{hyperestraier} || $log->logdie("can't find 'hyperestraier' part in confguration");                  } else {
198          $est_config->{database} = $database;                          $log->logdie("unknown use_indexer: $use_indexer");
199          $est_config->{clean} = $clean;                  }
200    
201                    $log->logide("can't continue without valid indexer") unless ($indexer);
202            }
203    
         my $est = new WebPAC::Output::Estraier( %{ $est_config } );  
204    
205          #          #
206          # now WebPAC::Store          # now WebPAC::Store
# Line 102  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->info("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 132  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");                  $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},
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 $normalize_path = $input->{normalize}->{path};  
287    
288                  if ($normalize_path =~ m/\.xml$/i) {                  if ($marc_normalize) {
289                          $n->open(                          @norm_array = ( {
290                                  tag => $input->{normalize}->{tag},                                  path => $marc_normalize,
291                                  xml_file => $input->{normalize}->{path},                                  output => $marc_output || 'out/marc/' . $database . '-' . $input->{name} . '.marc',
292                          );                          } );
                 } elsif ($normalize_path =~ m/\.(?:yml|yaml)$/i) {  
                         $n->open_yaml(  
                                 path => $normalize_path,  
                                 tag => $input->{normalize}->{tag},  
                         );  
293                  }                  }
294    
295                  foreach my $pos ( 0 ... $input_db->size ) {                  foreach my $normalize (@norm_array) {
296    
297                            my $normalize_path = $normalize->{path} || $log->logdie("can't find normalize path in config");
298    
299                            $log->logdie("Found '$normalize_path' as normalization file which isn't supported any more!") unless ( $normalize_path =~ m!\.pl$!i );
300    
301                            my $rules = read_file( $normalize_path ) or die "can't open $normalize_path: $!";
302    
303                            $log->info("Using $normalize_path for normalization...");
304    
305                            my $marc = new WebPAC::Output::MARC(
306                                    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 $row = $input_db->fetch || next;                                  # current mfn
338                                    $ds_config->{_mfn} = $mfn;
339    
340                          my $mfn = $row->{'000'}->[0];                                  # attach current input
341                                    $ds_config->{input} = $input;
342    
343                          if (! $mfn || $mfn !~ m#^\d+$#) {                                  my $ds = WebPAC::Normalize::data_structure(
344                                  $log->warn("record $pos doesn't have valid MFN but '$mfn', using $pos");                                          row => $row,
345                                  $mfn = $pos;                                          rules => $rules,
346                                  push @{ $row->{'000'} }, $pos;                                          lookup => $lookup ? $lookup->lookup_hash : undef,
347                                            config => $ds_config,
348                                            marc_encoding => 'utf-8',
349                                    );
350    
351                                    $db->save_ds(
352                                            id => $mfn,
353                                            ds => $ds,
354                                            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                          my $ds = $n->data_structure($row);                          $log->info("statistics of fields usage:\n", $input_db->stats) if ($stats);
383    
384                          $est->add(                          # close MARC file
385                                  id => $input->{name} . "/" . $mfn,                          $marc->finish if ($marc);
                                 ds => $ds,  
                                 type => $config->{hyperestraier}->{type},  
                         );  
386    
                         $total_rows++;  
387                  }                  }
388    
389          };          }
390    
391            eval { $indexer->finish } if ($indexer && $indexer->can('finish'));
392    
393          $log->info("$total_rows records indexed");          my $dt = time() - $start_t;
394            $log->info("$total_rows records ", $indexer ? "indexed " : "",
395                    sprintf("in %.2f sec [%.2f rec/sec]",
396                            $dt, ($total_rows / $dt)
397                    )
398            );
399    
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                          $log->info("adding link $database -> $link->{to} [$link->{credit}]");                          if ($use_indexer eq 'hyperestraier') {
406                          $est->add_link(                                  $log->info("saving link $database -> $link->{to} [$link->{credit}]");
407                                  from => $database,                                  push @links, {
408                                  to => $link->{to},                                          from => $database,
409                                  credit => $link->{credit},                                          to => $link->{to},
410                          );                                          credit => $link->{credit},
411                                    };
412                            } else {
413                                    $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.335  
changed lines
  Added in v.606

  ViewVC Help
Powered by ViewVC 1.1.26