diff options
-rwxr-xr-x | reports.cgi | 214 | ||||
-rw-r--r-- | template/en/default/reports/old-charts.html.tmpl | 69 |
2 files changed, 143 insertions, 140 deletions
diff --git a/reports.cgi b/reports.cgi index 0f5842d0b..2c9f8facc 100755 --- a/reports.cgi +++ b/reports.cgi @@ -30,8 +30,10 @@ # daily stats file, so now works independently of collectstats.pl # version # Added image caching by date and datasets -# Myk Melez <myk@mozilla.org): +# Myk Melez <myk@mozilla.org>: # Implemented form field validation and reorganized code. +# Frédéric Buclin <LpSolit@gmail.com>: +# Templatization. use strict; @@ -47,9 +49,9 @@ $@ && ThrowCodeError("gd_not_installed"); eval "use Chart::Lines"; $@ && ThrowCodeError("chart_lines_not_installed"); -local our $dir = bz_locations()->{'datadir'} . "/mining"; -local our $graph_url = 'graphs'; -local our $graph_dir = bz_locations()->{'libpath'} . '/' .$graph_url; +my $dir = bz_locations()->{'datadir'} . "/mining"; +my $graph_url = 'graphs'; +my $graph_dir = bz_locations()->{'libpath'} . '/' .$graph_url; # If we're using bug groups for products, we should apply those restrictions # to viewing reports, as well. Time to check the login in that case. @@ -59,7 +61,7 @@ Bugzilla->switch_to_shadow_db(); my $cgi = Bugzilla->cgi; my $template = Bugzilla->template; -local our $vars = {}; +my $vars = {}; # We only want those products that the user has permissions for. my @myproducts; @@ -68,11 +70,33 @@ push( @myproducts, "-All-"); push( @myproducts, map { $_->name } @{$user->get_selectable_products} ); if (! defined $cgi->param('product')) { + # Can we do bug charts? + (-d $dir && -d $graph_dir) + || ThrowCodeError('chart_dir_nonexistent', + {dir => $dir, graph_dir => $graph_dir}); + + my %default_sel = map { $_ => 1 } qw/UNCONFIRMED NEW ASSIGNED REOPENED/; + + my @datasets; + my @data = get_data($dir); + + foreach my $dataset (@data) { + my $datasets = {}; + $datasets->{'value'} = $dataset; + $datasets->{'selected'} = $default_sel{$dataset} ? 1 : 0; + push(@datasets, $datasets); + } + + $vars->{'datasets'} = \@datasets; + $vars->{'products'} = \@myproducts; - choose_product(@myproducts); - $template->put_footer(); + print $cgi->header(); -} else { + $template->process('reports/old-charts.html.tmpl', $vars) + || ThrowTemplateError($template->error()); + exit; +} +else { my $product = $cgi->param('product'); # For security and correctness, validate the value of the "product" form variable. @@ -85,96 +109,49 @@ if (! defined $cgi->param('product')) { # This means that is OK to detaint trick_taint($product); - print $cgi->header(-Content_Disposition=>'inline; filename=bugzilla_report.html'); + defined($cgi->param('datasets')) || ThrowUserError('missing_datasets'); - $template->put_header("Bug Charts"); - $vars->{'header_done'} = 1; + my $datasets = join('', $cgi->param('datasets')); - show_chart($product); + my $type = chart_image_type(); + my $data_file = daily_stats_filename($product); + my $image_file = chart_image_name($data_file, $type, $datasets); + my $url_image = correct_urlbase() . "$graph_url/$image_file"; - $template->put_footer(); -} + if (! -e "$graph_dir/$image_file") { + generate_chart("$dir/$data_file", "$graph_dir/$image_file", $type, + $product, $datasets); + } + $vars->{'url_image'} = $url_image; -################################## -# user came in with no form data # -################################## + print $cgi->header(-Content_Disposition=>'inline; filename=bugzilla_report.html'); -sub choose_product { - my @myproducts = (@_); - my $cgi = Bugzilla->cgi; - my $template = Bugzilla->template; + $template->process('reports/old-charts.html.tmpl', $vars) + || ThrowTemplateError($template->error()); + exit; +} +##################### +# Subroutines # +##################### + +sub get_data { + my $dir = shift; + + my @datasets; my $datafile = daily_stats_filename('-All-'); + open(DATA, '<', "$dir/$datafile") + || ThrowCodeError('chart_file_open_fail', {filename => "$dir/$datafile"}); - # Can we do bug charts? - (-d $dir && -d $graph_dir) - || ThrowCodeError("chart_dir_nonexistent", - {dir => $dir, graph_dir => $graph_dir}); - - open(DATA, "$dir/$datafile") - || ThrowCodeError("chart_file_open_fail", {filename => "$dir/$datafile"}); - - print $cgi->header(); - $template->put_header("Bug Charts"); - $vars->{'header_done'} = 1; - - print <<FIN; -<center> -<h1>Welcome to the Bugzilla Charting Kitchen</h1> -<form method=get action=reports.cgi> -<table border=1 cellpadding=5> -<tr> -<td align=center><b>Product:</b></td> -<td align=center> -<select name="product"> -FIN -foreach my $product (@myproducts) { - $product = html_quote($product); - print qq{<option value="$product">$product</option>}; -} -print <<FIN; -</select> -</td> -</tr> -<tr> - <td align=center><b>Chart datasets:</b></td> - <td align=center> - <select name="datasets" multiple size=5> -FIN - - my @datasets = (); - - while (<DATA>) { - if (/^# fields?: (.+)\s*$/) { - @datasets = grep ! /date/i, (split /\|/, $1); - last; - } - } - - close(DATA); - - my %default_sel = map { $_ => 1 } - qw/UNCONFIRMED NEW ASSIGNED REOPENED/; - foreach my $dataset (@datasets) { - my $sel = $default_sel{$dataset} ? ' selected' : ''; - print qq{<option value="$dataset:"$sel>$dataset</option>\n}; - } - - print <<FIN; - </select> - </td> - </tr> -<tr> -<td colspan=2 align=center> -<input type=submit value=Continue> -</td> -</tr> -</table> -</center> -</form> -<p> -FIN + while (<DATA>) { + if (/^# fields?: (.+)\s*$/) { + @datasets = grep ! /date/i, (split /\|/, $1); + last; + } + } + close(DATA); + return @datasets; } sub daily_stats_filename { @@ -183,37 +160,6 @@ sub daily_stats_filename { return $prodname; } -sub show_chart { - my ($product) = @_; - my $cgi = Bugzilla->cgi; - - if (! defined $cgi->param('datasets')) { - ThrowUserError("missing_datasets", $vars); - } - my $datasets = join('', $cgi->param('datasets')); - - print <<FIN; -<center> -FIN - - my $type = chart_image_type(); - my $data_file = daily_stats_filename($product); - my $image_file = chart_image_name($data_file, $type, $datasets); - my $url_image = correct_urlbase() . "$graph_url/" - . url_quote($image_file); - - if (! -e "$graph_dir/$image_file") { - generate_chart("$dir/$data_file", "$graph_dir/$image_file", $type, - $product, $datasets); - } - - print <<FIN; -<img src="$url_image"> -<br clear=left> -<br> -FIN -} - sub chart_image_type { # what chart type should we be generating? my $testimg = Chart::Lines->new(2,2); @@ -234,8 +180,7 @@ sub chart_image_name { # numbers, underscores and hyphens. if ($datasets !~ m/^[A-Za-z0-9:_-]+$/) { - $vars->{'datasets'} = $datasets; - ThrowUserError('invalid_datasets', $vars); + ThrowUserError('invalid_datasets', {'datasets' => $datasets}); } # Since we pass the tests, consider it OK @@ -248,23 +193,14 @@ sub chart_image_name { return "${data_file}_${id}.$type"; } -sub day_of_year { - my ($mday, $month, $year) = (localtime())[3 .. 5]; - $month += 1; - $year += 1900; - my $date = sprintf "%02d%02d%04d", $mday, $month, $year; -} - sub generate_chart { my ($data_file, $image_file, $type, $product, $datasets) = @_; - + if (! open FILE, $data_file) { if ($product eq '-All-') { $product = ''; } - - $vars->{'product'} = $product; - ThrowCodeError("chart_data_not_generated", $vars); + ThrowCodeError('chart_data_not_generated', {'product' => $product}); } my @fields; @@ -279,8 +215,7 @@ sub generate_chart { if (/^# fields?: (.*)\s*$/) { @fields = split /\||\r/, $1; unless ($fields[0] =~ /date/i) { - $vars->{'file'} = $data_file; - ThrowCodeError("chart_datafile_corrupt", $vars); + ThrowCodeError('chart_datafile_corrupt', {'file' => $data_file}); } push @labels, grep($datasets{$_}, @fields); } @@ -288,10 +223,9 @@ sub generate_chart { } unless (@fields) { - $vars->{'file'} = $data_file; - ThrowCodeError("chart_datafile_corrupt", $vars); + ThrowCodeError('chart_datafile_corrupt', {'file' => $data_file}); } - + my @line = split /\|/; my $date = $line[0]; my ($yy, $mm, $dd) = $date =~ /^\d{2}(\d{2})(\d{2})(\d{2})$/; @@ -316,9 +250,9 @@ sub generate_chart { close FILE; if (! @{$data{DATE}}) { - ThrowUserError("insufficient_data_points", $vars); + ThrowUserError('insufficient_data_points'); } - + my $img = Chart::Lines->new (800, 600); my $i = 0; diff --git a/template/en/default/reports/old-charts.html.tmpl b/template/en/default/reports/old-charts.html.tmpl new file mode 100644 index 000000000..724dba6c3 --- /dev/null +++ b/template/en/default/reports/old-charts.html.tmpl @@ -0,0 +1,69 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (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. + # + # Contributor(s): Frédéric Buclin <LpSolit@gmail.com> + #%] + +[%# INTERFACE: + # products: an array of product names the user is allowed to view. + # datasets: an array of hashes with available statuses and resolutions. + # url_image: URL of the generated graph. + #%] + +[% PROCESS "global/field-descs.none.tmpl" %] + +[% PROCESS global/header.html.tmpl title = "$terms.Bug Charts" + h1 = "Welcome to the $terms.Bugzilla Charting Kitchen" %] + +<div align="center"> + [% IF url_image %] + <img src="[% url_image FILTER html %]"> + <br clear="both"> + [% ELSE %] + <form id="choose_product" method="get" action="reports.cgi"> + <table border="1" cellpadding="5" cellspacing="2"> + <tr> + <th>Product:</th> + <td align="center"> + <select id="product" name="product"> + [% FOREACH product = products %] + <option value="[% product FILTER html %]">[% product FILTER html %]</option> + [% END %] + </select> + </td> + </tr> + <tr> + <th>Chart datasets:</th> + <td align="center"> + <select id="datasets" name="datasets" multiple="multiple" size="5"> + [%# We cannot use translated statuses and resolutions from field-descs.none.html + # because old charts do not distinguish statuses from resolutions. %] + [% FOREACH dataset = datasets %] + <option value="[% dataset.value FILTER html %]:" + [% " selected=\"selected\"" IF dataset.selected %]> + [% dataset.value FILTER html %]</option> + [% END %] + </select> + </td> + </tr> + <tr> + <th colspan="2"> + <input type="submit" id="submit" value="Continue"> + </th> + </tr> + </table> + </form> + [% END %] +</div> + +[% PROCESS global/footer.html.tmpl %] |