+class PAR2Set (object):
+
+ dir = None
+ file = None
+ likely_files = []
+
+ def __init__ (self, dir, file):
+ assert os.path.isdir (dir)
+ assert os.path.isfile (os.path.join (dir, file))
+
+ self.dir = dir
+ self.file = file
+
+ basename = get_basename (file)
+ self.likely_files = find_likely_files (basename, dir)
+
+ def __list_eq (self, l1, l2):
+
+ if len(l1) != len(l2):
+ return False
+
+ for e in l1:
+ if e not in l2:
+ return False
+
+ return True
+
+ def __eq__ (self, rhs):
+ return self.__list_eq (self.likely_files, rhs.likely_files)
+
+ def run_all (self):
+ par2files = find_par2_files (self.likely_files)
+ par2head = par2files[0]
+
+ join = is_noextract (self.likely_files)
+
+ # Repair Stage
+ repairer = RarslaveRepairer (self.dir, par2head, join)
+ ret = repairer.checkAndRepair ()
+
+ if ret != SUCCESS:
+ logger.addMessage ('Repair stage failed for: %s' % par2head, RarslaveLogger.MessageType.Fatal)
+ return -ECHECK
+
+ # Extraction Stage
+ EXTRACT_DIR = options.extract_dir
+ extractor = find_extraction_heads (self.dir, self.likely_files)
+ ret = extractor.extract (EXTRACT_DIR)
+
+ if ret != SUCCESS:
+ logger.addMessage ('Extraction stage failed for: %s' % par2head, RarslaveLogger.MessageType.Fatal)
+ return -EEXTRACT
+
+ # Deletion Stage
+ DELETE_INTERACTIVE = options.interactive
+ deleteable_files = find_deleteable_files (self.likely_files)
+ ret = delete_list (deleteable_files, DELETE_INTERACTIVE)
+
+ if ret != SUCCESS:
+ logger.addMessage ('Deletion stage failed for: %s' % par2head, RarslaveLogger.MessageType.Fatal)
+ return -EDELETE
+
+ logger.addMessage ('Successfully completed: %s' % par2head)
+ return SUCCESS
+
+def delete_list (files, interactive=False):
+ # Delete a list of files
+
+ done = False
+ valid_y = ['Y', 'YES']
+ valid_n = ['N', 'NO']
+
+ if interactive:
+ while not done:
+ print 'Do you want to delete the following?:'
+ s = raw_input ('Delete [y/N]: ').upper()
+
+ if s in valid_y + valid_n:
+ done = True
+
+ if s in valid_n:
+ return SUCCESS
+
+ for f in files:
+ # FIXME: re-enable this in production
+ # os.remove (f)
+ print 'rm \"%s\"' % f
+
+ return SUCCESS
+
+
+def generate_all_parsets (dir):
+ # Generate all parsets in the given directory.
+
+ assert os.path.isdir (dir) # Directory MUST be valid
+
+ parsets = []
+ p2files = find_all_par2_files (dir)
+
+ for f in p2files:
+ p = PAR2Set (dir, f)
+ if p not in parsets:
+ parsets.append (p)
+
+ return parsets
+
+def check_required_progs():
+ """Check if the required programs are installed"""
+
+ shell_not_found = 32512
+ needed = []
+
+ if run_command ('par2repair --help > /dev/null 2>&1') == shell_not_found:
+ needed.append ('par2repair')
+
+ if run_command ('unrar --help > /dev/null 2>&1') == shell_not_found:
+ needed.append ('unrar')
+
+ if run_command ('unzip --help > /dev/null 2>&1') == shell_not_found:
+ needed.append ('unzip')
+
+ if needed:
+ for n in needed:
+ print 'Needed program "%s" not found in $PATH' % (n, )
+
+ sys.exit(1)
+
+def run_options (options):
+ options.work_dir = full_abspath (options.work_dir)
+
+ if options.extract_dir != None:
+ options.extract_dir = full_abspath (options.extract_dir)
+
+ if options.version:
+ print PROGRAM + ' - ' + VERSION
+ print
+ print 'Copyright (c) 2005,2006 Ira W. Snyder (devel@irasnyder.com)'
+ print
+ print 'This program comes with ABSOLUTELY NO WARRANTY.'
+ print 'This is free software, and you are welcome to redistribute it'
+ print 'under certain conditions. See the file COPYING for details.'
+ sys.exit (0)
+
+ if options.check_progs:
+ check_required_progs ()
+
+ if options.write_def_config:
+ config.write_config (default=True)
+
+ if options.write_config:
+ config.write_config ()
+
+def find_loglevel (options):
+
+ loglevel = options.verbose - options.quiet
+
+ if loglevel < RarslaveLogger.MessageType.Fatal:
+ loglevel = RarslaveLogger.MessageType.Fatal
+
+ if loglevel > RarslaveLogger.MessageType.Debug:
+ loglevel = RarslaveLogger.MessageType.Debug
+
+ return loglevel
+
+def printMessageTable (loglevel):
+
+ if logger.hasFatalMessages ():
+ print '\nFatal Messages\n' + '=' * 80
+ logger.printLoglevel (RarslaveLogger.MessageType.Fatal)
+
+ if loglevel == RarslaveLogger.MessageType.Fatal:
+ return
+
+ if logger.hasNormalMessages ():
+ print '\nNormal Messages\n' + '=' * 80
+ logger.printLoglevel (RarslaveLogger.MessageType.Normal)
+
+ if loglevel == RarslaveLogger.MessageType.Normal:
+ return
+
+ if logger.hasVerboseMessages ():
+ print '\nVerbose Messages\n' + '=' * 80
+ logger.printLoglevel (RarslaveLogger.MessageType.Verbose)
+
+ if loglevel == RarslaveLogger.MessageType.Verbose:
+ return
+
+ if logger.hasDebugMessages ():
+ print '\nDebug Messages\n' + '=' * 80
+ logger.printLoglevel (RarslaveLogger.MessageType.Debug)
+
+ return
+