package Voting::Utils; use strict; use warnings; require Exporter; require Mail::Send; use Digest::MD5 qw(md5_hex); use Data::Dumper; use Voting::DBI; our @ISA = qw(Exporter); our @EXPORT_OK = qw(retrieveCandidates check_id_in_list); push @EXPORT_OK, qw(check_email_in_list); push @EXPORT_OK, qw(insert_voter_result); push @EXPORT_OK, qw(get_candidate_name_by_id); push @EXPORT_OK, qw(get_voted_candidates); push @EXPORT_OK, qw(get_vote_code_for_email); push @EXPORT_OK, qw(check_vote_code_for_email); push @EXPORT_OK, qw(check_email_sent_time_ok); push @EXPORT_OK, qw(update_email_request); push @EXPORT_OK, qw(send_vote_code_to_email); my $secret = 'this_is_for_demo_only_please_do_not_hack'; my $max_wait_time = 60; # 60 seconds my $base_url = "http://www.yuonlamp.com/voting/vote.html?code="; my $reply_to = 'yuonlamp@yahoo.com'; my $subject = 'Code for voting on our mailing list'; sub insert_voter_result { my ($args) = (@_); # $args->{email}, $args->{'candidate'} # if we find that the email address already exists, then we need to delete old voting results first # for this email address and then insert new one my @results; my $email; my $id; $email = $args->{email}; @results = Voting::Voters->search(email => $email); if (@results) { # Update voter's information my $need_update = 0; if ($args->{name}) { $results[0]->name($args->{name}); $need_update = 1; } if ($args->{comment}) { $results[0]->notes($args->{comment}); $need_update = 1; } if ($need_update) { $results[0]->update; } $id = $results[0]->id; # Now search and delete all prior votes from this email Voting::VoteResults->search(voter_id => $id)->delete_all; # Now insert the voting results if (!ref($args->{candidate})) { # just a scalar Voting::VoteResults->insert({ voter_id => $id, candidate_id => $args->{candidate}, }); } else { foreach my $cid (@{$args->{candidate}}) { Voting::VoteResults->insert({ voter_id => $id, candidate_id => $cid, }); } } # Now update the vote_tracking table if ($args->{'ip'}) { my $t = time; Voting::VoteTracking->insert({ voter_id => $id, vote_time => $t, vote_ip => $args->{'ip'}, }); } return 1; } return 0; } # Get all information for the candidates sub retrieveCandidates { my @candidates; my @results; @candidates = Voting::Candidates->retrieve_all; foreach my $c (@candidates) { my $rec; $rec->{id} = $c->id; $rec->{name} = $c->name; $rec->{email} = $c->email; push @results, $rec; } return \@results; } sub check_id_in_list { my ($id, $list) = (@_); if (!$id or !$list) { return 0; } if (ref($list) eq 'ARRAY') { foreach my $l (@$list) { if ($l eq $id) { return 1; } } return 0; } if ($id eq $list) { return 1; } return 0; } sub check_email_in_list { my ($email) = (@_); my @results; @results = Voting::Voters->search(email => $email); if (@results) { return 1; } return 0; } sub get_candidate_name_by_id { my ($id) = (@_); my @results; @results = Voting::Candidates->search(id => $id); if (@results) { return $results[0]->name; } return ""; } # Given reference to a hash # $args->{candidate} can be a scalar or reference to a list # return reference to a list of voted candidates sub get_voted_candidates { my ($args) = (@_); my $list; my @names; @names = (); $list = $args->{candidate}; if (ref($list) eq 'ARRAY') { foreach my $id (@$list) { my $name; $name = get_candidate_name_by_id($id); if ($name) { push @names, $name; } } } else { my $name; $name = get_candidate_name_by_id($list); if ($name) { push @names, $name; } } return @names; } sub get_vote_code_for_email { my ($email) = (@_); my $code; $code = md5_hex($email . $secret); $code = substr($code, 0, 6); return $code; } sub check_vote_code_for_email { my ($code, $email) = (@_); my $expected; $expected = md5_hex($email . $secret); $expected = substr($expected, 0, 6); if ($expected eq $code) { return 1; } return 0; } sub get_voter_id_by_email { my ($email) = (@_); my @results; my $id = 0; @results = Voting::Voters->search(email => $email); if (@results) { $id = $results[0]->id; } return $id; } sub update_email_request { my ($args) = (@_); my $id; my $t; $t = time; $id = get_voter_id_by_email($args->{'email'}); if ($id) { Voting::VoteRequest->insert({ voter_id => $id, request_time => $t, request_ip => $args->{'ip'}, }); return 1; } return 0; } sub check_email_sent_time_ok { my ($email) = (@_); # First need to get the ID from email # Search vote_request table to see if the email has been sent before my @results; my $id; my $latest_time = 0; $id = get_voter_id_by_email($email); if ($id) { @results = Voting::VoteRequest->search(voter_id => $id); if (@results) { foreach my $result (@results) { if ($result->request_time > $latest_time) { $latest_time = $result->request_time; } } if ( (time - $latest_time) < $max_wait_time) { return 0; } } return 1; } return 0; } sub send_vote_code_to_email { my ($args) = (@_); my $status; my $body; my $code; my $msg; my $fh; # First we need to check the last time the email was sent $status = check_email_sent_time_ok($args->{'email'}); if ($status) { # $msg = Mail::Send->new(Subject => $subject, To => $args->{'email'}); $msg->add('Reply-To', $reply_to); $code = get_vote_code_for_email($args->{'email'}); $fh = $msg->open('sendmail'); $base_url .= $code; #$body = "Please vote with this link: $base_url\n"; $body = "Please vote with this link: $base_url\n"; print $fh $body; close $fh; update_email_request($args); return 1; } return 0; } 1;