#!/usr/bin/perl -w # BugZilla statistics tool. # Generates a graph of reported and closed bugs for easier determining # wheter a project is going the right way for a release. A day is one # where either a bug was reported, fixed, or both. # Copyright (C) 2001 Thomas Eibner # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 675 Mass Ave, Cambridge, MA 02139, USA. # $Id: bugzillastats.pl,v 1.2 2001/07/30 04:32:34 thomas Exp $ use strict; use CGI::Carp qw(fatalsToBrowser); use DBI; use GD::Graph::lines; my $bug_days_limit = 25; my $product_name = 'ProductName'; my $db_src = 'DBI:mysql:bugzilla'; my $db_user = 'bugzilla'; my $db_pass = 'secret'; my $dbh = DBI->connect($db_src, $db_user, $db_pass, { RaiseError => 1 }) or die $DBI::errstr; my %bugs = (); my $sth_bugs_reported = $dbh->prepare(qq{select count(bug_id), DATE_FORMAT(creation_ts, "%Y%m%d") from bugs where product = ? group by 2 order by 2 desc limit ?}); my $sth_bugs_fixed = $dbh->prepare(qq{select count(bug_id), DATE_FORMAT(delta_ts, "%Y%m%d") from bugs where product = ? and (bug_status = 'RESOLVED' or bug_status = 'VERIFIED' or bug_status = 'CLOSED') group by 2 order by 2 desc limit ?}); $sth_bugs_reported->execute($product_name, $bug_days_limit); $sth_bugs_fixed->execute($product_name, $bug_days_limit); while (my ($count, $date) = $sth_bugs_reported->fetchrow_array()) { $bugs{$date}->{'new'} = $count; $bugs{$date}->{'fixed'} = 0; } while (my ($count, $date) = $sth_bugs_fixed->fetchrow_array()) { if (defined $bugs{$date}) { $bugs{$date}->{'fixed'} = $count; } else { $bugs{$date}->{'fixed'} = $count; $bugs{$date}->{'new'} = 0; } } $sth_bugs_reported->finish(); $dbh->disconnect(); my @keys = sort keys %bugs; my @new = (); my @fixed = (); foreach my $key (@keys) { push @new, $bugs{$key}->{'new'}; push @fixed, $bugs{$key}->{'fixed'}; } my @data = ( \@keys, \@new, \@fixed ); my $graph = new GD::Graph::lines(800,600); $graph->set( x_label => 'Time', y_label => 'Count', title => "Bug reports/fixes for $product_name", y_max_value => 25, y_min_value => 0, y_tick_number => 5, box_axis => 0, line_width => 2, zero_axis_only => 0, x_label_position => 1, y_label_position => 1, x_label_skip => 5, x_tick_offset => 5, transparent => 0 ); $graph->set_legend("New", "Fixed"); $graph->plot(\@data); save_chart($graph, 'bugs'); sub save_chart { my $chart = shift or die "Need a chart!"; my $name = shift or die "Need a name!"; my $ext = $chart->export_format; print qq{Content-Type: image/$ext\r\n\r\n}; binmode STDOUT; print STDOUT $chart->gd->$ext(); }