From 63c4dd9e1c068c1496b56ab0386bde61120663d8 Mon Sep 17 00:00:00 2001 From: "seth%cs.brandeis.edu" <> Date: Thu, 16 Mar 2000 06:29:44 +0000 Subject: A few changes ... 1. BugzillaEmail.pm is a (kinda, sorta) module which is going to hold the various code which is common between all the scripts which access bugzilla via email. 2. bug_email.pl uses this module 3. bugzilla_email_append.pl is a mostly ready script which will append messages to existing bugs. --- contrib/BugzillaEmail.pm | 79 +++++++++++++++++ contrib/bug_email.pl | 54 +---------- contrib/bugzilla_email_append.pl | 187 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 270 insertions(+), 50 deletions(-) create mode 100644 contrib/BugzillaEmail.pm create mode 100755 contrib/bugzilla_email_append.pl diff --git a/contrib/BugzillaEmail.pm b/contrib/BugzillaEmail.pm new file mode 100644 index 000000000..aaba0f4e0 --- /dev/null +++ b/contrib/BugzillaEmail.pm @@ -0,0 +1,79 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- + +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# This code is based on code found in bug_email.pl from the bugzilla +# email tracker. Initial contributors are :: +# Terry Weissman +# Gregor Fischer +# Klaas Freitag +# Seth Landsman + +# The purpose of this module is to abstract out a bunch of the code +# that is central to email interfaces to bugzilla and its database + +# Contributor : Seth Landsman + +# Initial checkin : 03/15/00 (SML) +# findUser() function moved from bug_email.pl to here + +push @INC, "../."; # this script now lives in contrib + +require "globals.pl"; + +use diagnostics; +use strict; + +my $EMAIL_TRANSFORM_NONE = "email_transform_none"; +my $EMAIL_TRANSFORM_BASE_DOMAIN = "email_transform_base_domain"; +my $EMAIL_TRANSFORM_NAME_ONLY = "email_transform_name_only"; + +# change to do incoming email address fuzzy matching +my $email_transform = $EMAIL_TRANSFORM_NAME_ONLY; + +# findUser() +# This function takes an email address and returns the user email. +# matching is sloppy based on the $email_transform parameter +sub findUser($) { + my ($address) = @_; + # if $email_transform is $EMAIL_TRANSFORM_NONE, return the address, otherwise, return undef + if ($email_transform eq $EMAIL_TRANSFORM_NONE) { + my $stmt = "SELECT login_name FROM profiles WHERE profiles.login_name = \'$address\';"; + SendSQL($stmt); + my $found_address = FetchOneColumn(); + return $found_address; + } elsif ($email_transform eq $EMAIL_TRANSFORM_BASE_DOMAIN) { + my ($username) = ($address =~ /(.+)@/); + my $stmt = "SELECT login_name FROM profiles WHERE profiles.login_name RLIKE \'$username\';"; + SendSQL($stmt); + + my $domain; + my $found = undef; + my $found_address; + my $new_address = undef; + while ((!$found) && ($found_address = FetchOneColumn())) { + ($domain) = ($found_address =~ /.+@(.+)/); + if ($address =~ /$domain/) { + $found = 1; + $new_address = $found_address; + } + } + return $new_address; + } elsif ($email_transform eq $EMAIL_TRANSFORM_NAME_ONLY) { + my ($username) = ($address =~ /(.+)@/); + my $stmt = "SELECT login_name FROM profiles WHERE profiles.login_name RLIKE \'$username\';"; + SendSQL($stmt); + my $found_address = FetchOneColumn(); + return $found_address; + } +} + +1; diff --git a/contrib/bug_email.pl b/contrib/bug_email.pl index a30fe457e..a70d49f60 100755 --- a/contrib/bug_email.pl +++ b/contrib/bug_email.pl @@ -37,7 +37,7 @@ # # You need to work with bug_email.pl the MIME::Parser installed. # -# $Id: bug_email.pl,v 1.4 2000/03/07 20:39:38 seth%cs.brandeis.edu Exp $ +# $Id: bug_email.pl,v 1.5 2000/03/15 22:29:45 seth%cs.brandeis.edu Exp $ ############################################################### # 02/12/2000 (SML) @@ -73,6 +73,7 @@ use MIME::Parser; push @INC, "../."; # this script now lives in contrib require "globals.pl"; +require "BugzillaEmail.pm"; my @mailerrors = (); # Buffer for Errors in the mail my @mailwarnings = (); # Buffer for Warnings found in the mail @@ -90,56 +91,9 @@ my $restricted = 0; my $SenderShort; my $Message_ID; -my $EMAIL_TRANSFORM_NONE = "email_transform_none"; -my $EMAIL_TRANSFORM_BASE_DOMAIN = "email_transform_base_domain"; -my $EMAIL_TRANSFORM_NAME_ONLY = "email_transform_name_only"; - -# change to do incoming email address fuzzy matching -my $email_transform = $EMAIL_TRANSFORM_NONE; - # change to use default product / component functionality -my $DEFAULT_PRODUCT = ""; -my $DEFAULT_COMPONENT = ""; - -############################################################### -# findUser -# -# this sub will find a user from the profiles table which is reasonably -# the same as the passed in email address, depending on the $email_transform -# parameter -sub findUser($) { - my ($address) = @_; - # if $email_transform is $EMAIL_TRANSFORM_NONE, return the address, otherwise, return undef - if ($email_transform eq $EMAIL_TRANSFORM_NONE) { - my $stmt = "SELECT login_name FROM profiles WHERE profiles.login_name = \'$address\';"; - SendSQL($stmt); - my $found_address = FetchOneColumn(); - return $found_address; - } elsif ($email_transform eq $EMAIL_TRANSFORM_BASE_DOMAIN) { - my ($username) = ($address =~ /(.+)@/); - my $stmt = "SELECT login_name FROM profiles WHERE profiles.login_name RLIKE \'$username\';"; - SendSQL($stmt); - - my $domain; - my $found = undef; - my $found_address; - my $new_address = undef; - while ((!$found) && ($found_address = FetchOneColumn())) { - ($domain) = ($found_address =~ /.+@(.+)/); - if ($address =~ /$domain/) { - $found = 1; - $new_address = $found_address; - } - } - return $new_address; - } elsif ($email_transform eq $EMAIL_TRANSFORM_NAME_ONLY) { - my ($username) = ($address =~ /(.+)@/); - my $stmt = "SELECT login_name FROM profiles WHERE profiles.login_name RLIKE \'$username\';"; - SendSQL($stmt); - my $found_address = FetchOneColumn(); - return $found_address; - } -} +my $DEFAULT_PRODUCT = "PENDING"; +my $DEFAULT_COMPONENT = "PENDING"; ############################################################### # storeAttachments diff --git a/contrib/bugzilla_email_append.pl b/contrib/bugzilla_email_append.pl new file mode 100755 index 000000000..065e2aba2 --- /dev/null +++ b/contrib/bugzilla_email_append.pl @@ -0,0 +1,187 @@ +#!/usr/bin/perl -w +# -*- Mode: perl; indent-tabs-mode: nil -*- + +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. + +# The purpose of this script is to take an email message, which +# specifies a bugid and append it to the bug as part of the longdesc +# table + +# Contributor : Seth M. Landsman + +# 03/15/00 : Initial version by SML + +# Email subject must be of format : +# .* Bug ### .* +# replying to a typical bugzilla email should be valid + +# TODO : +# 1. better way to get the body text (I don't know what dump_entity() is +# actually doing +# 2. response emails + +use diagnostics; +use strict; +use MIME::Parser; + +push @INC, "../."; # this script lives in contrib +require "globals.pl"; +require "BugzillaEmail.pm"; + +# Create a new MIME parser: +my $parser = new MIME::Parser; + +my $Comment = ""; + +# Create and set the output directory: +# FIXME: There should be a $BUGZILLA_HOME variable (SML) +(-d "../data/mimedump-tmp") or mkdir "../data/mimedump-tmp",0755 or die "mkdir: $!"; +(-w "../data/mimedump-tmp") or die "can't write to directory"; + +$parser->output_dir("../data/mimedump-tmp"); + +# Read the MIME message: +my $entity = $parser->read(\*STDIN) or die "couldn't parse MIME stream"; +$entity->remove_sig(10); # Removes the signature in the last 10 lines + +# Getting values from parsed mail +my $Sender = $entity->get( 'From' ); +$Sender ||= $entity->get( 'Reply-To' ); +my $Message_ID = $entity->get( 'Message-Id' ); + +die (" *** Cant find Sender-adress in sent mail ! ***\n" ) unless defined( $Sender ); +chomp( $Sender ); +chomp( $Message_ID ); + +print "Dealing with the sender $Sender\n"; + +ConnectToDatabase(); + +my $SenderShort = $Sender; +$SenderShort =~ s/^.*?([a-zA-Z0-9_.-]+?\@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_.-]+).*$/$1/; + +$SenderShort = findUser($SenderShort); + +print "SenderShort is $SenderShort\n"; +if (!defined($SenderShort)) { + $SenderShort = $Sender; + $SenderShort =~ s/^.*?([a-zA-Z0-9_.-]+?\@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_.-]+).*$/$1/; +} +print "The sendershort is now $SenderShort\n"; + +if (!defined($SenderShort)) { + DealWithError("No such user $SenderShort exists."); +} + +my $Subject = $entity->get('Subject'); +print "The subject is $Subject\n"; + +my ($bugid) = ($Subject =~ /\[Bug ([\d]+)\]/); +print "The bugid is $bugid\n"; + +# make sure the bug exists + +SendSQL("SELECT bug_id FROM bugs WHERE bug_id = $bugid;"); +my $found_id = FetchOneColumn(); +print "Did we find the bug? $found_id-\n"; +if (!defined($found_id)) { + DealWithError("Bug $bugid does not exist"); +} + +# get the user id +SendSQL("SELECT userid FROM profiles WHERE login_name = \'$SenderShort\';"); +my $userid = FetchOneColumn(); +if (!defined($userid)) { + DealWithError("Userid not found for $SenderShort"); +} + +# parse out the text of the message +dump_entity($entity); + +# Get rid of the bug id +$Subject =~ s/\[Bug [\d]+\]//; +#my $Comment = "This is only a test ..."; +my $Body = "Subject: " . $Subject . "\n" . $Comment; + +# shove it in the table +my $long_desc_query = "INSERT INTO longdescs SET bug_id=$found_id, who=$userid, bug_when=NOW(), thetext=" . SqlQuote($Body) . ";"; +SendSQL($long_desc_query); + +sub DealWithError { + my ($reason) = @_; + print $reason . "\n"; +} + +# Yanking this wholesale from bug_email, 'cause I know this works. I'll +# figure out what it really does later +#------------------------------ +# +# dump_entity ENTITY, NAME +# +# Recursive routine for parsing a mime coded mail. +# One mail may contain more than one mime blocks, which need to be +# handled. Therefore, this function is called recursively. +# +# It gets the for bugzilla important information from the mailbody and +# stores them into the global attachment-list @attachments. The attachment-list +# is needed in storeAttachments. +# +sub dump_entity { + my ($entity, $name) = @_; + defined($name) or $name = "'anonymous'"; + my $IO; + + + # Output the body: + my @parts = $entity->parts; + if (@parts) { # multipart... + my $i; + foreach $i (0 .. $#parts) { # dump each part... + dump_entity($parts[$i], ("$name, part ".(1+$i))); + } + } else { # single part... + + # Get MIME type, and display accordingly... + my $msg_part = $entity->head->get( 'Content-Disposition' ); + + $msg_part ||= ""; + + my ($type, $subtype) = split('/', $entity->head->mime_type); + my $body = $entity->bodyhandle; + my ($data, $on_disk ); + + if( $msg_part =~ /^attachment/ ) { + # Attached File + my $des = $entity->head->get('Content-Description'); + $des ||= ""; + + if( defined( $body->path )) { # Data is on disk + $on_disk = 1; + $data = $body->path; + + } else { # Data is in core + $on_disk = 0; + $data = $body->as_string; + } +# push ( @attachments, [ $data, $entity->head->mime_type, $on_disk, $des ] ); + } else { + # Real Message + if ($type =~ /^(text|message)$/) { # text: display it... + if ($IO = $body->open("r")) { + $Comment .= $_ while (defined($_ = $IO->getline)); + $IO->close; + } else { # d'oh! + print "$0: couldn't find/open '$name': $!"; + } + } else { print "Oooops - no Body !\n"; } + } + } +} -- cgit v1.2.3-24-g4f1b