Use exceptions for error handling
[rarslave2.git] / RarslaveDetector.py
index 9f14261..dfb2768 100644 (file)
@@ -1,52 +1,88 @@
 #!/usr/bin/env python
 # vim: set ts=4 sts=4 sw=4 textwidth=92:
 
-from RarslaveCommon import *
+"""
+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
-import PAR2Set_JOIN
-import PAR2Set_ZIP
-import PAR2Set_OLDRAR
-import PAR2Set_NEWRAR
-import PAR2Set_EF_OLDRAR
-import PAR2Set_EF_NEWRAR
+import PAR2Set.Join
+import PAR2Set.ZIP
+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)
-
-       TYPES = (       (PAR2Set_JOIN.detect_JOIN, PAR2Set_JOIN.PAR2Set_JOIN),
-                               (PAR2Set_ZIP.detect_ZIP, PAR2Set_ZIP.PAR2Set_ZIP),
-                               (PAR2Set_OLDRAR.detect_OLDRAR, PAR2Set_OLDRAR.PAR2Set_OLDRAR),
-                               (PAR2Set_NEWRAR.detect_NEWRAR, PAR2Set_NEWRAR.PAR2Set_NEWRAR),
-                               (PAR2Set_EF_OLDRAR.detect_EF_OLDRAR, PAR2Set_EF_OLDRAR.PAR2Set_EF_OLDRAR),
-                               (PAR2Set_EF_NEWRAR.detect_EF_NEWRAR, PAR2Set_EF_NEWRAR.PAR2Set_EF_NEWRAR),
+       """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
                self.p2file = p2file
-               self.basename = get_basename (p2file)
+               self.basename = rsutil.common.get_basename (p2file)
 
                # Find files that match by name only
-               self.name_matched_files = find_name_matches (self.dir, self.basename)
+               self.name_matched_files = rsutil.common.find_name_matches (self.dir, self.basename)
 
                # Find all par2 files for this set using name matches
-               self.all_p2files = find_par2_files (self.name_matched_files)
+               self.all_p2files = rsutil.common.find_par2_files (self.name_matched_files)
 
                # Try to get the protected files for this set
-               self.prot_matched_files = parse_all_par2 (self.dir, self.p2file, self.all_p2files)
+               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 == 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 -EDETECT
 
                # Make sure that something worked
-               if ret != 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