diff options
author | Robin H. Johnson <robbat2@gentoo.org> | 2015-06-27 22:32:45 -0700 |
---|---|---|
committer | Robin H. Johnson <robbat2@gentoo.org> | 2015-06-27 22:33:35 -0700 |
commit | 274977d0840c8a1879946234c4d07575e8bde153 (patch) | |
tree | e5ade4c066051b55a7b69a8c51ae132d252eebdc /Votify.pm | |
parent | Start some cleanup of Election code. (diff) | |
download | elections-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.pm | 127 |
1 files changed, 114 insertions, 13 deletions
@@ -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'}}); } |