]> granicus.if.org Git - python/commitdiff
More changes by Sjoerd & Jack
authorGuido van Rossum <guido@python.org>
Sun, 21 Jul 1996 02:50:30 +0000 (02:50 +0000)
committerGuido van Rossum <guido@python.org>
Sun, 21 Jul 1996 02:50:30 +0000 (02:50 +0000)
Tools/scripts/mailerdaemon.py

index 245f670217a86da38df4fdef66cc68a2ee91af97..f2e8ac46415ac3ef494f304d4f86fab74f7001fa 100755 (executable)
@@ -2,6 +2,7 @@
 
 import string
 import rfc822
+import calendar
 import regex
 import os
 import sys
@@ -17,21 +18,22 @@ class ErrorMessage(rfc822.Message):
        if not sub:
            return 0
        sub = string.lower(sub)
-       if sub == 'waiting mail': return 1
+       if sub[:12] == 'waiting mail': return 1
        if string.find(sub, 'warning') >= 0: return 1
+       self.sub = sub
        return 0
 
     def get_errors(self):
        for p in EMPARSERS:
            self.rewindbody()
            try:
-               return p(self.fp)
+               return p(self.fp, self.sub)
            except Unparseable:
                pass
        raise Unparseable
 
 sendmail_pattern = regex.compile('[0-9][0-9][0-9] ')
-def emparse_sendmail(fp):
+def emparse_sendmail(fp, sub):
     while 1:
        line = fp.readline()
        if not line:
@@ -60,7 +62,6 @@ def emparse_sendmail(fp):
        line = line[:-1]
        if not line:
            continue
-       found_a_line = 1
        if sendmail_pattern.match(line) == 4:
            # Yes, an error/warning line. Ignore 4, remember 5, stop on rest
            if line[0] == '5':
@@ -72,12 +73,23 @@ def emparse_sendmail(fp):
        line = string.split(line)
        if line and line[0][:3] == '---':
            break
+       found_a_line = 1
+    # special case for CWI sendmail
+    if len(line) > 1 and line[1] == 'Undelivered':
+       while 1:
+           line = fp.readline()
+           if not line:
+               break
+           line = string.strip(line)
+           if not line:
+               break
+           errors.append(line + ': ' + sub)
     # Empty transcripts are ok, others without an error are not.
     if found_a_line and not (errors or warnings):
        raise Unparseable
     return errors
     
-def emparse_cts(fp):
+def emparse_cts(fp, sub):
     while 1:
        line = fp.readline()
        if not line:
@@ -106,7 +118,7 @@ def emparse_cts(fp):
        errors.append(line)
     return errors
 
-def emparse_aol(fp):
+def emparse_aol(fp, sub):
     while 1:
        line = fp.readline()
        if not line:
@@ -132,7 +144,7 @@ def emparse_aol(fp):
            raise Unparseable
     return errors
     
-def emparse_compuserve(fp):
+def emparse_compuserve(fp, sub):
     while 1:
        line = fp.readline()
        if not line:
@@ -157,8 +169,7 @@ def emparse_compuserve(fp):
     return errors
 
 prov_pattern = regex.compile('.* | \(.*\)')
-
-def emparse_providence(fp):
+def emparse_providence(fp, sub):
     while 1:
        line = fp.readline()
        if not line:
@@ -189,58 +200,141 @@ def emparse_providence(fp):
        raise Unparseable
     return errors
 
+def emparse_x400(fp, sub):
+    exp = 'This report relates to your message:'
+    while 1:
+       line = fp.readline()
+       if not line:
+           raise Unparseable
+       line = line[:-1]
+
+       # Check that we're not in the returned message yet
+       if string.lower(line)[:5] == 'from:':
+           raise Unparseable
+       if line[:len(exp)] == exp:
+           break
+
+    errors = []
+    exp = 'Your message was not delivered to'
+    while 1:
+       line = fp.readline()
+       if not line:
+           break
+       line = line[:-1]
+       if not line:
+           continue
+       if line[:len(exp)] == exp:
+           error = string.strip(line[len(exp):])
+           sep = ': '
+           while 1:
+               line = fp.readline()
+               if not line:
+                   break
+               line = line[:-1]
+               if not line:
+                   break
+               if line[0] == ' ' and line[-1] != ':':
+                   error = error + sep + string.strip(line)
+                   sep = '; '
+           errors.append(error)
+           return errors
+    raise Unparseable
+
+def emparse_passau(fp, sub):
+    exp = 'Unable to deliver message because'
+    while 1:
+       line = fp.readline()
+       if not line:
+           raise Unparseable
+       if string.lower(line)[:5] == 'from:':
+           raise Unparseable
+       if line[:len(exp)] == exp:
+           break
+
+    errors = []
+    exp = 'Returned Text follows'
+    while 1:
+       line = fp.readline()
+       if not line:
+           raise Unparseable
+       line = line[:-1]
+       # Check that we're not in the returned message yet
+       if string.lower(line)[:5] == 'from:':
+           raise Unparseable
+       if not line:
+           continue
+       if line[:len(exp)] == exp:
+           return errors
+       errors.append(string.strip(line))
+
 EMPARSERS = [emparse_sendmail, emparse_aol, emparse_cts, emparse_compuserve,
-            emparse_providence]
+            emparse_providence, emparse_x400, emparse_passau]
+
+def sort_numeric(a, b):
+    a = string.atoi(a)
+    b = string.atoi(b)
+    if a < b: return -1
+    elif a > b: return 1
+    else: return 0
 
 def parsedir(dir, modify):
     os.chdir(dir)
-    files = os.listdir('.')
     pat = regex.compile('^[0-9]*$')
     errordict = {}
+    errorfirst = {}
     errorlast = {}
     nok = nwarn = nbad = 0
+
+    # find all numeric file names and sort them
+    files = filter(lambda fn, pat=pat: pat.match(fn) > 0, os.listdir('.'))
+    files.sort(sort_numeric)
     
     for fn in files:
-       if pat.match(fn) > 0:
-           # Ok, so it's a numeric filename. Lets try to parse it.
-           fp = open(fn)
-           m = ErrorMessage(fp)
-           sender = m.getaddr('From')
-           print '%s\t%-40s\t'%(fn, sender[1]),
-           
-           if m.is_warning():
-               print 'warning only'
-               nwarn = nwarn + 1
-               if modify:
-                   os.unlink(fn)
-               continue
-
-           try:
-               errors = m.get_errors()
-           except Unparseable:
-               print '** Not parseable'
-               nbad = nbad + 1
-               continue
-           print len(errors), 'errors'
-
-           # Remember them
-           for e in errors:
-               if not errordict.has_key(e):
-                   errordict[e] = 1
-               else:
-                   errordict[e] = errordict[e] + 1
-               errorlast[e] = fn
+       # Lets try to parse the file.
+       fp = open(fn)
+       m = ErrorMessage(fp)
+       sender = m.getaddr('From')
+       print '%s\t%-40s\t'%(fn, sender[1]),
 
-           nok = nok + 1
+       if m.is_warning():
+           print 'warning only'
+           nwarn = nwarn + 1
            if modify:
                os.unlink(fn)
+           continue
+
+       try:
+           errors = m.get_errors()
+       except Unparseable:
+           print '** Not parseable'
+           nbad = nbad + 1
+           continue
+       print len(errors), 'errors'
+
+       # Remember them
+       for e in errors:
+           try:
+               mm, dd = m.getdate('date')[1:1+2]
+               date = '%s %02d' % (calendar.month_abbr[mm], dd)
+           except:
+               date = '??????'
+           if not errordict.has_key(e):
+               errordict[e] = 1
+               errorfirst[e] = '%s (%s)' % (fn, date)
+           else:
+               errordict[e] = errordict[e] + 1
+           errorlast[e] = '%s (%s)' % (fn, date)
+
+       nok = nok + 1
+       if modify:
+           os.unlink(fn)
 
     print '--------------'
     print nok, 'files parsed,',nwarn,'files warning-only,',
     print nbad,'files unparseable'
     print '--------------'
     for e in errordict.keys():
-       print errordict[e], '\t', errorlast[e], '\t', e
+       print errordict[e], errorfirst[e], '-', errorlast[e], '\t', e
 
 def main():
     modify = 0