[rt-devel] modified rt-crontool
    plasma 
    plasmaball at pchome.com.tw
       
    Thu Sep 12 02:47:36 EDT 2002
    
    
  
Hi all,
I'd like to use rt-crontool to spot certain tickets, then email to
their owners.  But rt-crontool seems not working with
RT::Action::SendEmail because of RT::Transaction.  I modified
rt-crontool and took RT::Transaction out of RT::Action::SendEmail.
The folllowing are diff to rt-crontool against version 2.1.31, and the
resulting RT::Action::LightWeightSendEmail.  There is also a
RT::Action::SystemNotify that is almost identical to
RT::Action::Notify.
rt-crontool now knows about RT::Template.  It can be used as:
rt-crontool \
 --search RT::Search::ActiveTicketsInQueue --search-arg general \
 --action RT::Action::SystemNotify --action-arg Owner,AdminCc \
 --template-id 1
Then every owners and admincc's will be bombed by emails. <g>
Of course you may never want to use template #1. <g>  You can create
a new template to work with RT::Action::LightWeightSendEmail, the only
exception is that RT::Transaction is not allowed in templates.  Recall
that rt-crontool don't have any RT::Transaction.
plasma
================================================================
<diff of rt-crontool>
--- rt-crontool.orig    Tue Aug 27 16:43:13 2002
+++ rt-crontool Thu Sep 12 14:29:09 2002
@@ -11,6 +11,7 @@
 
 use RT::Interface::CLI qw(CleanEnv GetCurrentUser GetMessageContent loc);
 use RT::Tickets;
+use RT::Template;
 
 #Clean out all the nasties from the environment
 CleanEnv();
@@ -33,6 +34,7 @@
 }
 
 my ( $search, $condition, $action, $search_arg, $condition_arg, $action_arg,
+     $template_id,
      $help, $verbose );
 GetOptions( "search=s"        => \$search,
             "search-arg=s"    => \$search_arg,
@@ -40,6 +42,7 @@
             "condition-arg=s" => \$condition_arg,
             "action-arg=s"    => \$action_arg,
             "action=s"        => \$action,
+           "template-id=s"   => \$template_id,
             "help"            => \$help,
             "verbose|v"       => \$verbose );
 
@@ -50,6 +53,13 @@
 load_module($action)    if ($action);
 load_module($condition) if ($condition);
 
+# load template if specified
+my $template_obj;
+if ($template_id) {
+    $template_obj = RT::Template->new($RT::Nobody);
+    $template_obj->LoadById($template_id);
+}
+
 #At the appointed time:
 
 #find a bunch of tickets
@@ -78,6 +88,7 @@
 
     #prepare our action
     my $action_obj = $action->new( TicketObj => $ticket,
+                                  TemplateObj => $template_obj,
                                    Argument  => $action_arg );
 
     #if our preparation, move onto the next ticket
</diff>
================================================================
<RT::Action::LightWeightSendEmail>
package RT::Action::LightWeightSendMail;
require RT::Action::SendEmail;
@ISA = qw(RT::Action::SendEmail);
=head1 NAME
  RT::Action::LightWeightSendmail - An action which users can use to
  send mail out of RT (ex., in rt-crontool) without a RT::Transaction
  object.  It can be subclassed for more specialized mail sending
  behavior.
  You can pass it with an RT::Template object, but you can not use
  $Transaction in it because it's alwasy undef.
=cut
# {{{ sub Describe
sub Describe {
    my $self = shift;
    return (ref $self . " will send an email to ticket's owner.\n");
}
# }}}
# {{{ sub Prepare
sub Prepare {
    my $self = shift;
    # This actually populates the MIME::Entity fields in the Template Object
  
    unless ($self->TemplateObj) {
	$RT::Logger->warning("No template object handed to $self\n");
    }
  
    unless ($self->TicketObj) {
	$RT::Logger->warning("No ticket object handed to $self\n");
    }
  
  
    $self->TemplateObj->Parse(Argument => $self->Argument,
			      TicketObj => $self->TicketObj);
  
    # Header
  
    $self->SetSubject();
  
    $self->SetSubjectToken();
  
    $self->SetRecipients();  
  
    $self->SetReturnAddress();
    $self->SetRTSpecialHeaders();
  
    return 1;
  
}
# }}}
# {{{ sub Commit 
#Do what we need to do and send it out.
sub Commit {
    my $self = shift;
    # Go add all the Tos, Ccs and Bccs that we need to to the message to 
    # make it happy, but only if we actually have values in those arrays.
    
    $self->SetHeader('To', join(',', @{$self->{'To'}})) 
	if (@{$self->{'To'}});
    $self->SetHeader('Cc', join(',' , @{$self->{'Cc'}})) 
	if (@{$self->{'Cc'}});
    $self->SetHeader('Bcc', join(',', @{$self->{'Bcc'}})) 
	if (@{$self->{'Bcc'}});;
    my $MIMEObj = $self->TemplateObj->MIMEObj;
    $MIMEObj->make_singlepart;
    #If we don't have any recipients to send to, don't send a message;
    unless ($MIMEObj->head->get('To') ||
	    $MIMEObj->head->get('Cc') || 
	    $MIMEObj->head->get('Bcc') ) {
	$RT::Logger->debug("$self: No recipients found. Not sending.\n");
	return(1);
    }
    # PseudoTo	(fake to headers) shouldn't get matched for message recipients.
    # If we don't have any 'To' header, drop in the pseudo-to header.
    $self->SetHeader('To', join(',', @{$self->{'PseudoTo'}}))
	if ( (@{$self->{'PseudoTo'}}) and (! $MIMEObj->head->get('To')));
    
    if ($RT::MailCommand eq 'sendmailpipe') {
	open (MAIL, "|$RT::SendmailPath $RT::SendmailArguments") || return(0);
	print MAIL $MIMEObj->as_string;
	close(MAIL);
    }
    else {
	unless ($MIMEObj->send($RT::MailCommand, $RT::MailParams)) {
	    $RT::Logger->crit("$self: Could not send mail for ".$self->TransactionObj."\n");
	    return(0);
	}
    }
    
    return (1);
}
# }}}
# {{{ Deal with message headers (Set* subs, designed for  easy overriding)
# {{{ sub SetRTSpecialHeaders
# This routine adds all the random headers that RT wants in a mail message
# that don't matter much to anybody else.
sub SetRTSpecialHeaders {
    my $self = shift;
    
    $self->SetReferences();
    $self->SetPrecedence();
    $self->SetHeader('X-RT-Loop-Prevention', $RT::rtname); 
    $self->SetHeader('RT-Ticket', $RT::rtname. " #".$self->TicketObj->id());
    $self->SetHeader
      ('Managed-by',"Request Tracker $RT::VERSION (http://www.fsck.com/projects/rt/)");
    return();
}
# }}}
# {{{ sub SetReturnAddress 
sub SetReturnAddress {
  my $self = shift;
  my %args = ( is_comment => 0,
	       @_ );
  # From and Reply-To
  # $args{is_comment} should be set if the comment address is to be used.
  my $replyto;
  if ($args{'is_comment'}) { 
      $replyto = $self->TicketObj->QueueObj->CommentAddress || 
		  $RT::CommentAddress;
  }
  else {
      $replyto = $self->TicketObj->QueueObj->CorrespondAddress ||
		  $RT::CorrespondAddress;
  }
  unless ($self->TemplateObj->MIMEObj->head->get('Reply-To')) {
      $self->SetHeader('Reply-To', "$replyto");
  }
}
# }}}
# {{{ sub SetSubject
sub SetSubject {
    my $self = shift;
    my $subject = $self->{'Subject'} || "An email from RT";
    $self->SetHeader('Subject', $subject);
    return $subject;
}
# }}}
1;
</RT::Action::LightWeightSendEmail>
================================================================
<RT::Action::SystemNotify>
package RT::Action::SystemNotify;
require RT::Action::LightWeightSendMail;
@ISA = qw(RT::Action::LightWeightSendMail);
# {{{ sub SetRecipients
=head2 SetRecipients
Sets the recipients of this meesage to Owner, Requestor, AdminCc, Cc or All. 
Explicitly B<does not> notify the creator of the transaction.
=cut
sub SetRecipients {
    my $self = shift;
    my $arg = $self->Argument;
    $arg =~ s/\bAll\b/Owner,Requestor,AdminCc,Cc/;
    my ( @To, @PseudoTo, @Cc, @Bcc );
    if ( $arg =~ /\bRequestor\b/ ) {
        push ( @To, $self->TicketObj->Requestors->MemberEmailAddresses  );
    }
    if ( $arg =~ /\bCc\b/ ) {
        #If we have a To, make the Ccs, Ccs, otherwise, promote them to To
        if (@To) {
            push ( @Cc, $self->TicketObj->Cc->MemberEmailAddresses );
            push ( @Cc, $self->TicketObj->QueueObj->Cc->MemberEmailAddresses  );
        }
        else {
            push ( @Cc, $self->TicketObj->Cc->MemberEmailAddresses  );
            push ( @To, $self->TicketObj->QueueObj->Cc->MemberEmailAddresses  );
        }
    }
    if ( ( $arg =~ /\bOwner\b/ )
        && ( $self->TicketObj->OwnerObj->id != $RT::Nobody->id ) )
    {
        # If we're not sending to Ccs or requestors, 
        # then the Owner can be the To.
        if (@To) {
            push ( @Bcc, $self->TicketObj->OwnerObj->EmailAddress );
        }
        else {
            push ( @To, $self->TicketObj->OwnerObj->EmailAddress );
        }
    }
    if ( $arg =~ /\bAdminCc\b/ ) {
        push ( @Bcc, $self->TicketObj->AdminCc->MemberEmailAddresses  );
        push ( @Bcc, $self->TicketObj->QueueObj->AdminCc->MemberEmailAddresses  );
    }
    if ($RT::UseFriendlyToLine) {
        unless (@To) {
            push ( @PseudoTo,
                "'$arg of $RT::rtname Ticket #"
                  . $self->TicketObj->id . "':;" );
        }
    }
    #Strip the sender out of the To, Cc and AdminCc and set the 
    # recipients fields used to build the message by the superclass.
    $RT::Logger->debug("$self: To is ".join(",", at To));
    $RT::Logger->debug("$self: Cc is ".join(",", at Cc));
    $RT::Logger->debug("$self: Bcc is ".join(",", at Bcc));
    @{ $self->{'To'} }  = @To;
    @{ $self->{'Cc'} }  = @Cc;
    @{ $self->{'Bcc'} } = @Bcc;
    @{ $self->{'PseudoTo'} } = @PseudoTo;
    return (1);
}
# }}}
1;
</RT::Action::SystemNotify>
==========================================================
 PC home ¹q¤l«H½c¡A¥Ó½Ð½Ð¦Ü: http://www.pchome.com.tw
 PC home Online ºô¸ô®a®x¡G·|û²Ä¤@¡A¥xÆW³Ì¤jªº¤J¤fºô¯¸
==========================================================
    
    
More information about the Rt-devel
mailing list