Switched to fileinput module. This allows to read also gzip/bzip2
authorPascal Volk <user@localhost.localdomain.org>
Fri, 19 Feb 2010 11:40:39 +0000
changeset 8 7f131cf431bc
parent 7 83c4798e291d
child 9 3a392067015c
Switched to fileinput module. This allows to read also gzip/bzip2 compressed mail logs, w/o additional command-line options.
nixspamsum
--- a/nixspamsum	Wed Feb 17 23:34:16 2010 +0000
+++ b/nixspamsum	Fri Feb 19 11:40:39 2010 +0000
@@ -9,6 +9,7 @@
 
 import os
 import re
+import fileinput
 
 class NiXSapmSum(object):
     """
@@ -55,6 +56,7 @@
     def getMXs(self):
         return self._mxs
 
+
 def getOptionParser():
     from optparse import OptionParser
     description = 'NiX Spam DNSBL lookup based rejects summarizer'
@@ -78,13 +80,33 @@
     return parser
 
 
-def openLogFile(fname):
-    try:
-        fh = open(fname)
-        return fh
-    except IOError, e:
-        os.sys.stderr.write('Warning: %s\nskipped file: %s\n' % (e.strerror,
-            fname))
+def check_files(log_files):
+    """Checks that all files from *log_files* exist and all of them are
+    readable.
+
+    If a file doesn't exist or is not readable, it will be removed from
+    *log_files* set.
+
+    This function will return *True*, if at least one file has passed the
+    checks. Otherwise *False* will be returned. And the *log_files* set
+    will be emptied.
+
+    :param log_files: set of file names
+    :type log_files: set
+    :rtype: bool"""
+    assert isinstance(log_files, set), 'log_files argument must be a set'
+    lf_copy = log_files.copy()
+    for lf in lf_copy:
+        if not os.path.isfile(lf):
+            os.sys.stderr.write('Warning: No such file: %r\n' % lf)
+            log_files.remove(lf)
+        elif not os.access(lf, os.R_OK):
+            os.sys.stderr.write('Warning: Cannot read file: %r\n' % lf)
+            log_files.remove(lf)
+
+    if log_files:
+        return True
+    return False
 
 
 def buildTable(output, domains, percent, orderBy):
@@ -137,16 +159,23 @@
 def main():
     parser = getOptionParser()
     opts, args = parser.parse_args()
-    if len(args) < 1:
+    if not args:
         parser.error('No log file specified')
+    # drop duplicates
+    log_files = set(args)
+    # remove inexistent/unreadable files
+    if not check_files(log_files):
+        os.sys.stderr.write('No readable log files found\n')
+        return 1
+
     nixss = NiXSapmSum()
     nixss.setLogFormat(opts.format)
-    for fn in args:
-        fh = openLogFile(fn)
-        if fh is not None:
-            nixss.parseLog(fh)
-            fh.close()
+
+    fi = fileinput.FileInput(log_files, openhook=fileinput.hook_compressed)
+    nixss.parseLog(fi)
+    fi.close()
     showResult(nixss, opts)
+    return 0
 
 if __name__ == '__main__':
-    main()
+    os.sys.exit(main())