diff --git a/DeleteSamples.py b/DeleteSamples.py index 03956f6c..5d9abe99 100755 --- a/DeleteSamples.py +++ b/DeleteSamples.py @@ -32,6 +32,8 @@ import os import sys import nzbtomedia +from nzbtomedia.nzbToMediaUtil import joinPath + def is_sample(filePath, inputName, maxSampleSize, SampleIDs): # 200 MB in bytes @@ -101,7 +103,7 @@ if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5 for dirpath, dirnames, filenames in os.walk(os.environ['NZBPP_DIRECTORY']): for file in filenames: - filePath = os.path.join(dirpath, file) + filePath = joinPath(dirpath, file) fileName, fileExtension = os.path.splitext(file) if fileExtension in mediaContainer: # If the file is a video file diff --git a/ResetDateTime.py b/ResetDateTime.py index fc2df369..d5d88f02 100755 --- a/ResetDateTime.py +++ b/ResetDateTime.py @@ -15,6 +15,7 @@ import os import sys import nzbtomedia +from nzbtomedia.nzbToMediaUtil import joinPath if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5] < '11.0': print "Script triggered from NZBGet (11.0 or later)." @@ -66,7 +67,7 @@ if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5 directory = os.path.normpath(os.environ['NZBPP_DIRECTORY']) for dirpath, dirnames, filenames in os.walk(directory): for file in filenames: - filepath = os.path.join(dirpath, file) + filepath = joinPath(dirpath, file) print "reseting datetime for file", filepath try: os.utime(filepath, None) diff --git a/TorrentToMedia.py b/TorrentToMedia.py index 462b8067..94bc000e 100755 --- a/TorrentToMedia.py +++ b/TorrentToMedia.py @@ -16,9 +16,8 @@ from nzbtomedia.autoProcess.autoProcessMovie import autoProcessMovie from nzbtomedia.autoProcess.autoProcessMusic import autoProcessMusic from nzbtomedia.autoProcess.autoProcessTV import autoProcessTV from nzbtomedia.extractor import extractor -from nzbtomedia.nzbToMediaUtil import category_search, sanitizeFileName, is_sample, copy_link, parse_args, flatten, get_dirnames, \ - remove_read_only, cleanup_directories, create_torrent_class, pause_torrent, resume_torrent, listMediaFiles, \ - listArchiveFiles +from nzbtomedia.nzbToMediaUtil import category_search, sanitizeFileName, copy_link, parse_args, flatten, get_dirnames, \ + remove_read_only, cleanup_directories, create_torrent_class, pause_torrent, resume_torrent, listMediaFiles, joinPath from nzbtomedia import logger def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, clientAgent): @@ -45,7 +44,7 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, if inputCategory == "": inputCategory = "UNCAT" - outputDestination = os.path.normpath(os.path.join(nzbtomedia.OUTPUTDIRECTORY, inputCategory, sanitizeFileName(inputName))) + outputDestination = os.path.normpath(joinPath(nzbtomedia.OUTPUTDIRECTORY, inputCategory, sanitizeFileName(inputName))) logger.info("Output directory set to: %s" % (outputDestination)) if nzbtomedia.CFG["SickBeard"][inputCategory]: @@ -85,92 +84,87 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, outputDestinationMaster = outputDestination # Save the original, so we can change this within the loop below, and reset afterwards. now = datetime.datetime.now() - if single: inputDirectory,filename = os.path.split(inputDirectory) - for dirpath, dirnames, filenames in os.walk(inputDirectory): - if single: - dirnames[:] = [] - filenames[:] = [filenames] # we just want to work with this one file if single = True - logger.debug("Found %s files in %s" % (str(len(filenames)), dirpath)) - for file in filenames: - filePath = os.path.join(dirpath, file) - fileName, fileExtension = os.path.splitext(file) - if inputCategory in nzbtomedia.NOFLATTEN and not single: - newDir = dirpath # find the full path - newDir = newDir.replace(inputDirectory, "") #find the extra-depth directory - if len(newDir) > 0 and newDir[0] == "/": - newDir = newDir[1:] # remove leading "/" to enable join to work. - outputDestination = os.path.join(outputDestinationMaster, newDir) # join this extra directory to output. + + inputFiles = listMediaFiles(inputDirectory) + logger.debug("Found %s files in %s" % (str(len(inputFiles)), inputDirectory)) + for inputFile in inputFiles: + fileDirPath = os.path.dirname(inputFile) + fileName, fileExt = os.path.splitext(os.path.basename(inputFile)) + fullFileName = os.path.basename(inputFile) + + if inputCategory in nzbtomedia.NOFLATTEN: + if not fileDirPath == outputDestinationMaster: + outputDestination = joinPath(outputDestinationMaster, fileDirPath) # join this extra directory to output. logger.debug("Setting outputDestination to %s to preserve folder structure" % (outputDestination)) - targetDirectory = os.path.join(outputDestination, file) + targetDirectory = joinPath(outputDestination, fullFileName) - if root == 1: - if foundFile == 0: - logger.debug("Looking for %s in: %s" % (inputName, file)) - if (sanitizeFileName(inputName) in sanitizeFileName(file)) or (sanitizeFileName(fileName) in sanitizeFileName(inputName)): - #pass # This file does match the Torrent name - foundFile = 1 - logger.debug("Found file %s that matches Torrent Name %s" % (file, inputName)) - else: - continue # This file does not match the Torrent name, skip it - - if root == 2: - if foundFile == 0: - logger.debug("Looking for files with modified/created dates less than 5 minutes old.") - mtime_lapse = now - datetime.datetime.fromtimestamp(os.path.getmtime(os.path.join(dirpath, file))) - ctime_lapse = now - datetime.datetime.fromtimestamp(os.path.getctime(os.path.join(dirpath, file))) - if (mtime_lapse < datetime.timedelta(minutes=5)) or (ctime_lapse < datetime.timedelta(minutes=5)): - #pass # This file does match the date time criteria - foundFile = 1 - logger.debug("Found file %s with date modifed/created less than 5 minutes ago." % (file)) - else: - continue # This file has not been recently moved or created, skip it - - if fileExtension in nzbtomedia.MEDIACONTAINER and is_sample(filePath, inputName, nzbtomedia.MINSAMPLESIZE, - nzbtomedia.SAMPLEIDS) and not nzbtomedia.CFG["HeadPhones"][inputCategory]: # Ignore samples - logger.info("Ignoring sample file: %s " % (filePath)) + if root == 1: + if not foundFile: + logger.debug("Looking for %s in: %s" % (inputName, fullFileName)) + if (sanitizeFileName(inputName) in sanitizeFileName(fullFileName)) or (sanitizeFileName(fileName) in sanitizeFileName(inputName)): + foundFile = True + logger.debug("Found file %s that matches Torrent Name %s" % (fullFileName, inputName)) + else: continue - if fileExtension in nzbtomedia.COMPRESSEDCONTAINER: - if not (nzbtomedia.CFG["SickBeard"][inputCategory] and nzbtomedia.CFG["SickBeard"][inputCategory]["nzbExtractionBy"] == "Destination"): - # find part numbers in second "extension" from right, if we have more than 1 compressed file in the same directory. - if re.search(r'\d+', os.path.splitext(fileName)[1]) and os.path.dirname(filePath) in extracted_folder and not any(item in os.path.splitext(fileName)[1] for item in ['.720p','.1080p','.x264']): - part = int(re.search(r'\d+', os.path.splitext(fileName)[1]).group()) - if part == 1: # we only want to extract the primary part. - logger.debug("Found primary part of a multi-part archive %s. Extracting" % (file)) - else: - logger.debug("Found part %s of a multi-part archive %s. Ignoring" % (part, file)) - continue - logger.info("Found compressed archive %s for file %s" % (fileExtension, filePath)) - try: - extractor.extract(filePath, outputDestination) - extractionSuccess = True # we use this variable to determine if we need to pause a torrent or not in uTorrent (don't need to pause archived content) - extracted_folder.append(os.path.dirname(filePath)) - except: - logger.error("Extraction failed for: %s" % (file)) - continue + if root == 2: + mtime_lapse = now - datetime.datetime.fromtimestamp(os.path.getmtime(inputFile)) + ctime_lapse = now - datetime.datetime.fromtimestamp(os.path.getctime(inputFile)) - try: - copy_link(filePath, targetDirectory, nzbtomedia.USELINK, outputDestination) - copy_list.append([filePath, os.path.join(outputDestination, file)]) - except: - logger.error("Failed to link file: %s" % (file)) + if not foundFile: + logger.debug("Looking for files with modified/created dates less than 5 minutes old.") + if (mtime_lapse < datetime.timedelta(minutes=5)) or (ctime_lapse < datetime.timedelta(minutes=5)): + #pass # This file does match the date time criteria + foundFile = True + logger.debug("Found file %s with date modifed/created less than 5 minutes ago." % (fullFileName)) + else: + continue # This file has not been recently moved or created, skip it + + if fileExt in nzbtomedia.COMPRESSEDCONTAINER: + if not (nzbtomedia.CFG["SickBeard"][inputCategory] and nzbtomedia.CFG["SickBeard"][inputCategory]["nzbExtractionBy"] == "Destination"): + # find part numbers in second "extension" from right, if we have more than 1 compressed file in the same directory. + if re.search(r'\d+', os.path.splitext(fileName)[1]) and fileDirPath in extracted_folder and not any(item in os.path.splitext(fileName)[1] for item in ['.720p','.1080p','.x264']): + part = int(re.search(r'\d+', os.path.splitext(fileName)[1]).group()) + if part == 1: # we only want to extract the primary part. + logger.debug("Found primary part of a multi-part archive %s. Extracting" % (fullFileName)) + else: + logger.debug("Found part %s of a multi-part archive %s. Ignoring" % (part, fullFileName)) + continue + logger.info("Found compressed archive %s for file %s" % (fileExt, inputFile)) + try: + extractor.extract(inputFile, outputDestination) + extractionSuccess = True # we use this variable to determine if we need to pause a torrent or not in uTorrent (don't need to pause archived content) + extracted_folder.append(fileDirPath) + except: + logger.error("Extraction failed for: %s" % (fullFileName)) + continue + + try: + copy_link(inputFile, targetDirectory, nzbtomedia.USELINK, outputDestination) + copy_list.append([inputFile, joinPath(outputDestination, fullFileName)]) + except: + logger.error("Failed to link file: %s" % (fullFileName)) outputDestination = outputDestinationMaster # Reset here. if not inputCategory in nzbtomedia.NOFLATTEN: #don't flatten hp in case multi cd albums, and we need to copy this back later. flatten(outputDestination) - if platform.system().lower() == 'windows': # remove Read Only flag from files in Windows. + if platform.system() == 'Windows': # remove Read Only flag from files in Windows. remove_read_only(outputDestination) # Now check if video files exist in destination: if nzbtomedia.CFG["SickBeard","NzbDrone", "CouchPotato"][inputCategory]: - for videofile in listMediaFiles(outputDestination): - logger.debug("Found media file: %s" % (videofile)) - video += 1 - for archivefile in listArchiveFiles(outputDestination): - logger.debug("Found archive file: %s" % (archivefile)) - archive += 1 + for outputFile in listMediaFiles(outputDestination): + fullFileName = os.path.basename(outputFile) + fileName, fileExt = os.path.splitext(fullFileName) + + if fileExt in nzbtomedia.MEDIACONTAINER: + logger.debug("Found media file: %s" % (fullFileName)) + video += 1 + if fileExt in nzbtomedia.COMPRESSEDCONTAINER: + logger.debug("Found archive file: %s" % (fullFileName)) + archive += 1 if video > 0: logger.debug("Found %s media files" % (str(video))) @@ -231,7 +225,7 @@ def external_script(outputDestination, torrentName, torrentLabel): for dirpath, dirnames, filenames in os.walk(outputDestination): for file in filenames: - filePath = os.path.join(dirpath, file) + filePath = joinPath(dirpath, file) fileName, fileExtension = os.path.splitext(file) if fileExtension in nzbtomedia.USER_SCRIPT_MEDIAEXTENSIONS or "ALL" in nzbtomedia.USER_SCRIPT_MEDIAEXTENSIONS: @@ -284,7 +278,7 @@ def external_script(outputDestination, torrentName, torrentLabel): num_files_new = 0 for dirpath, dirnames, filenames in os.walk(outputDestination): for file in filenames: - filePath = os.path.join(dirpath, file) + filePath = joinPath(dirpath, file) fileName, fileExtension = os.path.splitext(file) if fileExtension in nzbtomedia.USER_SCRIPT_MEDIAEXTENSIONS or nzbtomedia.USER_SCRIPT_MEDIAEXTENSIONS == "ALL": diff --git a/autoProcessMedia.cfg.spec b/autoProcessMedia.cfg.spec index 250f7f4a..3d56b39f 100644 --- a/autoProcessMedia.cfg.spec +++ b/autoProcessMedia.cfg.spec @@ -169,6 +169,7 @@ [Extensions] compressedExtensions = .zip,.rar,.7z,.gz,.bz,.tar,.arj,.1,.01,.001 mediaExtensions = .mkv,.avi,.divx,.xvid,.mov,.wmv,.mp4,.mpg,.mpeg,.vob,.iso,.m4v + audioExtensions = .mp3, .aac, .ogg, .ape, .m4a, .asf, .wma, .flac metaExtensions = .nfo,.sub,.srt,.jpg,.gif ###### minSampleSize - Minimum required size to consider a media file not a sample file (in MB, eg 200mb) minSampleSize = 200 diff --git a/nzbtomedia/__init__.py b/nzbtomedia/__init__.py index b286a55f..8f396728 100644 --- a/nzbtomedia/__init__.py +++ b/nzbtomedia/__init__.py @@ -21,7 +21,7 @@ sys.path.insert(0, os.path.abspath(os.path.join(PROGRAM_DIR, 'lib'))) from nzbtomedia import logger, versionCheck from nzbtomedia.nzbToMediaConfig import config -from nzbtomedia.nzbToMediaUtil import WakeUp, makeDir +from nzbtomedia.nzbToMediaUtil import WakeUp, makeDir, joinPath # sabnzbd constants SABNZB_NO_OF_ARGUMENTS = 8 @@ -86,6 +86,7 @@ DELUGEPWD = None COMPRESSEDCONTAINER = None MEDIACONTAINER = None +AUDIOCONTAINER = None METACONTAINER = None MINSAMPLESIZE = None SAMPLEIDS = None @@ -135,7 +136,7 @@ def initialize(section=None): TRANSCODE, GIT_PATH, GIT_USER, GIT_BRANCH, GIT_REPO, SYS_ENCODING, NZB_CLIENTAGENT, SABNZBDHOST, SABNZBDPORT, SABNZBDAPIKEY, \ DUPLICATE, IGNOREEXTENSIONS, OUTPUTVIDEOEXTENSION, OUTPUTVIDEOCODEC, OUTPUTVIDEOPRESET, OUTPUTVIDEOFRAMERATE, \ OUTPUTVIDEOBITRATE, OUTPUTAUDIOCODEC, OUTPUTAUDIOBITRATE, OUTPUTSUBTITLECODEC, OUTPUTFASTSTART, OUTPUTQUALITYPERCENT, \ - NICENESS, LOG_DEBUG, FORCE_CLEAN, FFMPEG_PATH, FFMPEG, FFPROBE + NICENESS, LOG_DEBUG, FORCE_CLEAN, FFMPEG_PATH, FFMPEG, FFPROBE, AUDIOCONTAINER if __INITIALIZED__: return False @@ -241,6 +242,7 @@ def initialize(section=None): COMPRESSEDCONTAINER = (CFG["Extensions"]["compressedExtensions"]) # .zip,.rar,.7z MEDIACONTAINER = (CFG["Extensions"]["mediaExtensions"]) # .mkv,.avi,.divx + AUDIOCONTAINER = (CFG["Extensions"]["audioExtensions"]) METACONTAINER = (CFG["Extensions"]["metaExtensions"]) # .nfo,.sub,.srt MINSAMPLESIZE = int(CFG["Extensions"]["minSampleSize"]) # 200 (in MB) SAMPLEIDS = (CFG["Extensions"]["SampleIDs"]) # sample,-s. @@ -262,8 +264,8 @@ def initialize(section=None): # Setup FFMPEG and FFPROBE locations if platform.system() == 'Windows': - FFMPEG = os.path.join(FFMPEG_PATH, 'ffmpeg.exe') - FFPROBE = os.path.join(FFMPEG_PATH, 'ffprobe.exe') + FFMPEG = joinPath(FFMPEG_PATH, 'ffmpeg.exe') + FFPROBE = joinPath(FFMPEG_PATH, 'ffprobe.exe') if not (os.path.isfile(FFMPEG) or os.path.isfile(FFMPEG)): # problem FFMPEG = None @@ -276,7 +278,7 @@ def initialize(section=None): if not (FFMPEG or FFPROBE): # Auto-install FFMPEG and FFPROBE - res = subprocess.call([os.path.join(PROGRAM_DIR, 'getffmpeg.sh')], stdout=bitbucket, stderr=bitbucket) + res = subprocess.call([joinPath(PROGRAM_DIR, 'getffmpeg.sh')], stdout=bitbucket, stderr=bitbucket) if res == 0: # did not install or ffmpeg still not found. FFMPEG = subprocess.call(['which', 'ffmpeg'], stdout=bitbucket, stderr=bitbucket) FFPROBE = subprocess.call(['which', 'ffprobe'], stdout=bitbucket, stderr=bitbucket) diff --git a/nzbtomedia/autoProcess/autoProcessComics.py b/nzbtomedia/autoProcess/autoProcessComics.py index 52685afa..ea479c6b 100644 --- a/nzbtomedia/autoProcess/autoProcessComics.py +++ b/nzbtomedia/autoProcess/autoProcessComics.py @@ -2,7 +2,7 @@ import os import time import nzbtomedia from lib import requests -from nzbtomedia.nzbToMediaUtil import convert_to_ascii +from nzbtomedia.nzbToMediaUtil import convert_to_ascii, joinPath from nzbtomedia import logger class autoProcessComics: @@ -39,7 +39,7 @@ class autoProcessComics: params = {} params['nzb_folder'] = dirName if remote_path: - dirName_new = os.path.join(remote_path, os.path.basename(dirName)).replace("\\", "/") + dirName_new = joinPath(remote_path, os.path.basename(dirName)).replace("\\", "/") params['nzb_folder'] = dirName_new if nzbName != None: diff --git a/nzbtomedia/autoProcess/autoProcessMovie.py b/nzbtomedia/autoProcess/autoProcessMovie.py index ef569e2d..f223c936 100644 --- a/nzbtomedia/autoProcess/autoProcessMovie.py +++ b/nzbtomedia/autoProcess/autoProcessMovie.py @@ -4,7 +4,7 @@ import nzbtomedia from lib import requests from nzbtomedia.Transcoder import Transcoder from nzbtomedia.nzbToMediaSceneExceptions import process_all_exceptions -from nzbtomedia.nzbToMediaUtil import convert_to_ascii, delete, find_imdbid, find_download +from nzbtomedia.nzbToMediaUtil import convert_to_ascii, delete, find_imdbid, find_download, joinPath from nzbtomedia import logger @@ -160,7 +160,7 @@ class autoProcessMovie: params['media_folder'] = dirName if remote_path: - dirName_new = os.path.join(remote_path, os.path.basename(dirName)).replace("\\", "/") + dirName_new = joinPath(remote_path, os.path.basename(dirName)).replace("\\", "/") params['media_folder'] = dirName_new url = "%s%s" % (baseURL, command) diff --git a/nzbtomedia/autoProcess/autoProcessMusic.py b/nzbtomedia/autoProcess/autoProcessMusic.py index a7dd21d8..59e4e925 100644 --- a/nzbtomedia/autoProcess/autoProcessMusic.py +++ b/nzbtomedia/autoProcess/autoProcessMusic.py @@ -2,7 +2,7 @@ import os import time import nzbtomedia from lib import requests -from nzbtomedia.nzbToMediaUtil import convert_to_ascii +from nzbtomedia.nzbToMediaUtil import convert_to_ascii, joinPath from nzbtomedia import logger class autoProcessMusic: @@ -76,7 +76,7 @@ class autoProcessMusic: params['dir'] = os.path.dirname(dirName) if remote_path: - dirName_new = os.path.join(remote_path, os.path.basename(os.path.dirname(dirName))).replace("\\", "/") + dirName_new = joinPath(remote_path, os.path.basename(os.path.dirname(dirName))).replace("\\", "/") params['dir'] = dirName_new diff --git a/nzbtomedia/autoProcess/autoProcessTV.py b/nzbtomedia/autoProcess/autoProcessTV.py index 6c902cb7..4e5d8f95 100644 --- a/nzbtomedia/autoProcess/autoProcessTV.py +++ b/nzbtomedia/autoProcess/autoProcessTV.py @@ -5,7 +5,7 @@ from lib import requests from nzbtomedia.Transcoder import Transcoder from nzbtomedia.nzbToMediaAutoFork import autoFork from nzbtomedia.nzbToMediaSceneExceptions import process_all_exceptions -from nzbtomedia.nzbToMediaUtil import convert_to_ascii, is_sample, flatten, delete +from nzbtomedia.nzbToMediaUtil import convert_to_ascii, is_sample, flatten, delete, joinPath from nzbtomedia import logger class autoProcessTV: @@ -63,7 +63,7 @@ class autoProcessTV: if not os.path.isdir(dirName) and os.path.isfile(dirName): # If the input directory is a file, assume single file download and split dir/name. dirName = os.path.split(os.path.normpath(dirName))[0] - SpecificPath = os.path.join(dirName, str(nzbName)) + SpecificPath = joinPath(dirName, str(nzbName)) cleanName = os.path.splitext(SpecificPath) if cleanName[1] == ".nzb": SpecificPath = cleanName[0] @@ -79,7 +79,7 @@ class autoProcessTV: video = int(0) for dirpath, dirnames, filenames in os.walk(dirName): for file in filenames: - filePath = os.path.join(dirpath, file) + filePath = joinPath(dirpath, file) fileExtension = os.path.splitext(file)[1] if fileExtension in nzbtomedia.MEDIACONTAINER: # If the file is a video file if is_sample(filePath, nzbName, nzbtomedia.MINSAMPLESIZE, nzbtomedia.SAMPLEIDS): @@ -109,7 +109,7 @@ class autoProcessTV: if param in ["dirName", "dir"]: fork_params[param] = dirName if remote_path: - dirName_new = os.path.join(remote_path, os.path.basename(dirName)).replace("\\", "/") + dirName_new = joinPath(remote_path, os.path.basename(dirName)).replace("\\", "/") fork_params[param] = dirName_new if param == "process_method": diff --git a/nzbtomedia/extractor/extractor.py b/nzbtomedia/extractor/extractor.py index 767bf786..4c7d5ae4 100644 --- a/nzbtomedia/extractor/extractor.py +++ b/nzbtomedia/extractor/extractor.py @@ -2,7 +2,7 @@ import os import sys import nzbtomedia from subprocess import call, Popen -from nzbtomedia.nzbToMediaUtil import makeDir +from nzbtomedia.nzbToMediaUtil import makeDir, joinPath from nzbtomedia import logger # which() and os_platform() breaks when running in Transmission (has to do with os.environ) @@ -26,14 +26,14 @@ def extract(filePath, outputDestination): else: platform = 'x86' if not os.path.dirname(sys.argv[0]): - chplocation = os.path.normpath(os.path.join(os.getcwd(), 'nzbtomedia/extractor/bin/chp.exe')) + chplocation = os.path.normpath(joinPath(os.getcwd(), 'nzbtomedia/extractor/bin/chp.exe')) sevenzipLocation = os.path.normpath( - os.path.join(os.getcwd(), 'nzbtomedia/extractor/bin/' + platform + '/7z.exe')) + joinPath(os.getcwd(), 'nzbtomedia/extractor/bin/' + platform + '/7z.exe')) else: chplocation = os.path.normpath( - os.path.join(os.path.dirname(sys.argv[0]), 'nzbtomedia/extractor/bin/chp.exe')) + joinPath(os.path.dirname(sys.argv[0]), 'nzbtomedia/extractor/bin/chp.exe')) sevenzipLocation = os.path.normpath( - os.path.join(os.path.dirname(sys.argv[0]), 'nzbtomedia/extractor/bin/' + platform + '/7z.exe')) + joinPath(os.path.dirname(sys.argv[0]), 'nzbtomedia/extractor/bin/' + platform + '/7z.exe')) if not os.path.exists(sevenzipLocation): logger.error("EXTRACTOR: Could not find 7-zip, Exiting") return False diff --git a/nzbtomedia/nzbToMediaSceneExceptions.py b/nzbtomedia/nzbToMediaSceneExceptions.py index b9900dae..01f74f95 100644 --- a/nzbtomedia/nzbToMediaSceneExceptions.py +++ b/nzbtomedia/nzbToMediaSceneExceptions.py @@ -1,6 +1,6 @@ import os import logging -from nzbtomedia.nzbToMediaUtil import listMediaFiles +from nzbtomedia.nzbToMediaUtil import listMediaFiles, joinPath Logger = logging.getLogger() @@ -20,7 +20,7 @@ def process_qoq(filename, dirname): head, fileExtension = os.path.splitext(os.path.basename(filename)) newname = head[::-1] newfile = newname + fileExtension - newfilePath = os.path.join(dirname, newfile) + newfilePath = joinPath(dirname, newfile) os.rename(filename, newfilePath) logging.debug("New file name is %s", newfile) diff --git a/nzbtomedia/nzbToMediaUtil.py b/nzbtomedia/nzbToMediaUtil.py index 1199687a..3e87d11d 100644 --- a/nzbtomedia/nzbToMediaUtil.py +++ b/nzbtomedia/nzbToMediaUtil.py @@ -45,6 +45,8 @@ def makeDir(path): return False return True +def joinPath(path, *paths): + return os.path.join(path, *paths).replace('\\','/') def category_search(inputDirectory, inputName, inputCategory, root, categories): single = False @@ -67,20 +69,20 @@ def category_search(inputDirectory, inputName, inputCategory, root, categories): if not inputName: inputName = os.path.split(os.path.normpath(inputDirectory))[1] return inputDirectory, inputName, inputCategory, root, single - if inputCategory and os.path.isdir(os.path.join(inputDirectory, inputCategory).replace("\\","/")): + if inputCategory and os.path.isdir(joinPath(inputDirectory, inputCategory)): logger.info( "SEARCH: Found category directory %s in input directory directory %s" % (inputCategory, inputDirectory)) - inputDirectory = os.path.join(inputDirectory, inputCategory).replace("\\","/") + inputDirectory = joinPath(inputDirectory, inputCategory) logger.info("SEARCH: Setting inputDirectory to %s" % (inputDirectory)) - if inputName and os.path.isdir(os.path.join(inputDirectory, inputName).replace("\\","/")): + if inputName and os.path.isdir(joinPath(inputDirectory, inputName)): logger.info("SEARCH: Found torrent directory %s in input directory directory %s" % (inputName, inputDirectory)) - inputDirectory = os.path.join(inputDirectory, inputName).replace("\\","/") + inputDirectory = joinPath(inputDirectory, inputName) logger.info("SEARCH: Setting inputDirectory to %s" % (inputDirectory)) tordir = True - if inputName and os.path.isdir(os.path.join(inputDirectory, sanitizeFileName(inputName)).replace("\\","/")): + if inputName and os.path.isdir(joinPath(inputDirectory, sanitizeFileName(inputName))): logger.info("SEARCH: Found torrent directory %s in input directory directory %s" % ( sanitizeFileName(inputName), inputDirectory)) - inputDirectory = os.path.join(inputDirectory, sanitizeFileName(inputName).replace("\\","/")) + inputDirectory = joinPath(inputDirectory, sanitizeFileName(inputName)) logger.info("SEARCH: Setting inputDirectory to %s" % (inputDirectory)) tordir = True @@ -115,53 +117,50 @@ def category_search(inputDirectory, inputName, inputCategory, root, categories): return inputDirectory, inputName, inputCategory, root, single -def is_sample(filePath, inputName, minSampleSize, SampleIDs): +def is_sample(inputName, minSampleSize, SampleIDs): # 200 MB in bytes SIZE_CUTOFF = minSampleSize * 1024 * 1024 - if os.path.getsize(filePath) < SIZE_CUTOFF: + if os.path.getsize(inputName) < SIZE_CUTOFF: if 'SizeOnly' in SampleIDs: return True - # Ignore 'sample' in files unless 'sample' in Torrent Name + # Ignore 'sample' in files for ident in SampleIDs: - if ident.lower() in filePath.lower() and not ident.lower() in inputName.lower(): + if re.search(ident,inputName,flags=re.I): return True # Return False if none of these were met. return False - def copy_link(filePath, targetDirectory, useLink, outputDestination): if os.path.isfile(targetDirectory): - logger.info("COPYLINK: target file already exists. Nothing to be done") + logger.info("Target file already exists. Nothing to be done", 'COPYLINK') return True makeDir(outputDestination) if useLink == "hard": try: - logger.info("COPYLINK: Hard linking %s to %s" % (filePath, targetDirectory)) + logger.info("Hard linking %s to %s" % (filePath, targetDirectory), 'COPYLINK') linktastic.link(filePath, targetDirectory) except: - logger.error("COPYLINK") if os.path.isfile(targetDirectory): logger.warning( - "COPYLINK: Something went wrong in linktastic.link, but the destination file was created") + "Something went wrong in linktastic.link, but the destination file was created", 'COPYLINK') else: - logger.warning("COPYLINK: Something went wrong in linktastic.link, copying instead") - logger.debug("COPYLINK: Copying %s to %s" % (filePath, targetDirectory)) + logger.warning("Something went wrong in linktastic.link, copying instead", 'COPYLINK') + logger.debug("Copying %s to %s" % (filePath, targetDirectory), 'COPYLINK') shutil.copy(filePath, targetDirectory) elif useLink == "sym": try: - logger.info("COPYLINK: Moving %s to %s before sym linking" % (filePath, targetDirectory)) + logger.info("Moving %s to %s before sym linking" % (filePath, targetDirectory), 'COPYLINK') shutil.move(filePath, targetDirectory) - logger.info("COPYLINK: Sym linking %s to %s" % (targetDirectory, filePath)) + logger.info("Sym linking %s to %s" % (targetDirectory, filePath), 'COPYLINK') linktastic.symlink(targetDirectory, filePath) except: - logger.error("COPYLINK") if os.path.isfile(targetDirectory): logger.warning( - "COPYLINK: Something went wrong in linktastic.link, but the destination file was created") + "Something went wrong in linktastic.link, but the destination file was created", 'COPYLINK') else: - logger.info("COPYLINK: Something went wrong in linktastic.link, copying instead") - logger.debug("COPYLINK: Copying %s to %s" % (filePath, targetDirectory)) + logger.info("Something went wrong in linktastic.link, copying instead", 'COPYLINK') + logger.debug("Copying %s to %s" % (filePath, targetDirectory), 'COPYLINK') shutil.copy(filePath, targetDirectory) elif useLink == "move": logger.debug("Moving %s to %s" % (filePath, targetDirectory)) @@ -174,22 +173,24 @@ def copy_link(filePath, targetDirectory, useLink, outputDestination): def flatten(outputDestination): logger.info("FLATTEN: Flattening directory: %s" % (outputDestination)) - for dirpath, dirnames, filenames in os.walk( - outputDestination): # Flatten out the directory to make postprocessing easier - if dirpath == outputDestination: - continue # No need to try and move files in the root destination directory - for filename in filenames: - source = os.path.join(dirpath, filename).replace("\\","/") - target = os.path.join(outputDestination, filename).replace("\\","/") - try: - shutil.move(source, target) - except: - logger.error("FLATTEN: Could not flatten %s" % (source)) + for outputFile in listMediaFiles(outputDestination): + dirPath = os.path.dirname(outputFile) + fileName = os.path.basename(outputFile) + + if dirPath == outputDestination: + continue + + target = joinPath(outputDestination, fileName) + + try: + shutil.move(outputFile, target) + except: + logger.error("Could not flatten %s" % (outputFile), 'FLATTEN') + removeEmptyFolders(outputDestination) # Cleanup empty directories - def removeEmptyFolders(path): - logger.info("REMOVER: Removing empty folders in: %s" % (path)) + logger.info("Removing empty folders in: %s" % (path), 'REMOVER') if not os.path.isdir(path): return @@ -197,14 +198,14 @@ def removeEmptyFolders(path): files = os.listdir(path) if len(files): for f in files: - fullpath = os.path.join(path, f).replace("\\","/") + fullpath = joinPath(path, f) if os.path.isdir(fullpath): removeEmptyFolders(fullpath) # If folder empty, delete it files = os.listdir(path) if len(files) == 0: - logger.debug("REMOVER: Removing empty folder: %s" % (path)) + logger.debug("Removing empty folder: %s" % (path), 'REMOVER') os.rmdir(path) @@ -214,7 +215,7 @@ def remove_read_only(path): for dirpath, dirnames, filenames in os.walk(path): for filename in filenames: logger.debug("Removing Read Only Flag for: %s" % (filename)) - os.chmod(os.path.join(dirpath, filename).replace("\\","/"), stat.S_IWRITE) + os.chmod(joinPath(dirpath, filename), stat.S_IWRITE) #Wake function @@ -389,7 +390,7 @@ def get_dirnames(section, subsections=None): watch_dir = None try: - outputDirectory = os.path.join(nzbtomedia.OUTPUTDIRECTORY, subsection).replace("\\","/") + outputDirectory = joinPath(nzbtomedia.OUTPUTDIRECTORY, subsection) if not os.path.exists(outputDirectory): outputDirectory = None except: @@ -400,26 +401,26 @@ def get_dirnames(section, subsections=None): for mediafile in listMediaFiles(watch_dir): parentDir = os.path.dirname(mediafile) if parentDir == watch_dir: - p = os.path.join(parentDir, (os.path.splitext(os.path.splitext(mediafile)[0])[0])).replace("\\","/") + p = joinPath(parentDir, (os.path.splitext(os.path.splitext(mediafile)[0])[0])) if not os.path.exists(p): os.mkdir(p) shutil.move(mediafile, p) - dirNames.extend([os.path.join(watch_dir, o).replace("\\","/") for o in os.listdir(watch_dir) if - os.path.isdir(os.path.join(watch_dir, o).replace("\\","/"))]) + dirNames.extend([joinPath(watch_dir, o) for o in os.listdir(watch_dir) if + os.path.isdir(joinPath(watch_dir, o))]) if outputDirectory: # search for single files and move them into there own folder for post-processing for mediafile in listMediaFiles(outputDirectory): parentDir = os.path.dirname(mediafile) if parentDir == outputDirectory: - p = os.path.join(parentDir, (os.path.splitext(os.path.splitext(mediafile)[0])[0]).replace("\\","/")) + p = joinPath(parentDir, (os.path.splitext(os.path.splitext(mediafile)[0])[0])) if not os.path.exists(p): os.mkdir(p) shutil.move(mediafile, p) - dirNames.extend([os.path.join(outputDirectory, o).replace("\\","/") for o in os.listdir(outputDirectory) if - os.path.isdir(os.path.join(outputDirectory, o).replace("\\","/"))]) + dirNames.extend([joinPath(outputDirectory, o) for o in os.listdir(outputDirectory) if + os.path.isdir(joinPath(outputDirectory, o))]) if not dirNames: logger.warning("%s:%s has no directories identified for post-processing" % (section, subsection)) @@ -441,7 +442,7 @@ def cleanup_directories(inputCategory, processCategories, result, directory): file_list = [] for dirpath, dirnames, filenames in os.walk(directory): for file in filenames: - filePath = os.path.join(dirpath, file).replace("\\","/") + filePath = joinPath(dirpath, file) fileName, fileExtension = os.path.splitext(file) if fileExtension in nzbtomedia.MEDIACONTAINER or fileExtension in nzbtomedia.METACONTAINER: num_files_new += 1 @@ -580,43 +581,7 @@ def clean_nzbname(nzbname): nzbname = re.sub("^\[.*\]", "", nzbname) return nzbname.strip() - -def isArchiveFile(filename): - # ignore samples - - # ignore MAC OS's retarded "resource fork" files - if filename.startswith('._'): - return False - - sepFile = filename.rpartition(".") - - if sepFile[2].lower() in [i.replace(".","") for i in nzbtomedia.COMPRESSEDCONTAINER]: - return True - else: - return False - -def listArchiveFiles(path): - if not dir or not os.path.isdir(path): - return [] - - files = [] - for curFile in os.listdir(path): - fullCurFile = os.path.join(path, curFile).replace("\\","/") - - # if it's a folder do it recursively - if os.path.isdir(fullCurFile) and not curFile.startswith('.'): - files += listMediaFiles(fullCurFile) - - elif isMediaFile(curFile): - files.append(fullCurFile) - - return files - def isMediaFile(filename): - # ignore samples - if re.search('(^|[\W_])(sample\d*)[\W_]', filename, re.I): - return False - # ignore MAC OS's retarded "resource fork" files if filename.startswith('._'): return False @@ -624,26 +589,32 @@ def isMediaFile(filename): sepFile = filename.rpartition(".") if re.search('extras?$', sepFile[0], re.I): + logger.info("Ignoring extras file: %s " % (filename)) return False - if sepFile[2].lower() in [i.replace(".","") for i in nzbtomedia.MEDIACONTAINER]: + if sepFile[2].lower() in [i.replace(".","") for i in + (nzbtomedia.MEDIACONTAINER + nzbtomedia.AUDIOCONTAINER + nzbtomedia.COMPRESSEDCONTAINER)]: return True else: return False -def listMediaFiles(path): +def listMediaFiles(path, ignoreSample=True): if not dir or not os.path.isdir(path): return [] files = [] for curFile in os.listdir(path): - fullCurFile = os.path.join(path, curFile).replace("\\","/") + fullCurFile = joinPath(path, curFile) # if it's a folder do it recursively if os.path.isdir(fullCurFile) and not curFile.startswith('.') and not curFile == 'Extras': files += listMediaFiles(fullCurFile) elif isMediaFile(curFile): + # Optionally ignore sample files + if ignoreSample and is_sample(fullCurFile, nzbtomedia.MINSAMPLESIZE, nzbtomedia.SAMPLEIDS): + continue + files.append(fullCurFile) return files diff --git a/nzbtomedia/versionCheck.py b/nzbtomedia/versionCheck.py index 7a647e23..13a6b86d 100644 --- a/nzbtomedia/versionCheck.py +++ b/nzbtomedia/versionCheck.py @@ -14,6 +14,8 @@ import gh_api as github import nzbtomedia from nzbtomedia import logger +from nzbtomedia.nzbToMediaUtil import joinPath + class CheckVersion(): """ @@ -46,7 +48,7 @@ class CheckVersion(): """ # check if we're a windows build - if os.path.isdir(os.path.join(nzbtomedia.PROGRAM_DIR, u'.git')): + if os.path.isdir(joinPath(nzbtomedia.PROGRAM_DIR, u'.git')): install_type = 'git' else: install_type = 'source' @@ -335,7 +337,7 @@ class SourceUpdateManager(UpdateManager): def _find_installed_version(self): - version_file = os.path.join(nzbtomedia.PROGRAM_DIR, u'version.txt') + version_file = joinPath(nzbtomedia.PROGRAM_DIR, u'version.txt') if not os.path.isfile(version_file): self._cur_commit_hash = None @@ -431,11 +433,11 @@ class SourceUpdateManager(UpdateManager): """ base_url = 'https://github.com/' + self.github_repo_user + '/' + self.github_repo tar_download_url = base_url + '/tarball/' + self.branch - version_path = os.path.join(nzbtomedia.PROGRAM_DIR, u'version.txt') + version_path = joinPath(nzbtomedia.PROGRAM_DIR, u'version.txt') try: # prepare the update dir - sb_update_dir = os.path.join(nzbtomedia.PROGRAM_DIR, u'sb-update') + sb_update_dir = joinPath(nzbtomedia.PROGRAM_DIR, u'sb-update') if os.path.isdir(sb_update_dir): logger.log(u"Clearing out update folder " + sb_update_dir + " before extracting") @@ -446,7 +448,7 @@ class SourceUpdateManager(UpdateManager): # retrieve file logger.log(u"Downloading update from " + repr(tar_download_url)) - tar_download_path = os.path.join(sb_update_dir, u'nzbtomedia-update.tar') + tar_download_path = joinPath(sb_update_dir, u'nzbtomedia-update.tar') urllib.urlretrieve(tar_download_url, tar_download_path) if not os.path.isfile(tar_download_path): @@ -469,19 +471,19 @@ class SourceUpdateManager(UpdateManager): # find update dir name update_dir_contents = [x for x in os.listdir(sb_update_dir) if - os.path.isdir(os.path.join(sb_update_dir, x))] + os.path.isdir(joinPath(sb_update_dir, x))] if len(update_dir_contents) != 1: logger.log(u"Invalid update data, update failed: " + str(update_dir_contents), logger.ERROR) return False - content_dir = os.path.join(sb_update_dir, update_dir_contents[0]) + content_dir = joinPath(sb_update_dir, update_dir_contents[0]) # walk temp folder and move files to main folder logger.log(u"Moving files from " + content_dir + " to " + nzbtomedia.PROGRAM_DIR) for dirname, dirnames, filenames in os.walk(content_dir): # @UnusedVariable dirname = dirname[len(content_dir) + 1:] for curfile in filenames: - old_path = os.path.join(content_dir, dirname, curfile) - new_path = os.path.join(nzbtomedia.PROGRAM_DIR, dirname, curfile) + old_path = joinPath(content_dir, dirname, curfile) + new_path = joinPath(nzbtomedia.PROGRAM_DIR, dirname, curfile) #Avoid DLL access problem on WIN32/64 #These files needing to be updated manually diff --git a/tests/general.py b/tests/general.py index cd4e1f33..4126436b 100644 --- a/tests/general.py +++ b/tests/general.py @@ -1,20 +1,130 @@ +import datetime import os -import sys -import TorrentToMedia +import re import nzbtomedia -from nzbtomedia.Transcoder import Transcoder -from nzbtomedia.nzbToMediaUtil import listMediaFiles +import platform +from nzbtomedia.extractor import extractor +from nzbtomedia.nzbToMediaUtil import listMediaFiles, sanitizeFileName, \ + category_search, copy_link, flatten, remove_read_only, joinPath +from nzbtomedia import logger -os.environ['TR_TORRENT_DIR']="z:/downloads/complete/movie/The.Lego.Movie.2014.R5.x264.English.XviD-vTg.nfo_0166_-_The.Lego.Movie.2014.R5.x264.English.XviD-vTg.nfo_yEn.cp(tt1490017)" -os.environ['TR_TORRENT_NAME']="The.Lego.Movie.2014.R5.x264.English.XviD-vTg.nfo_0166_-_The.Lego.Movie.2014.R5.x264.English.XviD-vTg.nfo_yEn.cp(tt1490017)" -os.environ['TR_TORRENT_ID']="7855bb5c20189a73ea45aaf80c2541dfcf897f9d" -os.environ['TR_TORRENT_HASH']="7855bb5c20189a73ea45aaf80c2541dfcf897f9d" +status = int(1) # 1 = failed | 0 = success +root = 0 +video = 0 +archive = 0 +foundFile = 0 +extracted_folder = [] +copy_list = [] # Initialize the config nzbtomedia.initialize() -for video in listMediaFiles('Y:\Movies\Jobs (2013)'): - if nzbtomedia.TRANSCODE and Transcoder().isVideoGood(video): - print 'Good' +inputDirectory = "Z:\complete\movie\The.Lego.Movie.2014.R5.x264.English.XviD-vTg.nfo_0166_-_The.Lego.Movie.2014.R5.x264.English.XviD-vTg.nfo_yEn.cp(tt1490017)" +inputName = "The.Lego.Movie.2014.R5.x264.English.XviD-vTg.nfo_0166_-_The.Lego.Movie.2014.R5.x264.English.XviD-vTg.nfo_yEn.cp(tt1490017)" +inputCategory = 'movie' + +inputDirectory, inputName, inputCategory, root, single = category_search(inputDirectory, inputName, inputCategory, root, nzbtomedia.CATEGORIES) # Confirm the category by parsing directory structure +outputDestination = os.path.normpath(joinPath(nzbtomedia.OUTPUTDIRECTORY, inputCategory, sanitizeFileName(inputName))) + +logger.info("Scanning files in directory: %s" % (inputDirectory)) + +if nzbtomedia.CFG["HeadPhones"][inputCategory]: + nzbtomedia.NOFLATTEN.extend( + nzbtomedia.CFG["HeadPhones"].sections) # Make sure we preserve folder structure for HeadPhones. + +outputDestinationMaster = outputDestination # Save the original, so we can change this within the loop below, and reset afterwards. +now = datetime.datetime.now() + +inputFiles = listMediaFiles(inputDirectory) +logger.info("Found %s files in %s" % (str(len(inputFiles)), inputDirectory)) +for inputFile in inputFiles: + fileDirPath = os.path.dirname(inputFile) + fileName, fileExt = os.path.splitext(os.path.basename(inputFile)) + fullFileName = os.path.basename(inputFile) + + if inputCategory in nzbtomedia.NOFLATTEN: + if not fileDirPath == outputDestinationMaster: + outputDestination = joinPath(outputDestinationMaster, + fileDirPath) # join this extra directory to output. + logger.info("Setting outputDestination to %s to preserve folder structure" % (outputDestination)) + + targetDirectory = joinPath(outputDestination, fullFileName) + + if root == 1: + if not foundFile: + logger.info("Looking for %s in: %s" % (inputName, fullFileName)) + if (sanitizeFileName(inputName) in sanitizeFileName(fullFileName)) or ( + sanitizeFileName(fileName) in sanitizeFileName(inputName)): + foundFile = True + logger.info("Found file %s that matches Torrent Name %s" % (fullFileName, inputName)) + else: + continue + + if root == 2: + mtime_lapse = now - datetime.datetime.fromtimestamp(os.path.getmtime(inputFile)) + ctime_lapse = now - datetime.datetime.fromtimestamp(os.path.getctime(inputFile)) + + if not foundFile: + logger.info("Looking for files with modified/created dates less than 5 minutes old.") + if (mtime_lapse < datetime.timedelta(minutes=5)) or (ctime_lapse < datetime.timedelta(minutes=5)): + #pass # This file does match the date time criteria + foundFile = True + logger.info("Found file %s with date modifed/created less than 5 minutes ago." % (fullFileName)) + else: + continue # This file has not been recently moved or created, skip it + + if fileExt in nzbtomedia.COMPRESSEDCONTAINER: + if not (nzbtomedia.CFG["SickBeard"][inputCategory] and nzbtomedia.CFG["SickBeard"][inputCategory][ + "nzbExtractionBy"] == "Destination"): + # find part numbers in second "extension" from right, if we have more than 1 compressed file in the same directory. + if re.search(r'\d+', os.path.splitext(fileName)[1]) and fileDirPath in extracted_folder and not any( + item in os.path.splitext(fileName)[1] for item in ['.720p', '.1080p', '.x264']): + part = int(re.search(r'\d+', os.path.splitext(fileName)[1]).group()) + if part == 1: # we only want to extract the primary part. + logger.info("Found primary part of a multi-part archive %s. Extracting" % (fullFileName)) + else: + logger.info("Found part %s of a multi-part archive %s. Ignoring" % (part, fullFileName)) + continue + logger.info("Found compressed archive %s for file %s" % (fileExt, inputFile)) + try: + extractor.extract(inputFile, outputDestination) + extractionSuccess = True # we use this variable to determine if we need to pause a torrent or not in uTorrent (don't need to pause archived content) + extracted_folder.append(fileDirPath) + except: + logger.error("Extraction failed for: %s" % (fullFileName)) + continue + + try: + copy_link(inputFile, targetDirectory, nzbtomedia.USELINK, outputDestination) + copy_list.append([inputFile, joinPath(outputDestination, fullFileName)]) + except: + logger.error("Failed to link file: %s" % (fullFileName)) + +outputDestination = outputDestinationMaster # Reset here. +if not inputCategory in nzbtomedia.NOFLATTEN: #don't flatten hp in case multi cd albums, and we need to copy this back later. + flatten(outputDestination) + +if platform.system() == 'Windows': # remove Read Only flag from files in Windows. + remove_read_only(outputDestination) + +# Now check if video files exist in destination: +if nzbtomedia.CFG["SickBeard", "NzbDrone", "CouchPotato"][inputCategory]: + for outputFile in listMediaFiles(outputDestination): + fullFileName = os.path.basename(outputFile) + fileName, fileExt = os.path.splitext(fullFileName) + + if fileExt in nzbtomedia.MEDIACONTAINER: + logger.info("Found media file: %s" % (fullFileName)) + video += 1 + if fileExt in nzbtomedia.COMPRESSEDCONTAINER: + logger.info("Found archive file: %s" % (fullFileName)) + archive += 1 + + if video > 0: + logger.info("Found %s media files" % (str(video))) + status = 0 + elif archive > 0 and not nzbtomedia.CFG["SickBeard"][inputCategory]["nzbExtractionBy"] == "Destination": + logger.info("Found %s archive files to be extracted by SickBeard" % (str(archive))) + status = 0 else: - print 'Bad' + logger.warning("Found no media files in %s" % outputDestination)