diff options
Diffstat (limited to 'rt/sbin/rt-email-digest.in')
-rw-r--r-- | rt/sbin/rt-email-digest.in | 337 |
1 files changed, 0 insertions, 337 deletions
diff --git a/rt/sbin/rt-email-digest.in b/rt/sbin/rt-email-digest.in deleted file mode 100644 index 2fc7c0089..000000000 --- a/rt/sbin/rt-email-digest.in +++ /dev/null @@ -1,337 +0,0 @@ -#!@PERL@ -# BEGIN BPS TAGGED BLOCK {{{ -# -# COPYRIGHT: -# -# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC -# <jesse@bestpractical.com> -# -# (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 -# you are the copyright holder for those contributions and you grant -# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -# 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 }}} -use warnings; -use strict; - -BEGIN { - require File::Spec; - my @libs = ("@RT_LIB_PATH@", "@LOCAL_LIB_PATH@"); - my $bin_path; - - for my $lib (@libs) { - unless ( File::Spec->file_name_is_absolute($lib) ) { - unless ($bin_path) { - if ( File::Spec->file_name_is_absolute(__FILE__) ) { - $bin_path = ( File::Spec->splitpath(__FILE__) )[1]; - } - else { - require FindBin; - no warnings "once"; - $bin_path = $FindBin::Bin; - } - } - $lib = File::Spec->catfile( $bin_path, File::Spec->updir, $lib ); - } - unshift @INC, $lib; - } - -} - -use Date::Format qw( strftime ); -use Getopt::Long; -use RT; -use RT::Interface::CLI qw( CleanEnv loc ); -use RT::Interface::Email; - -CleanEnv(); -RT::LoadConfig(); -RT::Init(); - -sub usage { - my ($error) = @_; - print loc("Usage: ") . "$0 -m (daily|weekly) [--print] [--help]\n"; - print loc( - "[_1] is a utility, meant to be run from cron, that dispatches all deferred RT notifications as a per-user digest.", - $0 - ) . "\n"; - print "\n\t-m, --mode\t" - . loc("Specify whether this is a daily or weekly run.") . "\n"; - print "\t-p, --print\t" - . loc("Print the resulting digest messages to STDOUT; don't mail them. Do not mark them as sent") - . "\n"; - print "\t-h, --help\t" . loc("Print this message") . "\n"; - - if ( $error eq 'help' ) { - exit 0; - } else { - print loc("Error") . ": " . loc($error) . "\n"; - exit 1; - } -} - -my ( $frequency, $print, $help ) = ( '', '', '' ); -GetOptions( - 'mode=s' => \$frequency, - 'print' => \$print, - 'help' => \$help, -); - -usage('help') if $help; -usage("Mode argument must be 'daily' or 'weekly'") - unless $frequency =~ /^(daily|weekly)$/; - -run( $frequency, $print ); - -sub run { - my $frequency = shift; - my $print = shift; - -## Find all the tickets that have been modified within the time frame -## described by $frequency. - - my ( $all_digest, $sent_transactions ) = find_transactions($frequency); - -## Iterate through our huge hash constructing the digest message -## for each user and sending it. - - foreach my $user ( keys %$all_digest ) { - my ( $contents_list, $contents_body ) = build_digest_for_user( $user, $all_digest->{$user} ); - # Now we have a content head and a content body. We can send a message. - if ( send_digest( $user, $contents_list, $contents_body ) ) { - print "Sent message to $user\n"; - mark_transactions_sent( $frequency, $user, values %{$sent_transactions->{$user}} ) unless ($print); - } else { - print "Failed to send message to $user\n"; - } - } -} -exit 0; - -# Subroutines. - -sub send_digest { - my ( $to, $index, $messages ) = @_; - - # Combine the index and the messages. - - my $body = "============== Tickets with activity in the last " - . ( $frequency eq 'daily' ? "day" : "seven days" ) . "\n\n"; - - $body .= $index; - $body .= "\n\n============== Messages recorded in the last " - . ( $frequency eq 'daily' ? "day" : "seven days" ) . "\n\n"; - $body .= $messages; - - # Load our template. If we cannot load the template, abort - # immediately rather than failing through many loops. - my $digest_template = RT::Template->new( RT->SystemUser ); - my ( $ret, $msg ) = $digest_template->Load('Email Digest'); - unless ($ret) { - print loc("Failed to load template") - . " 'Email Digest': " - . $msg - . ". Cannot continue.\n"; - exit 1; - } - ( $ret, $msg ) = $digest_template->Parse( Argument => $body ); - unless ($ret) { - print loc("Failed to parse template") - . " 'Email Digest'. Cannot continue.\n"; - exit 1; - } - - # Set our sender and recipient. - $digest_template->MIMEObj->head->replace( 'From', RT::Config->Get('CorrespondAddress') ); - $digest_template->MIMEObj->head->replace( 'To', $to ); - - if ($print) { - $digest_template->MIMEObj->print; - return 1; - } else { - return RT::Interface::Email::SendEmail( Entity => $digest_template->MIMEObj) - } -} - -=item mark_transactions_sent( $frequency, $user, @txn_list ); - -Takes a frequency string (either 'daily' or 'weekly'), a user and one or more -transaction objects as its arguments. Marks the given deferred -notifications as sent. - -=cut - -sub mark_transactions_sent { - my ( $freq, $user, @txns ) = @_; - return unless $freq =~ /(daily|weekly)/; - return unless @txns; - foreach my $txn (@txns) { - - # Grab the attribute, mark the "sent" as true, and store the new - # value. - if ( my $attr = $txn->FirstAttribute('DeferredRecipients') ) { - my $deferred = $attr->Content; - $deferred->{$freq}->{$user}->{'_sent'} = 1; - $txn->SetAttribute( - Name => 'DeferredRecipients', - Description => 'Deferred recipients for this message', - Content => $deferred, - ); - } - } -} - -sub since_date { - my $frequency = shift; - - # Specify a short time for digest overlap, in case we aren't starting - # this process exactly on time. - my $OVERLAP_HEDGE = -30; - - my $since_date = RT::Date->new( RT->SystemUser ); - $since_date->Set( Format => 'unix', Value => time() ); - if ( $frequency eq 'daily' ) { - $since_date->AddDays(-1); - } else { - $since_date->AddDays(-7); - } - - $since_date->AddSeconds($OVERLAP_HEDGE); - - return $since_date; -} - -sub find_transactions { - my $frequency = shift; - my $since_date = since_date($frequency); - - my $txns = RT::Transactions->new( RT->SystemUser ); - - # First limit to recent transactions. - $txns->Limit( - FIELD => 'Created', - OPERATOR => '>', - VALUE => $since_date->ISO - ); - - # Next limit to ticket transactions. - $txns->Limit( - FIELD => 'ObjectType', - OPERATOR => '=', - VALUE => 'RT::Ticket', - ENTRYAGGREGATOR => 'AND' - ); - my $all_digest = {}; - my $sent_transactions = {}; - - while ( my $txn = $txns->Next ) { - my $ticket = $txn->Ticket; - my $queue = $txn->TicketObj->QueueObj->Name; - # Xxx todo - may clobber if two queues have the same name - foreach my $user ( $txn->DeferredRecipients($frequency) ) { - $all_digest->{$user}->{$queue}->{$ticket}->{ $txn->id } = $txn->ContentObj; - $sent_transactions->{$user}->{ $txn->id } = $txn; - } - } - - return ( $all_digest, $sent_transactions ); -} - -sub build_digest_for_user { - my $user = shift; - my $user_digest = shift; - - my $contents_list = ''; # Holds the digest index. - my $contents_body = ''; # Holds the digest body. - - # Has the user been disabled since a message was deferred on his/her - # behalf? - my $user_obj = RT::User->new( RT->SystemUser ); - $user_obj->LoadByEmail($user); - if ( $user_obj->PrincipalObj->Disabled ) { - print STDERR loc("Skipping disabled user") . " $user\n"; - next; - } - - print loc("Message for user") . " $user:\n\n" if $print; - foreach my $queue ( keys %$user_digest ) { - $contents_list .= "Queue $queue:\n"; - $contents_body .= "Queue $queue:\n"; - foreach my $ticket ( sort keys %{ $user_digest->{$queue} } ) { - my $tkt_txns = $user_digest->{$queue}->{$ticket}; - my $ticket_obj = RT::Ticket->new( RT->SystemUser ); - $ticket_obj->Load($ticket); - - # Spit out the index entry for this ticket. - my $ticket_title = sprintf( - "#%d %s [%s]\t%s\n", - $ticket, $ticket_obj->Status, $ticket_obj->OwnerObj->Name, - $ticket_obj->Subject - ); - $contents_list .= $ticket_title; - - # Spit out the messages for the transactions on this ticket. - $contents_body .= "\n== $ticket_title\n"; - foreach my $txn ( sort keys %$tkt_txns ) { - my $msg = $tkt_txns->{$txn}; - - # $msg contains an RT::Attachment with our outgoing - # message. Print a few headers for clarity's sake. - $contents_body .= "From: " . $msg->GetHeader('From') . "\n"; - my $date = $msg->GetHeader('Date '); - unless ($date) { - my $txn_obj = RT::Transaction->new( RT->SystemUser ); - $txn_obj->Load($txn); - my $date_obj = RT::Date->new( RT->SystemUser ); - $date_obj->Set( - Format => 'sql', - Value => $txn_obj->Created - ); - $date = strftime( '%a, %d %b %Y %H:%M:%S %z', - @{ [ localtime( $date_obj->Unix ) ] } ); - } - $contents_body .= "Date: $date\n\n"; - $contents_body .= $msg->Content . "\n"; - $contents_body .= "-------\n"; - } # foreach transaction - } # foreach ticket - } # foreach queue - - return ( $contents_list, $contents_body ); - -} |