@@ -72,14 +72,17 @@ class node. Any parts of other types are each stored in separate files
7272an exception, the original message is bounced back to the sender with the
7373explanatory message given in the exception.
7474
75- $Id: mailgw.py,v 1.11 2001-08-08 00:08:03 richard Exp $
75+ $Id: mailgw.py,v 1.12 2001-08-08 01:27:00 richard Exp $
7676'''
7777
7878
7979import string , re , os , mimetools , cStringIO , smtplib , socket , binascii , quopri
8080import traceback
8181import date
8282
83+ class MailUsageError (ValueError ):
84+ pass
85+
8386class Message (mimetools .Message ):
8487 ''' subclass mimetools.Message so we can retrieve the parts of the
8588 message...
@@ -121,8 +124,17 @@ def main(self, fp):
121124 '''
122125 # ok, figure the subject, author, recipients and content-type
123126 message = Message (fp )
127+ m = []
124128 try :
125129 self .handle_message (message )
130+ except MailUsageError , value :
131+ # bounce the message back to the sender with the usage message
132+ fulldoc = '\n ' .join (string .split (__doc__ , '\n ' )[2 :])
133+ sendto = [message .getaddrlist ('from' )[0 ][1 ]]
134+ m = ['Subject: Failed issue tracker submission' , '' ]
135+ m .append (str (value ))
136+ m .append ('\n Mail Gateway Help\n =================' )
137+ m .append (fulldoc )
126138 except :
127139 # bounce the message back to the sender with the error message
128140 sendto = [message .getaddrlist ('from' )[0 ][1 ]]
@@ -140,6 +152,7 @@ def main(self, fp):
140152 except :
141153 pass
142154 m .append (fp .read ())
155+ if m :
143156 try :
144157 smtp = smtplib .SMTP (self .MAILHOST )
145158 smtp .sendmail (self .ADMIN_EMAIL , sendto , '\n ' .join (m ))
@@ -157,12 +170,33 @@ def handle_message(self, message):
157170 subject = message .getheader ('subject' )
158171 m = subject_re .match (subject )
159172 if not m :
160- raise ValueError , 'No [designator] found in subject "%s"' % subject
173+ raise MailUsageError , '''
174+ The message you sent to roundup did not contain a properly formed subject
175+ line. The subject must contain a class name or designator to indicate the
176+ "topic" of the message. For example:
177+ Subject: [issue] This is a new issue
178+ - this will create a new issue in the tracker with the title "This is
179+ a new issue".
180+ Subject: [issue1234] This is a followup to issue 1234
181+ - this will append the message's contents to the existing issue 1234
182+ in the tracker.
183+
184+ Subject was: "%s"
185+ ''' % subject
161186 classname = m .group ('classname' )
162187 nodeid = m .group ('nodeid' )
163188 title = m .group ('title' ).strip ()
164189 subject_args = m .group ('args' )
165- cl = self .db .getclass (classname )
190+ try :
191+ cl = self .db .getclass (classname )
192+ except KeyError :
193+ raise MailUsageError , '''
194+ The class name you identified in the subject line ("%s") does not exist in the
195+ database.
196+
197+ Valid class names are: %s
198+ Subject was: "%s"
199+ ''' % (classname , ', ' .join (self .db .getclasses ()), subject )
166200 properties = cl .getprops ()
167201 props = {}
168202 args = m .group ('args' )
@@ -171,8 +205,20 @@ def handle_message(self, message):
171205 try :
172206 key , value = prop .split ('=' )
173207 except ValueError , message :
174- raise ValueError , 'Args list not of form [arg=value,value,...;arg=value,value,value..] (specific exception message was "%s")' % message
175- type = properties [key ]
208+ raise MailUsageError , '''
209+ Subject argument list not of form [arg=value,value,...;arg=value,value...]
210+ (specific exception message was "%s")
211+
212+ Subject was: "%s"
213+ ''' % (message , subject )
214+ try :
215+ type = properties [key ]
216+ except KeyError :
217+ raise MailUsageError , '''
218+ Subject argument list refers to an invalid property: "%s"
219+
220+ Subject was: "%s"
221+ ''' % (key , subject )
176222 if type .isStringType :
177223 props [key ] = value
178224 elif type .isDateType :
@@ -237,7 +283,10 @@ def handle_message(self, message):
237283 attachments .append ((name , part .gettype (), data ))
238284
239285 if content is None :
240- raise ValueError , 'No text/plain part found'
286+ raise MailUsageError , '''
287+ Roundup requires the submission to be plain text. The message parser could
288+ not find a text/plain part o use.
289+ '''
241290
242291 elif content_type [:10 ] == 'multipart/' :
243292 # skip over the intro to the first boundary
@@ -253,10 +302,16 @@ def handle_message(self, message):
253302 # this one's our content
254303 content = part .fp .read ()
255304 if content is None :
256- raise ValueError , 'No text/plain part found'
305+ raise MailUsageError , '''
306+ Roundup requires the submission to be plain text. The message parser could
307+ not find a text/plain part o use.
308+ '''
257309
258310 elif content_type != 'text/plain' :
259- raise ValueError , 'No text/plain part found'
311+ raise MailUsageError , '''
312+ Roundup requires the submission to be plain text. The message parser could
313+ not find a text/plain part o use.
314+ '''
260315
261316 else :
262317 content = message .fp .read ()
@@ -278,7 +333,15 @@ def handle_message(self, message):
278333 message_id = self .db .msg .create (author = author ,
279334 recipients = recipients , date = date .Date ('.' ), summary = summary ,
280335 content = content , files = files )
281- messages = cl .get (nodeid , 'messages' )
336+ try :
337+ messages = cl .get (nodeid , 'messages' )
338+ except IndexError :
339+ raise MailUsageError , '''
340+ The node specified by the designator in the subject of your message ("%s")
341+ does not exist.
342+
343+ Subject was: "%s"
344+ ''' % (nodeid , subject )
282345 messages .append (message_id )
283346 props ['messages' ] = messages
284347 cl .set (nodeid , ** props )
@@ -335,6 +398,9 @@ def parseContent(content, blank_line=re.compile(r'[\r\n]+\s*[\r\n]+'),
335398
336399#
337400# $Log: not supported by cvs2svn $
401+ # Revision 1.11 2001/08/08 00:08:03 richard
402+ # oops ;)
403+ #
338404# Revision 1.10 2001/08/07 00:24:42 richard
339405# stupid typo
340406#
0 commit comments