X-Git-Url: https://www.irasnyder.com/gitweb/?p=rarslave2.git;a=blobdiff_plain;f=rarslave.py;h=3f251f3b4f27733f33b09d5901f1a693ac80cdc2;hp=fab1f69f45f955b651a63dd402b3311cb3a95a1e;hb=e13c9c644cd762dcc0266dfa6b75fc003454ed61;hpb=61bead019809659b0a98f2309e19b5459139659a diff --git a/rarslave.py b/rarslave.py index fab1f69..3f251f3 100644 --- a/rarslave.py +++ b/rarslave.py @@ -3,9 +3,12 @@ import re, os, sys import par2parser +import RarslaveConfig # Global Variables (TYPE_OLDRAR, TYPE_NEWRAR, TYPE_ZIP, TYPE_NOEXTRACT) = range (4) +(ECHECK, EEXTRACT, EDELETE) = range(1,4) +config = RarslaveConfig.RarslaveConfig() class RarslaveExtractor (object): @@ -22,18 +25,17 @@ class RarslaveExtractor (object): self.heads.append (os.path.join (dir, head)) - def extract (self, todir): + def extract (self, todir=None): # Extract all heads of this set # Create the directory $todir if it doesn't exist - if not os.path.isdir (todir): + if todir != None and not os.path.isdir (todir): # TODO: LOGGER try: os.makedirs (todir) except OSError: # TODO: LOGGER - # Failed mkdir -p, clean up time ... - pass # FIXME: temporary for syntax + return -EEXTRACT # Extract all heads extraction_func = \ @@ -44,32 +46,47 @@ class RarslaveExtractor (object): # Call the extraction function on each head for h in self.heads: - extraction_func (h, todir) + if todir == None: + # Run in the head's directory + extraction_func (h, os.path.dirname (h)) + else: + extraction_func (h, todir) def __extract_rar (self, file, todir): assert os.path.isfile (file) assert os.path.isdir (todir) - RAR_CMD = 'unrar x -o+ -- ' - - #file = full_abspath (file) - #todir = full_abspath (todir) + RAR_CMD = config.get_value ('commands', 'unrar') cmd = '%s \"%s\"' % (RAR_CMD, file) ret = run_command (cmd, todir) + # Check error code + if ret != 0: + return -EEXTRACT + def __extract_zip (self, file, todir): - ZIP_CMD = 'unzip \"%s\" -d \"%s\"' + ZIP_CMD = config.get_value ('commands', 'unzip') cmd = ZIP_CMD % (file, todir) ret = run_command (cmd) + # Check error code + if ret != 0: + return -EEXTRACT + def __extract_noextract (self, file, todir): # Just move this file to the $todir, since no extraction is needed # FIXME: NOTE: mv will fail by itself if you're moving to the same dir! - cmd = 'mv \"%s\" \"%s\"' % (file, todir) + NOEXTRACT_CMD = config.get_value ('commands', 'noextract') + + cmd = NOEXTRACT_CMD % (file, todir) ret = run_command (cmd) + # Check error code + if ret != 0: + return -EEXTRACT + class RarslaveRepairer (object): @@ -87,7 +104,7 @@ class RarslaveRepairer (object): def checkAndRepair (self): # Form the command: # par2repair -- PAR2 PAR2_EXTRA [JOIN_FILES] - PAR2_CMD = 'par2repair -- ' + PAR2_CMD = config.get_value ('commands', 'par2repair') # Get set up basename = get_basename (self.file) @@ -110,6 +127,12 @@ class RarslaveRepairer (object): # run the command ret = run_command (command, self.dir) + # check the result + if ret != 0: + # TODO: logger + print 'error during checkAndRepair()' + return -ECHECK + def run_command (cmd, indir=None): # Runs the specified command-line in the directory given (or, in the current directory # if none is given). It returns the status code given by the application. @@ -118,10 +141,12 @@ def run_command (cmd, indir=None): if indir != None: assert os.path.isdir (indir) # MUST be a directory! - os.chdir (pwd) + os.chdir (indir) # FIXME: re-enable this after testing print 'RUNNING (%s): %s' % (indir, cmd) + return 0 + # return os.system (cmd) @@ -138,7 +163,7 @@ def get_filename (f): def get_basename (name): """Strips most kinds of endings from a filename""" - regex = '^(.+)\.(par2|vol\d+\+\d+|\d\d\d|part\d+|rar|zip|avi|mp4|mkv|ogm)$' + regex = config.get_value ('regular expressions', 'basename_regex') r = re.compile (regex, re.IGNORECASE) done = False @@ -168,7 +193,8 @@ def find_likely_files (name, dir): def find_par2_files (files): """Find all par2 files in the list $files""" - regex = re.compile ('^.*\.par2$', re.IGNORECASE) + PAR2_REGEX = config.get_value ('regular expressions', 'par2_regex') + regex = re.compile (PAR2_REGEX, re.IGNORECASE) return [f for f in files if regex.match (f)] def find_all_par2_files (dir): @@ -284,7 +310,8 @@ def is_noextract (files): def find_deleteable_files (files): # Deleteable types regex should come from the config dfiles = [] - dregex = re.compile ('^.*\.(par2|\d|\d\d\d|rar|r\d\d|zip)$', re.IGNORECASE) + DELETE_REGEX = config.get_value ('regular expressions', 'delete_regex') + dregex = re.compile (DELETE_REGEX, re.IGNORECASE) return [f for f in files if dregex.match (f)] @@ -322,6 +349,55 @@ class PAR2Set (object): 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 () # FIXME: Check return value + + if ret: # FAILURE + return -ECHECK + + # Extraction Stage + EXTRACT_DIR = config.get_value ('directories', 'extract_directory') + extractor = find_extraction_heads (self.dir, self.likely_files) + ret = extractor.extract (EXTRACT_DIR) + + if ret: # FAILURE + return -EEXTRACT + + # Deletion Stage + DELETE_INTERACTIVE = config.get_value ('options', 'interactive') + deleteable_files = find_deleteable_files (self.likely_files) + ret = delete_list (deleteable_files, DELETE_INTERACTIVE) + + if ret: # FAILURE + return -EDELETE + + return 0 + +def delete_list (files, interactive=False): + # Delete a list of files + # TODO: Add the ability to confirm deletion, like in the original rarslave + + if interactive: + # TODO: prompt here + # prompt -> OK_TO_DELETE -> do nothing, fall through + # prompt -> NOT_OK -> return immediately + pass + + for f in files: + # FIXME: re-enable this in production + # os.remove (f) + print 'rm', f + + return 0 + + def generate_all_parsets (dir): # Generate all parsets in the given directory. @@ -338,75 +414,13 @@ def generate_all_parsets (dir): return parsets def main (): - # Setup stage - print '\nSETUP STAGE' - DIR = os.path.abspath ('test_material/01/') - p2files = find_all_par2_files (DIR) - p2file = p2files[0] - - # Repair stage - print '\nREPAIR STAGE' - repairer = RarslaveRepairer (DIR, p2file) - repairer.checkAndRepair () - - # Extraction stage - print '\nEXTRACTION STAGE' - files = find_likely_files (get_basename (p2file), DIR) - extractor = find_extraction_heads (DIR, files) - extractor.extract('extract_dir') - - # Deletion stage - print '\nDELETION STAGE' - printlist ( find_deleteable_files (files) ) - - print '\n\n' - - # Setup stage - print '\nSETUP STAGE' - DIR = os.path.abspath ('test_material/13/') - p2files = find_all_par2_files (DIR) - p2file = p2files[0] - - # Repair stage - print '\nREPAIR STAGE' - RarslaveRepairer (DIR, p2file, join=True).checkAndRepair () - - # Extraction stage - print '\nEXTRACTION STAGE' - files = find_likely_files (get_basename (p2file), DIR) - find_extraction_heads (DIR, files).extract ('extract_dir') - - # Deletion stage - print '\nDELETION STAGE' - printlist ( find_deleteable_files (files) ) - - print '\n\n' - - # Setup stage - print '\nSETUP STAGE' - DIR = os.path.abspath ('test_material/14/') - p2files = find_all_par2_files (DIR) - p2file = p2files[0] - - # Repair stage - print '\nREPAIR STAGE' - RarslaveRepairer (DIR, p2file, join=True).checkAndRepair () - - # Extraction stage - print '\nEXTRACTION STAGE' - files = find_likely_files (get_basename (p2file), DIR) - find_extraction_heads (DIR, files).extract ('extract_dir') - - # Deletion stage - print '\nDELETEION STAGE' - printlist ( find_deleteable_files (files) ) - - #### TESTING #### - parsets = generate_all_parsets ('test_material/02/') - print '\n\nPARSETS LEN:', len(parsets) - for p in parsets: - print p.likely_files[0] + TOPDIR = os.path.abspath ('test_material') + for (dir, subdirs, files) in os.walk (TOPDIR): + print 'DEBUG: IN DIRECTORY:', dir + parsets = generate_all_parsets (dir) + for p in parsets: + p.run_all () if __name__ == '__main__': main ()