package Ernad::Sorting; use strict; use warnings; use Carp qw(confess); use Data::Dumper; use Encode; use File::Slurper; use Scalar::Util qw(looks_like_number); use XML::LibXML; use Ernad::Constant; use Ernad::Common; use Ernad::Dates; use Ernad::Sort; our @g_weights; # weights of papers for sorting our $xml_doc; # parser and document our $xml_root; # root node our $Changes; # flag that changes to paper were made ## first param - reference to the params hash ## second param - name of the created report sub Show { my $wepas=shift or die "no wepas"; my $rs=shift or die "no report state"; my $e=$rs->{'e'} or die "no erimp"; my $repcode=$rs->{'repcode'}; my $rerc=$e->{'report'}->{$repcode} or confess "I don't know about $repcode."; my $count; my $rix = $rs->load_rix(); my $count_items=$e->{'x'}->count_texts($rix); my $show_back_from='Sorting'; ## say we come back from papers if there was no item in the ## selection, and we jumped here. if(not $count_items) { $show_back_from='Papers'; } #my $repcode=$rs->{'repcode'} or confess "I need a repcode here."; if($e->{'testing'}) { my $out_file=$e->{'dir'}->{'test'}.'/rix_shown.xml'; my $rix_string=$rix->toString(); $rix_string=~s|{'dir'}->{'test'}.'/rerc_sorting'; &File::Slurper::write_text( $out_file, $rerc_dump ); } my $html_doc=$e->{'t'}->transform($rix,'sorting_screen', {'back_from'=>"'$show_back_from'"}, ); my $string=$html_doc->toString; ## reset weights reset_weights($rs,$wepas); return $string; } sub reset_weights { my $rs=shift; my $wepas=shift; my $action_name='editor_sort'; my $weights=&Ernad::Sorting::parse_weights_from_wepass($wepas); my $reset_weights=Ernad::Sort::set_all_weights_zero($weights); ## don't do anything when we don't have weights if(not &Ernad::Sort::are_all_weights_zero($weights)) { my $rix=$rs->{'rix'} or die; my $doc=&Ernad::Sort::inject_sort($rix,$weights,$action_name); $doc=&Ernad::Sort::inject_sort($rix,$reset_weights,$action_name); $rs->{'rix'}=$doc; } } # exchanges two papers # moves paper one position up sub move_up { ## number to move my $n = shift; ## can't move up paper 0 if( $n <= 0 ) { return 0; } my $amf_ns=$Ernad::Constant::c->{'amf_ns'} or die; my @docs = $xml_root->getElementsByTagNameNS($amf_ns,'haspart'); my $doc_1 = $docs[$n - 1]; my $doc_2 = $docs[$n]; my $r = $doc_1->parentNode; #open(R,"> /tmp/r_up"); #print R $r->toString(1); #close R; #open(R,"> /tmp/n1_up"); #print R $doc_1->toString(1); #close R; #open(R,"> /tmp/n2_up"); #print R $doc_2->toString(1); #close R; $r->insertBefore( $doc_2, $doc_1 ); ## moving weights my $t = $g_weights[$n - 1]; $g_weights[$n - 1] = $g_weights[$n]; $g_weights[$n] = $t; $Changes = 1; return 0; } # one position down sub move_down { ## number of node to move my $n = shift; my $amf_ns=$Ernad::Constant::c->{'amf_ns'} or die; my @docs = $xml_root->getElementsByTagNameNS($amf_ns,'haspart'); ## number beyond the end if( $n >= scalar( @docs) - 1 ) { return; } my $doc_1 = $docs[$n]; my $doc_2 = $docs[$n + 1]; my $collection_element = $doc_1->parentNode; $collection_element->insertBefore( $doc_2, $doc_1 ); #open(R,"> /tmp/r_down"); #print R $collection_element->toString(1); #close R; #open(R,"> /tmp/n1_down"); #print R $doc_1->toString(1); #close R; #open(R,"> /tmp/n2_down"); #print R $doc_2->toString(1); #close R; # moving weights my $t = $g_weights[$n]; $g_weights[$n] = $g_weights[$n + 1]; $g_weights[$n + 1] = $t; $Changes = 1; return 0; } # processes reference to params hash # returns 0 if mode wasnt changed, -1 if we go back( to report selecting ) # and 1 if we go forward( to sorting ) sub Process { my $wepas=shift or die; my $rs=shift or die; my $e=$rs->{'e'} or die; if($e->{'testing'}) { open(O,'> '.$e->{'dir'}->{'test'}.'/sorting_process.log'); my $print_wepas=Dumper $wepas; print O $print_wepas; } $Changes = 0; ## to reuse is load_rix $rs->{'wepas'}=$wepas; $xml_doc = $rs->load_rix(); $xml_root = $xml_doc->documentElement(); my $amf_ns=$Ernad::Constant::c->{'amf_ns'} or die; my $ernad_ns=$Ernad::Constant::c->{'ernad_ns'} or die; my @docs = $xml_root->getElementsByTagNameNS($amf_ns,'text'); my $count_docs=scalar @docs; ## if there are no document and the back button is pressed if($wepas->{'Back'}) { if($count_docs) { $rs->set_stage($e->{'const'}->{'selected_dir'}); return -1; } else { ## do docs, go back to created $rs->set_stage($e->{'const'}->{'created_dir'}); return -1; } } # if(not $count_docs and defined($wepas->{'Back'})) { # #2# $rs->save($e->{'const'}->{'selected_dir'}); # #$rs->save($e->{'const'}->{'filtered_dir'}); # confess 'here'; # $rs->set_stage($e->{'const'}->{'selected_dir'}); # return -1; #} my $cnt; my $repcode=$wepas->{'Report'} or die; my ( $k, @ks, @a, @ts ); my $w; my $or; ## then doing the movements/deletes foreach $k ( keys %$wepas ) { ## plus if( $k =~ /p_([0-9]+)/ ) { if($e->{'testing'}) { print O "moving up $k $1\n"; } move_up( $1 ); } ## minus elsif( $k =~ /m_([0-9]+)/ ) { if($e->{'testing'}) { print O "moving down $k $1\n"; } move_down( $1 ); } } ## ascending sort my $sort=''; if($wepas->{'Sort_a'}) { $sort='a'; } if($wepas->{'Sort_d'}) { $sort='d'; } if( $sort ) { my $action_name='editor_sort'; my $weights=&Ernad::Sorting::parse_weights_from_wepass($wepas); ## don't do anything when we don't have weights if(not &Ernad::Sort::are_all_weights_zero($weights)) { my $rix=$rs->{'rix'} or confess "I need a rix here."; my $doc=&Ernad::Sort::inject_sort($rix,$weights,$action_name); $doc=&Ernad::Sort::sort_by_criterion($doc,$action_name,$sort); $rs->{'rix'}=$doc; $Changes=1; } } if( $Changes ) { if($e->{'testing'}) { print O "Saving file\n"; close O; } $rs->save($e->{'const'}->{'filtered_dir'}); return 0; } #saving weights #Ernad::Common::save_to_file( \@g_weights, $rs->weights_file() ); ## sorting done, move to preview if( defined($wepas->{'Preview'} ) ) { $rs->save( $e->{'const'}->{'ordered_dir'} ); if($e->{'testing'}) { print O "acepted\n"; close O; } return 1; } ## sorting done, move to priew if( defined($wepas->{'Finish'} ) ) { # gone on 2016-06-03 # $rs->save( $e->{'const'}->{'ordered_dir'} ); ## otherwise it is not see next? #$rs->{'e'}=$e or die "no erimp"; &Ernad::Final::Process($wepas, $rs); if($e->{'testing'}) { print O "acepted\n"; close O; } return 1; } ## return to the previous state, filtering if( defined($wepas->{'Back'} ) ) { if($e->{'testing'}) { print O "back button pressed.\n"; close O; } ## need to remove weights #unlink $rs->weights_file(); #unlink $rs->weights_file() . '.xml'; # $rs->save($rs->stage( $e->{'const'}->{'filtered_dir'} )); if($count_docs) { #$rs->stage( $e->{'const'}->{'filtered_dir'} ); #$rs->save($rs->stage( $e->{'const'}->{'filtered_dir'} )); $rs->{'back_from'}='Sorting'; $rs->set_stage($e->{'const'}->{'selected_dir'}); } return -1; } # nothing happened if($e->{'testing'}) { print O "at end of processing\n"; close O; } return 0; } sub parse_weights_from_wepass { my $wepass=shift; my $weights=[]; #open(P,"> /tmp/parse"); foreach my $key (keys %{$wepass}) { #print P "key is $key\n"; if(not $key=~m|^n_(\d+)$|) { #print P "next on $key\n"; next; } my $number=$1; my $value=$wepass->{$key}; if(not looks_like_number($value)) { $value=0; } #print P "value is $value\n"; $weights->[$number]=$value; } #close P; return $weights; } 1;