package Ernad::Adverts; use strict; use warnings; use Carp qw(confess); use Data::Dumper; use File::Basename; use Ernad::Common; use Ernad::Erimp; use Krichel::File; my $verbose=1; our $e; sub find_adrep { my $repcode=shift or die "no repcode"; my $issuedate=shift or die "no repcode"; my $file=&find_adrep_file($repcode,$issuedate) or return ''; my $adrep=&find_adrep_from_file($file,$repcode) or return ''; if(ref $adrep eq 'XML::LibXML::Element') { return $adrep; } else { die 'bad object on adrep'; } } ## find issue_advert isuad sub find_isuad { my $issuedate=shift or die "no repcode"; my $file=&find_isuad_file($issuedate) or return ''; my $isuad=&find_isuad_from_file($file) or return ''; if(ref $isuad eq 'XML::LibXML::Element') { return $isuad; } else { confess 'I have a bad object on isuad.'; } } sub inject_adverts_into_rif { my $rif=shift; my $e=shift // $main::e // confess "Where is my erimp?"; if(not $rif) { confess "I need a rif here."; } if(not -f $rif) { confess "I can't open the rif $rif"; } #if(not defined($e)) { # my $impna=&Ernad::Common::find_impna_from_file($rif) # or confess "I can't get the impna from the file $rif"; # $e=Ernad::Erimp->new({'impna'=> $impna, 'verbose'=>1}); # $main::e=$e; #} my $refe=ref $e; if(not $refe eq 'Ernad::Erimp') { confess "What you gave me does not look like an erimp, but a $refe."; } #my $impna=&Ernad::Common::find_impna_from_file($rif) # or confess "I can't get the impna from the file $rif"; my $impna = $e->{'f'}->impna($rif); # my $repcode=$e->find_repcode_from_file($rif,$impna) my $repcode=$e->{'f'}->repcode($rif) or confess "I can't get the repcode from the file $rif"; my $issuedate=$e->{'f'}->issuedate($rif); # my $time=&Ernad::Common::find_time_from_file($rif); my $time=$e->{'f'}->tist($rif) or confess "I can't get the time from $rif"; my $adrep_element; ## adrep first $adrep_element=&find_adrep($repcode,$issuedate); if($adrep_element) { $e->echo(__LINE__,"I found an adrep element."); } else { $e->echo(__LINE__,"I found NO adrep element.",4); } ## isuad my $isuad_element=&find_isuad($issuedate); &inject_adverts_into_rif_file($isuad_element,$adrep_element,$rif); } ## saves the rif as well OLD sub inject_adverts_into_rif_file { my $isuad_element=shift // ''; my $adrep_element=shift // ''; my $rif_file=shift; if(not -f $rif_file) { die "no such file $rif_file"; } my $adrep_repcode=''; if($adrep_element) { $adrep_repcode=$adrep_element->getAttribute('report'); } my $rif_doc=&Krichel::File::load($rif_file); my $e=$main::e or die 'no erimp'; my $xpc=$e->{'xpc'}; ## clear existing advert elemnet foreach my $existing_advert_element ($xpc->findnodes('//e:advert',$rif_doc)) { $e->echo(__LINE__,"Advert exists."); if($existing_advert_element->hasAttribute('report')) { my $existing_advert_repcode=$existing_advert_element->getAttribute('report'); if($existing_advert_repcode eq $adrep_repcode) { $e->echo(__LINE__,"I am removing."); $existing_advert_element->parentNode->removeChild($existing_advert_element); } next; } ## the else is really redundant here, but just to make sure else { $e->echo(__LINE__,"It has no repcode. I am deleting the existing advert."); $existing_advert_element->parentNode->removeChild($existing_advert_element); } } ## let's place the advert next to the issuedate my $issuedate_element=$xpc->findnodes('//e:issuedate',$rif_doc)->[0]; if(not defined($issuedate_element)) { die "no issuedate in rif $rif_file"; } my $collection_element=$xpc->findnodes('/amf:amf/amf:collection',$rif_doc)->[0]; my $contents_changed=0; if($isuad_element) { $contents_changed=1; $collection_element->insertAfter($isuad_element,$issuedate_element); } if($adrep_element) { $contents_changed=1; $collection_element->insertAfter($adrep_element,$issuedate_element); } if($contents_changed) { $e->echo(__LINE__,"I probably have changed contents. I save $rif_file."); $rif_doc->toFile($rif_file,2); } return $rif_doc; } sub find_adrep_from_file { my $file=shift; ## the repcode argument is optional my $repcode=shift // ''; my $doc=Krichel::File::load($file) or die; my $start_date_on_file=&find_start_day_by_file_name($file); my $end_date_on_file=&find_end_day_by_file_name($file); my $advert_element=$doc->documentElement(); my $start_date_on_element=$advert_element->getAttribute('start_date') // ''; if(not $start_date_on_element) { $advert_element->setAttribute('start_date',$start_date_on_file); } elsif($start_date_on_element ne $start_date_on_file) { die "inconsistent start date in advert in $file"; } my $end_date_on_element=$advert_element->getAttribute('end_date') // ''; if(not $end_date_on_element) { $advert_element->setAttribute('end_date',$end_date_on_file); } elsif($end_date_on_element ne $end_date_on_file) { die "inconsistent end date in advert in $file"; } my $repcode_attribute=$advert_element->getAttribute('report') // ''; if($repcode_attribute) { if($repcode and $repcode ne $repcode_attribute) { die "inconsistent repcode $repcode supplied for on adrep $file"; } } else { if(not $repcode) { ## try to find the repcode as dirname my $repcode_tried=dirname(dirname($file)); if($repcode_tried) { if($verbose) { print "using the tried repcode $repcode\n"; $advert_element->setAttribute('report',$repcode); } } die "I find no repcode for advert in $file, supply one externally"; } else { $advert_element->setAttribute('report',$repcode); } } my $adrep_element=$advert_element->cloneNode(1); return $adrep_element; } sub find_adrep_file { my $repcode=shift; my $date=shift; my $e=$main::e or die 'no erimp'; my $rerc=$e->{'report'}->{$repcode}; my $adrep_dir=$rerc->{'dir'}->{'adrep'}; if(not -d $adrep_dir) { return 0; } if($verbose) { $e->echo(__LINE__,"adrep_dir is $adrep_dir",2); } my $date_glob='[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]'; my $adrep_glob="$adrep_dir/$date_glob".'_'."$date_glob.xml"; my @files_found=glob($adrep_glob); my @in_scope_files; foreach my $file (@files_found) { if(not &is_adrep_file_in_scope($file,$date)) { next; } push(@in_scope_files,$file); } my $total_in_scope_file=scalar @in_scope_files; if($total_in_scope_file > 1) { confess "I found several files in adrep scope for $repcode at $date. Write to my master."; } return $in_scope_files[0]; } sub find_start_day_by_file_name { my $file=shift; $file=basename($file); $file=~m|(\d{4}-\d{2}-\d{2})_(\d{4}-\d{2}-\d{2})\.xml| or die "bad file name $file"; my $start=$1; return $start; } sub find_end_day_by_file_name { my $file=shift; $file=basename($file); $file=~m|(\d{4}-\d{2}-\d{2})_(\d{4}-\d{2}-\d{2})\.xml| or die "bad file name $file"; my $end=$2; return $end; } sub is_adrep_file_in_scope { my $file=shift; my $date=shift; my $end=&find_end_day_by_file_name($file); if(&is_prior_or_same($end,$date)) { return 0; } my $start=&find_start_day_by_file_name($file); if(&is_prior_or_same($date,$start)) { return 0; } return 1; } sub is_prior_or_same { my $one=shift; my $two=shift; if(not $one=~s|(\d{4})-(\d{2})-(\d{2})|$1$2$3|) { die "invalid first date $one"; } if(not $two=~s|(\d{4})-(\d{2})-(\d{2})|$1$2$3|) { die "invalid second date $two"; } if($one <= $two) { return 1; } return 0; } sub find_isuad_file { my $date=shift; my $e=$main::e or die 'no erimp'; my $isuad_dir=$e->{'dir'}->{'isuad'}; if(not -d $isuad_dir) { return 0; } if($verbose) { $e->echo(__LINE__,"isuad_dir is $isuad_dir",2); } my $isuad_file="$isuad_dir/$date.xml"; if(not -f $isuad_file) { $e->echo(__LINE__,"I don't find $isuad_file",2); return 0; } return $isuad_file; } sub find_isuad_from_file { my $file=shift; ## the repcode argument is optional my $repcode=shift // ''; my $doc=Krichel::File::load($file) or confess "I could not load a document from $file"; my $advert_element=$doc->documentElement(); return $advert_element; } 1;