/[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 301 by dpavlin, Mon Dec 19 21:26:04 2005 UTC revision 581 by dpavlin, Tue Jul 4 11:36:12 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;
11  use WebPAC::Input 0.03;  use WebPAC::Input 0.03;
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.05;  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    
24  =head1 NAME  =head1 NAME
25    
# Line 40  limit loading to 100 records Line 43  limit loading to 100 records
43    
44  remove database and Hyper Estraier index before indexing  remove database and Hyper Estraier index before indexing
45    
46    =item --only=database_name/input_filter
47    
48    reindex just single database (legacy name is --one)
49    
50    C</input_filter> is optional part which can be C<name>
51    or C<type> from input
52    
53  =item --config conf/config.yml  =item --config conf/config.yml
54    
55  path to YAML configuration file  path to YAML configuration file
56    
57    =item --stats
58    
59    disable indexing and dump statistics about field and subfield
60    usage for each input
61    
62    =item --validate path/to/validation_file
63    
64    turn on extra validation of imput records, see L<WebPAC::Validation>
65    
66    =item --marc-normalize conf/normalize/mapping.pl
67    
68    This option specifies normalisation file for MARC creation
69    
70    =item --marc-output out/marc/test.marc
71    
72    Optional path to output file
73    
74    =item --marc-lint
75    
76    By default turned on if C<--marc-normalize> is used. You can disable lint
77    messages with C<--no-marc-lint>.
78    
79    =item --marc-dump
80    
81    Force dump or input and marc record for debugging.
82    
83  =back  =back
84    
85  =cut  =cut
# Line 54  my $limit; Line 90  my $limit;
90  my $clean = 0;  my $clean = 0;
91  my $config = 'conf/config.yml';  my $config = 'conf/config.yml';
92  my $debug = 0;  my $debug = 0;
93    my $only_filter;
94    my $stats = 0;
95    my $validate_path;
96    my ($marc_normalize, $marc_output);
97    my $marc_lint = 1;
98    my $marc_dump = 0;
99    
100  GetOptions(  GetOptions(
101          "limit=i" => \$limit,          "limit=i" => \$limit,
102          "offset=i" => \$offset,          "offset=i" => \$offset,
103          "clean" => \$clean,          "clean" => \$clean,
104            "one=s" => \$only_filter,
105            "only=s" => \$only_filter,
106          "config" => \$config,          "config" => \$config,
107          "debug" => \$debug,          "debug+" => \$debug,
108            "stats" => \$stats,
109            "validate=s" => \$validate_path,
110            "marc-normalize=s" => \$marc_normalize,
111            "marc-output=s" => \$marc_output,
112            "marc-lint!" => \$marc_lint,
113            "marc-dump!" => \$marc_dump,
114  );  );
115    
116  $config = LoadFile($config);  $config = LoadFile($config);
117    
118  print "config = ",Dumper($config) if ($debug);  print "config = ",dump($config) if ($debug);
119    
120  die "no databases in config file!\n" unless ($config->{databases});  die "no databases in config file!\n" unless ($config->{databases});
121    
122    my $log = _new WebPAC::Common()->_get_logger();
123    $log->info( "-" x 79 );
124    
125    my $validate;
126    $validate = new WebPAC::Validate(
127            path => $validate_path,
128    ) if ($validate_path);
129    
130    my $use_indexer = $config->{use_indexer} || 'hyperestraier';
131    if ($stats) {
132            $log->debug("option --stats disables update of indexing engine...");
133            $use_indexer = undef;
134    } else {
135            $log->info("using $use_indexer indexing engine...");
136    }
137    
138    # disable indexing when creating marc
139    $use_indexer = undef if ($marc_normalize);
140    
141  my $total_rows = 0;  my $total_rows = 0;
142    my $start_t = time();
143    
144    my @links;
145    my $indexer;
146    
147  while (my ($database, $db_config) = each %{ $config->{databases} }) {  while (my ($database, $db_config) = each %{ $config->{databases} }) {
148    
149          my $log = _new WebPAC::Common()->_get_logger();          my ($only_database,$only_input) = split(m#/#, $only_filter) if ($only_filter);
150            next if ($only_database && $database !~ m/$only_database/i);
151    
152          #          if ($use_indexer) {
153          # open Hyper Estraier database                  my $indexer_config = $config->{$use_indexer} || $log->logdie("can't find '$use_indexer' part in confguration");
154          #                  $indexer_config->{database} = $database;
155                    $indexer_config->{clean} = $clean;
156          my $est_config = $config->{hyperestraier} || $log->logdie("can't find 'hyperestraier' part in confguration");                  $indexer_config->{label} = $db_config->{name};
157          $est_config->{database} = $database;  
158                    if ($use_indexer eq 'hyperestraier') {
159    
160                            # open Hyper Estraier database
161                            use WebPAC::Output::Estraier '0.10';
162                            $indexer = new WebPAC::Output::Estraier( %{ $indexer_config } );
163                    
164                    } elsif ($use_indexer eq 'kinosearch') {
165    
166                            # open KinoSearch
167                            use WebPAC::Output::KinoSearch;
168                            $indexer_config->{clean} = 1 unless (-e $indexer_config->{index_path});
169                            $indexer = new WebPAC::Output::KinoSearch( %{ $indexer_config } );
170    
171          my $est = new WebPAC::Output::Estraier(                  } else {
172                  %{ $est_config },                          $log->logdie("unknown use_indexer: $use_indexer");
173          );                  }
174    
175          if ($clean) {                  $log->logide("can't continue without valid indexer") unless ($indexer);
                 $log->warn("creating new empty index $database");  
                 $est->master( action => 'nodedel', name => $database );  
                 $est->master( action => 'nodeadd', name => $database, label => $database );  
176          }          }
177    
178    
179          #          #
180          # now WebPAC::Store          # now WebPAC::Store
181          #          #
# Line 101  while (my ($database, $db_config) = each Line 185  while (my ($database, $db_config) = each
185          my $db_path = $config->{webpac}->{db_path} . '/' . $database;          my $db_path = $config->{webpac}->{db_path} . '/' . $database;
186    
187          if ($clean) {          if ($clean) {
188                  $log->info("creating new database $database in $db_path");                  $log->info("creating new database '$database' in $db_path");
189                  rmtree( $db_path ) || $log->warn("can't remove $db_path: $!");                  rmtree( $db_path ) || $log->warn("can't remove $db_path: $!");
190          } else {          } else {
191                  $log->info("working on $database in $db_path");                  $log->info("working on database '$database' in $db_path");
192          }          }
193    
194          my $db = new WebPAC::Store(          my $db = new WebPAC::Store(
# Line 131  while (my ($database, $db_config) = each Line 215  while (my ($database, $db_config) = each
215    
216          foreach my $input (@inputs) {          foreach my $input (@inputs) {
217    
218                    next if ($only_input && ($input->{name} !~ m#$only_input#i && $input->{type} !~ m#$only_input#i));
219    
220                  my $type = lc($input->{type});                  my $type = lc($input->{type});
221    
222                  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));
223    
224                  my $lookup = new WebPAC::Lookup(                  my $lookup = new WebPAC::Lookup(
225                          lookup_file => $input->{lookup},                          lookup_file => $input->{lookup},
226                  );                  ) if ($input->{lookup});
227    
228                  my $input_module = $config->{webpac}->{inputs}->{$type};                  my $input_module = $config->{webpac}->{inputs}->{$type};
229    
230                  $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",
231                            $input->{lookup} ? "lookup '$input->{lookup}'" : ""
232                    );
233    
234                  my $input_db = new WebPAC::Input(                  my $input_db = new WebPAC::Input(
235                          module => $input_module,                          module => $input_module,
# Line 149  while (my ($database, $db_config) = each Line 237  while (my ($database, $db_config) = each
237                          limit => $limit || $input->{limit},                          limit => $limit || $input->{limit},
238                          offset => $offset,                          offset => $offset,
239                          lookup => $lookup,                          lookup => $lookup,
240                            recode => $input->{recode},
241                            stats => $stats,
242                  );                  );
243                  $log->logdie("can't create input using $input_module") unless ($input);                  $log->logdie("can't create input using $input_module") unless ($input);
244    
245                  my $maxmfn = $input_db->open(                  my $maxmfn = $input_db->open(
246                          path => $input->{path},                          path => $input->{path},
247                          code_page => $input->{encoding},        # database encoding                          code_page => $input->{encoding},        # database encoding
248                            %{ $input },
249                  );                  );
250    
251                  my $n = new WebPAC::Normalize::XML(                  my @norm_array = ref($input->{normalize}) eq 'ARRAY' ?
252                  #       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};  
253    
254                  if ($normalize_path =~ m/\.xml$/i) {                  if ($marc_normalize) {
255                          $n->open(                          @norm_array = ( {
256                                  tag => $input->{normalize}->{tag},                                  path => $marc_normalize,
257                                  xml_file => $input->{normalize}->{path},                                  output => $marc_output || 'out/marc/' . $database . '-' . $input->{name} . '.marc',
258                          );                          } );
                 } elsif ($normalize_path =~ m/\.(?:yml|yaml)$/i) {  
                         $n->open_yaml(  
                                 path => $normalize_path,  
                                 tag => $input->{normalize}->{tag},  
                         );  
259                  }                  }
260    
261                  foreach my $pos ( 0 ... $input_db->size ) {                  foreach my $normalize (@norm_array) {
262    
263                            my $normalize_path = $normalize->{path} || $log->logdie("can't find normalize path in config");
264    
265                            $log->logdie("Found '$normalize_path' as normalization file which isn't supported any more!") unless ( $normalize_path =~ m!\.pl$!i );
266    
267                            my $rules = read_file( $normalize_path ) or die "can't open $normalize_path: $!";
268    
269                            $log->info("Using $normalize_path for normalization...");
270    
271                            my $marc = new WebPAC::Output::MARC(
272                                    path => $normalize->{output},
273                                    lint => $marc_lint,
274                                    dump => $marc_dump,
275                            ) if ($normalize->{output});
276    
277                            # reset position in database
278                            $input_db->seek(1);
279    
280                            foreach my $pos ( 0 ... $input_db->size ) {
281    
282                                    my $row = $input_db->fetch || next;
283    
284                          my $row = $input_db->fetch || next;                                  my $mfn = $row->{'000'}->[0];
285    
286                          my $mfn = $row->{'000'}->[0];                                  if (! $mfn || $mfn !~ m#^\d+$#) {
287                                            $log->warn("record $pos doesn't have valid MFN but '$mfn', using $pos");
288                                            $mfn = $pos;
289                                            push @{ $row->{'000'} }, $pos;
290                                    }
291    
292                          if (! $mfn || $mfn !~ m#^\d+$#) {  
293                                  $log->warn("record $pos doesn't have valid MFN but '$mfn', using $pos");                                  if ($validate) {
294                                  $mfn = $pos;                                          my @errors = $validate->validate_errors( $row );
295                                  push @{ $row->{'000'} }, $pos;                                          $log->error( "MFN $mfn validation errors:\n", join("\n", @errors) ) if (@errors);
296                                    }
297    
298                                    my $ds = WebPAC::Normalize::data_structure(
299                                            row => $row,
300                                            rules => $rules,
301                                            lookup => $lookup ? $lookup->lookup_hash : undef,
302                                            marc_encoding => 'utf-8',
303                                    );
304    
305                                    $db->save_ds(
306                                            id => $mfn,
307                                            ds => $ds,
308                                            prefix => $input->{name},
309                                    ) if ($ds && !$stats);
310    
311                                    $indexer->add(
312                                            id => $input->{name} . "/" . $mfn,
313                                            ds => $ds,
314                                            type => $config->{$use_indexer}->{type},
315                                    ) if ($indexer && $ds);
316    
317                                    if ($marc) {
318                                            my $i = 0;
319    
320                                            while (my $fields = WebPAC::Normalize::_get_marc_fields( fetch_next => 1 ) ) {
321                                                    $marc->add(
322                                                            id => $mfn . ( $i ? "/$i" : '' ),
323                                                            fields => $fields,
324                                                            leader => WebPAC::Normalize::marc_leader(),
325                                                            row => $row,
326                                                    );
327                                                    $i++;
328                                            }
329    
330                                            $log->info("Created $i instances of MFN $mfn\n") if ($i > 1);
331                                    }
332    
333                                    $total_rows++;
334                          }                          }
335    
336                          my $ds = $n->data_structure($row);                          $log->info("statistics of fields usage:\n", $input_db->stats) if ($stats);
337    
338                          $est->add(                          # close MARC file
339                                  id => $input->{name} . "/" . $mfn,                          $marc->finish if ($marc);
                                 ds => $ds,  
                                 type => $config->{hyperestraier}->{type},  
                         );  
340    
                         $total_rows++;  
341                  }                  }
342    
343          };          }
344    
345            eval { $indexer->finish } if ($indexer && $indexer->can('finish'));
346    
347          $log->info("$total_rows records indexed");          my $dt = time() - $start_t;
348            $log->info("$total_rows records ", $indexer ? "indexed " : "",
349                    sprintf("in %.2f sec [%.2f rec/sec]",
350                            $dt, ($total_rows / $dt)
351                    )
352            );
353    
354          #          #
355          # add Hyper Estraier links to other databases          # add Hyper Estraier links to other databases
356          #          #
357          if (ref($db_config->{links}) eq 'ARRAY') {          if (ref($db_config->{links}) eq 'ARRAY' && $use_indexer) {
358                  foreach my $link (@{ $db_config->{links} }) {                  foreach my $link (@{ $db_config->{links} }) {
359                          $log->info("adding link $database -> $link->{to} [$link->{credit}]");                          if ($use_indexer eq 'hyperestraier') {
360                          $est->add_link(                                  $log->info("saving link $database -> $link->{to} [$link->{credit}]");
361                                  from => $database,                                  push @links, {
362                                  to => $link->{to},                                          from => $database,
363                                  credit => $link->{credit},                                          to => $link->{to},
364                          );                                          credit => $link->{credit},
365                                    };
366                            } else {
367                                    $log->warn("NOT IMPLEMENTED WITH $use_indexer: adding link $database -> $link->{to} [$link->{credit}]");
368                            }
369                  }                  }
370          }          }
371    
372  }  }
373    
374    foreach my $link (@links) {
375            $log->info("adding link $link->{from} -> $link->{to} [$link->{credit}]");
376            $indexer->add_link( %{ $link } );
377    }

Legend:
Removed from v.301  
changed lines
  Added in v.581

  ViewVC Help
Powered by ViewVC 1.1.26