[Python-checkins] r53589 - tracker/roundup-src/roundup tracker/roundup-src/roundup/mailgw.py

erik.forsberg python-checkins at python.org
Sun Jan 28 16:51:51 CET 2007


Author: erik.forsberg
Date: Sun Jan 28 16:51:50 2007
New Revision: 53589

Modified:
   tracker/roundup-src/roundup/   (props changed)
   tracker/roundup-src/roundup/mailgw.py
Log:

Use mailgw.py from roundup-HEAD as it has a rewritten subject parser
that should cope better with mailing list subject lines. 

Ignore *.pyc on roundup-src.


Modified: tracker/roundup-src/roundup/mailgw.py
==============================================================================
--- tracker/roundup-src/roundup/mailgw.py	(original)
+++ tracker/roundup-src/roundup/mailgw.py	Sun Jan 28 16:51:50 2007
@@ -72,7 +72,7 @@
 an exception, the original message is bounced back to the sender with the
 explanatory message given in the exception.
 
-$Id: mailgw.py,v 1.180 2006/12/19 01:13:31 richard Exp $
+$Id: mailgw.py,v 1.183 2007/01/28 13:49:13 forsberg Exp $
 """
 __docformat__ = 'restructuredtext'
 
@@ -619,57 +619,89 @@
 
         # Matches subjects like:
         # Re: "[issue1234] title of issue [status=resolved]"
-        open, close = config['MAILGW_SUBJECT_SUFFIX_DELIMITERS']
-        delim_open = re.escape(open)
+
+        tmpsubject = subject # We need subject untouched for later use
+                             # in error messages
+
+        sd_open, sd_close = config['MAILGW_SUBJECT_SUFFIX_DELIMITERS']
+        delim_open = re.escape(sd_open)
         if delim_open in '[(': delim_open = '\\' + delim_open
-        delim_close = re.escape(close)
+        delim_close = re.escape(sd_close)
         if delim_close in '[(': delim_close = '\\' + delim_close
-        subject_re = r'''
-        (?P<refwd>\s*\W?\s*(fw|fwd|re|aw|sv|ang)\W\s*)*\s*   # Re:
-        (?P<quote>")?                                 # Leading "
-        (%s(?P<classname>[^\d\s]+)                    # [issue..
-           (?P<nodeid>\d+)?                           # ..1234]
-         %s)?\s*
-        (?P<title>[^%s]+)?                             # issue title
-        "?                                            # Trailing "
-        (?P<argswhole>%s(?P<args>.+?)%s)?             # [prop=value]
-        '''%(delim_open, delim_close, delim_open, delim_open, delim_close)
-        subject_re = re.compile(subject_re, re.IGNORECASE|re.VERBOSE)
+
+        matches = dict.fromkeys(['refwd', 'quote', 'classname',
+                                 'nodeid', 'title', 'args',
+                                 'argswhole'])
+
+
+        # Look for Re: et. al. Used later on for MAILGW_SUBJECT_CONTENT_MATCH
+        re_re = r'''(?P<refwd>(\s*\W?\s*(fw|fwd|re|aw|sv|ang)\W)+)\s*'''
+        m = re.match(re_re, tmpsubject, re.IGNORECASE|re.VERBOSE)
+        if m:
+            matches.update(m.groupdict())
+            tmpsubject = tmpsubject[len(matches['refwd']):] # Consume Re:
+
+        # Look for Leading "
+        m = re.match(r'''(?P<quote>\s*")''', tmpsubject,
+                     re.IGNORECASE|re.VERBOSE)
+        if m:
+            matches.update(m.groupdict())
+            tmpsubject = tmpsubject[len(matches['quote']):] # Consume quote
+
+        class_re = r'''%s(?P<classname>(%s))+(?P<nodeid>\d+)?%s''' % \
+                   (delim_open, "|".join(self.db.getclasses()), delim_close)
+        # Note: re.search, not re.match as there might be garbage
+        # (mailing list prefix, etc.) before the class identifier
+        m = re.search(class_re, tmpsubject, re.IGNORECASE|re.VERBOSE)
+        if m:
+            matches.update(m.groupdict())
+            # Skip to the end of the class identifier, including any
+            # garbage before it.
+            
+            tmpsubject = tmpsubject[m.end():]
+
+        m = re.match(r'''(?P<title>[^%s]+)''' % delim_open, tmpsubject,
+                     re.IGNORECASE|re.VERBOSE)
+        if m:
+            matches.update(m.groupdict())
+            tmpsubject = tmpsubject[len(matches['title']):] # Consume title
+
+        args_re = r'''(?P<argswhole>%s(?P<args>.+?)%s)?''' % (delim_open, delim_close)
+        m = re.search(args_re, tmpsubject, re.IGNORECASE|re.VERBOSE)
+        if m:
+            matches.update(m.groupdict())
 
         # figure subject line parsing modes
         pfxmode = config['MAILGW_SUBJECT_PREFIX_PARSING']
         sfxmode = config['MAILGW_SUBJECT_SUFFIX_PARSING']
 
-        # check for well-formed subject line
-        m = subject_re.match(subject)
-        if m:
-            # check for registration OTK
-            # or fallback on the default class
-            if self.db.config['EMAIL_REGISTRATION_CONFIRMATION']:
-                otk_re = re.compile('-- key (?P<otk>[a-zA-Z0-9]{32})')
-                otk = otk_re.search(m.group('title') or '')
-                if otk:
-                    self.db.confirm_registration(otk.group('otk'))
-                    subject = 'Your registration to %s is complete' % \
-                              config['TRACKER_NAME']
-                    sendto = [from_list[0][1]]
-                    self.mailer.standard_message(sendto, subject, '')
-                    return
-            # get the classname
-            if pfxmode == 'none':
-                classname = None
+        # check for registration OTK
+        # or fallback on the default class
+        if self.db.config['EMAIL_REGISTRATION_CONFIRMATION']:
+            otk_re = re.compile('-- key (?P<otk>[a-zA-Z0-9]{32})')
+            otk = otk_re.search(matches['title'] or '')
+            if otk:
+                self.db.confirm_registration(otk.group('otk'))
+                subject = 'Your registration to %s is complete' % \
+                          config['TRACKER_NAME']
+                sendto = [from_list[0][1]]
+                self.mailer.standard_message(sendto, subject, '')
+                return
+        # get the classname
+        if pfxmode == 'none':
+            classname = None
+        else:
+            classname = matches['classname']
+        if classname is None:
+            if self.default_class:
+                classname = self.default_class
             else:
-                classname = m.group('classname')
-            if classname is None:
-                if self.default_class:
-                    classname = self.default_class
-                else:
-                    classname = config['MAILGW_DEFAULT_CLASS']
-                    if not classname:
-                        # fail
-                        m = None
+                classname = config['MAILGW_DEFAULT_CLASS']
+                if not classname:
+                    # fail
+                    m = None
 
-        if not m and pfxmode == 'strict':
+        if not classname and pfxmode == 'strict':
             raise MailUsageError, _("""
 The message you sent to roundup did not contain a properly formed subject
 line. The subject must contain a class name or designator to indicate the
@@ -713,17 +745,17 @@
         if pfxmode == 'none':
             nodeid = None
         else:
-            nodeid = m.group('nodeid')
+            nodeid = matches['nodeid']
 
         # try in-reply-to to match the message if there's no nodeid
         inreplyto = message.getheader('in-reply-to') or ''
         if nodeid is None and inreplyto:
-            l = self.db.getclass('msg').stringFind(inreplyto=inreplyto)
+            l = self.db.getclass('msg').stringFind(messageid=inreplyto)
             if l:
-                nodeid = l[0]
+                nodeid = cl.filter(None, {'messages':l})[0]
 
         # title is optional too
-        title = m.group('title')
+        title = matches['title']
         if title:
             title = title.strip()
         else:
@@ -731,7 +763,7 @@
 
         # strip off the quotes that dumb emailers put around the subject, like
         #      Re: "[issue1] bla blah"
-        if m.group('quote') and title.endswith('"'):
+        if matches['quote'] and title.endswith('"'):
             title = title[:-1]
 
         # but we do need either a title or a nodeid...
@@ -752,7 +784,7 @@
         # additional restriction based on the matched node's creation or
         # activity.
         tmatch_mode = config['MAILGW_SUBJECT_CONTENT_MATCH']
-        if tmatch_mode != 'never' and nodeid is None and m.group('refwd'):
+        if tmatch_mode != 'never' and nodeid is None and matches['refwd']:
             l = cl.stringFind(title=title)
             limit = None
             if (tmatch_mode.startswith('creation') or
@@ -905,8 +937,8 @@
         # figure what the properties of this Class are
         properties = cl.getprops()
         props = {}
-        args = m.group('args')
-        argswhole = m.group('argswhole')
+        args = matches['args']
+        argswhole = matches['argswhole']
         if args:
             if sfxmode == 'none':
                 title += ' ' + argswhole


More information about the Python-checkins mailing list