r84691 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r84690‎ | r84691 | r84692 >
Date:18:33, 24 March 2011
Author:pdhanda
Status:deferred
Tags:
Comment:
Added weekly report mentioned in bug 25637#c3
Modified paths:
  • /trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport (added) (history)
  • /trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/Config.pm (added) (history)
  • /trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/Extension.pm (added) (history)
  • /trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/component-report.cgi (added) (history)
  • /trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/template (added) (history)
  • /trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/template/en (added) (history)
  • /trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/template/en/default (added) (history)
  • /trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/template/en/default/hook (added) (history)
  • /trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/template/en/default/hook/README (added) (history)
  • /trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/template/en/default/weeklyreport (added) (history)
  • /trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/template/en/default/weeklyreport/README (added) (history)
  • /trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/template/en/default/weeklyreport/component-report.html.tmpl (added) (history)
  • /trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/template/en/default/weeklyreport/weekly-bug-summary.html.tmpl (added) (history)
  • /trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/weekly-bug-summary.cgi (added) (history)

Diff [purge]

Index: trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/Config.pm
@@ -0,0 +1,27 @@
 2+# -*- Mode: perl; indent-tabs-mode: nil -*-
 3+#
 4+# The contents of this file are subject to the Mozilla Public
 5+# License Version 1.1 (the "License"); you may not use this file
 6+# except in compliance with the License. You may obtain a copy of
 7+# the License at http://www.mozilla.org/MPL/
 8+#
 9+# Software distributed under the License is distributed on an "AS
 10+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 11+# implied. See the License for the specific language governing
 12+# rights and limitations under the License.
 13+#
 14+# See: https://bugzilla.wikimedia.org/show_bug.cgi?id=25637#c3
 15+# Original Source code from http://websvn.kde.org/trunk/www/sites/bugs/
 16+
 17+package Bugzilla::Extension::WeeklyReport;
 18+use strict;
 19+
 20+use constant NAME => 'WeeklyReport';
 21+
 22+use constant REQUIRED_MODULES => [
 23+];
 24+
 25+use constant OPTIONAL_MODULES => [
 26+];
 27+
 28+__PACKAGE__->NAME;
Index: trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/Extension.pm
@@ -0,0 +1,30 @@
 2+# -*- Mode: perl; indent-tabs-mode: nil -*-
 3+#
 4+# The contents of this file are subject to the Mozilla Public
 5+# License Version 1.1 (the "License"); you may not use this file
 6+# except in compliance with the License. You may obtain a copy of
 7+# the License at http://www.mozilla.org/MPL/
 8+#
 9+# Software distributed under the License is distributed on an "AS
 10+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 11+# implied. See the License for the specific language governing
 12+# rights and limitations under the License.
 13+#
 14+# See: https://bugzilla.wikimedia.org/show_bug.cgi?id=25637#c3
 15+# Original Source code from http://websvn.kde.org/trunk/www/sites/bugs/
 16+
 17+
 18+package Bugzilla::Extension::WeeklyReport;
 19+use strict;
 20+use base qw(Bugzilla::Extension);
 21+
 22+our $VERSION = '0.01';
 23+
 24+# See the documentation of Bugzilla::Hook ("perldoc Bugzilla::Hook"
 25+# in the bugzilla directory) for a list of all available hooks.
 26+sub install_update_db {
 27+ my ($self, $args) = @_;
 28+
 29+}
 30+
 31+__PACKAGE__->NAME;
Index: trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/weekly-bug-summary.cgi
@@ -0,0 +1,386 @@
 2+#!/usr/bin/perl -wT
 3+
 4+# its stolen from somewhere but was mostly re-written by Dirk Mueller <mueller@kde.org>, 08/2006
 5+# templatized by Matt Rogers <mattr@kde.org>, 12/2007
 6+use strict;
 7+use lib ".";
 8+
 9+use Bugzilla;
 10+use Bugzilla::Constants;
 11+use Bugzilla::Util;
 12+use Bugzilla::Error;
 13+use Bugzilla::Field;
 14+
 15+sub total_bugs_in_bugzilla()
 16+{
 17+ my $dbh = Bugzilla->dbh;
 18+
 19+ # figure out total bugs
 20+ my (@totalbugs) = $dbh->selectrow_array(
 21+ "SELECT count(bugs.bug_id) FROM bugs WHERE bugs.bug_severity != 'enhancement' AND
 22+ ( bugs.bug_status = 'NEW' or bugs.bug_status = 'ASSIGNED' or
 23+ bugs.bug_status = 'REOPENED' or bugs.bug_status = 'UNCONFIRMED')"
 24+ );
 25+
 26+ # figure out total number of wishes
 27+ my (@totalwishes) = $dbh->selectrow_array (
 28+ "SELECT count(bugs.bug_id) FROM bugs WHERE bugs.bug_severity = 'enhancement' AND
 29+ ( bugs.bug_status = 'NEW' or bugs.bug_status = 'ASSIGNED' or
 30+ bugs.bug_status = 'REOPENED' or bugs.bug_status = 'UNCONFIRMED')"
 31+ );
 32+
 33+ return ($totalbugs[0], $totalwishes[0]);
 34+}
 35+
 36+sub bugs_opened()
 37+{
 38+ my($product, $days) = @_;
 39+
 40+ my $sqlproduct = "";
 41+ $sqlproduct = "AND bugs.product_id=$product"
 42+ if(defined $product and $product ne "%");
 43+
 44+ my ($count) = Bugzilla->dbh->selectrow_array(
 45+ "SELECT count(bugs.bug_id) FROM bugs
 46+ WHERE creation_ts >= from_days(to_days(NOW())-?)
 47+ $sqlproduct AND bugs.bug_severity != 'enhancement'", undef, ($days)
 48+ );
 49+
 50+ return $count;
 51+}
 52+
 53+sub wishes_opened()
 54+{
 55+ my($product, $days) = @_;
 56+
 57+ my $sqlproduct = "";
 58+ $sqlproduct = "AND bugs.product_id=" . Bugzilla->dbh->quote($product)
 59+ if(defined $product and $product ne "%");
 60+
 61+ my ($count) = Bugzilla->dbh->selectrow_array(
 62+ "SELECT count(bugs.bug_id) FROM bugs
 63+ WHERE creation_ts >= from_days(to_days(NOW())-?)
 64+ $sqlproduct AND bugs.bug_severity = 'enhancement'", undef, ($days)
 65+ );
 66+
 67+ return $count;
 68+}
 69+
 70+sub bugs_closed()
 71+{
 72+ my($product, $days) = @_;
 73+ my $query = "";
 74+ my $sqlproduct = "";
 75+ $sqlproduct = "AND bugs.product_id=" . Bugzilla->dbh->quote($product)
 76+ if(defined $product and $product ne "%");
 77+
 78+ my ($count) = Bugzilla->dbh->selectrow_array("
 79+select
 80+ count(distinct bugs.bug_id)
 81+from
 82+ bugs, bugs_activity
 83+where
 84+ bugs.bug_severity != 'enhancement' AND
 85+ (bugs_activity.added='RESOLVED' or bugs_activity.added='CLOSED' or
 86+ bugs_activity.added='NEEDSINFO')
 87+and
 88+ bugs_activity.bug_when >= FROM_DAYS(TO_DAYS(NOW())-?)
 89+and
 90+ bugs.bug_id = bugs_activity.bug_id
 91+ $sqlproduct
 92+ ", undef, ($days));
 93+
 94+ return($count);
 95+}
 96+
 97+sub wishes_closed()
 98+{
 99+ my($product, $days) = @_;
 100+ my $query = "";
 101+ my $sqlproduct = "";
 102+ $sqlproduct = "AND bugs.product_id=" . Bugzilla->dbh->quote($product)
 103+ if(defined $product and $product ne "%");
 104+
 105+ # We are going to build a long SQL query.
 106+ my ($count) = Bugzilla->dbh->selectrow_array("
 107+select
 108+ count(distinct bugs.bug_id)
 109+from
 110+ bugs, bugs_activity
 111+where
 112+ bugs.bug_severity = 'enhancement' AND
 113+ (bugs_activity.added='RESOLVED' or bugs_activity.added='CLOSED' or
 114+ bugs_activity.added='NEEDSINFO')
 115+and
 116+ bugs_activity.bug_when >= FROM_DAYS(TO_DAYS(NOW())-?)
 117+and
 118+ bugs.bug_id = bugs_activity.bug_id
 119+ $sqlproduct
 120+ ", undef, ($days));
 121+
 122+ return($count);
 123+}
 124+
 125+sub open_wishes()
 126+{
 127+ my($product) = @_;
 128+
 129+ my $sqlproduct = "";
 130+ $sqlproduct = "AND bugs.product_id=" . Bugzilla->dbh->quote($product)
 131+ if(defined $product and $product ne "%");
 132+
 133+ # We are going to build a long SQL query.
 134+ my ($count) = Bugzilla->dbh->selectrow_array("
 135+SELECT
 136+ count(bugs.bug_id)
 137+FROM bugs
 138+WHERE bugs.bug_severity = 'enhancement' AND
 139+ (bugs.bug_status = 'NEW' or bugs.bug_status = 'ASSIGNED' or
 140+ bugs.bug_status = 'REOPENED' or bugs.bug_status = 'UNCONFIRMED')
 141+$sqlproduct");
 142+
 143+ return $count;
 144+}
 145+
 146+
 147+# $format can be HTML or XML
 148+sub print_product_bug_lists() {
 149+ my($number, $days, $format, $fh) = @_;
 150+
 151+ my $query;
 152+
 153+ my @results;
 154+
 155+ # We are going to build a long SQL query.
 156+ my $sth = Bugzilla->dbh->prepare("
 157+select
 158+ products.name, bugs.product_id, count(bugs.product_id) as n
 159+from
 160+ bugs, products
 161+where
 162+ (bugs.bug_status = 'NEW' or bugs.bug_status = 'ASSIGNED' or
 163+ bugs.bug_status = 'REOPENED' or bugs.bug_status = 'UNCONFIRMED')
 164+and
 165+ bugs.bug_severity != 'enhancement'
 166+and
 167+ products.id = bugs.product_id
 168+
 169+group by product_id
 170+order by n desc
 171+limit $number
 172+ ");
 173+ $sth->execute;
 174+
 175+ # For each product we want to show the difference in the last period.
 176+ # But this will involve two sql connections at once, which the bugzilla
 177+ # functions don't handle too nicely.
 178+ # So lets collect the data first and then print the table.
 179+ my %product_count;
 180+ my %product_id;
 181+
 182+ while (my ($product, $p_id, $count) = $sth->fetchrow_array) {
 183+ $product_count{$product} = $count;
 184+ $product_id{$product} = $p_id;
 185+ }
 186+
 187+
 188+ foreach my $product (reverse sort
 189+ {$product_count{$a} <=> $product_count{$b}}
 190+ keys (%product_count)) {
 191+ my %product_results;
 192+ my $bopened = &bugs_opened($product_id{$product}, $days);
 193+ my $bclosed = &bugs_closed($product_id{$product}, $days);
 194+ $product_results{'id'} = $product_id{$product};
 195+ $product_results{'name'} = $product;
 196+ $product_results{'count'} = $product_count{$product};
 197+ $product_results{'bugs_opened'} = $bopened;
 198+ $product_results{'bugs_closed'} = $bclosed;
 199+ $product_results{'bugs_change'} = $bopened - $bclosed;
 200+ if( $product_results{'bugs_change'} > 0 ) {
 201+ $product_results{'bugs_change_color'} = "#FF9999";
 202+ } elsif( $product_results{'bugs_change'} < 0 ) {
 203+ $product_results{'bugs_change_color'} = "#99FF99";
 204+ }
 205+ $product_results{'total_wishes'} = &open_wishes($product_id{$product});
 206+ $product_results{'open_wishes'} = &wishes_opened($product_id{$product}, $days);
 207+ $product_results{'closed_wishes'} = &wishes_closed($product_id{$product}, $days);
 208+ $product_results{'wishes_change'} = $product_results{'open_wishes'} -
 209+ $product_results{'closed_wishes'};
 210+ if( $product_results{'wishes_change'} > 0 ) {
 211+ $product_results{'wish_change_color'} = "#FF9999";
 212+ } elsif( $product_results{'wishes_change'} < 0 ) {
 213+ $product_results{'wish_change_color'} = "#99FF99";
 214+ }
 215+ push @results, \%product_results;
 216+ }
 217+
 218+ return \@results;
 219+}
 220+
 221+sub print_bug_hunters_list() {
 222+ my($number, $days) = @_;
 223+ my @results;
 224+ my $query;
 225+
 226+ my $sth = Bugzilla->dbh->prepare("
 227+select
 228+ assign.login_name, count(assign.login_name), count(assign.login_name) as n
 229+from
 230+ bugs, bugs_activity, profiles assign
 231+where
 232+ (bugs_activity.added='RESOLVED' or bugs_activity.added = 'CLOSED' or
 233+ bugs_activity.added='NEEDSINFO')
 234+and
 235+ bugs_activity.bug_when >= from_days(TO_DAYS(NOW()) - ?)
 236+and
 237+ bugs_activity.who = assign.userid
 238+and
 239+ bugs.bug_id = bugs_activity.bug_id
 240+and
 241+ (bugs.bug_status = 'RESOLVED' or bugs.bug_status = 'CLOSED')
 242+group by assign.login_name
 243+order by n desc
 244+limit ?
 245+ ");
 246+
 247+ $sth->execute($days, $number);
 248+ while (my ($user, $count, $n) = $sth->fetchrow_array()) {
 249+
 250+ my %bh_results;
 251+
 252+ # defang the email address
 253+ $user =~ y/\@\./ / if (Bugzilla->user->id == 0);
 254+ $bh_results{'user'} = $user;
 255+ $bh_results{'count'} = $count;
 256+
 257+ push @results, \%bh_results;
 258+ }
 259+
 260+ return \@results;
 261+}
 262+
 263+sub print_bug_fixers_list() {
 264+ my($number, $days) = @_;
 265+ my @results;
 266+
 267+ my $sth = Bugzilla->dbh->prepare("
 268+SELECT
 269+ profiles.login_name, bugs.bug_id,
 270+ MIN(UNIX_TIMESTAMP(bugs_activity.bug_when)-UNIX_TIMESTAMP(bugs.creation_ts))
 271+ AS open_time
 272+FROM
 273+ bugs, bugs_activity, profiles, longdescs
 274+WHERE
 275+ bugs.resolution='FIXED'
 276+AND
 277+ bugs.bug_status='RESOLVED'
 278+AND
 279+ bugs_activity.bug_when >= FROM_DAYS(TO_DAYS(NOW())-?)
 280+AND
 281+ bugs.bug_id=bugs_activity.bug_id
 282+AND
 283+ bugs_activity.added='FIXED'
 284+AND
 285+ bugs_activity.who=profiles.userid
 286+AND
 287+ bugs.reporter != bugs_activity.who
 288+AND
 289+ longdescs.bug_id = bugs.bug_id
 290+AND
 291+ longdescs.who = bugs_activity.who
 292+AND
 293+ longdescs.thetext like \"SVN commit%\"
 294+GROUP BY
 295+ profiles.login_name, bugs.bug_id
 296+ORDER BY
 297+ open_time ASC
 298+LIMIT ?");
 299+
 300+ $sth->execute($days, $number);
 301+
 302+ while (my ($user, $bugid, $elapsed) = $sth->fetchrow_array) {
 303+
 304+ my %bf_results;
 305+
 306+ # defang the email address
 307+ $user =~ y/\@\./ / if (Bugzilla->user->id == 0);
 308+ $bf_results{'name'} = $user;
 309+ $bf_results{'elapsed'} = ${elapsed};
 310+ my $html_elapsed = "${elapsed}s";
 311+ $html_elapsed = int($elapsed/60) . " min" if ($elapsed > 60);
 312+ $html_elapsed = int($elapsed/(60*60)) . " h" if ($elapsed > (4*60*60));
 313+ $html_elapsed = int($elapsed/(60*60*24)) . " days" if ($elapsed > (58*60*60));
 314+ $bf_results{'formatted_elapsed'} = $html_elapsed;
 315+ $bf_results{'bugid'} = $bugid;
 316+
 317+ push @results, \%bf_results;
 318+ }
 319+
 320+ return \@results;
 321+}
 322+
 323+
 324+Bugzilla->login(LOGIN_OPTIONAL);
 325+
 326+# For most scripts we don't make $cgi and $template global variables. But
 327+# when preparing Bugzilla for mod_perl, this script used these
 328+# variables in so many subroutines that it was easier to just
 329+# make them globals.
 330+local our $cgi = Bugzilla->cgi;
 331+local our $template = Bugzilla->template;
 332+local our $vars = {};
 333+
 334+# Output appropriate HTTP response headers
 335+print $cgi->header(-type => 'text/html', -expires => '+3M');
 336+
 337+my %defaults;
 338+
 339+# If they didn't tell us a time period we choose the last week.
 340+my $current_days = 7;
 341+$current_days = $cgi->param('days') if (defined $cgi->param('days'));
 342+$current_days = 7 if (!detaint_natural($current_days));
 343+$defaults{'days'} = $current_days;
 344+
 345+my $current_tops = 20;
 346+$current_tops = $cgi->param('tops') if (defined $cgi->param('tops'));
 347+$current_tops = 20 if (!detaint_natural($current_tops));
 348+$defaults{'tops'} = $current_tops;
 349+
 350+$vars->{'duration'} = $current_days;
 351+$vars->{'top_number'} = $current_tops;
 352+
 353+($vars->{'totalbugs'}, $vars->{'totalwishes'}) = &total_bugs_in_bugzilla();
 354+
 355+my $bo = &bugs_opened("%", $current_days);
 356+my $wo = &wishes_opened("%", $current_days);
 357+my $bc = &bugs_closed("%", $current_days);
 358+my $wc = &wishes_closed("%", $current_days);
 359+
 360+$vars->{'new_open_bugs'} = $bo;
 361+$vars->{'new_closed_bugs'} = $bc;
 362+$vars->{'new_open_wishes'} = $wo;
 363+$vars->{'new_closed_wishes'} = $wc;
 364+
 365+my @tops = (10, 20, 30, 50, 100);
 366+$vars->{'tops'} = \@tops;
 367+
 368+my @days = (1, 2, 7, 14, 31, 180, 365);
 369+$vars->{'days'} = \@days;
 370+
 371+$vars->{'default'} = \%defaults;
 372+
 373+$vars->{'product_bug_lists'} = &print_product_bug_lists($current_tops, $current_days, "HTML");
 374+
 375+$vars->{'bug_hunters_list'} = &print_bug_hunters_list($current_tops, $current_days);
 376+
 377+$vars->{'bug_fixers_list'} = &print_bug_fixers_list($current_tops, $current_days);
 378+
 379+$template->process("weeklyreport/weekly-bug-summary.html.tmpl", $vars)
 380+ || ThrowTemplateError($template->error());
 381+
 382+
 383+
 384+
 385+
 386+print "</div>\n";
 387+
Property changes on: trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/weekly-bug-summary.cgi
___________________________________________________________________
Added: svn:executable
1388 + *
Index: trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/template/en/default/hook/README
@@ -0,0 +1,5 @@
 2+Template hooks go in this directory. Template hooks are called in normal
 3+Bugzilla templates like [% Hook.process('some-hook') %].
 4+More information about them can be found in the documentation of
 5+Bugzilla::Extension. (Do "perldoc Bugzilla::Extension" from the main
 6+Bugzilla directory to see that documentation.)
\ No newline at end of file
Index: trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/template/en/default/weeklyreport/weekly-bug-summary.html.tmpl
@@ -0,0 +1,95 @@
 2+[%# Wikimedia weekly bug summary template #%]
 3+
 4+[% PROCESS global/variables.none.tmpl %]
 5+
 6+[% PROCESS global/header.html.tmpl
 7+ title = "Wikimedia Weekly Bug Summary"
 8+%]
 9+
 10+<h3 style="text-align:center;">Total: [% totalbugs %] bugs and [% totalwishes %] enhancements</h3>
 11+
 12+<h4 style="text-align:center;">[% new_open_bugs %] bugs opened, [% new_closed_bugs %] bugs closed in the last [% duration %] days<br>
 13+([% new_open_wishes %] enhancements opened, [% new_closed_wishes %] enhancements closed)</h4>
 14+
 15+<form action="weekly-bug-summary.cgi" style="text-align:center;">Report top
 16+ [% sel = { name => 'tops'} %]
 17+ [% INCLUDE select %]
 18+summary over the last
 19+ [% sel = { name => 'days'} %]
 20+ [% INCLUDE select %]
 21+days and <input type="submit" value="Show" />
 22+</form>
 23+
 24+<h3 style="text-align:center;">Top [% top_number %] Wikimedia products with the most bugs:</h3>
 25+
 26+<table align="center" border="0" cellspacing="2" cellpadding="5">
 27+<tr style="background-color: #EEF6FF;"><th>Product</th>
 28+<th>Open<br />bugs</th>
 29+<th>Opened in<br />last [% duration %] days</th>
 30+<th>Closed in<br />last [% duration %] days</th>
 31+<th>Change</th>
 32+<th>Open<br />enhancements</th>
 33+<th>Opened in<br />last [% duration %] days</th>
 34+<th>Closed in<br />last [% duration %] days</th>
 35+<th>Change</th>
 36+<th>&nbsp;</th></tr>
 37+
 38+[%- FOREACH pr = product_bug_lists %]
 39+<tr>
 40+ <td><a href="component-report.cgi?product=[%- pr.name -%]">[%- pr.name -%]</a></td>
 41+ <td style="text-align:right;"><a href="buglist.cgi?product=[%- pr.name -%]&amp;bug_status=UNCONFIRMED&amp;bug_status=NEW&amp;bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;bug_severity=critical&amp;bug_severity=grave&amp;bug_severity=major&amp;bug_severity=crash&amp;bug_severity=normal&amp;bug_severity=minor">[%- pr.count -%]</a></td>
 42+ <td style="text-align:right;">+[%- pr.bugs_opened -%]</td>
 43+ <td style="text-align:right;">-[%- pr.bugs_closed -%]</td>
 44+ <td style="text-align:right; background-color: [%- pr.bugs_change_color -%];">[%- pr.bugs_change -%]</td>
 45+ <td style="text-align:right;"><a href="buglist.cgi?product=[%- pr.name -%]&amp;bug_status=UNCONFIRMED&amp;bug_status=NEW&amp;bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;bug_severity=enhancement">[%- pr.total_wishes -%]</a></td>
 46+ <td style="text-align:right;">+[%- pr.open_wishes -%]</td>
 47+ <td style="text-align:right;">-[%- pr.closed_wishes -%]</td>
 48+ <td style="text-align:right; background-color: [%- pr.wishes_change_color -%];">[%- pr.wishes_change -%]</td>
 49+ <td style="text-align:right;"><a href="reports.cgi?product=[%- pr.name -%]&output=show_chart&datasets=NEW%3A&datasets=ASSIGNED%3A&datasets=REOPENED%3A&datasets=UNCONFIRMED%3A&datasets=RESOLVED%3A&banner=1">Graph</a></td>
 50+</tr>
 51+[% END %]
 52+</table>
 53+
 54+<h3 style="text-align:center;"><a name="closers">Top [% top_number %] people who resolved the most reports in the last [% duration %] days:</a></h3>
 55+<table align="center" border="0" cellspacing="2" cellpadding="5">
 56+<tr style="background-color: #EEF6FF;">
 57+ <th>User</th><th># Resolved</th>
 58+</tr>
 59+[%- FOREACH bh = bug_hunters_list %]
 60+<tr>
 61+ <td>[% bh.user FILTER html %]</td>
 62+ <td>[% bh.count %]</td>
 63+<tr>
 64+[% END %]
 65+</table>
 66+
 67+<h3 style="text-align:center;"><a name="fixers">Top [% top_number %] people who most quickly fixed a report in the last [% duration %] days:</a></h3>
 68+<table align="center" border="0" cellspacing="2" cellpadding="5">
 69+<tr style="background-color: #EEF6FF;">
 70+<th>User</th><th>Elapsed time</th></tr>
 71+[%- FOREACH bf = bug_fixers_list %]
 72+<tr>
 73+ <td>[% bf.name FILTER html %]</td>
 74+ <td>[% bf.formatted_elapsed %] (<a href="show_bug.cgi?id=[% bf.bugid %]">[% bf.bugid %]</a>)</td>
 75+</tr>
 76+[% END %]
 77+</table>
 78+
 79+[% PROCESS global/footer.html.tmpl %]
 80+
 81+
 82+[%##########################################################################%]
 83+[%# Block for SELECT fields #%]
 84+[%##########################################################################%]
 85+
 86+[% BLOCK select %]
 87+ <select name="[% sel.name %]">
 88+ [%- FOREACH x = ${sel.name} %]
 89+ <option value="[% x FILTER html %]"
 90+ [% " selected=\"selected\"" IF x == default.${sel.name} %]>
 91+ [% x FILTER html %]
 92+ </option>
 93+ [% END %]
 94+ </select>
 95+[% END %]
 96+
Index: trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/template/en/default/weeklyreport/component-report.html.tmpl
@@ -0,0 +1,33 @@
 2+[%# KDE component report template #%]
 3+
 4+[% PROCESS global/variables.none.tmpl %]
 5+
 6+[% PROCESS global/header.html.tmpl
 7+ title = "Component Report"
 8+ h1 = "Report Count by Component and Severity"
 9+%]
 10+
 11+<p align="center">
 12+<table border="1" cellspacing="2" cellpadding="5" align="center">
 13+<tr style="background-color: #EEF6FF;">
 14+<td><b>Component</b></td>
 15+[% FOREACH sev = all_severities %]
 16+<td><b>[% sev %]</b></td>
 17+[% END %]
 18+<td><b>total</b></td>
 19+</tr>
 20+[% FOREACH comp = all_components %]
 21+<tr>
 22+ <td>[% product %] - [% comp %]</td>
 23+ [% FOREACH sev = all_severities %]
 24+ <td><a href="buglist.cgi?product=[% product %]&amp;component=[% comp %]&amp;bug_status=UNCONFIRMED&amp;bug_status=NEW&amp;bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;bug_severity=[% sev %]">[% bug_sev_counts.$comp.$sev %]</a></td>
 25+ [% END %]
 26+ <td><a href="buglist.cgi?product=[% product %]&amp;component=[% comp %]&amp;bug_status=UNCONFIRMED&amp;bug_status=NEW&amp;bug_status=ASSIGNED&amp;bug_status=REOPENED">[% bug_sev_counts.$comp.total %]</a></td>
 27+</tr>
 28+[% END %]
 29+
 30+
 31+</table>
 32+</p>
 33+[% PROCESS global/footer.html.tmpl %]
 34+
Index: trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/template/en/default/weeklyreport/README
@@ -0,0 +1,16 @@
 2+Normal templates go in this directory. You can load them in your
 3+code like this:
 4+
 5+use Bugzilla::Error;
 6+my $template = Bugzilla->template;
 7+$template->process('weeklyreport/some-template.html.tmpl')
 8+ or ThrowTemplateError($template->error());
 9+
 10+That would be how to load a file called some-template.html.tmpl that
 11+was in this directory.
 12+
 13+Note that you have to be careful that the full path of your template
 14+never conflicts with a template that exists in Bugzilla or in
 15+another extension, or your template might override that template. That's why
 16+we created this directory called 'weeklyreport' for you, so you
 17+can put your templates in here to help avoid conflicts.
\ No newline at end of file
Index: trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/component-report.cgi
@@ -0,0 +1,113 @@
 2+#!/usr/bin/perl -wT
 3+# -*- Mode: perl; indent-tabs-mode: nil -*-
 4+#
 5+# The contents of this file are subject to the Mozilla Public
 6+# License Version 1.1 (the "License"); you may not use this file
 7+# except in compliance with the License. You may obtain a copy of
 8+# the License at http://www.mozilla.org/MPL/
 9+#
 10+# Software distributed under the License is distributed on an "AS
 11+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 12+# implied. See the License for the specific language governing
 13+# rights and limitations under the License.
 14+#
 15+# The Original Code is the Bugzilla Bug Tracking System.
 16+#
 17+# The Initial Developer of the Original Code is Netscape Communications
 18+# Corporation. Portions created by Netscape are
 19+# Copyright (C) 1998 Netscape Communications Corporation. All
 20+# Rights Reserved.
 21+#
 22+# Contributor(s): Harrison Page <harrison@netscape.com>,
 23+# Terry Weissman <terry@mozilla.org>,
 24+# Dawn Endico <endico@mozilla.org>
 25+# Bryce Nesbitt <bryce@nextbus.COM>,
 26+# Added -All- report, change "nobanner" to "banner" (it is strange to have a
 27+# list with 2 positive and 1 negative choice), default links on, add show
 28+# sql comment.
 29+# Joe Robins <jmrobins@tgix.com>,
 30+# If using the usebuggroups parameter, users shouldn't be able to see
 31+# reports for products they don't have access to.
 32+# Gervase Markham <gerv@gerv.net> and Adam Spiers <adam@spiers.net>
 33+# Added ability to chart any combination of resolutions/statuses.
 34+# Derive the choice of resolutions/statuses from the -All- data file
 35+# Removed hardcoded order of resolutions/statuses when reading from
 36+# daily stats file, so now works independently of collectstats.pl
 37+# version
 38+# Added image caching by date and datasets
 39+# Myk Melez <myk@mozilla.org):
 40+# Implemented form field validation and reorganized code.
 41+#
 42+# Luis Villa <louie@ximian.com>:
 43+# modified it to report things in a new format
 44+# Matt Rogers <mattr@kde.org>:
 45+# Rewritten for bugzilla 3.0 including template
 46+
 47+use strict;
 48+use lib qw(.);
 49+
 50+use Bugzilla;
 51+use Bugzilla::Product;
 52+use Bugzilla::Constants;
 53+use Bugzilla::Error;
 54+
 55+use vars qw($vars $template);
 56+
 57+eval "use GD";
 58+my $use_gd = $@ ? 0 : 1;
 59+eval "use Chart::Lines";
 60+$use_gd = 0 if $@;
 61+
 62+# If we're using bug groups for products, we should apply those restrictions
 63+# to viewing reports, as well. Time to check the login in that case.
 64+
 65+my $cgi = Bugzilla->cgi;
 66+my $template = Bugzilla->template;
 67+my $vars = {};
 68+my $user = Bugzilla->login(LOGIN_OPTIONAL);
 69+
 70+print $cgi->header(-type => 'text/html', -expires => '+3M');
 71+
 72+my $query = <<EOF
 73+SELECT count(*), products.name, components.name, bug_severity
 74+ FROM bugs, products, components
 75+ WHERE ( bug_status = 'NEW' or bug_status = 'ASSIGNED' or bug_status = 'REOPENED' or bug_status = 'UNCONFIRMED' )
 76+ AND products.name = ?
 77+ AND bugs.product_id = products.id
 78+ AND bugs.component_id = components.id
 79+ AND products.id = components.product_id
 80+GROUP BY products.name, components.name, bug_severity
 81+ORDER BY components.name
 82+EOF
 83+;
 84+
 85+#Report on components by severity and priority
 86+my $sth = Bugzilla->dbh->prepare($query);
 87+my $product = $cgi->param('product');
 88+if ($product =~ /^([\w.-\s]+)$/) { $product = $1 }
 89+$sth->execute($product);
 90+
 91+my (@bug_counts, %bugs, %total_bugs);
 92+my $disp_component;
 93+my $total_bug_count;
 94+
 95+my $product_obj = new Bugzilla::Product({ 'name' => $product });
 96+
 97+$vars->{'product'} = $product;
 98+$vars->{'all_severities'} = Bugzilla::Field::get_legal_field_values('bug_severity');
 99+my @compnames;
 100+for my $comp (@{$product_obj->components}) {
 101+ push @compnames, $comp->name
 102+}
 103+$vars->{'all_components'} = \@compnames;
 104+
 105+while (my ($bcount, $product, $component, $sever) = $sth->fetchrow_array) {
 106+ $bugs{$component}{$sever} = $bcount;
 107+ $bugs{$component}{'total'} += $bcount;
 108+}
 109+
 110+$vars->{'bug_sev_counts'} = \%bugs;
 111+
 112+$template->process("weeklyreport/component-report.html.tmpl", $vars)
 113+ || ThrowTemplateError($template->error());
 114+
Property changes on: trunk/tools/bugzilla/bugzilla-4.0/extensions/WeeklyReport/component-report.cgi
___________________________________________________________________
Added: svn:executable
1115 + *

Follow-up revisions

RevisionCommit summaryAuthorDate
r84692Added link to weekly report mentioned in bug 25637#c3pdhanda18:35, 24 March 2011

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r78079(bug 25637) Make weekly report part of Bugzilla. Commit a basic framework for...demon17:35, 8 December 2010

Status & tagging log