import re, os, sys
import par2parser
import RarslaveConfig
+from RarslaveLogger import RarslaveLogger
# Global Variables
(TYPE_OLDRAR, TYPE_NEWRAR, TYPE_ZIP, TYPE_NOEXTRACT) = range (4)
-(ECHECK, EEXTRACT, EDELETE) = range(1,4)
+(SUCCESS, ECHECK, EEXTRACT, EDELETE) = range(4)
config = RarslaveConfig.RarslaveConfig()
+logger = RarslaveLogger ()
class RarslaveExtractor (object):
# Create the directory $todir if it doesn't exist
if todir != None and not os.path.isdir (todir):
- # TODO: LOGGER
+ logger.addMessage ('Creating directory: %s' % todir, False)
try:
os.makedirs (todir)
except OSError:
- # TODO: LOGGER
+ logger.addMessage ('FAILED to create directory: %s' % todir)
return -EEXTRACT
# Extract all heads
for h in self.heads:
if todir == None:
# Run in the head's directory
- extraction_func (h, os.path.dirname (h))
+ ret = extraction_func (h, os.path.dirname (h))
else:
- extraction_func (h, todir)
+ ret = extraction_func (h, todir)
+
+ # Check error code
+ if ret != SUCCESS:
+ logger.addMessage ('Failed extracting: %s' % h)
+ return -EEXTRACT
+
+ return SUCCESS
def __extract_rar (self, file, todir):
assert os.path.isfile (file)
if ret != 0:
return -EEXTRACT
+ return SUCCESS
+
def __extract_zip (self, file, todir):
ZIP_CMD = config.get_value ('commands', 'unzip')
if ret != 0:
return -EEXTRACT
+ return SUCCESS
+
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!
if ret != 0:
return -EEXTRACT
+ return SUCCESS
+
class RarslaveRepairer (object):
for f in par2_files:
if f != self.file:
- command += "\"%s\" " % get_filename(f)
+ command += "\"%s\" " % os.path.split (f)[1]
if self.join:
for f in all_files:
if f not in par2_files:
- command += "\"%s\" " % get_filename(f)
+ command += "\"%s\" " % os.path.split (f)[1]
# run the command
ret = run_command (command, self.dir)
# check the result
if ret != 0:
- # TODO: logger
- print 'error during checkAndRepair()'
+ logger.addMessage ('PAR2 Check / Repair failed: %s' % self.file)
return -ECHECK
+ return SUCCESS
+
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.
# FIXME: re-enable this after testing
print 'RUNNING (%s): %s' % (indir, cmd)
- return 0
+ return SUCCESS
# return os.system (cmd)
def full_abspath (p):
return os.path.abspath (os.path.expanduser (p))
-def get_filename (f):
- # TODO: I don't think that we should enforce this...
- # TODO: ... because I think we should be able to get the filename, regardless
- # TODO: of whether this is a legit filename RIGHT NOW or not.
- # assert os.path.isfile (f)
- return os.path.split (f)[1]
-
def get_basename (name):
"""Strips most kinds of endings from a filename"""
prot_files = par2parser.get_protected_files (dir, f)
done = True
except: #FIXME: add the actual exceptions
- print 'ERROR PARSING P2FILE ...', f
+ logger.addMessage ('Error parsing PAR2 file: %s', f)
continue
if done:
for f in prot_files:
extractor.addHead (dir, f)
else:
- print 'BADNESS'
+ logger.addMessage ('Error parsing all PAR2 files in this set ...', True)
# Make sure we found the type
- assert extractor != None
+ if extractor == None:
+ logger.addMessage ('Not able to find an extractor for this type of set: %s' % p2files[0])
+
+ # No-heads here, but it's better than failing completely
+ extractor = RarslaveExtractor (TYPE_NOEXTRACT)
return extractor
if has_extension (f, '.r00'):
return True
+ return False
+
def is_newrar (files):
for f in files:
if has_extension (f, '.part01.rar'):
return True
+ return False
+
def is_zip (files):
for f in files:
if has_extension (f, '.zip'):
return True
+ return False
+
def is_noextract (files):
# Type that needs no extraction.
# TODO: Add others ???
if has_extension (f, '.001'):
return True
+ return False
+
def find_deleteable_files (files):
# Deleteable types regex should come from the config
dfiles = []
# Repair Stage
repairer = RarslaveRepairer (self.dir, par2head, join)
- ret = repairer.checkAndRepair () # FIXME: Check return value
+ ret = repairer.checkAndRepair ()
- if ret: # FAILURE
+ if ret != SUCCESS:
+ logger.addMessage ('Repair stage failed for: %s' % par2head)
return -ECHECK
# Extraction Stage
extractor = find_extraction_heads (self.dir, self.likely_files)
ret = extractor.extract (EXTRACT_DIR)
- if ret: # FAILURE
+ if ret != SUCCESS:
+ logger.addMessage ('Extraction stage failed for: %s' % par2head)
return -EEXTRACT
# Deletion Stage
deleteable_files = find_deleteable_files (self.likely_files)
ret = delete_list (deleteable_files, DELETE_INTERACTIVE)
- if ret: # FAILURE
+ if ret != SUCCESS:
+ logger.addMessage ('Deletion stage failed for: %s' % par2head)
return -EDELETE
- return 0
+ logger.addMessage ('Successfully completed: %s' % par2head, True)
+ return SUCCESS
def delete_list (files, interactive=False):
# Delete a list of files
- # TODO: Add the ability to confirm deletion, like in the original rarslave
+
+ done = False
+ valid_y = ['Y', 'YES']
+ valid_n = ['N', 'NO']
if interactive:
- # TODO: prompt here
- # prompt -> OK_TO_DELETE -> do nothing, fall through
- # prompt -> NOT_OK -> return immediately
- pass
+ 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', f
+ print 'rm \"%s\"' % f
- return 0
+ return SUCCESS
def generate_all_parsets (dir):
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 ()
+ print '\nRARSLAVE STATUS\n'
+ logger.printAllMessages ()
+
if __name__ == '__main__':
main ()