- Timestamp:
- 06/01/10 10:48:29 (14 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 17 edited
- 5 copied
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/MANIFEST
r316 r319 20 20 lib/Epoll/DB/ImportV.pm 21 21 lib/Epoll/DB/Poll/Bdata.pm 22 lib/Epoll/DB/Poll/Results.pm23 22 lib/Epoll/DB/Poll.pm 24 23 lib/Epoll/DB/Voting.pm -
trunk/lib/Epoll/Controller/Admin.pm
r315 r319 129 129 } else { 130 130 } 131 } 132 if ($c->req->param('publish')) { 133 $c->model('Vote')->poll($c->stash->{voteid})->compute_results; 134 $c->model('Vote')->commit; 131 135 } 132 136 }; -
trunk/lib/Epoll/DB.pm
r307 r319 7 7 use base 'Epoll::DB::common'; 8 8 use Epoll::DB::Poll; 9 use Epoll::DB::Poll::Results;10 9 11 10 our $VERSION = '1.90'; … … 94 93 sub results { 95 94 my ($self, $pollid) = @_; 96 Epoll::DB::Poll ::Results->new($self->{dbstring}, $self->poll_id_from_uid($pollid));95 Epoll::DB::Poll->new($self->{dbstring}, $self->poll_id_from_uid($pollid)); 97 96 } 98 97 -
trunk/lib/Epoll/DB/Ballot.pm
r242 r319 67 67 q{ 68 68 select ballot_item.*, value as v, 69 coalesce(ballot_map.to, corrected)as corrected69 ballot_map.to as corrected 70 70 from ballot_item join ballot on ballot.id = ballot_item.id 71 71 left join ballot_map on ballot_map.poll = ballot.poll and -
trunk/lib/Epoll/DB/ImportV.pm
r315 r319 6 6 7 7 sub new { 8 my ($ self, $type) = @_;8 my ($class, $type) = @_; 9 9 10 10 my $ctype = ucfirst(lc($type)); -
trunk/lib/Epoll/DB/Poll.pm
r317 r319 14 14 use Epoll::DB::Choice; 15 15 use Epoll::DB::Poll::Bdata; 16 use Epoll::DB::Poll::BSubmit; 17 use YAML; 16 18 17 19 =head1 NAME … … 112 114 $voteid && $voteid =~ /^\d+$/ or return; 113 115 114 bless {116 my $poll = bless { 115 117 voteid => $voteid, 116 118 dbstring => $dbstring, 117 119 db => Epoll::DB::common::_newdb($dbstring), 118 120 }, $class; 119 } 121 122 my $type = $poll->type; 123 124 $type = ucfirst(lc($type)); 125 eval "require Epoll::DB::Poll::Type::$type;"; 126 if ($@) { 127 return; 128 } else { 129 return bless($poll, "Epoll::DB::Poll::Type::$type"); 130 } 131 } 132 133 sub type { lc($_[0]->info('type') || 'binary') } 120 134 121 135 sub voteid { $_[0]->{voteid} } … … 467 481 sub decrypted_ballots { 468 482 my ($self, $password) = @_; 469 my $privkey = $self->private_key($password) or return; 470 foreach ($self->list_ballot_need_dec) { 483 my $privkey; 484 if ($self->is_crypted) { 485 $privkey = $self->private_key($password) or return; 486 } 487 my $fetch_data = $self->db->prepare_cached( 488 q{select * from ballot_enc where decrypted = false and poll = ? 489 order by id} 490 ); 491 $fetch_data->execute($self->voteid); 492 while (my $res = $fetch_data->fetchrow_hashref) { 471 493 my $bdata = $self->bdata; 472 $bdata->decrypt($_, $privkey); 494 $bdata->decrypt_data($res->{id}, $res->{data}, $res->{enckey}, $privkey) 495 and return; 473 496 } 474 497 1 … … 477 500 sub register_ballot { 478 501 my ($self, $vmail, $choice, $referal) = @_; 479 480 my $bdata = $self->bdata; 481 foreach (@{ $choice || []}) { 482 $bdata->add_item($_); 483 } 484 $bdata->submit($vmail, $referal) or do { 485 $self->rollback; 486 return; 487 }; 488 489 # everything went fine, saving! 490 $self->commit; 491 492 $bdata->uid 502 # TODO: warn, deprecated 503 504 my $bdata = $self->bsubmit; 505 if (!$choice) { 506 } elsif (ref $choice eq 'ARRAY') { 507 foreach (@{ $choice || []}) { 508 $bdata->add_item($_, 1); 509 } 510 } else { 511 foreach (keys %{ $choice || {}}) { 512 $bdata->add_item($_, $choice->{$_}); 513 } 514 } 515 $bdata->set_voter($vmail, $referal); 516 return $bdata->submit($vmail, $referal); 493 517 } 494 518 … … 514 538 sub auth_voting { 515 539 my ($self, $mail, $password) = @_; 516 $self->voting_from_mail($mail)->auth($password); 540 if (my $voter = $self->voting_from_mail($mail)) { 541 return $voter->auth($password); 542 } else { 543 return; 544 } 517 545 } 518 546 … … 552 580 my ($self) = @_; 553 581 Epoll::DB::Poll::Bdata->new($self->{dbstring}, $self); 582 } 583 584 sub bsubmit { 585 my ($self) = @_; 586 Epoll::DB::Poll::BSubmit->new($self->{dbstring}, $self); 554 587 } 555 588 … … 742 775 my $getval = $self->db->prepare_cached( 743 776 q{ 744 select coalesce(corrected, value)as value from ballot join ballot_item777 select value as value from ballot join ballot_item 745 778 on ballot.id = ballot_item.id 746 779 where poll = ? … … 749 782 : '' 750 783 ) . q{ 751 group by coalesce(corrected, value) order by coalesce(corrected, value)784 group by value order by value 752 785 } 753 786 ); … … 790 823 ); 791 824 792 $sth->execute($self->voteid, $from, $to) or $self->rollback; 825 $sth->execute($self->voteid, $from, $to) or do { 826 $self->rollback; 827 return; 828 }; 793 829 } 794 830 } 795 831 $self->commit; 832 return 1; 796 833 } 797 834 … … 817 854 }); 818 855 819 $add->execute($self->voteid, $id || '', $mail, $extern_auth, $extern_uid); 856 return $add->execute($self->voteid, $id || '', $mail, $extern_auth, $extern_uid); 857 } else { 858 return 1; 820 859 } 821 860 } … … 946 985 } 947 986 987 988 948 989 ######### 949 990 # Count # … … 951 992 952 993 sub ballot_count { 953 my ($self) = @_; 954 return $self->is_crypted 955 ? $self->ballot_count_crypt 956 : $self->ballot_count_clear; 994 ballots_count(@_); 995 } 996 997 sub ballots_count { 998 my ($self) = @_; 999 return $self->ballot_count_crypt; 957 1000 } 958 1001 … … 967 1010 my $res = $sth->fetchrow_hashref; 968 1011 $sth->finish; 969 $res->{count} 1012 $res->{count} || 0 970 1013 } 971 1014 … … 980 1023 my $res = $sth->fetchrow_hashref; 981 1024 $sth->finish; 982 $res->{count} 983 } 984 985 sub voting_count { 1025 $res->{count} || 0 1026 } 1027 1028 sub voting_count { voters_count(@_) } 1029 1030 sub voters_count { 986 1031 my ($self) = @_; 987 1032 … … 1016 1061 sub not_signing_count { 1017 1062 my ($self) = @_; 1018 my $sth = $self->db->prepare_cached( 1019 q{ 1020 select count(*) from voting where key 1021 not in (select key from signing) 1063 $self->voters_count - $self->signing_count; 1064 } 1065 1066 sub valid_ballot_count { 1067 my ($self) = @_; 1068 1069 my $sth = $self->db->prepare_cached( 1070 q{ 1071 select count(*) from ballot where poll = ? 1072 and (invalid = 'f' or invalid is NULL) 1022 1073 } 1023 1074 ); … … 1027 1078 $sth->finish; 1028 1079 $res->{count} 1080 } 1081 1082 sub invalid_ballot_count { 1083 my ($self) = @_; 1084 1085 my $sth = $self->db->prepare_cached( 1086 q{ 1087 select count(*) from ballot where poll = ? 1088 and invalid = 't' 1089 } 1090 ); 1091 1092 $sth->execute($self->voteid); 1093 my $res = $sth->fetchrow_hashref; 1094 $sth->finish; 1095 $res->{count} || 0 1096 } 1097 1098 sub empty_ballot_count { 1099 my ($self) = @_; 1100 1101 my $sth = $self->db->prepare_cached( 1102 q{ 1103 select count(*) from ballot where poll = ? 1104 and id not in (select id from ballot_item) 1105 and (invalid = 'false' or invalid is null) 1106 } 1107 ); 1108 1109 $sth->execute($self->voteid); 1110 my $res = $sth->fetchrow_hashref; 1111 $sth->finish; 1112 $res->{count} 1113 } 1114 1115 sub not_empty_ballot_count { 1116 my ($self) = @_; 1117 1118 my $sth = $self->db->prepare_cached( 1119 q{ 1120 select count(*) from ballot where poll = ? 1121 and id in (select id from ballot_item) 1122 and (invalid = 'false' or invalid is null) 1123 } 1124 ); 1125 1126 $sth->execute($self->voteid); 1127 my $res = $sth->fetchrow_hashref; 1128 $sth->finish; 1129 $res->{count} || 0 1130 } 1131 1132 sub compute_results { 1133 my ($self) = @_; 1134 $self->param('static_results', 1135 YAML::Dump($self->_compute_results)); 1136 } 1137 1138 sub results { 1139 my ($self) = @_; 1140 if (my $res = YAML::Load($self->info('static_results'))) { 1141 return $res 1142 } else { 1143 return; 1144 } 1029 1145 } 1030 1146 … … 1032 1148 # CLEANING DATA # 1033 1149 ################# 1150 1151 sub delete_ballots { 1152 my ($self) = @_; 1153 1154 $self->store_results; 1155 $self->_delete_ballot; 1156 $self->commit; 1157 } 1034 1158 1035 1159 sub _delete_ballot { -
trunk/lib/Epoll/DB/Poll/BSubmit.pm
r315 r319 1 package Epoll::DB::Poll::B data;1 package Epoll::DB::Poll::BSubmit; 2 2 3 3 # $Id$ … … 5 5 use strict; 6 6 use warnings; 7 use base 'Epoll::DB::common'; 8 use Epoll::DB::Poll; 9 use XML::Simple; 10 use Crypt::CBC; 11 use Crypt::DES_EDE3; # Called from CBC 7 use base 'Epoll::DB::Poll::Bdata'; 12 8 13 9 =head1 NAME … … 21 17 =cut 22 18 23 sub new { 24 my ($class, $dbstring, $poll) = @_; 25 26 bless { 27 poll => $poll, 28 dbstring => $dbstring, 29 db => Epoll::DB::common::_newdb($dbstring), 30 data => {} 31 }, $class; 32 } 33 34 sub voteid { $_[0]->poll->voteid } 35 36 sub poll { 37 my ($self) = @_; 38 $self->{poll}; 39 } 40 41 sub uid { 42 my ($self) = @_; 43 $self->{data}{id} ||= Epoll::DB::common::gen_uid(); 44 } 45 46 sub items { 47 my ($self) = @_; 48 @{$self->{data}{content} || []} 19 sub set_voter { 20 my ($self, $voter, $referal) = @_; 21 $self->{voter} = $voter; 22 $self->{referal} = $referal; 49 23 } 50 24 51 25 sub add_item { 52 my ($self, @items) = @_; 53 foreach (@items) { 54 s/^\s+//; 55 s/\s+$//; 56 s/\s+/ /g; 57 $_ = lc($_); 58 59 push(@{$self->{data}{content}}, $_); 60 } 61 } 62 63 sub xmlout { 64 my ($self) = @_; 65 my $xml = XML::Simple->new(ForceArray => 1, RootName => 'ballot'); 66 $xml->XMLout({ 67 id => $self->uid, 68 content => [ $self->items ], 69 }); 70 } 71 72 sub xmlin { 73 my ($self, $data) = @_; 74 my $xmldata = XMLin($data, ForceArray => ['content']); 75 $self->{data}{id} = $xmldata->{id}; 76 if ($xmldata->{content}) { 77 if (ref $xmldata->{content}) { 78 foreach (@{ $xmldata->{content} || []}) { 79 $self->add_item($_); 80 } 81 } else { 82 $self->add_item($xmldata->{content}); 83 } 84 } 26 my ($self, $value, $weight) = @_; 27 $value =~ s/^\s+//; 28 $value =~ s/\s+$//; 29 $value =~ s/\s+/ /g; 30 $value = lc($value); 31 $self->{data}{content}{$value} = $weight; 85 32 } 86 33 87 34 sub submit { 88 my ($self , $voting, $referal) = @_;35 my ($self) = @_; 89 36 90 37 for (0..2) { # 3 try 91 38 # First we register voting has voted 92 $self->poll->_register_signing($ voting, $referal) or return; # TODO error ?39 $self->poll->_register_signing($self->{voter}, $self->{referal}) or return; # TODO error ? 93 40 94 41 # registring choices 95 if ($self->poll->is_crypted 96 ? $self->_store_crypted() 97 : $self->_store_clear()) { 42 if ($self->_store_crypted()) { 98 43 last; 99 44 } else { … … 107 52 108 53 $self->uid 109 }110 111 sub _store_clear {112 my ($self) = @_;113 my $addb = $self->db->prepare_cached(114 q{115 insert into ballot (id, poll, invalid) values (?,?,?)116 }117 );118 119 my $needvalid = 'f';120 my %items = ();121 foreach($self->items) {122 if ($self->poll->find_choice_key($_)) {123 $items{$_} = 't';124 } else {125 $items{$_} = 'f';126 $needvalid = undef;127 }128 }129 130 $addb->execute($self->uid, $self->voteid, $needvalid) or do {131 $self->rollback;132 return;133 };134 135 my $addbc = $self->db->prepare_cached(136 q{137 insert into ballot_item (id, value, fromlist) values (?,?,?)138 }139 );140 foreach (keys %items) {141 $_ or next;142 $addbc->execute($self->uid, $_, $items{$_}) or do {143 $self->rollback;144 return;145 };146 }147 148 1;149 }150 151 sub _store_crypted {152 my ($self) = @_;153 my $symkey = map{ chr(rand(256)) } (1 .. 24);154 my $cipher = new Crypt::CBC($symkey, 'DES_EDE3');155 my $encryptedballot = $cipher->encrypt_hex(156 $self->xmlout()157 );158 my $encsymkey = $self->poll->rsa->encrypt (159 Message => $symkey,160 Key => $self->poll->public_key,161 Armour => 1,162 ) || die $self->poll->rsa->errstr();163 164 my $addenc = $self->db->prepare_cached(165 q{insert into ballot_enc (id, data, enckey, poll) values (?,?,?,?)}166 );167 168 my $uid = Epoll::DB::common::gen_uid();169 $addenc->execute($uid, $encryptedballot, $encsymkey, $self->voteid);170 }171 172 sub _load_crypted {173 my ($self, $ballotid, $privkey) = @_;174 my $sth = $self->db->prepare_cached(175 q{select * from ballot_enc where id = ? for update}176 );177 $sth->execute($ballotid);178 my $ballot = $sth->fetchrow_hashref;179 $sth->finish;180 my $encsymkey = $ballot->{enckey};181 my $data = $ballot->{data};182 my $symkey = $self->poll->rsa->decrypt (183 Cyphertext => $encsymkey,184 Key => $privkey,185 Armour => 1,186 ) || die $self->poll->rsa->errstr();187 my $cipher = new Crypt::CBC($symkey, 'DES_EDE3');188 $self->xmlin($cipher->decrypt_hex($data));189 }190 191 sub decrypt {192 my ($self, $ballotid, $privkey) = @_;193 $self->_load_crypted($ballotid, $privkey);194 $self->_store_clear or return;195 my $upd = $self->db->prepare_cached(q{update ballot_enc set decrypted = true where id = ?});196 if ($upd->execute($ballotid)) {197 $self->commit;198 return;199 } else {200 $self->rollback;201 return 1;202 }203 54 } 204 55 -
trunk/lib/Epoll/DB/Poll/Bdata.pm
r242 r319 7 7 use base 'Epoll::DB::common'; 8 8 use Epoll::DB::Poll; 9 use XML::Simple;9 use YAML (); 10 10 use Crypt::CBC; 11 11 use Crypt::DES_EDE3; # Called from CBC … … 28 28 dbstring => $dbstring, 29 29 db => Epoll::DB::common::_newdb($dbstring), 30 data => {} 30 data => {}, 31 31 }, $class; 32 32 } … … 44 44 } 45 45 46 sub items {47 my ($self) = @_;48 @{$self->{data}{content} || []}49 }50 51 sub add_item {52 my ($self, @items) = @_;53 foreach (@items) {54 s/^\s+//;55 s/\s+$//;56 s/\s+/ /g;57 $_ = lc($_);58 59 push(@{$self->{data}{content}}, $_);60 }61 }62 63 46 sub xmlout { 64 47 my ($self) = @_; 65 my $xml = XML::Simple->new(ForceArray => 1, RootName => 'ballot'); 66 $xml->XMLout({ 67 id => $self->uid, 68 content => [ $self->items ], 69 }); 48 $self->uid; 49 YAML::Dump($self->{data}); 70 50 } 71 51 72 52 sub xmlin { 73 53 my ($self, $data) = @_; 74 my $xmldata = XMLin($data, ForceArray => ['content']); 75 $self->{data}{id} = $xmldata->{id}; 76 if ($xmldata->{content}) { 77 if (ref $xmldata->{content}) { 78 foreach (@{ $xmldata->{content} || []}) { 79 $self->add_item($_); 80 } 81 } else { 82 $self->add_item($xmldata->{content}); 83 } 84 } 85 } 86 87 sub submit { 88 my ($self, $voting, $referal) = @_; 89 90 for (0..2) { # 3 try 91 # First we register voting has voted 92 $self->poll->_register_signing($voting, $referal) or return; # TODO error ? 93 94 # registring choices 95 if ($self->poll->is_crypted 96 ? $self->_store_crypted() 97 : $self->_store_clear()) { 98 last; 99 } else { 100 $self->rollback; 101 next; 102 } 103 104 } 105 # everything went fine, saving! 106 $self->commit; 107 108 $self->uid 54 $self->{data} = YAML::Load($data); 109 55 } 110 56 … … 119 65 my $needvalid = 'f'; 120 66 my %items = (); 121 foreach( $self->items) {67 foreach(keys %{$self->{data}{content} || {}}) { 122 68 if ($self->poll->find_choice_key($_)) { 123 69 $items{$_} = 't'; … … 135 81 my $addbc = $self->db->prepare_cached( 136 82 q{ 137 insert into ballot_item (id, value, fromlist ) values (?,?,?)83 insert into ballot_item (id, value, fromlist, weight) values (?,?,?,?) 138 84 } 139 85 ); 140 foreach (keys % items) {86 foreach (keys %{$self->{data}{content} || {}}) { 141 87 $_ or next; 142 $addbc->execute($self->uid, $_, $items{$_} ) or do {88 $addbc->execute($self->uid, $_, $items{$_}, $self->{data}{content}{$_}) or do { 143 89 $self->rollback; 144 90 return; … … 151 97 sub _store_crypted { 152 98 my ($self) = @_; 153 my $symkey = map{ chr(rand(256)) } (1 .. 24); 154 my $cipher = new Crypt::CBC($symkey, 'DES_EDE3'); 155 my $encryptedballot = $cipher->encrypt_hex( 156 $self->xmlout() 157 ); 158 my $encsymkey = $self->poll->rsa->encrypt ( 159 Message => $symkey, 160 Key => $self->poll->public_key, 161 Armour => 1, 162 ) || die $self->poll->rsa->errstr(); 163 99 164 100 my $addenc = $self->db->prepare_cached( 165 101 q{insert into ballot_enc (id, data, enckey, poll) values (?,?,?,?)} 166 102 ); 167 168 103 my $uid = Epoll::DB::common::gen_uid(); 169 $addenc->execute($uid, $encryptedballot, $encsymkey, $self->voteid); 104 105 if (my $pollkey = $self->poll->public_key) { 106 my $symkey = map{ chr(rand(256)) } (1 .. 24); 107 my $cipher = new Crypt::CBC($symkey, 'DES_EDE3'); 108 my $encryptedballot = $cipher->encrypt_hex( 109 $self->xmlout() 110 ); 111 my $encsymkey = $self->poll->rsa->encrypt ( 112 Message => $symkey, 113 Key => $self->poll->public_key, 114 Armour => 1, 115 ) || die $self->poll->rsa->errstr(); 116 $addenc->execute($uid, $encryptedballot, $encsymkey, $self->voteid); 117 } else { 118 $addenc->execute($uid, $self->xmlout(), undef, $self->voteid); 119 } 170 120 } 171 121 … … 178 128 my $ballot = $sth->fetchrow_hashref; 179 129 $sth->finish; 180 my $encsymkey = $ballot->{enckey}; 181 my $data = $ballot->{data}; 182 my $symkey = $self->poll->rsa->decrypt ( 183 Cyphertext => $encsymkey, 184 Key => $privkey, 185 Armour => 1, 186 ) || die $self->poll->rsa->errstr(); 187 my $cipher = new Crypt::CBC($symkey, 'DES_EDE3'); 188 $self->xmlin($cipher->decrypt_hex($data)); 130 $self->_load_crypted_data($ballot->{data}, $ballot->{enckey}, $privkey); 131 } 132 133 sub _load_crypted_data { 134 my ($self, $data, $encsymkey, $privkey) = @_; 135 if ($encsymkey) { 136 my $symkey = $self->poll->rsa->decrypt ( 137 Cyphertext => $encsymkey, 138 Key => $privkey, 139 Armour => 1, 140 ) || die $self->poll->rsa->errstr(); 141 my $cipher = new Crypt::CBC($symkey, 'DES_EDE3'); 142 return $self->xmlin($cipher->decrypt_hex($data)); 143 } else { 144 return $self->xmlin($data); 145 } 146 } 147 148 sub decrypt_data { 149 my ($self, $ballotid, $data, $encsymkey, $privkey) = @_; 150 if ($self->_load_crypted_data($data, $encsymkey, $privkey) && 151 $self->_store_clear && 152 $self->_set_decrypted($ballotid)) { 153 $self->commit; 154 return; 155 } else { 156 $self->rollback; 157 return 1; 158 } 159 } 160 161 sub _set_decrypted { 162 my ($self, $ballotid) = @_; 163 my $upd = $self->db->prepare_cached(q{update ballot_enc set decrypted = true where id = ?}); 164 $upd->execute($ballotid) 189 165 } 190 166 … … 193 169 $self->_load_crypted($ballotid, $privkey); 194 170 $self->_store_clear or return; 195 my $upd = $self->db->prepare_cached(q{update ballot_enc set decrypted = true where id = ?}); 196 if ($upd->execute($ballotid)) { 171 if ($self->_set_decrypted($ballotid)) { 197 172 $self->commit; 198 173 return; -
trunk/lib/Epoll/DB/Poll/Type/Binary.pm
r315 r319 1 package Epoll::DB::Poll:: Results;1 package Epoll::DB::Poll::Type::Binary; 2 2 3 3 # $Id$ … … 6 6 use warnings; 7 7 use base 'Epoll::DB::Poll'; 8 use XML::Simple; 9 use vars qw($AUTOLOAD); 8 use YAML; 10 9 11 10 =head1 NAME … … 19 18 =cut 20 19 21 sub new{22 my ($ class, @args) = @_;20 sub _check_ballot { 21 my ($self, $bdata) = @_; 23 22 24 my $res = $class->SUPER::new(@args);25 26 $res = bless $res, $class;27 $res->load_static_data;28 $res29 23 } 30 24 31 sub AUTOLOAD { 32 my ($self, @args) = @_; 33 my ($constname, $sub) = $AUTOLOAD =~ m/(.*)::([^:]+)/; 34 $sub =~ /^__(.*)/ and die "No sub $1"; 35 if ($self->{static_results}) { 36 return $self->{static_results}{$sub}; 37 } else { 38 my $realsub = "__$sub"; 39 return $self->$realsub(@args); 40 } 25 sub _compute_results { 26 my ($self) = @_; 27 $self->_results( 28 $self->info('empty_ballot_has_voice') 29 ? 0 30 : 1 31 ); 41 32 } 42 33 43 sub DESTROY {} 44 45 sub load_static_data { 34 sub absolute_majority { 46 35 my ($self) = @_; 47 if (my $res = $self->info('static_results')) { 48 $self->{static_results} = XMLin( 49 $res, 50 ForceArray => ['results'] 51 ); 52 } 53 } 54 55 sub ballot_count { 56 my ($self) = @_; 57 if ($self->{static_results}) { 58 return $self->{static_results}{ballot_count}; 59 } else { 60 return $self->SUPER::ballot_count(); 61 } 62 } 63 64 sub __absolute_majority { 65 my ($self) = @_; 66 my $ballot_count = $self->voices_ballot_count; 67 return int($ballot_count / 2) + 1; 36 return int($self->_voices_ballot_count / 2) + 1; 68 37 } 69 38 70 sub __ abstention {39 sub ___abstention { 71 40 my ($self) = @_; 72 41 … … 85 54 } 86 55 87 sub __ballot_count_nonull {not_empty_ballot_count(@_)}56 sub voices_ballot_count { _voices_ballot_count(@_) } 88 57 89 sub _ _voices_ballot_count {58 sub _voices_ballot_count { 90 59 my ($self) = @_; 91 60 return $self->info('empty_ballot_has_voice') 92 ? $self->valid_ballot_count 93 : $self->not_empty_ballot_count; 94 } 95 96 sub __valid_ballot_count { 97 my ($self) = @_; 98 99 my $sth = $self->db->prepare_cached( 100 q{ 101 select count(*) from ballot where poll = ? 102 and (invalid = 'f' or invalid is NULL) 103 } 104 ); 105 106 $sth->execute($self->voteid); 107 my $res = $sth->fetchrow_hashref; 108 $sth->finish; 109 $res->{count} 110 } 111 112 sub __invalid_ballot_count { 113 my ($self) = @_; 114 115 my $sth = $self->db->prepare_cached( 116 q{ 117 select count(*) from ballot where poll = ? 118 and invalid = 't' 119 } 120 ); 121 122 $sth->execute($self->voteid); 123 my $res = $sth->fetchrow_hashref; 124 $sth->finish; 125 $res->{count} 126 } 127 128 sub __empty_ballot_count { 129 my ($self) = @_; 130 131 my $sth = $self->db->prepare_cached( 132 q{ 133 select count(*) from ballot where poll = ? 134 and id not in (select id from ballot_item) 135 and (invalid = 'false' or invalid is null) 136 } 137 ); 138 139 $sth->execute($self->voteid); 140 my $res = $sth->fetchrow_hashref; 141 $sth->finish; 142 $res->{count} 143 } 144 145 sub __not_empty_ballot_count { 146 my ($self) = @_; 147 148 my $sth = $self->db->prepare_cached( 149 q{ 150 select count(*) from ballot where poll = ? 151 and id in (select id from ballot_item) 152 and (invalid = 'false' or invalid is null) 153 } 154 ); 155 156 $sth->execute($self->voteid); 157 my $res = $sth->fetchrow_hashref; 158 $sth->finish; 159 $res->{count} 160 } 161 162 sub results_count { 163 my ($self) = @_; 164 $self->_results(); 165 } 166 167 sub results_nonull { 168 my ($self) = @_; 169 $self->_results(1); 170 } 171 172 sub __results { 173 my ($self) = @_; 174 $self->_results( 175 $self->info('empty_ballot_has_voice') 176 ? 0 177 : 1 178 ); 61 ? $self->valid_ballot_count 62 : $self->not_empty_ballot_count; 179 63 } 180 64 … … 186 70 select count(ballot.id), value from 187 71 ( 188 select NULL as id, label as value from choice where poll = ?72 select NULL as id, label as value from choice where poll = $1 189 73 union 190 select ballot.id, coalesce( corrected,ballot_map.to, value) as "value" from ballot74 select ballot.id, coalesce(ballot_map.to, value) as "value" from ballot 191 75 } . ($nonull ? '' : ' left ') . q{ join ballot_item 192 76 on ballot.id = ballot_item.id 193 left join ballot_map on ballot.poll = ballot_map.poll and ballot_map.from = ballot_item.value 194 where ballot.poll = ? and (invalid = 'false' or invalid is null 77 left join ballot_map on ballot_map.from = ballot_item.value and 78 ballot_map.poll = ballot.poll 79 where ballot.poll = $1 and (invalid = 'false' or invalid is null 195 80 ) 196 group by ballot.id, coalesce( corrected,ballot_map.to, value)) as ballot81 group by ballot.id, coalesce(ballot_map.to, value)) as ballot 197 82 group by value 198 83 order by count desc, value 199 84 } 200 85 ); 201 $sth->execute($self->voteid , $self->voteid);86 $sth->execute($self->voteid); 202 87 my @results; 203 88 my $abs_maj = $self->absolute_majority; 204 89 my $wanted_count = $self->info('elected_count'); 205 my $voice_count = $self-> voices_ballot_count;90 my $voice_count = $self->_voices_ballot_count; 206 91 while (my $res = $sth->fetchrow_hashref) { 207 92 if ($res->{count} >= $abs_maj) { … … 227 112 } 228 113 229 sub dump_results {230 my ($self) = @_;231 my $xml = XML::Simple->new(ForceArray => 1, RootName => 'results');232 my %results;233 234 foreach my $val (qw(235 ballot_count236 ),237 map { s/^__//; $_ } grep { /^__/ } keys %{Epoll::DB::Poll::Results::}238 ) {239 $results{$val} = $self->$val();240 }241 $xml->XMLout({242 %results243 });244 }245 246 sub delete_ballots {247 my ($self) = @_;248 249 $self->param('static_results' => $self->dump_results);250 $self->_delete_ballot;251 $self->commit;252 $self->{static_results} = XMLin(253 $self->info('static_results'),254 ForceArray => ['results']255 );256 }257 114 258 115 =head1 AUTHOR -
trunk/lib/Epoll/I18N/fr.po
r315 r319 81 81 msgstr "Bulletins" 82 82 83 #: root/templates/includes/poll_results.tt:47 84 #, fuzzy 85 msgid "Ballot list:" 86 msgstr "Bulletins:" 87 83 88 #: root/templates/includes/poll.tt:22 root/templates/includes/poll.tt:32 84 89 msgid "Ballot:" 85 90 msgstr "Bulletins:" 86 91 92 #: root/templates/includes/poll_results.tt:26 93 #, fuzzy 94 msgid "Ballots count" 95 msgstr "bulletins contenant:" 96 97 #: root/templates/admin/votersimport.tt:13 98 #: root/templates/admin/votersimport.tt:14 99 msgid "CSV file" 100 msgstr "" 101 87 102 #: root/templates/admin/denied.tt:4 88 103 msgid "Cannot modify a started or finish poll" … … 161 176 msgstr "Télécharger la clef privée" 162 177 178 #: root/templates/admin/votersimport.tt:10 179 #: root/templates/admin/votersimport.tt:11 180 msgid "Dummy" 181 msgstr "" 182 163 183 #: root/templates/includes/ballot_form.tt:59 164 184 msgid "Empty ballot" … … 169 189 msgstr "Saisissez le mot de passe d'administration du vote" 170 190 191 #: root/templates/admin/votersimport.tt:48 192 msgid "Enter here a comment to explain the password to use" 193 msgstr "" 194 171 195 #: root/templates/admin/includes/ballot_decrypt.tt:8 172 196 msgid "Enter poll key here:" … … 208 232 msgid "From voting list" 209 233 msgstr "Depuis la liste des votants" 234 235 #: root/templates/includes/poll_results.tt:49 236 msgid "Id" 237 msgstr "" 238 239 #: root/templates/admin/votersimport.tt:51 240 msgid "Import this list" 241 msgstr "" 210 242 211 243 #: root/templates/ballot/login.tt:6 … … 246 278 msgstr "Juin" 247 279 280 #: root/templates/admin/votersimport.tt:16 281 #: root/templates/admin/votersimport.tt:17 282 msgid "LDAP" 283 msgstr "" 284 248 285 #: root/templates/admin/includes/poll_extra_settings.tt:9 249 286 msgid "Mail include ballot id" … … 311 348 msgstr "Nombre" 312 349 350 #: root/templates/includes/poll_results.tt:17 351 #, fuzzy 352 msgid "Number of choice to retain:" 353 msgstr "Nombre de personnes à élire" 354 355 #: root/templates/includes/poll_results.tt:30 356 #, fuzzy 357 msgid "Number of empty ballot" 358 msgstr "Nombre de personnes à élire" 359 313 360 #: root/templates/admin/ballot.tt:22 314 361 msgid "Number of free input fields:" 315 362 msgstr "Nombre de champ de saisie libre:" 363 364 #: root/templates/includes/poll_results.tt:35 365 #, fuzzy 366 msgid "Number of nul ballot" 367 msgstr "Nombre de personnes à élire" 316 368 317 369 #: root/templates/admin/ballot.tt:15 … … 344 396 msgstr "A participé" 345 397 398 #: root/templates/includes/poll_results.tt:21 399 #, fuzzy 400 msgid "Participation" 401 msgstr "A participé" 402 346 403 #: root/templates/newpoll/index.tt:27 347 404 msgid "Password" … … 366 423 msgstr "Merci de confirmer l'effacement du vote %1" 367 424 425 #: root/templates/includes/poll_results.tt:13 426 msgid "Poll administrator must validate some ballot" 427 msgstr "" 428 368 429 #: root/templates/admin/date.tt:124 369 430 msgid "Poll end:" … … 391 452 msgstr "Prévisualisation du bulletin" 392 453 454 #: root/templates/includes/poll_results.tt:90 455 msgid "Results are not yet published" 456 msgstr "" 457 393 458 #: root/templates/ballot/done.tt:16 root/templates/ballot/signed.tt:6 394 459 msgid "Results will be available" 395 460 msgstr "Les résultats seront disponibles" 396 461 462 #: root/templates/includes/poll_results.tt:15 463 #, fuzzy 464 msgid "Results:" 465 msgstr "RÚglement:" 466 397 467 #: root/templates/admin/includes/poll_settings.tt:13 398 468 msgid "Rules:" … … 428 498 msgid "Sunday" 429 499 msgstr "Dimanche" 500 501 #: root/templates/includes/poll_results.tt:12 502 msgid "Temporary results" 503 msgstr "" 430 504 431 505 #: root/templates/newpoll/request.tt:7 … … 481 555 msgstr "Mardi" 482 556 557 #: root/templates/admin/votersimport.tt:47 558 msgid "Use external authentication" 559 msgstr "" 560 483 561 #: root/templates/ballot/default.tt:43 484 562 msgid "Valid" … … 585 663 msgstr "bulletins contenant:" 586 664 665 #: root/templates/includes/poll_results.tt:54 666 msgid "comment" 667 msgstr "" 668 587 669 #: root/templates/admin/includes/poll_settings.tt:49 588 670 msgid "crypt the poll" 589 671 msgstr "Chiffrer ce vote" 672 673 #: root/templates/includes/poll_results.tt:50 674 msgid "date (=> view as)" 675 msgstr "" 590 676 591 677 #: root/templates/admin/date.tt:116 root/templates/admin/date.tt:125 … … 607 693 msgstr "pour %1 à élire" 608 694 695 #: root/templates/importv/csv.tt:1 696 msgid "format:" 697 msgstr "format:" 698 609 699 #: root/templates/includes/signing_list.tt:23 610 700 msgid "has vote" … … 620 710 msgstr "si différent du nombre de choix" 621 711 622 #: root/templates/admin/validate.tt: 77712 #: root/templates/admin/validate.tt:82 623 713 msgid "input value" 624 714 msgstr "valeur saisie" … … 628 718 msgstr "invalide" 629 719 720 #: root/templates/includes/poll_results.tt:76 721 #, fuzzy 722 msgid "invalided" 723 msgstr "invalide" 724 630 725 #: root/templates/admin/validate.tt:56 631 726 msgid "is not valid" … … 640 735 msgstr "lister les bulletins:" 641 736 642 #: root/templates/admin/validate.tt: 75737 #: root/templates/admin/validate.tt:80 643 738 msgid "map ballot value" 644 739 msgstr "mapper les valeurs des bulletins" … … 648 743 msgstr "modifier mon vote" 649 744 650 #: root/templates/admin/validate.tt: 77745 #: root/templates/admin/validate.tt:82 651 746 msgid "must be see as" 652 747 msgstr "doit être vu comme" 748 749 #: root/templates/includes/poll_results.tt:78 750 #, fuzzy 751 msgid "must be validated" 752 msgstr "Des bulletins doivent être validés" 653 753 654 754 #: root/templates/admin/validate.tt:12 … … 656 756 msgstr "necessitant une validation" 657 757 758 #: root/templates/includes/poll_results.tt:52 759 msgid "not from list" 760 msgstr "" 761 762 #: root/templates/includes/poll_results.tt:49 763 #, fuzzy 764 msgid "number" 765 msgstr "Nombre" 766 658 767 #: root/templates/admin/voters.tt:59 659 768 msgid "password sent" 660 769 msgstr "mot de passe envoyé" 661 770 771 #: root/templates/admin/validate.tt:74 772 msgid "publish results" 773 msgstr "" 774 662 775 #: root/mail/poll_reminder_voting.tt:26 663 776 msgid "running" … … 668 781 msgstr "enregistrer" 669 782 783 #: root/templates/admin/votersimport.tt:33 784 msgid "search..." 785 msgstr "" 786 787 #: root/templates/admin/votersimport.tt:20 788 #, fuzzy 789 msgid "select" 790 msgstr "Effacer" 791 670 792 #: root/templates/admin/voters.tt:30 671 793 msgid "send password" … … 704 826 msgstr "L'identifiant de vote bulletin est:" 705 827 828 #, fuzzy 829 #~ msgid "Ballot Number" 830 #~ msgstr "Bulletins" 831 832 #, fuzzy 833 #~ msgid "Elected" 834 #~ msgstr "Effacer" 835 836 #, fuzzy 837 #~ msgid "Number of voice" 838 #~ msgstr "Nombre de choix possibles:" 839 840 #, fuzzy 841 #~ msgid "Number of voices" 842 #~ msgstr "Nombre de choix possibles:" 843 844 #, fuzzy 845 #~ msgid "choice" 846 #~ msgstr "Choix libre" 847 706 848 #~ msgid "From a csv file" 707 849 #~ msgstr "Depuis un fichier CSV" 708 850 709 #~ msgid "format:"710 #~ msgstr "format:"711 712 851 #~ msgid "Voting" 713 852 #~ msgstr "Votant" -
trunk/lib/Epoll/I18N/messages.pot
r315 r319 79 79 msgstr "" 80 80 81 #: root/templates/includes/poll_results.tt:47 82 msgid "Ballot list:" 83 msgstr "" 84 81 85 #: root/templates/includes/poll.tt:22 root/templates/includes/poll.tt:32 82 86 msgid "Ballot:" 83 87 msgstr "" 84 88 89 #: root/templates/includes/poll_results.tt:26 90 msgid "Ballots count" 91 msgstr "" 92 93 #: root/templates/admin/votersimport.tt:13 root/templates/admin/votersimport.tt:14 94 msgid "CSV file" 95 msgstr "" 96 85 97 #: root/templates/admin/denied.tt:4 86 98 msgid "Cannot modify a started or finish poll" … … 159 171 msgstr "" 160 172 173 #: root/templates/admin/votersimport.tt:10 root/templates/admin/votersimport.tt:11 174 msgid "Dummy" 175 msgstr "" 176 161 177 #: root/templates/includes/ballot_form.tt:59 162 178 msgid "Empty ballot" … … 167 183 msgstr "" 168 184 185 #: root/templates/admin/votersimport.tt:48 186 msgid "Enter here a comment to explain the password to use" 187 msgstr "" 188 169 189 #: root/templates/admin/includes/ballot_decrypt.tt:8 170 190 msgid "Enter poll key here:" … … 205 225 #: root/templates/includes/ballot_form.tt:28 206 226 msgid "From voting list" 227 msgstr "" 228 229 #: root/templates/includes/poll_results.tt:49 230 msgid "Id" 231 msgstr "" 232 233 #: root/templates/admin/votersimport.tt:51 234 msgid "Import this list" 207 235 msgstr "" 208 236 … … 241 269 msgstr "" 242 270 271 #: root/templates/admin/votersimport.tt:16 root/templates/admin/votersimport.tt:17 272 msgid "LDAP" 273 msgstr "" 274 243 275 #: root/templates/admin/includes/poll_extra_settings.tt:9 244 276 msgid "Mail include ballot id" … … 305 337 msgstr "" 306 338 339 #: root/templates/includes/poll_results.tt:17 340 msgid "Number of choice to retain:" 341 msgstr "" 342 343 #: root/templates/includes/poll_results.tt:30 344 msgid "Number of empty ballot" 345 msgstr "" 346 307 347 #: root/templates/admin/ballot.tt:22 308 348 msgid "Number of free input fields:" 349 msgstr "" 350 351 #: root/templates/includes/poll_results.tt:35 352 msgid "Number of nul ballot" 309 353 msgstr "" 310 354 … … 338 382 msgstr "" 339 383 384 #: root/templates/includes/poll_results.tt:21 385 msgid "Participation" 386 msgstr "" 387 340 388 #: root/templates/newpoll/index.tt:27 341 389 msgid "Password" … … 359 407 msgstr "" 360 408 409 #: root/templates/includes/poll_results.tt:13 410 msgid "Poll administrator must validate some ballot" 411 msgstr "" 412 361 413 #: root/templates/admin/date.tt:124 362 414 msgid "Poll end:" … … 384 436 msgstr "" 385 437 438 #: root/templates/includes/poll_results.tt:90 439 msgid "Results are not yet published" 440 msgstr "" 441 386 442 #: root/templates/ballot/done.tt:16 root/templates/ballot/signed.tt:6 387 443 msgid "Results will be available" 388 444 msgstr "" 389 445 446 #: root/templates/includes/poll_results.tt:15 447 msgid "Results:" 448 msgstr "" 449 390 450 #: root/templates/admin/includes/poll_settings.tt:13 391 451 msgid "Rules:" … … 418 478 #: root/templates/admin/date.tt:44 419 479 msgid "Sunday" 480 msgstr "" 481 482 #: root/templates/includes/poll_results.tt:12 483 msgid "Temporary results" 420 484 msgstr "" 421 485 … … 462 526 #: root/templates/admin/date.tt:46 463 527 msgid "Tuesday" 528 msgstr "" 529 530 #: root/templates/admin/votersimport.tt:47 531 msgid "Use external authentication" 464 532 msgstr "" 465 533 … … 564 632 msgstr "" 565 633 634 #: root/templates/includes/poll_results.tt:54 635 msgid "comment" 636 msgstr "" 637 566 638 #: root/templates/admin/includes/poll_settings.tt:49 567 639 msgid "crypt the poll" 640 msgstr "" 641 642 #: root/templates/includes/poll_results.tt:50 643 msgid "date (=> view as)" 568 644 msgstr "" 569 645 … … 585 661 msgstr "" 586 662 663 #: root/templates/importv/csv.tt:1 664 msgid "format:" 665 msgstr "" 666 587 667 #: root/templates/includes/signing_list.tt:23 588 668 msgid "has vote" … … 597 677 msgstr "" 598 678 599 #: root/templates/admin/validate.tt: 77679 #: root/templates/admin/validate.tt:82 600 680 msgid "input value" 601 681 msgstr "" … … 605 685 msgstr "" 606 686 687 #: root/templates/includes/poll_results.tt:76 688 msgid "invalided" 689 msgstr "" 690 607 691 #: root/templates/admin/validate.tt:56 608 692 msgid "is not valid" … … 617 701 msgstr "" 618 702 619 #: root/templates/admin/validate.tt: 75703 #: root/templates/admin/validate.tt:80 620 704 msgid "map ballot value" 621 705 msgstr "" … … 625 709 msgstr "" 626 710 627 #: root/templates/admin/validate.tt: 77711 #: root/templates/admin/validate.tt:82 628 712 msgid "must be see as" 713 msgstr "" 714 715 #: root/templates/includes/poll_results.tt:78 716 msgid "must be validated" 629 717 msgstr "" 630 718 … … 633 721 msgstr "" 634 722 723 #: root/templates/includes/poll_results.tt:52 724 msgid "not from list" 725 msgstr "" 726 727 #: root/templates/includes/poll_results.tt:49 728 msgid "number" 729 msgstr "" 730 635 731 #: root/templates/admin/voters.tt:59 636 732 msgid "password sent" 637 733 msgstr "" 638 734 735 #: root/templates/admin/validate.tt:74 736 msgid "publish results" 737 msgstr "" 738 639 739 #: root/mail/poll_reminder_voting.tt:26 640 740 msgid "running" … … 645 745 msgstr "" 646 746 747 #: root/templates/admin/votersimport.tt:33 748 msgid "search..." 749 msgstr "" 750 751 #: root/templates/admin/votersimport.tt:20 752 msgid "select" 753 msgstr "" 754 647 755 #: root/templates/admin/voters.tt:30 648 756 msgid "send password" -
trunk/root/templates/admin/ballot.tt
r296 r319 4 4 [% poll = c.model('Vote').poll(voteid) %] 5 5 6 <div style="float: left; width: 55%" class="box"> 7 <form action="[% c.uri_for(poll.uid, 'ballot') %]" method="POST"> 8 <table border=1> 9 <tr> 10 <td>[% l('Number of possible choice:') %]</td> 11 <td><input type="text" size="3" name="choice_count" value="[% c.req.param('choice_count') || poll.info('choice_count') | html %]"></td> 12 </tr> 13 14 <tr> 15 <td>[% l('Number of people to elect') %]<br> 16 ([% l('if different of number of choice') %]) 17 </td> 18 <td><input type="text" size="3" name="elected_count" value="[% c.req.param('elected_count') || poll.raw_info('elected_count') | html %]"></td> 19 </tr> 20 21 <tr> 22 <td>[% l('Number of free input fields:') %]</td> 23 <td><input type="text" size="3" name="free_choice" value="[% c.req.param('free_choice') || poll.info('free_choice') || 0 | html %]"></td> 24 </tr> 25 26 <tr> 27 <td>[% l('Number of people to elect, taken from voting list') %]</td> 28 <td><input type="text" size="3" name="elected_choice" value="[% c.req.param('elected_choice') || poll.info('elected_choice') || 0 | html %]"></td> 29 </tr> 30 31 </table> 32 <input type="submit" name="pollballot" value="[% l('save') %]"> 33 </form> 6 [% INCLUDE 'includes/ballot_settings.tt' %] 34 7 35 8 <hr> -
trunk/root/templates/admin/validate.tt
r282 r319 70 70 71 71 <div style="float:left; width: 40%;" class="box"> 72 <div id="publish"> 73 <form action="[% c.uri_for(poll.uid, 'validate') %]" method="POST"> 74 <input type=submit name="publish" value="[% l('publish results') %]"> 75 </form> 76 </div> 72 77 [% FOREACH untrusted = poll.ballot_untrusted_values('noinvalid') %] 73 78 [% IF loop.first %] … … 79 84 <tr> 80 85 [% bl = [ poll.ballot_by_value(untrusted) ] %] 81 <td>[% untrusted | html %] [% bl.size %]</td>86 <td>[% untrusted | html %]</td> 82 87 <td> 83 88 <form action="[% c.uri_for(poll.uid, 'validate') %]" method="POST"> -
trunk/root/templates/admin/votersimport.tt
r315 r319 53 53 </div> 54 54 [% END %] 55 <p>[% voter.0 | html %]</p> 55 <p>[% voter.0 | html %] 56 [% voter.1 | html %] 57 [% voter.2 | html %]</p> 56 58 [% END %] 57 59 </div> -
trunk/root/templates/includes/ballot_form.tt
r298 r319 11 11 12 12 <form action="[% b_form_url %]" method="POST"> 13 <p>Vous devez faire [% poll.info('choice_count') %] choix14 [%- IF poll.info('choice_count') != poll.info('elected_count') -%]15 pour [% poll.info('elected_count') %] élu(s)[%- END -%].</p>16 13 17 [% FOREACH key = poll.choices() %] 18 [% "<p>Candidats:</p>" IF loop.first %] 19 [% choice = poll.choice(key) %] 20 <input type="checkbox" name="sbal" value="[% key %]"[% " checked" IF sbal.$key %]> 21 [% choice.info.label | html %]<br> 22 [% END %] 14 [% ballottt = 'pollinc/' _ poll.type _ '/ballot.tt' %] 15 [% INCLUDE $ballottt %] 23 16 24 [% count = 0 %]25 [% IF poll.voting_keys.size %]26 [% WHILE count < (poll.info('elected_choice') || 0) %]27 [% IF count == 0 %]28 <p>[% l('From voting list') %]</p>29 [% END %]30 [% FOREACH vkey = poll.voting_keys %]31 [% voting = poll.voting(vkey) %]32 [% '<select name="esbal"><option value=""></option>' IF loop.first %]33 <option value="[% voting.info.label || voting.info.mail | html %]"34 [% " selected" IF esbal.$count == (voting.info.label || voting.info.mail) %]>35 [% voting.info.label || voting.info.mail | html %]36 </option>37 [% '</select><br>' IF loop.last %]38 [% END %]39 [% count = count + 1 %]40 [% END %]41 [% ELSE %]42 <p>[% l('No voter to show') %]</p>43 [% END %]44 45 46 [% count = 0 %]47 [% WHILE count < poll.info('free_choice') %]48 [% IF count == 0 %]49 <p>[% l('Free choice') %]</p>50 [% END %]51 <input type="text" name="fsbal" value="[% fsbal.$count %]"><br>52 [% count = count + 1 %]53 [% END %]54 17 <br> 55 18 <input type="submit" name="ballot" value="[% l('Vote') _ ' ' %] >>"> -
trunk/root/templates/includes/ballot_settings.tt
r315 r319 1 1 <!-- $Id$ --> 2 [% INCLUDE 'includes/admin_menu.tt' %]3 4 2 [% poll = c.model('Vote').poll(voteid) %] 5 3 6 4 <div style="float: left; width: 55%" class="box"> 7 5 <form action="[% c.uri_for(poll.uid, 'ballot') %]" method="POST"> 8 <table border=1>9 <tr>10 <td>[% l('Number of possible choice:') %]</td>11 <td><input type="text" size="3" name="choice_count" value="[% c.req.param('choice_count') || poll.info('choice_count') | html %]"></td>12 </tr>13 6 14 <tr> 15 <td>[% l('Number of people to elect') %]<br> 16 ([% l('if different of number of choice') %]) 17 </td> 18 <td><input type="text" size="3" name="elected_count" value="[% c.req.param('elected_count') || poll.raw_info('elected_count') | html %]"></td> 19 </tr> 7 [% ballotsettingstt = 'pollinc/' _ poll.type _ '/ballot_settings.tt' %] 8 [% INCLUDE $ballotsettingstt %] 20 9 21 <tr>22 <td>[% l('Number of free input fields:') %]</td>23 <td><input type="text" size="3" name="free_choice" value="[% c.req.param('free_choice') || poll.info('free_choice') || 0 | html %]"></td>24 </tr>25 26 <tr>27 <td>[% l('Number of people to elect, taken from voting list') %]</td>28 <td><input type="text" size="3" name="elected_choice" value="[% c.req.param('elected_choice') || poll.info('elected_choice') || 0 | html %]"></td>29 </tr>30 31 </table>32 10 <input type="submit" name="pollballot" value="[% l('save') %]"> 33 11 </form> 34 12 35 <hr>36 37 [% IF ! poll.choices_keys.size %]38 <p class="alert">[% l('No choice are configured') %]</p>39 [% ELSE %]40 [% FOREACH choicek = poll.choices_keys %]41 [% choice = poll.choice(choicek) %]42 <form action="[% c.uri_for(poll.uid, 'ballot') %]" method="POST">43 [% loop.count %] - [% choice.info.label | html %]44 <input type="hidden" name="delch" value="[% choicek %]">45 <input type="submit" name="del" value="[% l('delete') %]">46 </form>47 <br>48 [% END %]49 [% END %]50 <form action="[% c.uri_for(poll.uid, 'ballot') %]" method="POST">51 [% l('Add a choice') %]<br>52 <input type="text" name="addch">53 <input type="submit" value="[% l('Add') %]">54 </form>55 </div>56 57 <div style="float: right; width: 30%" class="ballot">58 <p>[% l('Preview of ballot') %]</p>59 [% INCLUDE 'includes/ballot_form.tt' b_form_url = c.uri_for(poll.uid, 'ballot') %]60 </div>61 62 <div style="clear: both"></div> -
trunk/root/templates/includes/poll_results.tt
r315 r319 18 18 19 19 <table border="1"> 20 <tr><td>[% l('Participation') %]</td><td>[% poll.signing_count %]</td><td>[% poll.signing_count / poll.voting_count * 100 | format('%.2f %%') IF poll.voting_count %]</td></tr> 21 <tr><td>[% l('Ballot Number') %]</td><td>[% poll.ballot_count %]</td><td></td></tr> 22 <tr><td>[% l('Number of empty ballot') %]</td><td>[% poll.empty_ballot_count %]</td><td>[% poll.empty_ballot_count / poll.ballot_count * 100 | format('%.2f %%') IF poll.ballot_count %]</td></tr> 23 <tr><td>[% l('Number of nul ballot') %]</td><td>[% poll.invalid_ballot_count %]</td><td>[% poll.invalid_ballot_count / poll.ballot_count * 100 | format('%.2f %%') IF poll.ballot_count %]</td></tr> 24 <tr><td>[% l('Number of voices') %]</td><td>[% poll.voices_ballot_count %]</td><td>[% poll.voices_ballot_count / poll.ballot_count * 100 | format('%.2f %%') IF poll.ballot_count %]</td></tr> 20 <tr> 21 <td>[% l('Participation') %]</td> 22 <td>[% poll.signing_count %]</td> 23 <td>[% poll.signing_count / poll.voting_count * 100 | format('%.2f %%') IF poll.voting_count %]</td> 24 </tr> 25 <tr> 26 <td>[% l('Ballots count') %]</td> 27 <td>[% poll.ballots_count %]</td> 28 <td></td></tr> 29 <tr> 30 <td>[% l('Number of empty ballot') %]</td> 31 <td>[% poll.empty_ballot_count %]</td> 32 <td>[% poll.empty_ballot_count / poll.ballot_count * 100 | format('%.2f %%') IF poll.ballot_count %]</td> 33 </tr> 34 <tr> 35 <td>[% l('Number of nul ballot') %]</td> 36 <td>[% poll.invalid_ballot_count %]</td> 37 <td>[% poll.invalid_ballot_count / poll.ballots_count * 100 | format('%.2f %%') IF poll.ballots_count %]</td> 38 </tr> 25 39 </table> 26 40 27 [% IF poll.ballot_count_nonull %] 28 [% FOREACH res = poll.results %] 29 [% IF loop.first %] 30 <p>[% l('Score:') %]</p> 31 <table border="1"><tr> 32 <th>[% l('Legend:') %]</th> 33 <td class="majabs">[% l('Absolute Majority') %]</td> 34 <td class="selected">[% l('Elected') %]</td> 35 <td class="notselected">l('Not elected') %]</td> 36 </tr></table><br> 37 <table border="1"> 38 <tr><th>Score</th><th>[% l('Line n°') %]</th><th>[% l('choice') %]</th><th>[% 39 l('Number of voice') %]</th><th>[% l('%') %]</th><th></th></tr> 40 [% END %] 41 42 [% IF res.elected %] 43 [% IF res.abs_maj %] 44 [% class = 'majabs' %] 45 [% ELSE %] 46 [% class = 'selected' %] 47 [% END %] 48 [% ELSE %] 49 [% class = 'notselected' %] 50 [% END %] 51 <tr class="[% class %]"> 52 <td>[% res.order %]</td> 53 <td>[% loop.count %]</td> 54 <td>[% res.value | html %]</td> 55 <td>[% res.count %]</td> 56 <td>[% res.count * 100 / poll.ballot_count_nonull | format('%.2f') %]</td> 57 <td><img src="[% c.uri_for('/static', 'images', 'green-v.png') %]" 58 height="10px" width="[% res.count * 400 / poll.ballot_count_nonull | format('%d') %]px"></td> 59 </tr> 60 61 [% IF loop.last %] 62 </table> 63 [% END %] 64 [% END %] 65 [% ELSE %] 66 <p class="alert">[% l('No results') %]</p> 67 [% END %] 68 </div> 41 [% resultstt = 'pollinc/' _ poll.type _ '/results.tt' %] 42 [% INCLUDE $resultstt %] 69 43 70 44 [% FOREACH id = poll.ballot_keys %] -
trunk/root/templates/pollinc/binary/ballot.tt
r315 r319 2 2 [% poll = c.model('Vote').poll(voteid) %] 3 3 4 [% IF poll.info('procedure') %]5 [% poll.info('procedure') | html %]6 <hr>7 [% ELSIF poll.info('description') %]8 [% poll.info('description') | html %]9 <hr>10 [% END %]11 12 <form action="[% b_form_url %]" method="POST">13 4 <p>Vous devez faire [% poll.info('choice_count') %] choix 14 5 [%- IF poll.info('choice_count') != poll.info('elected_count') -%] … … 43 34 [% END %] 44 35 45 46 36 [% count = 0 %] 47 37 [% WHILE count < poll.info('free_choice') %] … … 52 42 [% count = count + 1 %] 53 43 [% END %] 54 <br>55 <input type="submit" name="ballot" value="[% l('Vote') _ ' ' %] >>">56 </form>57 <hr>58 <form action="[% b_form_url %]" method="POST">59 <input type="submit" name="ballot" value="[% l('Empty ballot') _ ' ' %] >>">60 </form> -
trunk/root/templates/pollinc/binary/ballot_settings.tt
r315 r319 1 1 <!-- $Id$ --> 2 [% INCLUDE 'includes/admin_menu.tt' %]3 4 2 [% poll = c.model('Vote').poll(voteid) %] 5 3 6 <div style="float: left; width: 55%" class="box">7 <form action="[% c.uri_for(poll.uid, 'ballot') %]" method="POST">8 4 <table border=1> 9 5 <tr> … … 30 26 31 27 </table> 32 <input type="submit" name="pollballot" value="[% l('save') %]">33 </form>34 35 <hr>36 37 [% IF ! poll.choices_keys.size %]38 <p class="alert">[% l('No choice are configured') %]</p>39 [% ELSE %]40 [% FOREACH choicek = poll.choices_keys %]41 [% choice = poll.choice(choicek) %]42 <form action="[% c.uri_for(poll.uid, 'ballot') %]" method="POST">43 [% loop.count %] - [% choice.info.label | html %]44 <input type="hidden" name="delch" value="[% choicek %]">45 <input type="submit" name="del" value="[% l('delete') %]">46 </form>47 <br>48 [% END %]49 [% END %]50 <form action="[% c.uri_for(poll.uid, 'ballot') %]" method="POST">51 [% l('Add a choice') %]<br>52 <input type="text" name="addch">53 <input type="submit" value="[% l('Add') %]">54 </form>55 </div>56 57 <div style="float: right; width: 30%" class="ballot">58 <p>[% l('Preview of ballot') %]</p>59 [% INCLUDE 'includes/ballot_form.tt' b_form_url = c.uri_for(poll.uid, 'ballot') %]60 </div>61 62 <div style="clear: both"></div> -
trunk/root/templates/pollinc/binary/results.tt
r315 r319 1 1 <!-- $Id$ --> 2 [% poll = c.model('Vote'). results(voteid) %]2 [% poll = c.model('Vote').poll(voteid) %] 3 3 4 [% IF poll.can_show_result %] 5 6 <div id="results" class="box"> 7 <div style="float: right"> 8 <p><a href="[% c.uri_for('/vote', poll.uid, 'results.pdf') %]">Résultat en PDF</a></p> 9 <p><a href="[% c.uri_for('/vote', poll.uid, 'report.pdf') %]">Rapport en PDF</a></p> 10 </div> 11 [% IF poll.list_ballot_needvalid.size %] 12 <p>[% l('Temporary results') %]</p> 13 <p class="alert">[% l('Poll administrator must validate some ballot') %]</p> 14 [% ELSE %] 15 <p>[% l('Results:') %]</p> 16 [% END %] 17 <p>[% l('Number of choice to retain:') _ ' ' %][% poll.info('choice_count') %]</p> 18 19 <table border="1"> 20 <tr><td>[% l('Participation') %]</td><td>[% poll.signing_count %]</td><td>[% poll.signing_count / poll.voting_count * 100 | format('%.2f %%') IF poll.voting_count %]</td></tr> 21 <tr><td>[% l('Ballot Number') %]</td><td>[% poll.ballot_count %]</td><td></td></tr> 22 <tr><td>[% l('Number of empty ballot') %]</td><td>[% poll.empty_ballot_count %]</td><td>[% poll.empty_ballot_count / poll.ballot_count * 100 | format('%.2f %%') IF poll.ballot_count %]</td></tr> 23 <tr><td>[% l('Number of nul ballot') %]</td><td>[% poll.invalid_ballot_count %]</td><td>[% poll.invalid_ballot_count / poll.ballot_count * 100 | format('%.2f %%') IF poll.ballot_count %]</td></tr> 24 <tr><td>[% l('Number of voices') %]</td><td>[% poll.voices_ballot_count %]</td><td>[% poll.voices_ballot_count / poll.ballot_count * 100 | format('%.2f %%') IF poll.ballot_count %]</td></tr> 25 </table> 26 27 [% IF poll.ballot_count_nonull %] 4 [% IF poll.results %] 28 5 [% FOREACH res = poll.results %] 29 6 [% IF loop.first %] … … 33 10 <td class="majabs">[% l('Absolute Majority') %]</td> 34 11 <td class="selected">[% l('Elected') %]</td> 35 <td class="notselected"> l('Not elected') %]</td>12 <td class="notselected">[% l('Not elected') %]</td> 36 13 </tr></table><br> 37 14 <table border="1"> … … 54 31 <td>[% res.value | html %]</td> 55 32 <td>[% res.count %]</td> 56 <td>[% res.count * 100 / poll.ballot_count_nonull | format('%.2f') %]</td> 57 <td><img src="[% c.uri_for('/static', 'images', 'green-v.png') %]" 58 height="10px" width="[% res.count * 400 / poll.ballot_count_nonull | format('%d') %]px"></td> 33 <td>[% res.count * 100 / poll.voices_ballot_count | format('%.2f') %]</td> 34 <td><img src="[% c.uri_for('/static', 'images', 'green-v.png') %]" height="10px" width="[% res.count * 400 / poll.voices_ballot_count | format('%d') %]px"></td> 59 35 </tr> 60 36 … … 68 44 </div> 69 45 70 [% FOREACH id = poll.ballot_keys %]71 [% IF loop.first %]72 <div id="ballot_list" class="box">73 <p>[% l('Ballot list:') %]</p>74 <table border="1">75 <tr><th>[% l('number') %]</th><th>[% l('Id') %]</th>76 <th>[% l('date (=> view as)') | html %]77 [% IF poll.info('free_choice') %]78 <br>(*: [% l('not from list') %])79 [% END %]80 </th><th>[% l('comment') %]</th></tr>81 [% END %]82 <tr>83 <td>[% loop.count %]</td>84 <td><pre>[% id | html %]</pre></td>85 <td>86 [% items = poll.ballot(id).items %]87 [% IF items.size %]88 [% FOREACH item = items %]89 [% "<ul>\n" IF loop.first %]90 <li>[% item.v | html %]91 [% ' *' IF NOT item.fromlist %]92 [% IF item.corrected %] (=> [% item.corrected %])[% END %]</li>93 [% "</ul>\n" IF loop.last %]94 [% END %]95 [% ELSE %]96 <i>Vote blanc</i>97 [% END %]98 </td>99 <td>100 [% invalid = '#' _ poll.ballot(id).info.invalid %]101 [% IF invalid == '#1' %]102 <span class="alert">[% l('invalided') %]</span>103 [% ELSIF invalid == '#' %]104 <i>[% l('must be validated') %]</i>105 [% END %]106 </td>107 </tr>108 [% IF loop.last %]109 </table>110 </div>111 [% END %]112 [% END %]113 114 [% ELSE %][% # can show result %]115 <div class="page_box">116 <p>[% l('Results are not yet published') %]<p>117 </div>118 [% END %] -
trunk/t/10Epoll_DB.t
r309 r319 25 25 my ($r) = @_; 26 26 is($r->absolute_majority, 1, "Can get absolute_majority"); 27 is($r->ballot _count, 0, "can get ballot count");27 is($r->ballots_count, 0, "can get ballot count"); 28 28 is($r->voting_count, 0, "can get voting count"); 29 29 is($r->signing_count, 0, "can get signing count"); … … 44 44 my ($r) = @_; 45 45 is($r->absolute_majority, 2, "Can get absolute_majority"); 46 is($r->ballot _count, 4, "can get ballot count");47 is($r-> ballot_count_nonull, 3, "can get ballot count");46 is($r->ballots_count, 4, "can get ballot count"); 47 is($r->_voices_ballot_count, 3, "can get ballot count"); 48 48 is($r->voting_count, 6, "can get voting count"); 49 49 is($r->signing_count, 4, "can get signing count"); … … 63 63 f => {}, 64 64 }, 65 map_values => sub { 66 my ($r) = @_; 67 $r->map_value('ch10', 'ch1'); 68 }, 65 69 test_count => 14, 66 70 tests => sub { 67 71 my ($r) = @_; 68 $r->map_value('ch10', 'ch1');69 72 is($r->absolute_majority, 2, "Can get absolute_majority"); 70 is($r->ballot _count, 4, "can get ballot count");73 is($r->ballots_count, 4, "can get ballot count"); 71 74 is($r->not_empty_ballot_count, 3, "can get ballot count"); 72 75 is($r->empty_ballot_count, 1, "can get empty ballot count"); … … 102 105 my ($r) = @_; 103 106 is($r->absolute_majority, 3, "Can get absolute_majority"); 104 is($r->ballot _count, 5, "can get ballot count");107 is($r->ballots_count, 5, "can get ballot count"); 105 108 is($r->not_empty_ballot_count, 3, "can get ballot count"); 106 109 is($r->empty_ballot_count, 2, "can get empty ballot count"); … … 121 124 plan tests => 122 125 3 # Fixed test 123 + scalar(@$test_polls) * 7# number of tested polls scenario124 + $poll_test_count * 2; # poll test126 + scalar(@$test_polls) * 8 # number of tested polls scenario 127 + $poll_test_count; # poll test 125 128 126 129 use_ok 'Epoll', 'Epoll'; … … 160 163 ); 161 164 } 165 166 if ($tpoll->{map_values}) { 167 $tpoll->{map_values}->($poll); 168 } 162 169 163 170 isa_ok(my $results = $vote->results($pollid), 'Epoll::DB::Poll'); 164 171 165 $tpoll->{tests}->($results); 166 167 ok($results->delete_ballots, "Can switch to static results"); 172 ok($results->decrypted_ballots(), "Can decrypt ballot"); 173 ok($results->compute_results(), "Can compute results"); 168 174 169 175 $tpoll->{tests}->($results); -
trunk/t/15ImportV.t
r315 r319 1 1 use strict; 2 2 use warnings; 3 use Test::More tests => 1;3 use Test::More tests => 2; 4 4 5 5 use_ok('Epoll::DB::ImportV'); … … 8 8 "Can instanciate dummy import"); 9 9 10 warn $import->auth_type;11 warn $import->can_authenticate;12 13 10 $import->{params}{foo} = 1; 14 11 $import->{params}{bar} = 1; 15 12 16 warn $import->xml_params;17 $import->load_xml_params($import->xml_params);18 $import->load_xml_params($import->xml_params);19 20 warn join ' ', keys %{$import->{params}}; -
trunk/t/20Epoll_Web.t
r309 r319 36 36 "Request /admin/$pollid/ballot should succeed" ); 37 37 38 ok( request("/ ballot/$pollid")->is_success, "Request /admin/$pollid should succeed" );38 ok( request("/admin/$pollid?vpass$pollid=password")->is_success, "Request /admin/$pollid should succeed" ); 39 39 ok( request("/ballot/$pollid?mail=user@;password=$votingpass")->is_success, 40 "Request / admin/$pollid should succeed" );40 "Request /ballot/$pollid should succeed" ); 41 41 42 42 # Be sure today is included: … … 56 56 "Request /admin/$pollid/ballot should succeed" ); 57 57 58 ok( request("/ballot/$pollid")->is_success, "Request / admin/$pollid should succeed" );59 ok( request("/ballot/$vote_uid")->is_success, "Request / admin/$vote_uid should succeed" );58 ok( request("/ballot/$pollid")->is_success, "Request /ballot/$pollid should succeed" ); 59 ok( request("/ballot/$vote_uid")->is_success, "Request /ballot/$vote_uid should succeed" ); 60 60 ok( request("/ballot/$pollid?mail=user@;password=$votingpass")->is_success, 61 "Request / admin/$pollid should succeed" );61 "Request /ballot/$pollid should succeed" ); 62 62 63 63
Note: See TracChangeset
for help on using the changeset viewer.