* [gentoo-commits] proj/elections:master commit in: /
@ 2011-02-13 2:21 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2011-02-13 2:21 UTC (permalink / raw
To: gentoo-commits
commit: 3ef378a3339ec2a2776daec4a4376d642a750697
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sun Feb 13 02:20:56 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sun Feb 13 02:20:56 2011 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/elections.git;a=commit;h=3ef378a3
Update symlink for live election.
---
current | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/current b/current
index 1dcf9bd..c9b5dea 120000
--- a/current
+++ b/current
@@ -1 +1 @@
-council201006
\ No newline at end of file
+trustees-201102
\ No newline at end of file
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2011-03-12 10:56 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2011-03-12 10:56 UTC (permalink / raw
To: gentoo-commits
commit: 11454907181978b99c00db92949e046948aaee05
Author: Robin H. Johnson <robbat2 <AT> orbis-terrarum <DOT> net>
AuthorDate: Sat Mar 12 10:56:05 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sat Mar 12 10:56:05 2011 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/elections.git;a=commit;h=11454907
Alter *ify code to support an epoch value in a file instead of the mtime of the file.
---
countify | 17 +++++++++++++++--
listify | 17 +++++++++++++++--
votify | 17 +++++++++++++++--
3 files changed, 45 insertions(+), 6 deletions(-)
diff --git a/countify b/countify
index c882fc7..2de6ba8 100755
--- a/countify
+++ b/countify
@@ -24,13 +24,26 @@ use strict;
(my $version = '$Revision: 1.3 $') =~ s/.*?(\d.*\d).*/$zero version $1\n/;
my %opt;
+sub grabfile_int {
+ my $f = shift;
+ open FILE, "<", $f;
+ $i = <FILE>;
+ close FILE;
+ chomp $i;
+ return $i + 0;
+}
+
# Collect the open elections
my (@open_elections, $usage_elections);
opendir(D, "$Votify::datadir/") or die;
@open_elections = sort grep {
s/^start-// and do {
- my ($starttime) = (stat _)[9] if stat("$Votify::datadir/start-$_");
- my ($stoptime) = (stat _)[9] if stat("$Votify::datadir/stop-$_");
+ my ($startfile) = sprintf "%s/start-%s", $Votify::datadir, $_;
+ my ($stopfile) = sprintf "%s/stop-%s", $Votify::datadir, $_;
+ my ($starttime) = grabfile_int($startfile);
+ my ($stoptime) = grabfile_int($stopfile);
+ $starttime = (stat _)[9] if stat($startfile) and (!defined($starttime) or ($starttime <= 0));
+ $stoptime = (stat _)[9] if stat($stopfile) and (!defined($stoptime) or ($stoptime <= 0));
((not defined $starttime or $starttime < time) and
(not defined $stoptime or $stoptime > time))
}
diff --git a/listify b/listify
index 641d473..632e444 100755
--- a/listify
+++ b/listify
@@ -24,14 +24,27 @@ use strict;
(my $version = '$Revision: 1.5 $') =~ s/.*?(\d.*\d).*/$zero version $1\n/;
my (%opt, %elections);
+sub grabfile_int {
+ my $f = shift;
+ open FILE, "<", $f;
+ $i = <FILE>;
+ close FILE;
+ chomp $i;
+ return $i + 0;
+}
+
# Collect the open elections
my (@open_elections, $usage_elections);
opendir(D, "$Votify::datadir/") or die;
@open_elections = sort grep {
s/^start-// and do {
my ($name) = $_;
- my ($starttime) = (stat _)[9] if stat("$Votify::datadir/start-$_");
- my ($stoptime) = (stat _)[9] if stat("$Votify::datadir/stop-$_");
+ my ($startfile) = sprintf "%s/start-%s", $Votify::datadir, $_;
+ my ($stopfile) = sprintf "%s/stop-%s", $Votify::datadir, $_;
+ my ($starttime) = grabfile_int($startfile);
+ my ($stoptime) = grabfile_int($stopfile);
+ $starttime = (stat _)[9] if stat($startfile) and (!defined($starttime) or ($starttime <= 0));
+ $stoptime = (stat _)[9] if stat($stopfile) and (!defined($stoptime) or ($stoptime <= 0));
my $valid = ((not defined $starttime or $starttime < time) and
(not defined $stoptime or $stoptime > time));
if($valid) {
diff --git a/votify b/votify
index c8d4e40..2e295bc 100755
--- a/votify
+++ b/votify
@@ -24,13 +24,26 @@ use strict;
(my $version = '$Revision: 1.5 $') =~ s/.*?(\d.*\d).*/$zero version $1\n/;
my (%opt);
+sub grabfile_int {
+ my $f = shift;
+ open FILE, "<", $f;
+ $i = <FILE>;
+ close FILE;
+ chomp $i;
+ return $i + 0;
+}
+
# Collect the open elections
my (@open_elections, $usage_elections);
opendir(D, "$Votify::datadir/") or die;
@open_elections = sort grep {
s/^start-// and do {
- my ($starttime) = (stat _)[9] if stat("$Votify::datadir/start-$_");
- my ($stoptime) = (stat _)[9] if stat("$Votify::datadir/stop-$_");
+ my ($startfile) = sprintf "%s/start-%s", $Votify::datadir, $_;
+ my ($stopfile) = sprintf "%s/stop-%s", $Votify::datadir, $_;
+ my ($starttime) = grabfile_int($startfile);
+ my ($stoptime) = grabfile_int($stopfile);
+ $starttime = (stat _)[9] if stat($startfile) and (!defined($starttime) or ($starttime <= 0));
+ $stoptime = (stat _)[9] if stat($stopfile) and (!defined($stoptime) or ($stoptime <= 0));
((not defined $starttime or $starttime < time) and
(not defined $stoptime or $stoptime > time))
}
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2011-03-12 10:57 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2011-03-12 10:57 UTC (permalink / raw
To: gentoo-commits
commit: 297502404343c3bce24efb274c8e9d851da7b4c6
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sat Mar 12 10:57:32 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sat Mar 12 10:57:32 2011 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/elections.git;a=commit;h=29750240
Perl syntax.
---
countify | 2 +-
listify | 2 +-
votify | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/countify b/countify
index 2de6ba8..a831d4b 100755
--- a/countify
+++ b/countify
@@ -27,7 +27,7 @@ my %opt;
sub grabfile_int {
my $f = shift;
open FILE, "<", $f;
- $i = <FILE>;
+ my $i = <FILE>;
close FILE;
chomp $i;
return $i + 0;
diff --git a/listify b/listify
index 632e444..4bfe965 100755
--- a/listify
+++ b/listify
@@ -27,7 +27,7 @@ my (%opt, %elections);
sub grabfile_int {
my $f = shift;
open FILE, "<", $f;
- $i = <FILE>;
+ my $i = <FILE>;
close FILE;
chomp $i;
return $i + 0;
diff --git a/votify b/votify
index 2e295bc..2ed6926 100755
--- a/votify
+++ b/votify
@@ -27,7 +27,7 @@ my (%opt);
sub grabfile_int {
my $f = shift;
open FILE, "<", $f;
- $i = <FILE>;
+ my $i = <FILE>;
close FILE;
chomp $i;
return $i + 0;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2011-03-12 18:41 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2011-03-12 18:41 UTC (permalink / raw
To: gentoo-commits
commit: 77343313c5066402dbff5968a45dc78e811c7434
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sat Mar 12 18:41:02 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sat Mar 12 18:41:02 2011 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/elections.git;a=commit;h=77343313
Missed a second place in votify where the old mtime algorithm was used.
---
votify | 12 ++++++++++--
1 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/votify b/votify
index 2ed6926..e607d66 100755
--- a/votify
+++ b/votify
@@ -139,8 +139,16 @@ my ($b) = Ballot->new($election);
# Check if the election is open. This should really happen in an
# Election class in Votify.pm eventually
my ($starttime, $stoptime);
-if (stat("$Votify::datadir/start-$election")) { $starttime = (stat _)[9] }
-if (stat("$Votify::datadir/stop-$election")) { $stoptime = (stat _)[9] }
+my ($startfile) = sprintf "%s/start-%s", $Votify::datadir, $election;
+my ($stopfile) = sprintf "%s/stop-%s", $Votify::datadir, $election;
+if ( -f $startfile ) {
+ $starttime = grabfile_int($startfile);
+ $starttime = (stat _)[9] if stat($startfile) and (!defined($starttime) or ($starttime <= 0));
+}
+if ( -f $stopfile ) {
+ ($stoptime) = grabfile_int($stopfile);
+ $stoptime = (stat _)[9] if stat($stopfile) and (!defined($stoptime) or ($stoptime <= 0));
+}
if ($starttime && $starttime > time) {
print "\n", "*" x 75, "\n";
print "WARNING: Specified election doesn't start until ",
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2011-04-09 0:09 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2011-04-09 0:09 UTC (permalink / raw
To: gentoo-commits
commit: 71335be74f981fdfb3d1b3d473c85ffc5376912b
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sat Apr 9 00:09:13 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sat Apr 9 00:09:13 2011 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/elections.git;a=commit;h=71335be7
Fix Votify.pm better to take mail-in ballots.
---
Votify.pm | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/Votify.pm b/Votify.pm
index 73bc287..c99685d 100644
--- a/Votify.pm
+++ b/Votify.pm
@@ -157,12 +157,13 @@ sub collect {
}
@pwentry = getpwnam($v);
- unless (@pwentry) {
- print STDERR "Warning: unknown user: $v\n";
- next;
+ if(@pwentry) {
+ $home = $pwentry[7];
+ } else {
+ print STDERR "Warning: Assuming /home/$v/ for unknown user: $v\n";
+ $home = sprintf '/home/%s/',$v;
}
- $home = $pwentry[7];
unless (-d $home) {
print STDERR "Warning: no directory: $home\n";
next;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2011-06-09 7:46 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2011-06-09 7:46 UTC (permalink / raw
To: gentoo-commits
commit: 37acab452de9c08e38c73b1bda643380da381681
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Thu Jun 9 07:46:48 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Thu Jun 9 07:46:48 2011 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/elections.git;a=commit;h=37acab45
Bug #326751: ease of use for vapier with auto-complete.
---
votify | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/votify b/votify
index e607d66..9363962 100755
--- a/votify
+++ b/votify
@@ -134,6 +134,7 @@ die "$zero: only one command allowed; use --help for help\n" if 1 < keys %opt;
die "$zero: election required; use --help for help\n" unless @ARGV == 1;
my ($election) = $ARGV[0];
+$election =~ s/^\.ballot-//g; # bug 326751
my ($b) = Ballot->new($election);
# Check if the election is open. This should really happen in an
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2011-06-20 6:08 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2011-06-20 6:08 UTC (permalink / raw
To: gentoo-commits
commit: d406e0433a87ea824f228b5f605c4c49d43cf3d4
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Mon Jun 20 06:08:40 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Mon Jun 20 06:08:40 2011 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/elections.git;a=commit;h=d406e043
Update symlink.
---
current | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/current b/current
index c9b5dea..effc1a3 120000
--- a/current
+++ b/current
@@ -1 +1 @@
-trustees-201102
\ No newline at end of file
+council-201106
\ No newline at end of file
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2011-06-20 6:13 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2011-06-20 6:13 UTC (permalink / raw
To: gentoo-commits
commit: 51d54212e0a9403c7d8a047d86527cbec9813244
Author: root <root <AT> woodpecker <DOT> gentoo <DOT> org>
AuthorDate: Mon Jun 20 06:08:50 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Mon Jun 20 06:08:50 2011 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/elections.git;a=commit;h=51d54212
Merge branch 'master' of git+ssh://git.gentoo.org/proj/elections
current | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
^ permalink raw reply [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2011-06-20 6:13 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2011-06-20 6:13 UTC (permalink / raw
To: gentoo-commits
commit: ed23dab801dcfb1dc8fa6a53b8e7dac947573374
Author: root <root <AT> woodpecker <DOT> gentoo <DOT> org>
AuthorDate: Sat Apr 9 00:09:50 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sat Apr 9 00:09:50 2011 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/elections.git;a=commit;h=ed23dab8
Merge branch 'master' of git+ssh://git.gentoo.org/proj/elections
^ permalink raw reply [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2011-06-20 6:13 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2011-06-20 6:13 UTC (permalink / raw
To: gentoo-commits
commit: 4880ad306328819ca7f997600ddf2a6e276bca73
Author: root <root <AT> woodpecker <DOT> gentoo <DOT> org>
AuthorDate: Mon Jun 20 06:08:13 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Mon Jun 20 06:08:13 2011 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/elections.git;a=commit;h=4880ad30
Merge branch 'master' of git+ssh://git.gentoo.org/proj/elections
{council2007 => council-201106}/Votify.pm | 0
council-201106/ballot-council-201106 | 13 +++
.../council-201106-devs-list | 0
council-201106/election-details | 6 ++
{council201006 => council-201106}/get-devs-list | 0
council-201106/officials-council-201106 | 2 +
.../start-council-201106 | 0
.../stop-council-201106 | 0
.../voters-council-201106 | 82 +++++++-------------
votify | 1 +
10 files changed, 51 insertions(+), 53 deletions(-)
^ permalink raw reply [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2011-06-20 6:13 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2011-06-20 6:13 UTC (permalink / raw
To: gentoo-commits
commit: 9f1c231ef4aa654d47efbc921c8c03148ceefc26
Author: root <root <AT> woodpecker <DOT> gentoo <DOT> org>
AuthorDate: Sat Apr 9 00:07:47 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sat Apr 9 00:07:47 2011 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/elections.git;a=commit;h=9f1c231e
Fix Votify.pm better to take mail-in ballots.
---
Votify.pm | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/Votify.pm b/Votify.pm
index 73bc287..c99685d 100644
--- a/Votify.pm
+++ b/Votify.pm
@@ -157,12 +157,13 @@ sub collect {
}
@pwentry = getpwnam($v);
- unless (@pwentry) {
- print STDERR "Warning: unknown user: $v\n";
- next;
+ if(@pwentry) {
+ $home = $pwentry[7];
+ } else {
+ print STDERR "Warning: Assuming /home/$v/ for unknown user: $v\n";
+ $home = sprintf '/home/%s/',$v;
}
- $home = $pwentry[7];
unless (-d $home) {
print STDERR "Warning: no directory: $home\n";
next;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2011-06-20 6:14 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2011-06-20 6:14 UTC (permalink / raw
To: gentoo-commits
commit: 3292aff645e0a454ac074314fc5997c6fa145aaa
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Mon Jun 20 06:14:44 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Mon Jun 20 06:14:44 2011 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/elections.git;a=commit;h=3292aff6
Merge branch 'master' of git+ssh://git.gentoo.org/proj/elections
^ permalink raw reply [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2012-02-15 2:07 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2012-02-15 2:07 UTC (permalink / raw
To: gentoo-commits
commit: 05d7af947bdc08ee1faaab5a131d090cb3f738de
Author: Christian Ruppert <idl0r <AT> gentoo <DOT> org>
AuthorDate: Wed Feb 15 02:05:51 2012 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Wed Feb 15 02:07:04 2012 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/elections.git;a=commit;h=05d7af94
Fix some uninitialized variables warnings
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
---
listify | 7 ++++---
votify | 7 ++++---
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/listify b/listify
index 4bfe965..c7fdf80 100755
--- a/listify
+++ b/listify
@@ -26,11 +26,12 @@ my (%opt, %elections);
sub grabfile_int {
my $f = shift;
+ my $i = 0;
open FILE, "<", $f;
- my $i = <FILE>;
+ $i = <FILE> if defined(<FILE>);
close FILE;
- chomp $i;
- return $i + 0;
+ chomp $i if $i;
+ return $i;
}
# Collect the open elections
diff --git a/votify b/votify
index 9363962..94c532a 100755
--- a/votify
+++ b/votify
@@ -26,11 +26,12 @@ my (%opt);
sub grabfile_int {
my $f = shift;
+ my $i = 0;
open FILE, "<", $f;
- my $i = <FILE>;
+ $i = <FILE> if defined(<FILE>);
close FILE;
- chomp $i;
- return $i + 0;
+ chomp $i if $i;
+ return $i;
}
# Collect the open elections
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2012-06-18 21:08 Christian Ruppert
0 siblings, 0 replies; 44+ messages in thread
From: Christian Ruppert @ 2012-06-18 21:08 UTC (permalink / raw
To: gentoo-commits
commit: 246aad7efa486fdeade636ebaecdc9b61c81b985
Author: Christian Ruppert <idl0r <AT> gentoo <DOT> org>
AuthorDate: Mon Jun 18 21:08:13 2012 +0000
Commit: Christian Ruppert <idl0r <AT> gentoo <DOT> org>
CommitDate: Mon Jun 18 21:08:13 2012 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/elections.git;a=commit;h=246aad7e
Set current
---
current | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/current b/current
index effc1a3..1aec752 120000
--- a/current
+++ b/current
@@ -1 +1 @@
-council-201106
\ No newline at end of file
+council-201206
\ No newline at end of file
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2012-07-16 19:01 Christian Ruppert
0 siblings, 0 replies; 44+ messages in thread
From: Christian Ruppert @ 2012-07-16 19:01 UTC (permalink / raw
To: gentoo-commits
commit: 083ae9ab312f7b0f3c222e55211d45a2fcede463
Author: Christian Ruppert <idl0r <AT> gentoo <DOT> org>
AuthorDate: Mon Jul 16 19:01:01 2012 +0000
Commit: Christian Ruppert <idl0r <AT> gentoo <DOT> org>
CommitDate: Mon Jul 16 19:01:01 2012 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/elections.git;a=commit;h=083ae9ab
Update current
---
current | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/current b/current
index 1aec752..7b3152d 120000
--- a/current
+++ b/current
@@ -1 +1 @@
-council-201206
\ No newline at end of file
+trustees-201206
\ No newline at end of file
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2013-02-06 0:09 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 44+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2013-02-06 0:09 UTC (permalink / raw
To: gentoo-commits
commit: 483bd203ac3946803f533d9d6e2b975366f35914
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Wed Feb 6 00:07:22 2013 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Wed Feb 6 00:07:22 2013 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/elections.git;a=commit;h=483bd203
Add ciaranm's script to generate vote distribution maps for an election.
Applied a small change to have the script take an election name parameter.
---
election-grapher.rb | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 99 insertions(+), 0 deletions(-)
diff --git a/election-grapher.rb b/election-grapher.rb
new file mode 100755
index 0000000..e316429
--- /dev/null
+++ b/election-grapher.rb
@@ -0,0 +1,99 @@
+#!/usr/bin/ruby19
+
+list = ARGF.argv
+
+if list.size != 1
+ puts "Invalid call. You need to pass the election name to this script"
+ exit(-1)
+end
+
+ElectionName = list.at(0)
+
+ResultsFile = "master-" + ElectionName + ".txt"
+RankingsFile = ElectionName + "-rank.txt"
+ScaleSize = 14
+HeightScale = 5
+BarHeight = 8
+
+# Get all candidate names and initialise their vote count
+candidates = Hash.new
+ballots = Hash.new
+File.open ResultsFile, "r" do | file |
+ file.each_line do | line |
+ next if line =~ /^-/
+ line.split(%r/\s+/).each do | person |
+ candidates[person] = [0] * ScaleSize unless candidates[person]
+ end
+ end
+
+ file.seek(0, IO::SEEK_SET)
+
+ key = false
+ file.each_line do | line |
+ if line =~ %r/^-/
+ key = line.split(/\s+/).grep(/^[a-fA-F0-9]{4}$/)[0]
+ ballots[key] = []
+ else
+ raise "key not set yet" unless key
+ ballots[key].push line.chomp.split(/\s+/)
+ end
+ end
+end
+
+# Add in missing candidates
+ballots.keys.each do | key |
+ append_candidates = candidates.keys.dup
+ ballots[key].flatten.each do | candidate |
+ append_candidates.delete_if do | item |
+ item == candidate
+ end
+ end
+ unless append_candidates.empty?
+ ballots[key].push append_candidates
+ end
+end
+
+# Calculate distributions
+ballots.each_pair do | ballot, results |
+ scale_by = ScaleSize / (0.0 + results.length)
+ results.each_with_index do | result, index |
+ place = (scale_by * index.to_f).to_i
+ raise "out of range" unless (0..ScaleSize - 1).include? place
+ result.each do | candidate |
+ candidates[candidate][place] += 1
+ end
+ end
+end
+
+# Read in rankings
+rankings = []
+File.open RankingsFile, "r" do | file |
+ file.each_line do | line |
+ key = line.split(/\s+/)[0]
+ rankings << key
+ end
+end
+
+
+# Display distributions
+candidates.keys.sort do | a, b |
+ rankings << a unless rankings.index a
+ rankings << b unless rankings.index b
+ (rankings.index a) <=> (rankings.index b)
+end.each do | candidate |
+ puts " " + candidate + " (" + (rankings.index(candidate) + 1).to_s + ")"
+ BarHeight.downto(0) do | height |
+ print "|"
+ candidates[candidate].each do | value |
+ if value > (height * HeightScale)
+ print "#"
+ else
+ print " "
+ end
+ end
+ puts
+ end
+ puts "+" + ("-" * ScaleSize)
+ puts
+end
+
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2013-06-30 6:32 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 44+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2013-06-30 6:32 UTC (permalink / raw
To: gentoo-commits
commit: 206efcc3a8c06400ef3e39e1f5980ed01f517d9d
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Sun Jun 30 06:30:18 2013 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Sun Jun 30 06:30:18 2013 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/elections.git;a=commit;h=206efcc3
Mark council-201306 as the current election.
---
current | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/current b/current
index 7b3152d..f05765a 120000
--- a/current
+++ b/current
@@ -1 +1 @@
-trustees-201206
\ No newline at end of file
+council-201306
\ No newline at end of file
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2015-06-27 16:18 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2015-06-27 16:18 UTC (permalink / raw
To: gentoo-commits
commit: 12fb6ecd06195bb42b7f590e5bdca512f4e9b3f7
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sat Jun 27 16:18:20 2015 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sat Jun 27 16:18:20 2015 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=12fb6ecd
Copy 2014/07/01 symlink from woodpecker.
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
current | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/current b/current
index 3cbba7b..dfd9edc 120000
--- a/current
+++ b/current
@@ -1 +1 @@
-trustees-201306
\ No newline at end of file
+council-201406
\ No newline at end of file
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2015-06-28 0:12 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 44+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2015-06-28 0:12 UTC (permalink / raw
To: gentoo-commits
commit: 5999dd5e798d9efc087bc5c1e771e7265bc209ed
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Sun Jun 28 00:07:19 2015 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Sun Jun 28 00:07:19 2015 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=5999dd5e
Update current to the council-201506 election.
Signed-off-by: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo.org>
current | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/current b/current
index dfd9edc..7195ce7 120000
--- a/current
+++ b/current
@@ -1 +1 @@
-council-201406
\ No newline at end of file
+council-201506
\ No newline at end of file
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2016-06-18 17:28 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2016-06-18 17:28 UTC (permalink / raw
To: gentoo-commits
commit: 4aa542e6634b127ae3c3a9f28719bc070006a39c
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sun Jun 28 05:33:17 2015 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sun Jun 28 05:33:35 2015 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=4aa542e6
Rewrite old bash election-stats-count in perl, using the new election code.
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
election-stats-count | 26 +----------
statify | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 122 insertions(+), 25 deletions(-)
diff --git a/election-stats-count b/election-stats-count
deleted file mode 100755
index 7c39015..0000000
--- a/election-stats-count
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-# TODO:
-# - this should NOT produce any output when the election is closed.
-# - should work with concurrent elections
-HOMEDIR=/etc/elections/
-NAME=$(awk '/^name/{print $2}' $HOMEDIR/current/election-details)
-OFFICIALS=$(cat ${HOMEDIR}/current/officials-$NAME)
-COUNT_VOTERS=$(wc -l <${HOMEDIR}/current/voters-$NAME)
-
-COUNT_SUBMIT=$(ls /home/*/.ballot-${NAME}-submitted 2>/dev/null | wc -l)
-COUNT_PENDING=$(ls /home/*/.ballot-${NAME} 2>/dev/null | wc -l)
-
-
-umask 057
-for u in ${OFFICIALS} ; do
-OUTFILE="/home/$u/voter-turnout-${NAME}"
-#cat <<-EOF
-cat >${OUTFILE} <<-EOF
-Eligable voters: $COUNT_VOTERS
-Submitted votes: ${COUNT_SUBMIT}
-Pending votes: ${COUNT_PENDING}
-Turnout: $(echo "scale=10; ${COUNT_SUBMIT}/${COUNT_VOTERS}*100" | bc | xargs printf '%02.3f' )%
-EOF
-chown ${u}:root ${OUTFILE}
-done
diff --git a/election-stats-count b/election-stats-count
new file mode 120000
index 0000000..fad4dda
--- /dev/null
+++ b/election-stats-count
@@ -0,0 +1 @@
+statify
\ No newline at end of file
diff --git a/statify b/statify
new file mode 100755
index 0000000..c424696
--- /dev/null
+++ b/statify
@@ -0,0 +1,121 @@
+#!/usr/bin/perl -w
+# $Id$
+#
+# Copyright 2015 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# Author: Robin H Johnson <robbat2@gentoo.org>
+#
+# statify: Produce early election statistics
+#
+
+BEGIN {
+ if(-f '/etc/elections/Votify.pm') {
+ push @INC, '/etc/elections';
+ } else {
+ push @INC, '.' if -f 'Votify.pm';
+ }
+}
+
+use POSIX;
+use Getopt::Long;
+use List::Util;
+use Cwd qw(abs_path);
+use File::Spec::Functions;
+use Votify 'official';
+use strict;
+
+######################################################################
+# Global vars
+######################################################################
+
+(my $zero = $0) =~ s,.*/,,;
+(my $version = $Votify::version) =~ s/.*?(\d.*\d).*/$zero version $1\n/;
+my %opt;
+
+# Collect the open elections
+my (%open_elections, $usage_elections);
+%open_elections = Votify::get_open_elections_hash();
+if (scalar keys %open_elections) {
+ $usage_elections = join("\n ", keys %open_elections);
+} else {
+ $usage_elections = "(no elections currently open)";
+}
+
+# rest of usage
+my $usage = <<EOT;
+
+usage:
+ $zero [OPTS] <election>
+ $zero [OPTS] --all
+
+where options are:
+
+ --all Run on all open elections
+ --write-to-officials Write statistics to officials homedirs
+
+and <election> is one of the elections currently in-progress. The following
+elections are currently open:
+
+ $usage_elections
+
+EOT
+
+######################################################################
+# Main
+######################################################################
+for my $election_name (keys %open_elections) {
+ my (@officials, @voters);
+ open(F, '<', $open_elections{$election_name}{'officialsfile'})
+ or die("failed to open officials file");
+ chomp(@officials = <F>);
+ close(F);
+
+ $open_elections{$election_name}{'officials'} = @officials;
+
+ open(F, '<', $open_elections{$election_name}{'votersfile'})
+ or die("failed to open voters file");
+ chomp(@voters = <F>);
+ close(F);
+
+ $open_elections{$election_name}{'voters'} = @voters;
+
+ my ($count_voters, $count_submit, $count_pending) = (0, 0,0);
+ for my $votername (@voters) {
+ $count_voters++;
+ if(-f catfile('/home', $votername, ".ballot-${election_name}-submitted")) {
+ $count_submit++;
+ } elsif (-f catfile('/home', $votername, ".ballot-${election_name}")) {
+ $count_pending++;
+ }
+ }
+ die "Mismatched voter count" unless $count_voters == scalar(@voters);
+ $open_elections{$election_name}{'count'} = {
+ voters => $count_voters,
+ submitted => $count_submit,
+ pending => $count_pending,
+ };
+ my $results_buffer = ''
+ .sprintf("Election: %s\n", $election_name)
+ .sprintf("Timestamp: %s\n", POSIX::strftime($Votify::datefmt, gmtime))
+ .sprintf("Eligable voters: %d\n", $count_voters)
+ .sprintf("Submitted votes: %d\n", $count_submit)
+ .sprintf("Pending votes: %d\n", $count_pending)
+ .sprintf("Turnout: %02.3f%%\n", $count_submit*100.0/$count_voters)
+ .sprintf("Pending Turnout: %02.3f%%\n", ($count_submit+$count_pending)*100.0/$count_voters);
+ print "$results_buffer\n";
+
+ umask 057;
+ for my $officialname (@officials) {
+ my $fn = catfile('/home', $officialname, 'voter-turnout-'.$election_name);
+ open(F, '>', $fn) or
+ die("failed to open voter turnout file ($fn): $!");
+ print F $results_buffer;
+ close F;
+ chown ((getpwnam($officialname))[2]), 0, ($fn) or
+ die("failed to chown voter turnout file ($fn): $!");
+ }
+}
+
+
+__END__
+# vim:sw=4 et
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2016-06-18 17:28 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2016-06-18 17:28 UTC (permalink / raw
To: gentoo-commits
commit: bd4772016b1b8690acdd276fb5d7dd9eaaf6b6e2
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sun Jun 28 05:34:09 2015 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sun Jun 28 05:34:09 2015 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=bd477201
None of the codebase uses the "current" symlink anymore!
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
current | 1 -
1 file changed, 1 deletion(-)
diff --git a/current b/current
deleted file mode 120000
index 7195ce7..0000000
--- a/current
+++ /dev/null
@@ -1 +0,0 @@
-council-201506
\ No newline at end of file
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2016-06-18 17:28 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2016-06-18 17:28 UTC (permalink / raw
To: gentoo-commits
commit: 398f72c9a0d1da496a7fb408cef3c2d156cff170
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sat Jun 27 16:37:58 2015 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sun Jun 28 05:33:35 2015 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=398f72c9
Start some cleanup of Election code.
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
Votify.pm | 42 ++----------------------------------------
countify | 13 ++-----------
listify | 6 ++++--
votify | 18 ++----------------
4 files changed, 10 insertions(+), 69 deletions(-)
diff --git a/Votify.pm b/Votify.pm
index c99685d..1be8de7 100644
--- a/Votify.pm
+++ b/Votify.pm
@@ -1,6 +1,6 @@
# $Id: Votify.pm,v 1.5 2005/05/16 23:58:09 agriffis Exp $
#
-# Copyright 2005 Gentoo Foundation
+# Copyright 2005-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
#
# votify.pm: common classes for votify and countify
@@ -14,6 +14,7 @@ use strict;
our ($datadir) = '/etc/elections/current';
(our $zero = $0) =~ s,.*/,,;
+our $version = '1.6';
sub import {
my ($class, $mode) = @_;
@@ -642,43 +643,4 @@ sub to_s {
1;
__END__
-
-$Log: Votify.pm,v $
-Revision 1.5 2005/05/16 23:58:09 agriffis
-change wording
-
-Revision 1.4 2005/05/16 18:40:07 agriffis
-fix shortname calculation
-
-Revision 1.3 2005/05/16 18:10:46 agriffis
-ranking works completely now, even if it needs badly to be refactored
-
-Revision 1.2 2005/05/16 04:03:46 agriffis
-add first pass at countify --rank
-
-
-__END__
-
-$Log: Votify.pm,v $
-Revision 1.5 2005/05/16 23:58:09 agriffis
-change wording
-
-Revision 1.4 2005/05/16 18:40:07 agriffis
-fix shortname calculation
-
-Revision 1.3 2005/05/16 18:10:46 agriffis
-ranking works completely now, even if it needs badly to be refactored
-
-Revision 1.2 2005/05/16 04:03:46 agriffis
-add first pass at countify --rank
-
-Revision 1.3 2005/05/09 23:12:02 agriffis
-Add support for registered voters
-
-Revision 1.2 2005/05/05 23:03:46 agriffis
-Fix indentation (and some output as well)
-
-Revision 1.1 2005/05/05 22:05:34 agriffis
-first pass at Gentoo Foundation voting program
-
# vim:sw=4 et
diff --git a/countify b/countify
index a831d4b..975a7ec 100755
--- a/countify
+++ b/countify
@@ -1,7 +1,7 @@
#!/usr/bin/perl -w
# $Id: countify,v 1.3 2005/05/16 18:10:46 agriffis Exp $
#
-# Copyright 2005 Gentoo Foundation
+# Copyright 2005-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
#
# countify: collect, tabulate and announce ballot results
@@ -21,7 +21,7 @@ use strict;
######################################################################
(my $zero = $0) =~ s,.*/,,;
-(my $version = '$Revision: 1.3 $') =~ s/.*?(\d.*\d).*/$zero version $1\n/;
+(my $version = $Votify::version) =~ s/.*?(\d.*\d).*/$zero version $1\n/;
my %opt;
sub grabfile_int {
@@ -162,13 +162,4 @@ if ($opt{'rank'}) {
}
__END__
-
-$Log: countify,v $
-Revision 1.3 2005/05/16 18:10:46 agriffis
-ranking works completely now, even if it needs badly to be refactored
-
-Revision 1.2 2005/05/16 04:03:46 agriffis
-add first pass at countify --rank
-
-
# vim:sw=4 et
diff --git a/listify b/listify
index c7fdf80..10b4b82 100755
--- a/listify
+++ b/listify
@@ -1,7 +1,7 @@
#!/usr/bin/perl -w
# $Id: votify,v 1.5 2005/05/16 04:03:46 agriffis Exp $
#
-# Copyright 2005 Gentoo Foundation
+# Copyright 2005-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
#
# votify: generate, verify and submit voting ballots for trustee elections
@@ -21,7 +21,7 @@ use strict;
######################################################################
(my $zero = $0) =~ s,.*/,,;
-(my $version = '$Revision: 1.5 $') =~ s/.*?(\d.*\d).*/$zero version $1\n/;
+(my $version = $Votify::version) =~ s/.*?(\d.*\d).*/$zero version $1\n/;
my (%opt, %elections);
sub grabfile_int {
@@ -76,4 +76,6 @@ EOF
print $usage_elections;
exit;
+
+__END__
# vim:sw=4 et
diff --git a/votify b/votify
index 94c532a..40607b7 100755
--- a/votify
+++ b/votify
@@ -1,7 +1,7 @@
#!/usr/bin/perl -w
# $Id: votify,v 1.5 2005/05/16 04:03:46 agriffis Exp $
#
-# Copyright 2005 Gentoo Foundation
+# Copyright 2005-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
#
# votify: generate, verify and submit voting ballots for trustee elections
@@ -21,7 +21,7 @@ use strict;
######################################################################
(my $zero = $0) =~ s,.*/,,;
-(my $version = '$Revision: 1.5 $') =~ s/.*?(\d.*\d).*/$zero version $1\n/;
+(my $version = $Votify::version) =~ s/.*?(\d.*\d).*/$zero version $1\n/;
my (%opt);
sub grabfile_int {
@@ -226,18 +226,4 @@ EOF
}
__END__
-
-$Log: votify,v $
-Revision 1.5 2005/05/16 04:03:46 agriffis
-add first pass at countify --rank
-
-Revision 1.3 2005/05/09 23:12:02 agriffis
-Add support for registered voters
-
-Revision 1.2 2005/05/05 23:03:46 agriffis
-Fix indentation (and some output as well)
-
-Revision 1.1 2005/05/05 22:05:34 agriffis
-first pass at Gentoo Foundation voting program
-
# vim:sw=4 et
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2016-06-18 17:28 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2016-06-18 17:28 UTC (permalink / raw
To: gentoo-commits
commit: 274977d0840c8a1879946234c4d07575e8bde153
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sun Jun 28 05:32:45 2015 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sun Jun 28 05:33:35 2015 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=274977d0
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 <AT> gentoo.org>
Votify.pm | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
countify | 38 ++++++-------------
listify | 58 +++++++++-------------------
votify | 55 ++++++++-------------------
4 files changed, 157 insertions(+), 121 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'}});
}
diff --git a/countify b/countify
index 975a7ec..1465da4 100755
--- a/countify
+++ b/countify
@@ -8,7 +8,13 @@
#
#BEGIN { push @INC, (getpwnam 'fox2mike')[7].'/elections' }
-BEGIN { push @INC, '/etc/elections/current' }
+BEGIN {
+ if(-f '/etc/elections/Votify.pm') {
+ push @INC, '/etc/elections';
+ } else {
+ push @INC, '.' if -f 'Votify.pm';
+ }
+}
use POSIX;
use Getopt::Long;
@@ -24,33 +30,11 @@ use strict;
(my $version = $Votify::version) =~ s/.*?(\d.*\d).*/$zero version $1\n/;
my %opt;
-sub grabfile_int {
- my $f = shift;
- open FILE, "<", $f;
- my $i = <FILE>;
- close FILE;
- chomp $i;
- return $i + 0;
-}
-
# Collect the open elections
-my (@open_elections, $usage_elections);
-opendir(D, "$Votify::datadir/") or die;
-@open_elections = sort grep {
- s/^start-// and do {
- my ($startfile) = sprintf "%s/start-%s", $Votify::datadir, $_;
- my ($stopfile) = sprintf "%s/stop-%s", $Votify::datadir, $_;
- my ($starttime) = grabfile_int($startfile);
- my ($stoptime) = grabfile_int($stopfile);
- $starttime = (stat _)[9] if stat($startfile) and (!defined($starttime) or ($starttime <= 0));
- $stoptime = (stat _)[9] if stat($stopfile) and (!defined($stoptime) or ($stoptime <= 0));
- ((not defined $starttime or $starttime < time) and
- (not defined $stoptime or $stoptime > time))
- }
-} readdir D;
-closedir D;
-if (@open_elections) {
- $usage_elections = join("\n ", @open_elections);
+my (%open_elections, $usage_elections);
+%open_elections = Votify::get_open_elections_hash();
+if (scalar keys %open_elections) {
+ $usage_elections = join("\n ", keys %open_elections);
} else {
$usage_elections = "(no elections currently open)";
}
diff --git a/listify b/listify
index 10b4b82..c8c24eb 100755
--- a/listify
+++ b/listify
@@ -7,8 +7,13 @@
# votify: generate, verify and submit voting ballots for trustee elections
#
-#BEGIN { push @INC, (getpwnam 'fox2mike')[7].'/elections' }
-BEGIN { push @INC, '/etc/elections/current' }
+BEGIN {
+ if(-f '/etc/elections/Votify.pm') {
+ push @INC, '/etc/elections';
+ } else {
+ push @INC, '.' if -f 'Votify.pm';
+ }
+}
use POSIX;
use Getopt::Long;
@@ -24,46 +29,17 @@ use strict;
(my $version = $Votify::version) =~ s/.*?(\d.*\d).*/$zero version $1\n/;
my (%opt, %elections);
-sub grabfile_int {
- my $f = shift;
- my $i = 0;
- open FILE, "<", $f;
- $i = <FILE> if defined(<FILE>);
- close FILE;
- chomp $i if $i;
- return $i;
-}
-
# Collect the open elections
-my (@open_elections, $usage_elections);
-opendir(D, "$Votify::datadir/") or die;
-@open_elections = sort grep {
- s/^start-// and do {
- my ($name) = $_;
- my ($startfile) = sprintf "%s/start-%s", $Votify::datadir, $_;
- my ($stopfile) = sprintf "%s/stop-%s", $Votify::datadir, $_;
- my ($starttime) = grabfile_int($startfile);
- my ($stoptime) = grabfile_int($stopfile);
- $starttime = (stat _)[9] if stat($startfile) and (!defined($starttime) or ($starttime <= 0));
- $stoptime = (stat _)[9] if stat($stopfile) and (!defined($stoptime) or ($stoptime <= 0));
- my $valid = ((not defined $starttime or $starttime < time) and
- (not defined $stoptime or $stoptime > time));
- if($valid) {
- $elections{$name} = {};
- $elections{$name}{starttime} = $starttime;
- $elections{$name}{stoptime} = $stoptime;
- }
- $valid;
- }
-} readdir D;
-closedir D;
-my $datefmt = '%Y-%m-%d %H:%M UTC';
-if (@open_elections) {
- $usage_elections = "Presently available elections:\n" . join('', map {
- my ($name) = $_;
- my ($start) = strftime($datefmt, localtime($elections{$name}{starttime}));
- my ($stop) = strftime($datefmt, localtime($elections{$name}{stoptime}));
- sprintf("\t%s: %s to %s\n", $name, $start, $stop) } @open_elections);
+my ($usage_elections);
+
+%elections = Votify::get_open_elections_hash();
+
+if (scalar(keys %elections) > 0) {
+ $usage_elections = "Presently available elections:\n" . join('', map {
+ my ($name) = $_;
+ my ($start) = strftime($Votify::datefmt, gmtime($elections{$name}{starttime}));
+ my ($stop) = strftime($Votify::datefmt, gmtime($elections{$name}{stoptime}));
+ sprintf("\t%s: %s to %s\n", $name, $start, $stop) } keys %elections);
$usage_elections .= <<EOF
\nA handy tool called "votify" can be used to vote in the election. You can use
"votify --help" to get instructions on how to vote, verify, and submit your
diff --git a/votify b/votify
index 40607b7..e52881d 100755
--- a/votify
+++ b/votify
@@ -8,7 +8,13 @@
#
#BEGIN { push @INC, (getpwnam 'fox2mike')[7].'/elections' }
-BEGIN { push @INC, '/etc/elections/current' }
+BEGIN {
+ if(-f '/etc/elections/Votify.pm') {
+ push @INC, '/etc/elections';
+ } else {
+ push @INC, '.' if -f 'Votify.pm';
+ }
+}
use POSIX;
use Getopt::Long;
@@ -24,34 +30,11 @@ use strict;
(my $version = $Votify::version) =~ s/.*?(\d.*\d).*/$zero version $1\n/;
my (%opt);
-sub grabfile_int {
- my $f = shift;
- my $i = 0;
- open FILE, "<", $f;
- $i = <FILE> if defined(<FILE>);
- close FILE;
- chomp $i if $i;
- return $i;
-}
-
# Collect the open elections
-my (@open_elections, $usage_elections);
-opendir(D, "$Votify::datadir/") or die;
-@open_elections = sort grep {
- s/^start-// and do {
- my ($startfile) = sprintf "%s/start-%s", $Votify::datadir, $_;
- my ($stopfile) = sprintf "%s/stop-%s", $Votify::datadir, $_;
- my ($starttime) = grabfile_int($startfile);
- my ($stoptime) = grabfile_int($stopfile);
- $starttime = (stat _)[9] if stat($startfile) and (!defined($starttime) or ($starttime <= 0));
- $stoptime = (stat _)[9] if stat($stopfile) and (!defined($stoptime) or ($stoptime <= 0));
- ((not defined $starttime or $starttime < time) and
- (not defined $stoptime or $stoptime > time))
- }
-} readdir D;
-closedir D;
-if (@open_elections) {
- $usage_elections = join("\n ", @open_elections);
+my (%open_elections, $usage_elections);
+%open_elections = Votify::get_open_elections_hash();
+if (scalar keys %open_elections) {
+ $usage_elections = join("\n ", keys %open_elections);
} else {
$usage_elections = "(no elections currently open)";
}
@@ -104,7 +87,7 @@ Instructions:
(4) Submit your ballot. This renames your ballot to
~/.ballot-<election>-submitted so that it will be tallied when the votes
are collected.
-
+
\$ $zero --submit <election>
EOT
@@ -141,16 +124,8 @@ my ($b) = Ballot->new($election);
# Check if the election is open. This should really happen in an
# Election class in Votify.pm eventually
my ($starttime, $stoptime);
-my ($startfile) = sprintf "%s/start-%s", $Votify::datadir, $election;
-my ($stopfile) = sprintf "%s/stop-%s", $Votify::datadir, $election;
-if ( -f $startfile ) {
- $starttime = grabfile_int($startfile);
- $starttime = (stat _)[9] if stat($startfile) and (!defined($starttime) or ($starttime <= 0));
-}
-if ( -f $stopfile ) {
- ($stoptime) = grabfile_int($stopfile);
- $stoptime = (stat _)[9] if stat($stopfile) and (!defined($stoptime) or ($stoptime <= 0));
-}
+$starttime = $open_elections{$election}{'starttime'};
+$stoptime = $open_elections{$election}{'stoptime'};
if ($starttime && $starttime > time) {
print "\n", "*" x 75, "\n";
print "WARNING: Specified election doesn't start until ",
@@ -166,7 +141,7 @@ if ($stoptime && $stoptime < time) {
if ($opt{'new'}) {
# Make sure the user is eligible
- open(F, "<$Votify::datadir/voters-$election") or die "Failed to open voters file";
+ open(F, '<', $open_elections{$election}{'votersfile'}) or die "Failed to open voters file";
my (@voters) = <F>;
chomp(@voters);
close(F);
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2016-06-19 12:13 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 44+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2016-06-19 12:13 UTC (permalink / raw
To: gentoo-commits
commit: feb500c197990874101ae84aa51a6b718e96ae79
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Sun Jun 19 12:05:35 2016 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Sun Jun 19 12:05:35 2016 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=feb500c1
Allow running votify outside of /etc/elections and the repository dir.
Signed-off-by: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo.org>
Votify.pm | 12 ++++++------
votify | 8 +++++---
2 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/Votify.pm b/Votify.pm
index 48e5938..ed5b519 100644
--- a/Votify.pm
+++ b/Votify.pm
@@ -10,13 +10,13 @@ package Votify;
use POSIX;
use Cwd qw(abs_path);
+use File::Basename;
use File::Spec::Functions;
use List::Util;
use strict;
our $datefmt = '%Y-%m-%d %H:%M:%S UTC';
-
-our ($basedir) = List::Util::first { -d $_ } ('/etc/elections', '.');
+our ($basedir) = List::Util::first { -d $_ } ('/etc/elections', dirname(__FILE__));
(our $zero = $0) =~ s,.*/,,;
our $version = '1.6';
@@ -41,16 +41,16 @@ sub validate_election_dir {
my $election_dir = $_;
my $election_name = $election_dir;
$election_name =~ /.*\//;
- return 0 unless -d $election_dir;
+ return 0 unless -d "$basedir/$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);
+ $file_valid = 1 if -f sprintf("%s/%s-%s", "$basedir/$election_name", $_, $election_name);
# New naming:
- $file_valid = 1 if -f sprintf("%s/%s", $election_name, $_);
+ $file_valid = 1 if -f sprintf("%s/%s", "$basedir/$election_name", $_);
#printf "File %s valid=%d\n", $_, $file_valid;
$file_valid;
} @REQUIRED_FILES;
@@ -88,7 +88,7 @@ sub get_single_election_hashref {
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));
+ my @filenames = (sprintf("%s/%s", "$basedir/$election_name", $fn), sprintf("%s/%s-%s", "$basedir/$election_name", $fn, $election_name));
#print Dumper(@filenames);
my $filename = abs_path(List::Util::first { -f $_ } @filenames);
$election{"${fn}file"} = $filename;
diff --git a/votify b/votify
index e52881d..4fb688d 100755
--- a/votify
+++ b/votify
@@ -7,13 +7,15 @@
# votify: generate, verify and submit voting ballots for trustee elections
#
-#BEGIN { push @INC, (getpwnam 'fox2mike')[7].'/elections' }
BEGIN {
+ my $dirname;
if(-f '/etc/elections/Votify.pm') {
- push @INC, '/etc/elections';
+ $dirname = '/etc/elections';
} else {
- push @INC, '.' if -f 'Votify.pm';
+ use File::Basename;
+ $dirname = dirname(__FILE__);
}
+ push @INC, $dirname;
}
use POSIX;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2016-06-19 12:13 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 44+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2016-06-19 12:13 UTC (permalink / raw
To: gentoo-commits
commit: d485ef42ae4a6374e6215a3fa3e70d2ad06a4085
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Sun Jun 19 12:13:03 2016 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Sun Jun 19 12:13:03 2016 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=d485ef42
Allow running listify and statify outside of /etc/elections and the repository dir.
Signed-off-by: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo.org>
listify | 7 +++++--
statify | 9 ++++++---
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/listify b/listify
index c8c24eb..7ca2bc3 100755
--- a/listify
+++ b/listify
@@ -8,11 +8,14 @@
#
BEGIN {
+ my $dirname;
if(-f '/etc/elections/Votify.pm') {
- push @INC, '/etc/elections';
+ $dirname = '/etc/elections';
} else {
- push @INC, '.' if -f 'Votify.pm';
+ use File::Basename;
+ $dirname = dirname(__FILE__);
}
+ push @INC, $dirname;
}
use POSIX;
diff --git a/statify b/statify
index c424696..a26a066 100755
--- a/statify
+++ b/statify
@@ -8,12 +8,15 @@
# statify: Produce early election statistics
#
-BEGIN {
+BEGIN {
+ my $dirname;
if(-f '/etc/elections/Votify.pm') {
- push @INC, '/etc/elections';
+ $dirname = '/etc/elections';
} else {
- push @INC, '.' if -f 'Votify.pm';
+ use File::Basename;
+ $dirname = dirname(__FILE__);
}
+ push @INC, $dirname;
}
use POSIX;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2016-07-03 11:04 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 44+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2016-07-03 11:04 UTC (permalink / raw
To: gentoo-commits
commit: d95697a5993e3af4618556703c1f388f569f2c8f
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Sun Jul 3 11:02:32 2016 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Sun Jul 3 11:02:32 2016 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=d95697a5
Allow running countify outside of /etc/elections and the repository dir.
Signed-off-by: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo.org>
countify | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/countify b/countify
index 1465da4..9f3e6f0 100755
--- a/countify
+++ b/countify
@@ -7,13 +7,15 @@
# countify: collect, tabulate and announce ballot results
#
-#BEGIN { push @INC, (getpwnam 'fox2mike')[7].'/elections' }
BEGIN {
+ my $dirname;
if(-f '/etc/elections/Votify.pm') {
- push @INC, '/etc/elections';
+ $dirname = '/etc/elections';
} else {
- push @INC, '.' if -f 'Votify.pm';
+ use File::Basename;
+ $dirname = dirname(__FILE__);
}
+ push @INC, $dirname;
}
use POSIX;
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2016-07-03 15:01 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2016-07-03 15:01 UTC (permalink / raw
To: gentoo-commits
commit: 6a7d8fab58c70a80175dc107178ee5dcac733adc
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sun Jul 3 15:01:33 2016 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sun Jul 3 15:01:33 2016 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=6a7d8fab
Votify: improve election base validation, and code documentation.
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
Votify.pm | 81 +++++++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 55 insertions(+), 26 deletions(-)
diff --git a/Votify.pm b/Votify.pm
index ed5b519..8e0fe1a 100644
--- a/Votify.pm
+++ b/Votify.pm
@@ -13,7 +13,10 @@ use Cwd qw(abs_path);
use File::Basename;
use File::Spec::Functions;
use List::Util;
+use Data::Dumper;
+use Carp::Always;
use strict;
+use warnings;
our $datefmt = '%Y-%m-%d %H:%M:%S UTC';
our ($basedir) = List::Util::first { -d $_ } ('/etc/elections', dirname(__FILE__));
@@ -27,42 +30,61 @@ sub import {
my @REQUIRED_FILES = qw(ballot officials start stop voters);
-sub get_datadir {
- my $election_name = shift;
+# Takes the name of an election and ensure it's validate under the basedir,
+# returning the full path to the election if valid, and undef if not valid.
+# Where valid is:
+# A directory containing ALL of the files in @REQUIRED_FILES, either either
+# their direct names, or the name of the election on the end of the files.
+# Eg 'ballot' or 'ballot-election1234'.
+sub validate_election_dir {
+ my $election_rawdir = shift;
+ return 0 unless defined $election_rawdir;
+ return 0 if substr($election_rawdir,0,1) eq ".";
+
+ my $election_name = $election_rawdir;
+ $election_name =~ s/.*\///;
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 "$basedir/$election_dir";
+ # Fail if it's not a directory in the basedir
+ return 0 unless -d $election_dir;
+
+ # Do not try to validate hidden directories.
return 0 if substr($election_name,0,1) eq ".";
- my $valid = List::Util::reduce {
- $a or $b ? 1 : 0;
- } map {
+
+ # Validate that the required files exist in the dir
+ # Part 1, convert the array to a map
+ my %REQUIRED_FILES_valid = map {
my $file_valid = 0;
# Legacy naming:
- $file_valid = 1 if -f sprintf("%s/%s-%s", "$basedir/$election_name", $_, $election_name);
+ $file_valid = 1 if -f sprintf("%s/%s-%s", $election_dir, $_, $election_name);
# New naming:
- $file_valid = 1 if -f sprintf("%s/%s", "$basedir/$election_name", $_);
+ $file_valid = 1 if -f sprintf("%s/%s", $election_dir, $_);
#printf "File %s valid=%d\n", $_, $file_valid;
- $file_valid;
+ ($_, $file_valid);
} @REQUIRED_FILES;
- return $valid;
+
+ # Part 2, ensure all of the map is true
+ my $valid = List::Util::reduce {
+ $a or $b ? 1 : 0;
+ } values(%REQUIRED_FILES_valid);
+
+ # Now return.
+ return $election_dir if $valid;
+ return undef;
}
sub get_elections_list {
my @elections;
opendir(D, $Votify::basedir) or die;
@elections = sort grep {
- my $valid = validate_election_dir(catfile($Votify::basedir, $_));
- $valid;
+ -d $_ and
+ $_ ne "." and
+ $_ ne ".." and
+ $_ ne "" and
+ substr($_, 0, 1) ne ".";
+ } grep {
+ my $valid_election_dir = validate_election_dir($_);
+ defined $valid_election_dir;
} readdir D;
closedir D;
return @elections;
@@ -84,7 +106,8 @@ sub grabfile_int {
sub get_single_election_hashref {
my $election_name = shift;
- my $election_dir = catfile($Votify::basedir, $election_name);
+ my $election_dir = validate_election_dir($election_name);
+ return undef unless defined $election_dir;
my %election;
foreach my $fn (@REQUIRED_FILES){
#print "Scan $fn\n";
@@ -101,7 +124,9 @@ sub get_single_election_hashref {
sub get_elections_hash {
my %elections;
- %elections = map { $_ => get_single_election_hashref($_) } get_elections_list();
+ my @elections_list = get_elections_list();
+ #print Dumper(\@elections_list);
+ %elections = map { $_ => get_single_election_hashref($_) } @elections_list;
return %elections;
}
@@ -151,11 +176,13 @@ sub officials {
######################################################################
package VoterList;
+use File::Spec::Functions;
sub new {
my ($class, $election_name) = @_;
my (@voterlist, $r);
- my $datadir = Votify::get_datadir($election_name);
+ my $datadir = Votify::validate_election_dir($election_name);
+ die "Unable to get election dir for name $election_name" unless defined $datadir;
my ($self) = {
election => $election_name,
default_filename => catfile($datadir, "confs-$election_name"),
@@ -230,10 +257,12 @@ sub write {
package MasterBallot;
use Data::Dumper;
+use File::Spec::Functions;
sub new {
my ($class, $election_name, $vl) = @_;
- my $datadir = Votify::get_datadir($election_name);
+ my $datadir = Votify::validate_election_dir($election_name);
+ die "Unable to get election dir for name $election_name" unless defined $datadir;
my ($self) = {
election => $election_name,
default_filename => catfile($datadir, "master-$election_name"),
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2016-07-21 18:07 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2016-07-21 18:07 UTC (permalink / raw
To: gentoo-commits
commit: 672613c1a37c84d7af4dc0d56b2df3a138ca5813
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Thu Jul 21 17:57:47 2016 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Thu Jul 21 17:57:47 2016 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=672613c1
Resolve symlinks to find the correct elections directory.
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
Votify.pm | 2 +-
countify | 5 +++--
listify | 5 +++--
statify | 5 +++--
votify | 5 +++--
5 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/Votify.pm b/Votify.pm
index 8e0fe1a..e09d279 100644
--- a/Votify.pm
+++ b/Votify.pm
@@ -19,7 +19,7 @@ use strict;
use warnings;
our $datefmt = '%Y-%m-%d %H:%M:%S UTC';
-our ($basedir) = List::Util::first { -d $_ } ('/etc/elections', dirname(__FILE__));
+our ($basedir) = List::Util::first { -d $_ } ('/etc/elections', dirname(abs_path(__FILE__)));
(our $zero = $0) =~ s,.*/,,;
our $version = '1.6';
diff --git a/countify b/countify
index 9f3e6f0..13618a4 100755
--- a/countify
+++ b/countify
@@ -12,8 +12,9 @@ BEGIN {
if(-f '/etc/elections/Votify.pm') {
$dirname = '/etc/elections';
} else {
- use File::Basename;
- $dirname = dirname(__FILE__);
+ use Cwd qw(abs_path);
+ use File::Basename qw(dirname);
+ $dirname = dirname(abs_path(__FILE__));
}
push @INC, $dirname;
}
diff --git a/listify b/listify
index 7ca2bc3..346f70a 100755
--- a/listify
+++ b/listify
@@ -12,8 +12,9 @@ BEGIN {
if(-f '/etc/elections/Votify.pm') {
$dirname = '/etc/elections';
} else {
- use File::Basename;
- $dirname = dirname(__FILE__);
+ use Cwd qw(abs_path);
+ use File::Basename qw(dirname);
+ $dirname = dirname(abs_path(__FILE__));
}
push @INC, $dirname;
}
diff --git a/statify b/statify
index a26a066..752c78d 100755
--- a/statify
+++ b/statify
@@ -13,8 +13,9 @@ BEGIN {
if(-f '/etc/elections/Votify.pm') {
$dirname = '/etc/elections';
} else {
- use File::Basename;
- $dirname = dirname(__FILE__);
+ use Cwd qw(abs_path);
+ use File::Basename qw(dirname);
+ $dirname = dirname(abs_path(__FILE__));
}
push @INC, $dirname;
}
diff --git a/votify b/votify
index 4fb688d..c34fed2 100755
--- a/votify
+++ b/votify
@@ -12,8 +12,9 @@ BEGIN {
if(-f '/etc/elections/Votify.pm') {
$dirname = '/etc/elections';
} else {
- use File::Basename;
- $dirname = dirname(__FILE__);
+ use Cwd qw(abs_path);
+ use File::Basename qw(dirname);
+ $dirname = dirname(abs_path(__FILE__));
}
push @INC, $dirname;
}
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2016-07-21 18:07 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2016-07-21 18:07 UTC (permalink / raw
To: gentoo-commits
commit: 374585264af6d60d48a89271e5e5b4fc7e66aded
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Thu Jul 21 17:58:24 2016 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Thu Jul 21 18:07:20 2016 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=37458526
get_elections_list: readwrite for readability and fix cwd bug
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
Votify.pm | 41 ++++++++++++++++++++++++++++++-----------
1 file changed, 30 insertions(+), 11 deletions(-)
diff --git a/Votify.pm b/Votify.pm
index e09d279..d53cfcb 100644
--- a/Votify.pm
+++ b/Votify.pm
@@ -75,19 +75,38 @@ sub validate_election_dir {
sub get_elections_list {
my @elections;
+
+ # Raw data:
opendir(D, $Votify::basedir) or die;
- @elections = sort grep {
- -d $_ and
- $_ ne "." and
- $_ ne ".." and
- $_ ne "" and
- substr($_, 0, 1) ne ".";
- } grep {
- my $valid_election_dir = validate_election_dir($_);
- defined $valid_election_dir;
- } readdir D;
+ @elections = readdir D;
closedir D;
- return @elections;
+
+ # Pass 1:
+ # Get rid of some definetly non-elections
+ @elections = grep {
+ my $state = List::Util::reduce { $a and $b } [
+ # All of these must be true:
+ -d(catfile($Votify::basedir, $_)),
+ ($_ ne "."), # Exclude current dir
+ ($_ ne ".."), # Exclude parent
+ ($_ ne ""), # Exclude bugs
+ substr($_, 0, 1) ne ".", # No hidden items
+ 1, # Fallback for when the items are commented out
+ ];
+ #printf "2: %s %d\n", $_, ($state);
+ $state;
+ } @elections;
+
+ # Pass 2:
+ # Full validation
+ @elections = grep {
+ my $valid_election_dir = validate_election_dir($_);
+ my $state = (defined $valid_election_dir) && $valid_election_dir;
+ #printf "1: validate_election_dir(%s) = %s, state=%d\n", $_, $valid_election_dir, $state;
+ $state;
+ } @elections;
+
+ return sort @elections;
}
sub grabfile_int {
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2017-06-24 23:54 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2017-06-24 23:54 UTC (permalink / raw
To: gentoo-commits
commit: b0c007c6048b687f3b4b1bfc9a489192e5e9f40e
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sat Jun 24 23:54:12 2017 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sat Jun 24 23:54:12 2017 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=b0c007c6
Votify: debug spam.
Use of uninitialized value in subroutine entry at /etc/elections/Votify.pm line 135.
Votify::get_single_election_hashref("council-201706") called at /etc/elections/Votify.pm line 148
Votify::get_elections_hash() called at /etc/elections/Votify.pm line 153
Votify::get_open_elections_hash() called at /etc/elections/election-stats-count line 41
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
Votify.pm | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Votify.pm b/Votify.pm
index d53cfcb..d24b8cb 100644
--- a/Votify.pm
+++ b/Votify.pm
@@ -129,10 +129,10 @@ sub get_single_election_hashref {
return undef unless defined $election_dir;
my %election;
foreach my $fn (@REQUIRED_FILES){
- #print "Scan $fn\n";
+ print STDERR "Scan $fn\n";
my @filenames = (sprintf("%s/%s", "$basedir/$election_name", $fn), sprintf("%s/%s-%s", "$basedir/$election_name", $fn, $election_name));
- #print Dumper(@filenames);
- my $filename = abs_path(List::Util::first { -f $_ } @filenames);
+ print STDERR Dumper(@filenames);
+ my $filename = abs_path(List::Util::first { $_ && -f $_ } @filenames);
$election{"${fn}file"} = $filename;
};
#print Dumper(%election);
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2017-06-25 0:04 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2017-06-25 0:04 UTC (permalink / raw
To: gentoo-commits
commit: 2433330ac00a69b6960746cd6bd2c4fce490626b
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sun Jun 25 00:04:04 2017 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sun Jun 25 00:04:04 2017 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=2433330a
Votify: undef fixed, disable debug
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
Votify.pm | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Votify.pm b/Votify.pm
index d24b8cb..87fba2f 100644
--- a/Votify.pm
+++ b/Votify.pm
@@ -129,9 +129,9 @@ sub get_single_election_hashref {
return undef unless defined $election_dir;
my %election;
foreach my $fn (@REQUIRED_FILES){
- print STDERR "Scan $fn\n";
+ #print STDERR "Scan $fn\n";
my @filenames = (sprintf("%s/%s", "$basedir/$election_name", $fn), sprintf("%s/%s-%s", "$basedir/$election_name", $fn, $election_name));
- print STDERR Dumper(@filenames);
+ #print STDERR Dumper(@filenames);
my $filename = abs_path(List::Util::first { $_ && -f $_ } @filenames);
$election{"${fn}file"} = $filename;
};
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2020-06-20 5:17 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2020-06-20 5:17 UTC (permalink / raw
To: gentoo-commits
commit: 533bedb17bdf5ad652cca631574537d356a5901a
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sat Jun 20 05:11:15 2020 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sat Jun 20 05:11:15 2020 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=533bedb1
README: braindump of the entire election process
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
README | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 91 insertions(+)
diff --git a/README b/README
index 7dee785..45490f5 100644
--- a/README
+++ b/README
@@ -21,3 +21,94 @@ listify: generate text to include in MOTD
election-stats-count: generate turnout stats for ongoing elections, for
election officials to review an election in progress (put it in a cronjob,
needs root).
+
+Instructions
+------------
+1. Setup an election:
+---------------------
+To create a new election, make a top-level directory with the exact name of
+the election. Usually in the format of `{council,trustees}-YYYYMM`.
+Let ${election_name} be the name of the election. Any member of the elections
+project or infra may set this up.
+
+- `Votify.pm`: symlink to ../Votify.pm for tooling
+- `ballot-${election_name}`
+ One entry per line, in alphabetical order.
+ The special candidate `_reopen_nominations` is valid in some elections.
+ The ballot order will be randomized per candidate, at voting time.
+- `election-details`:
+ key-value file with details about the election.
+ `name`: exact election name
+ `startDate`, `endDate`: start & end time in UTC
+ `officials`: election officials (prohibited from being candidates)
+ `voters`: URL to list of members who may cast a ballot
+ `ballot`: URL to sample ballot
+- `officials-${election_name}`: list of election officials
+- `start-${election_name}`: election start time, as epoch seconds.
+- `stop-${election_name}`: election end time, as epoch seconds.
+- `voters-${election_name}`: list of members who may cast a ballot
+
+Populate the files, commit & push to Git. At the start time, an official
+should verify that the ballot works. Ideally a non-infra official, who then
+confirms to the infra election handler it worked.
+
+2.1. Let people vote:
+-------------------
+The regular way is to login to `dev.gentoo.org` and run `votify`.
+
+2.2. Handle special ballots:
+--------------------------
+Some elections may have voters who cast ballots by irregular means: they
+should be accepted only via GPG-signed email to the election officials, who
+should agree that the signature is valid and matches a key that was already on
+a list prior to the election. The infra contact should place the ballot in
+`dev.gentoo.org:/home/$membername/.ballot-${election_name}-submitted`
+
+The elections mechanisms make no provision for truely secret ballot: election
+officials WILL see the content of the ballot.
+
+This is primarily a requirement for the Trustees election, which accepts
+ballots from all Foundation members. The roll of Foundation members includes
+active developers, retired developers, and other applicants to the Foundation
+Trustees.
+
+3. Wait:
+--------
+Just wait. `election-stats-count` runs every 30 minutes by cronjob, and prints
+status files into the home directories of election officials: `voter-turnout-${election_name}`.
+
+4. Close of election:
+---------------------
+This is where the infra contact is absolutely required.
+The infra contact must run `countify --collect` as root, which will write
+the master ballot & confirmation stub file to all officials.
+
+5. Verify results:
+------------------
+Each election official should verify the results to collectively certify the
+results. This requires `countify --rank` to transform the master ballot into
+results.
+
+6. Email conf stubs:
+--------------------
+ONE election official should use the mail-voters scripts to send confirmation
+stubs to each eligable voter. Note that this is ALL eligable voters, and not
+just those that cast a ballot.
+
+7. Announce results:
+--------------------
+The collected election officials should announce results; The email should
+include the output of `countify --rank`, as well as the master ballot for
+independent verification.
+
+8. Cleanup:
+-----------
+- The master ballot must be committed to git. This file is named
+ `master-${election_name}`
+- This list of voters who cast a ballot should be recorded & committed.
+ This is required to purge rolls of inactive voters in some cases (Foundation
+ members are required to vote at least every 2nd election if they are not an
+ active developer). This file must be named `casting-voters-${election_name}`
+- The confirmation stub file should be destroyed after the election results
+ have been formally accepted, to make de-anonymizing the ballots harder.
+- Lastly, `git mv` the election directory into the `completed/` directory.
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2020-06-20 5:17 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2020-06-20 5:17 UTC (permalink / raw
To: gentoo-commits
commit: 0e626c77be9a8e2ba2d05ebf1cc3c242a65e980f
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sat Jun 20 05:10:51 2020 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sat Jun 20 05:10:51 2020 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=0e626c77
gitignore: try to block confs from being committed
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
.gitignore | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f013bcc
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+# The confirmation stubs should never be distributed.
+**/confs-*
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2020-07-06 5:10 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2020-07-06 5:10 UTC (permalink / raw
To: gentoo-commits
commit: 77b3e54d957ff7d31845f84b835adea0995c8fd5
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Mon Jul 6 05:10:24 2020 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Mon Jul 6 05:10:24 2020 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=77b3e54d
README: improve countify instructions
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
README | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/README b/README
index 45490f5..0d3c8e6 100644
--- a/README
+++ b/README
@@ -80,14 +80,27 @@ status files into the home directories of election officials: `voter-turnout-${e
4. Close of election:
---------------------
This is where the infra contact is absolutely required.
-The infra contact must run `countify --collect` as root, which will write
-the master ballot & confirmation stub file to all officials.
+The infra contact must run `countify --collect ${election_name}` as root, which will write
+the master ballot & confirmation stub file to all officials:
+```
+$ sudo su
+# cd /etc/elections
+# ./countify --collect ${election_name}
+# find /home/${official}/results-${election_name}/
+/home/${official}/results-${election_name}/master-${election_name}
+/home/${official}/results-${election_name}/confs-${election_name}
+```
5. Verify results:
------------------
Each election official should verify the results to collectively certify the
results. This requires `countify --rank` to transform the master ballot into
results.
+```
+$ cd /home/${official}/results-${election_name}
+$ countify --rank
+(election output)
+```
6. Email conf stubs:
--------------------
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2021-06-18 6:57 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2021-06-18 6:57 UTC (permalink / raw
To: gentoo-commits
commit: 247f865bf13016731beed5e2254c2528f971c763
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Fri Jun 18 06:55:14 2021 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Fri Jun 18 06:55:19 2021 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=247f865b
README.md: refresh docs
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
README => README.md | 61 ++++++++++++++++++++++++++++++++++-------------------
1 file changed, 39 insertions(+), 22 deletions(-)
diff --git a/README b/README.md
similarity index 64%
rename from README
rename to README.md
index 0d3c8e6..a59ed18 100644
--- a/README
+++ b/README.md
@@ -2,23 +2,24 @@ Gentoo Elections
----------------
Welcome to the Gentoo Elections codebase.
-This handles all elections in Gentoo per the Elections project [1].
+
+This handles all elections per the [Gentoo Elections](https://wiki.gentoo.org/wiki/Project:Elections) project.
The Condercet system is used, and most of this repository exists just to house
the actual data needed to run each election, such as the start/stop time,
eligable voters, blank ballot etc.
-Completed elections are available in the completed/ directory.
+Completed elections are available in the `completed/` directory.
The codebase is meant to be checked out somewhere read-only (Gentoo
-Infrastructure uses /etc/elections/), with the votify & countify scripts
-symlinked into somewhere used by $PATH for normal users (eg /usr/local/bin).
+Infrastructure uses `/etc/elections/`), with the `votify` & `countify` scripts
+symlinked into somewhere used by $PATH for normal users (eg `/usr/local/bin`).
-Listify & election-stats-count are other helpful tools.
+`listify` & `election-stats-count` are other helpful tools.
-listify: generate text to include in MOTD
+- `listify`: generate text to include in MOTD
-election-stats-count: generate turnout stats for ongoing elections, for
+- `election-stats-count`: generate turnout stats for ongoing elections, for
election officials to review an election in progress (put it in a cronjob,
needs root).
@@ -28,14 +29,15 @@ Instructions
---------------------
To create a new election, make a top-level directory with the exact name of
the election. Usually in the format of `{council,trustees}-YYYYMM`.
-Let ${election_name} be the name of the election. Any member of the elections
+
+Let `${election_name}` be the name of the election. Any member of the elections
project or infra may set this up.
-- `Votify.pm`: symlink to ../Votify.pm for tooling
+- `Votify.pm`: symlink to `../Votify.pm` for tooling
- `ballot-${election_name}`
One entry per line, in alphabetical order.
The special candidate `_reopen_nominations` is valid in some elections.
- The ballot order will be randomized per candidate, at voting time.
+ The ballot order will be randomized per candidate, at voting time.
- `election-details`:
key-value file with details about the election.
`name`: exact election name
@@ -52,6 +54,12 @@ Populate the files, commit & push to Git. At the start time, an official
should verify that the ballot works. Ideally a non-infra official, who then
confirms to the infra election handler it worked.
+The URLs may link to either of two repos for the data:
+- `sites/projects/elections.git`, which populates:
+ `https://projects.gentoo.org/elections/TYPE/YYYY/...`
+- `projects/elections.git` (this repo), which is only visible on Gitweb:
+ https://gitweb.gentoo.org/proj/elections.git/
+
2.1. Let people vote:
-------------------
The regular way is to login to `dev.gentoo.org` and run `votify`.
@@ -79,9 +87,9 @@ status files into the home directories of election officials: `voter-turnout-${e
4. Close of election:
---------------------
-This is where the infra contact is absolutely required.
-The infra contact must run `countify --collect ${election_name}` as root, which will write
-the master ballot & confirmation stub file to all officials:
+This is the only step where the infra contact is absolutely required.
+The infra contact must run `countify --collect ${election_name}` as root,
+which will write the master ballot & confirmation stub file to all officials:
```
$ sudo su
# cd /etc/elections
@@ -98,7 +106,7 @@ results. This requires `countify --rank` to transform the master ballot into
results.
```
$ cd /home/${official}/results-${election_name}
-$ countify --rank
+$ countify --rank | tee ranked-${election_name}
(election output)
```
@@ -116,12 +124,21 @@ independent verification.
8. Cleanup:
-----------
-- The master ballot must be committed to git. This file is named
- `master-${election_name}`
-- This list of voters who cast a ballot should be recorded & committed.
- This is required to purge rolls of inactive voters in some cases (Foundation
- members are required to vote at least every 2nd election if they are not an
- active developer). This file must be named `casting-voters-${election_name}`
-- The confirmation stub file should be destroyed after the election results
- have been formally accepted, to make de-anonymizing the ballots harder.
+- The following files must be commited to `proj/elections.git` repo.
+ - `master-${election_name}`
+ - `casting-voters-${election_name}`
+ - `ranked-${election_name}`
+- The some files should also be copied with renames into the
+ `sites/projects/elections.git` repo as follows:
+ - `ballot-${election_name}` -> `ballot-${election_name}.txt`
+ - `master-${election_name}` -> `master-${election_name}.txt`
+ - `ranked-${election_name}` -> `${election_name}-results.txt`
+ - `voters-${election_name}.txt` -> `voters-${election_name}.txt`
+- `casting-voters-${election_name}` is a list of voters who cast a ballot, and
+ needs to be recorded. This is required to purge rolls of inactive voters in
+ some cases (Foundation members are required to vote at least every 2nd
+ election if they are not an active developer).
+- The confirmation stub file `confs-${election_name}` MUST be destroyed after
+ the election results have been formally accepted, to make de-anonymizing the
+ ballots harder.
- Lastly, `git mv` the election directory into the `completed/` directory.
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2021-06-18 6:57 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2021-06-18 6:57 UTC (permalink / raw
To: gentoo-commits
commit: 8e9679101b638f65af8be2e034263efed09bf22e
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Fri Jun 18 06:56:42 2021 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Fri Jun 18 06:56:42 2021 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=8e967910
Votify: improvements from re-using the codebase for another project
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
Votify.pm | 49 +++++++++++++++++++++++++++++++++++--------------
countify | 19 +++++++++++++------
2 files changed, 48 insertions(+), 20 deletions(-)
diff --git a/Votify.pm b/Votify.pm
index 87fba2f..35a717f 100644
--- a/Votify.pm
+++ b/Votify.pm
@@ -8,13 +8,13 @@
package Votify;
-use POSIX;
+use Carp::Always;
use Cwd qw(abs_path);
+use Data::Dumper;
use File::Basename;
use File::Spec::Functions;
use List::Util;
-use Data::Dumper;
-use Carp::Always;
+use POSIX;
use strict;
use warnings;
@@ -218,8 +218,8 @@ sub new {
close(F);
# assign confirmation numbers randomly
- for my $v (@voterlist) {
- do { $r = int rand 0xffff } while exists $self->{'voters'}{$r};
+ for my $v (List::Util::shuffle(@voterlist)) {
+ do { $r = int rand 0xffffffff } while exists $self->{'voters'}{$r};
$self->{'voters'}{$r} = $v;
$self->{'confs'}{$v} = $r;
}
@@ -239,7 +239,7 @@ sub confs {
sub voters {
my ($self) = @_;
- sort keys %{$self->{'confs'}};
+ return sort keys %{$self->{'confs'}};
}
sub getvoter {
@@ -252,7 +252,7 @@ sub getconf {
return $self->{'confs'}{$voter};
}
-sub write {
+sub write_confs {
my ($self, $filename) = @_;
$filename ||= $self->{'default_filename'};
@@ -263,8 +263,8 @@ sub write {
}
open(F, ">$filename") or die("can't write to $filename");
- for my $c ($self->confs) {
- printf F "%04x %s\n", $c, $self->getvoter($c);
+ for my $c (sort { $a <=> $b } map { int $_ } $self->confs) {
+ printf F "%08x %s\n", $c, $self->getvoter($c);
}
close F;
}
@@ -287,6 +287,7 @@ sub new {
default_filename => catfile($datadir, "master-$election_name"),
filename => '',
voterlist => $vl,
+ casting_voters => {}, # indexed by voter
ballots => {}, # indexed by conf num
candidates => undef, # indexed by long name
table => undef, # indexed by row+column
@@ -326,6 +327,7 @@ sub collect {
next;
}
$self->{'ballots'}{$c} = $b;
+ $self->{'casting_voters'}{$v} = 1;
}
elsif (-f "$home/.ballot-$self->{election}") {
print STDERR "Warning: $v did not submit their ballot\n";
@@ -333,7 +335,7 @@ sub collect {
}
}
-sub write {
+sub write_master {
my ($self, $filename) = @_;
$filename ||= $self->{'default_filename'};
@@ -344,14 +346,15 @@ sub write {
}
open(F, ">$filename") or die("can't write to $filename");
- for my $c (sort keys %{$self->{'ballots'}}) {
- printf F "--------- confirmation %04x ---------\n", $c;
+ for my $c (sort { $a <=> $b } map { int $_ } keys %{$self->{'ballots'}}) {
+ my $confid = sprintf("%08x",$c);
+ printf F "--------- confirmation %s ---------\n", $confid;
print F $self->{'ballots'}{$c}->to_s
}
close F;
}
-sub read {
+sub read_master {
my ($self, $filename) = @_;
my ($election, $entries) = $self->{'election'};
@@ -362,7 +365,7 @@ sub read {
{ local $/ = undef; $entries = <F>; }
for my $e (split /^--------- confirmation /m, $entries) {
next unless $e; # skip the first zero-length record
- unless ($e =~ /^([[:xdigit:]]{4}) ---------\n(.*)$/s) {
+ unless ($e =~ /^([[:xdigit:]]{4,12}) ---------\n(.*)$/s) {
die "error parsing entry:\n$e";
}
my ($c, $s, $b) = ($1, $2, Ballot->new($election));
@@ -371,6 +374,24 @@ sub read {
}
}
+sub write_casting_voters {
+ my ($self, $filename) = @_;
+
+ $filename ||= $self->{'default_filename'};
+ $self->{'filename'} = $filename;
+
+ if (-f $filename) {
+ die "$filename already exists; please remove it first";
+ }
+
+ open(F, ">$filename") or die("can't write to $filename");
+ for my $v (sort keys %{$self->{'casting_voters'}}) {
+ printf F "%s\n", $v;
+ }
+ close F;
+}
+
+
sub generate_candidates {
my ($self) = @_;
my ($B, @C, $s);
diff --git a/countify b/countify
index 13618a4..cf31d69 100755
--- a/countify
+++ b/countify
@@ -19,9 +19,13 @@ BEGIN {
push @INC, $dirname;
}
-use POSIX;
+use Cwd qw(abs_path);
+use File::Basename;
+use File::Spec::Functions;
use Getopt::Long;
use List::Util;
+use POSIX;
+
use Votify 'official';
use strict;
@@ -94,12 +98,15 @@ if ($opt{'collect'}) {
$master->collect($vl->voters);
for my $o ($ol->officials) {
my ($uid, $home) = (getpwnam $o)[2,7];
- mkdir "$home/results-$election";
- $master->write("$home/results-$election/master-$election");
- $vl->write("$home/results-$election/confs-$election");
+ $home = "/home/$o" unless defined $home;
+ mkdir catfile("$home", "results-$election");
+ $master->write_master("$home/results-$election/master-$election");
+ $master->write_casting_voters("$home/results-$election/casting-voters-$election");
+ $vl->write_confs("$home/results-$election/confs-$election");
chown $uid, -1, "$home/results-$election",
"$home/results-$election/master-$election",
- "$home/results-$election/confs-$election";
+ "$home/results-$election/confs-$election",
+ "$home/results-$election/casting-voters-$election";
}
exit 0;
}
@@ -107,7 +114,7 @@ if ($opt{'collect'}) {
if ($opt{'rank'}) {
my ($master) = MasterBallot->new($election, $vl);
my (@candidates, @winner, @ranked, @ranks);
- $master->read("$ENV{HOME}/results-$election/master-$election");
+ $master->read_master("$ENV{HOME}/results-$election/master-$election");
$master->generate_candidates();
@candidates = sort keys %{$master->{'candidates'}};
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2022-06-25 13:58 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 44+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2022-06-25 13:58 UTC (permalink / raw
To: gentoo-commits
commit: 41a51364e07db18d5e7e32bf33f40e57962b43f3
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Sat Jun 25 13:58:10 2022 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Sat Jun 25 13:58:10 2022 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=41a51364
Drop patch from repo.
Signed-off-by: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo.org>
votify-print.patch | 19 -------------------
1 file changed, 19 deletions(-)
diff --git a/votify-print.patch b/votify-print.patch
deleted file mode 100644
index 2055ba1..0000000
--- a/votify-print.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-diff --git a/Votify.pm b/Votify.pm
-index 8e0fe1a..d8c7d22 100644
---- a/Votify.pm
-+++ b/Votify.pm
-@@ -84,9 +84,14 @@ sub get_elections_list {
- substr($_, 0, 1) ne ".";
- } grep {
- my $valid_election_dir = validate_election_dir($_);
-+ print "$_ is a valid_election_dir\n" if defined $valid_election_dir;
- defined $valid_election_dir;
- } readdir D;
- closedir D;
-+ print "These are the contents of the elections array:\n";
-+ foreach (@elections) {
-+ print "$_\n";
-+ }
- return @elections;
- }
-
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2022-06-25 16:31 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2022-06-25 16:31 UTC (permalink / raw
To: gentoo-commits
commit: fe4e279fb5adbb90e780dc13d1c7db9e94737d20
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sat Jun 25 16:29:10 2022 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sat Jun 25 16:31:03 2022 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=fe4e279f
statify: fix chown
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
statify | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/statify b/statify
index 752c78d..b7c9396 100755
--- a/statify
+++ b/statify
@@ -108,14 +108,15 @@ for my $election_name (keys %open_elections) {
.sprintf("Pending Turnout: %02.3f%%\n", ($count_submit+$count_pending)*100.0/$count_voters);
print "$results_buffer\n";
- umask 057;
+ umask 077;
for my $officialname (@officials) {
my $fn = catfile('/home', $officialname, 'voter-turnout-'.$election_name);
open(F, '>', $fn) or
die("failed to open voter turnout file ($fn): $!");
print F $results_buffer;
close F;
- chown ((getpwnam($officialname))[2]), 0, ($fn) or
+ my $uid = (getpwnam($officialname))[2];
+ chown($uid, -1, $fn) or
die("failed to chown voter turnout file ($fn): $!");
}
}
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2022-06-30 22:36 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2022-06-30 22:36 UTC (permalink / raw
To: gentoo-commits
commit: 9629cf285e461313b68438ecc4f6a25532c0c137
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Thu Jun 30 22:36:10 2022 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Thu Jun 30 22:36:10 2022 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=9629cf28
Votify: accept symlinks as well as files
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
Votify.pm | 20 ++++++++++++--------
statify | 4 ++--
2 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/Votify.pm b/Votify.pm
index 35a717f..db311ea 100644
--- a/Votify.pm
+++ b/Votify.pm
@@ -56,9 +56,9 @@ sub validate_election_dir {
my %REQUIRED_FILES_valid = map {
my $file_valid = 0;
# Legacy naming:
- $file_valid = 1 if -f sprintf("%s/%s-%s", $election_dir, $_, $election_name);
+ $file_valid = 1 if -r sprintf("%s/%s-%s", $election_dir, $_, $election_name);
# New naming:
- $file_valid = 1 if -f sprintf("%s/%s", $election_dir, $_);
+ $file_valid = 1 if -r sprintf("%s/%s", $election_dir, $_);
#printf "File %s valid=%d\n", $_, $file_valid;
($_, $file_valid);
} @REQUIRED_FILES;
@@ -132,7 +132,7 @@ sub get_single_election_hashref {
#print STDERR "Scan $fn\n";
my @filenames = (sprintf("%s/%s", "$basedir/$election_name", $fn), sprintf("%s/%s-%s", "$basedir/$election_name", $fn, $election_name));
#print STDERR Dumper(@filenames);
- my $filename = abs_path(List::Util::first { $_ && -f $_ } @filenames);
+ my $filename = abs_path(List::Util::first { $_ && -r $_ && -s $_ && ! -d $_ } @filenames);
$election{"${fn}file"} = $filename;
};
#print Dumper(%election);
@@ -258,7 +258,7 @@ sub write_confs {
$filename ||= $self->{'default_filename'};
$self->{'filename'} = $filename;
- if (-f $filename) {
+ if (-e $filename) {
die "$filename already exists; please remove it first";
}
@@ -319,7 +319,11 @@ sub collect {
next;
}
- if (-f "$home/.ballot-$self->{election}-submitted") {
+ my $submitted_filename = "$home/.ballot-$self->{election}-submitted";
+ if (-d $submitted_filename) {}
+ print STDERR "Warning: $v has a directory instead of a ballot\n";
+ }
+ elsif (-e $submitted_filename && -r $submitted_filename) {
my ($b) = Ballot->new($self->{'election'});
$b->read("$home/.ballot-$self->{election}-submitted");
if ($b->verify) {
@@ -329,7 +333,7 @@ sub collect {
$self->{'ballots'}{$c} = $b;
$self->{'casting_voters'}{$v} = 1;
}
- elsif (-f "$home/.ballot-$self->{election}") {
+ elsif (-e "$home/.ballot-$self->{election}") {
print STDERR "Warning: $v did not submit their ballot\n";
}
}
@@ -341,7 +345,7 @@ sub write_master {
$filename ||= $self->{'default_filename'};
$self->{'filename'} = $filename;
- if (-f $filename) {
+ if (-e $filename) {
die "$filename already exists; please remove it first";
}
@@ -380,7 +384,7 @@ sub write_casting_voters {
$filename ||= $self->{'default_filename'};
$self->{'filename'} = $filename;
- if (-f $filename) {
+ if (-e $filename) {
die "$filename already exists; please remove it first";
}
diff --git a/statify b/statify
index b7c9396..0cccff1 100755
--- a/statify
+++ b/statify
@@ -86,9 +86,9 @@ for my $election_name (keys %open_elections) {
my ($count_voters, $count_submit, $count_pending) = (0, 0,0);
for my $votername (@voters) {
$count_voters++;
- if(-f catfile('/home', $votername, ".ballot-${election_name}-submitted")) {
+ if(-e catfile('/home', $votername, ".ballot-${election_name}-submitted")) {
$count_submit++;
- } elsif (-f catfile('/home', $votername, ".ballot-${election_name}")) {
+ } elsif (-e catfile('/home', $votername, ".ballot-${election_name}")) {
$count_pending++;
}
}
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2022-07-01 15:50 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2022-07-01 15:50 UTC (permalink / raw
To: gentoo-commits
commit: 3b7342b8b037c9d7e240a06f68943456fcda1491
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Fri Jul 1 15:50:47 2022 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Fri Jul 1 15:50:47 2022 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=3b7342b8
Votify: editor fail
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
Votify.pm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Votify.pm b/Votify.pm
index db311ea..6f73954 100644
--- a/Votify.pm
+++ b/Votify.pm
@@ -320,7 +320,7 @@ sub collect {
}
my $submitted_filename = "$home/.ballot-$self->{election}-submitted";
- if (-d $submitted_filename) {}
+ if (-d $submitted_filename) {
print STDERR "Warning: $v has a directory instead of a ballot\n";
}
elsif (-e $submitted_filename && -r $submitted_filename) {
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2022-07-01 19:12 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2022-07-01 19:12 UTC (permalink / raw
To: gentoo-commits
commit: 6fb33c7d84a6e9fefe03ec6b0af77a01eaf1d421
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Fri Jul 1 19:12:46 2022 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Fri Jul 1 19:12:46 2022 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=6fb33c7d
infra-schedule-countify-collect: new tool to schedule countify --collect
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
README.md | 20 +++++++++++++++++--
infra-schedule-countify-collect | 44 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 62 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index a59ed18..1afdba0 100644
--- a/README.md
+++ b/README.md
@@ -85,8 +85,24 @@ Trustees.
Just wait. `election-stats-count` runs every 30 minutes by cronjob, and prints
status files into the home directories of election officials: `voter-turnout-${election_name}`.
-4. Close of election:
----------------------
+4.a. Automated "Close of election"
+----------------------------------
+Before the end of the election, run the script to schedule automated
+`countify --collect`:
+```
+$ sudo su
+# cd /etc/elections
+# ./infra-schedule-countify-collect ${election_name}
+````
+
+The job can be verified with:
+```
+# atq
+# at -c $JOB_ID
+```
+
+4.b. Manual "Close of election"
+-------------------------------
This is the only step where the infra contact is absolutely required.
The infra contact must run `countify --collect ${election_name}` as root,
which will write the master ballot & confirmation stub file to all officials:
diff --git a/infra-schedule-countify-collect b/infra-schedule-countify-collect
new file mode 100755
index 0000000..f44f343
--- /dev/null
+++ b/infra-schedule-countify-collect
@@ -0,0 +1,44 @@
+#!/bin/bash
+# This will schedule an at(1) job to run for countify --collect
+# Any special ballots must be in place before the end of the election.
+# Infra needs to run this script, and it will schedule the rest, so infra does
+# NOT need to be on hand at the end closing time.
+election_name=$1
+
+UID=$(id -u)
+if test $UID -ne 0; then
+ echo "You must be root to run this" 1>&2
+ exit 1
+fi
+
+# Find the dir, validate
+for d in /etc/elections/$election_name ./$election_name ; do
+ files=( start stop voters ballot officials )
+ good=1
+ for f in ${files[@]}; do
+ test -e $d/${f}-$election_name || good=0
+ done
+ if test $good -eq 1 ; then
+ export election_dir=$d
+ break
+ fi
+ unset good
+done
+
+if test -z "$election_dir" ; then
+ echo "Could not find election $election_name in /etc/elections" 1>&2
+ exit 1
+fi
+
+stopfile=$election_dir/stop-$election_name
+t=$(date -u +%Y%m%d%H%M.%S -d @$(<$stopfile) )
+
+cd /etc/elections
+unset MAIL PWD SSH_CLIENT SSH_CONNECTION SSH_TTY
+
+at -t $t <<-EOF
+#!/bin/sh
+# This was scheduled by $SUDO_USER at $(date -uR)
+cd /etc/elections
+./countify --collect ${election_name}
+EOF
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2023-04-19 22:28 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2023-04-19 22:28 UTC (permalink / raw
To: gentoo-commits
commit: ca7e83173e09bafdb5763df6fd50cec499b14a85
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Wed Apr 19 22:27:50 2023 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Wed Apr 19 22:27:50 2023 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=ca7e8317
Votify: handle empty control files, e.g. empty voters
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
Votify.pm | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Votify.pm b/Votify.pm
index 6f73954..49f21da 100644
--- a/Votify.pm
+++ b/Votify.pm
@@ -132,8 +132,9 @@ sub get_single_election_hashref {
#print STDERR "Scan $fn\n";
my @filenames = (sprintf("%s/%s", "$basedir/$election_name", $fn), sprintf("%s/%s-%s", "$basedir/$election_name", $fn, $election_name));
#print STDERR Dumper(@filenames);
- my $filename = abs_path(List::Util::first { $_ && -r $_ && -s $_ && ! -d $_ } @filenames);
- $election{"${fn}file"} = $filename;
+ my $filename = List::Util::first { $_ && -r $_ && -s $_ && ! -d $_ } @filenames;
+ my $absfilename = abs_path($filename) if $filename;
+ $election{"${fn}file"} = $absfilename if $absfilename;
};
#print Dumper(%election);
$election{starttime} = grabfile_int($election{'startfile'});
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2024-05-25 17:14 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2024-05-25 17:14 UTC (permalink / raw
To: gentoo-commits
commit: f07952719a64905acf2face8ed2989a19edbcd9c
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sat May 25 17:02:48 2024 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sat May 25 17:02:48 2024 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=f0795271
README: improve details about infra steps
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
README.md | 25 +++++++++++++++++++------
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/README.md b/README.md
index 856b1f9..9cd9ec1 100644
--- a/README.md
+++ b/README.md
@@ -69,12 +69,14 @@ The URLs may link to either of two repos for the data:
-------------------
The regular way is to login to `dev.gentoo.org` and run `votify`.
-2.2. Handle special ballots:
---------------------------
+2.2. Handle special ballots (optional)
+--------------------------------------
+This step requires an infra contact.
+
Some elections may have voters who cast ballots by irregular means: they
should be accepted only via GPG-signed email to the election officials, who
should agree that the signature is valid and matches a key that was already on
-a list prior to the election. The infra contact should place the ballot in
+a list prior to the election. The infra contact must place the ballot in
`dev.gentoo.org:/home/$membername/.ballot-${election_name}-submitted`
The elections mechanisms make no provision for truely secret ballot: election
@@ -90,10 +92,15 @@ Trustees.
Just wait. `election-stats-count` runs every 30 minutes by cronjob, and prints
status files into the home directories of election officials: `voter-turnout-${election_name}`.
+
+4. Close of election:
+---------------------
+This is the only step where the infra contact is absolutely required.
+
4.a. Automated "Close of election"
----------------------------------
-Before the end of the election, run the script to schedule automated
-`countify --collect`:
+Before the end of the election, the infra contact must run the script to schedule
+automated `countify --collect`:
```
$ sudo su
# cd /etc/elections
@@ -106,9 +113,15 @@ The job can be verified with:
# at -c $JOB_ID
```
+If the election closing time is modified, the old job MUST be deleted before
+the automated collection executes.
+```
+# atq
+# atrm $JOB_ID
+```
+
4.b. Manual "Close of election"
-------------------------------
-This is the only step where the infra contact is absolutely required.
The infra contact must run `countify --collect ${election_name}` as root,
which will write the master ballot & confirmation stub file to all officials:
```
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [gentoo-commits] proj/elections:master commit in: /
@ 2024-06-02 0:13 Robin H. Johnson
0 siblings, 0 replies; 44+ messages in thread
From: Robin H. Johnson @ 2024-06-02 0:13 UTC (permalink / raw
To: gentoo-commits
commit: 41002dc5a2d784967053a34de70c3ebe9578c3b4
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sun Jun 2 00:09:11 2024 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sun Jun 2 00:11:41 2024 +0000
URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=41002dc5
build: make it easier to start a new election
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
README.md | 37 +++++++++++++++---------
Votify.pm | 5 ++--
election-details.template | 8 +++++
populate-election.sh | 74 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 108 insertions(+), 16 deletions(-)
diff --git a/README.md b/README.md
index 9cd9ec1..a61f1a0 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ This handles all elections per the [Gentoo Elections](https://wiki.gentoo.org/wi
The Condercet system is used, and most of this repository exists just to house
the actual data needed to run each election, such as the start/stop time,
-eligable voters, blank ballot etc.
+eligible voters, blank ballot etc.
Completed elections are available in the `completed/` directory.
@@ -28,32 +28,43 @@ Instructions
1. Setup an election:
---------------------
To create a new election, make a top-level directory with the exact name of
-the election. Usually in the format of `{council,trustees}-YYYYMM`.
+the election. Usually in the format of `{council,trustees}-YYYYMM`. All of the
+following files should be in that directory.
Let `${election_name}` be the name of the election. Any member of the elections
project or infra may set this up.
-- `Votify.pm`: symlink to `../Votify.pm` for tooling
-- `ballot-${election_name}`
- One entry per line, in alphabetical order.
- The special candidate `_reopen_nominations` is valid in some elections.
- The ballot order will be randomized per candidate, at voting time.
- `election-details`:
- key-value file with details about the election.
+ key-value file with details about the election, see `election-details.template`
`name`: exact election name
`startDate`, `endDate`: start & end time in UTC
- `officials`: election officials, including the infra contact, (prohibited from being candidates)
+ `officials`: election officials, including the infra contact (prohibited from being candidates)
`voters`: URL to list of members who may cast a ballot
`ballot`: URL to sample ballot
+ `url`: URL to the Elections page for this specific election (optional, newer)
+
+Using the above file, and the `populate-election.sh` script, the remaining
+files are created (pulling from URLs as needed.)
+
+- `Votify.pm`: symlink to `../Votify.pm` for tooling
+- `ballot-${election_name}`
+ One entry per line, in alphabetical order.
+ The special candidate `_reopen_nominations` is valid in some elections.
+ The ballot order will be randomized per candidate, at voting time.
- `officials-${election_name}`: list of election officials, including the infra contact
- `start-${election_name}`: election start time, as epoch seconds.
- `stop-${election_name}`: election end time, as epoch seconds.
- `voters-${election_name}`: list of members who may cast a ballot
-For developers, the one liner, worked example below, run on woodpecker, works.
-ldapsearch -ZZ -x -D uid=neddyseagoon,ou=devs,dc=gentoo,dc=org -W '(&(gentooStatus=active)(!(gentooAccess=infra-system.group)))' uid gentoojoin -LLL | grep "^uid" | sed -e "s/^uid: //" | sort -n > voters-council-202306.txt
-Some fine tuning to remove developers added to roll call after the cut off
-may be required.
+For developers, the one liner, worked example below, run on woodpecker, can create the `voters` file.
+```
+ldapsearch -ZZ -x -w '' -S uid -LLL \
+ '(&(gentooStatus=active)(!(gentooAccess=infra-system.group)))' \
+ uid gentoojoin \
+ |awk -F ': ' '/uid:/ {print $2}' > voters-council-202406
+```
+Some fine tuning to remove developers added to roll call after the cut off
+may be required.
Populate the files, commit & push to Git. At the start time, an official
should verify that the ballot works. Ideally a non-infra official, who then
diff --git a/Votify.pm b/Votify.pm
index 49f21da..284dad2 100644
--- a/Votify.pm
+++ b/Votify.pm
@@ -1,6 +1,5 @@
-# $Id: Votify.pm,v 1.5 2005/05/16 23:58:09 agriffis Exp $
-#
-# Copyright 2005-2016 Gentoo Foundation
+#!/usr/bin/perl
+# Copyright 1999-2024 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
#
# votify.pm: common classes for votify and countify
diff --git a/election-details.template b/election-details.template
new file mode 100644
index 0000000..0df3612
--- /dev/null
+++ b/election-details.template
@@ -0,0 +1,8 @@
+name: __TYPE__-__YYYYMM__
+startDate: __YYYY__-MM-DD 00:00:00 UTC
+endDate: __YYYY__-MM-DD 23:59:59 UTC
+officials: __OFFICIALS__
+voters: https://projects.gentoo.org/elections/__TYPE__/__YYYY__/voters-__TYPE__-__YYYYMM__.txt
+ballot: https://projects.gentoo.org/elections/__TYPE__/__YYYY__/ballot-__TYPE__-__YYYYMM__.txt
+url: https://wiki.gentoo.org/wiki/Project:Elections/__TYPE__/__YYYYMM__
+
diff --git a/populate-election.sh b/populate-election.sh
new file mode 100755
index 0000000..bbfbc60
--- /dev/null
+++ b/populate-election.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+# Copyright 2024-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+#
+# populate-election.sh: Create election files based on the election-details file.
+#
+
+ELECTION=${1%/}
+fullpath=$(readlink -f "./${ELECTION}")
+
+warn() {
+ echo "$@" 1>&2
+}
+
+die() {
+ echo "$@" 1>&2
+ exit 1
+}
+
+if [[ -z "${ELECTION}" ]]; then
+ die "usage: $(basename "$0") ELECTION-NAME"
+fi
+
+details="${fullpath}"/election-details
+
+if ! test -f "${details}" ; then
+ warn "Could not find $ELECTION at ${details}: missing file - generating from template"
+ mkdir -p "${ELECTION}"/
+ cat election-details.template >"${ELECTION}"/election-details
+ _type=${ELECTION//*-}
+ _yyyymm=${ELECTION//-*}
+ sed -i \
+ -e "s/__TYPE__/${_type}/g" \
+ -e "s/__YYYYMM__/${_yyyymm}/g" \
+ -e "s/__YYYY__/${_yyyymm:0:4}/g" \
+ "${ELECTION}"/election-details
+fi
+
+if ! grep -sq -x -e "name: ${ELECTION}" "${details}" ; then
+ die "Could not find $ELECTION at ${details}: bad content"
+fi
+
+for f in name startDate endDate officials voters ballot url ; do
+ awk -v f=$f -F ': ' '($1==f){print $2}' "${details}" |grep -E -e '.{6,}' -sq || die "$ELECTION: missing field $f in $details"
+done
+
+for f in voters ballot officials ; do
+ k1=${f/:*}
+ k2=${f/*:}
+ d=$ELECTION/${k1}-$ELECTION
+ v=$(awk -v f="$k2" -F ': ' '($1==f){print $2}' "${details}")
+ if [[ "$v" =~ "https://" ]]; then
+ curl --fail -Lsq -o "${d}" "$v" || warn "Could not fetch ${f} from $v"
+ else
+ tr -s ', ' '\n' <<<"$v" |fmt -1 |sort >"$d"
+ fi
+done
+
+for f in start:startDate stop:endDate ; do
+ k1=${f/:*}
+ k2=${f/*:}
+ d=$ELECTION/${k1}-$ELECTION
+ v=$(awk -v f="$k2" -F ': ' '($1==f){print $2}' "${details}")
+ date +%s -d "$v" >"${d}"
+done
+
+if [ -f "${ELECTION}/ballot-${ELECTION}" ]; then
+ overlap_candidate_official=$(grep -x -f "${ELECTION}/officials-${ELECTION}" "${ELECTION}/ballot-${ELECTION}" -o)
+ if [[ -n "${overlap_candidate_official}" ]]; then
+ die "ERROR: One or more candidates are also election officials: ${overlap_candidate_official}"
+ fi
+fi
+
+ln -sf "../Votify.pm" "${ELECTION}/"
^ permalink raw reply related [flat|nested] 44+ messages in thread
end of thread, other threads:[~2024-06-02 0:13 UTC | newest]
Thread overview: 44+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-19 22:28 [gentoo-commits] proj/elections:master commit in: / Robin H. Johnson
-- strict thread matches above, loose matches on Subject: below --
2024-06-02 0:13 Robin H. Johnson
2024-05-25 17:14 Robin H. Johnson
2022-07-01 19:12 Robin H. Johnson
2022-07-01 15:50 Robin H. Johnson
2022-06-30 22:36 Robin H. Johnson
2022-06-25 16:31 Robin H. Johnson
2022-06-25 13:58 Jorge Manuel B. S. Vicetto
2021-06-18 6:57 Robin H. Johnson
2021-06-18 6:57 Robin H. Johnson
2020-07-06 5:10 Robin H. Johnson
2020-06-20 5:17 Robin H. Johnson
2020-06-20 5:17 Robin H. Johnson
2017-06-25 0:04 Robin H. Johnson
2017-06-24 23:54 Robin H. Johnson
2016-07-21 18:07 Robin H. Johnson
2016-07-21 18:07 Robin H. Johnson
2016-07-03 15:01 Robin H. Johnson
2016-07-03 11:04 Jorge Manuel B. S. Vicetto
2016-06-19 12:13 Jorge Manuel B. S. Vicetto
2016-06-19 12:13 Jorge Manuel B. S. Vicetto
2016-06-18 17:28 Robin H. Johnson
2016-06-18 17:28 Robin H. Johnson
2016-06-18 17:28 Robin H. Johnson
2016-06-18 17:28 Robin H. Johnson
2015-06-28 0:12 Jorge Manuel B. S. Vicetto
2015-06-27 16:18 Robin H. Johnson
2013-06-30 6:32 Jorge Manuel B. S. Vicetto
2013-02-06 0:09 Jorge Manuel B. S. Vicetto
2012-07-16 19:01 Christian Ruppert
2012-06-18 21:08 Christian Ruppert
2012-02-15 2:07 Robin H. Johnson
2011-06-20 6:14 Robin H. Johnson
2011-06-20 6:13 Robin H. Johnson
2011-06-20 6:13 Robin H. Johnson
2011-06-20 6:13 Robin H. Johnson
2011-06-20 6:13 Robin H. Johnson
2011-06-20 6:08 Robin H. Johnson
2011-06-09 7:46 Robin H. Johnson
2011-04-09 0:09 Robin H. Johnson
2011-03-12 18:41 Robin H. Johnson
2011-03-12 10:57 Robin H. Johnson
2011-03-12 10:56 Robin H. Johnson
2011-02-13 2:21 Robin H. Johnson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox