package Ernad::Dir; use strict; use warnings; use base 'Ernad'; use Carp qw(confess); use Data::Dumper; use Ernad::Constant; use Krichel::Shoti; use File::Basename; use File::Path; use Ernad::Dates; sub oldest_issuedate { my $d=shift; my $dirname=shift // ''; if(not $dirname) { confess "I have no dirname to geta most recent rif from."; } if(not -d $dirname) { confess "I don't see the directory '$dirname'."; } my $min_date; foreach my $file (glob("$dirname/*")) { my $bana=basename($file); if(not $bana=~m|^(\d{4}-\d{2}-\d{2})|) { next; } my $issuedate=$1; if(not $min_date or &Ernad::Dates::compare_dates($min_date,$issuedate)<0) { $min_date=$issuedate; } } return $min_date; } # sub newest_issuedate_in_dir { # my $d=shift; # my $dirname=shift // ''; # if (not $dirname) { # confess "I have no dirname to geta most recent rif from."; # } # if(not -d $dirname) { # confess "I don't see the directory '$dirname'."; # } # my $max_date; # foreach my $file (glob("$dirname/*")) { # my $bana=basename($file); # if(not $bana=~m|^(\d{4}-\d{2}-\d{2})|) { # next; # } # my $issuedate=$1; # if(not $max_date or &Ernad::Dates::compare_dates($max_date,$issuedate) > 0) { # $max_date=$issuedate; # } # } # return $max_date; # } ## very permissive, written on VKO to IST flight after wine sub files_by_date { my $d=shift; my $dir=shift // confess 'I need a directory here'; my $get_date=shift // ''; if(not -d $dir) { confess "I don't see your directory $dir,"; } my $out; my @files=glob("$dir/*"); foreach my $file (@files) { my $bana=basename($file); if(not $bana=~m|(\d{4}-\d{2}-\d{2})|) { next; } my $issuedate=$1; if($out->{$issuedate}) { my $already_file=$out->{$issuedate}; confess "I have $already_file and $file of issuedate $issuedate"; } $out->{$issuedate}=$file; } ## return a specific file if this has been required. if($get_date) { return $out->{$get_date}; } return $out; } ## more recent version of previous function sub latest_rif { my $d=shift; my $dir=shift // confess 'I need a directory here'; my $issuedate=shift or confess "I need an issuedate here."; my @rifs=glob("$dir/$issuedate*"); my $latest_tist=0; my $latest_rif=''; my $e=$d->{'e'} // $main::e // confess "Where is my erimp?"; foreach my $rif (@rifs) { # if(not is_rif_name($rif)) { if(not $e->{'f'}->is($rif)) { next; } my $tist=$e->{'f'}->tist($rif); if($tist > $latest_tist) { $latest_tist=$tist; $latest_rif=$rif; } } return $latest_rif; } ## extends the previous function to the case when there is ### a subdir, used with source #sub get_latest_rif_with_subdir { # my $d=shift; # my $in_dir=shift // confess 'I need a directory here'; # my $issuedate=shift or confess 'I need an issuedate here.'; # my $latest_tist=0; # my $latest_rif=''; # my $e=$d->{'e'} // $main::e // confess "Where is my erimp?"; # opendir(my $in_dh, $in_dir) or confess "I can't opendir $in_dir: $!"; # foreach my $subdir (readdir($in_dh)) { # my $dir="$in_dir/$subdir"; # if(not -d "$in_dir/$subdir") { # next; # } # my @rifs=glob("$dir/$issuedate*"); # foreach my $rif (@rifs) { # if(not $e->{'f'}->is($rif)) { # next; # } # my $tist=$e->{'f'}->tist($rif); # if($tist > $latest_tist) { # $latest_tist=$tist; # $latest_rif=$rif; # } # } # } # return $latest_rif; #} ## used only in this file sub get_earliest_rif { my $d=shift; my $dir=shift; my $issuedate=shift or confess "I need an issuedate here."; my @rifs=glob("$dir/$issuedate*"); my $earliest_tist=time; my $earliest_rif=''; my $e=$d->{'e'} // $main::e // confess "Where is my erimp?"; foreach my $rif (@rifs) { if(not $e->{'f'}->is($rif)) { next; } my $tist=$e->{'f'}->tist($rif); if($tist < $earliest_tist) { $earliest_tist=$tist; $earliest_rif=$rif; } } return $earliest_rif; } sub get_last_file { my $d=shift; my $glob = shift(); # Get wildcard parameter ## use my @globs = glob( $glob ); return 0 if( scalar( @globs ) == 0 ); return $globs[$#globs]; } # ## used in Seed only # sub find_ordered_issues_in_folder { # my $d=shift; # my $dirname=shift // ''; # if(not $dirname) { # die 'no directory'; # } # if(not -d $dirname) { # die "no such dirertory: $dirname"; # } # opendir( my $dir, $dirname) or die "Error: can't open dir $dirname"; # my $found_file=''; # ## parsing all files # my $file; # my $dates; # my $points; # while ($file = readdir $dir ) { # ## skipping "." and ".." # if (not is_rif_name($file)) { # next; # } # if($file=~m|(\d{4})-(\d{2})-(\d{2})|) { # my $issuedate="$1-$2-$3"; # my $issue_point="$1$2$3"; # $points->{$issuedate}=$issue_point; # $dates->{$issuedate}=$file; # } # } # my @issues=sort { $points->{$a} <=> $points->{$b}} (keys %$dates); # return \@issues; # } ## used in Issue.pm sub find_file_for_issue { my $d=shift; my $dirname=shift; my $issuedate=shift; my @files; opendir( my $dir, $dirname) or die "Error: can't open dir $dirname"; my $found_file=''; ## parsing all files my $file; my $dates; my $points; my $e=$d->{'e'} // $main::e // confess "Where is my erimp?"; while ($file = readdir $dir ) { ## skipping "." and ".." if (not $e->{'f'}->is($file)) { next; } my $fufi="$dirname/$file"; ## Xmas 2017 if($file=~m|(\d{4}-\d{2}-\d{2})_([0-9a-z]{6})|) { my $issuedate_on_file=$1; my $shoti=$2; my $tist=&Krichel::Shoti::ekam($shoti); my $issue_point=$tist; if($issuedate_on_file ne $issuedate) { next; } $points->{$fufi}=$issue_point or confess "no issue point for $fufi"; push(@files,"$dirname/$file"); } if($file=~m|(\d{4}-\d{2}-\d{2})_(\d+)|) { my $issuedate_on_file=$1; my $issue_point=$2; if($issuedate_on_file ne $issuedate) { next; } $points->{$fufi}=$issue_point or confess "no issue point for $fufi"; push(@files,"$dirname/$file"); } } #print Dumper @files; #print Dumper $points; @files=sort { $points->{$a} <=> $points->{$b}} (@files); #print Dumper @files; return \@files; } ## used in Presort sub list_amf_files_per_issue { my $d=shift; my $dirname=shift; my @files; opendir( my $dir, $dirname) or die "Error: can't open dir $dirname"; my $found_file=''; ## parsing all files my $file; my $out; my $e=$d->{'e'} // $main::e // confess "Where is my erimp?"; while ($file = readdir $dir ) { ## skipping "." and ".." if (not $e->{'f'}->is($file)) { next; } my $fufi="$dirname/$file"; ## Xmas 2017 if($file=~m|(\d{4}-\d{2}-\d{2})_([0-9a-z]{6})|) { my $issuedate_on_file=$1; my $shoti=$2; my $issue_point=&Krichel::Shoti::ekam($shoti); $out->{$issuedate_on_file}->{$issue_point}=$fufi; } elsif($file=~m|(\d{4}-\d{2}-\d{2})_(\d+)|) { my $issuedate_on_file=$1; my $issue_point=$2; $out->{$issuedate_on_file}->{$issue_point}=$fufi; } } return $out; } ## used in Erimp.pm sub issues { my $d=shift; my $dir=shift // ''; opendir(my $dh, $dir) or confess "I can't opendir $dir: $!"; my $issues=(); my $e=$d->{'e'} // $main::e // confess "Where is my erimp?"; foreach my $filename (readdir($dh)) { if(not $e->{'f'}->is($filename)) { # print "'$filename is not a rif.\n"; next; } my $issuedate=substr($filename,0,10); ## count the number of times we have a file of an issue date from 0 if(not defined($issues->{$issuedate})) { $issues->{$issuedate}=1; } else { $issues->{$issuedate}++; } } return $issues; } ## same as previous, but not with restriction on rifs #sub find_issuedates_in_dir { # my $d=shift; # my $dir=shift // ''; # opendir(my $dh, $dir) or confess "I can't opendir $dir: $!"; # my $issues=(); # foreach my $filename (readdir($dh)) { # if($filename eq '.' or $filename eq '..') { # next; # } # my $issuedate=substr($filename,0,10); # ## count the number of times we have a file of an issue date from 0 # if(not defined($issues->{$issuedate})) { # $issues->{$issuedate}=1; # } # else { # $issues->{$issuedate}++; # } # } # return $issues; #} ### used in Seed only #sub get_rif_after_date { # my $d=shift; # my $dir=shift // confess "I need a directory here."; # if(not -d $dir) { # confess "I can't see your directory $dir"; # } # my $date=shift // confess "I need a directory here."; # my $fufi; # opendir(my $dh, $dir) or confess "I can't opendir $dir: $!"; # my $e=$d->{'e'} // $main::e // confess "Where is my erimp?"; # foreach my $bana (sort readdir($dh)) { # #print "I have bana $bana\n"; # if(not $e->{'f'}->is($bana)) { # next; # } # my $issuedate=$e->{'f'}->issuedate($bana); # #print "issuedate is $issuedate\n"; # if(&Ernad::Dates::compare_dates($issuedate,$date) > 0) { # #print "It is earlier than $date\n"; # next; # } # $fufi="$dir/$bana"; # return $fufi; # } #} ## list shows a hasref sub list_rifs { my $d=shift; my $dir = shift // confess 'I need a directory here.'; my $lax = shift // 0; if(not -d $dir) { if(not $lax) { confess "I don't see the directory '$dir'."; } else { return undef; } } my $out=[]; my $e=$d->{'e'} // $main::e // confess "Where is my erimp?"; my $glob=$dir.'/*'.$e->{'const'}->{'rif_ext'}; push(@$out,glob($glob)); push(@$out,glob("$glob.gz")); return $out; } sub most_recent_rif { my $d=shift; my $dirname=shift // ''; my $lax = shift // 0; if (not $dirname) { confess "I have no dirname to geta most recent rif from."; } if(not -d $dirname) { if(not $lax) { confess "I don't see the directory '$dirname'."; } else { return undef; } } my $required_issuedate=shift // ''; my $found_file=''; my $found_tist=0; my $e=$d->{'e'} // $main::e // confess "Where is my erimp?"; my $files=$d->list_rifs($dirname,$lax) // return undef; if(not scalar(@$files)) { return undef; } foreach my $file (@$files) { if($required_issuedate) { my $issuedate=$e->{'f'}->issuedate($file); if($issuedate ne $required_issuedate) { next; } } if($found_file eq '') { ## first rif $found_tist=$e->{'f'}->tist($file); $found_file=$file; next; } my $tist=$e->{'f'}->tist($file) // confess "Where is the tist on $file?"; if($tist > $found_tist) { $found_file=$file; $found_tist=$tist; } } return $found_file; } ## new for the fila, first of last issuedate sub fila { my $d=shift; my $dir=shift; my $e=$d->{'e'} // $main::e // confess "Where is my erimp?"; if(not -d $dir) { $e->echo(__LINE__,"I can't open the directory $dir"); return undef; } my $glob="$dir/*"; ## highly dependent on the glob returning the files in string order! my @fufis=reverse glob($glob); my $given_issuedate; my $fila_fufi=''; foreach my $fufi (@fufis) { if(not $e->{'f'}->is($fufi)) { next; } if(not $given_issuedate) { $given_issuedate=$e->{'f'}->issuedate($fufi); $fila_fufi=$fufi; next; } my $this_issuedate=$e->{'f'}->issuedate($fufi); if($this_issuedate ne $given_issuedate) { return $fila_fufi; } $fila_fufi=$fufi; } return $fila_fufi; } ## in Learn/Dokli.pm only #sub is_issue_in_dir { # my $d=shift; # my $dir=shift // confess "I need a diretory here."; # if(not -d $dir) { # confess "I can't see the directory '$dir'"; # } # my $issuedate=shift // confess "I need an issuedate here."; # if(not $issuedate=~m|\d{4}-\d{2}-\d{2}|) { # confess "This '$issuedate' does not look like a issuedate to me."; # } # my $glob="$dir/$issuedate*"; # my @files=glob($glob); # if(scalar @files) { # return 1; # } # return 0; #} ## in Erimp only sub earliest_issue { my $d=shift; my $dir=shift // ''; if(not $dir or not -d $dir) { confess "I need a directory here."; } my $out=$d->extreme_issuedates($dir); return $out->{'min'}; } ## required by Chopa.pm sub get_latest_rif_from_each_issue_in_dir { my $d=shift; my $dir=shift // ''; my $issues=$d->issues($dir); my $rifs=(); foreach my $issue (keys %$issues) { my $rif=$d->latest_rif($dir,$issue); push(@$rifs,$rif); } return $rifs; } ;; sub get_latest_rif_from_each_issue_in_subdir { my $d=shift; my $dir=shift // ''; my $issues=$d->issues($dir); my $rifs=(); foreach my $issue (keys %$issues) { my $rif=$d->latest_rif($dir,$issue); push(@$rifs,$rif); } return $rifs; } # appears unused #sub check_uniqueness_of_issue_in_dir { # my $d=shift; # my $dir=shift // ''; # my $issues=$d->issues($dir); # my $rifs=(); # foreach my $issue (keys %$issues) { # my $rif=$d->latest_rif($dir,$issue); # push(@$rifs,$rif); # } # return $rifs; #} sub get_earliest_rif_from_each_issue_in_dir { my $d=shift; my $dir=shift // ''; my $issues=$d->issues($dir); my $rifs=(); foreach my $issue (keys %$issues) { my $rif=&get_earliest_rif($dir,$issue); push(@$rifs,$rif); } return $rifs; } ## in the old learning system only sub extreme_issuedates { my $d=shift; my $input=shift or confess 'I need input as the first parameter here.'; my $start=shift // ''; my $end=shift // ''; my $verbose=1; my $min=&Ernad::Dates::today(); my $max='0000-00-00'; if(-d $input) { my $dirname=$input; opendir( my $dir, $dirname ) or die "Error: can't open dir $dirname"; while (my $file = readdir $dir ) { $file=~m|(\d{4}-\d{2}-\d{2})| or next; my $date=$1; if(&Ernad::Dates::compare_dates($date, $max) < 0) { if($end and &Ernad::Dates::compare_dates($date,$end) < 0) { next; } if($start and &Ernad::Dates::compare_dates($date,$start) > 0) { next; } $max=$date; } if(&Ernad::Dates::compare_dates($date, $min) > 0) { if($end and &Ernad::Dates::compare_dates($date,$end) < 0) { next; } if($start and &Ernad::Dates::compare_dates($date,$start) > 0) { next; } $min=$date; } } } elsif(ref $input eq 'HASH') { foreach my $date (keys %{$input}) { if(not $date =~m|^(\d{4})-(\d{2})-(\d{2})|) { die "'$date' is not a date"; } if(&Ernad::Dates::compare_dates($date, $max) < 0) { if($end and &Ernad::Dates::compare_dates($date,$end) < 0) { next; } if($start and &Ernad::Dates::compare_dates($date,$start) > 0) { next; } $max=$date; } if(&Ernad::Dates::compare_dates($date, $min) > 0) { if($end and &Ernad::Dates::compare_dates($date,$end) < 0) { next; } if($start and &Ernad::Dates::compare_dates($date,$start) > 0) { next; } $min=$date; } } } else { my $print_input=Dumper $input; die "I can't deal with this input $print_input"; } my $o; $o->{'min'}=$min; $o->{'max'}=$max; return $o; } ## in namf only, and there only commented #sub find_dates_in_dir { # my $d=shift; # my $dirname=shift; # my $min=shift // ''; # my $max=shift // ''; # opendir( my $dir, $dirname ) or die "Error: can't open dir $dirname"; # my $hash; # my $list; # while (my $file = readdir $dir) { # $file=~m|^(\d{4})-(\d{2})-(\d{2})| or next; # my $date=substr($file,0,10); # if($min and &Ernad::Dates::compare_dates($date, $min) > 0) { # next; # } # if($max and &Ernad::Dates::compare_dates($date, $max) < 0) { # next; # } # if(defined($hash->{$date})) { # $hash->{$date}=1; # } # else { # $hash->{$date}++; # } # } # my $count=0; # foreach my $date (sort keys %$hash) { # $list->[$count++]=$date; # } # return $list; #} ## does only do one level subdir ## apparently unused #sub find_hash_of_dates_in_subdir { # my $d=shift; # my $dirname=shift or confess "I need a directory here."; # ## optional limits # my $min=shift // ''; # my $max=shift // ''; # opendir( my $dir, $dirname ) or die "Error: can't open dir $dirname"; # my $hash; # my $list; # while (my $subdir = readdir $dir) { # my $subdirname="$dirname/$subdir"; # opendir( my $subdir, $subdirname ) or confess "Error: can't open dir $dirname"; # while (my $file = readdir $subdir) { # $file=~m|(\d{4}-\d{2}-\d{2})| or next; # my $date=$1; # if($min and &Ernad::Dates::compare_dates($date, $min) > 0) { # next; # } # if($max and &Ernad::Dates::compare_dates($date, $max) < 0) { # next; # } # push(@{$list->{$date}},$file); # } # } # return $list; #} sub last_date_times { my $d=shift; my $dirname=shift or die;; my $includes=shift; opendir( my $dir, $dirname ) or die "Error: can't open dir $dirname"; my $hash; my $list; my $time_for_date; my $debug=1; ## check excludes my $include_hash; if(defined($includes)) { foreach my $date (keys %{$includes}) { if(not $date=~m|^\d{4}-\d{2}-\d{2}$|) { die "bad includes date $date"; } $include_hash->{$date}=1; } } while (my $file = readdir $dir) { ## Xmas 2017 my $date; my $tist; if($file=~m|^(\d{4}-\d{2}-\d{2})_([0-9a-z]{6})|) { $date=$1; my $shoti=$2; $tist=&Krichel::Shoti::ekam($shoti); } elsif($file=~m|^(\d{4}-\d{2}-\d{2})_(\d+)|) { $date=$1; $tist=$2; } else { next; } if(defined($include_hash) and not defined($include_hash->{$date})) { if($debug) { print "skipping date $date in find_hash_of_last_dates_in_dir $dirname\n"; } } if(not defined($time_for_date->{$date})) { $time_for_date->{$date}=$tist; } else { if($time_for_date->{$date}<$tist) { $time_for_date->{$date}=$tist; } } } return $time_for_date; } sub find_last_date_in_dir { my $d=shift; my $dir=shift; my $e=$main::e // confess 'Where is my erimp?'; # my $bana=&Ernad::Common::get_most_recent_rif($dir) or return ''; my $bana=$d->most_recent_rif($dir) or return ''; my $date=$e->{'f'}->issuedate($bana) or return ''; return $date; } ## try to obsolete, only used in ~/perl/delay_page without min and max sub hash_of_dates { my $d=shift; my $dirname=shift or die; ## optional limits my $min=shift // ''; my $max=shift // ''; opendir( my $dir, $dirname ) or confess "I can't open the directory '$dirname'."; my $hash; my $list; while (my $file = readdir $dir) { $file=~m|(\d{4}-\d{2}-\d{2})| or next; my $date=$1; if($min and &Ernad::Dates::compare_dates($date, $min) > 0) { next; } if($max and &Ernad::Dates::compare_dates($date, $max) < 0) { next; } push(@{$list->{$date}},$file); } return $list; } sub dates { my $d=shift; my $dirname=shift // confess "I need a directory."; if(not -d $dirname) { confess "I don't see your directory '$dirname'."; } ## optional restriction my $restrict=shift // ''; opendir( my $dir, $dirname ) or confess "I can't open the directory '$dirname'."; my $hash; my $list; while (my $file = readdir $dir) { if($restrict and not $file=~m|$restrict|) { next; } $file=~m|(\d{4}-\d{2}-\d{2})| or next; my $date=$1; push(@{$list->{$date}},$file); } return $list; } 1;