package Ernad::Yanabino; use strict; use warnings; use Carp qw(confess); use Data::Dumper; use XML::LibXML; use Ernad::Common; use Ernad::Dates; use Krichel::File; ## return $total papers from file, and deletes them in the file sub trim_in_file { my $in_file=shift; my $total=shift; my $eles=shift // {}; # my $xpc=&Ernad::Common::create_xpc; my $e=$main::e // confess 'I need an erimp here.'; my $xpc=$e->{'xpc'} // confess 'I need an xpc here.'; my $doc=&Krichel::File::load($in_file); my $xp='//amf:collection/amf:haspart[1]'; my $count=0; while($count<$total) { $count++; my $hp_ele=$xpc->findnodes($xp,$doc)->[0] // last; my $ref=$xpc->findnodes('//amf:haspart/amf:text/@'.'ref',$hp_ele)->[0]->nodeValue // confess "I can't see the handle."; $eles->{$ref}=$hp_ele->cloneNode(1); $hp_ele->parentNode->removeChild($hp_ele); } ## delete the file if we could not get the full amount requested if($count<$total) { unlink $in_file; } else { $doc->toFile($in_file); } return $eles; } ### return $total papers from file, and deletes them in the file #sub count_texts_in_file { # my $in_file=shift; # my $total=shift; # my $eles=shift // {}; # my $xpc=&Ernad::Common::create_xpc; # my $doc=&Krichel::File::load($in_file); # #my $xp='count(//amf:collection/amf:haspart[1]/amf:text)'; # #my $xp='//amf:haspart/amf:text'; ## my $xp='//amf:text'; # my $count=$xpc->findnodes($xp,$doc)->size(); # return $count; #} ## trims a file and saves in another file sub trim_and_save_file { my $in_file=shift // confess "I need an in_file"; my $out_file=shift // confess "I need an out_file"; my $total=shift // confess "I need a number to fetch"; if(not $total=~m|^\d+$|) { confess "Your number '$total' does not look like a number."; } my $eles=shift // {}; my $e=$main::e // confess 'I need an erimp here.'; my $xpc=$e->{'xpc'} // confess 'I need an xpc here.'; # my $xpc=&Ernad::Common::create_xpc; my $doc=&Krichel::File::load($in_file); my $xp='//amf:collection/amf:haspart[1]'; my $count=0; while($count<$total) { $count++; my $hp_ele=$xpc->findnodes($xp,$doc)->[0] // last; my $ref=$xpc->findnodes('//amf:haspart/amf:text/@'.'ref',$hp_ele)->[0]->nodeValue // confess "I can't see the handle."; $eles->{$ref}=$hp_ele->cloneNode(1); $hp_ele->parentNode->removeChild($hp_ele); } &Krichel::File::prepare($out_file); $doc->toFile($out_file); return $eles; } ## returns an array of pile files, current or not sub list_piles { my $dir=shift; my $files=[]; my $count_files=0; if(not -d $dir) { confess "I can't see $dir."; } foreach my $file (`find $dir -name '*.xml' 2> /dev/null`) { chomp $file; $file=~s|$dir/*||; $files->[$count_files++]=$file; } return $files; } ## return a hash of dates, with the piles for that date (?) sub date_piles { my $piles_list=shift // "I need a piles array here"; ## dates on piles my $dates={}; ## origin of a pile my $origs={}; ## target hash. It links an orig to the most recent pile of this orig. my $piles={}; foreach my $pile (@{$piles_list}) { if($pile=~m|^/*new/(\d{4}-\d{2}-\d{2})|) { $dates->{$pile}=$1; $origs->{$pile}=$1; } elsif($pile=~m|^/*(\d{4}-\d{2}-\d{2})/(\d{4}-\d{2}-\d{2})\.xml$|) { $dates->{$pile}=$1; $origs->{$pile}=$2; } ## an emacs autosave elsif($pile=~m|^/*(\d{4}-\d{2}-\d{2})/(\d{4}-\d{2}-\d{2})\.xml~$|) { next; } else { confess "I should not be here, with my $pile."; } } foreach my $pile (@{$piles_list}) { my $orig=$origs->{$pile}; if(not defined($piles->{$orig})) { $piles->{$orig}=$pile; next; } my $current_date=$dates->{$piles->{$orig}} // confess "I don't have a date for $pile"; my $date=$dates->{$pile}; if(not $pile=~m|new| and &Ernad::Dates::compare_dates($current_date,$date)>=0) { #print "I have a new version for $orig at $pile\n"; $piles->{$orig}=$pile; } else { #print "$current_date $date\n"; } } #print Dumper $piles; return $piles; } sub find_last_issuedate_by_piles { my $piles_list=shift // "I need a piles array here"; my $issues={}; my $last_date=''; foreach my $pile (@{$piles_list}) { my $date; if($pile=~m|^/*new/(\d{4}-\d{2}-\d{2})|) { next; } if($pile=~m|^/*(\d{4}-\d{2}-\d{2})/(\d{4}-\d{2}-\d{2})\.xml|) { $date=$1; if(not $last_date) { $last_date=$date; } if(&Ernad::Dates::compare_dates($date,$last_date)<=0) { $last_date=$date; } } } return $last_date; } ## return a hash of dates, with the latest pile for that date sub current_piles { my $piles=shift // confess "I need piles here."; my $piles_dir=shift // ''; my $verbose=shift // ''; my $e=$main::e or confess 'Where is my erimp?'; if(not $piles_dir) { $piles_dir=$e->{'dir'}->{'piles'} // confess "I need the piles_dir here."; } foreach my $date (keys %$piles) { my $pile_file=$piles->{$date} // confess "I need a pile_file here."; my $pile_fufi=$piles_dir.'/'.$pile_file; if(not -f $pile_fufi) { confess "I can't see the file '$pile_fufi'\n"; } my $handles_ref=$e->{'x'}->papids($pile_fufi,'array') // []; my $total_handles=scalar (@{$handles_ref}); if($verbose) { print "I found $total_handles in $pile_file\n"; } if(not $total_handles) { delete $piles->{$date}; } else { ## add the full path $piles->{$date}=$piles_dir.'/'.$piles->{$date}; } } return $piles; } sub get_piles { my $piles_dir=shift // ''; my $verbose=shift // ''; if(not $piles_dir) { $piles_dir=$main::e->{'dir'}->{'pile'} // confess "I need the piles_dir here."; } if(not -d $piles_dir) { confess "I can't see the piles_dir $piles_dir"; } ## an array refenece my $piles_array=&list_piles($piles_dir); ## a hash reference my $dated_piles=&date_piles($piles_array); #print Dumper $dated_piles; ## pile_dir has to be second argument to actially read the files my $piles=¤t_piles($dated_piles,$piles_dir); return $piles; } sub find_weekly_average { my $days_back=shift; my $verbose=shift // $main::o{'v'} // ''; my $e=$main::e // confess "I need the erimp defined here."; my $allport=$e->get_allport_repcode() // ''; if(not $allport) { print "Fixme. I can't deal with erimps without allport\n"; } my $rerc=$e->{'report'}->{$allport}; my $dir=$rerc->{'dir'}->{'sent'}; my $today=&Ernad::Dates::today(); ## deal with repeats in the sent direction my $done_issuedates; my $previous_count=0; my $count_papers=0; foreach my $file (`ls $dir`) { chomp $file; my $fufi="$dir/$file"; if($verbose) { print "I am looking at $file in $dir\n"; } my $issuedate=$e->{'f'}->issuedate($fufi); if(not $issuedate) { if($verbose) { print "I can't get an issuedate from $fufi.\n"; } ## in any case go next next; } if($done_issuedates->{$issuedate}) { ## this should not happen if($verbose) { print "issuedate $issuedate is repeated in $fufi.\n"; } next; } $done_issuedates->{$issuedate}=1; my $ago=&Ernad::Dates::diff_dates($issuedate,$today); if($ago>$days_back) { if($verbose) { print "$file is too old\n"; } next; } ### If it's done, it's a repeat file for the same issue. ### Let's subtract the previous_count #if(defined($done->{$issuedate})) { # if($verbose) { # print "On repeat of $issuedate, I decrease by $previous_count.\n"; # } # $count_papers-=$previous_count; #} my $count_handles=&count_handles_in_file($fufi); $count_papers+=$count_handles; $previous_count=$count_handles; } my $average=int(7*$count_papers/$days_back); return $average; } sub count_handles_in_file { my $file=shift // confess "I need a file here."; if(not -f $file) { confess "I can't open your file '$file'\n"; } my $e=$main::e // confess "I need the erimp defined here."; my $handles; my $handles_lines=$e->{'t'}->t($file,'show_handles','chars'); foreach my $handle (split(/\n/,$handles_lines)) { $handles->{$handle}=1; } my $count_papers=scalar keys %$handles; return $count_papers; } sub count_papers_in_queue { my $piles=shift // ''; if(not $piles) { $piles=&get_piles; } #print Dumper $piles; my $count_queue=0; foreach my $date (keys %$piles) { my $file=$piles->{$date}; $count_queue+=&count_handles_in_file($file); } return $count_queue; } 1;