示例#1
0
def validateDir(path, dirName, nzbNameOriginal, failed, result):
    """
    Check if directory is valid for processing

    :param path: Path to use
    :param dirName: Directory to check
    :param nzbNameOriginal: Original NZB name
    :param failed: Previously failed objects
    :param result: Previous results
    :return: True if dir is valid for processing, False if not
    """

    IGNORED_FOLDERS = ['.AppleDouble', '.@__thumb', '@eaDir']

    folder_name = os.path.basename(dirName)
    if folder_name in IGNORED_FOLDERS:
        return False

    result.output += logHelper("Processing folder " + dirName, sickrage.srCore.srLogger.DEBUG)

    if folder_name.startswith('_FAILED_'):
        result.output += logHelper("The directory name indicates it failed to extract.", sickrage.srCore.srLogger.DEBUG)
        failed = True
    elif folder_name.startswith('_UNDERSIZED_'):
        result.output += logHelper("The directory name indicates that it was previously rejected for being undersized.",
                                   sickrage.srCore.srLogger.DEBUG)
        failed = True
    elif folder_name.upper().startswith('_UNPACK'):
        result.output += logHelper(
            "The directory name indicates that this release is in the process of being unpacked.",
            sickrage.srCore.srLogger.DEBUG)
        result.missedfiles.append(dirName + " : Being unpacked")
        return False

    if failed:
        process_failed(os.path.join(path, dirName), nzbNameOriginal, result)
        result.missedfiles.append(dirName + " : Failed download")
        return False

    if is_hidden_folder(os.path.join(path, dirName)):
        result.output += logHelper("Ignoring hidden folder: " + dirName, sickrage.srCore.srLogger.DEBUG)
        result.missedfiles.append(dirName + " : Hidden folder")
        return False

    # make sure the dir isn't inside a show dir
    for dbData in [x['doc'] for x in sickrage.srCore.mainDB.db.all('tv_shows', with_doc=True)]:
        if dirName.lower().startswith(os.path.realpath(dbData["location"]).lower() + os.sep) or \
                        dirName.lower() == os.path.realpath(dbData["location"]).lower():
            result.output += logHelper(
                "Cannot process an episode that's already been moved to its show dir, skipping " + dirName,
                sickrage.srCore.srLogger.WARNING)
            return False

    # Get the videofile list for the next checks
    allFiles = []
    allDirs = []
    for _, processdir, fileList in os.walk(os.path.join(path, dirName), topdown=False):
        allDirs += processdir
        allFiles += fileList

    videoFiles = [x for x in allFiles if isMediaFile(x)]
    allDirs.append(dirName)

    # check if the dir have at least one tv video file
    for video in videoFiles:
        try:
            NameParser().parse(video, cache_result=False)
            return True
        except (InvalidNameException, InvalidShowException):
            pass

    for proc_dir in allDirs:
        try:
            NameParser().parse(proc_dir, cache_result=False)
            return True
        except (InvalidNameException, InvalidShowException):
            pass

    if sickrage.srCore.srConfig.UNPACK:
        # Search for packed release
        packedFiles = [x for x in allFiles if isRarFile(x)]

        for packed in packedFiles:
            try:
                NameParser().parse(packed, cache_result=False)
                return True
            except (InvalidNameException, InvalidShowException):
                pass

    result.output += logHelper(dirName + " : No processable items found in folder", sickrage.srCore.srLogger.DEBUG)
    return False
示例#2
0
def processDir(dirName, nzbName=None, process_method=None, force=False, is_priority=None, delete_on=False, failed=False,
               proc_type="auto", **kwargs):
    """
    Scans through the files in dirName and processes whatever media files it finds

    :param dirName: The folder name to look in
    :param nzbName: The NZB name which resulted in this folder being downloaded
    :param force: True to postprocess already postprocessed files
    :param failed: Boolean for whether or not the download failed
    :param proc_type: Type of postprocessing auto or manual
    """

    result = ProcessResult()

    result.output += logHelper("Processing folder %s" % dirName, sickrage.srCore.srLogger.DEBUG)

    result.output += logHelper("TV_DOWNLOAD_DIR: %s" % sickrage.srCore.srConfig.TV_DOWNLOAD_DIR,
                               sickrage.srCore.srLogger.DEBUG)
    postpone = False

    # if they passed us a real dir then assume it's the one we want
    if os.path.isdir(dirName):
        dirName = os.path.realpath(dirName)

    # if the client and SickRage are not on the same machine translate the Dir in a network dir
    elif sickrage.srCore.srConfig.TV_DOWNLOAD_DIR and os.path.isdir(sickrage.srCore.srConfig.TV_DOWNLOAD_DIR) \
            and os.path.normpath(dirName) != os.path.normpath(sickrage.srCore.srConfig.TV_DOWNLOAD_DIR):
        dirName = os.path.join(sickrage.srCore.srConfig.TV_DOWNLOAD_DIR,
                               os.path.abspath(dirName).split(os.path.sep)[-1])
        result.output += logHelper("Trying to use folder %s" % dirName, sickrage.srCore.srLogger.DEBUG)

    # if we didn't find a real dir then quit
    if not os.path.isdir(dirName):
        result.output += logHelper(
            "Unable to figure out what folder to process. If your downloader and SiCKRAGE aren't on the same PC make sure you fill out your TV download dir in the config.",
            sickrage.srCore.srLogger.DEBUG)
        return result.output

    path, dirs, files = get_path_dir_files(dirName, nzbName, proc_type)

    files = [x for x in files if notTorNZBFile(x)]
    SyncFiles = [x for x in files if isSyncFile(x)]

    # Don't post process if files are still being synced and option is activated
    if SyncFiles and sickrage.srCore.srConfig.POSTPONE_IF_SYNC_FILES:
        postpone = True

    nzbNameOriginal = nzbName

    if not postpone:
        result.output += logHelper("PostProcessing Path: %s" % path, sickrage.srCore.srLogger.INFO)
        result.output += logHelper("PostProcessing Dirs: [%s]" % ", ".join(dirs), sickrage.srCore.srLogger.DEBUG)

        rarFiles = [x for x in files if isRarFile(x)]
        rarContent = unRAR(path, rarFiles, force, result)
        files += rarContent
        videoFiles = [x for x in files if isMediaFile(x)]
        videoInRar = [x for x in rarContent if isMediaFile(x)]

        result.output += logHelper("PostProcessing Files: [%s]" % ", ".join(files), sickrage.srCore.srLogger.DEBUG)
        result.output += logHelper("PostProcessing VideoFiles: [%s]" % ", ".join(videoFiles),
                                   sickrage.srCore.srLogger.DEBUG)
        result.output += logHelper("PostProcessing RarContent: [%s]" % ", ".join(rarContent),
                                   sickrage.srCore.srLogger.DEBUG)
        result.output += logHelper("PostProcessing VideoInRar: [%s]" % ", ".join(videoInRar),
                                   sickrage.srCore.srLogger.DEBUG)

        # If nzbName is set and there's more than one videofile in the folder, files will be lost (overwritten).
        if len(videoFiles) >= 2:
            nzbName = None

        if not process_method:
            process_method = sickrage.srCore.srConfig.PROCESS_METHOD

        result.result = True

        # Don't Link media when the media is extracted from a rar in the same path
        if process_method in ('hardlink', 'symlink') and videoInRar:
            process_media(path, videoInRar, nzbName, 'move', force, is_priority, result)
            delete_files(path, rarContent, result)
            for video in set(videoFiles) - set(videoInRar):
                process_media(path, [video], nzbName, process_method, force, is_priority, result)
        elif sickrage.srCore.srConfig.DELRARCONTENTS and videoInRar:
            process_media(path, videoInRar, nzbName, process_method, force, is_priority, result)
            delete_files(path, rarContent, result, True)
            for video in set(videoFiles) - set(videoInRar):
                process_media(path, [video], nzbName, process_method, force, is_priority, result)
        else:
            for video in videoFiles:
                process_media(path, [video], nzbName, process_method, force, is_priority, result)

    else:
        result.output += logHelper("Found temporary sync files, skipping post processing for: %s" % path)
        result.output += logHelper("Sync Files: [%s] in path %s" % (", ".join(SyncFiles), path))
        result.missedfiles.append("%s : Syncfiles found" % path)

    # Process Video File in all TV Subdir
    for curDir in [x for x in dirs if validateDir(path, x, nzbNameOriginal, failed, result)]:

        result.result = True

        for processPath, _, fileList in os.walk(os.path.join(path, curDir), topdown=False):

            if not validateDir(path, processPath, nzbNameOriginal, failed, result):
                continue

            postpone = False

            SyncFiles = [x for x in fileList if isSyncFile(x)]

            # Don't post process if files are still being synced and option is activated
            if SyncFiles and sickrage.srCore.srConfig.POSTPONE_IF_SYNC_FILES:
                postpone = True

            if not postpone:
                rarFiles = [x for x in fileList if isRarFile(x)]
                rarContent = unRAR(processPath, rarFiles, force, result)
                fileList = set(fileList + rarContent)
                videoFiles = [x for x in fileList if isMediaFile(x)]
                videoInRar = [x for x in rarContent if isMediaFile(x)]
                notwantedFiles = [x for x in fileList if x not in videoFiles]
                if notwantedFiles:
                    result.output += logHelper("Found unwanted files: [%s]" % ", ".join(notwantedFiles),
                                               sickrage.srCore.srLogger.DEBUG)

                # Don't Link media when the media is extracted from a rar in the same path
                if process_method in ('hardlink', 'symlink') and videoInRar:
                    process_media(processPath, videoInRar, nzbName, 'move', force, is_priority, result)
                    process_media(processPath, set(videoFiles) - set(videoInRar), nzbName, process_method, force,
                                  is_priority, result)
                    delete_files(processPath, rarContent, result)
                elif sickrage.srCore.srConfig.DELRARCONTENTS and videoInRar:
                    process_media(processPath, videoInRar, nzbName, process_method, force, is_priority, result)
                    process_media(processPath, set(videoFiles) - set(videoInRar), nzbName, process_method, force,
                                  is_priority, result)
                    delete_files(processPath, rarContent, result, True)
                else:
                    process_media(processPath, videoFiles, nzbName, process_method, force, is_priority, result)

                    # Delete all file not needed
                    if process_method != "move" or not result.result \
                            or (
                                            proc_type == "manual" and not delete_on):  # Avoid to delete files if is Manual PostProcessing
                        continue

                    delete_files(processPath, notwantedFiles, result)

                    if (
                                not sickrage.srCore.srConfig.NO_DELETE or proc_type == "manual") and process_method == "move" and \
                                    os.path.normpath(processPath) != os.path.normpath(
                                sickrage.srCore.srConfig.TV_DOWNLOAD_DIR):
                        if delete_folder(processPath, check_empty=True):
                            result.output += logHelper("Deleted folder: %s" % processPath,
                                                       sickrage.srCore.srLogger.DEBUG)
            else:
                result.output += logHelper("Found temporary sync files, skipping post processing for: %s" % processPath)
                result.output += logHelper("Sync Files: [%s] in path %s" % (", ".join(SyncFiles), processPath))
                result.missedfiles.append("%s : Syncfiles found" % processPath)

    if result.aggresult:
        result.output += logHelper("Processing completed")
        if result.missedfiles:
            result.output += logHelper("I did encounter some unprocessable items: [%s]" % ", ".join(result.missedfiles))
    else:
        result.output += logHelper(
            "Problem(s) during processing, failed the following files/folders:  [%s]" % ", ".join(
                result.missedfiles),
            sickrage.srCore.srLogger.WARNING)

    return result.output
示例#3
0
def validateDir(path, dirName, nzbNameOriginal, failed, result):
    """
    Check if directory is valid for processing

    :param path: Path to use
    :param dirName: Directory to check
    :param nzbNameOriginal: Original NZB name
    :param failed: Previously failed objects
    :param result: Previous results
    :return: True if dir is valid for processing, False if not
    """

    IGNORED_FOLDERS = ['.AppleDouble', '.@__thumb', '@eaDir']

    folder_name = os.path.basename(dirName)
    if folder_name in IGNORED_FOLDERS:
        return False

    result.output += logHelper("Processing folder " + dirName, sickrage.srCore.srLogger.DEBUG)

    if folder_name.startswith('_FAILED_'):
        result.output += logHelper("The directory name indicates it failed to extract.", sickrage.srCore.srLogger.DEBUG)
        failed = True
    elif folder_name.startswith('_UNDERSIZED_'):
        result.output += logHelper("The directory name indicates that it was previously rejected for being undersized.",
                                   sickrage.srCore.srLogger.DEBUG)
        failed = True
    elif folder_name.upper().startswith('_UNPACK'):
        result.output += logHelper(
            "The directory name indicates that this release is in the process of being unpacked.",
            sickrage.srCore.srLogger.DEBUG)
        result.missedfiles.append(dirName + " : Being unpacked")
        return False

    if failed:
        process_failed(os.path.join(path, dirName), nzbNameOriginal, result)
        result.missedfiles.append(dirName + " : Failed download")
        return False

    if is_hidden_folder(os.path.join(path, dirName)):
        result.output += logHelper("Ignoring hidden folder: " + dirName, sickrage.srCore.srLogger.DEBUG)
        result.missedfiles.append(dirName + " : Hidden folder")
        return False

    # make sure the dir isn't inside a show dir
    for dbData in [x['doc'] for x in sickrage.srCore.mainDB.db.all('tv_shows', with_doc=True)]:
        if dirName.lower().startswith(os.path.realpath(dbData["location"]).lower() + os.sep) or \
                        dirName.lower() == os.path.realpath(dbData["location"]).lower():
            result.output += logHelper(
                "Cannot process an episode that's already been moved to its show dir, skipping " + dirName,
                sickrage.srCore.srLogger.WARNING)
            return False

    # Get the videofile list for the next checks
    allFiles = []
    allDirs = []
    for _, processdir, fileList in os.walk(os.path.join(path, dirName), topdown=False):
        allDirs += processdir
        allFiles += fileList

    videoFiles = [x for x in allFiles if isMediaFile(x)]
    allDirs.append(dirName)

    # check if the dir have at least one tv video file
    for video in videoFiles:
        try:
            NameParser().parse(video, cache_result=False)
            return True
        except (InvalidNameException, InvalidShowException):
            pass

    for proc_dir in allDirs:
        try:
            NameParser().parse(proc_dir, cache_result=False)
            return True
        except (InvalidNameException, InvalidShowException):
            pass

    if sickrage.srCore.srConfig.UNPACK:
        # Search for packed release
        packedFiles = [x for x in allFiles if isRarFile(x)]

        for packed in packedFiles:
            try:
                NameParser().parse(packed, cache_result=False)
                return True
            except (InvalidNameException, InvalidShowException):
                pass

    result.output += logHelper(dirName + " : No processable items found in folder", sickrage.srCore.srLogger.DEBUG)
    return False
示例#4
0
def processDir(dirName, nzbName=None, process_method=None, force=False, is_priority=None, delete_on=False, failed=False,
               proc_type="auto", **kwargs):
    """
    Scans through the files in dirName and processes whatever media files it finds

    :param dirName: The folder name to look in
    :param nzbName: The NZB name which resulted in this folder being downloaded
    :param force: True to postprocess already postprocessed files
    :param failed: Boolean for whether or not the download failed
    :param proc_type: Type of postprocessing auto or manual
    """

    result = ProcessResult()

    result.output += logHelper("Processing folder %s" % dirName, sickrage.srCore.srLogger.DEBUG)

    result.output += logHelper("TV_DOWNLOAD_DIR: %s" % sickrage.srCore.srConfig.TV_DOWNLOAD_DIR,
                               sickrage.srCore.srLogger.DEBUG)
    postpone = False

    # if they passed us a real dir then assume it's the one we want
    if os.path.isdir(dirName):
        dirName = os.path.realpath(dirName)

    # if the client and SickRage are not on the same machine translate the Dir in a network dir
    elif sickrage.srCore.srConfig.TV_DOWNLOAD_DIR and os.path.isdir(sickrage.srCore.srConfig.TV_DOWNLOAD_DIR) \
            and os.path.normpath(dirName) != os.path.normpath(sickrage.srCore.srConfig.TV_DOWNLOAD_DIR):
        dirName = os.path.join(sickrage.srCore.srConfig.TV_DOWNLOAD_DIR,
                               os.path.abspath(dirName).split(os.path.sep)[-1])
        result.output += logHelper("Trying to use folder %s" % dirName, sickrage.srCore.srLogger.DEBUG)

    # if we didn't find a real dir then quit
    if not os.path.isdir(dirName):
        result.output += logHelper(
            "Unable to figure out what folder to process. If your downloader and SiCKRAGE aren't on the same PC make sure you fill out your TV download dir in the config.",
            sickrage.srCore.srLogger.DEBUG)
        return result.output

    path, dirs, files = get_path_dir_files(dirName, nzbName, proc_type)

    files = [x for x in files if notTorNZBFile(x)]
    SyncFiles = [x for x in files if isSyncFile(x)]

    # Don't post process if files are still being synced and option is activated
    if SyncFiles and sickrage.srCore.srConfig.POSTPONE_IF_SYNC_FILES:
        postpone = True

    nzbNameOriginal = nzbName

    if not postpone:
        result.output += logHelper("PostProcessing Path: %s" % path, sickrage.srCore.srLogger.INFO)
        result.output += logHelper("PostProcessing Dirs: [%s]" % ", ".join(dirs), sickrage.srCore.srLogger.DEBUG)

        rarFiles = [x for x in files if isRarFile(x)]
        rarContent = unRAR(path, rarFiles, force, result)
        files += rarContent
        videoFiles = [x for x in files if isMediaFile(x)]
        videoInRar = [x for x in rarContent if isMediaFile(x)]

        result.output += logHelper("PostProcessing Files: [%s]" % ", ".join(files), sickrage.srCore.srLogger.DEBUG)
        result.output += logHelper("PostProcessing VideoFiles: [%s]" % ", ".join(videoFiles),
                                   sickrage.srCore.srLogger.DEBUG)
        result.output += logHelper("PostProcessing RarContent: [%s]" % ", ".join(rarContent),
                                   sickrage.srCore.srLogger.DEBUG)
        result.output += logHelper("PostProcessing VideoInRar: [%s]" % ", ".join(videoInRar),
                                   sickrage.srCore.srLogger.DEBUG)

        # If nzbName is set and there's more than one videofile in the folder, files will be lost (overwritten).
        if len(videoFiles) >= 2:
            nzbName = None

        if not process_method:
            process_method = sickrage.srCore.srConfig.PROCESS_METHOD

        result.result = True

        # Don't Link media when the media is extracted from a rar in the same path
        if process_method in ('hardlink', 'symlink') and videoInRar:
            process_media(path, videoInRar, nzbName, 'move', force, is_priority, result)
            delete_files(path, rarContent, result)
            for video in set(videoFiles) - set(videoInRar):
                process_media(path, [video], nzbName, process_method, force, is_priority, result)
        elif sickrage.srCore.srConfig.DELRARCONTENTS and videoInRar:
            process_media(path, videoInRar, nzbName, process_method, force, is_priority, result)
            delete_files(path, rarContent, result, True)
            for video in set(videoFiles) - set(videoInRar):
                process_media(path, [video], nzbName, process_method, force, is_priority, result)
        else:
            for video in videoFiles:
                process_media(path, [video], nzbName, process_method, force, is_priority, result)

    else:
        result.output += logHelper("Found temporary sync files, skipping post processing for: %s" % path)
        result.output += logHelper("Sync Files: [%s] in path %s" % (", ".join(SyncFiles), path))
        result.missedfiles.append("%s : Syncfiles found" % path)

    # Process Video File in all TV Subdir
    for curDir in [x for x in dirs if validateDir(path, x, nzbNameOriginal, failed, result)]:

        result.result = True

        for processPath, _, fileList in os.walk(os.path.join(path, curDir), topdown=False):

            if not validateDir(path, processPath, nzbNameOriginal, failed, result):
                continue

            postpone = False

            SyncFiles = [x for x in fileList if isSyncFile(x)]

            # Don't post process if files are still being synced and option is activated
            if SyncFiles and sickrage.srCore.srConfig.POSTPONE_IF_SYNC_FILES:
                postpone = True

            if not postpone:
                rarFiles = [x for x in fileList if isRarFile(x)]
                rarContent = unRAR(processPath, rarFiles, force, result)
                fileList = set(fileList + rarContent)
                videoFiles = [x for x in fileList if isMediaFile(x)]
                videoInRar = [x for x in rarContent if isMediaFile(x)]
                notwantedFiles = [x for x in fileList if x not in videoFiles]
                if notwantedFiles:
                    result.output += logHelper("Found unwanted files: [%s]" % ", ".join(notwantedFiles),
                                               sickrage.srCore.srLogger.DEBUG)

                # Don't Link media when the media is extracted from a rar in the same path
                if process_method in ('hardlink', 'symlink') and videoInRar:
                    process_media(processPath, videoInRar, nzbName, 'move', force, is_priority, result)
                    process_media(processPath, set(videoFiles) - set(videoInRar), nzbName, process_method, force,
                                  is_priority, result)
                    delete_files(processPath, rarContent, result)
                elif sickrage.srCore.srConfig.DELRARCONTENTS and videoInRar:
                    process_media(processPath, videoInRar, nzbName, process_method, force, is_priority, result)
                    process_media(processPath, set(videoFiles) - set(videoInRar), nzbName, process_method, force,
                                  is_priority, result)
                    delete_files(processPath, rarContent, result, True)
                else:
                    process_media(processPath, videoFiles, nzbName, process_method, force, is_priority, result)

                    # Delete all file not needed
                    if process_method != "move" or not result.result \
                            or (
                                            proc_type == "manual" and not delete_on):  # Avoid to delete files if is Manual PostProcessing
                        continue

                    delete_files(processPath, notwantedFiles, result)

                    if (
                                not sickrage.srCore.srConfig.NO_DELETE or proc_type == "manual") and process_method == "move" and \
                                    os.path.normpath(processPath) != os.path.normpath(
                                sickrage.srCore.srConfig.TV_DOWNLOAD_DIR):
                        if delete_folder(processPath, check_empty=True):
                            result.output += logHelper("Deleted folder: %s" % processPath,
                                                       sickrage.srCore.srLogger.DEBUG)
            else:
                result.output += logHelper("Found temporary sync files, skipping post processing for: %s" % processPath)
                result.output += logHelper("Sync Files: [%s] in path %s" % (", ".join(SyncFiles), processPath))
                result.missedfiles.append("%s : Syncfiles found" % processPath)

    if result.aggresult:
        result.output += logHelper("Processing completed")
        if result.missedfiles:
            result.output += logHelper("I did encounter some unprocessable items: [%s]" % ", ".join(result.missedfiles))
    else:
        result.output += logHelper(
            "Problem(s) during processing, failed the following files/folders:  [%s]" % ", ".join(
                result.missedfiles),
            sickrage.srCore.srLogger.WARNING)

    return result.output
示例#5
0
    def loadFromNFO(self, location):

        if not os.path.isdir(self.show._location):
            sickrage.LOGGER.info(
                    str(
                            self.show.indexerid) + ": The show dir is missing, not bothering to try loading the episode NFO")
            return

        sickrage.LOGGER.debug(
                str(
                    self.show.indexerid) + ": Loading episode details from the NFO file associated with " + location)

        self.location = location

        if self.location != "":

            if self.status == UNKNOWN:
                if isMediaFile(self.location):
                    sickrage.LOGGER.debug("7 Status changes from " + str(self.status) + " to " + str(
                            Quality.statusFromName(self.location, anime=self.show.is_anime)))
                    self.status = Quality.statusFromName(self.location, anime=self.show.is_anime)

            nfoFile = replaceExtension(self.location, "nfo")
            sickrage.LOGGER.debug(str(self.show.indexerid) + ": Using NFO name " + nfoFile)

            if os.path.isfile(nfoFile):
                try:
                    showXML = ElementTree(file=nfoFile)
                except (SyntaxError, ValueError) as e:
                    sickrage.LOGGER.error("Error loading the NFO, backing up the NFO and skipping for now: {}".format(e))
                    try:
                        os.rename(nfoFile, nfoFile + ".old")
                    except Exception as e:
                        sickrage.LOGGER.error(
                                "Failed to rename your episode's NFO file - you need to delete it or fix it: {}".format(
                                        e))
                    raise NoNFOException("Error in NFO format")

                for epDetails in showXML.iter('episodedetails'):
                    if epDetails.findtext('season') is None or int(epDetails.findtext('season')) != self.season or \
                                    epDetails.findtext('episode') is None or int(
                            epDetails.findtext('episode')) != self.episode:
                        sickrage.LOGGER.debug(
                                "%s: NFO has an <episodedetails> block for a different episode - wanted S%02dE%02d but got S%02dE%02d" %
                                (
                                    self.show.indexerid, self.season or 0, self.episode or 0,
                                    epDetails.findtext('season') or 0,
                                    epDetails.findtext('episode') or 0))
                        continue

                    if epDetails.findtext('title') is None or epDetails.findtext('aired') is None:
                        raise NoNFOException("Error in NFO format (missing episode title or airdate)")

                    self.name = epDetails.findtext('title')
                    self.episode = int(epDetails.findtext('episode'))
                    self.season = int(epDetails.findtext('season'))

                    xem_refresh(self.show.indexerid, self.show.indexer)

                    self.scene_absolute_number = get_scene_absolute_numbering(
                            self.show.indexerid,
                            self.show.indexer,
                            self.absolute_number
                    )

                    self.scene_season, self.scene_episode = get_scene_numbering(
                            self.show.indexerid,
                            self.show.indexer,
                            self.season, self.episode
                    )

                    self.description = epDetails.findtext('plot')
                    if self.description is None:
                        self.description = ""

                    if epDetails.findtext('aired'):
                        rawAirdate = [int(x) for x in epDetails.findtext('aired').split("-")]
                        self.airdate = datetime.date(rawAirdate[0], rawAirdate[1], rawAirdate[2])
                    else:
                        self.airdate = datetime.date.fromordinal(1)

                    self.hasnfo = True
            else:
                self.hasnfo = False

            if os.path.isfile(replaceExtension(nfoFile, "tbn")):
                self.hastbn = True
            else:
                self.hastbn = False
示例#6
0
    def loadFromIndexer(self, season=None, episode=None, cache=True, tvapi=None, cachedSeason=None):

        if season is None:
            season = self.season
        if episode is None:
            episode = self.episode

        sickrage.LOGGER.debug("%s: Loading episode details from %s for episode S%02dE%02d" %
                      (self.show.indexerid, sickrage.INDEXER_API(self.show.indexer).name, season or 0, episode or 0))

        indexer_lang = self.show.lang

        try:
            if cachedSeason is None:
                if tvapi is None:
                    lINDEXER_API_PARMS = sickrage.INDEXER_API(self.indexer).api_params.copy()

                    if not cache:
                        lINDEXER_API_PARMS[b'cache'] = False

                    if indexer_lang:
                        lINDEXER_API_PARMS[b'language'] = indexer_lang

                    if self.show.dvdorder != 0:
                        lINDEXER_API_PARMS[b'dvdorder'] = True

                    t = sickrage.INDEXER_API(self.indexer).indexer(**lINDEXER_API_PARMS)
                else:
                    t = tvapi
                myEp = t[self.show.indexerid][season][episode]
            else:
                myEp = cachedSeason[episode]

        except (indexer_error, IOError) as e:
            sickrage.LOGGER.debug("" + sickrage.INDEXER_API(self.indexer).name + " threw up an error: {}".format(e))
            # if the episode is already valid just log it, if not throw it up
            if self.name:
                sickrage.LOGGER.debug("" + sickrage.INDEXER_API(
                        self.indexer).name + " timed out but we have enough info from other sources, allowing the error")
                return
            else:
                sickrage.LOGGER.error("" + sickrage.INDEXER_API(self.indexer).name + " timed out, unable to create the episode")
                return False
        except (indexer_episodenotfound, indexer_seasonnotfound):
            sickrage.LOGGER.debug("Unable to find the episode on " + sickrage.INDEXER_API(
                    self.indexer).name + "... has it been removed? Should I delete from db?")
            # if I'm no longer on the Indexers but I once was then delete myself from the DB
            if self.indexerid != -1:
                self.deleteEpisode()
            return

        if getattr(myEp, 'episodename', None) is None:
            sickrage.LOGGER.info("This episode %s - S%02dE%02d has no name on %s. Setting to an empty string" % (
                self.show.name, season or 0, episode or 0, sickrage.INDEXER_API(self.indexer).name))
            setattr(myEp, 'episodename', '')
            # # if I'm incomplete on TVDB but I once was complete then just delete myself from the DB for now
            # if self.indexerid != -1:
            #     self.deleteEpisode()
            # return False

        if getattr(myEp, 'absolute_number', None) is None:
            sickrage.LOGGER.debug("This episode %s - S%02dE%02d has no absolute number on %s" % (
                self.show.name, season or 0, episode or 0, sickrage.INDEXER_API(self.indexer).name))
        else:
            sickrage.LOGGER.debug("%s: The absolute_number for S%02dE%02d is: %s " % (
                self.show.indexerid, season or 0, episode or 0, myEp[b"absolute_number"]))
            self.absolute_number = int(myEp[b"absolute_number"])

        self.name = getattr(myEp, 'episodename', "")
        self.season = season
        self.episode = episode

        xem_refresh(self.show.indexerid, self.show.indexer)

        self.scene_absolute_number = get_scene_absolute_numbering(
                self.show.indexerid,
                self.show.indexer,
                self.absolute_number
        )

        self.scene_season, self.scene_episode = get_scene_numbering(
                self.show.indexerid,
                self.show.indexer,
                self.season, self.episode
        )

        self.description = getattr(myEp, 'overview', "")

        firstaired = getattr(myEp, 'firstaired', None)
        if not firstaired or firstaired == "0000-00-00":
            firstaired = str(datetime.date.fromordinal(1))
        rawAirdate = [int(x) for x in firstaired.split("-")]

        try:
            self.airdate = datetime.date(rawAirdate[0], rawAirdate[1], rawAirdate[2])
        except (ValueError, IndexError):
            sickrage.LOGGER.warning("Malformed air date of %s retrieved from %s for (%s - S%02dE%02d)" % (
                firstaired, sickrage.INDEXER_API(self.indexer).name, self.show.name, season or 0, episode or 0))
            # if I'm incomplete on the indexer but I once was complete then just delete myself from the DB for now
            if self.indexerid != -1:
                self.deleteEpisode()
            return False

        # early conversion to int so that episode doesn't get marked dirty
        self.indexerid = getattr(myEp, 'id', None)
        if self.indexerid is None:
            sickrage.LOGGER.error("Failed to retrieve ID from " + sickrage.INDEXER_API(self.indexer).name)
            if self.indexerid != -1:
                self.deleteEpisode()
            return False

        # don't update show status if show dir is missing, unless it's missing on purpose
        if not os.path.isdir(
                self.show._location) and not sickrage.CREATE_MISSING_SHOW_DIRS and not sickrage.ADD_SHOWS_WO_DIR:
            sickrage.LOGGER.info(
                    "The show dir %s is missing, not bothering to change the episode statuses since it'd probably be invalid" % self.show._location)
            return

        if self.location:
            sickrage.LOGGER.debug("%s: Setting status for S%02dE%02d based on status %s and location %s" %
                          (self.show.indexerid, season or 0, episode or 0, statusStrings[self.status],
                           self.location))

        if not os.path.isfile(self.location):
            if self.airdate >= datetime.date.today() or self.airdate == datetime.date.fromordinal(1):
                sickrage.LOGGER.debug("Episode airs in the future or has no airdate, marking it %s" % statusStrings[
                    UNAIRED])
                self.status = UNAIRED
            elif self.status in [UNAIRED, UNKNOWN]:
                # Only do UNAIRED/UNKNOWN, it could already be snatched/ignored/skipped, or downloaded/archived to disconnected media
                sickrage.LOGGER.debug(
                    "Episode has already aired, marking it %s" % statusStrings[self.show.default_ep_status])
                self.status = self.show.default_ep_status if self.season > 0 else SKIPPED  # auto-skip specials
            else:
                sickrage.LOGGER.debug(
                        "Not touching status [ %s ] It could be skipped/ignored/snatched/archived" % statusStrings[
                            self.status])

        # if we have a media file then it's downloaded
        elif isMediaFile(self.location):
            # leave propers alone, you have to either post-process them or manually change them back
            if self.status not in Quality.SNATCHED_PROPER + Quality.DOWNLOADED + Quality.SNATCHED + Quality.ARCHIVED:
                sickrage.LOGGER.debug(
                        "5 Status changes from " + str(self.status) + " to " + str(
                                Quality.statusFromName(self.location)))
                self.status = Quality.statusFromName(self.location, anime=self.show.is_anime)

        # shouldn't get here probably
        else:
            sickrage.LOGGER.debug("6 Status changes from " + str(self.status) + " to " + str(UNKNOWN))
            self.status = UNKNOWN