[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