Use exceptions for error handling
[rarslave2.git] / RarslaveDetector.py
index 08a0b66..dfb2768 100644 (file)
@@ -1,6 +1,33 @@
 #!/usr/bin/env python
 # vim: set ts=4 sts=4 sw=4 textwidth=92:
 
+"""
+Class which runs each detector in the PAR2Set classes, and attempts
+to run all matches on the current set.
+"""
+
+__author__    = "Ira W. Snyder (devel@irasnyder.com)"
+__copyright__ = "Copyright (c) 2006, Ira W. Snyder (devel@irasnyder.com)"
+__license__   = "GNU GPL v2 (or, at your option, any later version)"
+
+#    RarslaveDetector.py
+#
+#    Copyright (C) 2006,2007  Ira W. Snyder (devel@irasnyder.com)
+#
+#    This program is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation; either version 2 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, write to the Free Software
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
 import rsutil.common
 
 # PAR2Set-derived types
@@ -10,23 +37,31 @@ import PAR2Set.OldRAR
 import PAR2Set.NewRAR
 import PAR2Set.ExtractFirstOldRAR
 import PAR2Set.ExtractFirstNewRAR
+import PAR2Set.NoExtract
 
 import logging
 
 class RarslaveDetector (object):
 
-       # A tuple of tuples with the following definition:
-       # (TYPE_NAME, DETECTION_FUNCTION, PAR2Set-derived class)
+       """A class to detect the type of a set, and then run the appropriate class
+          on the set."""
 
+       # A tuple of tuples of the following type:
+       # (type_detection_function, type_working_class)
        TYPES = (       (PAR2Set.Join.detector,   PAR2Set.Join.Join),
                                (PAR2Set.ZIP.detector,    PAR2Set.ZIP.ZIP),
                                (PAR2Set.OldRAR.detector, PAR2Set.OldRAR.OldRAR),
                                (PAR2Set.NewRAR.detector, PAR2Set.NewRAR.NewRAR),
                                (PAR2Set.ExtractFirstOldRAR.detector, PAR2Set.ExtractFirstOldRAR.ExtractFirstOldRAR),
                                (PAR2Set.ExtractFirstNewRAR.detector, PAR2Set.ExtractFirstNewRAR.ExtractFirstNewRAR),
+                               (PAR2Set.NoExtract.detector, PAR2Set.NoExtract.NoExtract),
                        )
 
        def __init__ (self, dir, p2file):
+               """Constructor
+
+                  dir -- the directory containing this set
+                  p2file -- a single PAR2 file from this set"""
 
                # The real "meat" of the class
                self.dir = dir
@@ -43,10 +78,11 @@ class RarslaveDetector (object):
                self.prot_matched_files = rsutil.common.parse_all_par2 (self.dir, self.p2file, self.all_p2files)
 
        def runMatchingTypes (self):
-               # Now tries to run every type of PAR2Set-derived class for which the detector
-               # detects that the class is valid.
+               """Run all matching PAR2Set types for which the detection function detects that
+                  the class is valid."""
 
                detected = False
+               success = False
 
                for (detector, classname) in self.TYPES:
                        if detector (self.name_matched_files, self.prot_matched_files):
@@ -58,14 +94,18 @@ class RarslaveDetector (object):
                                logging.debug ('Detected type: %s' % p2set)
 
                                # Try to have rarslave do it's thing
-                               ret = p2set.runAll ()
+                               try:
+                                       # Have rarslave do it's thing
+                                       p2set.runAll ()
 
-                               # If something already worked, there is no need to continue,
-                               # since we've already finished!
-                               if ret == rsutil.common.SUCCESS:
+                                       # It succeeded, exit the loop early
+                                       success = True
                                        break
-                               else:
-                                       logging.error ('Detected type failed for: %s' % self.p2file)
+                               except (OSError, RuntimeError):
+                                       logging.error('Detected type (%s) failed for: %s' % (p2set, self.p2file))
+                               except:
+                                       logging.error('Unknown exception occurred')
+                                       raise
 
                # Make sure we detected at least one valid type
                if not detected:
@@ -73,13 +113,10 @@ class RarslaveDetector (object):
                        logging.debug ('The following information will help in writing a detector:')
                        logging.debug ('name_matches: %s' % self.name_matched_files)
                        logging.debug ('prot_matches: %s' % self.prot_matched_files)
-                       return -rsutil.common.EDETECT
 
                # Make sure that something worked
-               if ret != rsutil.common.SUCCESS:
-                       logging.critical ('All types failed for: %s' % self.p2file)
-
-               return ret
+               if success == False:
+                       logging.critical('All types failed for: %s' % self.p2file)
 
 def main ():
        pass