[rt-devel] three patches and comments...

Alex Krohn alex at gossamer-threads.com
Mon May 7 19:18:44 EDT 2001


Hi,

We just finished installing and customzing RT 1.3.70. I like the
modularity and the Scrips are very cool. A couple things that may be of
help:

1. The install would go a lot smoother if the user must create the
database already. We ran into a lot of problems getting all the
username/passwords correct. I would recommend just having options for
database name, database user and database pass to run as and then create
the tables and go. Leave creating the database and setting up db
permissions to whoever installed the database server.

2. Found a small bug:

Index: Transaction.pm
===================================================================
RCS file: /raid/cvsroot/rt/lib/RT/Attic/Transaction.pm,v
retrieving revision 1.1.2.88
diff -r1.1.2.88 Transaction.pm
228d227
<     if (@_) {
230d228
<     }

You had an if .. around a my'd variable making it never in scope.

3. Had quite a few issues with attachments and template replies. You
use:

{$Transaction->Message->First->Content}

everywhere in the templates. This runs into problems as if I send a
message with an attachment, in the attachments table the first entry has
no content as it's a multipart message. I ended up updating the
templates to:

{ 
  $Transaction->Attachments('text/plain')->First->Content ||
  $Transaction->Attachments('text/html')->First->Content  ||
  "No Viewable Message."
}

to get the first viewable part. Might be nice to add this as a builtin
function. Something like:

        {$Transaction->ViewablePart}

It would also be useful to have a function that would quote previous
replies as in:

        Support Ticket Summary:
        {$Transaction->QuotedSummary}

and that would go back through the tickets and create a quoted history
much like you see via the web.

4. We added an Auto Assign feature that would assign an incoming ticket
to a member. It allows you to call rt-mailgate with --group=groupname
and it will assign the incoming case to the member of the group with the
fewest support cases. If no one in the group can be found, it will look
for someone in the 'general' group.

A patch follows if anyone is interested. I couldn't get my head around
DBIx::SearchBuilder for table joins I'm afraid, so I used raw sql. =)

[root at alex bin]# diff rt-mailgate /usr/local/rt2/bin/rt-mailgate 
43c43
< my ($From, $TicketId, $Subject,$SquelchReplies);
---
> my ($Group, $From, $TicketId, $Subject,$SquelchReplies);
67,68c67,69
<     
<     
---
>     if (($flag eq '-g') or ($flag eq '--group')) {
>       $Group = shift @ARGV;
>     }
165a167,175
> 
> # Auto Assign it to someone in a group if specified.
>       my $Owner;
>       if ($Group) {
>               $Owner = AutoAssign($Group);
>               if (! $Owner and ($Group ne 'general')) {
>                       $Owner = AutoAssign ('general');
>               }
>       }
180a191
>                           Owner => $Owner,
286a298,340
> 
> sub AutoAssign {
>     my $Group = shift;
>     my $Query = qq~
> SELECT GroupMembers.UserId
> FROM Groups, GroupMembers
> WHERE Groups.Name = ? AND (GroupMembers.GroupId = Groups.id)
>     ~;
>     my $sth = $RT::Handle->SimpleQuery ($Query, $Group);
>     my $users = $sth->fetchall_arrayref;
>     my $string = '(' . join (',', map { $_->[0] } @$users) . ')';
> print "users: ($string)\n";
>     if ($string eq '()') { return; }
> 
>     $Query = qq~
> SELECT Users.id
> FROM Users LEFT JOIN Tickets ON Users.id = Tickets.Owner
> WHERE Tickets.Owner IS NULL 
>       AND (Users.id IN $string)
> LIMIT 1
>     ~;
>     $sth = $RT::Handle->SimpleQuery ($Query);
>     my ($userid) = $sth->fetchrow_array;
> print "Got user: $userid\n";
>     if ($userid) { return $userid; }
> 
> # No one found with no cases, find least busy guy.
>     $Query = qq~
> SELECT Owner, COUNT(*) AS Volume
> FROM Groups, GroupMembers, Tickets
> WHERE Groups.Name = ? AND 
>         (Groups.id = GroupMembers.GroupId AND
>          GroupMembers.UserId = Tickets.Owner)
> GROUP BY Owner
> ORDER BY Volume ASC
> LIMIT 1
>     ~;    
>     $sth = $RT::Handle->SimpleQuery ($Query, $Group);
>     ($userid) = $sth->fetchrow_array;
> print "Second user: $userid\n";
> 
>     return $userid;
> }

5. Here's a patch to SendEmail.pm that will forward attachments as well
as the regular message. I couldn't see a good way to do this in the
template unfortunately, but would love to hear ideas:

[root at alex Action]# diff SendEmail.pm /usr/local/rt2/lib/RT/Action/SendEmail.pm 
54a58
>     my $attach = shift;
58a63,64
> 
>     my $TopPart = $self->TransactionObj->Message->First();
60,63c66,69
<     if (defined $self->TransactionObj->Message->First()) { 
<     my $headers = $self->TransactionObj->Message->First->Headers();
<     if ($headers =~ /^RT-Squelch-Replies-To: (.*?)$/si) {
<       my $blacklist = $1;
---
>     if (defined $TopPart) { 
>         my $headers = $TopPart->Headers();
>         if ($headers =~ /^RT-Squelch-Replies-To: (.*?)$/si) {
>           my $blacklist = $1;
66c72
<       my @headers = qw (To Cc Bcc);
---
>           my @headers = qw (To Cc Bcc);
69,71c75,78
<       while ( my $line =  $self->TemplateObj->MIMEObj->head->get($header)) {
<           if ($line =~ s/$blacklist,//)  {
<               $self->TemplateObj->MIMEObj->head->replace($header, $line);
---
>           while ( my $line =  $self->TemplateObj->MIMEObj->head->get($header)) {
>               if ($line =~ s/$blacklist,//)  {
>                   $self->TemplateObj->MIMEObj->head->replace($header, $line);
>               }
72a80,107
>         }
>       if ($attach) {
>               my $type = lc $TopPart->ContentType;
>               if ($type =~ /multipart/) {
>                   my $Attachments = $self->TransactionObj->Attachments;
>                   $Attachments->Next; # Skip first part (Empty multipart).
>                   my $found_viewable = 0;
>                   while (my $Attach = $Attachments->Next) {
>                       my $subtype = lc $Attach->ContentType;
> 
> # Skip text/plain and text/html if this is an HTML message.
>                       if (!$found_viewable and $subtype =~ /text/) {
>                               $found_viewable = 1;
>                               next;
>                       }
> 
> # Skip embedded messages
>                       next if ($subtype =~ /multipart/);
> 
> # Otherwise Attach the file.
>                       $self->TemplateObj->MIMEObj->attach (
>                                       Type => $Attach->ContentType,
>                                       Encoding => "-SUGGEST",
>                                       Filename => $Attach->Filename,
>                                       Data => $Attach->Content
>                               );
>                   }
>                 }
75,76c110,112
<   }
<     $self->TemplateObj->MIMEObj->make_singlepart;
---
>     unless ($self->TemplateObj->MIMEObj->parts > 1) {
>         $self->TemplateObj->MIMEObj->make_singlepart;
>     }

This basically says if you pass 1 into Commit() then the SendMail will
attach any attached files in the current transaction.

Hope this helps someone, and let me know if you have any questions.

Cheers,

Alex

--------------------  Gossamer Threads Inc.  ----------------------
Alex Krohn                        Email: alex at gossamer-threads.com
Internet Consultant               Phone: (604) 687-5804
http://www.gossamer-threads.com   Fax  : (604) 687-5806





More information about the Rt-devel mailing list