]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 413851 - add CSV output option to request lists. r=LpSolit.
authorGervase Markham <gerv@gerv.net>
Wed, 2 Jan 2013 17:09:36 +0000 (17:09 +0000)
committerGervase Markham <gerv@mozilla.org>
Wed, 2 Jan 2013 17:09:36 +0000 (17:09 +0000)
Bugzilla/CGI.pm
buglist.cgi
report.cgi
request.cgi
template/en/default/request/queue.csv.tmpl [new file with mode: 0644]
template/en/default/request/queue.html.tmpl

index cb92800f109f58fb85515bd16514ce4b7dd36487..513babd4f4974a769be77c3e3e2f6ef294db52ba 100644 (file)
@@ -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
index a59f0ee18ae98837a380eddd2846fef90ac04cf6..8a436a0a2998e45afa95ec1caa6759ecdf06ea72 100755 (executable)
@@ -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
index e70dcf4b2cfaf004dcca0f6064b08a3a7d940724..69aadddbd8f53f147f7330b7b99a8cde8a0f7ab7 100755 (executable)
@@ -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.
index 17e6c926d7725d40fb8c95a6e5042bd41a4dd54f..436f94bc4599cc6a09017f550e75b47b75c3e6ab 100755 (executable)
@@ -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 (file)
index 0000000..c6d962b
--- /dev/null
@@ -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 %]
index c2dc9809a9773d339322baa66f55eb2cc9800189..676e8926468315f05280c49a8e74f914d16fab8a 100644 (file)
@@ -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 %]