Changeset 160
- Timestamp:
- 04/05/09 22:54:18 (15 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/MANIFEST
r159 r160 24 24 lib/Vote/DB.pm 25 25 lib/Vote/DB/common.pm 26 lib/Vote/DB/Poll.pm 27 lib/Vote/DB/Voting.pm 28 lib/Vote/DB/Ballot.pm 26 29 lib/Vote/Model/Vote.pm 27 30 lib/Vote/Template/Plugin/Mail.pm -
trunk/lib/Vote/DB.pm
r159 r160 8 8 use Mail::Mailer; 9 9 use base 'Vote::DB::common'; 10 use Vote::DB::Poll; 11 use Vote::DB::Ballot; # see ballot() 10 12 11 13 =head1 NAME … … 48 50 } 49 51 50 51 52 sub list_running_vote { 52 53 my ($self) = @_; … … 86 87 } 87 88 89 sub poll { 90 my ($self, $pollid) = @_; 91 Vote::DB::Poll->new($self->{dbstring}, $pollid); 92 } 93 94 sub ballot { 95 my ($self, $ballotid) = @_; 96 # TODO must die, ballot are attached to a poll 97 Vote::DB::Ballot->new($self->{dbstring}, $ballotid); 98 } 99 88 100 sub vote_param { 89 101 my ($self, $voteid, %attr) = @_; 90 91 keys %attr or return; 92 my @online_f = qw(label start end owner password); 93 94 if (grep { exists($attr{$_}) } @online_f) { 95 my $sth = $self->db->prepare_cached( 96 q{update poll set } . 97 join(',', map { qq("$_" = ?) } grep { exists $attr{$_} } @online_f) . 98 q{ where id = ?} 99 ); 100 $sth->execute((map { $attr{$_} } grep { exists $attr{$_} } @online_f), $voteid) 101 or do { 102 $self->db->rollback; 103 return; 104 }; 105 } 106 107 # vote settings in settings table 108 foreach my $var (keys %attr) { 109 grep { $var eq $_ } @online_f and next; 110 $self->vote_set_settings($voteid, $var, $attr{$var}); 111 } 112 1 102 warn "# vote_param"; 103 $self->poll($voteid)->param(%attr); 113 104 } 114 105 115 106 sub vote_status { 116 107 my ($self, $id) = @_; 117 118 my $sth = $self->db->prepare_cached( 119 q{ 120 select (start > now() or start is null) as before, 121 "end" < now() as after 122 from poll 123 where id = ? 124 } 125 ); 126 $sth->execute($id); 127 my $res = $sth->fetchrow_hashref; 128 $sth->finish; 129 $res or return; 130 if ($res->{before}) { 131 return 'BEFORE'; 132 } elsif ($res->{after}) { 133 return 'AFTER'; 134 } else { 135 return 'RUNNING'; 136 } 108 warn "# vote_status"; 109 $self->poll($id)->status; 137 110 } 138 111 139 112 sub vote_info { 140 113 my ($self, $id) = @_; 141 142 my $sth = $self->db->prepare_cached( 143 q{ 144 select *, 145 to_char("start", 'DD/MM/YYYY') as dstart, 146 to_char("start", 'HH24:MI:SS') as hstart, 147 to_char("end", 'DD/MM/YYYY') as dend, 148 to_char("end", 'HH24:MI:SS') as hend 149 from poll where id = ? 150 } 151 ); 152 153 $sth->execute($id); 154 my $res = $sth->fetchrow_hashref; 155 $sth->finish; 156 if ($res) { 157 my $get = $self->db->prepare_cached( 158 q{select var, val from settings where poll = ?} 159 ); 160 $get->execute($id); 161 while (my $set = $get->fetchrow_hashref) { 162 $res->{$set->{var}} = $set->{val}; 163 } 164 } 165 $res->{free_choice} ||= 0; # avoiding undef 166 $res 114 $self->poll($id)->info; 167 115 } 168 116 169 117 sub vote_set_settings { 170 118 my ($self, $poll, $var, $val) = @_; 171 172 my $upd = $self->db->prepare_cached( 173 q{update settings set val = ? where poll = ? and var = ?} 174 ); 175 176 if ($upd->execute($val, $poll, $var) == 0) { 177 my $add = $self->db->prepare_cached( 178 q{insert into settings (poll, var, val) values (?,?,?)} 179 ); 180 181 $add->execute($poll, $var, $val); 182 } 119 $self->poll($poll)->set_settings($var, $val); 183 120 } 184 121 185 122 sub vote_signing { 186 123 my ($self, $id) = @_; 187 188 my $sth = $self->db->prepare_cached( 189 q{ 190 select *, voting.key as vkey from voting left join signing 191 on signing.key = voting.key 192 where poll = ? order by voting.mail 193 } 194 ); 195 $sth->execute($id); 196 my @people; 197 while (my $res = $sth->fetchrow_hashref) { 198 push(@people, $res); 199 } 200 @people 124 $self->poll($id)->signing; 201 125 } 202 126 203 127 sub vote_voting { 204 128 my ($self, $voteid) = @_; 205 206 my $sth = $self->db->prepare_cached( 207 q{ 208 select key from voting 209 where poll = ? order by voting.mail 210 } 211 ); 212 $sth->execute($voteid); 213 my @people; 214 while (my $res = $sth->fetchrow_hashref) { 215 push(@people, $res->{key}); 216 } 217 @people 129 $self->poll($voteid)->voting; 218 130 } 219 131 220 132 sub voting_info { 221 133 my ($self, $id) = @_; 222 223 my $sth = $self->db->prepare_cached( 224 q{ 225 select *, voting.key as vkey from voting left join signing 226 on signing.key = voting.key 227 where voting.key = ? 228 } 229 ); 230 $sth->execute($id); 231 232 my $res = $sth->fetchrow_hashref; 233 $sth->finish; 234 $res 134 $self->poll($id)->voting_info; 235 135 } 236 136 237 137 sub vote_choices { 238 138 my ($self, $id) = @_; 239 240 my $sth = $self->db->prepare_cached( 241 q{ 242 select key from choice where poll = ? 243 order by label 244 } 245 ); 246 $sth->execute($id); 247 my @ch; 248 while (my $res = $sth->fetchrow_hashref) { 249 push(@ch, $res->{key}); 250 } 251 @ch 252 } 139 $self->poll($id)->choices; 140 } 141 142 sub vote_add_choice { 143 my ($self, $voteid, $label) = @_; 144 $self->poll($voteid)->add_choice($label); 145 } 146 147 # Choice sub class ?? 253 148 254 149 sub choice_info { … … 263 158 } 264 159 265 sub vote_add_choice {266 my ($self, $voteid, $label) = @_;267 268 my $sth = $self->db->prepare_cached(269 q{insert into choice (poll, label) values (?,?)}270 );271 272 $sth->execute($voteid, $label) or do {273 $self->db->rollback;274 return;275 };276 277 1278 }279 280 160 sub modify_choice { 281 161 my ($self, $chid, $label) = @_; … … 299 179 sub voting_info_id { 300 180 my ($self, $mail, $voteid) = @_; 301 302 my $sth = $self->db->prepare_cached( 303 q{ 304 select * from voting where mail = ? and poll = ? 305 } 306 ); 307 $sth->execute($mail, $voteid); 308 my $res = $sth->fetchrow_hashref(); 309 $sth->finish; 310 $res 311 } 312 313 sub _register_signing { 314 my ($self, $mail, $voteid, $referal) = @_; 315 316 my $vinfo = $self->voting_info_id($mail, $voteid) or return; 317 318 my $sth = $self->db->prepare_cached( 319 q{ 320 insert into signing (key, referal) values (?,?) 321 } 322 ); 323 $sth->execute($vinfo->{key}, $referal) or do { 324 $self->db->rollback; 325 return; 326 }; 327 328 1; 329 } 330 331 sub gen_uid { 332 unpack("H*", join("", map { chr(rand(256)) } (0..15))) 333 } 334 335 sub _register_ballot { 336 my ($self, $voteid, $choice, $fchoice) = @_; 337 338 my $addb = $self->db->prepare_cached( 339 q{ 340 insert into ballot (id, poll, invalid) values (?,?,?) 341 } 342 ); 343 my $uid = gen_uid; 344 $addb->execute($uid, $voteid, scalar(@{$fchoice || []}) ? undef : 'f') or do { 345 self->db->rollback; 346 return; 347 }; 348 349 my $addbc = $self->db->prepare_cached( 350 q{ 351 insert into ballot_item (id, value, fromlist) values (?,?,?) 352 } 353 ); 354 foreach (@{ $choice || []}) { 355 $addbc->execute($uid, $_, 't') or do { 356 $self->db->rollback; 357 return; 358 }; 359 } 360 foreach (@{ $fchoice || []}) { 361 $_ or next; 362 $addbc->execute($uid, $_, 'f') or do { 363 $self->db->rollback; 364 return; 365 }; 366 } 367 368 $uid; 181 $self->poll($voteid)->voting_from_mail($mail)->info; 369 182 } 370 183 371 184 sub register_ballot { 372 185 my ($self, $vid, $voteid, $choice, $fchoice, $referal) = @_; 373 374 my $uid; 375 for (0..2) { # 3 try 376 # First we register voting has voted 377 $self->_register_signing($vid, $voteid, $referal) or return; # TODO error ? 378 379 # registring choices 380 $uid = $self->_register_ballot($voteid, $choice, $fchoice); 381 defined($uid) and last; 382 383 } 384 # everything went fine, saving! 385 $self->db->commit; 386 387 388 $uid 186 $self->poll($voteid)->register_ballot($vid, $choice, $fchoice, $referal); 389 187 } 390 188 391 189 sub mail_ballot_confirm { 392 190 my ($self, $vid, $voteid, $info) = @_; 393 my $voteinfo = $self->vote_info($voteid) or return; 394 $info->{ballotid} or return; 395 my $mailer = new Mail::Mailer 'smtp', Server => (Vote->config->{smtp} || 'localhost'); 396 $ENV{MAILADDRESS} = $vid; 397 $mailer->open({ 398 From => $vid, # TODO allow to configure this 399 To => $vid, 400 Subject => 'Confirmation de vote: ' . $voteinfo->{label}, 401 mail_header(), 402 }); 403 print $mailer <<EOF; 404 405 Vous venez de participer au vote: 406 407 -------- 408 $voteinfo->{label} 409 -------- 410 411 Votre bulletin est idéntifié sous le numéro: 412 $info->{ballotid} 413 414 Les résultats seront disponibles à cet url: 415 $info->{url} 416 417 Cordialement. 418 EOF 419 $mailer->close 420 or warn "couldn't send whole message: $!\n"; 421 191 $self->poll($voteid)->mail_ballot_confirm($vid, $info); 422 192 } 423 193 424 194 sub vote_voting_count { 425 195 my ($self, $id) = @_; 426 427 my $sth = $self->db->prepare_cached( 428 q{ 429 select count(*) from voting 430 where poll = ? 431 } 432 ); 433 $sth->execute($id); 434 my $res = $sth->fetchrow_hashref; 435 $sth->finish; 436 $res->{count} 196 $self->poll($id)->voting_count; 437 197 } 438 198 … … 441 201 sub vote_signing_count { 442 202 my ($self, $voteid) = @_; 443 444 my $sth = $self->db->prepare_cached( 445 q{ 446 select count(*) from signing join voting 447 on voting.key = signing.key where poll = ? 448 } 449 ); 450 451 $sth->execute($voteid); 452 my $res = $sth->fetchrow_hashref; 453 $sth->finish; 454 $res->{count} 203 $self->poll($voteid)->signing_count; 455 204 } 456 205 … … 459 208 sub vote_ballot_count { 460 209 my ($self, $voteid) = @_; 461 462 my $sth = $self->db->prepare_cached( 463 q{ 464 select count(*) from ballot where poll = ? 465 } 466 ); 467 468 $sth->execute($voteid); 469 my $res = $sth->fetchrow_hashref; 470 $sth->finish; 471 $res->{count} 210 $self->poll($voteid)->ballot_count; 472 211 } 473 212 … … 476 215 sub vote_ballot_count_nonull { 477 216 my ($self, $voteid) = @_; 478 479 my $sth = $self->db->prepare_cached( 480 q{ 481 select count(*) from ballot where poll = ? 482 and id in (select id from ballot_item) and 483 (invalid = 'false' or invalid is null) 484 } 485 ); 486 487 $sth->execute($voteid); 488 my $res = $sth->fetchrow_hashref; 489 $sth->finish; 490 $res->{count} 217 $self->poll($voteid)->ballot_count_nonull; 491 218 } 492 219 493 220 sub auth_voting { 494 221 my ($self, $poll, $mail, $password) = @_; 495 my $userinfo = $self->voting_info_id($mail, $poll) or return; 496 497 $userinfo->{passwd} or return; 498 if (crypt($password, $userinfo->{passwd} || '') eq $userinfo->{passwd}) { 499 return 1; 500 } else { 501 return 0; 502 } 222 $self->poll($poll)->auth_voting($mail, $password); 503 223 } 504 224 505 225 sub auth_poll { 506 226 my ($self, $voteid, $passwd) = @_; 507 508 my $vinfo = $self->vote_info($voteid) or return; 509 510 $vinfo->{password} or return; 511 $passwd or return; 512 if (crypt($passwd, $vinfo->{password} || '') eq $vinfo->{password}) { 513 return 1; 514 } else { 515 return 0; 516 } 227 $self->poll($voteid)->auth_poll($passwd); 517 228 } 518 229 519 230 sub voting_has_sign { 520 231 my ($self, $poll, $user) = @_; 521 522 my $sth = $self->db->prepare_cached( 523 q{ 524 select date from signing join voting 525 on voting.key = signing.key 526 where poll = ? and mail = ? 527 } 528 ); 529 530 $sth->execute($poll, $user); 531 my $res = $sth->fetchrow_hashref; 532 $sth->finish; 533 return $res->{date} 232 $self->poll($poll)->voting_has_sign($user); 534 233 } 535 234 … … 538 237 sub vote_results_count { 539 238 my ($self, $voteid) = @_; 540 541 my $sth = $self->db->prepare( 542 q{ 543 select count(ballot.id), value from 544 (select ballot.id, coalesce(corrected, value) as "value" from ballot left join ballot_item 545 on ballot.id = ballot_item.id where ballot.poll = ? and (invalid = 'false'or invalid is null) 546 group by ballot.id, coalesce(corrected, value)) as ballot 547 group by value 548 order by count desc, value 549 } 550 ); 551 $sth->execute($voteid); 552 my @results; 553 while (my $res = $sth->fetchrow_hashref) { 554 push(@results, $res); 555 } 556 @results; 239 $self->poll($voteid)->results_count; 557 240 } 558 241 559 242 sub vote_results_nonull { 560 243 my ($self, $voteid) = @_; 561 562 my $sth = $self->db->prepare( 563 q{ 564 select count(ballot.id), value from 565 (select ballot.id, coalesce(corrected, value) as "value" from ballot join ballot_item 566 on ballot.id = ballot_item.id where ballot.poll = ? and (invalid = 'false'or invalid is null) 567 group by ballot.id, coalesce(corrected, value)) as ballot 568 group by value 569 order by count desc, value 570 } 571 ); 572 $sth->execute($voteid); 573 my @results; 574 while (my $res = $sth->fetchrow_hashref) { 575 push(@results, $res); 576 } 577 \@results; 244 $self->poll($voteid)->results_nonull; 578 245 } 579 246 580 247 sub list_vote_ballot { 581 248 my ($self, $voteid) = @_; 582 583 my $sth = $self->db->prepare_cached( 584 q{ 585 select id from ballot where poll = ? 586 order by id 587 } 588 ); 589 $sth->execute($voteid); 590 my @ids; 591 while (my $res = $sth->fetchrow_hashref) { 592 push(@ids, $res->{id}); 593 } 594 @ids 249 $self->poll($voteid)->list_ballot; 595 250 } 596 251 597 252 sub list_vote_ballot_needvalid { 598 253 my ($self, $voteid) = @_; 599 600 my $sth = $self->db->prepare_cached( 601 q{ 602 select id from ballot where poll = ? 603 and invalid is null order by id 604 } 605 ); 606 $sth->execute($voteid); 607 my @ids; 608 while (my $res = $sth->fetchrow_hashref) { 609 push(@ids, $res->{id}); 610 } 611 @ids 254 $self->poll->list_ballot_needvalid; 612 255 } 613 256 614 257 sub ballot_info { 615 258 my ($self, $ballotid) = @_; 616 617 my $sth = $self->db->prepare_cached( 618 q{ select * from ballot where id = ? } 619 ); 620 621 $sth->execute($ballotid); 622 my $res = $sth->fetchrow_hashref; 623 $sth->finish; 624 $res 259 $self->ballot($ballotid)->info; 625 260 } 626 261 627 262 sub mark_ballot_invalid { 628 263 my ($self, $ballotid, $invalid) = @_; 629 630 my $sth = $self->db->prepare_cached( 631 q{update ballot set invalid = ? where id = ?} 632 ); 633 634 $sth->execute($invalid ? 't' : 'f', $ballotid); 264 $self->ballot($ballotid)->mark_invalid($invalid); 635 265 } 636 266 637 267 sub ballot_items { 638 268 my ($self, $ballotid) = @_; 639 640 my $sth = $self->db->prepare_cached( 641 q{select *, value as v from ballot_item where id = ?} 642 ); 643 $sth->execute($ballotid); 644 my @ids; 645 while (my $res = $sth->fetchrow_hashref) { 646 push(@ids, $res); 647 } 648 \@ids 269 $self->ballot($ballotid)->items; 649 270 } 650 271 651 272 sub vote_ballot_untrusted_values { 652 273 my ($self, $voteid) = @_; 653 654 my $getval = $self->db->prepare_cached( 655 q{ 656 select value from ballot join ballot_item 657 on ballot.id = ballot_item.id 658 where poll = ? and fromlist = false and corrected is null 659 group by value order by value 660 } 661 ); 662 $getval->execute($voteid); 663 my @vals; 664 while (my $res = $getval->fetchrow_hashref) { 665 push(@vals, $res->{value}); 666 } 667 @vals 274 $self->poll($voteid)->ballot_untrusted_values; 668 275 } 669 276 670 277 sub vote_ballot_values { 671 278 my ($self, $voteid) = @_; 672 673 my $getval = $self->db->prepare_cached( 674 q{ 675 select coalesce(corrected, value) as value from ballot join ballot_item 676 on ballot.id = ballot_item.id 677 where poll = ? 678 group by coalesce(corrected, value) order by coalesce(corrected, value) 679 } 680 ); 681 $getval->execute($voteid); 682 my @vals; 683 while (my $res = $getval->fetchrow_hashref) { 684 push(@vals, $res->{value}); 685 } 686 @vals 279 $self->poll($voteid)->ballot_values; 687 280 } 688 281 689 282 sub vote_map_value { 690 283 my ($self, $voteid, $from, $to) = @_; 691 692 my $sth = $self->db->prepare_cached( 693 q{ 694 update ballot_item set corrected = ? where 695 id in (select id from ballot where poll = ?) 696 and (value = ? or corrected = ?) 697 } 698 ); 699 700 $sth->execute($to, $voteid, $from, $from) or $self->db->rollback; 701 $self->db->commit; 284 $self->poll($voteid)->map_value($from, $to); 702 285 } 703 286 704 287 sub addupd_voting { 705 288 my ($self, $voteid, $mail, $id) = @_; 706 707 $mail =~ s/\s*$//; 708 $mail =~ s/^\s*//; 709 $mail = lc($mail); 710 $id =~ s/\s*$//; 711 $id =~ s/^\s//; 712 my $upd = $self->db->prepare_cached( 713 q{ 714 update voting set label = ? where mail = ? and poll = ? 715 } 716 ); 717 718 if ($upd->execute($id || '', $mail, $voteid) == 0) { 719 my $add = $self->db->prepare_cached(q{ 720 insert into voting (poll, label, mail) values (?,?,?) 721 }); 722 723 $add->execute($voteid, $id || '', $mail); 724 } 289 $self->poll($voteid)->addupd_voting($mail, $id); 725 290 } 726 291 … … 738 303 sub voting_from_file { 739 304 my ($self, $voteid, $fh, $delete) = @_; 740 741 if ($delete) { 742 my $sth = $self->db->prepare(q{delete from voting where poll = ?}); 743 $sth->execute($voteid); 744 } 745 746 while (my $line = <$fh>) { 747 chomp($line); 748 my ($mail, $name) = split(';', $line); 749 $mail or do { 750 $self->db->rollback; 751 return; 752 }; 753 $self->addupd_voting($voteid, $mail, $name || ''); 754 } 755 1; 305 $self->poll($voteid)->voting_from_file($fh, $delete); 756 306 } 757 307 758 308 sub mail_passwd_ifnul { 759 309 my ($self, $voteid, $mailinfo) = @_; 760 761 my $list_voting = $self->db->prepare_cached( 762 q{select key from voting where poll = ? and passwd is null or passwd = ''} 763 ); 764 765 $list_voting->execute($voteid); 766 while (my $res = $list_voting->fetchrow_hashref) { 767 $self->mail_voting_passwd($res->{key}, $mailinfo); 768 } 769 } 770 771 sub mail_voting_passwd { 772 my ($self, $id, $mailinfo) = @_; 773 774 my $vinfo = $self->voting_info($id) or return; 775 my $voteinfo = $self->vote_info($vinfo->{poll}); 776 $voteinfo->{description} ||= ""; 777 778 my $passwd = random_string(8); 779 my $encpasswd = $self->gen_enc_passwd($passwd); 780 781 my $upd_voting = $self->db->prepare_cached( 782 q{update voting set passwd = ? where key = ?} 783 ); 784 785 $upd_voting->execute($encpasswd, $id); 786 787 my $date = $voteinfo->{dstart} && $voteinfo->{dend} 788 ? sprintf("\n" . 'Vous pourrez voter entre le %s %s et le %s %s' . "\n", 789 $voteinfo->{dstart}, $voteinfo->{hstart}, $voteinfo->{dend}, $voteinfo->{hend}) 790 : ''; 791 792 # TODO complete this properly: 793 my $mailer = new Mail::Mailer 'smtp', Server => (Vote->config->{smtp} || 'localhost'); 794 $ENV{MAILADDRESS} = $voteinfo->{owner}; 795 $mailer->open({ 796 From => $voteinfo->{owner}, 797 To => $vinfo->{mail}, 798 Subject => 'Invitation a voter: ' . $voteinfo->{label}, 799 'X-Epoll-poll' => $id, 800 mail_header(), 801 }); 802 print $mailer <<EOF; 803 Vous êtes convié à participer a ce vote: 804 805 -------- 806 $voteinfo->{label} 807 -------- 808 $voteinfo->{description} 809 -------- 810 811 à l'adresse: 812 813 $mailinfo->{voteurl} 814 $date 815 816 -- 817 Votre identifiant est: $vinfo->{mail} 818 Votre mot de passe est: $passwd 819 820 Conservez précieusement ces identifiants, il ne vous seront pas retransmits. 821 822 Cordialement. 823 EOF 824 $mailer->close or warn "couldn't send whole message: $!\n"; 825 826 $self->db->commit; 310 $self->poll($voteid)->mail_passwd_ifnul($mailinfo); 827 311 } 828 312 … … 881 365 ); 882 366 883 my $reqid = gen_uid;367 my $reqid = Vote::DB::common::gen_uid(); 884 368 885 369 $addreq->execute($reqid, $info{label}, $info{mail}); … … 890 374 To => $info{mail}, 891 375 Subject => 'Votre nouveau vote', 892 mail_header(),376 Vote::DB::common::mail_header(), 893 377 }); 894 378 print $mailer <<EOF; -
trunk/lib/Vote/DB/common.pm
r159 r160 7 7 use Vote; 8 8 use DBI; 9 use vars qw(@EXPORT); 10 use base 'Exporter'; 11 @EXPORT = qw(gen_uid); 9 12 10 13 =head1 NAME … … 20 23 sub _newdb { 21 24 my ($dbstring) = @_; 22 my $db = DBI->connect (25 my $db = DBI->connect_cached( 23 26 'dbi:Pg:' . $dbstring, 24 27 undef, undef, … … 74 77 } 75 78 79 sub gen_uid { 80 unpack("H*", join("", map { chr(rand(256)) } (0..15))) 81 } 82 76 83 =head1 AUTHOR 77 84
Note: See TracChangeset
for help on using the changeset viewer.