package Ernad::Learn::Common; use strict; use warnings; use Carp qw(cluck longmess shortmess croak confess); use Data::Dumper; use Ernad::Dates; sub version_from_dates { my $dates=shift; if(not ref($dates) eq 'HASH') { confess "I need a dates hash here."; } my $ext=&Ernad::Common::find_extreme_issuedates($dates); my $max=$ext->{'max'} or confess "I can't find a maximum."; my $min=$ext->{'min'} or confess "I can't find a mimimum."; my $version=$min.'_'.$max; return $version; } ## an optional range check sub check_range { my $o=shift; my $date=shift // confess 'no input date in check_range'; if(not defined($o->{'end_issuedate'}) and not defined($o->{'start_issuedate'})) { return 1; } my $end=$o->{'end_issuedate'}; if(defined($end)) { if(&Ernad::Common::compare_date($date,$end) < 0) { $o->{'e'}->echo(__LINE__,"date $date is later than the limit $end"); return 0; } } my $start=$o->{'start_issuedate'}; if(defined($start)) { if(not defined($o->{'start_issuedate'})) { confess "start_issuedate not defined."; } } if(&Ernad::Common::compare_date($date,$start) > 0) { $o->{'e'}->echo(__LINE__,"date $date is later than the limit $start"); return 0; } return 1; } ## set the fitport sub set_fitport { my $o=shift; my $given_report=$o->{'report'} // ''; ## allow repcode as an alias if(not $given_report and defined($o->{'repcode'})) { $given_report=$o->{'repcode'} } if(defined($o->{'fitport'})) { my $fitport=$o->{'fitport'}; $o->{'e'}->{'fitport'}=$fitport; $o->{'e'}->echo(__LINE__,"fitport is already defined as '$fitport'",2); return; } ## find the fitport my $allport=$o->{'e'}->get_allport_repcode() // ''; if(not $allport) { confess "I need an allport defined here"; } if(not $given_report) { $o->{'fitport'}=$allport; return; } ## for a fitport onther than the allport, a terms exfit must be ## present. It is that one that has te be cohcked. my $exfit_xslt_file=&find_exfit_xslt_file($o,'term',$given_report); if(-f $exfit_xslt_file) { $o->{'fitport'}=$given_report; $o->{'e'}->{'fitport'}=$o->{'fitport'}; $o->{'e'}->echo(__LINE__,"I will be using a non-allport fitport ".$o->{'fitport'},2); $o->{'fitport'}=$given_report; return; } $o->{'e'}->{'fitport'}=$o->{'fitport'}; } ## returns the fitport for a report sub get_fitport { my $o=shift; my $repcode=shift // confess "I need a report here"; ## for a fitport onther than the allport, a terms exfit must be ## present. It is that one that has te be cohcked. my $exfit_xslt_file=&find_exfit_xslt_file($o,'term',$repcode); if(-f $exfit_xslt_file) { $o->{'e'}->echo(__LINE__,"I will be using a non-allport fitport $repcode",2); $o->{'fitport'}=$repcode; return $repcode; } my $allport=$o->{'e'}->get_allport_repcode(); $o->{'fitport'}=$allport // confess "I need an allport set here."; return $o->{'allport'}; } sub set_basic { my $o=shift; my $arg_time=shift // ''; ## fixme: this needs more coherent internal logic my $e=$o->{'e'} // confess "I need an erimp here"; $o->{'learn_dir'}=$e->{'dir'}->{'learn'} or confess "I need a learn_dir here"; my $learn_dir=$o->{'learn_dir'}; ## with allport if(not $e->{'dir'}->{'namf'} or (not -d $e->{'dir'}->{'namf'})) { $o->{'allport'}=$e->get_allport_repcode() or confess "I need an allport here"; } ## without allport else { #$o->{'allport'}=$e->{'repcode'} // confess "I need a repcode here."; ## removed on 2017-04-13 my $repcode=$o->{'repcode'} // confess "I need a repcode here."; $o->{'fitport'}=$repcode; } #my $allport=$o->{'allport'}; my $exfit_dir; if(defined($o->{'fitport'})) { $exfit_dir=$o->{'exfit_dir'}=$learn_dir.'/exfit/'.$o->{'fitport'}; } else { $exfit_dir=$o->{'exfit_dir'}=$learn_dir.'/exfit/'.$o->{'allport'}; } $o->{$exfit_dir}=$exfit_dir; my $fitar_dir=$o->{'exfit_dir'} or confess "I don't have an exfit_dir."; $fitar_dir=~s|/exfit/|/fitar/|; $o->{'fitar_dir'}=$fitar_dir; my $fidek_dir=$o->{'exfit_dir'}; $fidek_dir=~s|/exfit/|/fidek/|; $o->{'fidek_dir'}=$fidek_dir; my $isink_dir=$learn_dir.'/isink'; $o->{'isink_dir'}=$isink_dir; my $mocla_dir=$learn_dir.'/mocla'; $o->{'mocla_dir'}=$mocla_dir; my $lisig_dir=$learn_dir.'/lisig'; if($e->{'conf'}->{'separate_doklis'}) { my $repcode=$o->{'repcode'} // confess "I need a repcode here."; $lisig_dir="$lisig_dir/$repcode"; } $o->{'lisig_dir'}=$lisig_dir; my $time; if($arg_time) { $time=$arg_time; } elsif($o->{'update_time'}) { $time=$o->{'update_time'}; } elsif(defined($o->{'time'})) { $time=$o->{'time'}; } else { my $ref=ref $o; $o->{'e'}->echo(__LINE__,"I have no time for $ref. I use the current time."); $o->{'time'}=time; $time=$o->{'time'}; } &set_issuedates($o); my $file_version=$o->{'version'}.'_'.$time; $o->{'file_version'}=$file_version; foreach my $fitcla (@{$o->{'fitclas'}}) { $o->{'fitar_file'}->{$fitcla}=$o->{'fitar_dir'}.'/'.$file_version.'_'.$fitcla.'.txt'; $o->{'all_fitar_file'}->{$fitcla}=$o->{'fitar_dir'}.'/'.$file_version.'.txt'; $o->{'fidek_file'}->{$fitcla}=$o->{'fidek_dir'}.'/'.$file_version.'_'.$fitcla.'.dump'; } my $ookli_dir=$o->{'exfit_dir'}; $ookli_dir=~s|/exfit/|/dokli/|; $o->{'dokli_dir'}=$ookli_dir; $o->{'all_dokli_glob'}=$o->{'dokli_dir'}.'/*.txt'; $o->{'fitrank_file'}=$o->{'fitar_dir'}.'/fitrank_'.$time.'.dump'; &set_fitport($o); } ## unclear whether this is all issuedates ever on only those by report. ## take allport_sent interpretation ## not used for isinks sub set_issuedates { my $o=shift; my $e=$o->{'e'} or confess "I need an Erimp here"; ## the second and third argument are completely optional in the call. ## they may be set manually at invocation my $source_dir=$e->{'dir'}->{'allport_sent'}; if(not defined($source_dir)) { $source_dir=$e->{'dir'}->{'namf'} // confess "I need a namf dir here."; } my $dates; ### if the source dir is the allport_sent dir if($source_dir) { $dates=&Ernad::Common::find_hash_of_dates_in_dir($source_dir, $o->{'start_issuedate'}, $o->{'end_issuedate'}); } ## if there is no such directory, we need to find it from the source of #else { # $source_dir=$e->{'report'}->{$e->{'repcode'}}->{'dir'}->{'source'} # // confess "I need a source_dir here."; # $dates=&Ernad::Common::find_hash_of_dates_in_subdir($source_dir, # $o->{'start_issuedate'}, # $o->{'end_issuedate'}); #} if(not defined($dates)) { $e->echo(__LINE__,"I seem to have no issuedates to learn from."); exit; } my $ext=&Ernad::Common::find_extreme_issuedates($dates); my $max=$ext->{'max'} or confess "I can't see the minimum"; my $min=$ext->{'min'} or confess "I can't see the maximum"; my $train_limit=$e->{'conf'}->{'train_limit_by_days'} // confess "I don't see the train_limit_by_days"; if($train_limit) { $o->{'ernad_limit_by_days'}=$train_limit; $o->{'e'}->echo(__LINE__,"in set_issuedates, train limit by days set to $train_limit",4); } else { $o->{'ernad_limit_by_days'}=0; } ## the ernad limit must be defined, it may be zero if(not defined($o->{'ernad_limit_by_days'})) { confess 'I need an ernad_limit_by_days defined here.'; } my $elbyd=$o->{'ernad_limit_by_days'}; ## implement a system-wide limit, but saves all the issuedate into ## all_issuedates. This is may be used for frex parsing foreach my $date (keys %$dates) { $o->{'all_issuedates'}->{$date}=1; if($elbyd and &Ernad::Dates::diff_dates($date,$max) > $elbyd) { #print ref $o; if(not defined($o->{'verbose'})) { my $ref=ref $o; die "object of $ref has no verbosity set"; } $o->{'e'}->echo(__LINE__,"I remove $date. It's further than $elbyd",2); delete $dates->{$date}; } } $o->{'issuedates'}=$dates; ## if(not scalar(keys %{$o->{'issuedates'}})) { confess "I don't have any issuedates to work with."; } $o->{'issuedates'}=$dates; ## find new start and end $ext=&Ernad::Common::find_extreme_issuedates($dates); $max=$ext->{'max'} or die; $min=$ext->{'min'} or die; my $version=&version_from_dates($dates); $o->{'version'}=$min.'_'.$max; } sub find_exfit_xslt_file { my $o=shift; my $fitcla=shift; my $repcode=shift; my $exfit_xslt_dir=$o->{'e'}->{'dir'}->{'exfit_xslt'}; my $ext='_'.$fitcla.$o->{'e'}->{'const'}->{'xsl_ext'}; my $exfit_file=$exfit_xslt_dir.'/'.$repcode.$ext; return $exfit_file; } ## obsolete sub clear_dirs { my $d=shift; my @clear_dirs=shift // ('dokli_dir','exfit_dir','fidek_dir','fitar_dir','mocla_dir'); foreach my $dir_name (@clear_dirs) { my $dir=$d->{$dir_name} or confess "I can't find a directory $dir_name"; system("rm $dir/*"); } } 1;