[aur-dev] [PATCH v2 0/7] Display vote results on the Proposal Details page
Reroll with some minor changes. Counting the total number of TUs instead of the number of active TUs now (adapted to recent bylaws changes). Dropped the patches to update participation if a TU becomes active during the voting period since they are no longer needed. I kept [1/7]: "Allow for setting an account's inactivity status" since it is a useful feature anyway. Lukas Fleischer (7): Allow for setting an account's inactivity status Store the number of TUs when starting a vote Show participation in vote details Add a quorum column to TU_VoteInfo Add a vote type to the TU proposal form tu_details.php: Avoid inline computations tu_details.php: Display vote result UPGRADING | 18 +++++++++++++++ support/schema/aur-schema.sql | 3 +++ web/html/account.php | 5 +++-- web/html/addvote.php | 46 ++++++++++++++++++++++++++++---------- web/lib/acctfuncs.inc.php | 41 +++++++++++++++++++++++++-------- web/template/account_details.php | 6 +++++ web/template/account_edit_form.php | 5 +++++ web/template/tu_details.php | 43 +++++++++++++++++++++++++++++++---- 8 files changed, 140 insertions(+), 27 deletions(-) -- 1.8.4.rc3.500.gc3113b0
This adds a field to the users table and corresponding fields to the account edit and display forms that allow for setting an (in-)activity status. This might turn out to be useful if a user is on vacation and can not respond to update/orphan/deletion requests. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- UPGRADING | 9 +++++++++ support/schema/aur-schema.sql | 1 + web/html/account.php | 5 +++-- web/lib/acctfuncs.inc.php | 28 ++++++++++++++++++++++------ web/template/account_details.php | 6 ++++++ web/template/account_edit_form.php | 5 +++++ 6 files changed, 46 insertions(+), 8 deletions(-) diff --git a/UPGRADING b/UPGRADING index a04471f..d8527e3 100644 --- a/UPGRADING +++ b/UPGRADING @@ -1,6 +1,15 @@ Upgrading ========= +From 2.2.0 to 2.3.0 +------------------- + +1. Add an inactivity time stamp to the "Users" table: + +---- +ALTER TABLE Users ADD COLUMN InactivityTS BIGINT NOT NULL DEFAULT 0; +---- + From 2.1.0 to 2.2.0 ------------------- diff --git a/support/schema/aur-schema.sql b/support/schema/aur-schema.sql index 0d04f12..68db93f 100644 --- a/support/schema/aur-schema.sql +++ b/support/schema/aur-schema.sql @@ -35,6 +35,7 @@ CREATE TABLE Users ( LastVoted BIGINT UNSIGNED NOT NULL DEFAULT 0, LastLogin BIGINT UNSIGNED NOT NULL DEFAULT 0, LastLoginIPAddress INTEGER UNSIGNED NOT NULL DEFAULT 0, + InactivityTS BIGINT UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY (ID), UNIQUE (Username), UNIQUE (Email), diff --git a/web/html/account.php b/web/html/account.php index 4af3043..79b5eeb 100644 --- a/web/html/account.php +++ b/web/html/account.php @@ -52,7 +52,8 @@ if (isset($_COOKIE["AURSID"])) { display_account_form($atype, "UpdateAccount", $row["Username"], $row["AccountTypeID"], $row["Suspended"], $row["Email"], "", "", $row["RealName"], $row["LangPreference"], - $row["IRCNick"], $row["PGPKey"], $row["ID"]); + $row["IRCNick"], $row["PGPKey"], + $row["InactivityTS"] ? 1 : 0, $row["ID"]); } else { print __("You do not have permission to edit this account."); } @@ -81,7 +82,7 @@ if (isset($_COOKIE["AURSID"])) { in_request("U"), in_request("T"), in_request("S"), in_request("E"), in_request("P"), in_request("C"), in_request("R"), in_request("L"), in_request("I"), - in_request("K"), in_request("ID")); + in_request("K"), in_request("J"), in_request("ID")); } } else { if ($atype == "Trusted User" || $atype == "Developer") { diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php index 1deeac5..7602ec2 100644 --- a/web/lib/acctfuncs.inc.php +++ b/web/lib/acctfuncs.inc.php @@ -54,12 +54,13 @@ function html_format_pgp_fingerprint($fingerprint) { * @param string $L The language preference of the displayed user * @param string $I The IRC nickname of the displayed user * @param string $K The PGP key fingerprint of the displayed user + * @param string $J The inactivity status of the displayed user * @param string $UID The user ID of the displayed user * * @return void */ function display_account_form($UTYPE,$A,$U="",$T="",$S="", - $E="",$P="",$C="",$R="",$L="",$I="",$K="",$UID=0) { + $E="",$P="",$C="",$R="",$L="",$I="",$K="",$J="", $UID=0) { global $SUPPORTED_LANGS; include("account_edit_form.php"); @@ -83,12 +84,13 @@ function display_account_form($UTYPE,$A,$U="",$T="",$S="", * @param string $L The language preference of the user * @param string $I The IRC nickname of the user * @param string $K The PGP fingerprint of the user + * @param string $J The inactivity status of the user * @param string $UID The user ID of the modified account * * @return string|void Return void if successful, otherwise return error */ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="", - $P="",$C="",$R="",$L="",$I="",$K="",$UID=0) { + $P="",$C="",$R="",$L="",$I="",$K="",$J="",$UID=0) { # error check and process request for a new/modified account global $SUPPORTED_LANGS, $AUR_LOCATION; @@ -185,7 +187,7 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="", if ($error) { print "<ul class='errorlist'><li>".$error."</li></ul>\n"; display_account_form($UTYPE, $A, $U, $T, $S, $E, "", "", - $R, $L, $I, $K, $UID); + $R, $L, $I, $K, $J, $UID); } else { if ($TYPE == "new") { # no errors, go ahead and create the unprivileged user @@ -206,9 +208,10 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="", $I = $dbh->quote($I); $K = $dbh->quote(str_replace(" ", "", $K)); $q = "INSERT INTO Users (AccountTypeID, Suspended, "; - $q.= "Username, Email, Passwd, Salt, RealName, "; - $q.= "LangPreference, IRCNick, PGPKey) VALUES (1, 0, "; - $q.= "$U, $E, $P, $salt, $R, $L, $I, $K)"; + $q.= "InactivityTS, Username, Email, Passwd, Salt, "; + $q.= "RealName, LangPreference, IRCNick, PGPKey) "; + $q.= "VALUES (1, 0, 0, $U, $E, $P, $salt, $R, $L, "; + $q.= "$I, $K)"; $result = $dbh->exec($q); if (!$result) { print __("Error trying to create account, %s%s%s.", @@ -240,6 +243,18 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="", } else { # no errors, go ahead and modify the user account + $q = "SELECT InactivityTS FROM Users WHERE "; + $q.= "ID = " . intval($UID); + $result = $dbh->query($q); + $row = $result->fetch(PDO::FETCH_NUM); + if ($row[0] && $J) { + $inactivity_ts = $row[0]; + } elseif ($J) { + $inactivity_ts = time(); + } else { + $inactivity_ts = 0; + } + $q = "UPDATE Users SET "; $q.= "Username = " . $dbh->quote($U); if ($T) { @@ -262,6 +277,7 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="", $q.= ", LangPreference = " . $dbh->quote($L); $q.= ", IRCNick = " . $dbh->quote($I); $q.= ", PGPKey = " . $dbh->quote(str_replace(" ", "", $K)); + $q.= ", InactivityTS = " . $inactivity_ts; $q.= " WHERE ID = ".intval($UID); $result = $dbh->exec($q); if (!$result) { diff --git a/web/template/account_details.php b/web/template/account_details.php index fdebfb3..02ed32b 100644 --- a/web/template/account_details.php +++ b/web/template/account_details.php @@ -38,6 +38,12 @@ <td><?= html_format_pgp_fingerprint($row["PGPKey"]) ?></td> </tr> <tr> + <th><?= __("Status") . ":" ?></th> + <td> + <?= $row["InactivityTS"] ? __("Inactive since") . ' ' . date("Y-m-d H:i", $row["InactivityTS"]) : __("Active"); ?> + </td> + </tr> + <tr> <th><?= __("Last Voted") . ":" ?></th> <td> <?= $row["LastVoted"] ? date("Y-m-d", $row["LastVoted"]) : __("Never"); ?> diff --git a/web/template/account_edit_form.php b/web/template/account_edit_form.php index a0de2a3..30b26fd 100644 --- a/web/template/account_edit_form.php +++ b/web/template/account_edit_form.php @@ -56,6 +56,11 @@ <?php endif; ?> <p> + <label for="id_inactive"><?= __("Inactive") ?>:</label> + <input type="checkbox" name="J" id="id_inactive" <?= $J ? 'checked="checked"' : '' ?> /> + </p> + + <p> <label for="id_email"><?= __("Email Address") ?>:</label> <input type="text" size="30" maxlength="64" name="E" id="id_email" value="<?= htmlspecialchars($E,ENT_QUOTES) ?>" /> (<?= __("required") ?>) </p> -- 1.8.4.rc3.500.gc3113b0
This will be used for automated calculation of vote participation later. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- UPGRADING | 7 +++++++ support/schema/aur-schema.sql | 1 + web/lib/acctfuncs.inc.php | 10 ++++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/UPGRADING b/UPGRADING index d8527e3..c584647 100644 --- a/UPGRADING +++ b/UPGRADING @@ -10,6 +10,13 @@ From 2.2.0 to 2.3.0 ALTER TABLE Users ADD COLUMN InactivityTS BIGINT NOT NULL DEFAULT 0; ---- +2. Add a field to store the total number of TUs to the "TU_VoteInfo" table: + +---- +ALTER TABLE TU_VoteInfo + ADD COLUMN ActiveTUs tinyint(3) unsigned NOT NULL default '0'; +---- + From 2.1.0 to 2.2.0 ------------------- diff --git a/support/schema/aur-schema.sql b/support/schema/aur-schema.sql index 68db93f..51f9601 100644 --- a/support/schema/aur-schema.sql +++ b/support/schema/aur-schema.sql @@ -202,6 +202,7 @@ CREATE TABLE IF NOT EXISTS TU_VoteInfo ( Yes tinyint(3) unsigned NOT NULL default '0', No tinyint(3) unsigned NOT NULL default '0', Abstain tinyint(3) unsigned NOT NULL default '0', + ActiveTUs tinyint(3) unsigned NOT NULL default '0', PRIMARY KEY (ID), FOREIGN KEY (SubmitterID) REFERENCES Users(ID) ON DELETE CASCADE ) ENGINE = InnoDB; diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php index 7602ec2..738c7b2 100644 --- a/web/lib/acctfuncs.inc.php +++ b/web/lib/acctfuncs.inc.php @@ -618,10 +618,16 @@ function open_user_proposals($user) { function add_tu_proposal($agenda, $user, $votelength, $submitteruid) { $dbh = DB::connect(); - $q = "INSERT INTO TU_VoteInfo (Agenda, User, Submitted, End, SubmitterID) VALUES "; + $q = "SELECT COUNT(*) FROM Users WHERE AccountTypeID = 2"; + $result = $dbh->query($q); + $row = $result->fetch(PDO::FETCH_NUM); + $active_tus = $row[0]; + + $q = "INSERT INTO TU_VoteInfo (Agenda, User, Submitted, End, "; + $q.= "SubmitterID, ActiveTUs) VALUES "; $q.= "(" . $dbh->quote($agenda) . ", " . $dbh->quote($user) . ", "; $q.= "UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + " . $dbh->quote($votelength); - $q.= ", " . $submitteruid . ")"; + $q.= ", " . $submitteruid . ", " . $active_tus . ")"; $result = $dbh->exec($q); } -- 1.8.4.rc3.500.gc3113b0
This is calculated by dividing the sum of all votes by the total number of TUs (where the number of TUs is measured when the vote starts). Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/template/tu_details.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/web/template/tu_details.php b/web/template/tu_details.php index be816ce..4f291f0 100644 --- a/web/template/tu_details.php +++ b/web/template/tu_details.php @@ -34,6 +34,7 @@ <th><?= __("Abstain") ?></th> <th><?= __("Total") ?></th> <th><?= __('Voted') ?></th> + <th><?= __('Participation') ?></th> </tr> <tr> <td><?= $row['Yes'] ?></td> @@ -47,6 +48,11 @@ <span style="color: green; font-weight: bold"><?= __("Yes") ?></span> <?php endif; ?> </td> + <?php if ($row['ActiveTUs'] > 0): ?> + <td><?= number_format(($row['Yes'] + $row['No'] + $row['Abstain']) / $row['ActiveTUs'] * 100, 2) ?>%</td> + <?php else: ?> + <td><?= __("unknown") ?></td> + <?php endif; ?> </tr> </table> </div> -- 1.8.4.rc3.500.gc3113b0
This allows for specifying a quorum per vote and sets a basis for implementing automated acceptance/rejection of TU votes later. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- UPGRADING | 6 ++++-- support/schema/aur-schema.sql | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/UPGRADING b/UPGRADING index c584647..357f2a6 100644 --- a/UPGRADING +++ b/UPGRADING @@ -10,11 +10,13 @@ From 2.2.0 to 2.3.0 ALTER TABLE Users ADD COLUMN InactivityTS BIGINT NOT NULL DEFAULT 0; ---- -2. Add a field to store the total number of TUs to the "TU_VoteInfo" table: +2. Add fields to store the total number of TUs and the quorum to the + "TU_VoteInfo" table: ---- ALTER TABLE TU_VoteInfo - ADD COLUMN ActiveTUs tinyint(3) unsigned NOT NULL default '0'; + ADD COLUMN ActiveTUs tinyint(3) unsigned NOT NULL default '0', + ADD COLUMN Quorum decimal(2, 2) unsigned NOT NULL; ---- From 2.1.0 to 2.2.0 diff --git a/support/schema/aur-schema.sql b/support/schema/aur-schema.sql index 51f9601..59da3aa 100644 --- a/support/schema/aur-schema.sql +++ b/support/schema/aur-schema.sql @@ -198,6 +198,7 @@ CREATE TABLE IF NOT EXISTS TU_VoteInfo ( User VARCHAR(32) NOT NULL, Submitted bigint(20) unsigned NOT NULL, End bigint(20) unsigned NOT NULL, + Quorum decimal(2, 2) unsigned NOT NULL, SubmitterID int(10) unsigned NOT NULL, Yes tinyint(3) unsigned NOT NULL default '0', No tinyint(3) unsigned NOT NULL default '0', -- 1.8.4.rc3.500.gc3113b0
There are only four valid reasons for starting a TU vote, so instead of letting the user choose a vote length, let her pick a reason and set vote length and quorum based on that selection. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/html/addvote.php | 46 ++++++++++++++++++++++++++++++++++------------ web/lib/acctfuncs.inc.php | 7 ++++--- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/web/html/addvote.php b/web/html/addvote.php index 43973f3..3ce99c0 100644 --- a/web/html/addvote.php +++ b/web/html/addvote.php @@ -37,16 +37,34 @@ if ($atype == "Trusted User" || $atype == "Developer") { } } - if (!empty($_POST['length'])) { - if (!is_numeric($_POST['length'])) { - $error.= __("Length must be a number.") ; - } else if ($_POST['length'] < 1) { - $error.= __("Length must be at least 1."); - } else { - $len = (60*60*24)*$_POST['length']; + if (!empty($_POST['type'])) { + switch ($_POST['type']) { + case "add_tu": + /* Addition of a TU */ + $len = 7 * 24 * 60 * 60; + $quorum = 0.66; + break; + case "remove_tu": + /* Removal of a TU */ + $len = 7 * 24 * 60 * 60; + $quorum = 0.75; + break; + case "remove_inactive_tu": + /* Removal of a TU (undeclared inactivity) */ + $len = 5 * 24 * 60 * 60; + $quorum = 0.66; + break; + case "bylaws": + /* Amendment of Bylaws */ + $len = 7 * 24 * 60 * 60; + $quorum = 0.75; + break; + default: + $error.= __("Invalid type.") ; + break; } } else { - $len = 60*60*24*7; + $error.= __("Invalid type.") ; } if (empty($_POST['agenda'])) { @@ -55,7 +73,7 @@ if ($atype == "Trusted User" || $atype == "Developer") { } if (!empty($_POST['addVote']) && empty($error)) { - add_tu_proposal($_POST['agenda'], $_POST['user'], $len, $uid); + add_tu_proposal($_POST['agenda'], $_POST['user'], $len, $quorum, $uid); print "<p class=\"pkgoutput\">" . __("New proposal submitted.") . "</p>\n"; } else { @@ -75,9 +93,13 @@ if ($atype == "Trusted User" || $atype == "Developer") { <?= __("(empty if not applicable)") ?> </p> <p> - <label for="id_length"><?= __("Length in days") ?></label> - <input type="text" name="length" id="id_length" value="<?php if (!empty($_POST['length'])) { print htmlentities($_POST['length'], ENT_QUOTES); } ?>" /> - <?= __("(defaults to 7 if empty)") ?> + <label for="id_type"><?= __("Type") ?></label> + <select name="type" id="id_type"> + <option value="add_tu"><?= __("Addition of a TU") ?></option> + <option value="remove_tu"><?= __("Removal of a TU") ?></option> + <option value="remove_inactive_tu"><?= __("Removal of a TU (undeclared inactivity)") ?></option> + <option value="bylaws"><?= __("Amendment of Bylaws") ?></option> + </select> </p> <p> <label for="id_agenda"><?= __("Proposal") ?></label><br /> diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php index 738c7b2..31cdd79 100644 --- a/web/lib/acctfuncs.inc.php +++ b/web/lib/acctfuncs.inc.php @@ -615,7 +615,7 @@ function open_user_proposals($user) { * * @return void */ -function add_tu_proposal($agenda, $user, $votelength, $submitteruid) { +function add_tu_proposal($agenda, $user, $votelength, $quorum, $submitteruid) { $dbh = DB::connect(); $q = "SELECT COUNT(*) FROM Users WHERE AccountTypeID = 2"; @@ -623,11 +623,12 @@ function add_tu_proposal($agenda, $user, $votelength, $submitteruid) { $row = $result->fetch(PDO::FETCH_NUM); $active_tus = $row[0]; - $q = "INSERT INTO TU_VoteInfo (Agenda, User, Submitted, End, "; + $q = "INSERT INTO TU_VoteInfo (Agenda, User, Submitted, End, Quorum, "; $q.= "SubmitterID, ActiveTUs) VALUES "; $q.= "(" . $dbh->quote($agenda) . ", " . $dbh->quote($user) . ", "; $q.= "UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + " . $dbh->quote($votelength); - $q.= ", " . $submitteruid . ", " . $active_tus . ")"; + $q.= ", " . $dbh->quote($quorum) . ", " . $submitteruid . ", "; + $q.= $active_tus . ")"; $result = $dbh->exec($q); } -- 1.8.4.rc3.500.gc3113b0
Compute the total number of votes and the participation at the beginning of the template instead of doing it inside the template itself. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/template/tu_details.php | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/web/template/tu_details.php b/web/template/tu_details.php index 4f291f0..61abab7 100644 --- a/web/template/tu_details.php +++ b/web/template/tu_details.php @@ -1,3 +1,12 @@ +<?php +$yes = $row["Yes"]; +$no = $row["No"]; +$abstain = $row["Abstain"]; +$active_tus = $row["ActiveTUs"]; + +$total = $yes + $no + $abstain; +$participation = $total / $active_tus; +?> <div class="box"> <h2><?= __("Proposal Details") ?></h2> @@ -37,10 +46,10 @@ <th><?= __('Participation') ?></th> </tr> <tr> - <td><?= $row['Yes'] ?></td> - <td><?= $row['No'] ?></td> - <td><?= $row['Abstain'] ?></td> - <td><?= ($row['Yes'] + $row['No'] + $row['Abstain']) ?></td> + <td><?= $yes ?></td> + <td><?= $no ?></td> + <td><?= $abstain ?></td> + <td><?= $total ?></td> <td> <?php if ($hasvoted == 0): ?> <span style="color: red; font-weight: bold"><?= __("No") ?></span> @@ -48,8 +57,8 @@ <span style="color: green; font-weight: bold"><?= __("Yes") ?></span> <?php endif; ?> </td> - <?php if ($row['ActiveTUs'] > 0): ?> - <td><?= number_format(($row['Yes'] + $row['No'] + $row['Abstain']) / $row['ActiveTUs'] * 100, 2) ?>%</td> + <?php if ($active_tus > 0): ?> + <td><?= number_format($participation * 100, 2) ?>%</td> <?php else: ?> <td><?= __("unknown") ?></td> <?php endif; ?> -- 1.8.4.rc3.500.gc3113b0
This adds an field that indicates whether the vote was accepted or rejected, based on the rules specified in the TU Bylaws. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/template/tu_details.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/web/template/tu_details.php b/web/template/tu_details.php index 61abab7..c09e30c 100644 --- a/web/template/tu_details.php +++ b/web/template/tu_details.php @@ -3,9 +3,18 @@ $yes = $row["Yes"]; $no = $row["No"]; $abstain = $row["Abstain"]; $active_tus = $row["ActiveTUs"]; +$quorum = $row["Quorum"]; $total = $yes + $no + $abstain; $participation = $total / $active_tus; + +if ($yes > $active_tus / 2) { + $vote_accepted = true; +} elseif ($participation > $quorum && $yes > $no) { + $vote_accepted = true; +} else { + $vote_accepted = false; +} ?> <div class="box"> <h2><?= __("Proposal Details") ?></h2> @@ -30,6 +39,17 @@ $participation = $total / $active_tus; <br /> <?= __("End") ?>: <strong><?= gmdate("Y-m-d H:i", $row['End']) ?></strong> + <?php if ($isrunning == 0): ?> + <br /> + <?= __("Result") ?>: + <?php if (!$quorum): ?> + <span><?= __("unknown") ?></span> + <?php elseif ($vote_accepted): ?> + <span style="color: green; font-weight: bold"><?= __("Accepted") ?></span> + <?php else: ?> + <span style="color: red; font-weight: bold"><?= __("Rejected") ?></span> + <?php endif; ?> + <?php endif; ?> </p> <p> -- 1.8.4.rc3.500.gc3113b0
participants (1)
-
Lukas Fleischer