1# BEGIN BPS TAGGED BLOCK {{{ 2# 3# COPYRIGHT: 4# 5# This software is Copyright (c) 1996-2021 Best Practical Solutions, LLC 6# <sales@bestpractical.com> 7# 8# (Except where explicitly superseded by other copyright notices) 9# 10# 11# LICENSE: 12# 13# This work is made available to you under the terms of Version 2 of 14# the GNU General Public License. A copy of that license should have 15# been provided with this software, but in any event can be snarfed 16# from www.gnu.org. 17# 18# This work is distributed in the hope that it will be useful, but 19# WITHOUT ANY WARRANTY; without even the implied warranty of 20# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21# General Public License for more details. 22# 23# You should have received a copy of the GNU General Public License 24# along with this program; if not, write to the Free Software 25# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26# 02110-1301 or visit their web page on the internet at 27# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. 28# 29# 30# CONTRIBUTION SUBMISSION POLICY: 31# 32# (The following paragraph is not intended to limit the rights granted 33# to you to modify and distribute this software under the terms of 34# the GNU General Public License and is only of importance to you if 35# you choose to contribute your changes and enhancements to the 36# community by submitting them to Best Practical Solutions, LLC.) 37# 38# By intentionally submitting any modifications, corrections or 39# derivatives to this work, or any other work intended for use with 40# Request Tracker, to Best Practical Solutions, LLC, you confirm that 41# you are the copyright holder for those contributions and you grant 42# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, 43# royalty-free, perpetual, license to use, copy, create derivative 44# works based on those contributions, and sublicense and distribute 45# those contributions and any derivatives thereof. 46# 47# END BPS TAGGED BLOCK }}} 48 49package RT::Shredder::Plugin::Attachments; 50 51use strict; 52use warnings FATAL => 'all'; 53use base qw(RT::Shredder::Plugin::Base::Search); 54 55=head1 NAME 56 57RT::Shredder::Plugin::Attachments - search plugin for wiping attachments. 58 59=head1 ARGUMENTS 60 61=head2 files_only - boolean value 62 63Search only file attachments. 64 65=head2 file - mask 66 67Search files with specific file name only. 68 69Example: '*.xl?' or '*.gif' 70 71=head2 longer - attachment content size 72 73Search attachments which content is longer than specified. 74You can use trailing 'K' or 'M' character to specify size in 75kilobytes or megabytes. 76 77=cut 78 79sub SupportArgs { return $_[0]->SUPER::SupportArgs, qw(files_only file longer) } 80 81sub TestArgs 82{ 83 my $self = shift; 84 my %args = @_; 85 my $queue; 86 if( $args{'file'} ) { 87 unless( $args{'file'} =~ /^[\w\. *?]+$/) { 88 return( 0, "Files mask '$args{file}' has invalid characters" ); 89 } 90 $args{'file'} = $self->ConvertMaskToSQL( $args{'file'} ); 91 } 92 if( $args{'longer'} ) { 93 unless( $args{'longer'} =~ /^\d+\s*[mk]?$/i ) { 94 return( 0, "Invalid file size argument '$args{longer}'" ); 95 } 96 } 97 return $self->SUPER::TestArgs( %args ); 98} 99 100sub Run 101{ 102 my $self = shift; 103 my @conditions = (); 104 my @values = (); 105 if( $self->{'opt'}{'file'} ) { 106 my $mask = $self->{'opt'}{'file'}; 107 push @conditions, "( Filename LIKE ? )"; 108 push @values, $mask; 109 } 110 if( $self->{'opt'}{'files_only'} ) { 111 push @conditions, "( LENGTH(Filename) > 0 )"; 112 } 113 if( $self->{'opt'}{'longer'} ) { 114 my $size = $self->{'opt'}{'longer'}; 115 $size =~ s/([mk])//i; 116 $size *= 1024 if $1 && lc $1 eq 'k'; 117 $size *= 1024*1024 if $1 && lc $1 eq 'm'; 118 push @conditions, "( LENGTH(Content) > ? )"; 119 push @values, $size; 120 } 121 return (0, "At least one condition should be provided" ) unless @conditions; 122 my $query = "SELECT id FROM Attachments WHERE ". join ' AND ', @conditions; 123 if( $self->{'opt'}{'limit'} ) { 124 $RT::Handle->ApplyLimits( \$query, $self->{'opt'}{'limit'} ); 125 } 126 my $sth = $RT::Handle->SimpleQuery( $query, @values ); 127 return (0, "Internal error: '$sth'. Please send bug report.") unless $sth; 128 129 my @objs; 130 while( my $row = $sth->fetchrow_arrayref ) { 131 push @objs, $row->[0]; 132 } 133 return (0, "Internal error: '". $sth->err ."'. Please send bug report.") if $sth->err; 134 135 @objs = map {"RT::Attachment-$_"} @objs; 136 137 return (1, @objs); 138} 139 1401; 141 142