Exemple #1
0
    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)
Exemple #2
0
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
Exemple #3
0
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
Exemple #4
0
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)
Exemple #5
0
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
Exemple #6
0
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
Exemple #7
0
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
Exemple #8
0
    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
Exemple #10
0
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)
Exemple #11
0
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)
Exemple #12
0
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)
Exemple #14
0
    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:
Exemple #15
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)
Exemple #17
0
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)