X-Git-Url: http://git.home-dn.net/?p=manu%2FRT-Extension-SearchResults-ODS.git;a=blobdiff_plain;f=html%2FSearch%2FResults.ods;fp=html%2FSearch%2FResults.ods;h=37d4e6f2140a043bddb4f4bb528fee51c3362363;hp=9659c86b319446de4d5edd2b716769d7f17aa345;hb=8c7186545d13b38783caf887a92871536aa01d18;hpb=d4074b22b5c51361a938461b25bbc68acb6d31f2 diff --git a/html/Search/Results.ods b/html/Search/Results.ods index 9659c86..37d4e6f 100644 --- a/html/Search/Results.ods +++ b/html/Search/Results.ods @@ -1,40 +1,40 @@ %# BEGIN BPS TAGGED BLOCK {{{ -%# +%# %# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC -%# -%# +%# +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC +%# +%# %# (Except where explicitly superseded by other copyright notices) -%# -%# +%# +%# %# LICENSE: -%# +%# %# This work is made available to you under the terms of Version 2 of %# the GNU General Public License. A copy of that license should have %# been provided with this software, but in any event can be snarfed %# from www.gnu.org. -%# +%# %# This work 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., 51 Franklin Street, Fifth Floor, Boston, MA %# 02110-1301 or visit their web page on the internet at %# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -%# -%# +%# +%# %# CONTRIBUTION SUBMISSION POLICY: -%# +%# %# (The following paragraph is not intended to limit the rights granted %# to you to modify and distribute this software under the terms of %# the GNU General Public License and is only of importance to you if %# you choose to contribute your changes and enhancements to the %# community by submitting them to Best Practical Solutions, LLC.) -%# +%# %# By intentionally submitting any modifications, corrections or %# derivatives to this work, or any other work intended for use with %# Request Tracker, to Best Practical Solutions, LLC, you confirm that @@ -43,13 +43,20 @@ %# royalty-free, perpetual, license to use, copy, create derivative %# works based on those contributions, and sublicense and distribute %# those contributions and any derivatives thereof. -%# +%# %# END BPS TAGGED BLOCK }}} <%ARGS> +$Format => undef +$Query => '' $OrderBy => 'id' $Order => 'ASC' +$PreserveNewLines => 0 +<%ONCE> +my $no_html = HTML::Scrubber->new( deny => '*' ); + <%INIT> +require HTML::Entities; use OpenOffice::OODoc; my $tmpdir; @@ -64,57 +71,73 @@ my $tmpfile = File::Spec->catfile( $tmpdir, 'Results.ods' ); odfWorkingDirectory($tmpdir); my $workbook = odfDocument(file => $tmpfile, create => 'spreadsheet') or die $!; -my $Tickets = RT::Tickets->new( $session{'CurrentUser'} ); -$Tickets->FromSQL( $ARGS{'Query'} ); -if ( $OrderBy =~ /\|/ ) { +$r->content_type('application/vnd.oasis.opendocument.spreadsheet'); - # Multiple Sorts - my @OrderBy = split /\|/, $OrderBy; - my @Order = split /\|/, $Order; - $Tickets->OrderByCols( - map { { FIELD => $OrderBy[$_], ORDER => $Order[$_] } } - ( 0 .. $#OrderBy ) ); -} -else { - $Tickets->OrderBy( FIELD => $OrderBy, ORDER => $Order ); -} +my $DisplayFormat = $m->comp('/Elements/ScrubHTML', Content => $Format); -my @rows; -my %known_cfs; +my @Format = $m->comp('/Elements/CollectionAsTable/ParseFormat', Format => $DisplayFormat); -my @attrs = qw( id QueueObj->Name Subject Status TimeEstimated TimeWorked TimeLeft Priority FinalPriority OwnerObj->Name - Requestors->MemberEmailAddressesAsString Cc->MemberEmailAddressesAsString AdminCc->MemberEmailAddressesAsString - DueObj->ISO ToldObj->ISO CreatedObj->ISO ResolvedObj->ISO LastUpdatedObj->ISO); +my @columns; -$r->content_type('application/vnd.oasis.opendocument.spreadsheet'); -while ( my $Ticket = $Tickets->Next()) { - my $row; - foreach my $attr (@attrs) { - if ($attr =~ /(.*)->ISO$/ and $Ticket->$1->Unix <= 0) { - $row->{$attr} = ""; - } else { - my $method = '$Ticket->'.$attr.'()'; - $method =~ s/->ISO\(\)$/->ISO( Timezone => 'user' )/; - $row->{$attr} = eval $method; - if ($@) {die "Failed to find $attr - ". $@}; - } - } +my $should_loc = { map { $_ => 1 } qw(Status) }; - my $cfs = $Ticket->QueueObj->TicketCustomFields(); - while (my $cf = $cfs->Next) { - $known_cfs{$cf->Id} = $cf->Name; - my @content; - my $values = $Ticket->CustomFieldValues($cf->Id); - while (my $value = $values->Next) { - push @content, $value->Content; +my $col_entry = sub { + my $col = shift; + # in tsv output, "#" is often a comment character but we use it for "id" + delete $col->{title} + if $col->{title} and $col->{title} =~ /^\s*#\s*$/; + return { + header => Encode::encode_utf8(loc($col->{title} || $col->{attribute})), + map => $m->comp( + "/Elements/ColumnMap", + Name => $col->{attribute}, + Attr => 'value' + ), + should_loc => $should_loc->{$col->{attribute}}, + } +}; + +if ($PreserveNewLines) { + my $col = []; + push @columns, $col; + for (@Format) { + if ($_->{title} eq 'NEWLINE') { + $col = []; + push @columns, $col; + } + else { + push @$col, $col_entry->($_); } - $row->{'CustomField-'.$cf->Id} = join(', ',@content); } - push @rows, $row; +} +else { + push @columns, [map { $_->{attribute} + ? $col_entry->($_) + : () } @Format]; +} + +my $Tickets = RT::Tickets->new( $session{'CurrentUser'} ); +$Tickets->FromSQL( $Query ); +if ( $OrderBy =~ /\|/ ) { + # Multiple Sorts + my @OrderBy = split /\|/, $OrderBy; + my @Order = split /\|/, $Order; + $Tickets->OrderByCols( + map { { FIELD => $OrderBy[$_], ORDER => $Order[$_] } } + ( 0 .. $#OrderBy ) + ); +} +else { + $Tickets->OrderBy( FIELD => $OrderBy, ORDER => $Order ); } -my $rows_count = scalar(@rows) + 1; -my $cols_count = scalar(@attrs) + scalar( keys %known_cfs ); +my $rows_count = $Tickets->Count; +my $cols_count = 0; +foreach my $col (@columns) { + foreach my $sub_col (@$col) { + $cols_count++; + } +} $workbook->expandTable(0, $rows_count, $cols_count ); @@ -135,47 +158,41 @@ sub int_to_alpha { return $alpha; } - my $xml = ''; my $xmlpos = $workbook->getElement('//table:table', 0); -$workbook->insertElement ( $xmlpos, $xml, position => 'after'); - -{ - my @header; - my $ws_col = 0; - foreach my $attr (@attrs) { - my $label = $attr; - $label =~ s'Obj-.(?:AsString|Name|ISO)''g; - $label =~ s'-\>MemberEmailAddressesAsString''g; +$workbook->insertElement ( $xmlpos, $xml, position => 'after'); + +my $ws_col = 0; +foreach my $col (@columns) { + foreach my $sub_col ( @$col ) { + my $label = $sub_col->{header}; Encode::_utf8_off($label); $workbook->updateCell(0, 0, $ws_col, $label); $ws_col++; } - foreach my $id (sort keys %known_cfs) { - Encode::_utf8_off($known_cfs{$id}); - $workbook->updateCell(0, 0, $ws_col, "CF-".$known_cfs{$id}); - $ws_col++; - } } my $ws_row = 1; -foreach my $row (@rows) { - my $ws_col = 0; - my @row; - foreach my $attr(@attrs) { - Encode::_utf8_off($row->{"$attr"}); - $workbook->updateCell(0, $ws_row, $ws_col, $row->{"$attr"}); - $ws_col++; - } - foreach my $id (sort keys %known_cfs) { - my $val = $row->{'CustomField-'.$id}; - #$val =~ s/(\n|\r)//g; - Encode::_utf8_off($val); - $workbook->updateCell(0, $ws_row, $ws_col, $val); - $ws_col++; +my $ii = 0; +while (my $row = $Tickets->Next) { + $ws_col = 0; + for my $col (@columns) { + for (@$col) { + my $val = ProcessColumnMapValue($_->{map}, Arguments => [$row, $ii++], Escape => 0); + $val = loc($val) if $_->{should_loc}; + # remove tabs from all field values, they screw up the tsv + $val = '' unless defined $val; + $val =~ s/(?:\n|\r)//g; $val =~ s{\t}{ }g; + $val = $no_html->scrub($val); + $val = HTML::Entities::decode_entities($val); + Encode::_utf8_off($val); + $workbook->updateCell(0, $ws_row, $ws_col, $val); + $ws_col++; + } } $ws_row++; } + $workbook->save(); open (ODT, $tmpfile); while () { @@ -184,5 +201,7 @@ while () { close (ODT); unlink ($tmpfile); $m->abort(); - +$m->abort(); + +