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

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

  ViewVC Help
Powered by ViewVC 1.1.26