aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin H. Johnson <robbat2@gentoo.org>2015-06-27 22:32:45 -0700
committerRobin H. Johnson <robbat2@gentoo.org>2015-06-27 22:33:35 -0700
commit274977d0840c8a1879946234c4d07575e8bde153 (patch)
treee5ade4c066051b55a7b69a8c51ae132d252eebdc /Votify.pm
parentStart some cleanup of Election code. (diff)
downloadelections-274977d0840c8a1879946234c4d07575e8bde153.tar.gz
elections-274977d0840c8a1879946234c4d07575e8bde153.tar.bz2
elections-274977d0840c8a1879946234c4d07575e8bde153.zip
Refactor elections, so we can have common fetching of which elections are open, and then consistently use the epoch timestamp inside the start/stop files.
Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>
Diffstat (limited to 'Votify.pm')
-rw-r--r--Votify.pm127
1 files changed, 114 insertions, 13 deletions
diff --git a/Votify.pm b/Votify.pm
index 1be8de7..289be2c 100644
--- a/Votify.pm
+++ b/Votify.pm
@@ -9,10 +9,14 @@
package Votify;
use POSIX;
+use Cwd qw(abs_path);
+use File::Spec::Functions;
use List::Util;
use strict;
-our ($datadir) = '/etc/elections/current';
+our $datefmt = '%Y-%m-%d %H:%M:%S UTC';
+
+our ($basedir) = List::Util::first { -d $_ } ('/etc/elections', '.');
(our $zero = $0) =~ s,.*/,,;
our $version = '1.6';
@@ -21,6 +25,98 @@ sub import {
$Votify::mode = $mode;
}
+my @REQUIRED_FILES = qw(ballot officials start stop voters);
+
+sub get_datadir {
+ my $election_name = shift;
+ my $election_dir = abs_path(catfile($Votify::basedir, $election_name));
+ if(!validate_election_dir()) {
+ die "$election_name is not a valid election!"
+ }
+ return $election_dir;
+}
+
+sub validate_election_dir {
+ return 0 unless $_;
+ my $election_dir = $_;
+ my $election_name = $election_dir;
+ $election_name =~ /.*\//;
+ return 0 unless -d $election_dir;
+ return 0 if substr($election_name,0,1) eq ".";
+ my $valid = List::Util::reduce {
+ $a or $b ? 1 : 0;
+ } map {
+ my $file_valid = 0;
+ # Legacy naming:
+ $file_valid = 1 if -f sprintf("%s/%s-%s", $election_name, $_, $election_name);
+ # New naming:
+ $file_valid = 1 if -f sprintf("%s/%s", $election_name, $_);
+ #printf "File %s valid=%d\n", $_, $file_valid;
+ $file_valid;
+ } @REQUIRED_FILES;
+ return $valid;
+}
+
+sub get_elections_list {
+ my @elections;
+ opendir(D, $Votify::basedir) or die;
+ @elections = sort grep {
+ my $valid = validate_election_dir(catfile($Votify::basedir, $_));
+ $valid;
+ } readdir D;
+ closedir D;
+ return @elections;
+}
+
+sub grabfile_int {
+ my $f = shift;
+ #print "Checking $f\n";
+ my $i = 0;
+ open my $fh, '<', $f or return -1;
+ local $/ = undef;
+ $i = <$fh> if defined($fh);
+ close $fh;
+ #print "Raw file: $i\n";
+ chomp $i if $i;
+ return $i;
+}
+
+
+sub get_single_election_hashref {
+ my $election_name = shift;
+ my $election_dir = catfile($Votify::basedir, $election_name);
+ my %election;
+ foreach my $fn (@REQUIRED_FILES){
+ #print "Scan $fn\n";
+ my @filenames = (sprintf("%s/%s", $election_name, $fn), sprintf("%s/%s-%s", $election_name, $fn, $election_name));
+ #print Dumper(@filenames);
+ my $filename = abs_path(List::Util::first { -f $_ } @filenames);
+ $election{"${fn}file"} = $filename;
+ };
+ #print Dumper(%election);
+ $election{starttime} = grabfile_int($election{'startfile'});
+ $election{stoptime} = grabfile_int($election{'stopfile'});
+ return \%election;
+}
+
+sub get_elections_hash {
+ my %elections;
+ %elections = map { $_ => get_single_election_hashref($_) } get_elections_list();
+ return %elections;
+}
+
+sub get_open_elections_hash {
+ my %elections = get_elections_hash();
+ my @open_elections = grep {
+ my $starttime = $elections{$_}{'starttime'};
+ my $stoptime = $elections{$_}{'stoptime'};
+ my $valid = ((not defined $starttime or $starttime < time) and
+ (not defined $stoptime or $stoptime > time));
+ $valid;
+ } keys %elections;
+ return map { $_ => $elections{$_} } @open_elections;
+}
+
######################################################################
# OfficialList
######################################################################
@@ -28,14 +124,15 @@ sub import {
package OfficialList;
sub new {
- my ($class, $election) = @_;
+ my ($class, $election_name) = @_;
my ($self) = {
- election => $election,
+ election => $election_name,
officials => [],
};
+ my $election = Votify::get_single_election_hashref($self->{'election'});
# no point in waiting to load
- open(F, "<$Votify::datadir/officials-$election")
+ open(F, '<', $election->{'officialsfile'})
or die("failed to open officials file");
chomp(@{$self->{'officials'}} = <F>);
close(F);
@@ -56,18 +153,20 @@ sub officials {
package VoterList;
sub new {
- my ($class, $election) = @_;
+ my ($class, $election_name) = @_;
my (@voterlist, $r);
+ my $datadir = Votify::get_datadir($election_name);
my ($self) = {
- election => $election,
- default_filename => "$Votify::datadir/confs-$election",
+ election => $election_name,
+ default_filename => catfile($datadir, "confs-$election_name"),
filename => '',
voters => {}, # confnum => voter
confs => {}, # voter => confnum
};
# no point in waiting to load
- open(F, "<$Votify::datadir/voters-$election")
+ my $election = Votify::get_single_election_hashref($self->{'election'});
+ open(F, '<', $election->{'votersfile'})
or die("failed to open voters file");
chomp(@voterlist = <F>);
close(F);
@@ -133,10 +232,11 @@ package MasterBallot;
use Data::Dumper;
sub new {
- my ($class, $election, $vl) = @_;
+ my ($class, $election_name, $vl) = @_;
+ my $datadir = Votify::get_datadir($election_name);
my ($self) = {
- election => $election,
- default_filename => "$Votify::datadir/master-$election",
+ election => $election_name,
+ default_filename => catfile($datadir, "master-$election_name"),
filename => '',
voterlist => $vl,
ballots => {}, # indexed by conf num
@@ -296,7 +396,7 @@ sub display_table {
@shortnames = sort values %{$self->{'candidates'}};
$minlen = length scalar keys %{$self->{'ballots'}};
$minlen = 5 if $minlen < 5;
-
+
# build the format string
for my $s (@shortnames) {
if (length($s) > $minlen) {
@@ -491,7 +591,8 @@ sub read {
sub populate {
my ($self) = @_;
- $self->read("$Votify::datadir/ballot-$self->{election}");
+ my $election = Votify::get_single_election_hashref($self->{'election'});
+ $self->read($election->{'ballotfile'});
@{$self->{'choices'}} = List::Util::shuffle(@{$self->{'choices'}});
}