summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGervase Markham <gerv@gerv.net>2013-01-02 18:09:36 +0100
committerGervase Markham <gerv@mozilla.org>2013-01-02 18:09:36 +0100
commit21b50cba4e08e723f8c2d8e8b5800d0a13e2c180 (patch)
tree504bae35d3f49fbbc951567fe07068294a949393
parentdb29480b097468be60ff0ffbc4344166443ae525 (diff)
downloadbugzilla-21b50cba4e08e723f8c2d8e8b5800d0a13e2c180.tar.gz
bugzilla-21b50cba4e08e723f8c2d8e8b5800d0a13e2c180.tar.xz
Bug 413851 - add CSV output option to request lists. r=LpSolit.
-rw-r--r--Bugzilla/CGI.pm25
-rwxr-xr-xbuglist.cgi31
-rwxr-xr-xreport.cgi7
-rwxr-xr-xrequest.cgi15
-rw-r--r--template/en/default/request/queue.csv.tmpl46
-rw-r--r--template/en/default/request/queue.html.tmpl6
6 files changed, 99 insertions, 31 deletions
diff --git a/Bugzilla/CGI.pm b/Bugzilla/CGI.pm
index cb92800f1..513babd4f 100644
--- a/Bugzilla/CGI.pm
+++ b/Bugzilla/CGI.pm
@@ -281,6 +281,10 @@ sub header {
unshift(@_, '-type' => shift(@_));
}
+ if ($self->{'_content_disp'}) {
+ unshift(@_, '-content_disposition' => $self->{'_content_disp'});
+ }
+
# Add the cookies in if we have any
if (scalar(@{$self->{Bugzilla_cookie_list}})) {
unshift(@_, '-cookie' => $self->{Bugzilla_cookie_list});
@@ -528,6 +532,22 @@ sub url_is_attachment_base {
return ($self->self_url =~ $regex) ? 1 : 0;
}
+sub set_dated_content_disp {
+ my ($self, $type, $prefix, $ext) = @_;
+
+ my @time = localtime(time());
+ my $date = sprintf "%04d-%02d-%02d", 1900+$time[5], $time[4]+1, $time[3];
+ my $filename = "$prefix-$date.$ext";
+
+ $filename =~ s/\s/_/g; # Remove whitespace to avoid HTTP header tampering
+ $filename =~ s/\\/_/g; # Remove backslashes as well
+ $filename =~ s/"/\\"/g; # escape quotes
+
+ my $disposition = "$type; filename=\"$filename\"";
+
+ $self->{'_content_disp'} = $disposition;
+}
+
##########################
# Vars TIEHASH Interface #
##########################
@@ -635,6 +655,11 @@ instead of calling this directly.
Redirects from the current URL to one prefixed by the urlbase parameter.
+=item C<set_dated_content_disp>
+
+Sets an appropriate date-dependent value for the Content Disposition header
+for a downloadable resource.
+
=back
=head1 SEE ALSO
diff --git a/buglist.cgi b/buglist.cgi
index a59f0ee18..8a436a0a2 100755
--- a/buglist.cgi
+++ b/buglist.cgi
@@ -281,18 +281,17 @@ sub GetGroups {
}
sub _close_standby_message {
- my ($contenttype, $disposition, $serverpush) = @_;
+ my ($contenttype, $disp, $disp_prefix, $extension, $serverpush) = @_;
my $cgi = Bugzilla->cgi;
-
+ $cgi->set_dated_content_disp($disp, $disp_prefix, $extension);
+
# Close the "please wait" page, then open the buglist page
if ($serverpush) {
print $cgi->multipart_end();
- print $cgi->multipart_start(-type => $contenttype,
- -content_disposition => $disposition);
+ print $cgi->multipart_start(-type => $contenttype);
}
else {
- print $cgi->header(-type => $contenttype,
- -content_disposition => $disposition);
+ print $cgi->header($contenttype);
}
}
@@ -324,17 +323,10 @@ $params ||= new Bugzilla::CGI($cgi);
# if available. We have to do this now, even though we return HTTP headers
# at the end, because the fact that there is a remembered query gets
# forgotten in the process of retrieving it.
-my @time = localtime(time());
-my $date = sprintf "%04d-%02d-%02d", 1900+$time[5],$time[4]+1,$time[3];
-my $filename = "bugs-$date.$format->{extension}";
+my $disp_prefix = "bugs";
if ($cmdtype eq "dorem" && $remaction =~ /^run/) {
- $filename = $cgi->param('namedcmd') . "-$date.$format->{extension}";
- # Remove white-space from the filename so the user cannot tamper
- # with the HTTP headers.
- $filename =~ s/\s/_/g;
+ $disp_prefix = $cgi->param('namedcmd');
}
-$filename =~ s/\\/\\\\/g; # escape backslashes
-$filename =~ s/"/\\"/g; # escape quotes
# Take appropriate action based on user's request.
if ($cmdtype eq "dorem") {
@@ -935,7 +927,8 @@ if ($one_product && $user->can_enter_product($one_product)) {
# The following variables are used when the user is making changes to multiple bugs.
if ($dotweak && scalar @bugs) {
if (!$vars->{'caneditbugs'}) {
- _close_standby_message('text/html', 'inline', $serverpush);
+ _close_standby_message('text/html',
+ 'inline', "error", "html", $serverpush);
ThrowUserError('auth_failure', {group => 'editbugs',
action => 'modify',
object => 'multiple_bugs'});
@@ -1042,10 +1035,8 @@ if ($format->{'extension'} eq "csv") {
$vars->{'human'} = $cgi->param('human');
}
-# Suggest a name for the bug list if the user wants to save it as a file.
-$disposition .= "; filename=\"$filename\"";
-
-_close_standby_message($contenttype, $disposition, $serverpush);
+_close_standby_message($contenttype, $disposition, $disp_prefix,
+ $format->{'extension'}, $serverpush);
################################################################################
# Content Generation
diff --git a/report.cgi b/report.cgi
index e70dcf4b2..69aadddbd 100755
--- a/report.cgi
+++ b/report.cgi
@@ -309,11 +309,8 @@ my $format = $template->get_format("reports/report", $formatparam,
# set debug=1 to always get an HTML content-type, and view the error.
$format->{'ctype'} = "text/html" if $cgi->param('debug');
-my @time = localtime(time());
-my $date = sprintf "%04d-%02d-%02d", 1900+$time[5],$time[4]+1,$time[3];
-my $filename = "report-$date.$format->{extension}";
-print $cgi->header(-type => $format->{'ctype'},
- -content_disposition => "inline; filename=$filename");
+$cgi->set_dated_content_disp("inline", "report", $format->{extension});
+print $cgi->header($format->{'ctype'});
# Problems with this CGI are often due to malformed data. Setting debug=1
# prints out both data structures.
diff --git a/request.cgi b/request.cgi
index 17e6c926d..436f94bc4 100755
--- a/request.cgi
+++ b/request.cgi
@@ -26,8 +26,12 @@ my $cgi = Bugzilla->cgi;
Bugzilla->switch_to_shadow_db;
my $template = Bugzilla->template;
my $action = $cgi->param('action') || '';
+my $format = $template->get_format('request/queue',
+ scalar($cgi->param('format')),
+ scalar($cgi->param('ctype')));
-print $cgi->header();
+$cgi->set_dated_content_disp("inline", "requests", $format->{extension});
+print $cgi->header($format->{'ctype'});
my $fields;
$fields->{'requester'}->{'type'} = 'single';
@@ -42,7 +46,7 @@ unless (defined $cgi->param('requestee')
Bugzilla::User::match_field($fields);
if ($action eq 'queue') {
- queue();
+ queue($format);
}
else {
my $flagtypes = get_flag_types();
@@ -60,7 +64,7 @@ else {
}
$vars->{'components'} = [ sort { $a cmp $b } keys %components ];
- $template->process('request/queue.html.tmpl', $vars)
+ $template->process($format->{'template'}, $vars)
|| ThrowTemplateError($template->error());
}
exit;
@@ -70,6 +74,7 @@ exit;
################################################################################
sub queue {
+ my $format = shift;
my $cgi = Bugzilla->cgi;
my $dbh = Bugzilla->dbh;
my $template = Bugzilla->template;
@@ -295,8 +300,10 @@ sub queue {
}
$vars->{'components'} = [ sort { $a cmp $b } keys %components ];
+ $vars->{'urlquerypart'} = $cgi->canonicalise_query('ctype');
+
# Generate and return the UI (HTML page) from the appropriate template.
- $template->process("request/queue.html.tmpl", $vars)
+ $template->process($format->{'template'}, $vars)
|| ThrowTemplateError($template->error());
}
diff --git a/template/en/default/request/queue.csv.tmpl b/template/en/default/request/queue.csv.tmpl
new file mode 100644
index 000000000..c6d962b4f
--- /dev/null
+++ b/template/en/default/request/queue.csv.tmpl
@@ -0,0 +1,46 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0. #%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+
+[% column_headers = {
+ "type" => "Flag",
+ "status" => field_descs.bug_status,
+ "bug_summary" => field_descs.short_desc,
+ "bug_id" => field_descs.bug_id,
+ "attach_summary" => "Attachment Description",
+ "attach_id" => "Attachment ID",
+ "requester" => "Requester",
+ "requestee" => "Requestee",
+ "created" => "Created",
+ "category" => field_descs.product _ ": " _ field_descs.component,
+} %]
+
+[% display_columns = ["requester", "requestee", "type", "status",
+ "bug_id", "bug_summary", "attach_id",
+ "attach_summary", "created", "category"] %]
+
+[% IF requests.size == 0 %]
+No requests.
+[% ELSE %]
+ [% FOREACH column = display_columns %]
+ [% column_headers.$column FILTER csv %][% ',' IF NOT loop.last() %]
+ [% END %]
+
+ [% FOREACH request = requests %]
+ [% FOREACH column = display_columns %]
+ [% IF column == 'created' %]
+ [% request.$column FILTER time FILTER csv %]
+ [% ELSIF column.match('^requeste') %]
+ [% request.$column FILTER email FILTER csv %]
+ [% ELSE %]
+ [% request.$column FILTER csv %]
+ [% END %][% ',' IF NOT loop.last() %]
+ [% END %]
+
+ [% END %]
+[% END %]
diff --git a/template/en/default/request/queue.html.tmpl b/template/en/default/request/queue.html.tmpl
index c2dc9809a..676e89264 100644
--- a/template/en/default/request/queue.html.tmpl
+++ b/template/en/default/request/queue.html.tmpl
@@ -207,6 +207,8 @@ to some group are shown by default.
</tr>
[% END %]
[% PROCESS display_buglist %]
+ <br><br>
+ <a href="request.cgi?[% urlquerypart FILTER html %]&amp;ctype=csv">View entire list as CSV</a>
[% END %]
[% PROCESS global/footer.html.tmpl %]
@@ -264,6 +266,6 @@ to some group are shown by default.
</table>
[% NEXT UNLESS buglist.keys.size %]
<a href="buglist.cgi?bug_id=
- [%- buglist.keys.nsort.join(",") FILTER html %]">(view as
- [%+ terms.bug %] list)</a>
+ [%- buglist.keys.nsort.join(",") FILTER html %]">View as
+ [%+ terms.bug %] list</a>
[% END %]