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

Last change on this file since 28 was 28, checked in by nanardon, 15 years ago
  • add: send mail to voting people
File size: 14.3 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    my $sth = $self->db->prepare_cached(
118        q{update poll set } .
119        join(',', map { qq("$_" = ?) } grep { exists $attr{$_} } @online_f) .
120        q{ where id = ?}
121    );
122    $sth->execute((map { $attr{$_} } grep { exists $attr{$_} } @online_f), $voteid)
123        or $self->db->rollback;
124
125    # vote settings in settings table
126    foreach my $var (keys %attr) {
127        grep { $var eq $_ } @online_f and next;
128        $self->vote_set_settings($voteid, $var, $attr{$var});
129    }
130    1
131}
132
133sub vote_status {
134    my ($self, $id) = @_;
135   
136    my $sth = $self->db->prepare_cached(
137        q{
138        select start > now() as before,
139               "end" < now() as after
140        from poll
141        where id = ?
142        }
143    );
144    $sth->execute($id);
145    my $res = $sth->fetchrow_hashref;
146    $sth->finish;
147    $res or return;
148    if ($res->{before}) {
149        return 'BEFORE';
150    } elsif ($res->{after}) {
151        return 'AFTER';
152    } else {
153        return 'RUNNING';
154    }
155}
156
157sub vote_info {
158    my ($self, $id) = @_;
159
160    my $sth = $self->db->prepare_cached(
161        q{
162        select * from poll where id = ?
163        }
164    );
165
166    $sth->execute($id);
167    my $res = $sth->fetchrow_hashref;
168    $sth->finish;
169    if ($res) {
170        my $get = $self->db->prepare_cached(
171            q{select var, val from settings where poll = ?}
172        );
173        $get->execute($id);
174        while (my $set = $get->fetchrow_hashref) {
175            $res->{$set->{var}} = $set->{val};
176        }
177    }
178    $res
179}
180
181sub vote_set_settings {
182    my ($self, $poll, $var, $val) = @_;
183
184    my $upd = $self->db->prepare_cached(
185        q{update settings set val = ? where poll = ? and var = ?}
186    );
187
188    if ($upd->execute($val, $poll, $var) == 0) {
189        my $add = $self->db->prepare_cached(
190            q{insert into settings (poll, var, val) values (?,?,?)}
191        );
192
193        $add->execute($poll, $var, $val);
194    }
195}
196
197sub vote_signing {
198    my ($self, $id) = @_;
199
200    my $sth = $self->db->prepare_cached(
201        q{
202        select *, voting.key as vkey from voting left join signing
203        on signing.key = voting.key
204        where poll = ? order by voting.id
205        }
206    );
207    $sth->execute($id);
208    my @people;
209    while (my $res = $sth->fetchrow_hashref) {
210        push(@people, $res);
211    }
212    @people
213}
214
215sub vote_voting {
216    my ($self, $id) = @_;
217
218    my $sth = $self->db->prepare_cached(
219        q{
220        select key from voting
221        where poll = ? order by voting.id
222        }
223    );
224    $sth->execute($id);
225    my @people;
226    while (my $res = $sth->fetchrow_hashref) {
227        push(@people, $res->{key});
228    }
229    @people
230}
231
232sub voting_info {
233    my ($self, $id) = @_;
234
235    my $sth = $self->db->prepare_cached(
236        q{
237        select *, voting.key as vkey from voting left join signing
238        on signing.key = voting.key
239        where voting.key = ?
240        }
241    );
242    $sth->execute($id);
243   
244    my $res = $sth->fetchrow_hashref;
245    $sth->finish;
246    $res
247}
248
249sub vote_signing_count {
250    my ($self, $id) = @_;
251
252    my $sth = $self->db->prepare_cached(
253        q{
254        select count(*) from voting
255        where poll = ?
256        }
257    );
258    $sth->execute($id);
259    my $res = $sth->fetchrow_hashref;
260    $sth->finish;
261    $res->{count}
262}
263
264sub vote_choices {
265    my ($self, $id) = @_;
266
267    my $sth = $self->db->prepare_cached(
268        q{
269        select key from choice where poll = ?
270        order by label
271        }
272    );
273    $sth->execute($id);
274    my @ch;
275    while (my $res = $sth->fetchrow_hashref) {
276        push(@ch, $res->{key});
277    }
278    @ch
279}
280
281sub choice_info {
282    my ($self, $chid) = @_;
283    my $sth = $self->db->prepare_cached(
284        q{select * from choice where key = ?}
285    );
286    $sth->execute($chid);
287    my $res = $sth->fetchrow_hashref;
288    $sth->finish;
289    $res
290}
291
292sub vote_add_choice {
293    my ($self, $voteid, $label) = @_;
294
295    my $sth = $self->db->prepare_cached(
296        q{insert into choice (poll, label) values (?,?)}
297    );
298
299    $sth->execute($voteid, $label) or do {
300        $self->db->rollback;
301        return;
302    };
303
304    1
305}
306
307sub modify_choice {
308    my ($self, $chid, $label) = @_;
309
310    my $sth = $self->db->prepare_cached(
311        q{update choice set label = ? where key = ?}
312    );
313    $sth->execute($label, $chid);
314}
315
316sub delete_choice {
317    my ($self, $chid) = @_;
318
319    my $sth = $self->db->prepare_cached(
320        q{delete from choice where key = ?}
321    );
322
323    $sth->execute($chid);
324}
325
326sub voting_info_id {
327    my ($self, $id, $voteid) = @_;
328
329    my $sth = $self->db->prepare_cached(
330        q{
331        select * from voting where id = ? and poll = ?
332        }
333    );
334    $sth->execute($id, $voteid);
335    my $res = $sth->fetchrow_hashref();
336    $sth->finish;
337    $res
338}
339
340sub _register_signing {
341    my ($self, $vid, $voteid, $referal) = @_;
342
343    my $vinfo = $self->voting_info_id($vid, $voteid) or return;
344
345    my $sth = $self->db->prepare_cached(
346        q{
347        insert into signing (key, referal) values (?,?)
348        }
349    );
350    $sth->execute($vinfo->{key}, $referal) or do {
351        $self->db->rollback;
352        return;
353    };
354
355    1;
356}
357
358sub gen_uid {
359    unpack("H*", join("", map { chr(rand(256)) } (0..15)))
360}
361
362sub _register_ballot {
363    my ($self, $voteid, $choice, $fchoice) = @_;
364
365    my $addb = $self->db->prepare_cached(
366        q{
367        insert into ballot (id, poll, invalid) values (?,?,?)
368        }
369    );
370    my $uid = gen_uid;
371    $addb->execute($uid, $voteid, scalar(@{$fchoice || []}) ? undef : 'f') or do {
372        self->db->rollback;
373        return;
374    };
375
376    my $addbc = $self->db->prepare_cached(
377        q{
378        insert into ballot_item (id, value, fromlist) values (?,?,?)
379        }
380    );
381    foreach (@{ $choice || []}) {
382        $addbc->execute($uid, $_, 't') or do {
383            $self->db->rollback;
384            return;
385        };
386    }
387    foreach (@{ $fchoice || []}) {
388        $addbc->execute($uid, $_, 'f') or do {
389            $self->db->rollback;
390            return;
391        };
392    }
393
394    $uid;
395}
396
397sub register_ballot {
398    my ($self, $vid, $voteid, $choice, $fchoice, $referal) = @_;
399
400    # First we register voting has voted
401    $self->_register_signing($vid, $voteid, $referal) or return; # TODO error ?
402
403    # registring choices
404    my $uid = $self->_register_ballot($voteid, $choice, $fchoice) or return;
405
406    # everything went fine, saving!
407    $self->db->commit;
408
409    $uid
410}
411
412sub signing_count {
413    my ($self, $voteid) = @_;
414
415    my $sth = $self->db->prepare_cached(
416        q{
417        select count(*) from signing join voting
418        on voting.key = signing.key where poll = ?
419        }
420    );
421
422    $sth->execute($voteid);
423    my $res = $sth->fetchrow_hashref;
424    $sth->finish;
425    $res->{count}
426}
427
428sub ballot_count {
429    my ($self, $voteid) = @_;
430
431    my $sth = $self->db->prepare_cached(
432        q{
433        select count(*) from ballot where poll = ?
434        }
435    );
436
437    $sth->execute($voteid);
438    my $res = $sth->fetchrow_hashref;
439    $sth->finish;
440    $res->{count}
441}
442
443sub ballot_count_nonull {
444    my ($self, $voteid) = @_;
445
446    my $sth = $self->db->prepare_cached(
447        q{
448        select count(*) from ballot where poll = ?
449        and id in (select id from ballot_item) and invalid = 'false'
450        }
451    );
452
453    $sth->execute($voteid);
454    my $res = $sth->fetchrow_hashref;
455    $sth->finish;
456    warn $res->{count};
457    $res->{count}
458}
459
460sub auth_voting {
461    my ($self, $poll, $user, $password) = @_;
462    my $userinfo = $self->voting_info_id($user, $poll) or return;
463
464    $userinfo->{passwd} or return;
465    if (crypt($password, $userinfo->{passwd} || '') eq $userinfo->{passwd}) {
466        return 1;
467    } else {
468        return 0;
469    }
470}
471
472sub voting_has_sign {
473    my ($self, $poll, $user) = @_;
474
475    my $sth = $self->db->prepare_cached(
476        q{
477        select date from signing join voting
478        on voting.key = signing.key
479        where poll = ? and id = ?
480        }
481    );
482
483    $sth->execute($poll, $user);
484    my $res = $sth->fetchrow_hashref;
485    $sth->finish;
486    return $res->{date}
487}
488
489# Requete de decompte des voix:
490
491sub vote_results_count {
492    my ($self, $voteid) = @_;
493
494    my $sth = $self->db->prepare(
495        q{
496        select count(ballot.id), value from ballot left join ballot_item
497        on ballot.id = ballot_item.id where ballot.poll = ? and invalid = 'false'
498        group by value
499        order by count
500        }
501    );
502    $sth->execute($voteid);
503    my @results;
504    while (my $res = $sth->fetchrow_hashref) {
505        push(@results, $res);
506    }
507    @results;
508}
509
510sub vote_results_nonull {
511    my ($self, $voteid) = @_;
512
513    my $sth = $self->db->prepare(
514        q{
515        select count(ballot.id), value from ballot join ballot_item
516        on ballot.id = ballot_item.id where ballot.poll = ? and invalid = 'false'
517        group by value
518        order by count desc
519        }
520    );
521    $sth->execute($voteid);
522    my @results;
523    while (my $res = $sth->fetchrow_hashref) {
524        push(@results, $res);
525    }
526    \@results;
527}
528
529sub list_vote_ballot {
530    my ($self, $voteid) = @_;
531
532    my $sth = $self->db->prepare_cached(
533        q{
534        select id from ballot where poll = ?
535        order by id
536        }
537    );
538    $sth->execute($voteid);
539    my @ids;
540    while (my $res = $sth->fetchrow_hashref) {
541        push(@ids, $res->{id});
542    }
543    @ids
544}
545
546sub list_vote_ballot_needvalid {
547    my ($self, $voteid) = @_;
548
549    my $sth = $self->db->prepare_cached(
550        q{
551        select id from ballot where poll = ?
552        and invalid is null order by id
553        }
554    );
555    $sth->execute($voteid);
556    my @ids;
557    while (my $res = $sth->fetchrow_hashref) {
558        push(@ids, $res->{id});
559    }
560    @ids
561}
562
563sub ballot_info {
564    my ($self, $ballotid) = @_;
565
566    my $sth = $self->db->prepare_cached(
567        q{ select * from ballot where id = ? }
568    );
569
570    $sth->execute($ballotid);
571    my $res = $sth->fetchrow_hashref;
572    $sth->finish;
573    $res
574}
575
576sub ballot_items {
577    my ($self, $ballotid) = @_;
578
579    my $sth = $self->db->prepare_cached(
580        q{select *, value as v from ballot_item where id = ?}
581    );
582    $sth->execute($ballotid);
583    my @ids;
584    while (my $res = $sth->fetchrow_hashref) {
585        push(@ids, $res);
586    }
587    @ids
588}
589
590sub addupd_voting {
591    my ($self, $voteid, $id, $mail) = @_;
592
593    my $upd = $self->db->prepare_cached(
594        q{
595        update voting set mail = ? where poll = ? and id = ?
596        }
597    );
598
599    if ($upd->execute($mail, $voteid, $id) == 0) {
600        my $add = $self->db->prepare_cached(q{
601            insert into voting (poll, id, mail) values (?,?,?)
602        });
603
604        $add->execute($voteid, $id, $mail);
605    }
606}
607
608sub delete_voting {
609    my ($self, $key) = @_;
610
611    my $sth = $self->db->prepare_cached(
612        q{delete from voting where key = ?}
613    );
614
615    $sth->execute($key);
616}
617
618sub voting_from_file {
619    my ($self, $voteid, $fh, $delete) = @_;
620
621    if ($delete) {
622        my $sth = $self->db->prepare(q{delete from voting where poll = ?});
623        $sth->execute($voteid);
624    }
625
626    while (my $line = <$fh>) {
627        chomp($line);
628        warn $line;
629        my ($id, $mail) = split(';', $line);
630        $id && $mail or do {
631            $self->db->rollback;
632            return;
633        };
634        $self->addupd_voting($voteid, $id, $mail);
635    }
636    1;
637}
638
639sub mail_passwd_ifnul {
640    my ($self, $voteid, $mailinfo) = @_;
641
642    my $list_voting = $self->db->prepare_cached(
643        q{select key from voting where poll = ? and passwd is null or passwd = ''}
644    );
645
646    $list_voting->execute($voteid);
647    while (my $res = $list_voting->fetchrow_hashref) {
648        $self->mail_voting_passwd($res->{key}, $mailinfo);
649    }
650}
651
652sub mail_voting_passwd {
653    my ($self, $id, $mailinfo) = @_;
654   
655    my $vinfo = $self->voting_info($id) or return;
656    my $voteinfo = $self->vote_info($vinfo->{poll});
657
658    my $passwd = random_string(8);
659    my $encpasswd = $self->gen_enc_passwd($passwd);
660
661    my $upd_voting = $self->db->prepare_cached(
662        q{update voting set passwd = ? where key = ?}
663    );
664
665    $upd_voting->execute($encpasswd, $id);
666
667    # TODO complete this properly:
668    my $mailer = new Mail::Mailer 'smtp', Server => 'mailhost';
669    $mailer->open({
670        From => 'Voting system <nomail@nomail.com>',
671        To => $vinfo->{mail},
672        Subject => 'Vote passwd',
673    });
674    print $mailer <<EOF;
675Vous êtes convié à voter:
676$voteinfo->{label}
677
678Votre identifiant est: $vinfo->{id}
679Votre mot de passe est: $passwd
680
681Cordialement.
682EOF
683    $mailer->close;
684
685    $self->db->commit;
686}
687
688=head1 AUTHOR
689
690Thauvin Olivier
691
692=head1 LICENSE
693
694This library is free software, you can redistribute it and/or modify
695it under the same terms as Perl itself.
696
697=cut
698
6991;
Note: See TracBrowser for help on using the repository browser.