Gentoo Archives: gentoo-commits

From: "Robin H. Johnson" <robbat2@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/elections:master commit in: /
Date: Fri, 18 Jun 2021 06:57:47
Message-Id: 1623999402.8e9679101b638f65af8be2e034263efed09bf22e.robbat2@gentoo
1 commit: 8e9679101b638f65af8be2e034263efed09bf22e
2 Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
3 AuthorDate: Fri Jun 18 06:56:42 2021 +0000
4 Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
5 CommitDate: Fri Jun 18 06:56:42 2021 +0000
6 URL: https://gitweb.gentoo.org/proj/elections.git/commit/?id=8e967910
7
8 Votify: improvements from re-using the codebase for another project
9
10 Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
11
12 Votify.pm | 49 +++++++++++++++++++++++++++++++++++--------------
13 countify | 19 +++++++++++++------
14 2 files changed, 48 insertions(+), 20 deletions(-)
15
16 diff --git a/Votify.pm b/Votify.pm
17 index 87fba2f..35a717f 100644
18 --- a/Votify.pm
19 +++ b/Votify.pm
20 @@ -8,13 +8,13 @@
21
22 package Votify;
23
24 -use POSIX;
25 +use Carp::Always;
26 use Cwd qw(abs_path);
27 +use Data::Dumper;
28 use File::Basename;
29 use File::Spec::Functions;
30 use List::Util;
31 -use Data::Dumper;
32 -use Carp::Always;
33 +use POSIX;
34 use strict;
35 use warnings;
36
37 @@ -218,8 +218,8 @@ sub new {
38 close(F);
39
40 # assign confirmation numbers randomly
41 - for my $v (@voterlist) {
42 - do { $r = int rand 0xffff } while exists $self->{'voters'}{$r};
43 + for my $v (List::Util::shuffle(@voterlist)) {
44 + do { $r = int rand 0xffffffff } while exists $self->{'voters'}{$r};
45 $self->{'voters'}{$r} = $v;
46 $self->{'confs'}{$v} = $r;
47 }
48 @@ -239,7 +239,7 @@ sub confs {
49
50 sub voters {
51 my ($self) = @_;
52 - sort keys %{$self->{'confs'}};
53 + return sort keys %{$self->{'confs'}};
54 }
55
56 sub getvoter {
57 @@ -252,7 +252,7 @@ sub getconf {
58 return $self->{'confs'}{$voter};
59 }
60
61 -sub write {
62 +sub write_confs {
63 my ($self, $filename) = @_;
64
65 $filename ||= $self->{'default_filename'};
66 @@ -263,8 +263,8 @@ sub write {
67 }
68
69 open(F, ">$filename") or die("can't write to $filename");
70 - for my $c ($self->confs) {
71 - printf F "%04x %s\n", $c, $self->getvoter($c);
72 + for my $c (sort { $a <=> $b } map { int $_ } $self->confs) {
73 + printf F "%08x %s\n", $c, $self->getvoter($c);
74 }
75 close F;
76 }
77 @@ -287,6 +287,7 @@ sub new {
78 default_filename => catfile($datadir, "master-$election_name"),
79 filename => '',
80 voterlist => $vl,
81 + casting_voters => {}, # indexed by voter
82 ballots => {}, # indexed by conf num
83 candidates => undef, # indexed by long name
84 table => undef, # indexed by row+column
85 @@ -326,6 +327,7 @@ sub collect {
86 next;
87 }
88 $self->{'ballots'}{$c} = $b;
89 + $self->{'casting_voters'}{$v} = 1;
90 }
91 elsif (-f "$home/.ballot-$self->{election}") {
92 print STDERR "Warning: $v did not submit their ballot\n";
93 @@ -333,7 +335,7 @@ sub collect {
94 }
95 }
96
97 -sub write {
98 +sub write_master {
99 my ($self, $filename) = @_;
100
101 $filename ||= $self->{'default_filename'};
102 @@ -344,14 +346,15 @@ sub write {
103 }
104
105 open(F, ">$filename") or die("can't write to $filename");
106 - for my $c (sort keys %{$self->{'ballots'}}) {
107 - printf F "--------- confirmation %04x ---------\n", $c;
108 + for my $c (sort { $a <=> $b } map { int $_ } keys %{$self->{'ballots'}}) {
109 + my $confid = sprintf("%08x",$c);
110 + printf F "--------- confirmation %s ---------\n", $confid;
111 print F $self->{'ballots'}{$c}->to_s
112 }
113 close F;
114 }
115
116 -sub read {
117 +sub read_master {
118 my ($self, $filename) = @_;
119 my ($election, $entries) = $self->{'election'};
120
121 @@ -362,7 +365,7 @@ sub read {
122 { local $/ = undef; $entries = <F>; }
123 for my $e (split /^--------- confirmation /m, $entries) {
124 next unless $e; # skip the first zero-length record
125 - unless ($e =~ /^([[:xdigit:]]{4}) ---------\n(.*)$/s) {
126 + unless ($e =~ /^([[:xdigit:]]{4,12}) ---------\n(.*)$/s) {
127 die "error parsing entry:\n$e";
128 }
129 my ($c, $s, $b) = ($1, $2, Ballot->new($election));
130 @@ -371,6 +374,24 @@ sub read {
131 }
132 }
133
134 +sub write_casting_voters {
135 + my ($self, $filename) = @_;
136 +
137 + $filename ||= $self->{'default_filename'};
138 + $self->{'filename'} = $filename;
139 +
140 + if (-f $filename) {
141 + die "$filename already exists; please remove it first";
142 + }
143 +
144 + open(F, ">$filename") or die("can't write to $filename");
145 + for my $v (sort keys %{$self->{'casting_voters'}}) {
146 + printf F "%s\n", $v;
147 + }
148 + close F;
149 +}
150 +
151 +
152 sub generate_candidates {
153 my ($self) = @_;
154 my ($B, @C, $s);
155
156 diff --git a/countify b/countify
157 index 13618a4..cf31d69 100755
158 --- a/countify
159 +++ b/countify
160 @@ -19,9 +19,13 @@ BEGIN {
161 push @INC, $dirname;
162 }
163
164 -use POSIX;
165 +use Cwd qw(abs_path);
166 +use File::Basename;
167 +use File::Spec::Functions;
168 use Getopt::Long;
169 use List::Util;
170 +use POSIX;
171 +
172 use Votify 'official';
173 use strict;
174
175 @@ -94,12 +98,15 @@ if ($opt{'collect'}) {
176 $master->collect($vl->voters);
177 for my $o ($ol->officials) {
178 my ($uid, $home) = (getpwnam $o)[2,7];
179 - mkdir "$home/results-$election";
180 - $master->write("$home/results-$election/master-$election");
181 - $vl->write("$home/results-$election/confs-$election");
182 + $home = "/home/$o" unless defined $home;
183 + mkdir catfile("$home", "results-$election");
184 + $master->write_master("$home/results-$election/master-$election");
185 + $master->write_casting_voters("$home/results-$election/casting-voters-$election");
186 + $vl->write_confs("$home/results-$election/confs-$election");
187 chown $uid, -1, "$home/results-$election",
188 "$home/results-$election/master-$election",
189 - "$home/results-$election/confs-$election";
190 + "$home/results-$election/confs-$election",
191 + "$home/results-$election/casting-voters-$election";
192 }
193 exit 0;
194 }
195 @@ -107,7 +114,7 @@ if ($opt{'collect'}) {
196 if ($opt{'rank'}) {
197 my ($master) = MasterBallot->new($election, $vl);
198 my (@candidates, @winner, @ranked, @ranks);
199 - $master->read("$ENV{HOME}/results-$election/master-$election");
200 + $master->read_master("$ENV{HOME}/results-$election/master-$election");
201 $master->generate_candidates();
202 @candidates = sort keys %{$master->{'candidates'}};