def _process_media(self, process_path, video_files, nzb_name, process_method, force, force_replace, use_trash=False): processor = None for cur_video_file in video_files: if self._already_postprocessed(process_path, cur_video_file, force): self._set_process_success(False) continue cur_video_file_path = ek.ek(os.path.join, process_path, cur_video_file) try: processor = postProcessor.PostProcessor(cur_video_file_path, nzb_name, process_method, force_replace, use_trash=use_trash) file_success = processor.process() process_fail_message = '' except exceptions.PostProcessingFailed as e: file_success = False process_fail_message = '<br />.. ' + ex(e) self._set_process_success(file_success) if processor: self._buffer(processor.log.strip('\n')) if file_success: self._log_helper(u'Successfully processed ' + cur_video_file, logger.MESSAGE) elif self.any_vid_processed: self._log_helper(u'Warning fail for %s%s' % (cur_video_file_path, process_fail_message), logger.WARNING) else: self._log_helper(u'Did not use file %s%s' % (cur_video_file_path, process_fail_message), logger.WARNING)
def process_media(processPath, videoFiles, nzbName, process_method, force, is_priority, result): processor = None for cur_video_file in videoFiles: cur_video_file_path = ek.ek(os.path.join, processPath, cur_video_file) if already_postprocessed(processPath, cur_video_file, force, result): result.output += logHelper(u"Already Processed " + cur_video_file_path + " : Skipping", logger.DEBUG) continue try: processor = postProcessor.PostProcessor(cur_video_file_path, nzbName, process_method, is_priority) result.result = processor.process() process_fail_message = "" except exceptions.PostProcessingFailed, e: result.result = False process_fail_message = ex(e) if processor: result.output += processor.log if result.result: result.output += logHelper(u"Processing succeeded for " + cur_video_file_path) else: result.output += logHelper(u"Processing failed for " + cur_video_file_path + ": " + process_fail_message, logger.WARNING) result.missedfiles.append(cur_video_file_path + " : Processing failed: " + process_fail_message) result.aggresult = False
def process_media(processPath, videoFiles, nzbName, process_method, force, is_priority, result): processor = None for cur_video_file in videoFiles: if already_postprocessed(processPath, cur_video_file, force, result): continue cur_video_file_path = ek.ek(os.path.join, processPath, cur_video_file) try: processor = postProcessor.PostProcessor(cur_video_file_path, nzbName, process_method, is_priority) result.result = processor.process() process_fail_message = "" except exceptions.PostProcessingFailed, e: result.result = False process_fail_message = ex(e) if processor: result.output += processor.log if result.result: result.output += logHelper(u"Processing succeeded for " + cur_video_file_path) else: result.output += logHelper( u"Processing failed for " + cur_video_file_path + ": " + process_fail_message, logger.WARNING) #If something fail abort the processing on dir if not result.result: break
def processDir(dirName, nzbName=None, recurse=False, failed=False): """ Scans through the files in dirName and processes whatever media files it finds dirName: The folder name to look in nzbName: The NZB name which resulted in this folder being downloaded recurse: Boolean for whether we should descend into subfolders or not failed: Boolean for whether or not the download failed """ returnStr = '' returnStr += logHelper(u"Processing folder " + dirName, logger.DEBUG) # if they passed us a real dir then assume it's the one we want if ek.ek(os.path.isdir, dirName): dirName = ek.ek(os.path.realpath, dirName) # if they've got a download dir configured then use it elif sickbeard.TV_DOWNLOAD_DIR and ek.ek(os.path.isdir, sickbeard.TV_DOWNLOAD_DIR) \ and ek.ek(os.path.normpath, dirName) != ek.ek(os.path.normpath, sickbeard.TV_DOWNLOAD_DIR): dirName = ek.ek(os.path.join, sickbeard.TV_DOWNLOAD_DIR, ek.ek(os.path.abspath, dirName).split(os.path.sep)[-1]) returnStr += logHelper(u"Trying to use folder " + dirName, logger.DEBUG) # if we didn't find a real dir then quit if not ek.ek(os.path.isdir, dirName): returnStr += logHelper( u"Unable to figure out what folder to process. If your downloader and Sick Beard aren't on the same PC make sure you fill out your TV download dir in the config.", logger.DEBUG) return returnStr if failed: returnStr += logHelper(u"Failed download detected: (" + str(nzbName) + ", " + dirName + ")") try: processor = postProcessor.PostProcessor(dirName, nzbName, failed=failed) process_result = processor.process() process_fail_message = "" except exceptions.PostProcessingFailed, e: process_result = False process_fail_message = ex(e) returnStr += processor.log if sickbeard.DELETE_FAILED and process_result: returnStr += logHelper( u"Deleting folder of failed download " + dirName, logger.DEBUG) try: shutil.rmtree(dirName) except (OSError, IOError), e: returnStr += logHelper( u"Warning: Unable to remove the failed folder " + dirName + ": " + ex(e), logger.WARNING)
def process_media(process_path, video_files, release_name, process_method, force, is_priority, result): # pylint: disable=too-many-arguments """ Postprocess mediafiles :param process_path: Path to process in :param video_files: Filenames to look for and postprocess :param release_name: Name of NZB/Torrent file related :param process_method: auto/manual :param force: Postprocess currently postprocessing file :param is_priority: Boolean, is this a priority download :param result: Previous results """ processor = None for cur_video_file in video_files: cur_video_file_path = ek(os.path.join, process_path, cur_video_file) if already_processed(process_path, cur_video_file, force, result): result.output += log_helper( u"Skipping already processed file: {0}".format(cur_video_file), logger.DEBUG) continue try: processor = postProcessor.PostProcessor(cur_video_file_path, release_name, process_method, is_priority) result.result = processor.process() process_fail_message = u"" except EpisodePostProcessingFailedException as e: result.result = False process_fail_message = ex(e) if processor: result.output += processor.log if result.result: result.output += log_helper( u"Processing succeeded for {0}".format(cur_video_file_path)) else: result.output += log_helper( u"Processing failed for {0}: {1}".format( cur_video_file_path, process_fail_message), logger.WARNING) result.missed_files.append(u"{0} : Processing failed: {1}".format( cur_video_file_path, process_fail_message)) result.aggresult = False
def process_media(processPath, videoFiles, nzbName, process_method, force, is_priority, result): """ Postprocess mediafiles :param processPath: Path to postprocess in :param videoFiles: Filenames to look for and postprocess :param nzbName: Name of NZB file related :param process_method: auto/manual :param force: Postprocess currently postprocessing file :param is_priority: Boolean, is this a priority download :param result: Previous results """ processor = None for cur_video_file in videoFiles: cur_video_file_path = ek(os.path.join, processPath, cur_video_file) if already_postprocessed(processPath, cur_video_file, force, result): result.output += logHelper( "Already Processed " + cur_video_file_path + " : Skipping", logging.DEBUG) continue try: processor = postProcessor.PostProcessor(cur_video_file_path, nzbName, process_method, is_priority) result.result = processor.process() process_fail_message = "" except EpisodePostProcessingFailedException as e: result.result = False process_fail_message = ex(e) if processor: result.output += processor.log if result.result: result.output += logHelper("Processing succeeded for " + cur_video_file_path) else: result.output += logHelper( "Processing failed for " + cur_video_file_path + ": " + process_fail_message, logging.WARNING) result.missedfiles.append(cur_video_file_path + " : Processing failed: " + process_fail_message) result.aggresult = False
def process_media(processPath, videoFiles, nzbName, process_method, force, is_priority, result): # pylint: disable=too-many-arguments """ Postprocess mediafiles :param processPath: Path to postprocess in :param videoFiles: Filenames to look for and postprocess :param nzbName: Name of NZB file related :param process_method: auto/manual :param force: Postprocess currently postprocessing file :param is_priority: Boolean, is this a priority download :param result: Previous results """ processor = None for cur_video_file in videoFiles: cur_video_file_path = ek(os.path.join, processPath, cur_video_file) if already_postprocessed(processPath, cur_video_file, force, result): result.output += logHelper(u"Skipping already processed file: %s" % cur_video_file, logger.DEBUG) continue try: processor = postProcessor.PostProcessor(cur_video_file_path, nzbName, process_method, is_priority) # This feature prevents PP for files that do not have subtitle associated with the video file if sickbeard.POSTPONE_IF_NO_SUBS and subtitles_enabled(cur_video_file): associatedFiles = processor.list_associated_files(cur_video_file_path, subtitles_only=True) if not [associatedFile for associatedFile in associatedFiles if associatedFile[-3:] in subtitle_extensions]: result.output += logHelper(u"No subtitles associated. Postponing the post-process of this file: %s" % cur_video_file, logger.DEBUG) continue else: result.output += logHelper(u"Found subtitles associated. Continuing the post-process of this file: %s" % cur_video_file) result.result = processor.process() process_fail_message = u"" except EpisodePostProcessingFailedException as e: result.result = False process_fail_message = ex(e) if processor: result.output += processor.log if result.result: result.output += logHelper(u"Processing succeeded for %s" % cur_video_file_path) else: result.output += logHelper(u"Processing failed for %s: %s" % (cur_video_file_path, process_fail_message), logger.WARNING) result.missedfiles.append(u"%s : Processing failed: %s" % (cur_video_file_path, process_fail_message)) result.aggresult = False
def _process_media(self, process_path, video_files, nzb_name, process_method, force, force_replace, use_trash=False, showObj=None): processor = None for cur_video_file in video_files: if self._already_postprocessed(process_path, cur_video_file, force): self._set_process_success(False) continue cur_video_file_path = ek.ek(os.path.join, process_path, cur_video_file) parent = self.find_parent(cur_video_file_path) if parent: self._log_helper('Video %s is in a subdir of show root dir: %s, not processing media.' % (cur_video_file_path, parent)) continue try: processor = postProcessor.PostProcessor( cur_video_file_path, nzb_name, process_method, force_replace, use_trash=use_trash, webhandler=self.webhandler, showObj=showObj) file_success = processor.process() process_fail_message = '' except exceptions.PostProcessingFailed: file_success = False process_fail_message = '<br />.. Post Processing Failed' self._set_process_success(file_success) if processor: self._buffer(processor.log.strip('\n')) if file_success: self._log_helper(u'Successfully processed ' + cur_video_file, logger.MESSAGE) elif self.any_vid_processed: self._log_helper(u'Warning fail for %s%s' % (cur_video_file_path, process_fail_message), logger.WARNING) else: self._log_helper(u'Did not use file %s%s' % (cur_video_file_path, process_fail_message), logger.WARNING)
def process_media(processPath, videoFiles, nzbName, process_method, force, is_priority): global process_result, returnStr for cur_video_file in videoFiles: if already_postprocessed(processPath, cur_video_file, force): continue cur_video_file_path = ek.ek(os.path.join, processPath, cur_video_file) try: processor = postProcessor.PostProcessor(cur_video_file_path, nzbName, process_method, is_priority) process_result = processor.process() process_fail_message = "" except exceptions.PostProcessingFailed, e: # TODO: Add option to treat failure in processing as a failed download (the following line should do it) # curCountMediaProcessed -= 1 process_result = False process_fail_message = ex(e) returnStr += processor.log if process_result: returnStr += logHelper(u"Processing succeeded for " + cur_video_file_path) else: returnStr += logHelper( u"Processing failed for " + cur_video_file_path + ": " + process_fail_message, logger.WARNING) #If something fail abort the processing on dir if not process_result: break
def processDir(dirName, nzbName=None, recurse=False): """ Scans through the files in dirName and processes whatever media files it finds dirName: The folder name to look in nzbName: The NZB name which resulted in this folder being downloaded recurse: Boolean for whether we should descend into subfolders or not """ returnStr = '' returnStr += logHelper(u"Processing folder " + dirName, logger.DEBUG) # if they passed us a real dir then assume it's the one we want if ek.ek(os.path.isdir, dirName): dirName = ek.ek(os.path.realpath, dirName) # if they've got a download dir configured then use it elif sickbeard.TV_DOWNLOAD_DIR and ek.ek(os.path.isdir, sickbeard.TV_DOWNLOAD_DIR) \ and ek.ek(os.path.normpath, dirName) != ek.ek(os.path.normpath, sickbeard.TV_DOWNLOAD_DIR): dirName = ek.ek(os.path.join, sickbeard.TV_DOWNLOAD_DIR, ek.ek(os.path.abspath, dirName).split(os.path.sep)[-1]) returnStr += logHelper(u"Trying to use folder " + dirName, logger.DEBUG) # if we didn't find a real dir then quit if not ek.ek(os.path.isdir, dirName): returnStr += logHelper( u"Unable to figure out what folder to process. If your downloader and Sick Beard aren't on the same PC make sure you fill out your TV download dir in the config.", logger.DEBUG) return returnStr # TODO: check if it's failed and deal with it if it is if ek.ek(os.path.basename, dirName).startswith('_FAILED_'): returnStr += logHelper( u"The directory name indicates it failed to extract, cancelling", logger.DEBUG) return returnStr elif ek.ek(os.path.basename, dirName).startswith('_UNDERSIZED_'): returnStr += logHelper( u"The directory name indicates that it was previously rejected for being undersized, cancelling", logger.DEBUG) return returnStr elif ek.ek(os.path.basename, dirName).startswith('_UNPACK_'): returnStr += logHelper( u"The directory name indicates that this release is in the process of being unpacked, skipping", logger.DEBUG) return returnStr # make sure the dir isn't inside a show dir myDB = db.DBConnection() sqlResults = myDB.select("SELECT * FROM tv_shows") for sqlShow in sqlResults: if dirName.lower().startswith( ek.ek(os.path.realpath, sqlShow["location"]).lower() + os.sep) or dirName.lower() == ek.ek( os.path.realpath, sqlShow["location"]).lower(): returnStr += logHelper( u"You're trying to post process an episode that's already been moved to its show dir", logger.ERROR) return returnStr fileList = ek.ek(os.listdir, dirName) # split the list into video files and folders folders = filter( lambda x: ek.ek(os.path.isdir, ek.ek(os.path.join, dirName, x)), fileList) videoFiles = filter(helpers.isMediaFile, fileList) _checkOrphanedProcessedFiles(dirName, fileList) # recursively process all the folders for curFolder in folders: returnStr += logHelper( u"Recursively processing a folder: " + curFolder, logger.DEBUG) returnStr += processDir(ek.ek(os.path.join, dirName, curFolder), recurse=True) remainingFolders = filter( lambda x: ek.ek(os.path.isdir, ek.ek(os.path.join, dirName, x)), fileList) # If nzbName is set and there's more than one videofile in the folder, files will be lost (overwritten). if nzbName != None and len(videoFiles) >= 2: nzbName = None # process any files in the dir for cur_video_file_path in videoFiles: cur_video_file_path = ek.ek(os.path.join, dirName, cur_video_file_path) # prevent infinite auto process loop when KEEP_PROCESSED_DIR = true, by marking videos as processed if sickbeard.KEEP_PROCESSED_DIR: # check if file has already been processed - a .processed file will exist helper_file = helpers.replaceExtension(cur_video_file_path, "processed") if ek.ek(os.path.isfile, helper_file): logHelper(u"Processing skipped for " + cur_video_file_path + ": .processed file detected.") continue try: processor = postProcessor.PostProcessor(cur_video_file_path, nzbName) process_result = processor.process() process_fail_message = "" except exceptions.PostProcessingFailed, e: process_result = False process_fail_message = ex(e) returnStr += processor.log # as long as the postprocessing was successful delete the old folder unless the config wants us not to if process_result: if len(videoFiles) == 1 and not sickbeard.KEEP_PROCESSED_DIR and \ ek.ek(os.path.normpath, dirName) != ek.ek(os.path.normpath, sickbeard.TV_DOWNLOAD_DIR) and \ len(remainingFolders) == 0: returnStr += logHelper(u"Deleting folder " + dirName, logger.DEBUG) try: shutil.rmtree(dirName) except (OSError, IOError), e: returnStr += logHelper( u"Warning: unable to remove the folder " + dirName + ": " + ex(e), logger.WARNING) returnStr += logHelper(u"Processing succeeded for " + cur_video_file_path)
def processDir(dirName, nzbName=None, recurse=False): """ Scans through the files in dirName and processes whatever media files it finds dirName: The folder name to look in nzbName: The NZB name which resulted in this folder being downloaded recurse: Boolean for whether we should descend into subfolders or not """ returnStr = '' returnStr += logHelper(u"Processing folder " + dirName, logger.DEBUG) # if they passed us a real dir then assume it's the one we want if ek.ek(os.path.isdir, dirName): dirName = ek.ek(os.path.realpath, dirName) # if they've got a download dir configured then use it elif sickbeard.TV_DOWNLOAD_DIR and ek.ek(os.path.isdir, sickbeard.TV_DOWNLOAD_DIR) \ and ek.ek(os.path.normpath, dirName) != ek.ek(os.path.normpath, sickbeard.TV_DOWNLOAD_DIR): dirName = ek.ek(os.path.join, sickbeard.TV_DOWNLOAD_DIR, ek.ek(os.path.abspath, dirName).split(os.path.sep)[-1]) returnStr += logHelper(u"Trying to use folder " + dirName, logger.DEBUG) # if we didn't find a real dir then quit if not ek.ek(os.path.isdir, dirName): returnStr += logHelper( u"Unable to figure out what folder to process. If your downloader and Sick Beard aren't on the same PC make sure you fill out your TV download dir in the config.", logger.DEBUG) return returnStr # TODO: check if it's failed and deal with it if it is if ek.ek(os.path.basename, dirName).startswith('_FAILED_'): returnStr += logHelper( u"The directory name indicates it failed to extract, cancelling", logger.DEBUG) return returnStr elif ek.ek(os.path.basename, dirName).startswith('_UNDERSIZED_'): returnStr += logHelper( u"The directory name indicates that it was previously rejected for being undersized, cancelling", logger.DEBUG) return returnStr elif ek.ek(os.path.basename, dirName).startswith('_UNPACK_'): returnStr += logHelper( u"The directory name indicates that this release is in the process of being unpacked, skipping", logger.DEBUG) return returnStr # make sure the dir isn't inside a show dir myDB = db.DBConnection() sqlResults = myDB.select("SELECT * FROM tv_shows") for sqlShow in sqlResults: if dirName.lower().startswith( ek.ek(os.path.realpath, sqlShow["location"]).lower() + os.sep) or dirName.lower() == ek.ek( os.path.realpath, sqlShow["location"]).lower(): returnStr += logHelper( u"You're trying to post process an episode that's already been moved to its show dir", logger.ERROR) return returnStr fileList = ek.ek(os.listdir, dirName) # split the list into video files and folders folders = filter( lambda x: ek.ek(os.path.isdir, ek.ek(os.path.join, dirName, x)), fileList) videoFiles = filter(helpers.isMediaFile, fileList) # recursively process all the folders for curFolder in folders: returnStr += logHelper( u"Recursively processing a folder: " + curFolder, logger.DEBUG) returnStr += processDir(ek.ek(os.path.join, dirName, curFolder), recurse=True) remainingFolders = filter( lambda x: ek.ek(os.path.isdir, ek.ek(os.path.join, dirName, x)), fileList) # If nzbName is set and there's more than one videofile in the folder, files will be lost (overwritten). if nzbName != None and len(videoFiles) >= 2: nzbName = None # process any files in the dir for cur_video_file_path in videoFiles: cur_video_file_path = ek.ek(os.path.join, dirName, cur_video_file_path) # IF VIDEO_FILE ALREADY PROCESS THEN CONTINUE # TODO myDB = db.DBConnection() # with open(cur_video_file_path, 'rb') as fh: # m = hashlib.md5() # while True: # data = fh.read(8192) # if not data: # break # m.update(data) # MD5 = m.hexdigest() m = hashlib.md5() m.update(cur_video_file_path) MD5 = m.hexdigest() logger.log("MD5 search : " + MD5, logger.DEBUG) sqlResults = myDB.select( "select * from processed_files where md5 = \"" + MD5 + "\"") process_file = True ## # IF file is already a simlinks process = false ## if os.path.realpath(cur_video_file_path) != cur_video_file_path: logger.log("File " + cur_video_file_path + " is a symlink ") process_file = False for sqlProcess in sqlResults: if sqlProcess["md5"] == MD5: logger.log("File " + cur_video_file_path + " already processed for ") process_file = False if process_file: try: processor = postProcessor.PostProcessor( cur_video_file_path, nzbName) process_result = processor.process() process_fail_message = "" except exceptions.PostProcessingFailed, e: process_result = False process_fail_message = ex(e) returnStr += processor.log # as long as the postprocessing was successful delete the old folder unless the config wants us not to if process_result: # if len(videoFiles) == 1 \ # and ( ( not sickbeard.KEEP_PROCESSED_DIR and ek.ek(os.path.normpath, dirName) != ek.ek(os.path.normpath, sickbeard.TV_DOWNLOAD_DIR) ) \ # or ( sickbeard.PROCESS_METHOD == "move" and ek.ek(os.path.normpath, dirName) != ek.ek(os.path.normpath, sickbeard.TORRENT_DOWNLOAD_DIR) ) ) \ # and len(remainingFolders) == 0: delete = False if len(videoFiles) == 1 and len(remainingFolders) == 0: if ek.ek(os.path.normpath, dirName) != ek.ek(os.path.normpath, sickbeard.TORRENT_DOWNLOAD_DIR) and \ ek.ek(os.path.normpath, dirName) != ek.ek(os.path.normpath, sickbeard.TV_DOWNLOAD_DIR): if sickbeard.TORRENT_DOWNLOAD_DIR in dirName: if sickbeard.PROCESS_METHOD == "move" and ek.ek( os.path.normpath, dirName) != ek.ek( os.path.normpath, sickbeard.TORRENT_DOWNLOAD_DIR): delete = True elif not sickbeard.KEEP_PROCESSED_DIR and ek.ek( os.path.normpath, dirName) != ek.ek( os.path.normpath, sickbeard.TV_DOWNLOAD_DIR): delete = True if delete: returnStr += logHelper(u"Deleting folder " + dirName, logger.DEBUG) try: shutil.rmtree(dirName) except (OSError, IOError), e: returnStr += logHelper( u"Warning: unable to remove the folder " + dirName + ": " + ex(e), logger.WARNING) returnStr += logHelper(u"Processing succeeded for " + cur_video_file_path) else: returnStr += logHelper( u"Processing failed for " + cur_video_file_path + ": " + process_fail_message, logger.WARNING) if sickbeard.TV_DOWNLOAD_DIR != "": for i in range(1, 5): helpers.del_empty_dirs(sickbeard.TV_DOWNLOAD_DIR) if sickbeard.TORRENT_DOWNLOAD_DIR != "": for i in range(1, 5): helpers.del_empty_dirs(sickbeard.TORRENT_DOWNLOAD_DIR)
def processDir (dirName, nzbName=None, recurse=False): returnStr = '' returnStr += logHelper(u"Processing folder "+dirName, logger.DEBUG) # if they passed us a real dir then assume it's the one we want if ek.ek(os.path.isdir, dirName): dirName = ek.ek(os.path.realpath, dirName) # if they've got a download dir configured then use it elif sickbeard.TV_DOWNLOAD_DIR and ek.ek(os.path.isdir, sickbeard.TV_DOWNLOAD_DIR) \ and ek.ek(os.path.normpath, dirName) != ek.ek(os.path.normpath, sickbeard.TV_DOWNLOAD_DIR): dirName = ek.ek(os.path.join, sickbeard.TV_DOWNLOAD_DIR, ek.ek(os.path.abspath, dirName).split(os.path.sep)[-1]) returnStr += logHelper(u"Trying to use folder "+dirName, logger.DEBUG) # if we didn't find a real dir then quit if not ek.ek(os.path.isdir, dirName): returnStr += logHelper(u"Unable to figure out what folder to process. If your downloader and Sick Beard aren't on the same PC make sure you fill out your TV download dir in the config.", logger.DEBUG) return returnStr # TODO: check if it's failed and deal with it if it is if ek.ek(os.path.basename, dirName).startswith('_FAILED_'): returnStr += logHelper(u"The directory name indicates it failed to extract, cancelling", logger.DEBUG) return returnStr elif ek.ek(os.path.basename, dirName).startswith('_UNDERSIZED_'): returnStr += logHelper(u"The directory name indicates that it was previously rejected for being undersized, cancelling", logger.DEBUG) return returnStr elif ek.ek(os.path.basename, dirName).startswith('_UNPACK_'): returnStr += logHelper(u"The directory name indicates that this release is in the process of being unpacked, skipping", logger.DEBUG) return returnStr # make sure the dir isn't inside a show dir myDB = db.DBConnection() sqlResults = myDB.select("SELECT * FROM tv_shows") for sqlShow in sqlResults: if dirName.lower().startswith(ek.ek(os.path.realpath, sqlShow["location"]).lower()+os.sep) or dirName.lower() == ek.ek(os.path.realpath, sqlShow["location"]).lower(): returnStr += logHelper(u"You're trying to post process an episode that's already been moved to its show dir", logger.ERROR) return returnStr fileList = ek.ek(os.listdir, dirName) # split the list into video files and folders folders = filter(lambda x: ek.ek(os.path.isdir, ek.ek(os.path.join, dirName, x)), fileList) videoFiles = filter(helpers.isMediaFile, fileList) # recursively process all the folders for curFolder in folders: returnStr += logHelper(u"Recursively processing a folder: "+curFolder, logger.DEBUG) returnStr += processDir(ek.ek(os.path.join, dirName, curFolder), recurse=True) remainingFolders = filter(lambda x: ek.ek(os.path.isdir, ek.ek(os.path.join, dirName, x)), fileList) # process any files in the dir for cur_video_file_path in videoFiles: cur_video_file_path = ek.ek(os.path.join, dirName, cur_video_file_path) try: processor = postProcessor.PostProcessor(cur_video_file_path, nzbName) process_result = processor.process() except exceptions.PostProcessingFailed: process_result = False returnStr += processor.log # as long as the postprocessing was successful delete the old folder unless the config wants us not to if process_result: if len(videoFiles) == 1 and not sickbeard.KEEP_PROCESSED_DIR and \ ek.ek(os.path.normpath, dirName) != ek.ek(os.path.normpath, sickbeard.TV_DOWNLOAD_DIR) and \ len(remainingFolders) == 0: returnStr += logHelper(u"Deleting folder " + dirName, logger.DEBUG) try: shutil.rmtree(dirName) except (OSError, IOError), e: returnStr += logHelper(u"Warning: unable to remove the folder " + dirName + ": " + str(e).decode('utf-8'), logger.ERROR) returnStr += logHelper(u"Processing succeeded for "+cur_video_file_path) else: returnStr += logHelper(u"Processing failed for "+cur_video_file_path)
topdown=False): videoFiles = filter(helpers.isMediaFile, fileList) notwantedFiles = [x for x in fileList if x not in videoFiles] # If nzbName is set and there's more than one videofile in the folder, files will be lost (overwritten). if nzbName != None and len(videoFiles) >= 2: nzbName = None for cur_video_file in videoFiles: cur_video_file_path = ek.ek(os.path.join, processPath, cur_video_file) try: processor = postProcessor.PostProcessor( cur_video_file_path, nzbName) process_result = processor.process() process_fail_message = "" except exceptions.PostProcessingFailed, e: process_result = False process_fail_message = ex(e) returnStr += processor.log if process_result: returnStr += logHelper(u"Processing succeeded for " + cur_video_file_path) else: returnStr += logHelper( u"Processing failed for " + cur_video_file_path + ": " + process_fail_message, logger.WARNING)
remainingFolders = filter( lambda x: ek.ek(os.path.isdir, ek.ek(os.path.join, dirName, x)), fileList) # If nzbName is set and there's more than one videofile in the folder, files will be lost (overwritten). if nzbName != None and len(videoFiles) >= 2: nzbName = None # process any files in the dir for cur_video_file_path in videoFiles: cur_video_file_path = ek.ek(os.path.join, dirName, cur_video_file_path) try: processor = postProcessor.PostProcessor(cur_video_file_path, nzbName, failed=failed) process_result = processor.process() process_fail_message = "" except exceptions.PostProcessingFailed, e: process_result = False process_fail_message = ex(e) returnStr += processor.log # as long as the postprocessing was successful delete the old folder unless the config wants us not to if process_result: if len(videoFiles) == 1 and not sickbeard.KEEP_PROCESSED_DIR and \ ek.ek(os.path.normpath, dirName) != ek.ek(os.path.normpath, sickbeard.TV_DOWNLOAD_DIR) and \ len(remainingFolders) == 0:
def run(self): """ Called every few seconds to handle any running/finished torrents """ if not LIBTORRENT_AVAILABLE: return if not self.loadedRunningTorrents: torrent_save_file = _get_running_torrents_pickle_path(False) if os.path.isfile(torrent_save_file): logger.log( u'Saved torrents found in %s, loading' % (torrent_save_file), logger.DEBUG) _load_saved_torrents() self.loadedRunningTorrents = True sess = _get_session(False) if sess is not None: while 1: a = sess.pop_alert() if not a: break if type(a) == str: logger.log(a, logger.DEBUG) else: logger.log( u'(%s): %s' % (type(a).__name__, ek.fixStupidEncodings(a.message(), True)), logger.DEBUG) logTorrentStatus = (time.time() - self.lastTorrentStatusLogTS) >= 600 for torrent_data in running_torrents: if torrent_data['handle'].has_metadata(): ti = torrent_data['handle'].get_torrent_info() name = ti.name() torrent_data['name'] = name torrent_data['total_size'] = ti.total_size() if not torrent_data['have_torrentFile']: # if this was a magnet or url, and we now have downloaded the metadata # for it, best to save it locally in case we need to resume ti = torrent_data['handle'].get_torrent_info() torrentFile = lt.create_torrent(ti) torrent_data['torrent'] = lt.bencode( torrentFile.generate()) torrent_data['have_torrentFile'] = True logger.log( u'Created torrent file for %s as metadata d/l is now complete' % (name), logger.DEBUG) else: name = '-' s = torrent_data['handle'].status() torrent_data['status'] = str(s.state) torrent_data['progress'] = s.progress torrent_data['rate_down'] = s.download_rate torrent_data['rate_up'] = s.upload_rate torrent_data['paused'] = s.paused torrent_data['error'] = s.error #currentRatio = 0.0 if s.total_download == 0 else float(s.total_upload)/float(s.total_download) currentRatio = 0.0 if s.all_time_download == 0 else float( s.all_time_upload) / float(s.all_time_download) torrent_data['ratio'] = currentRatio if s.state in [ lt.torrent_status.seeding, lt.torrent_status.finished ]: with torrent_data['lock']: # this is the post-processing & removing code, so make sure that there's # only one thread doing either here, as the two could easily interfere with # one another if not torrent_data['post_processed']: # torrent has just completed download, so we need to do # post-processing on it. ti = torrent_data['handle'].get_torrent_info() any_file_success = False for f in ti.files(): fullpath = os.path.join( sickbeard.LIBTORRENT_WORKING_DIR, 'data', f.path) logger.log( u'Post-processing "%s"' % (fullpath), logger.DEBUG) if isMediaFile(fullpath): logger.log(u'this is a media file', logger.DEBUG) try: processor = postProcessor.PostProcessor( fullpath, name) if processor.process( forceKeepOriginalFiles=True): logger.log( u'Success post-processing "%s"' % (fullpath), logger.DEBUG) any_file_success = True except exceptions.PostProcessingFailed, e: logger.log( u'Failed post-processing file "%s" with error "%s"' % (fullpath, ex(e)), logger.ERROR) if not any_file_success: logger.log( u'When post-processing the completed torrent %s, no useful files were found.' % (name), logger.ERROR) torrent_data['post_processed'] = True else: # post-processing has already been performed. So we just # need to ensure check the ratio and delete the torrent # if we're good. if currentRatio >= sickbeard.LIBTORRENT_SEED_TO_RATIO: logger.log( u'Torrent "%s" has seeded to ratio %f. Removing it.' % (name, currentRatio), logger.MESSAGE) deleteFilesToo = True if not torrent_data['post_processed']: logger.log( u'Torrent has not been post_processed. Keeping files.', logger.MESSAGE) deleteFilesToo = False _remove_torrent_by_handle( torrent_data['handle'], deleteFilesToo) else: if logTorrentStatus: self.lastTorrentStatusLogTS = time.time() logger.log( u'"%s" seeding %0.3f' % (name, currentRatio), logger.DEBUG) elif s.state == lt.torrent_status.downloading: if logTorrentStatus: self.lastTorrentStatusLogTS = time.time() logger.log( u'"%s" downloading %0.2f' % (name, s.progress * 100.0), logger.DEBUG)
def processDir(dirName, nzbName=None, recurse=False): """ Scans through the files in dirName and processes whatever media files it finds dirName: The folder name to look in nzbName: The NZB name which resulted in this folder being downloaded """ returnStr = '' returnStr += logHelper(u"Processing folder " + dirName, logger.DEBUG) returnStr += logHelper(u"TV_DOWNLOAD_DIR: " + sickbeard.TV_DOWNLOAD_DIR, logger.DEBUG) # if they passed us a real dir then assume it's the one we want if ek.ek(os.path.isdir, dirName): dirName = ek.ek(os.path.realpath, dirName) # if the client and Sickbeard are not on the same machine translate the Dir in a network dir elif sickbeard.TV_DOWNLOAD_DIR and ek.ek(os.path.isdir, sickbeard.TV_DOWNLOAD_DIR) \ and ek.ek(os.path.normpath, dirName) != ek.ek(os.path.normpath, sickbeard.TV_DOWNLOAD_DIR): dirName = ek.ek(os.path.join, sickbeard.TV_DOWNLOAD_DIR, ek.ek(os.path.abspath, dirName).split(os.path.sep)[-1]) returnStr += logHelper(u"Trying to use folder " + dirName, logger.DEBUG) # if we didn't find a real dir then quit if not ek.ek(os.path.isdir, dirName): returnStr += logHelper( u"Unable to figure out what folder to process. If your downloader and Sick Beard aren't on the same PC make sure you fill out your TV download dir in the config.", logger.DEBUG) return returnStr if dirName == sickbeard.TV_DOWNLOAD_DIR and not nzbName: #Scheduled Post Processing Active #Get at first all the subdir in the dirName for path, dirs, files in ek.ek(os.walk, dirName): break else: path, dirs = ek.ek(os.path.split, dirName) #Script Post Processing if not nzbName is None and not nzbName.endswith( '.nzb') and os.path.isfile(os.path.join( dirName, nzbName)): #For single torrent file without Dir files = [os.path.join(dirName, nzbName)] dirs = [] else: files = ek.ek(os.listdir, dirName) dirs = [dirs] process_result = False videoFiles = filter(helpers.isMediaFile, files) # If nzbName is set and there's more than one videofile in the folder, files will be lost (overwritten). if nzbName != None and len(videoFiles) >= 2: nzbName = None returnStr += logHelper(u"PostProcessing Path: " + path, logger.DEBUG) returnStr += logHelper(u"PostProcessing Dirs: " + str(dirs), logger.DEBUG) returnStr += logHelper(u"PostProcessing Files: " + str(files), logger.DEBUG) returnStr += logHelper(u"PostProcessing VideoFiles: " + str(videoFiles), logger.DEBUG) #Process Video File in the current Path for cur_video_file in videoFiles: cur_video_file_path = ek.ek(os.path.join, dirName, cur_video_file) try: processor = postProcessor.PostProcessor(cur_video_file_path, nzbName) process_result = processor.process() process_fail_message = "" except exceptions.PostProcessingFailed, e: process_result = False process_fail_message = ex(e) returnStr += processor.log if process_result: returnStr += logHelper(u"Processing succeeded for " + cur_video_file_path) else: returnStr += logHelper( u"Processing failed for " + cur_video_file_path + ": " + process_fail_message, logger.WARNING)
def processDir(dirName, nzbName=None, method=None, recurse=False, pp_options={}): """ Scans through the files in dirName and processes whatever media files it finds dirName: The folder name to look in nzbName: The NZB name which resulted in this folder being downloaded method: The method of postprocessing: Automatic, Script, Manual recurse: Boolean for whether we should descend into subfolders or not """ returnStr = u"" returnStr += logHelper(u"Processing folder: " + dirName, logger.DEBUG) # if they passed us a real dir then assume it's the one we want if ek.ek(os.path.isdir, dirName): dirName = ek.ek(os.path.realpath, dirName) # if they've got a download dir configured then use it elif sickbeard.TV_DOWNLOAD_DIR and ek.ek(os.path.isdir, sickbeard.TV_DOWNLOAD_DIR) \ and ek.ek(os.path.normpath, dirName) != ek.ek(os.path.normpath, sickbeard.TV_DOWNLOAD_DIR): dirName = ek.ek(os.path.join, sickbeard.TV_DOWNLOAD_DIR, ek.ek(os.path.abspath, dirName).split(os.path.sep)[-1]) returnStr += logHelper(u"Trying to use folder: " + dirName, logger.DEBUG) # if we didn't find a real dir then quit if not ek.ek(os.path.isdir, dirName): returnStr += logHelper( u"Unable to figure out what folder to process. If your downloader and Sick Beard aren't on the same PC make sure you fill out your TV download dir in the config.", logger.DEBUG) return returnStr # TODO: check if it's failed and deal with it if it is if ek.ek(os.path.basename, dirName).startswith('_FAILED_'): returnStr += logHelper( u"The directory name indicates it failed to extract, cancelling", logger.DEBUG) return returnStr elif ek.ek(os.path.basename, dirName).startswith('_UNDERSIZED_'): returnStr += logHelper( u"The directory name indicates that it was previously rejected for being undersized, cancelling", logger.DEBUG) return returnStr elif ek.ek(os.path.basename, dirName).startswith('_UNPACK_'): returnStr += logHelper( u"The directory name indicates that this release is in the process of being unpacked, skipping", logger.DEBUG) return returnStr # make sure the dir isn't inside a show dir myDB = db.DBConnection() sqlResults = myDB.select("SELECT * FROM tv_shows") for sqlShow in sqlResults: if dirName.lower().startswith( ek.ek(os.path.realpath, sqlShow["location"]).lower() + os.sep) or dirName.lower() == ek.ek( os.path.realpath, sqlShow["location"]).lower(): returnStr += logHelper( u"You're trying to post process an existing show directory: " + dirName, logger.ERROR) returnStr += u"\n" return returnStr fileList = ek.ek(os.listdir, dirName) # split the list into video files and folders folders = filter( lambda x: ek.ek(os.path.isdir, ek.ek(os.path.join, dirName, x)), fileList) # videoFiles, sorted by size, process biggest file first. Leaves smaller same named file behind videoFiles = sorted( filter(helpers.isMediaFile, fileList), key=lambda x: ek.ek(os.path.getsize, ek.ek(os.path.join, dirName, x)), reverse=True) remaining_video_files = list(videoFiles) num_videoFiles = len(videoFiles) # if there are no videofiles in parent and only one subfolder, pass the nzbName to child if num_videoFiles == 0 and len(folders) == 1: parent_nzbName = nzbName else: parent_nzbName = None # recursively process all the folders for cur_folder in folders: returnStr += u"\n" # use full path cur_folder = ek.ek(os.path.join, dirName, cur_folder) if helpers.is_hidden_folder(cur_folder): returnStr += logHelper(u"Ignoring hidden folder: " + cur_folder, logger.DEBUG) else: returnStr += logHelper( u"Recursively processing a folder: " + cur_folder, logger.DEBUG) returnStr += processDir(cur_folder, nzbName=parent_nzbName, recurse=True, method=method, pp_options=pp_options) remainingFolders = filter( lambda x: ek.ek(os.path.isdir, ek.ek(os.path.join, dirName, x)), fileList) if num_videoFiles == 0: returnStr += logHelper( u"There are no videofiles in folder: " + dirName, logger.DEBUG) # if there a no videofiles, try deleting empty folder if method != 'Manual': if delete_folder(dirName, check_empty=True): returnStr += logHelper(u"Deleted empty folder: " + dirName, logger.DEBUG) # if there's more than one videofile in the folder, files can be lost (overwritten) when nzbName contains only one episode. if num_videoFiles >= 2: nzbName = None # process any files in the dir for cur_video_file in videoFiles: cur_video_file_path = ek.ek(os.path.join, dirName, cur_video_file) if method == 'Automatic': # check if we processed this video file before cur_video_file_path_size = ek.ek(os.path.getsize, cur_video_file_path) myDB = db.DBConnection() search_sql = "SELECT tv_episodes.tvdbid, history.resource FROM tv_episodes INNER JOIN history ON history.showid=tv_episodes.showid" search_sql += " WHERE history.season=tv_episodes.season and history.episode=tv_episodes.episode" search_sql += " and tv_episodes.status IN (" + ",".join( [str(x) for x in common.Quality.DOWNLOADED]) + ")" search_sql += " and history.resource LIKE ? and tv_episodes.file_size = ?" sql_results = myDB.select( search_sql, [cur_video_file_path, cur_video_file_path_size]) if len(sql_results): returnStr += logHelper( u"Ignoring file: " + cur_video_file_path + " looks like it's been processed already", logger.DEBUG) continue try: returnStr += u"\n" processor = postProcessor.PostProcessor(cur_video_file_path, nzb_name=nzbName, pp_options=pp_options) process_result = processor.process() process_fail_message = "" except exceptions.PostProcessingFailed, e: process_result = False process_fail_message = ex(e) except Exception, e: process_result = False process_fail_message = "Post Processor returned unhandled exception: " + ex( e)