/[webpac2]/trunk/lib/WebPAC/Input.pm
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/lib/WebPAC/Input.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 634 by dpavlin, Wed Sep 6 18:08:30 2006 UTC revision 726 by dpavlin, Fri Sep 29 19:52:17 2006 UTC
# Line 16  WebPAC::Input - read different file form Line 16  WebPAC::Input - read different file form
16    
17  =head1 VERSION  =head1 VERSION
18    
19  Version 0.11  Version 0.13
20    
21  =cut  =cut
22    
23  our $VERSION = '0.11';  our $VERSION = '0.13';
24    
25  =head1 SYNOPSIS  =head1 SYNOPSIS
26    
# Line 98  sub new { Line 98  sub new {
98          $log->logconfess("lookup argument is not suppored any more. rewrite call to lookup_ref") if ($self->{lookup});          $log->logconfess("lookup argument is not suppored any more. rewrite call to lookup_ref") if ($self->{lookup});
99    
100          $log->logconfess("specify low-level file format module") unless ($self->{module});          $log->logconfess("specify low-level file format module") unless ($self->{module});
101          my $module = $self->{module};          my $module_path = $self->{module};
102          $module =~ s#::#/#g;          $module_path =~ s#::#/#g;
103          $module .= '.pm';          $module_path .= '.pm';
104          $log->debug("require low-level module $self->{module} from $module");          $log->debug("require low-level module $self->{module} from $module_path");
105    
106          require $module;          require $module_path;
         #eval $self->{module} .'->import';  
107    
108          # check if required subclasses are implemented          # check if required subclasses are implemented
109          foreach my $subclass (qw/open_db fetch_rec init/) {          foreach my $subclass (qw/open_db fetch_rec init dump_rec/) {
110                  my $n = $self->{module} . '::' . $subclass;                  # FIXME
                 if (! defined &{ $n }) {  
                         my $missing = "missing $subclass in $self->{module}";  
                         $self->{$subclass} = sub { $log->logwarn($missing) };  
                 } else {  
                         $self->{$subclass} = \&{ $n };  
                 }  
         }  
   
         if ($self->{init}) {  
                 $log->debug("calling init");  
                 $self->{init}->($self, @_);  
111          }          }
112    
113          $self->{'encoding'} ||= 'ISO-8859-2';          $self->{'encoding'} ||= 'ISO-8859-2';
# Line 162  This function will read whole database i Line 150  This function will read whole database i
150          code_page => 'cp852',          code_page => 'cp852',
151          limit => 500,          limit => 500,
152          offset => 6000,          offset => 6000,
         lookup => $lookup_obj,  
153          stats => 1,          stats => 1,
154          lookup_ref => sub {          lookup_coderef => sub {
155                  my ($k,$v) = @_;                  my $rec = shift;
156                  # store lookup $k => $v                  # store lookups
157          },          },
158          modify_records => {          modify_records => {
159                  900 => { '^a' => { ' : ' => '^b' } },                  900 => { '^a' => { ' : ' => '^b' } },
160                  901 => { '*' => { '^b' => ' ; ' } },                  901 => { '*' => { '^b' => ' ; ' } },
161          },          },
162            modify_file => 'conf/modify/mapping.map',
163   );   );
164    
165  By default, C<code_page> is assumed to be C<cp852>.  By default, C<code_page> is assumed to be C<cp852>.
# Line 182  C<limit> is optional parametar to read j Line 170  C<limit> is optional parametar to read j
170    
171  C<stats> create optional report about usage of fields and subfields  C<stats> create optional report about usage of fields and subfields
172    
173  C<lookup_coderef> is closure to call when adding C<< key => 'value' >> combinations to  C<lookup_coderef> is closure to called to save data into lookups
 lookup.  
174    
175  C<modify_records> specify mapping from subfields to delimiters or from  C<modify_records> specify mapping from subfields to delimiters or from
176  delimiters to subfields, as well as oprations on fields (if subfield is  delimiters to subfields, as well as oprations on fields (if subfield is
177  defined as C<*>.  defined as C<*>.
178    
179    C<modify_file> is alternative for C<modify_records> above which preserves order and offers
180    (hopefully) simplier sintax than YAML or perl (see L</modify_file_regex>). This option
181    overrides C<modify_records> if both exists for same input.
182    
183  Returns size of database, regardless of C<offset> and C<limit>  Returns size of database, regardless of C<offset> and C<limit>
184  parametars, see also C<size>.  parametars, see also C<size>.
185    
# Line 204  sub open { Line 195  sub open {
195          $log->logconfess("lookup_coderef must be CODE, not ",ref($arg->{lookup_coderef}))          $log->logconfess("lookup_coderef must be CODE, not ",ref($arg->{lookup_coderef}))
196                  if ($arg->{lookup_coderef} && ref($arg->{lookup_coderef}) ne 'CODE');                  if ($arg->{lookup_coderef} && ref($arg->{lookup_coderef}) ne 'CODE');
197    
198            $log->debug( $arg->{lookup_coderef} ? '' : 'not ', "using lookup_coderef");
199    
200          $log->logcroak("need path") if (! $arg->{'path'});          $log->logcroak("need path") if (! $arg->{'path'});
201          my $code_page = $arg->{'code_page'} || 'cp852';          my $code_page = $arg->{'code_page'} || 'cp852';
202    
# Line 235  sub open { Line 228  sub open {
228    
229          }          }
230    
231          my $rec_regex = $self->modify_record_regexps(%{ $arg->{modify_records} });          my $rec_regex;
232          $log->debug("rec_regex: ", Dumper($rec_regex));          if (my $p = $arg->{modify_file}) {
233                    $log->debug("using modify_file $p");
234                    $rec_regex = $self->modify_file_regexps( $p );
235            } elsif (my $h = $arg->{modify_records}) {
236                    $log->debug("using modify_records ", Dumper( $h ));
237                    $rec_regex = $self->modify_record_regexps(%{ $h });
238            }
239            $log->debug("rec_regex: ", Dumper($rec_regex)) if ($rec_regex);
240    
241          my ($db, $size) = $self->{open_db}->( $self,          my $class = $self->{module} || $log->logconfess("can't get low-level module name!");
242    
243            my $ll_db = $class->new(
244                  path => $arg->{path},                  path => $arg->{path},
245  #               filter => sub {  #               filter => sub {
246  #                       my ($l,$f_nr) = @_;  #                       my ($l,$f_nr) = @_;
# Line 250  sub open { Line 252  sub open {
252                  %{ $arg },                  %{ $arg },
253          );          );
254    
255          unless (defined($db)) {          unless (defined($ll_db)) {
256                  $log->logwarn("can't open database $arg->{path}, skipping...");                  $log->logwarn("can't open database $arg->{path}, skipping...");
257                  return;                  return;
258          }          }
259    
260            my $size = $ll_db->size;
261    
262          unless ($size) {          unless ($size) {
263                  $log->logwarn("no records in database $arg->{path}, skipping...");                  $log->logwarn("no records in database $arg->{path}, skipping...");
264                  return;                  return;
# Line 286  sub open { Line 290  sub open {
290    
291                  $log->debug("position: $pos\n");                  $log->debug("position: $pos\n");
292    
293                  my $rec = $self->{fetch_rec}->($self, $db, $pos, sub {                  my $rec = $ll_db->fetch_rec($pos, sub {
294                                  my ($l,$f_nr) = @_;                                  my ($l,$f_nr) = @_;
295  #                               return unless defined($l);  #                               return unless defined($l);
296  #                               return $l unless ($rec_regex && $f_nr);  #                               return $l unless ($rec_regex && $f_nr);
# Line 336  sub open { Line 340  sub open {
340                  if ($self->{stats}) {                  if ($self->{stats}) {
341    
342                          # fetch clean record with regexpes applied for statistics                          # fetch clean record with regexpes applied for statistics
343                          my $rec = $self->{fetch_rec}->($self, $db, $pos);                          my $rec = $ll_db->fetch_rec($pos);
344    
345                          foreach my $fld (keys %{ $rec }) {                          foreach my $fld (keys %{ $rec }) {
346                                  $self->{_stats}->{fld}->{ $fld }++;                                  $self->{_stats}->{fld}->{ $fld }++;
# Line 534  sub stats { Line 538  sub stats {
538          return $out;          return $out;
539  }  }
540    
541    =head2 dump
542    
543    Display humanly readable dump of record
544    
545    =cut
546    
547    sub dump {
548            my $self = shift;
549    
550            return $self->{dump_rec}->($self, $self->{pos});
551    
552    }
553    
554  =head2 modify_record_regexps  =head2 modify_record_regexps
555    
556  Generate hash with regexpes to be applied using L<filter>.  Generate hash with regexpes to be applied using l<filter>.
557    
558    my $regexpes = $input->modify_record_regexps(    my $regexpes = $input->modify_record_regexps(
559                  900 => { '^a' => { ' : ' => '^b' } },                  900 => { '^a' => { ' : ' => '^b' } },
# Line 545  Generate hash with regexpes to be applie Line 562  Generate hash with regexpes to be applie
562    
563  =cut  =cut
564    
565    sub _get_regex {
566            my ($sf,$from,$to) = @_;
567            if ($sf =~ /^\^/) {
568                    return
569                            's/\Q'. $sf .'\E([^\^]*?)\Q'. $from .'\E([^\^]*?)/'. $sf .'$1'. $to .'$2/';
570            } else {
571                    return
572                            's/\Q'. $from .'\E/'. $to .'/g';
573            }
574    }
575    
576  sub modify_record_regexps {  sub modify_record_regexps {
577          my $self = shift;          my $self = shift;
578          my $modify_record = {@_};          my $modify_record = {@_};
# Line 564  sub modify_record_regexps { Line 592  sub modify_record_regexps {
592                                  #die "no field?" unless defined($to);                                  #die "no field?" unless defined($to);
593                                  $log->debug("transform: |$from| -> |$to|");                                  $log->debug("transform: |$from| -> |$to|");
594    
595                                  if ($sf =~ /^\^/) {                                  my $regex = _get_regex($sf,$from,$to);
596                                          my $regex =                                  push @{ $regexpes->{$f} }, $regex;
597                                                  's/\Q'. $sf .'\E(.*?)\Q'. $from .'\E(.*?)/'. $sf .'$1'. $to .'$2/g';                                  $log->debug("regex: $regex");
                                         push @{ $regexpes->{$f} }, $regex;  
                                         $log->debug(">>>>> $regex [sf]");  
                                 } else {  
                                         my $regex =  
                                                 's/\Q'. $from .'\E/'. $to .'/g';  
                                         push @{ $regexpes->{$f} }, $regex;  
                                         $log->debug(">>>>> $regex [global]");  
                                 }  
   
598                          }                          }
599                  }                  }
600          }          }
601    
602            return $regexpes;
603    }
604    
605    =head2 modify_file_regexps
606    
607    Generate hash with regexpes to be applied using l<filter> from
608    pseudo hash/yaml format for regex mappings.
609    
610    It should be obvious:
611    
612            200
613              '^a'
614                ' : ' => '^e'
615                ' = ' => '^d'
616    
617    In field I<200> find C<'^a'> and then C<' : '>, and replace it with C<'^e'>.
618    In field I<200> find C<'^a'> and then C<' = '>, and replace it with C<'^d'>.
619    
620      my $regexpes = $input->modify_file_regexps( 'conf/modify/common.pl' );
621    
622    On undef path it will just return.
623    
624    =cut
625    
626    sub modify_file_regexps {
627            my $self = shift;
628    
629            my $modify_path = shift || return;
630    
631            my $log = $self->_get_logger();
632    
633            my $regexpes;
634    
635            CORE::open(my $fh, $modify_path) || $log->logdie("can't open modify file $modify_path: $!");
636    
637            my ($f,$sf);
638    
639            while(<$fh>) {
640                    chomp;
641                    next if (/^#/ || /^\s*$/);
642    
643                    if (/^\s*(\d+)\s*$/) {
644                            $f = $1;
645                            $log->debug("field: $f");
646                            next;
647                    } elsif (/^\s*'([^']*)'\s*$/) {
648                            $sf = $1;
649                            $log->die("can't define subfiled before field in: $_") unless ($f);
650                            $log->debug("subfield: $sf");
651                    } elsif (/^\s*'([^']*)'\s*=>\s*'([^']*)'\s*$/) {
652                            my ($from,$to) = ($1, $2);
653    
654                            $log->debug("transform: |$from| -> |$to|");
655    
656                            my $regex = _get_regex($sf,$from,$to);
657                            push @{ $regexpes->{$f} }, $regex;
658                            $log->debug("regex: $regex");
659                    }
660            }
661    
662          return $regexpes;          return $regexpes;
663  }  }
664    

Legend:
Removed from v.634  
changed lines
  Added in v.726

  ViewVC Help
Powered by ViewVC 1.1.26