Esempio n. 1
0
    def logFailed(epObj, release, provider=None):
        """
        Log a failed download

        :param epObj: Episode object
        :param release: Release group
        :param provider: Provider used for snatch
        """
        showid = int(epObj.show.indexerid)
        season = int(epObj.season)
        epNum = int(epObj.episode)
        status, quality = Quality.splitCompositeStatus(epObj.status)
        action = Quality.compositeStatus(FAILED, quality)

        History._logHistoryItem(action, showid, season, epNum, quality, release, provider)
Esempio n. 2
0
    def logFailed(epObj, release, provider=None):
        """
        Log a failed download

        :param epObj: Episode object
        :param release: Release group
        :param provider: Provider used for snatch
        """
        showid = int(epObj.show.indexerid)
        season = int(epObj.season)
        epNum = int(epObj.episode)
        status, quality = Quality.splitCompositeStatus(epObj.status)
        action = Quality.compositeStatus(FAILED, quality)

        History._logHistoryItem(action, showid, season, epNum, quality,
                                release, provider)
Esempio n. 3
0
    def _get_segments(self, show, fromDate):
        if show.paused:
            sickrage.srLogger.debug(
                "Skipping backlog for {show_name} because the show is paused".
                format(show_name=show.name))
            return {}

        anyQualities, bestQualities = Quality.splitQuality(
            show.quality)  # @UnusedVariable

        sickrage.srLogger.debug(
            "Seeing if we need anything from {show_name}".format(
                show_name=show.name))

        sqlResults = main_db.MainDB().select(
            "SELECT status, season, episode FROM tv_episodes WHERE season > 0 AND airdate > ? AND showid = ?",
            [fromDate.toordinal(), show.indexerid])

        # check through the list of statuses to see if we want any
        wanted = {}
        for result in sqlResults:
            curCompositeStatus = int(result[b"status"] or -1)
            curStatus, curQuality = Quality.splitCompositeStatus(
                curCompositeStatus)

            if bestQualities:
                highestBestQuality = max(bestQualities)
                lowestBestQuality = min(bestQualities)
            else:
                highestBestQuality = 0
                lowestBestQuality = 0

            # if we need a better one then say yes
            if (curStatus in (DOWNLOADED, SNATCHED, SNATCHED_PROPER) and
                    curQuality < highestBestQuality) or curStatus == WANTED:
                epObj = show.getEpisode(int(result[b"season"]),
                                        int(result[b"episode"]))

                # only fetch if not archive on first match, or if show is lowest than the lower expected quality
                if (epObj.show.archive_firstmatch == 0
                        or curQuality < lowestBestQuality):
                    if epObj.season not in wanted:
                        wanted[epObj.season] = [epObj]
                    else:
                        wanted[epObj.season].append(epObj)

        return wanted
Esempio n. 4
0
    def logSubtitle(showid, season, episode, status, subtitleResult):
        """
        Log download of subtitle

        :param showid: Showid of download
        :param season: Show season
        :param episode: Show episode
        :param status: Status of download
        :param subtitleResult: Result object
        """
        resource = subtitleResult.language.opensubtitles
        provider = subtitleResult.provider_name

        status, quality = Quality.splitCompositeStatus(status)
        action = Quality.compositeStatus(SUBTITLED, quality)

        History._logHistoryItem(action, showid, season, episode, quality, resource, provider)
Esempio n. 5
0
    def logSubtitle(showid, season, episode, status, subtitleResult):
        """
        Log download of subtitle

        :param showid: Showid of download
        :param season: Show season
        :param episode: Show episode
        :param status: Status of download
        :param subtitleResult: Result object
        """
        resource = subtitleResult.language.opensubtitles
        provider = subtitleResult.provider_name

        status, quality = Quality.splitCompositeStatus(status)
        action = Quality.compositeStatus(SUBTITLED, quality)

        History._logHistoryItem(action, showid, season, episode, quality,
                                resource, provider)
Esempio n. 6
0
    def markFailed(epObj):
        """
        Mark an episode as failed

        :param epObj: Episode object to mark as failed
        :return: empty string
        """
        log_str = ""

        try:
            with epObj.lock:
                quality = Quality.splitCompositeStatus(epObj.status)[1]
                epObj.status = Quality.compositeStatus(FAILED, quality)
                epObj.saveToDB()

        except EpisodeNotFoundException as e:
            sickrage.srLogger.warning("Unable to get episode, please set its status manually: {}".format(e.message))

        return log_str
Esempio n. 7
0
    def markFailed(epObj):
        """
        Mark an episode as failed

        :param epObj: Episode object to mark as failed
        :return: empty string
        """
        log_str = ""

        try:
            with epObj.lock:
                quality = Quality.splitCompositeStatus(epObj.status)[1]
                epObj.status = Quality.compositeStatus(FAILED, quality)
                epObj.saveToDB()

        except EpisodeNotFoundException as e:
            sickrage.srLogger.warning(
                "Unable to get episode, please set its status manually: {}".
                format(e.message))

        return log_str
Esempio n. 8
0
    def _get_segments(self, show, fromDate):
        if show.paused:
            sickrage.srLogger.debug("Skipping backlog for {show_name} because the show is paused".format(show_name=show.name))
            return {}

        anyQualities, bestQualities = Quality.splitQuality(show.quality)  # @UnusedVariable

        sickrage.srLogger.debug("Seeing if we need anything from {show_name}".format(show_name=show.name))

        sqlResults = main_db.MainDB().select(
            "SELECT status, season, episode FROM tv_episodes WHERE season > 0 AND airdate > ? AND showid = ?",
            [fromDate.toordinal(), show.indexerid])

        # check through the list of statuses to see if we want any
        wanted = {}
        for result in sqlResults:
            curCompositeStatus = int(result[b"status"] or -1)
            curStatus, curQuality = Quality.splitCompositeStatus(curCompositeStatus)

            if bestQualities:
                highestBestQuality = max(bestQualities)
                lowestBestQuality = min(bestQualities)
            else:
                highestBestQuality = 0
                lowestBestQuality = 0

            # if we need a better one then say yes
            if (curStatus in (DOWNLOADED, SNATCHED,
                              SNATCHED_PROPER) and curQuality < highestBestQuality) or curStatus == WANTED:
                epObj = show.getEpisode(int(result[b"season"]), int(result[b"episode"]))

                # only fetch if not archive on first match, or if show is lowest than the lower expected quality
                if (epObj.show.archive_firstmatch == 0 or curQuality < lowestBestQuality):
                    if epObj.season not in wanted:
                        wanted[epObj.season] = [epObj]
                    else:
                        wanted[epObj.season].append(epObj)

        return wanted
Esempio n. 9
0
def wantedEpisodes(show, fromDate):
    """
    Get a list of episodes that we want to download
    :param show: Show these episodes are from
    :param fromDate: Search from a certain date
    :return: list of wanted episodes
    """

    anyQualities, bestQualities = Quality.splitQuality(show.quality)  # @UnusedVariable
    allQualities = list(set(anyQualities + bestQualities))

    sickrage.srLogger.debug("Seeing if we need anything from " + show.name)

    sqlResults = main_db.MainDB().select(
            "SELECT status, season, episode FROM tv_episodes WHERE showid = ? AND season > 0 AND airdate > ?",
            [show.indexerid, fromDate.toordinal()])

    # check through the list of statuses to see if we want any
    wanted = []
    for result in sqlResults:
        curCompositeStatus = int(result[b"status"] or -1)
        curStatus, curQuality = Quality.splitCompositeStatus(curCompositeStatus)

        if bestQualities:
            highestBestQuality = max(allQualities)
        else:
            highestBestQuality = 0

        # if we need a better one then say yes
        if (curStatus in (DOWNLOADED, SNATCHED,
                          SNATCHED_PROPER) and curQuality < highestBestQuality) or curStatus == WANTED:
            epObj = show.getEpisode(int(result[b"season"]), int(result[b"episode"]))
            epObj.wantedQuality = [i for i in allQualities if (i > curQuality and i != Quality.UNKNOWN)]
            wanted.append(epObj)

    return wanted
Esempio n. 10
0
    def _getProperList(self):
        """
        Walk providers for propers
        """
        propers = {}

        search_date = datetime.today() - timedelta(days=2)

        origThreadName = threading.currentThread().getName()

        # for each provider get a list of the
        for providerID, providerObj in {k: v for k, v in sortedProviderDict(
                sickrage.srConfig.RANDOMIZE_PROVIDERS).items()
                                        if v.isActive}.items():

            threading.currentThread().setName(origThreadName + " :: [" + providerObj.name + "]")

            sickrage.srLogger.info("Searching for any new PROPER releases from " + providerObj.name)

            try:
                curPropers = providerObj.findPropers(search_date)
            except AuthException as e:
                sickrage.srLogger.debug("Authentication error: {}".format(e.message))
                continue
            except Exception as e:
                sickrage.srLogger.debug("Error while searching " + providerObj.name + ", skipping: {}".format(e.message))
                sickrage.srLogger.debug(traceback.format_exc())
                continue

            # if they haven't been added by a different provider than add the proper to the list
            for x in curPropers:
                if not re.search(r'(^|[\. _-])(proper|repack)([\. _-]|$)', x.name, re.I):
                    sickrage.srLogger.debug('findPropers returned a non-proper, we have caught and skipped it.')
                    continue

                name = self._genericName(x.name)
                if not name in propers:
                    sickrage.srLogger.debug("Found new proper: " + x.name)
                    x.provider = providerObj
                    propers[name] = x

            threading.currentThread().setName(origThreadName)

        # take the list of unique propers and get it sorted by
        sortedPropers = sorted(propers.values(), key=operator.attrgetter('date'), reverse=True)
        finalPropers = []

        for curProper in sortedPropers:

            try:
                myParser = NameParser(False)
                parse_result = myParser.parse(curProper.name)
            except InvalidNameException:
                sickrage.srLogger.debug("Unable to parse the filename " + curProper.name + " into a valid episode")
                continue
            except InvalidShowException:
                sickrage.srLogger.debug("Unable to parse the filename " + curProper.name + " into a valid show")
                continue

            if not parse_result.series_name:
                continue

            if not parse_result.episode_numbers:
                sickrage.srLogger.debug(
                        "Ignoring " + curProper.name + " because it's for a full season rather than specific episode")
                continue

            sickrage.srLogger.debug(
                    "Successful match! Result " + parse_result.original_name + " matched to show " + parse_result.show.name)

            # set the indexerid in the db to the show's indexerid
            curProper.indexerid = parse_result.show.indexerid

            # set the indexer in the db to the show's indexer
            curProper.indexer = parse_result.show.indexer

            # populate our Proper instance
            curProper.show = parse_result.show
            curProper.season = parse_result.season_number if parse_result.season_number is not None else 1
            curProper.episode = parse_result.episode_numbers[0]
            curProper.release_group = parse_result.release_group
            curProper.version = parse_result.version
            curProper.quality = Quality.nameQuality(curProper.name, parse_result.is_anime)
            curProper.content = None

            # filter release
            bestResult = pickBestResult(curProper, parse_result.show)
            if not bestResult:
                sickrage.srLogger.debug("Proper " + curProper.name + " were rejected by our release filters.")
                continue

            # only get anime proper if it has release group and version
            if bestResult.show.is_anime:
                if not bestResult.release_group and bestResult.version == -1:
                    sickrage.srLogger.debug("Proper " + bestResult.name + " doesn't have a release group and version, ignoring it")
                    continue

            # check if we actually want this proper (if it's the right quality)            
            sqlResults = main_db.MainDB().select(
                "SELECT status FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ?",
                                     [bestResult.indexerid, bestResult.season, bestResult.episode])
            if not sqlResults:
                continue

            # only keep the proper if we have already retrieved the same quality ep (don't get better/worse ones)
            oldStatus, oldQuality = Quality.splitCompositeStatus(int(sqlResults[0][b"status"]))
            if oldStatus not in (DOWNLOADED, SNATCHED) or oldQuality != bestResult.quality:
                continue

            # check if we actually want this proper (if it's the right release group and a higher version)
            if bestResult.show.is_anime:
                sqlResults = main_db.MainDB().select(
                        "SELECT release_group, version FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ?",
                        [bestResult.indexerid, bestResult.season, bestResult.episode])

                oldVersion = int(sqlResults[0][b"version"])
                oldRelease_group = (sqlResults[0][b"release_group"])

                if oldVersion > -1 and oldVersion < bestResult.version:
                    sickrage.srLogger.info(
                        "Found new anime v" + str(bestResult.version) + " to replace existing v" + str(oldVersion))
                else:
                    continue

                if oldRelease_group != bestResult.release_group:
                    sickrage.srLogger.info(
                        "Skipping proper from release group: " + bestResult.release_group + ", does not match existing release group: " + oldRelease_group)
                    continue

            # if the show is in our list and there hasn't been a proper already added for that particular episode then add it to our list of propers
            if bestResult.indexerid != -1 and (bestResult.indexerid, bestResult.season, bestResult.episode) not in map(
                    operator.attrgetter('indexerid', 'season', 'episode'), finalPropers):
                sickrage.srLogger.info("Found a proper that we need: " + str(bestResult.name))
                finalPropers.append(bestResult)

        return finalPropers
Esempio n. 11
0
def makeSceneSeasonSearchString(show, ep_obj, extraSearchType=None):
    numseasons = 0

    if show.air_by_date or show.sports:
        # the search string for air by date shows is just
        seasonStrings = [str(ep_obj.airdate).split('-')[0]]
    elif show.is_anime:
        seasonEps = show.getAllEpisodes(ep_obj.season)

        # get show qualities
        anyQualities, bestQualities = Quality.splitQuality(show.quality)

        # compile a list of all the episode numbers we need in this 'season'
        seasonStrings = []
        for episode in seasonEps:

            # get quality of the episode
            curCompositeStatus = episode.status
            curStatus, curQuality = Quality.splitCompositeStatus(
                curCompositeStatus)

            if bestQualities:
                highestBestQuality = max(bestQualities)
            else:
                highestBestQuality = 0

            # if we need a better one then add it to the list of episodes to fetch
            if (curStatus in (DOWNLOADED, SNATCHED) and
                    curQuality < highestBestQuality) or curStatus == WANTED:
                ab_number = episode.scene_absolute_number
                if ab_number > 0:
                    seasonStrings.append("%02d" % ab_number)

    else:
        numseasonsSQlResult = main_db.MainDB().select(
            "SELECT COUNT(DISTINCT season) as numseasons FROM tv_episodes WHERE showid = ? and season != 0",
            [show.indexerid])

        if numseasonsSQlResult:
            numseasons = int(numseasonsSQlResult[0][0])
        seasonStrings = ["S%02d" % int(ep_obj.scene_season)]

    showNames = set(makeSceneShowSearchStrings(show, ep_obj.scene_season))

    toReturn = []

    # search each show name
    for curShow in showNames:
        # most providers all work the same way
        if not extraSearchType:
            # if there's only one season then we can just use the show name straight up
            if numseasons == 1:
                toReturn.append(curShow)
            # for providers that don't allow multiple searches in one request we only search for Sxx style stuff
            else:
                for cur_season in seasonStrings:
                    if ep_obj.show.is_anime:
                        if ep_obj.show.release_groups is not None:
                            if len(show.release_groups.whitelist) > 0:
                                for keyword in show.release_groups.whitelist:
                                    toReturn.append(keyword + '.' + curShow +
                                                    "." + cur_season)
                    else:
                        toReturn.append(curShow + "." + cur_season)

    return toReturn
Esempio n. 12
0
def makeSceneSeasonSearchString(show, ep_obj, extraSearchType=None):
    numseasons = 0

    if show.air_by_date or show.sports:
        # the search string for air by date shows is just
        seasonStrings = [str(ep_obj.airdate).split('-')[0]]
    elif show.is_anime:
        seasonEps = show.getAllEpisodes(ep_obj.season)

        # get show qualities
        anyQualities, bestQualities = Quality.splitQuality(show.quality)

        # compile a list of all the episode numbers we need in this 'season'
        seasonStrings = []
        for episode in seasonEps:

            # get quality of the episode
            curCompositeStatus = episode.status
            curStatus, curQuality = Quality.splitCompositeStatus(curCompositeStatus)

            if bestQualities:
                highestBestQuality = max(bestQualities)
            else:
                highestBestQuality = 0

            # if we need a better one then add it to the list of episodes to fetch
            if (curStatus in (
                    DOWNLOADED,
                    SNATCHED) and curQuality < highestBestQuality) or curStatus == WANTED:
                ab_number = episode.scene_absolute_number
                if ab_number > 0:
                    seasonStrings.append("%02d" % ab_number)

    else:
        numseasonsSQlResult = main_db.MainDB().select(
                "SELECT COUNT(DISTINCT season) as numseasons FROM tv_episodes WHERE showid = ? and season != 0",
                [show.indexerid])

        if numseasonsSQlResult:
            numseasons = int(numseasonsSQlResult[0][0])
        seasonStrings = ["S%02d" % int(ep_obj.scene_season)]

    showNames = set(makeSceneShowSearchStrings(show, ep_obj.scene_season))

    toReturn = []

    # search each show name
    for curShow in showNames:
        # most providers all work the same way
        if not extraSearchType:
            # if there's only one season then we can just use the show name straight up
            if numseasons == 1:
                toReturn.append(curShow)
            # for providers that don't allow multiple searches in one request we only search for Sxx style stuff
            else:
                for cur_season in seasonStrings:
                    if ep_obj.show.is_anime:
                        if ep_obj.show.release_groups is not None:
                            if len(show.release_groups.whitelist) > 0:
                                for keyword in show.release_groups.whitelist:
                                    toReturn.append(keyword + '.' + curShow + "." + cur_season)
                    else:
                        toReturn.append(curShow + "." + cur_season)

    return toReturn
Esempio n. 13
0
    def _getProperList(self):
        """
        Walk providers for propers
        """
        propers = {}

        search_date = datetime.today() - timedelta(days=2)

        origThreadName = threading.currentThread().getName()

        # for each provider get a list of the
        for providerID, providerObj in {
                k: v
                for k, v in sortedProviderDict(
                    sickrage.srConfig.RANDOMIZE_PROVIDERS).items()
                if v.isActive
        }.items():

            threading.currentThread().setName(origThreadName + " :: [" +
                                              providerObj.name + "]")

            sickrage.srLogger.info(
                "Searching for any new PROPER releases from " +
                providerObj.name)

            try:
                curPropers = providerObj.findPropers(search_date)
            except AuthException as e:
                sickrage.srLogger.debug("Authentication error: {}".format(
                    e.message))
                continue
            except Exception as e:
                sickrage.srLogger.debug("Error while searching " +
                                        providerObj.name +
                                        ", skipping: {}".format(e.message))
                sickrage.srLogger.debug(traceback.format_exc())
                continue

            # if they haven't been added by a different provider than add the proper to the list
            for x in curPropers:
                if not re.search(r'(^|[\. _-])(proper|repack)([\. _-]|$)',
                                 x.name, re.I):
                    sickrage.srLogger.debug(
                        'findPropers returned a non-proper, we have caught and skipped it.'
                    )
                    continue

                name = self._genericName(x.name)
                if not name in propers:
                    sickrage.srLogger.debug("Found new proper: " + x.name)
                    x.provider = providerObj
                    propers[name] = x

            threading.currentThread().setName(origThreadName)

        # take the list of unique propers and get it sorted by
        sortedPropers = sorted(propers.values(),
                               key=operator.attrgetter('date'),
                               reverse=True)
        finalPropers = []

        for curProper in sortedPropers:

            try:
                myParser = NameParser(False)
                parse_result = myParser.parse(curProper.name)
            except InvalidNameException:
                sickrage.srLogger.debug("Unable to parse the filename " +
                                        curProper.name +
                                        " into a valid episode")
                continue
            except InvalidShowException:
                sickrage.srLogger.debug("Unable to parse the filename " +
                                        curProper.name + " into a valid show")
                continue

            if not parse_result.series_name:
                continue

            if not parse_result.episode_numbers:
                sickrage.srLogger.debug(
                    "Ignoring " + curProper.name +
                    " because it's for a full season rather than specific episode"
                )
                continue

            sickrage.srLogger.debug("Successful match! Result " +
                                    parse_result.original_name +
                                    " matched to show " +
                                    parse_result.show.name)

            # set the indexerid in the db to the show's indexerid
            curProper.indexerid = parse_result.show.indexerid

            # set the indexer in the db to the show's indexer
            curProper.indexer = parse_result.show.indexer

            # populate our Proper instance
            curProper.show = parse_result.show
            curProper.season = parse_result.season_number if parse_result.season_number is not None else 1
            curProper.episode = parse_result.episode_numbers[0]
            curProper.release_group = parse_result.release_group
            curProper.version = parse_result.version
            curProper.quality = Quality.nameQuality(curProper.name,
                                                    parse_result.is_anime)
            curProper.content = None

            # filter release
            bestResult = pickBestResult(curProper, parse_result.show)
            if not bestResult:
                sickrage.srLogger.debug(
                    "Proper " + curProper.name +
                    " were rejected by our release filters.")
                continue

            # only get anime proper if it has release group and version
            if bestResult.show.is_anime:
                if not bestResult.release_group and bestResult.version == -1:
                    sickrage.srLogger.debug(
                        "Proper " + bestResult.name +
                        " doesn't have a release group and version, ignoring it"
                    )
                    continue

            # check if we actually want this proper (if it's the right quality)
            sqlResults = main_db.MainDB().select(
                "SELECT status FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ?",
                [bestResult.indexerid, bestResult.season, bestResult.episode])
            if not sqlResults:
                continue

            # only keep the proper if we have already retrieved the same quality ep (don't get better/worse ones)
            oldStatus, oldQuality = Quality.splitCompositeStatus(
                int(sqlResults[0][b"status"]))
            if oldStatus not in (DOWNLOADED,
                                 SNATCHED) or oldQuality != bestResult.quality:
                continue

            # check if we actually want this proper (if it's the right release group and a higher version)
            if bestResult.show.is_anime:
                sqlResults = main_db.MainDB().select(
                    "SELECT release_group, version FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ?",
                    [
                        bestResult.indexerid, bestResult.season,
                        bestResult.episode
                    ])

                oldVersion = int(sqlResults[0][b"version"])
                oldRelease_group = (sqlResults[0][b"release_group"])

                if oldVersion > -1 and oldVersion < bestResult.version:
                    sickrage.srLogger.info("Found new anime v" +
                                           str(bestResult.version) +
                                           " to replace existing v" +
                                           str(oldVersion))
                else:
                    continue

                if oldRelease_group != bestResult.release_group:
                    sickrage.srLogger.info(
                        "Skipping proper from release group: " +
                        bestResult.release_group +
                        ", does not match existing release group: " +
                        oldRelease_group)
                    continue

            # if the show is in our list and there hasn't been a proper already added for that particular episode then add it to our list of propers
            if bestResult.indexerid != -1 and (
                    bestResult.indexerid, bestResult.season,
                    bestResult.episode) not in map(
                        operator.attrgetter('indexerid', 'season', 'episode'),
                        finalPropers):
                sickrage.srLogger.info("Found a proper that we need: " +
                                       str(bestResult.name))
                finalPropers.append(bestResult)

        return finalPropers