Example #1
0
 def test_FULLHDBLURAY(self):
     self.assertEqual(
         Quality.FULLHDBLURAY,
         Quality.nameQuality("Test.Show.S01E02.1080p.BluRay.x264-GROUP"))
     self.assertEqual(
         Quality.FULLHDBLURAY,
         Quality.nameQuality("Test.Show.S01E02.1080p.HDDVD.x264-GROUP"))
Example #2
0
 def test_HDTV(self):
     self.assertEqual(
         Quality.HDTV,
         Quality.nameQuality("Test.Show.S01E02.720p.HDTV.x264-GROUP"))
     self.assertEqual(
         Quality.HDTV,
         Quality.nameQuality("Test.Show.S01E02.HR.WS.PDTV.x264-GROUP"))
Example #3
0
 def test_RAWHDTV(self):
     self.assertEqual(Quality.RAWHDTV,
                      Quality.nameQuality("Test.Show.S01E02.720p.HDTV.DD5.1.MPEG2-GROUP"))
     self.assertEqual(Quality.RAWHDTV,
                      Quality.nameQuality("Test.Show.S01E02.1080i.HDTV.DD2.0.MPEG2-GROUP"))
     self.assertEqual(Quality.RAWHDTV,
                      Quality.nameQuality("Test.Show.S01E02.1080i.HDTV.H.264.DD2.0-GROUP"))
     self.assertEqual(Quality.RAWHDTV,
                      Quality.nameQuality("Test Show - S01E02 - 1080i HDTV MPA1.0 H.264 - GROUP"))
     self.assertEqual(Quality.RAWHDTV,
                      Quality.nameQuality("Test.Show.S01E02.1080i.HDTV.DD.5.1.h264-GROUP"))
Example #4
0
def generate_sample_ep(multi=None, abd=False, sports=False, anime_type=None):
    # make a fake episode object
    ep = Episode(2, 3, 3, "Ep Name")

    ep._status = Quality.compositeStatus(DOWNLOADED, Quality.HDTV)
    ep._airdate = date(2011, 3, 9)

    if abd:
        ep._release_name = 'Show.Name.2011.03.09.HDTV.XviD-RLSGROUP'
        ep.show.air_by_date = 1
    elif sports:
        ep._release_name = 'Show.Name.2011.03.09.HDTV.XviD-RLSGROUP'
        ep.show.sports = 1
    else:
        if anime_type != 3:
            ep.show.anime = 1
            ep._release_name = 'Show.Name.003.HDTV.XviD-RLSGROUP'
        else:
            ep._release_name = 'Show.Name.S02E03.HDTV.XviD-RLSGROUP'

    if multi is not None:
        ep._name = "Ep Name (1)"

        if anime_type != 3:
            ep.show.anime = 1

            ep._release_name = 'Show.Name.003-004.HDTV.XviD-RLSGROUP'

            second_ep = Episode(2, 4, 4, "Ep Name (2)")
            second_ep._status = Quality.compositeStatus(
                DOWNLOADED, Quality.HDTV)
            second_ep._release_name = ep.release_name

            ep.relatedEps.append(second_ep)
        else:
            ep._release_name = 'Show.Name.S02E03E04E05.HDTV.XviD-RLSGROUP'

            second_ep = Episode(2, 4, 4, "Ep Name (2)")
            second_ep._status = Quality.compositeStatus(
                DOWNLOADED, Quality.HDTV)
            second_ep._release_name = ep.release_name

            third_ep = Episode(2, 5, 5, "Ep Name (3)")
            third_ep._status = Quality.compositeStatus(DOWNLOADED,
                                                       Quality.HDTV)
            third_ep._release_name = ep.release_name

            ep.relatedEps.append(second_ep)
            ep.relatedEps.append(third_ep)

    return ep
Example #5
0
 def test_HDWEBDL(self):
     self.assertEqual(
         Quality.HDWEBDL,
         Quality.nameQuality("Test.Show.S01E02.720p.WEB-DL-GROUP"))
     self.assertEqual(
         Quality.HDWEBDL,
         Quality.nameQuality("Test.Show.S01E02.720p.WEBRip-GROUP"))
     self.assertEqual(
         Quality.HDWEBDL,
         Quality.nameQuality(
             "Test.Show.S01E02.WEBRip.720p.H.264.AAC.2.0-GROUP"))
     self.assertEqual(
         Quality.HDWEBDL,
         Quality.nameQuality(
             "Test.Show.S01E02.720p.WEB-DL.AAC2.0.H.264-GROUP"))
     self.assertEqual(
         Quality.HDWEBDL,
         Quality.nameQuality(
             "Test Show S01E02 720p WEB-DL AAC2 0 H 264-GROUP"))
     self.assertEqual(
         Quality.HDWEBDL,
         Quality.nameQuality(
             "Test_Show.S01E02_720p_WEB-DL_AAC2.0_H264-GROUP"))
     self.assertEqual(
         Quality.HDWEBDL,
         Quality.nameQuality(
             "Test.Show.S01E02.720p.WEB-DL.AAC2.0.H264-GROUP"))
     self.assertEqual(
         Quality.HDWEBDL,
         Quality.nameQuality(
             "Test.Show.S01E02.720p.iTunes.Rip.H264.AAC-GROUP"))
Example #6
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)
Example #7
0
def generate_sample_ep(multi=None, abd=False, sports=False, anime_type=None):
    # make a fake episode object
    ep = Episode(2, 3, 3, "Ep Name")

    ep._status = Quality.compositeStatus(DOWNLOADED, Quality.HDTV)
    ep._airdate = date(2011, 3, 9)

    if abd:
        ep._release_name = "Show.Name.2011.03.09.HDTV.XviD-RLSGROUP"
        ep.show.air_by_date = 1
    elif sports:
        ep._release_name = "Show.Name.2011.03.09.HDTV.XviD-RLSGROUP"
        ep.show.sports = 1
    else:
        if anime_type != 3:
            ep.show.anime = 1
            ep._release_name = "Show.Name.003.HDTV.XviD-RLSGROUP"
        else:
            ep._release_name = "Show.Name.S02E03.HDTV.XviD-RLSGROUP"

    if multi is not None:
        ep._name = "Ep Name (1)"

        if anime_type != 3:
            ep.show.anime = 1

            ep._release_name = "Show.Name.003-004.HDTV.XviD-RLSGROUP"

            second_ep = Episode(2, 4, 4, "Ep Name (2)")
            second_ep._status = Quality.compositeStatus(DOWNLOADED, Quality.HDTV)
            second_ep._release_name = ep.release_name

            ep.relatedEps.append(second_ep)
        else:
            ep._release_name = "Show.Name.S02E03E04E05.HDTV.XviD-RLSGROUP"

            second_ep = Episode(2, 4, 4, "Ep Name (2)")
            second_ep._status = Quality.compositeStatus(DOWNLOADED, Quality.HDTV)
            second_ep._release_name = ep.release_name

            third_ep = Episode(2, 5, 5, "Ep Name (3)")
            third_ep._status = Quality.compositeStatus(DOWNLOADED, Quality.HDTV)
            third_ep._release_name = ep.release_name

            ep.relatedEps.append(second_ep)
            ep.relatedEps.append(third_ep)

    return ep
Example #8
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)
Example #9
0
    def logSnatch(searchResult):
        """
        Log history of snatch

        :param searchResult: search result object
        """
        for curEpObj in searchResult.episodes:

            showid = int(curEpObj.show.indexerid)
            season = int(curEpObj.season)
            episode = int(curEpObj.episode)
            quality = searchResult.quality
            version = searchResult.version

            providerClass = searchResult.provider
            if providerClass is not None:
                provider = providerClass.name
            else:
                provider = "unknown"

            action = Quality.compositeStatus(SNATCHED, searchResult.quality)

            resource = searchResult.name

            History._logHistoryItem(action, showid, season, episode, quality,
                                    resource, provider, version)
Example #10
0
    def logSnatch(searchResult):
        """
        Log history of snatch

        :param searchResult: search result object
        """
        for curEpObj in searchResult.episodes:

            showid = int(curEpObj.show.indexerid)
            season = int(curEpObj.season)
            episode = int(curEpObj.episode)
            quality = searchResult.quality
            version = searchResult.version

            providerClass = searchResult.provider
            if providerClass is not None:
                provider = providerClass.name
            else:
                provider = "unknown"

            action = Quality.compositeStatus(SNATCHED, searchResult.quality)

            resource = searchResult.name

            History._logHistoryItem(action, showid, season, episode, quality, resource, provider, version)
Example #11
0
def isFinalResult(result):
    """
    Checks if the given result is good enough quality that we can stop searching for other ones.

    If the result is the highest quality in both the any/best quality lists then this function
    returns True, if not then it's False
    """

    sickrage.srLogger.debug("Checking if we should keep searching after we've found " + result.name)

    show_obj = result.episodes[0].show

    any_qualities, best_qualities = Quality.splitQuality(show_obj.quality)

    # if there is a redownload that's higher than this then we definitely need to keep looking
    if best_qualities and result.quality < max(best_qualities):
        return False

    # if it does not match the shows black and white list its no good
    elif show_obj.is_anime and show_obj.release_groups.is_valid(result):
        return False

    # if there's no redownload that's higher (above) and this is the highest initial download then we're good
    elif any_qualities and result.quality in any_qualities:
        return True

    elif best_qualities and result.quality == max(best_qualities):
        return True

    # if we got here than it's either not on the lists, they're empty, or it's lower than the highest required
    else:
        return False
Example #12
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
Example #13
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)
Example #14
0
 def test_FULLHDWEBDL(self):
     self.assertEqual(
         Quality.FULLHDWEBDL,
         Quality.nameQuality("Test.Show.S01E02.1080p.WEB-DL-GROUP"))
     self.assertEqual(
         Quality.FULLHDWEBDL,
         Quality.nameQuality("Test.Show.S01E02.1080p.WEBRip-GROUP"))
     self.assertEqual(
         Quality.FULLHDWEBDL,
         Quality.nameQuality(
             "Test.Show.S01E02.WEBRip.1080p.H.264.AAC.2.0-GROUP"))
     self.assertEqual(
         Quality.FULLHDWEBDL,
         Quality.nameQuality(
             "Test.Show.S01E02.WEBRip.1080p.H264.AAC.2.0-GROUP"))
     self.assertEqual(
         Quality.FULLHDWEBDL,
         Quality.nameQuality(
             "Test.Show.S01E02.1080p.iTunes.H.264.AAC-GROUP"))
     self.assertEqual(
         Quality.FULLHDWEBDL,
         Quality.nameQuality(
             "Test Show S01E02 1080p iTunes H 264 AAC-GROUP"))
     self.assertEqual(
         Quality.FULLHDWEBDL,
         Quality.nameQuality(
             "Test_Show_S01E02_1080p_iTunes_H_264_AAC-GROUP"))
Example #15
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)
Example #16
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
Example #17
0
    def getQuality(self, item, anime=False):
        """
        Figures out the quality of the given RSS item node

        item: An elementtree.ElementTree element representing the <item> tag of the RSS feed

        Returns a Quality value obtained from the node's data
        """
        (title, url) = self._get_title_and_url(item)
        quality = Quality.sceneQuality(title, anime)
        return quality
Example #18
0
 def test_RAWHDTV(self):
     self.assertEqual(
         Quality.RAWHDTV,
         Quality.nameQuality(
             "Test.Show.S01E02.720p.HDTV.DD5.1.MPEG2-GROUP"))
     self.assertEqual(
         Quality.RAWHDTV,
         Quality.nameQuality(
             "Test.Show.S01E02.1080i.HDTV.DD2.0.MPEG2-GROUP"))
     self.assertEqual(
         Quality.RAWHDTV,
         Quality.nameQuality(
             "Test.Show.S01E02.1080i.HDTV.H.264.DD2.0-GROUP"))
     self.assertEqual(
         Quality.RAWHDTV,
         Quality.nameQuality(
             "Test Show - S01E02 - 1080i HDTV MPA1.0 H.264 - GROUP"))
     self.assertEqual(
         Quality.RAWHDTV,
         Quality.nameQuality(
             "Test.Show.S01E02.1080i.HDTV.DD.5.1.h264-GROUP"))
Example #19
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
Example #20
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
Example #21
0
 def test_HDWEBDL(self):
     self.assertEqual(Quality.HDWEBDL, Quality.nameQuality("Test.Show.S01E02.720p.WEB-DL-GROUP"))
     self.assertEqual(Quality.HDWEBDL, Quality.nameQuality("Test.Show.S01E02.720p.WEBRip-GROUP"))
     self.assertEqual(Quality.HDWEBDL,
                      Quality.nameQuality("Test.Show.S01E02.WEBRip.720p.H.264.AAC.2.0-GROUP"))
     self.assertEqual(Quality.HDWEBDL,
                      Quality.nameQuality("Test.Show.S01E02.720p.WEB-DL.AAC2.0.H.264-GROUP"))
     self.assertEqual(Quality.HDWEBDL,
                      Quality.nameQuality("Test Show S01E02 720p WEB-DL AAC2 0 H 264-GROUP"))
     self.assertEqual(Quality.HDWEBDL,
                      Quality.nameQuality("Test_Show.S01E02_720p_WEB-DL_AAC2.0_H264-GROUP"))
     self.assertEqual(Quality.HDWEBDL,
                      Quality.nameQuality("Test.Show.S01E02.720p.WEB-DL.AAC2.0.H264-GROUP"))
     self.assertEqual(Quality.HDWEBDL,
                      Quality.nameQuality("Test.Show.S01E02.720p.iTunes.Rip.H264.AAC-GROUP"))
Example #22
0
 def test_FULLHDWEBDL(self):
     self.assertEqual(Quality.FULLHDWEBDL, Quality.nameQuality("Test.Show.S01E02.1080p.WEB-DL-GROUP"))
     self.assertEqual(Quality.FULLHDWEBDL, Quality.nameQuality("Test.Show.S01E02.1080p.WEBRip-GROUP"))
     self.assertEqual(Quality.FULLHDWEBDL,
                      Quality.nameQuality("Test.Show.S01E02.WEBRip.1080p.H.264.AAC.2.0-GROUP"))
     self.assertEqual(Quality.FULLHDWEBDL,
                      Quality.nameQuality("Test.Show.S01E02.WEBRip.1080p.H264.AAC.2.0-GROUP"))
     self.assertEqual(Quality.FULLHDWEBDL,
                      Quality.nameQuality("Test.Show.S01E02.1080p.iTunes.H.264.AAC-GROUP"))
     self.assertEqual(Quality.FULLHDWEBDL,
                      Quality.nameQuality("Test Show S01E02 1080p iTunes H 264 AAC-GROUP"))
     self.assertEqual(Quality.FULLHDWEBDL,
                      Quality.nameQuality("Test_Show_S01E02_1080p_iTunes_H_264_AAC-GROUP"))
Example #23
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
Example #24
0
    def __init__(self, season, episode, absolute_number, name):
        self._name = name
        self._season = season
        self._episode = episode
        self._absolute_number = absolute_number
        self._airdate = date(2010, 3, 9)
        self._status = Quality.compositeStatus(DOWNLOADED, Quality.SDTV)
        self._release_name = 'Show.Name.S02E03.HDTV.XviD-RLSGROUP'
        self._release_group = 'RLSGROUP'
        self._is_proper = True

        self.show = Show()
        self.scene_season = season
        self.scene_episode = episode
        self.scene_absolute_number = absolute_number
        self.relatedEps = []
Example #25
0
def isFirstBestMatch(result):
    """
    Checks if the given result is a best quality match and if we want to archive the episode on first match.
    """

    sickrage.srLogger.debug("Checking if we should archive our first best quality match for for episode " + result.name)

    show_obj = result.episodes[0].show

    any_qualities, best_qualities = Quality.splitQuality(show_obj.quality)

    # if there is a redownload that's a match to one of our best qualities and we want to archive the episode then we are done
    if best_qualities and show_obj.archive_firstmatch and result.quality in best_qualities:
        return True

    return False
Example #26
0
    def _parse_string(self, name):
        if not name:
            return

        matches = []
        bestResult = None

        for (cur_regex_num, cur_regex_name, cur_regex) in self.compiled_regexes:
            match = cur_regex.match(name)

            if not match:
                continue

            result = ParseResult(name)
            result.which_regex = [cur_regex_name]
            result.score = 0 - cur_regex_num

            named_groups = match.groupdict().keys()

            if 'series_name' in named_groups:
                result.series_name = match.group('series_name')
                if result.series_name:
                    result.series_name = self.clean_series_name(result.series_name)
                    result.score += 1

            if 'series_num' in named_groups and match.group('series_num'):
                result.score += 1

            if 'season_num' in named_groups:
                tmp_season = int(match.group('season_num'))
                if cur_regex_name == 'bare' and tmp_season in (19, 20):
                    continue
                result.season_number = tmp_season
                result.score += 1

            if 'ep_num' in named_groups:
                ep_num = self._convert_number(match.group('ep_num'))
                if 'extra_ep_num' in named_groups and match.group('extra_ep_num'):
                    result.episode_numbers = range(ep_num, self._convert_number(match.group('extra_ep_num')) + 1)
                    result.score += 1
                else:
                    result.episode_numbers = [ep_num]
                result.score += 1

            if 'ep_ab_num' in named_groups:
                ep_ab_num = self._convert_number(match.group('ep_ab_num'))
                if 'extra_ab_ep_num' in named_groups and match.group('extra_ab_ep_num'):
                    result.ab_episode_numbers = range(ep_ab_num,
                                                      self._convert_number(match.group('extra_ab_ep_num')) + 1)
                    result.score += 1
                else:
                    result.ab_episode_numbers = [ep_ab_num]
                result.score += 1

            if 'air_date' in named_groups:
                air_date = match.group('air_date')
                try:
                    result.air_date = parser.parse(air_date, fuzzy=True).date()
                    result.score += 1
                except Exception:
                    continue

            if 'extra_info' in named_groups:
                tmp_extra_info = match.group('extra_info')

                # Show.S04.Special or Show.S05.Part.2.Extras is almost certainly not every episode in the season
                if tmp_extra_info and cur_regex_name == 'season_only' and re.search(
                        r'([. _-]|^)(special|extra)s?\w*([. _-]|$)', tmp_extra_info, re.I):
                    continue
                result.extra_info = tmp_extra_info
                result.score += 1

            if 'release_group' in named_groups:
                result.release_group = match.group('release_group')
                result.score += 1

            if 'version' in named_groups:
                # assigns version to anime file if detected using anime regex. Non-anime regex receives -1
                version = match.group('version')
                if version:
                    result.version = version
                else:
                    result.version = 1
            else:
                result.version = -1

            matches.append(result)

        if len(matches):
            # pick best match with highest score based on placement
            bestResult = max(sorted(matches, reverse=True, key=lambda x: x.which_regex), key=lambda x: x.score)

            show = None
            if not self.naming_pattern:
                # try and create a show object for this result
                show = self.get_show(bestResult.series_name, self.tryIndexers)

            # confirm passed in show object indexer id matches result show object indexer id
            if show:
                if self.showObj and show.indexerid != self.showObj.indexerid:
                    show = None
                bestResult.show = show
            elif not show and self.showObj:
                bestResult.show = self.showObj

            # if this is a naming pattern test or result doesn't have a show object then return best result
            if not bestResult.show or self.naming_pattern:
                return bestResult

            # get quality
            bestResult.quality = Quality.nameQuality(name, bestResult.show.is_anime)

            new_episode_numbers = []
            new_season_numbers = []
            new_absolute_numbers = []

            # if we have an air-by-date show then get the real season/episode numbers
            if bestResult.is_air_by_date:
                from core.databases import main_db
                airdate = bestResult.air_date.toordinal()
                sql_result = main_db.MainDB().select(
                        "SELECT season, episode FROM tv_episodes WHERE showid = ? AND indexer = ? AND airdate = ?",
                        [bestResult.show.indexerid, bestResult.show.indexer, airdate])

                season_number = None
                episode_numbers = []

                if sql_result:
                    season_number = int(sql_result[0][0])
                    episode_numbers = [int(sql_result[0][1])]

                if not season_number or not len(episode_numbers):
                    try:
                        lINDEXER_API_PARMS = sickrage.srCore.INDEXER_API(bestResult.show.indexer).api_params.copy()

                        if bestResult.show.lang:
                            lINDEXER_API_PARMS[b'language'] = bestResult.show.lang

                        t = sickrage.srCore.INDEXER_API(bestResult.show.indexer).indexer(**lINDEXER_API_PARMS)

                        epObj = t[bestResult.show.indexerid].airedOn(bestResult.air_date)[0]

                        season_number = int(epObj[b"seasonnumber"])
                        episode_numbers = [int(epObj[b"episodenumber"])]
                    except indexer_episodenotfound:
                        sickrage.srLogger.warning(
                                "Unable to find episode with date " + bestResult.air_date + " for show " + bestResult.show.name + ", skipping")
                        episode_numbers = []
                    except indexer_error as e:
                        sickrage.srLogger.warning(
                                "Unable to contact " + sickrage.srCore.INDEXER_API(bestResult.show.indexer).name + ": {}".format(
                                        e))
                        episode_numbers = []

                for epNo in episode_numbers:
                    s = season_number
                    e = epNo

                    if bestResult.show.is_scene:
                        (s, e) = get_indexer_numbering(bestResult.show.indexerid,
                                                       bestResult.show.indexer,
                                                       season_number,
                                                       epNo)
                    new_episode_numbers.append(e)
                    new_season_numbers.append(s)

            elif bestResult.show.is_anime and len(bestResult.ab_episode_numbers):
                scene_season = get_scene_exception_by_name(bestResult.series_name)[1]
                for epAbsNo in bestResult.ab_episode_numbers:
                    a = epAbsNo

                    if bestResult.show.is_scene:
                        a = get_indexer_absolute_numbering(bestResult.show.indexerid,
                                                           bestResult.show.indexer, epAbsNo,
                                                           True, scene_season)

                    (s, e) = get_all_episodes_from_absolute_number(bestResult.show, [a])

                    new_absolute_numbers.append(a)
                    new_episode_numbers.extend(e)
                    new_season_numbers.append(s)

            elif bestResult.season_number and len(bestResult.episode_numbers):
                for epNo in bestResult.episode_numbers:
                    s = bestResult.season_number
                    e = epNo

                    if bestResult.show.is_scene:
                        (s, e) = get_indexer_numbering(bestResult.show.indexerid,
                                                       bestResult.show.indexer,
                                                       bestResult.season_number,
                                                       epNo)
                    if bestResult.show.is_anime:
                        a = get_absolute_number_from_season_and_episode(bestResult.show, s, e)
                        if a:
                            new_absolute_numbers.append(a)

                    new_episode_numbers.append(e)
                    new_season_numbers.append(s)

            # need to do a quick sanity check heregex.  It's possible that we now have episodes
            # from more than one season (by tvdb numbering), and this is just too much
            # for sickrage, so we'd need to flag it.
            new_season_numbers = list(set(new_season_numbers))  # remove duplicates
            if len(new_season_numbers) > 1:
                raise InvalidNameException("Scene numbering results episodes from "
                                           "seasons %s, (i.e. more than one) and "
                                           "sickrage does not support this.  "
                                           "Sorry." % (new_season_numbers))

            # I guess it's possible that we'd have duplicate episodes too, so lets
            # eliminate them
            new_episode_numbers = list(set(new_episode_numbers))
            new_episode_numbers.sort()

            # maybe even duplicate absolute numbers so why not do them as well
            new_absolute_numbers = list(set(new_absolute_numbers))
            new_absolute_numbers.sort()

            if len(new_absolute_numbers):
                bestResult.ab_episode_numbers = new_absolute_numbers

            if len(new_season_numbers) and len(new_episode_numbers):
                bestResult.episode_numbers = new_episode_numbers
                bestResult.season_number = new_season_numbers[0]

            if bestResult.show.is_scene:
                sickrage.srLogger.debug("Converted parsed result {} into {}".format(bestResult.original_name, bestResult))

        # CPU sleep
        time.sleep(1)

        return bestResult
Example #27
0
def pickBestResult(results, show):
    """
    Find the best result out of a list of search results for a show

    :param results: list of result objects
    :param show: Shows we check for
    :return: best result object
    """
    results = results if isinstance(results, list) else [results]

    sickrage.srLogger.debug("Picking the best result out of " + str([x.name for x in results]))

    bestResult = None

    # find the best result for the current episode
    for cur_result in results:
        if show and cur_result.show is not show:
            continue

        # build the black And white list
        if show.is_anime:
            if not show.release_groups.is_valid(cur_result):
                continue

        sickrage.srLogger.info("Quality of " + cur_result.name + " is " + Quality.qualityStrings[cur_result.quality])

        anyQualities, bestQualities = Quality.splitQuality(show.quality)

        if cur_result.quality not in anyQualities + bestQualities:
            sickrage.srLogger.debug(cur_result.name + " is a quality we know we don't want, rejecting it")
            continue

        if show.rls_ignore_words and show_names.containsAtLeastOneWord(cur_result.name,
                                                                       cur_result.show.rls_ignore_words):
            sickrage.srLogger.info(
                    "Ignoring " + cur_result.name + " based on ignored words filter: " + show.rls_ignore_words)
            continue

        if show.rls_require_words and not show_names.containsAtLeastOneWord(cur_result.name,
                                                                            cur_result.show.rls_require_words):
            sickrage.srLogger.info(
                    "Ignoring " + cur_result.name + " based on required words filter: " + show.rls_require_words)
            continue

        if not show_names.filterBadReleases(cur_result.name, parse=False):
            sickrage.srLogger.info(
                    "Ignoring " + cur_result.name + " because its not a valid scene release that we want, ignoring it")
            continue

        if hasattr(cur_result, 'size'):
            if sickrage.srConfig.USE_FAILED_DOWNLOADS and FailedHistory.hasFailed(cur_result.name, cur_result.size,
                                                                                   cur_result.provider.name):
                sickrage.srLogger.info(cur_result.name + " has previously failed, rejecting it")
                continue

        if not bestResult:
            bestResult = cur_result
        elif cur_result.quality in bestQualities and (
                        bestResult.quality < cur_result.quality or bestResult.quality not in bestQualities):
            bestResult = cur_result
        elif cur_result.quality in anyQualities and bestResult.quality not in bestQualities and bestResult.quality < cur_result.quality:
            bestResult = cur_result
        elif bestResult.quality == cur_result.quality:
            if "proper" in cur_result.name.lower() or "repack" in cur_result.name.lower():
                bestResult = cur_result
            elif "internal" in bestResult.name.lower() and "internal" not in cur_result.name.lower():
                bestResult = cur_result
            elif "xvid" in bestResult.name.lower() and "x264" in cur_result.name.lower():
                sickrage.srLogger.info("Preferring " + cur_result.name + " (x264 over xvid)")
                bestResult = cur_result

    if bestResult:
        sickrage.srLogger.debug("Picked " + bestResult.name + " as the best")
    else:
        sickrage.srLogger.debug("No result picked.")

    return bestResult
Example #28
0
 def test_SDTV(self):
     self.assertEqual(
         Quality.SDTV,
         Quality.nameQuality("Test.Show.S01E02.PDTV.XViD-GROUP"))
     self.assertEqual(
         Quality.SDTV,
         Quality.nameQuality("Test.Show.S01E02.PDTV.x264-GROUP"))
     self.assertEqual(
         Quality.SDTV,
         Quality.nameQuality("Test.Show.S01E02.HDTV.XViD-GROUP"))
     self.assertEqual(
         Quality.SDTV,
         Quality.nameQuality("Test.Show.S01E02.HDTV.x264-GROUP"))
     self.assertEqual(
         Quality.SDTV,
         Quality.nameQuality("Test.Show.S01E02.DSR.XViD-GROUP"))
     self.assertEqual(
         Quality.SDTV,
         Quality.nameQuality("Test.Show.S01E02.DSR.x264-GROUP"))
     self.assertEqual(
         Quality.SDTV,
         Quality.nameQuality("Test.Show.S01E02.TVRip.XViD-GROUP"))
     self.assertEqual(
         Quality.SDTV,
         Quality.nameQuality("Test.Show.S01E02.TVRip.x264-GROUP"))
     self.assertEqual(
         Quality.SDTV,
         Quality.nameQuality("Test.Show.S01E02.WEBRip.XViD-GROUP"))
     self.assertEqual(
         Quality.SDTV,
         Quality.nameQuality("Test.Show.S01E02.WEBRip.x264-GROUP"))
     self.assertEqual(
         Quality.SDTV,
         Quality.nameQuality("Test.Show.S01E02.WEB-DL.x264-GROUP"))
     self.assertEqual(
         Quality.SDTV,
         Quality.nameQuality("Test.Show.S01E02.WEB-DL.AAC2.0.H.264-GROUP"))
     self.assertEqual(
         Quality.SDTV,
         Quality.nameQuality("Test.Show.S01E02 WEB-DL H 264-GROUP"))
     self.assertEqual(
         Quality.SDTV,
         Quality.nameQuality("Test.Show.S01E02_WEB-DL_H_264-GROUP"))
     self.assertEqual(
         Quality.SDTV,
         Quality.nameQuality("Test.Show.S01E02.WEB-DL.AAC2.0.H264-GROUP"))
Example #29
0
 def test_SDDVD(self):
     self.assertEqual(
         Quality.SDDVD,
         Quality.nameQuality("Test.Show.S01E02.DVDRiP.XViD-GROUP"))
     self.assertEqual(
         Quality.SDDVD,
         Quality.nameQuality("Test.Show.S01E02.DVDRiP.DiVX-GROUP"))
     self.assertEqual(
         Quality.SDDVD,
         Quality.nameQuality("Test.Show.S01E02.DVDRiP.x264-GROUP"))
     self.assertEqual(
         Quality.SDDVD,
         Quality.nameQuality("Test.Show.S01E02.DVDRip.WS.XViD-GROUP"))
     self.assertEqual(
         Quality.SDDVD,
         Quality.nameQuality("Test.Show.S01E02.DVDRip.WS.DiVX-GROUP"))
     self.assertEqual(
         Quality.SDDVD,
         Quality.nameQuality("Test.Show.S01E02.DVDRip.WS.x264-GROUP"))
     self.assertEqual(
         Quality.SDDVD,
         Quality.nameQuality("Test.Show.S01E02.BDRIP.XViD-GROUP"))
     self.assertEqual(
         Quality.SDDVD,
         Quality.nameQuality("Test.Show.S01E02.BDRIP.DiVX-GROUP"))
     self.assertEqual(
         Quality.SDDVD,
         Quality.nameQuality("Test.Show.S01E02.BDRIP.x264-GROUP"))
     self.assertEqual(
         Quality.SDDVD,
         Quality.nameQuality("Test.Show.S01E02.BDRIP.WS.XViD-GROUP"))
     self.assertEqual(
         Quality.SDDVD,
         Quality.nameQuality("Test.Show.S01E02.BDRIP.WS.DiVX-GROUP"))
     self.assertEqual(
         Quality.SDDVD,
         Quality.nameQuality("Test.Show.S01E02.BDRIP.WS.x264-GROUP"))
Example #30
0
    def _doSearch(self,
                  search_params,
                  search_mode='eponly',
                  epcount=0,
                  age=0,
                  epObj=None):

        results = []
        items = {'Season': [], 'Episode': [], 'RSS': []}

        self.categories = "cat=" + str(self.cat)

        if not self._doLogin():
            return results

        for mode in search_params.keys():
            sickrage.srLogger.debug("Search Mode: %s" % mode)
            for search_string in search_params[mode]:

                if mode is 'RSS':
                    self.page = 2

                last_page = 0
                y = int(self.page)

                if search_string == '':
                    continue

                search_string = str(search_string).replace('.', ' ')

                for x in range(0, y):
                    z = x * 20
                    if last_page:
                        break

                    if mode is not 'RSS':
                        searchURL = (self.urls['search_page'] +
                                     '&filter={2}').format(
                                         z, self.categories, search_string)
                    else:
                        searchURL = self.urls['search_page'].format(
                            z, self.categories)

                    if mode is not 'RSS':
                        sickrage.srLogger.debug("Search string: %s " %
                                                search_string)

                    sickrage.srLogger.debug("Search URL: %s" % searchURL)
                    data = self.getURL(searchURL)
                    if not data:
                        sickrage.srLogger.debug(
                            "No data returned from provider")
                        continue

                    try:
                        with bs4_parser(data) as html:
                            torrent_table = html.find(
                                'table', attrs={'class': 'copyright'})
                            torrent_rows = torrent_table.find_all(
                                'tr') if torrent_table else []

                            # Continue only if one Release is found
                            if len(torrent_rows) < 3:
                                sickrage.srLogger.debug(
                                    "Data returned from provider does not contain any torrents"
                                )
                                last_page = 1
                                continue

                            if len(torrent_rows) < 42:
                                last_page = 1

                            for result in torrent_table.find_all('tr')[2:]:

                                try:
                                    link = result.find('td').find('a')
                                    title = link.string
                                    download_url = self.urls[
                                        'download'] % result.find_all(
                                            'td')[8].find('a')['href'][-8:]
                                    leechers = result.find_all(
                                        'td')[3].find_all('td')[1].text
                                    leechers = int(leechers.strip('[]'))
                                    seeders = result.find_all(
                                        'td')[3].find_all('td')[2].text
                                    seeders = int(seeders.strip('[]'))
                                    # FIXME
                                    size = -1
                                except (AttributeError, TypeError):
                                    continue

                                filename_qt = self._reverseQuality(
                                    self._episodeQuality(result))
                                for text in self.hdtext:
                                    title1 = title
                                    title = title.replace(text, filename_qt)
                                    if title != title1:
                                        break

                                if Quality.nameQuality(
                                        title) == Quality.UNKNOWN:
                                    title += filename_qt

                                if not self._is_italian(
                                        result) and not self.subtitle:
                                    sickrage.srLogger.debug(
                                        "Torrent is subtitled, skipping: %s " %
                                        title)
                                    continue

                                if self.engrelease and not self._is_english(
                                        result):
                                    sickrage.srLogger.debug(
                                        "Torrent isnt english audio/subtitled , skipping: %s "
                                        % title)
                                    continue

                                search_show = re.split(r'([Ss][\d{1,2}]+)',
                                                       search_string)[0]
                                show_title = search_show
                                rindex = re.search(r'([Ss][\d{1,2}]+)', title)
                                if rindex:
                                    show_title = title[:rindex.start()]
                                    ep_params = title[rindex.start():]

                                if show_title.lower() != search_show.lower() \
                                        and search_show.lower() in show_title.lower() and ep_params:
                                    title = search_show + ep_params

                                if not all([title, download_url]):
                                    continue

                                if self._is_season_pack(title):
                                    title = re.sub(r'([Ee][\d{1,2}\-?]+)', '',
                                                   title)

                                # Filter unseeded torrent
                                if seeders < self.minseed or leechers < self.minleech:
                                    if mode is not 'RSS':
                                        sickrage.srLogger.debug(
                                            "Discarding torrent because it doesn't meet the minimum seeders or leechers: {0} (S:{1} L:{2})"
                                            .format(title, seeders, leechers))
                                    continue

                                item = title, download_url, size, seeders, leechers
                                if mode is not 'RSS':
                                    sickrage.srLogger.debug(
                                        "Found result: %s " % title)

                                items[mode].append(item)

                    except Exception:
                        sickrage.srLogger.error(
                            "Failed parsing provider. Traceback: %s" %
                            traceback.format_exc())

                # For each search mode sort all the items by seeders if available if available
                items[mode].sort(key=lambda tup: tup[3], reverse=True)

                results += items[mode]

        return results
Example #31
0
 def test_UNKNOWN(self):
     self.assertEqual(Quality.UNKNOWN,
                      Quality.nameQuality("Test.Show.S01E02-SiCKBEARD"))
Example #32
0
 def test_UNKNOWN(self):
     self.assertEqual(Quality.UNKNOWN, Quality.nameQuality("Test.Show.S01E02-SiCKBEARD"))
Example #33
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
Example #34
0
 def test_SDTV(self):
     self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.PDTV.XViD-GROUP"))
     self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.PDTV.x264-GROUP"))
     self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.HDTV.XViD-GROUP"))
     self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.HDTV.x264-GROUP"))
     self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.DSR.XViD-GROUP"))
     self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.DSR.x264-GROUP"))
     self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.TVRip.XViD-GROUP"))
     self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.TVRip.x264-GROUP"))
     self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.WEBRip.XViD-GROUP"))
     self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.WEBRip.x264-GROUP"))
     self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.WEB-DL.x264-GROUP"))
     self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.WEB-DL.AAC2.0.H.264-GROUP"))
     self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02 WEB-DL H 264-GROUP"))
     self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02_WEB-DL_H_264-GROUP"))
     self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.WEB-DL.AAC2.0.H264-GROUP"))
Example #35
0
 def test_FULLHDTV(self):
     self.assertEqual(
         Quality.FULLHDTV,
         Quality.nameQuality("Test.Show.S01E02.1080p.HDTV.x264-GROUP"))
Example #36
0
 def test_SDDVD(self):
     self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRiP.XViD-GROUP"))
     self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRiP.DiVX-GROUP"))
     self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRiP.x264-GROUP"))
     self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRip.WS.XViD-GROUP"))
     self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRip.WS.DiVX-GROUP"))
     self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRip.WS.x264-GROUP"))
     self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.XViD-GROUP"))
     self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.DiVX-GROUP"))
     self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.x264-GROUP"))
     self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.WS.XViD-GROUP"))
     self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.WS.DiVX-GROUP"))
     self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.WS.x264-GROUP"))
Example #37
0
    def _doSearch(self, search_params, search_mode='eponly', epcount=0, age=0, epObj=None):

        results = []
        items = {'Season': [], 'Episode': [], 'RSS': []}

        self.categories = "cat=" + str(self.cat)

        if not self._doLogin():
            return results

        for mode in search_params.keys():
            sickrage.srLogger.debug("Search Mode: %s" % mode)
            for search_string in search_params[mode]:

                if mode is 'RSS':
                    self.page = 2

                last_page = 0
                y = int(self.page)

                if search_string == '':
                    continue

                search_string = str(search_string).replace('.', ' ')

                for x in range(0, y):
                    z = x * 20
                    if last_page:
                        break

                    if mode is not 'RSS':
                        searchURL = (self.urls['search_page'] + '&filter={2}').format(z, self.categories,
                                                                                      search_string)
                    else:
                        searchURL = self.urls['search_page'].format(z, self.categories)

                    if mode is not 'RSS':
                        sickrage.srLogger.debug("Search string: %s " % search_string)

                    sickrage.srLogger.debug("Search URL: %s" % searchURL)
                    data = self.getURL(searchURL)
                    if not data:
                        sickrage.srLogger.debug("No data returned from provider")
                        continue

                    try:
                        with bs4_parser(data) as html:
                            torrent_table = html.find('table', attrs={'class': 'copyright'})
                            torrent_rows = torrent_table.find_all('tr') if torrent_table else []

                            # Continue only if one Release is found
                            if len(torrent_rows) < 3:
                                sickrage.srLogger.debug("Data returned from provider does not contain any torrents")
                                last_page = 1
                                continue

                            if len(torrent_rows) < 42:
                                last_page = 1

                            for result in torrent_table.find_all('tr')[2:]:

                                try:
                                    link = result.find('td').find('a')
                                    title = link.string
                                    download_url = self.urls['download'] % result.find_all('td')[8].find('a')['href'][
                                                                           -8:]
                                    leechers = result.find_all('td')[3].find_all('td')[1].text
                                    leechers = int(leechers.strip('[]'))
                                    seeders = result.find_all('td')[3].find_all('td')[2].text
                                    seeders = int(seeders.strip('[]'))
                                    # FIXME
                                    size = -1
                                except (AttributeError, TypeError):
                                    continue

                                filename_qt = self._reverseQuality(self._episodeQuality(result))
                                for text in self.hdtext:
                                    title1 = title
                                    title = title.replace(text, filename_qt)
                                    if title != title1:
                                        break

                                if Quality.nameQuality(title) == Quality.UNKNOWN:
                                    title += filename_qt

                                if not self._is_italian(result) and not self.subtitle:
                                    sickrage.srLogger.debug("Torrent is subtitled, skipping: %s " % title)
                                    continue

                                if self.engrelease and not self._is_english(result):
                                    sickrage.srLogger.debug("Torrent isnt english audio/subtitled , skipping: %s " % title)
                                    continue

                                search_show = re.split(r'([Ss][\d{1,2}]+)', search_string)[0]
                                show_title = search_show
                                rindex = re.search(r'([Ss][\d{1,2}]+)', title)
                                if rindex:
                                    show_title = title[:rindex.start()]
                                    ep_params = title[rindex.start():]

                                if show_title.lower() != search_show.lower() \
                                        and search_show.lower() in show_title.lower() and ep_params:
                                    title = search_show + ep_params

                                if not all([title, download_url]):
                                    continue

                                if self._is_season_pack(title):
                                    title = re.sub(r'([Ee][\d{1,2}\-?]+)', '', title)

                                # Filter unseeded torrent
                                if seeders < self.minseed or leechers < self.minleech:
                                    if mode is not 'RSS':
                                        sickrage.srLogger.debug(
                                                "Discarding torrent because it doesn't meet the minimum seeders or leechers: {0} (S:{1} L:{2})".format(
                                                        title, seeders, leechers))
                                    continue

                                item = title, download_url, size, seeders, leechers
                                if mode is not 'RSS':
                                    sickrage.srLogger.debug("Found result: %s " % title)

                                items[mode].append(item)

                    except Exception:
                        sickrage.srLogger.error("Failed parsing provider. Traceback: %s" % traceback.format_exc())

                # For each search mode sort all the items by seeders if available if available
                items[mode].sort(key=lambda tup: tup[3], reverse=True)

                results += items[mode]

        return results
Example #38
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
Example #39
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
Example #40
0
 def test_FULLHDBLURAY(self):
     self.assertEqual(Quality.FULLHDBLURAY,
                      Quality.nameQuality("Test.Show.S01E02.1080p.BluRay.x264-GROUP"))
     self.assertEqual(Quality.FULLHDBLURAY,
                      Quality.nameQuality("Test.Show.S01E02.1080p.HDDVD.x264-GROUP"))
Example #41
0
 def test_FULLHDTV(self):
     self.assertEqual(Quality.FULLHDTV, Quality.nameQuality("Test.Show.S01E02.1080p.HDTV.x264-GROUP"))
Example #42
0
 def test_HDTV(self):
     self.assertEqual(Quality.HDTV, Quality.nameQuality("Test.Show.S01E02.720p.HDTV.x264-GROUP"))
     self.assertEqual(Quality.HDTV, Quality.nameQuality("Test.Show.S01E02.HR.WS.PDTV.x264-GROUP"))
Example #43
0
def snatchEpisode(result, endStatus=SNATCHED):
    """
    Contains the internal logic necessary to actually "snatch" a result that
    has been found.

    :param result: SearchResult instance to be snatched.
    :param endStatus: the episode status that should be used for the episode object once it's snatched.
    :return: boolean, True on success
    """

    if result is None:
        return False

    result.priority = 0  # -1 = low, 0 = normal, 1 = high
    if sickrage.srConfig.ALLOW_HIGH_PRIORITY:
        # if it aired recently make it high priority
        for curEp in result.episodes:
            if date.today() - curEp.airdate <= timedelta(days=7):
                result.priority = 1
    if re.search(r'(^|[\. _-])(proper|repack)([\. _-]|$)', result.name, re.I) is not None:
        endStatus = SNATCHED_PROPER

    if result.url.startswith('magnet') or result.url.endswith('torrent'):
        result.resultType = 'torrent'

    # NZBs can be sent straight to SAB or saved to disk
    if result.resultType in ("nzb", "nzbdata"):
        if sickrage.srConfig.NZB_METHOD == "blackhole":
            dlResult = _downloadResult(result)
        elif sickrage.srConfig.NZB_METHOD == "sabnzbd":
            dlResult = SabNZBd.sendNZB(result)
        elif sickrage.srConfig.NZB_METHOD == "nzbget":
            is_proper = True if endStatus == SNATCHED_PROPER else False
            dlResult = NZBGet.sendNZB(result, is_proper)
        else:
            sickrage.srLogger.error("Unknown NZB action specified in config: " + sickrage.srConfig.NZB_METHOD)
            dlResult = False

    # TORRENTs can be sent to clients or saved to disk
    elif result.resultType == "torrent":
        # torrents are saved to disk when blackhole mode
        if sickrage.srConfig.TORRENT_METHOD == "blackhole":
            dlResult = _downloadResult(result)
        else:
            if not result.content and not result.url.startswith('magnet'):
                result.content = result.provider.getURL(result.url, needBytes=True)

            if result.content or result.url.startswith('magnet'):
                client = getClientIstance(sickrage.srConfig.TORRENT_METHOD)()
                dlResult = client.sendTORRENT(result)
            else:
                sickrage.srLogger.warning("Torrent file content is empty")
                dlResult = False
    else:
        sickrage.srLogger.error("Unknown result type, unable to download it (%r)" % result.resultType)
        dlResult = False

    if not dlResult:
        return False

    if sickrage.srConfig.USE_FAILED_DOWNLOADS:
        FailedHistory.logSnatch(result)

    notifications.message('Episode snatched', result.name)

    History.logSnatch(result)

    # don't notify when we re-download an episode
    sql_l = []
    trakt_data = []
    for curEpObj in result.episodes:
        with curEpObj.lock:
            if isFirstBestMatch(result):
                curEpObj.status = Quality.compositeStatus(SNATCHED_BEST, result.quality)
            else:
                curEpObj.status = Quality.compositeStatus(endStatus, result.quality)

            sql_q = curEpObj.saveToDB(False)
            if sql_q:
                sql_l.append(sql_q)
                del sql_q  # cleanup

        if curEpObj.status not in Quality.DOWNLOADED:
            try:
                srNotifiers.notify_snatch(
                        curEpObj._format_pattern('%SN - %Sx%0E - %EN - %QN') + " from " + result.provider.name)
            except:
                sickrage.srLogger.debug("Failed to send snatch notification")

            trakt_data.append((curEpObj.season, curEpObj.episode))

    data = sickrage.srCore.NOTIFIERS.trakt_notifier.trakt_episode_data_generate(trakt_data)

    if sickrage.srConfig.USE_TRAKT and sickrage.srConfig.TRAKT_SYNC_WATCHLIST:
        sickrage.srLogger.debug("Add episodes, showid: indexerid " + str(result.show.indexerid) + ", Title " + str(
                result.show.name) + " to Traktv Watchlist")
        if data:
            sickrage.srCore.NOTIFIERS.trakt_notifier.update_watchlist(result.show, data_episode=data, update="add")

    if len(sql_l) > 0:
        main_db.MainDB().mass_upsert(sql_l)
        del sql_l  # cleanup

    return True
Example #44
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