diff options
-rw-r--r-- | CHANGES | 7 | ||||
-rw-r--r-- | README | 1 | ||||
-rw-r--r-- | bug_form.pl | 24 | ||||
-rwxr-xr-x | buglist.cgi | 8 | ||||
-rwxr-xr-x | changepassword.cgi | 2 | ||||
-rwxr-xr-x | colchange.cgi | 2 | ||||
-rw-r--r-- | defparams.pl | 15 | ||||
-rwxr-xr-x | doeditcomponents.cgi | 5 | ||||
-rwxr-xr-x | doeditvotes.cgi | 102 | ||||
-rwxr-xr-x | editcomponents.cgi | 7 | ||||
-rw-r--r-- | globals.pl | 29 | ||||
-rwxr-xr-x | makeproducttable.sh | 3 | ||||
-rwxr-xr-x | makevotestable.sh | 38 | ||||
-rwxr-xr-x | process_bug.cgi | 6 | ||||
-rwxr-xr-x | processmail | 4 | ||||
-rwxr-xr-x | showvotes.cgi | 120 | ||||
-rw-r--r-- | votehelp.html | 5 |
17 files changed, 361 insertions, 17 deletions
@@ -10,6 +10,13 @@ query the CVS tree. For example, will tell you what has been changed in the last week. +10/7/99 Added voting ability. You must run the new script +"makevotestable.sh". You must also feed the following to mysql: + + alter table products add column votesperuser smallint not null; + + + 9/15/99 Apparently, newer alphas of MySQL won't allow you to have "when" as a column name. So, I have had to rename a column in the bugs_activity table. You must feed the below to mysql or you won't @@ -282,6 +282,7 @@ command. Order does not matter, but this one is fine: ./makeproducttable.sh ./makeprofilestable.sh ./makeversiontable.sh + ./makevotestable.sh You may want to edit the scripts; once bugs are entered it gets very hard to make changes. Think carefully about how you want database users to describe bugs. Here's one diff --git a/bug_form.pl b/bug_form.pl index c563daf06..665d82f62 100644 --- a/bug_form.pl +++ b/bug_form.pl @@ -111,7 +111,7 @@ my $id = $::FORM{'id'}; my $query = " select - bug_id, + bugs.bug_id, product, version, rep_platform, @@ -130,10 +130,12 @@ select status_whiteboard, date_format(creation_ts,'Y-m-d'), groupset, - delta_ts -from bugs -where bug_id = $id -and bugs.groupset & $::usergroupset = bugs.groupset"; + delta_ts, + sum(votes.count) +from bugs left join votes using(bug_id) +where bugs.bug_id = $id +and bugs.groupset & $::usergroupset = bugs.groupset +group by bugs.bug_id"; SendSQL($query); my %bug; @@ -145,7 +147,7 @@ if (@row = FetchSQLData()) { "bug_severity", "component", "assigned_to", "reporter", "bug_file_loc", "short_desc", "target_milestone", "qa_contact", "status_whiteboard", "creation_ts", - "groupset", "delta_ts") { + "groupset", "delta_ts", "votes") { $bug{$field} = shift @row; if (!defined $bug{$field}) { $bug{$field} = ""; @@ -368,6 +370,16 @@ if (Param("usedependencies")) { print "</tr></table>\n"; } +if ($::prodmaxvotes{$bug{'product'}}) { + print qq{ +<table><tr> +<th><a href="votehelp.html">Votes</a> for bug $id:</th><td> +<a href="showvotes.cgi?bug_id=$id">$bug{'votes'}</a> + <a href="showvotes.cgi?voteon=$id">Vote for this bug</a> +</td></tr></table> +}; +} + print " <br> <B>Additional Comments:</B> diff --git a/buglist.cgi b/buglist.cgi index d780e2af2..6c8e6ef16 100755 --- a/buglist.cgi +++ b/buglist.cgi @@ -173,6 +173,7 @@ DefCol("version", "substring(bugs.version, 1, 5)", "Vers", "bugs.version"); DefCol("os", "substring(bugs.op_sys, 1, 4)", "OS", "bugs.op_sys"); DefCol("target_milestone", "bugs.target_milestone", "TargetM", "bugs.target_milestone"); +DefCol("votes", "sum(votes.count)", "Votes", "sum(votes.count)"); my @collist; if (defined $::COOKIE{'COLUMNLIST'}) { @@ -208,11 +209,12 @@ bugs.bug_status"; $query .= " -from bugs, +from bugs left join votes using(bug_id), profiles assign, profiles report left join profiles qacont on bugs.qa_contact = qacont.userid, versions projector + where bugs.assigned_to = assign.userid and bugs.reporter = report.userid and bugs.product = projector.program @@ -226,7 +228,7 @@ if ((defined $::FORM{'emailcc1'} && $::FORM{'emailcc1'}) || # We need to poke into the CC table. Do weird SQL left join stuff so that # we can look in the CC table, but won't reject any bugs that don't have # any CC fields. - $query =~ s/bugs,/bugs left join cc using (bug_id) left join profiles ccname on cc.who = ccname.userid,/; + $query =~ s/bugs left join,/bugs left join cc using (bug_id) left join profiles ccname on cc.who = ccname.userid left join,/; } if (defined $::FORM{'sql'}) { @@ -431,6 +433,8 @@ foreach my $f ("short_desc", "long_desc", "bug_file_loc", } +$query .= "group by bugs.bug_id\n"; + if (defined $::FORM{'order'} && $::FORM{'order'} ne "") { $query .= "order by "; ORDER: for ($::FORM{'order'}) { diff --git a/changepassword.cgi b/changepassword.cgi index 068180fbd..c6d408562 100755 --- a/changepassword.cgi +++ b/changepassword.cgi @@ -83,6 +83,8 @@ On which of these bugs would you like email notification of changes?</td> <input type=submit value=Submit> </form> <hr> +<a href=\"showvotes.cgi\">Review your votes</a> +<hr> "; navigation_header(); exit; diff --git a/colchange.cgi b/colchange.cgi index 2dd1b350b..eb3eafd39 100755 --- a/colchange.cgi +++ b/colchange.cgi @@ -31,7 +31,7 @@ print "Content-type: text/html\n"; my @masterlist = ("opendate", "changeddate", "severity", "priority", "platform", "owner", "reporter", "status", "resolution", - "component", "product", "version", "project", "os"); + "component", "product", "version", "project", "os", "votes"); if (Param("usetargetmilestone")) { push(@masterlist, "target_milestone"); diff --git a/defparams.pl b/defparams.pl index a7c4ba060..7efdc4053 100644 --- a/defparams.pl +++ b/defparams.pl @@ -339,5 +339,20 @@ DefParam("emailsuffix", ""); +DefParam("voteremovedmail", +q{This is a mail message to send to anyone who gets a vote removed from a bug for any reason. %to% gets replaced by a comma-separated list of people who used to be voting for this bug. %bugid% gets replaced by the bug number. %reason% gets replaced by a short reason describing why the vote was removed. %<i>anythingelse</i>% gets replaced by the definition of thatparameter (as defined on this page).}, + "l", +"From: bugzilla-daemon +To: %to% +Subject: [Bug %bugid%] Your vote has been removed from this bug + +You used to have a vote on bug %bugid%, but it has been removed. + +Reason: %reason% + +%urlbase%show_bug.cgi?id=%bugid% +"); + + 1; diff --git a/doeditcomponents.cgi b/doeditcomponents.cgi index bfe09e93d..7f138f285 100755 --- a/doeditcomponents.cgi +++ b/doeditcomponents.cgi @@ -96,12 +96,12 @@ GetVersionTable(); my $prodcode = "P000"; foreach my $product (@::legal_product) { - SendSQL("select description, milestoneurl, disallownew from products where product='$product'"); + SendSQL("select description, milestoneurl, disallownew, votesperuser from products where product='$product'"); my @row = FetchSQLData(); if (!@row) { next; } - my ($description, $milestoneurl, $disallownew) = (@row); + my ($description, $milestoneurl, $disallownew, $votesperuser) = (@row); $prodcode++; Check($product, $::FORM{"prodcode-$prodcode"}); @@ -111,6 +111,7 @@ foreach my $product (@::legal_product) { DoOne($milestoneurl, "$prodcode-milestoneurl", $where); } DoOne($disallownew, "$prodcode-disallownew", $where); + DoOne($votesperuser, "$prodcode-votesperuser", $where); SendSQL("select value, initialowner, initialqacontact, description from components where program=" . SqlQuote($product) . " order by value"); my $c = 0; diff --git a/doeditvotes.cgi b/doeditvotes.cgi new file mode 100755 index 000000000..03c4c1d88 --- /dev/null +++ b/doeditvotes.cgi @@ -0,0 +1,102 @@ +#!/usr/bonsaitools/bin/perl -w +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public License +# Version 1.0 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations +# under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Netscape Communications +# Corporation. Portions created by Netscape are Copyright (C) 1998 +# Netscape Communications Corporation. All Rights Reserved. +# +# Contributor(s): Terry Weissman <terry@mozilla.org> + +use diagnostics; +use strict; + +require "CGI.pl"; + +confirm_login(); + +print "Content-type: text/html\n\n"; + +ConnectToDatabase(); +GetVersionTable(); + +my $who = DBNameToIdAndCheck($::COOKIE{'Bugzilla_login'}); + +if ($who ne $::FORM{'who'}) { + PutHeader("Wrong login."); + print "The login info got confused. If you want to adjust the votes\n"; + print "for <tt>$::COOKIE{'Bugzilla_login'}</tt>, then please\n"; + print "<a href=showvotes.cgi?user=$who>click here</a>.<hr>\n"; + navigation_header(); + exit(); +} + +my @buglist = grep {/^\d+$/} keys(%::FORM); + +if (0 == @buglist) { + PutHeader("Oops?"); + print "Something got confused. Please click <b>Back</b> and try again."; + navigation_header(); + exit(); +} + +foreach my $id (@buglist) { + $::FORM{$id} = trim($::FORM{$id}); + if ($::FORM{$id} !~ /\d+/ || $::FORM{$id} < 0) { + PutHeader("Numbers only, please"); + print "Only use numeric values for your bug votes.\n"; + print "Please click <b>Back</b> and try again.<hr>\n"; + navigation_header(); + exit(); + } +} + +SendSQL("select bug_id, product from bugs where bug_id = " . + join(" or bug_id = ", @buglist)); + +my %prodcount; + +while (MoreSQLData()) { + my ($id, $prod) = (FetchSQLData()); + if (!defined $prodcount{$prod}) { + $prodcount{$prod} = 0; + } + $prodcount{$prod} += $::FORM{$id}; +} + +foreach my $prod (keys(%prodcount)) { + if ($prodcount{$prod} > $::prodmaxvotes{$prod}) { + PutHeader("Don't overstuff!", "Illegal vote"); + print "You may only use $::prodmaxvotes{$prod} votes for bugs in the\n"; + print "<tt>$prod</tt> product, but you are using $prodcount{$prod}.\n"; + print "Please click <b>Back</b> and try again.<hr>\n"; + navigation_header(); + exit(); + } +} + +SendSQL("delete from votes where who = $who"); +foreach my $id (@buglist) { + if ($::FORM{$id} > 0) { + SendSQL("insert into votes (who, bug_id, count) values ($who, $id, $::FORM{$id})"); + } +} + +PutHeader("Voting tabulated", "Voting tabulated", $::COOKIE{'Bugzilla_login'}); +print "Your votes have been recorded.\n"; +print qq{<p><a href="showvotes.cgi?user=$who">Review your votes</a><hr>\n}; +navigation_header(); +exit(); + + diff --git a/editcomponents.cgi b/editcomponents.cgi index a7e1e660e..e4b6a23de 100755 --- a/editcomponents.cgi +++ b/editcomponents.cgi @@ -59,12 +59,12 @@ GetVersionTable(); my $prodcode = "P000"; foreach my $product (@::legal_product) { - SendSQL("select description, milestoneurl, disallownew from products where product='$product'"); + SendSQL("select description, milestoneurl, disallownew, votesperuser from products where product='$product'"); my @row = FetchSQLData(); if (!@row) { next; } - my ($description, $milestoneurl, $disallownew) = (@row); + my ($description, $milestoneurl, $disallownew, $votesperuser) = (@row); $prodcode++; print "<input type=hidden name=prodcode-$prodcode value=\"" . value_quote($product) . "\">\n"; @@ -77,6 +77,9 @@ foreach my $product (@::legal_product) { print "<td><input size=80 name=$prodcode-milestoneurl value=\"" . value_quote($milestoneurl) . "\"></td></tr>\n"; } + print qq{<tr><th align=right>Maximum votes per user:</th><td>\n}; + print qq{<input size=10 name=$prodcode-votesperuser value=$votesperuser>}; + print qq{</td></tr>\n}; my $check0 = !$disallownew ? " SELECTED" : ""; my $check1 = $disallownew ? " SELECTED" : ""; print "<tr><td colspan=2><select name=$prodcode-disallownew>\n"; diff --git a/globals.pl b/globals.pl index 4f5b9a226..ccb0e8167 100644 --- a/globals.pl +++ b/globals.pl @@ -236,9 +236,9 @@ sub GenerateVersionTable { my $dotargetmilestone = Param("usetargetmilestone"); my $mpart = $dotargetmilestone ? ", milestoneurl" : ""; - SendSQL("select product, description, disallownew$mpart from products"); + SendSQL("select product, description, votesperuser, disallownew$mpart from products"); while (@line = FetchSQLData()) { - my ($p, $d, $dis, $u) = (@line); + my ($p, $d, $votesperuser, $dis, $u) = (@line); $::proddesc{$p} = $d; if ($dis) { # Special hack. Stomp on the description and make it "0" if we're @@ -249,6 +249,7 @@ sub GenerateVersionTable { if ($dotargetmilestone) { $::milestoneurl{$p} = $u; } + $::prodmaxvotes{$p} = $votesperuser; } @@ -300,6 +301,7 @@ sub GenerateVersionTable { print FID GenerateCode('@::legal_' . $i); } print FID GenerateCode('%::proddesc'); + print FID GenerateCode('%::prodmaxvotes'); if ($dotargetmilestone) { my $last = Param("nummilestones"); @@ -515,6 +517,29 @@ sub UserInGroup { } +sub RemoveVotes { + my ($id, $reason) = (@_); + ConnectToDatabase(); + SendSQL("select profiles.login_name from votes, profiles where votes.bug_id = $id and profiles.userid = votes.who"); + my @list; + while (MoreSQLData()) { + push(@list, FetchOneColumn()); + } + if (0 < @list) { + if (open(SENDMAIL, "|/usr/lib/sendmail -t")) { + my %substs; + $substs{"to"} = join(',', @list); + $substs{"bugid"} = $id; + $substs{"reason"} = $reason; + print SENDMAIL PerformSubsts(Param("voteremovedmail"), \%substs); + close SENDMAIL; + } + SendSQL("delete from votes where bug_id = $id"); + } +} + + + sub Param { my ($value) = (@_); if (defined $::param{$value}) { diff --git a/makeproducttable.sh b/makeproducttable.sh index ce5dae79c..806c69627 100755 --- a/makeproducttable.sh +++ b/makeproducttable.sh @@ -31,7 +31,8 @@ create table products ( product tinytext, description mediumtext, milestoneurl tinytext not null, -disallownew tinyint not null +disallownew tinyint not null, +votesperuser smallint not null ); diff --git a/makevotestable.sh b/makevotestable.sh new file mode 100755 index 000000000..bc2e163c1 --- /dev/null +++ b/makevotestable.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# +# The contents of this file are subject to the Mozilla Public License +# Version 1.0 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations +# under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Netscape Communications +# Corporation. Portions created by Netscape are Copyright (C) 1998 +# Netscape Communications Corporation. All Rights Reserved. +# +# Contributor(s): Terry Weissman <terry@mozilla.org> + +mysql > /dev/null 2>/dev/null << OK_ALL_DONE + +use bugs; + +drop table votes; +OK_ALL_DONE + +mysql << OK_ALL_DONE +use bugs; +create table votes ( +who mediumint not null, +bug_id mediumint not null, +count smallint not null, + +index(who), +index(bug_id) +); + diff --git a/process_bug.cgi b/process_bug.cgi index aa168bd55..2bd10e890 100755 --- a/process_bug.cgi +++ b/process_bug.cgi @@ -303,7 +303,7 @@ sub LogDependencyActivity { foreach my $id (@idlist) { my %dependencychanged; - SendSQL("lock tables bugs write, bugs_activity write, cc write, profiles write, dependencies write"); + SendSQL("lock tables bugs write, bugs_activity write, cc write, profiles write, dependencies write, votes write"); my @oldvalues = SnapShotBug($id); if (defined $::FORM{'delta_ts'} && $::FORM{'delta_ts'} ne $delta_ts) { @@ -490,6 +490,10 @@ The changes made were: $old = DBID_to_name($old) if $old != 0; $new = DBID_to_name($new) if $new != 0; } + if ($col eq 'product') { + RemoveVotes($id, + "This bug has been moved to a different product"); + } $col = SqlQuote($col); $old = SqlQuote($old); $new = SqlQuote($new); diff --git a/processmail b/processmail index 04c064df3..58d53e51f 100755 --- a/processmail +++ b/processmail @@ -190,6 +190,10 @@ sub GetBugText { my @cclist; @cclist = split(/,/, ShowCcList($id)); + SendSQL("select profiles.login_name from votes, profiles where votes.bug_id = $id and profiles.userid = votes.who"); + while (MoreSQLData()) { + push(@cclist, FetchOneColumn()); + } $::bug{'cclist'} = \@cclist; diff --git a/showvotes.cgi b/showvotes.cgi new file mode 100755 index 000000000..1d03ae191 --- /dev/null +++ b/showvotes.cgi @@ -0,0 +1,120 @@ +#!/usr/bonsaitools/bin/perl -w +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public License +# Version 1.0 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations +# under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Netscape Communications +# Corporation. Portions created by Netscape are Copyright (C) 1998 +# Netscape Communications Corporation. All Rights Reserved. +# +# Contributor(s): Terry Weissman <terry@mozilla.org> + +use diagnostics; +use strict; + +require "CGI.pl"; + +if (defined $::FORM{'voteon'} || (!defined $::FORM{'bug_id'} && + !defined $::FORM{'user'})) { + confirm_login(); + ConnectToDatabase(); + $::FORM{'user'} = DBNameToIdAndCheck($::COOKIE{'Bugzilla_login'}); +} + +print "Content-type: text/html\n\n"; + +if (defined $::FORM{'bug_id'}) { + my $id = $::FORM{'bug_id'}; + my $linkedid = qq{<a href="show_bug.cgi?id=$id">$id</a>}; + PutHeader("Show votes", "Show votes", "Bug $linkedid"); + ConnectToDatabase(); + SendSQL("select profiles.login_name, votes.who, votes.count from votes, profiles where votes.bug_id = " . SqlQuote($id) . " and profiles.userid = votes.who"); + print "<table>\n"; + print "<tr><th>Who</th><th>Number of votes</th></tr>\n"; + my $sum = 0; + while (MoreSQLData()) { + my ($name, $userid, $count) = (FetchSQLData()); + print qq{<tr><td><a href="showvotes.cgi?user=$userid">$name</a></td><td align=right>$count</td></tr>\n}; + $sum += $count; + } + print "</table>"; + print "<p>Total votes: $sum<p>\n"; +} elsif (defined $::FORM{'user'}) { + ConnectToDatabase(); + quietly_check_login(); + GetVersionTable(); + my $who = $::FORM{'user'}; + my $name = DBID_to_name($who); + PutHeader("Show votes", "Show votes", $name); + print qq{<form action="doeditvotes.cgi">\n}; + print "<table><tr><td></td><th>Bug \#</th><th>Summary</th><th>Votes</th></tr>\n"; + SendSQL("lock tables bugs read, votes write"); + if (defined($::FORM{'voteon'})) { + # Oh, boy, what a hack. Make sure there is an entry for this bug + # in the vote table, just so that things display right. + # Yuck yuck yuck.### + SendSQL("select votes.count from votes where votes.bug_id = $::FORM{'voteon'} and votes.who = $who"); + if (!MoreSQLData()) { + SendSQL("insert into votes (who, bug_id, count) values ($who, $::FORM{'voteon'}, 0)"); + } + } + my $canedit = (defined $::COOKIE{'Bugzilla_login'} && + $::COOKIE{'Bugzilla_login'} eq $name); + foreach my $product (sort(keys(%::prodmaxvotes))) { + if ($::prodmaxvotes{$product} <= 0) { + next; + } + my $qprod = value_quote($product); + SendSQL("select votes.bug_id, votes.count, bugs.short_desc, bugs.bug_status from votes, bugs where votes.who = $who and votes.bug_id = bugs.bug_id and bugs.product = " . SqlQuote($product) . "order by votes.bug_id"); + my $sum = 0; + print "<tr><th>$product</th></tr>"; + while (MoreSQLData()) { + my ($id, $count, $summary, $status) = (FetchSQLData()); + my $opened = ($status eq "NEW" || $status eq "ASSIGNED" || + $status eq "REOPENED"); + my $strike = $opened ? "" : "<strike>"; + my $endstrike = $opened ? "" : "</strike>"; + $summary = html_quote($summary); + $sum += $count; + if ($canedit) { + $count = "<input name=$id value=$count size=5>"; + } + print qq{ +<tr> +<td></td> +<td><a href="showvotes.cgi?bug_id=$id">$id</a></td> +<td><a href="show_bug.cgi?id=$id">$strike$summary$endstrike</a></td> +<td align=right>$count</td> +</tr> +}; + } + my $plural = (($sum == 1) ? "" : "s"); + print "<td colspan=3>$sum vote$plural used out of\n"; + print "$::prodmaxvotes{$product} allowed.</td>\n"; + } + print "</table>\n"; + if ($canedit) { + print qq{<input type=submit value="Submit">\n}; + print "<br>To change your votes, type in new numbers (using zero to\n"; + print "mean no votes), and then click <b>Submit</b>.\n"; + } + print "<input type=hidden name=who value=$who>"; + print "</form>\n"; + SendSQL("delete from votes where count <= 0"); + SendSQL("unlock tables"); +} + +print qq{<a href="votehelp.html">Help! I don't understand this voting stuff</a>}; + +navigation_header(); + diff --git a/votehelp.html b/votehelp.html index 46b7de744..da76fa91e 100644 --- a/votehelp.html +++ b/votehelp.html @@ -48,5 +48,10 @@ To vote for a bug: may rebalance your votes as necessary. </ul> +You will automatically get email notifying you of any changes that +occur on bugs you vote for. + +<p> + You may review your votes at any time by clicking on the "Change your password or preferences" link at the bottom of the query page. |