source: trunk/lib/Vote/Model/Vote.pm @ 38

Last change on this file since 38 was 38, checked in by nanardon, 15 years ago
  • more html improvement
File size: 16.9 KB
Line 
1package Vote::Model::Vote;
2
3use strict;
4use warnings;
5use base 'Catalyst::Model';
6use Vote;
7use DBI;
8use Mail::Mailer;
9
10=head1 NAME
11
12Vote::Model::Vote - Catalyst Model
13
14=head1 DESCRIPTION
15
16Catalyst Model.
17
18=cut
19
20sub new {
21    my ($class) = @_;
22    my $db = DBI->connect(
23        'dbi:Pg:' . Vote->config->{db},
24        undef, undef,
25        {
26            RaiseError => 0,
27            AutoCommit => 0,
28            PrintWarn => 0,
29            PrintError => 1,
30        }
31    ) or return;
32   
33    bless {
34        db => $db,
35    }, $class;
36}
37
38sub db { $_[0]->{db} }
39
40sub random_string {
41    my $lenght = $_[-1] || 8;
42
43    return join('', map { ('a'..'z', 'A'..'Z', 0..9)[rand 62] } (1..$lenght));
44}
45
46sub gen_enc_passwd {
47    my ($self, $passwd) = @_;
48
49    $passwd ||= random_string(8);
50    return(crypt($passwd, '$1$' . random_string(8) . '$'));
51}
52
53sub list_comming_vote {
54    my ($self) = @_;
55
56    my $sth = $self->db->prepare_cached(
57        q{
58        select id from poll where
59        (start > now() and "end" > now()) or
60        "end" is null or start is null
61        }
62    );
63
64    $sth->execute;
65    my @id;
66    while(my $res = $sth->fetchrow_hashref) {
67        push(@id, $res->{id});
68    }
69
70    @id
71}
72
73
74sub list_running_vote {
75    my ($self) = @_;
76
77    my $sth = $self->db->prepare_cached(
78        q{
79        select id from poll where start < now() and "end" > now()
80        }
81    );
82
83    $sth->execute;
84    my @id;
85    while(my $res = $sth->fetchrow_hashref) {
86        push(@id, $res->{id});
87    }
88
89    @id
90}
91
92sub list_closed_vote {
93    my ($self) = @_;
94
95    my $sth = $self->db->prepare_cached(
96        q{
97        select id from poll where
98        start < now() and "end" < now()
99        }
100    );
101
102    $sth->execute;
103    my @id;
104    while(my $res = $sth->fetchrow_hashref) {
105        push(@id, $res->{id});
106    }
107
108    @id
109}
110
111sub vote_param {
112    my ($self, $voteid, %attr) = @_;
113
114    keys %attr or return;
115    my @online_f = qw(label start end owner password);
116
117    if (grep { exists($attr{$_}) } @online_f) {
118        my $sth = $self->db->prepare_cached(
119            q{update poll set } .
120            join(',', map { qq("$_" = ?) } grep { exists $attr{$_} } @online_f) .
121            q{ where id = ?}
122        );
123        $sth->execute((map { $attr{$_} } grep { exists $attr{$_} } @online_f), $voteid)
124            or do {
125            $self->db->rollback;
126            return;
127        };
128    }
129
130    # vote settings in settings table
131    foreach my $var (keys %attr) {
132        grep { $var eq $_ } @online_f and next;
133        $self->vote_set_settings($voteid, $var, $attr{$var});
134    }
135    1
136}
137
138sub vote_status {
139    my ($self, $id) = @_;
140   
141    my $sth = $self->db->prepare_cached(
142        q{
143        select (start > now() or start is null) as before,
144               "end" < now() as after
145        from poll
146        where id = ?
147        }
148    );
149    $sth->execute($id);
150    my $res = $sth->fetchrow_hashref;
151    $sth->finish;
152    $res or return;
153    if ($res->{before}) {
154        return 'BEFORE';
155    } elsif ($res->{after}) {
156        return 'AFTER';
157    } else {
158        return 'RUNNING';
159    }
160}
161
162sub vote_info {
163    my ($self, $id) = @_;
164
165    my $sth = $self->db->prepare_cached(
166        q{
167        select * from poll where id = ?
168        }
169    );
170
171    $sth->execute($id);
172    my $res = $sth->fetchrow_hashref;
173    $sth->finish;
174    if ($res) {
175        my $get = $self->db->prepare_cached(
176            q{select var, val from settings where poll = ?}
177        );
178        $get->execute($id);
179        while (my $set = $get->fetchrow_hashref) {
180            $res->{$set->{var}} = $set->{val};
181        }
182    }
183    $res
184}
185
186sub vote_set_settings {
187    my ($self, $poll, $var, $val) = @_;
188
189    my $upd = $self->db->prepare_cached(
190        q{update settings set val = ? where poll = ? and var = ?}
191    );
192
193    if ($upd->execute($val, $poll, $var) == 0) {
194        my $add = $self->db->prepare_cached(
195            q{insert into settings (poll, var, val) values (?,?,?)}
196        );
197
198        $add->execute($poll, $var, $val);
199    }
200}
201
202sub vote_signing {
203    my ($self, $id) = @_;
204
205    my $sth = $self->db->prepare_cached(
206        q{
207        select *, voting.key as vkey from voting left join signing
208        on signing.key = voting.key
209        where poll = ? order by voting.mail
210        }
211    );
212    $sth->execute($id);
213    my @people;
214    while (my $res = $sth->fetchrow_hashref) {
215        push(@people, $res);
216    }
217    @people
218}
219
220sub vote_voting {
221    my ($self, $voteid) = @_;
222
223    my $sth = $self->db->prepare_cached(
224        q{
225        select key from voting
226        where poll = ? order by voting.mail
227        }
228    );
229    $sth->execute($voteid);
230    my @people;
231    while (my $res = $sth->fetchrow_hashref) {
232        push(@people, $res->{key});
233    }
234    @people
235}
236
237sub voting_info {
238    my ($self, $id) = @_;
239
240    my $sth = $self->db->prepare_cached(
241        q{
242        select *, voting.key as vkey from voting left join signing
243        on signing.key = voting.key
244        where voting.key = ?
245        }
246    );
247    $sth->execute($id);
248
249    my $res = $sth->fetchrow_hashref;
250    $sth->finish;
251    $res
252}
253
254sub vote_choices {
255    my ($self, $id) = @_;
256
257    my $sth = $self->db->prepare_cached(
258        q{
259        select key from choice where poll = ?
260        order by label
261        }
262    );
263    $sth->execute($id);
264    my @ch;
265    while (my $res = $sth->fetchrow_hashref) {
266        push(@ch, $res->{key});
267    }
268    @ch
269}
270
271sub choice_info {
272    my ($self, $chid) = @_;
273    my $sth = $self->db->prepare_cached(
274        q{select * from choice where key = ?}
275    );
276    $sth->execute($chid);
277    my $res = $sth->fetchrow_hashref;
278    $sth->finish;
279    $res
280}
281
282sub vote_add_choice {
283    my ($self, $voteid, $label) = @_;
284
285    my $sth = $self->db->prepare_cached(
286        q{insert into choice (poll, label) values (?,?)}
287    );
288
289    $sth->execute($voteid, $label) or do {
290        $self->db->rollback;
291        return;
292    };
293
294    1
295}
296
297sub modify_choice {
298    my ($self, $chid, $label) = @_;
299
300    my $sth = $self->db->prepare_cached(
301        q{update choice set label = ? where key = ?}
302    );
303    $sth->execute($label, $chid);
304}
305
306sub delete_choice {
307    my ($self, $chid) = @_;
308
309    my $sth = $self->db->prepare_cached(
310        q{delete from choice where key = ?}
311    );
312
313    $sth->execute($chid);
314}
315
316sub voting_info_id {
317    my ($self, $mail, $voteid) = @_;
318
319    my $sth = $self->db->prepare_cached(
320        q{
321        select * from voting where mail = ? and poll = ?
322        }
323    );
324    $sth->execute($mail, $voteid);
325    my $res = $sth->fetchrow_hashref();
326    $sth->finish;
327    $res
328}
329
330sub _register_signing {
331    my ($self, $mail, $voteid, $referal) = @_;
332
333    my $vinfo = $self->voting_info_id($mail, $voteid) or return;
334
335    my $sth = $self->db->prepare_cached(
336        q{
337        insert into signing (key, referal) values (?,?)
338        }
339    );
340    $sth->execute($vinfo->{key}, $referal) or do {
341        $self->db->rollback;
342        return;
343    };
344
345    1;
346}
347
348sub gen_uid {
349    unpack("H*", join("", map { chr(rand(256)) } (0..15)))
350}
351
352sub _register_ballot {
353    my ($self, $voteid, $choice, $fchoice) = @_;
354
355    my $addb = $self->db->prepare_cached(
356        q{
357        insert into ballot (id, poll, invalid) values (?,?,?)
358        }
359    );
360    my $uid = gen_uid;
361    $addb->execute($uid, $voteid, scalar(@{$fchoice || []}) ? undef : 'f') or do {
362        self->db->rollback;
363        return;
364    };
365
366    my $addbc = $self->db->prepare_cached(
367        q{
368        insert into ballot_item (id, value, fromlist) values (?,?,?)
369        }
370    );
371    foreach (@{ $choice || []}) {
372        $addbc->execute($uid, $_, 't') or do {
373            $self->db->rollback;
374            return;
375        };
376    }
377    foreach (@{ $fchoice || []}) {
378        $addbc->execute($uid, $_, 'f') or do {
379            $self->db->rollback;
380            return;
381        };
382    }
383
384    $uid;
385}
386
387sub register_ballot {
388    my ($self, $vid, $voteid, $choice, $fchoice, $referal) = @_;
389
390    # First we register voting has voted
391    $self->_register_signing($vid, $voteid, $referal) or return; # TODO error ?
392
393    # registring choices
394    my $uid = $self->_register_ballot($voteid, $choice, $fchoice) or return;
395
396    # everything went fine, saving!
397    $self->db->commit;
398
399    $uid
400}
401
402sub vote_voting_count {
403    my ($self, $id) = @_;
404
405    my $sth = $self->db->prepare_cached(
406        q{
407        select count(*) from voting
408        where poll = ?
409        }
410    );
411    $sth->execute($id);
412    my $res = $sth->fetchrow_hashref;
413    $sth->finish;
414    $res->{count}
415}
416
417sub signing_count { vote_signing_count(@_) }
418
419sub vote_signing_count {
420    my ($self, $voteid) = @_;
421
422    my $sth = $self->db->prepare_cached(
423        q{
424        select count(*) from signing join voting
425        on voting.key = signing.key where poll = ?
426        }
427    );
428
429    $sth->execute($voteid);
430    my $res = $sth->fetchrow_hashref;
431    $sth->finish;
432    $res->{count}
433}
434
435sub ballot_count { vote_ballot_count(@_) }
436
437sub vote_ballot_count {
438    my ($self, $voteid) = @_;
439
440    my $sth = $self->db->prepare_cached(
441        q{
442        select count(*) from ballot where poll = ?
443        }
444    );
445
446    $sth->execute($voteid);
447    my $res = $sth->fetchrow_hashref;
448    $sth->finish;
449    $res->{count}
450}
451
452sub ballot_count_nonull { vote_ballot_count_nonull(@_) }
453
454sub vote_ballot_count_nonull {
455    my ($self, $voteid) = @_;
456
457    my $sth = $self->db->prepare_cached(
458        q{
459        select count(*) from ballot where poll = ?
460        and id in (select id from ballot_item) and invalid = 'false'
461        }
462    );
463
464    $sth->execute($voteid);
465    my $res = $sth->fetchrow_hashref;
466    $sth->finish;
467    $res->{count}
468}
469
470sub auth_voting {
471    my ($self, $poll, $mail, $password) = @_;
472    my $userinfo = $self->voting_info_id($mail, $poll) or return;
473
474    $userinfo->{passwd} or return;
475    if (crypt($password, $userinfo->{passwd} || '') eq $userinfo->{passwd}) {
476        return 1;
477    } else {
478        return 0;
479    }
480}
481
482sub auth_poll {
483    my ($self, $voteid, $passwd) = @_;
484
485    my $vinfo = $self->vote_info($voteid) or return;
486
487    $vinfo->{password} or return;
488    warn $vinfo->{password};
489    if (crypt($passwd, $vinfo->{password} || '') eq $vinfo->{password}) {
490        return 1;
491    } else {
492        return 0;
493    }
494}
495
496sub voting_has_sign {
497    my ($self, $poll, $user) = @_;
498
499    my $sth = $self->db->prepare_cached(
500        q{
501        select date from signing join voting
502        on voting.key = signing.key
503        where poll = ? and mail = ?
504        }
505    );
506
507    $sth->execute($poll, $user);
508    my $res = $sth->fetchrow_hashref;
509    $sth->finish;
510    return $res->{date}
511}
512
513# Requete de decompte des voix:
514
515sub vote_results_count {
516    my ($self, $voteid) = @_;
517
518    my $sth = $self->db->prepare(
519        q{
520        select count(ballot.id), value from ballot left join ballot_item
521        on ballot.id = ballot_item.id where ballot.poll = ? and invalid = 'false'
522        group by value
523        order by count
524        }
525    );
526    $sth->execute($voteid);
527    my @results;
528    while (my $res = $sth->fetchrow_hashref) {
529        push(@results, $res);
530    }
531    @results;
532}
533
534sub vote_results_nonull {
535    my ($self, $voteid) = @_;
536
537    my $sth = $self->db->prepare(
538        q{
539        select count(ballot.id), value from ballot join ballot_item
540        on ballot.id = ballot_item.id where ballot.poll = ? and invalid = 'false'
541        group by value
542        order by count desc
543        }
544    );
545    $sth->execute($voteid);
546    my @results;
547    while (my $res = $sth->fetchrow_hashref) {
548        push(@results, $res);
549    }
550    \@results;
551}
552
553sub list_vote_ballot {
554    my ($self, $voteid) = @_;
555
556    my $sth = $self->db->prepare_cached(
557        q{
558        select id from ballot where poll = ?
559        order by id
560        }
561    );
562    $sth->execute($voteid);
563    my @ids;
564    while (my $res = $sth->fetchrow_hashref) {
565        push(@ids, $res->{id});
566    }
567    @ids
568}
569
570sub list_vote_ballot_needvalid {
571    my ($self, $voteid) = @_;
572
573    my $sth = $self->db->prepare_cached(
574        q{
575        select id from ballot where poll = ?
576        and invalid is null order by id
577        }
578    );
579    $sth->execute($voteid);
580    my @ids;
581    while (my $res = $sth->fetchrow_hashref) {
582        push(@ids, $res->{id});
583    }
584    @ids
585}
586
587sub ballot_info {
588    my ($self, $ballotid) = @_;
589
590    my $sth = $self->db->prepare_cached(
591        q{ select * from ballot where id = ? }
592    );
593
594    $sth->execute($ballotid);
595    my $res = $sth->fetchrow_hashref;
596    $sth->finish;
597    $res
598}
599
600sub mark_ballot_invalid {
601    my ($self, $ballotid, $invalid) = @_;
602
603    my $sth = $self->db->prepare_cached(
604        q{update ballot set invalid = ? where id = ?}
605    );
606
607    $sth->execute($invalid ? 't' : 'f', $ballotid);
608}
609
610sub ballot_items {
611    my ($self, $ballotid) = @_;
612
613    my $sth = $self->db->prepare_cached(
614        q{select *, value as v from ballot_item where id = ?}
615    );
616    $sth->execute($ballotid);
617    my @ids;
618    while (my $res = $sth->fetchrow_hashref) {
619        push(@ids, $res);
620    }
621    \@ids
622}
623
624sub addupd_voting {
625    my ($self, $voteid, $mail, $id) = @_;
626
627    my $upd = $self->db->prepare_cached(
628        q{
629        update voting set label = ? where mail = ? and poll = ?
630        }
631    );
632
633    if ($upd->execute($mail, $voteid, $id) == 0) {
634        my $add = $self->db->prepare_cached(q{
635            insert into voting (poll, label, mail) values (?,?,?)
636        });
637
638        $add->execute($voteid, $id, $mail);
639    }
640}
641
642sub delete_voting {
643    my ($self, $key) = @_;
644
645    my $sth = $self->db->prepare_cached(
646        q{delete from voting where key = ?}
647    );
648
649    $sth->execute($key);
650}
651
652sub voting_from_file {
653    my ($self, $voteid, $fh, $delete) = @_;
654
655    if ($delete) {
656        my $sth = $self->db->prepare(q{delete from voting where poll = ?});
657        $sth->execute($voteid);
658    }
659
660    while (my $line = <$fh>) {
661        chomp($line);
662        warn $line;
663        my ($id, $mail) = split(';', $line);
664        $id && $mail or do {
665            $self->db->rollback;
666            return;
667        };
668        $self->addupd_voting($voteid, $id, $mail);
669    }
670    1;
671}
672
673sub mail_passwd_ifnul {
674    my ($self, $voteid, $mailinfo) = @_;
675
676    my $list_voting = $self->db->prepare_cached(
677        q{select key from voting where poll = ? and passwd is null or passwd = ''}
678    );
679
680    $list_voting->execute($voteid);
681    while (my $res = $list_voting->fetchrow_hashref) {
682        $self->mail_voting_passwd($res->{key}, $mailinfo);
683    }
684}
685
686sub mail_voting_passwd {
687    my ($self, $id, $mailinfo) = @_;
688   
689    my $vinfo = $self->voting_info($id) or return;
690    my $voteinfo = $self->vote_info($vinfo->{poll});
691
692    my $passwd = random_string(8);
693    my $encpasswd = $self->gen_enc_passwd($passwd);
694
695    my $upd_voting = $self->db->prepare_cached(
696        q{update voting set passwd = ? where key = ?}
697    );
698
699    $upd_voting->execute($encpasswd, $id);
700
701    # TODO complete this properly:
702    my $mailer = new Mail::Mailer 'smtp', Server => 'mailhost';
703    $mailer->open({
704        From => 'Voting system <nomail@nomail.com>',
705        To => $vinfo->{mail},
706        Subject => 'Vote passwd',
707    });
708    print $mailer <<EOF;
709Vous êtes convié à voter:
710$voteinfo->{label}
711
712Votre identifiant est: $vinfo->{mail}
713Votre mot de passe est: $passwd
714
715Cordialement.
716EOF
717    $mailer->close;
718
719    $self->db->commit;
720}
721
722sub poll_request_info {
723    my ($self, $rid) = @_;
724
725    my $sth = $self->db->prepare_cached(
726        q{select * from poll_request where id = ?}
727    );
728
729    $sth->execute($rid);
730    my $res = $sth->fetchrow_hashref;
731    $sth->finish;
732    $res
733}
734
735sub poll_from_request {
736    my ($self, $rid, $passwd) = @_;
737    my $rinfo = $self->poll_request_info($rid) or return;
738
739    my $encpasswd = $self->gen_enc_passwd($passwd);
740
741    my $getpollid = $self->db->prepare_cached(
742        q{select nextval('poll_id_seq')}
743    );
744    $getpollid->execute();
745    my $newpollid = $getpollid->fetchrow_hashref->{nextval};
746   
747    my $newpoll = $self->db->prepare_cached(
748        q{insert into poll (id, label, owner, password) values (?,?,?,?)}
749    );
750
751    $newpoll->execute($newpollid, $rinfo->{label}, $rinfo->{mail}, $encpasswd);
752    # set some default
753    $self->vote_param($newpollid,
754        free_choice => 0,
755        choice_count => 1,
756    );     
757
758    my $delreq = $self->db->prepare_cached(
759        q{delete from poll_request where id = ?}
760    );
761
762    $delreq->execute($rid);
763    $self->db->commit;
764
765    $newpollid
766}
767
768sub create_poll_request {
769    my ($self, %info) = @_;
770
771    $info{mail} or return;
772    my $addreq = $self->db->prepare_cached(
773        q{insert into poll_request (id, label, mail) values (?,?,?)}
774    );
775
776    my $reqid = gen_uid;
777
778    $addreq->execute($reqid, $info{label}, $info{mail});
779    my $mailer = new Mail::Mailer 'smtp', Server => 'mailhost';
780    $mailer->open({
781        From => 'Voting system <nomail@nomail.com>',
782        To => $info{mail},
783        Subject => 'Votre nouveau vote',
784    });
785    print $mailer <<EOF;
786
787Vous avez demandez la création d'un nouveau vote:
788$info{label}
789
790Pour valider votre demande, veuiller allez visitez la page:
791$info{url}/$reqid
792
793A bientot
794EOF
795    $mailer->close;
796    $self->db->commit;
797    1;
798}
799
800=head1 AUTHOR
801
802Thauvin Olivier
803
804=head1 LICENSE
805
806This library is free software, you can redistribute it and/or modify
807it under the same terms as Perl itself.
808
809=cut
810
8111;
Note: See TracBrowser for help on using the repository browser.