package Ernad::Announce; use strict; use warnings; use utf8; use Carp qw(confess); use File::Spec; use Data::Dumper; use Ernad::Email; use Ernad::Common; use Ernad::Membership; ## finds the impna from the file sub get_impna_from_file { my $file=shift; my @path_parts=split('/',File::Spec->rel2abs( $file )); my $next_is_good=0; foreach my $dir (reverse @path_parts) { if($dir eq $Ernad::Constant::c->{'announce_dir'}) { $next_is_good=1; next; } if($next_is_good==1) { return $dir; } } } sub get { my $file=shift; ## a variable we return my $a; my $doc=&Ernad::Common::load_and_return_xml($file); my $xpc=&Ernad::Common::create_xpc(); my @ann_eles=$xpc->find('//e:announcement',$doc)->get_nodelist; my $count_ann=0; my $announce_dir=$main::e->{'dir'}->{'announce'} // confess "I don't see the announce dir."; my $tmp_dir=$announce_dir.'/tmp'; if(-d $tmp_dir) { system("rm -f $tmp_dir/*"); } ## compose external data to handle to each announments my $ext; ## add the common elements @{$ext->{'test_eles'}}=$xpc->find('//e:test',$doc)->get_nodelist; foreach my $common_ele ($xpc->find('//e:common[@id]',$doc)->get_nodelist()) { my $id=$common_ele->getAttribute('id'); my $type=$common_ele->getAttribute('type'); $ext->{'common'}->{$id}->{$type}=$common_ele->cloneNode(1); } foreach my $ann_ele (@ann_eles) { $a=&prepare_for_ann($ann_ele,$a,$ext); } #if($ext->{'test_eles'}) { # $a->{'test'}=1; #} # print Dumper $a; return $a; } sub prepare_for_ann { my $ann_ele=shift; my $a=shift // []; my $ext=shift; my $ann; my $count=scalar(@$a) + 1; my $xml=$ann_ele->cloneNode(1); $ann=&add_lists($ann,$xml,'out'); $ann=&add_lists($ann,$xml,'in'); my $addresses; if(scalar @{$ext->{'test_eles'}}) { foreach my $test_ele (@{$ext->{'test_eles'}}) { my $email=$test_ele->getAttribute('email') // next; $addresses->{$email}=1; } $ann->{'test'}=1; } else { $addresses=&Ernad::Membership::joint_members(@{$ann->{'in'}}) // confess "I don't have in_addresses."; if($ann->{'out'}) { $addresses=&Ernad::Membership::out_members($addresses,@{$ann->{'out'}}); } } &file_addresses($addresses,$count); ## add the test elements so they are available for testing my $test_eles=$ext->{'test_eles'} // []; foreach my $test_ele (@$test_eles) { $xml->appendChild($test_ele->cloneNode()); } ## add the subject my $ernad_ns=$Ernad::Constant::c->{'ernad_ns'} // die; my $subject=$ann_ele->getElementsByTagNameNS($ernad_ns,'subject')->get_node(0); my $subject_ele=$subject->cloneNode(1); if(not $subject) { confess "I don't see a subject in $xml"; } my $xpc=&Ernad::Common::create_xpc(); foreach my $common_ref_ele ($xml->getElementsByTagNameNS($ernad_ns,'common')) { my $ref=$common_ref_ele->getAttribute('ref'); my $type=$common_ref_ele->getAttribute('type'); my $replace_ele=$ext->{'common'}->{$ref}->{$type}->cloneNode(1); foreach my $child ($replace_ele->childNodes()) { $common_ref_ele->parentNode->insertBefore($child,$common_ref_ele); } $common_ref_ele->parentNode->removeChild($common_ref_ele); } my $amf_ns=$Ernad::Constant::c->{'amf_ns'}; my @repcodes=@{$ann->{'in'}}; ## take the first just to have anything my $main_repcode=$repcodes[0]; my $repdoc=$main::e->{'e'}->{'r'}->doc($main_repcode) // confess 'I need a repdoc here.'; $xml->appendChild($subject_ele); $ann->{'xml'}=$xml->cloneNode(1); $ann->{'amf'}=$repdoc->documentElement(); &file_docs($ann,$count); push(@$a,$ann); return $a; } sub file_docs { my $ann=shift; my $amf=$ann->{'amf'}; my $xml=$ann->{'xml'}; my $bana=shift; my $announce_dir=$main::e->{'dir'}->{'announce'} // confess "I don't see the announce dir."; my $tmp_dir=$announce_dir.'/tmp'; my $save_email="$tmp_dir/$bana"; my $ernad_ns=$Ernad::Constant::c->{'ernad_ns'} // die; my $amf_ns=$Ernad::Constant::c->{'amf_ns'} // die; my $docs; my $xpc=&Ernad::Common::create_xpc(); #my $subject_ele=$xpc->find('//e:subject',$xml)->get_node(1); my $subject_ele=$xml->getElementsByTagNameNS($ernad_ns,'subject')->[0]->cloneNode(1); foreach my $type ('text','html') { my $this_amf=$amf->cloneNode(1); my $file="$tmp_dir/$bana.$type.xml"; my $out_file; if($type eq 'text') { $out_file="$tmp_dir/$bana.txt"; } if($type eq 'html') { $out_file="$tmp_dir/$bana.html"; } my $ele=$xml->getElementsByTagNameNS($ernad_ns,$type)->[0] // confess "I don't see an emelemnt for the type $type"; if($subject_ele) { $ele->appendChild($subject_ele->cloneNode(1)); } my $doc=XML::LibXML::Document->new('1.0','utf-8'); my $haseditor_ele=$this_amf->getElementsByTagNameNS($amf_ns,'haseditor')->[0]; $haseditor_ele->parentNode->appendChild($ele); $doc->setDocumentElement($this_amf); $doc->toFile($file); $docs->{$type}=$doc; } ## note use of 'docs' my $email_file=Ernad::Email::prepare_email($docs,'announce',$save_email); } sub file_addresses { my $addresses=shift; my $bana=shift; my $announce_dir=$main::e->{'dir'}->{'announce'} // confess "I don't see the announce dir."; my $tmp_dir=$announce_dir.'/tmp'; my $file="$tmp_dir/$bana.addresses"; &Ernad::Common::prepare_for_file($file); open(F,"> $file"); foreach my $member (keys %$addresses) { print F "$member\n"; } close F; } sub add_lists { my $ann=shift; my $ann_ele=shift; ## 'in' or 'out' my $in_out=shift; my $xpc=&Ernad::Common::create_xpc(); my $lists_ele=$xpc->find('./e:lists',$ann_ele)->[0]; if(not $lists_ele) { confess "I have an announcement without lists element."; } my $value=$lists_ele->getAttribute($in_out) // return $ann; foreach my $part (split(/,/,$value)) { if(not defined($main::e->{'report'}->{$part})) { confess "I don't know about the report $part"; } push(@{$ann->{$in_out}},$part); } return $ann; } sub send_if_test { my $a=shift; my $count=0; my $dir=$main::e->{'dir'}->{'announce'}.'/tmp'; if(not -d $dir) { confess "I don't see $dir"; } foreach my $ann (@$a) { $count++; if(not $ann->{'test'}) { next; } my $mail_file="$dir/$count.mail"; if(not -f $mail_file) { confess "I don't see $mail_file."; } my $address_file="$dir/$count.addresses"; if(not -f $address_file) { confess "I don't see $address_file."; } my $bin_file=$main::e->{'dir'}->{'perl'}.'/send_to_addresses'; my $s="$bin_file $mail_file $address_file 5"; system($s); } } 1;