#!/usr/bin/perl -w # -- # mkStats.pl - send stats output via email # Copyright (C) 2001-2007 OTRS GmbH, http://otrs.org/ # -- # $Id: mkStats.pl,v 1.49 2007/07/31 13:09:19 tr Exp $ # -- # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -- use strict; use warnings; # use ../ as lib location use File::Basename; use FindBin qw($RealBin); use lib dirname($RealBin); use lib dirname($RealBin)."/Kernel/cpan-lib"; use vars qw($VERSION); $VERSION = '$Revision: 1.49 $'; $VERSION =~ s/^\$.*:\W(.*)\W.+?$/$1/; use Getopt::Std; use Kernel::Config; use Kernel::System::Time; use Kernel::System::Main; use Kernel::System::DB; use Kernel::System::Log; use Kernel::System::Email; use Kernel::System::CheckItem; use Kernel::System::Stats; use Kernel::System::Group; use Kernel::System::User; use Kernel::System::CSV; use Kernel::System::PDF; use Kernel::Language; # create common objects my %CommonObject = (); $CommonObject{UserID} = 1; $CommonObject{ConfigObject} = Kernel::Config->new(); $CommonObject{LogObject} = Kernel::System::Log->new( LogPrefix => 'OTRS-SendStats', %CommonObject, ); $CommonObject{CSVObject} = Kernel::System::CSV->new(%CommonObject); $CommonObject{TimeObject} = Kernel::System::Time->new(%CommonObject); $CommonObject{MainObject} = Kernel::System::Main->new(%CommonObject); $CommonObject{DBObject} = Kernel::System::DB->new(%CommonObject); $CommonObject{GroupObject} = Kernel::System::Group->new(%CommonObject); $CommonObject{UserObject} = Kernel::System::User->new(%CommonObject); $CommonObject{StatsObject} = Kernel::System::Stats->new(%CommonObject); $CommonObject{CheckItemObject} = Kernel::System::CheckItem->new(%CommonObject); $CommonObject{EmailObject} = Kernel::System::Email->new(%CommonObject); $CommonObject{PDFObject} = Kernel::System::PDF->new(%CommonObject); # get options my %Opts = (); getopt('nrsmhoplf', \%Opts); if ($Opts{'h'}) { print "mkStats.pl - OTRS cmd stats\n"; print "Copyright (C) 2001-2006 OTRS GmbH, http://otrs.org/\n"; print "usage: mkStats.pl -n [-p ] [-o ] [-r -s ] [-m ] [-l ] [-f CSV|Print]\n"; print " e. g. 'Year=1977&Month=10' (only for static files)\n"; print " /output/dir/\n"; exit 1; } # required output param check if (!$Opts{o} && !$Opts{r}) { print STDERR "ERROR: Need -o /tmp/ OR -r email\@example.com [-m 'some message']\n"; exit 1; } # stats module check if (!$Opts{n}) { print STDERR "ERROR: Need -n StatNumber\n"; exit 1; } # fill up body if (!$Opts{m} && $Opts{p}) { $Opts{m} .= "Stats with following options:\n\n"; $Opts{m} .= "StatNumber: $Opts{n}\n"; my @P = split(/&/, $Opts{'p'}); for (@P) { my ($Key, $Value) = split(/=/, $_, 2); $Opts{'m'} .= "$Key: $Value\n"; } } # only necessary for emails if (!$Opts{m} && $Opts{r}) { print STDERR "ERROR: Need -m 'some message (necessary for emails)'\n"; exit 1; } # language my $Lang = $CommonObject{ConfigObject}->Get('DefaultLanguage') || 'en'; if ($Opts{l}) { $Lang = $Opts{l}; } $CommonObject{LanguageObject} = Kernel::Language->new( UserLanguage => $Lang, LogObject => $CommonObject{LogObject}, ConfigObject => $CommonObject{ConfigObject}, MainObject => $CommonObject{MainObject}, ); # format my $Format = 'CSV'; if ($Opts{f}) { if ($Opts{f} eq 'Print') { $Format = 'Print'; } } # recipient check if ($Opts{r}) { if (!$CommonObject{CheckItemObject}->CheckEmail(Address => $Opts{r})) { print STDERR "ERROR: " . $CommonObject{CheckItemObject}->CheckError() . "\n"; exit 1; } } # sender, if given if (!$Opts{s}) { $Opts{s} = ''; } # directory check if ($Opts{o} && !-e $Opts{o}) { print STDERR "ERROR: No such directory: $Opts{o}\n"; exit 1; } # process the informations my $StatNumber = $Opts{n}; my $StatID = $CommonObject{StatsObject}->StatNumber2StatID(StatNumber => $StatNumber); if (!$StatID) { print STDERR "ERROR: No StatNumber: $Opts{n}\n"; exit 1; } my ($s,$m,$h, $D,$M,$Y) = $CommonObject{TimeObject}->SystemTime2Date( SystemTime => $CommonObject{TimeObject}->SystemTime(), ); my %GetParam = (); my $Stat = $CommonObject{StatsObject}->StatsGet(StatID => $StatID); if ($Stat->{StatType} eq 'static') { $GetParam{Year} = $Y; $GetParam{Month} = $M; $GetParam{Day} = $D; # get params from -p # only for static files my $Params = $CommonObject{StatsObject}->GetParams(StatID => $StatID); foreach my $ParamItem (@{$Params}) { if (!$ParamItem->{Multiple}) { my $Value = GetParam( Param => $ParamItem->{Name}, ); if (defined($Value)) { $GetParam{$ParamItem->{Name}} = GetParam( Param => $ParamItem->{Name}, ); } elsif (defined($ParamItem->{SelectedID})) { $GetParam{$ParamItem->{Name}} = $ParamItem->{SelectedID}; } } else { my @Value = GetArray( Param => $ParamItem->{Name}, ); if (@Value) { $GetParam{$ParamItem->{Name}} = \@Value; } elsif (defined($ParamItem->{SelectedID})) { $GetParam{$ParamItem->{Name}} = [$ParamItem->{SelectedID}]; } } } } elsif ($Stat->{StatType} eq 'dynamic') { %GetParam = %{$Stat}; } # run stat... my @StatArray = @{$CommonObject{StatsObject}->StatsRun( StatID => $StatID, GetParam => \%GetParam, )}; # generate output my $TitleArrayRef = shift (@StatArray); my $Title = $TitleArrayRef->[0]; my $HeadArrayRef = shift (@StatArray); my $CountStatArray = @StatArray; my $Time = sprintf("%04d-%02d-%02d %02d:%02d:%02d",$Y,$M,$D,$h,$m,$s); if (!@StatArray) { push(@StatArray, [' ',0]); } my %Attachment; if ($Format eq 'Print' && $CommonObject{PDFObject}) { # Create the PDF my %User = $CommonObject{UserObject}->GetUserData(UserID => $CommonObject{UserID}); my $PrintedBy = $CommonObject{LanguageObject}->Get('printed by'); my $Page = $CommonObject{LanguageObject}->Get('Page'); my $SystemTime = $CommonObject{TimeObject}->SystemTime(); my $TimeStamp = $CommonObject{TimeObject}->SystemTime2TimeStamp( SystemTime => $SystemTime, ); my $Time = $CommonObject{LanguageObject}->FormatTimeString($TimeStamp, 'DateFormat'); # create the content array my $CellData; my $CounterRow = 0; my $CounterHead = 0; foreach my $Content (@{$HeadArrayRef}) { $CellData->[$CounterRow]->[$CounterHead]->{Content} = $Content; $CellData->[$CounterRow]->[$CounterHead]->{Font} = 'ProportionalBold'; $CounterHead++; } if ($CounterHead > 0) { $CounterRow++; } foreach my $Row (@StatArray) { my $CounterColumn = 0; foreach my $Content (@{$Row}) { $CellData->[$CounterRow]->[$CounterColumn]->{Content} = $Content; $CounterColumn++; } $CounterRow++; } if (!$CellData->[0]->[0]) { $CellData->[0]->[0]->{Content} = $CommonObject{LanguageObject}->Get('No Result!'); } # page params my %PageParam; $PageParam{PageOrientation} = 'landscape'; $PageParam{MarginTop} = 30; $PageParam{MarginRight} = 40; $PageParam{MarginBottom} = 40; $PageParam{MarginLeft} = 40; $PageParam{HeaderRight} = $CommonObject{ConfigObject}->Get('Stats::StatsHook') . $Stat->{StatNumber}; $PageParam{FooterLeft} = 'mkStats.pl'; $PageParam{HeadlineLeft} = $Title; $PageParam{HeadlineRight} = $PrintedBy . ' ' . $User{UserFirstname} . ' ' . $User{UserLastname} . ' (' . $User{UserEmail} . ') ' . $Time; # table params my %TableParam; $TableParam{CellData} = $CellData; $TableParam{Type} = 'Cut'; $TableParam{FontSize} = 6; $TableParam{Border} = 0; $TableParam{BackgroundColorEven} = '#AAAAAA'; $TableParam{BackgroundColorOdd} = '#DDDDDD'; $TableParam{Padding} = 1; $TableParam{PaddingTop} = 3; $TableParam{PaddingBottom} = 3; # get maximum number of pages my $MaxPages = $CommonObject{ConfigObject}->Get('PDF::MaxPages'); if (!$MaxPages || $MaxPages < 1 || $MaxPages > 1000) { $MaxPages = 100; } # create new pdf document $CommonObject{PDFObject}->DocumentNew( Title => $CommonObject{ConfigObject}->Get('Product') . ': ' . $Title, Encode => $CommonObject{LanguageObject}->GetRecommendedCharset(), ); # start table output my $Loop = 1; my $Counter = 1; while ($Loop) { # if first page if ($Counter eq 1) { $CommonObject{PDFObject}->PageNew( %PageParam, FooterRight => $Page . ' ' . $Counter, ); } # output table (or a fragment of it) %TableParam = $CommonObject{PDFObject}->Table( %TableParam, ); # stop output or another page if ($TableParam{State}) { $Loop = 0; } else { $CommonObject{PDFObject}->PageNew( %PageParam, FooterRight => $Page . ' ' . ($Counter + 1), ); } $Counter++; # check max pages if ($Counter >= $MaxPages) { $Loop = 0; } } # return the document my $PDFString = $CommonObject{PDFObject}->DocumentOutput(); # save the pdf with the title and timestamp as filename my $Filename = $CommonObject{StatsObject}->StringAndTimestamp2Filename( String => $Stat->{Title} . " Created", ); %Attachment = ( Filename => $Filename . ".pdf", ContentType => "application/pdf", Content => $PDFString, Encoding => "base64", Disposition => "attachment", ); } else { # Create the CVS data my $Output = "Name: $Title; Created: $Time\n"; $Output .= $CommonObject{CSVObject}->Array2CSV( Head => $HeadArrayRef, Data => \@StatArray, ); # save the csv with the title and timestamp as filename my $Filename = $CommonObject{StatsObject}->StringAndTimestamp2Filename( String => $Stat->{Title} . " Created", ); %Attachment = ( Filename => $Filename . ".csv", ContentType => "text/csv", Content => $Output, Encoding => "base64", Disposition => "attachment", ); } # write output if ($Opts{o}) { if (open my $Filehandle, '>', "$Opts{o}/$Attachment{Filename}") { print $Filehandle $Attachment{Content}; close $Filehandle; print "NOTICE: Writing file $Opts{o}/$Attachment{Filename}.\n"; exit; } else { print STDERR "ERROR: Can't write $Opts{o}/$Attachment{Filename}: $!\n"; exit 1; } } # send email elsif ($CommonObject{EmailObject}->Send( From => $Opts{s}, To => $Opts{r}, Subject => "[Stats - $CountStatArray Records] $Title; Created: $Time", Body => $CommonObject{LanguageObject}->Get($Opts{'m'}), Charset => $CommonObject{ConfigObject} ->{DefaultCharset}, Attachment => [ { %Attachment }, ], )) { print "NOTICE: Email sent to '$Opts{'r'}'.\n"; } exit(0); sub GetParam { my %Param = @_; if (!$Param{Param}) { print STDERR "ERROR: Need Param Arg in GetParam()\n"; } my @P = split(/&/, $Opts{p} || ''); for (@P) { my ($Key, $Value) = split(/=/, $_, 2); if ($Key eq $Param{Param}) { return $Value; } } return; } sub GetArray { my %Param = @_; if (!$Param{Param}) { print STDERR "ERROR: Need Param Arg in GetArray()\n"; } my @P = split(/&/, $Opts{p} || ''); my @Array; for (@P) { my ($Key, $Value) = split(/=/, $_, 1); if ($Key eq $Param{Param}) { push (@Array, $Value); } } return @Array; }