예제 #1
0
    def search_cache(self, show_id, season, episode, manualSearch=False, downCurQuality=False):
        cache_results = {}
        dbData = []

        # get data from external database
        if sickrage.app.config.enable_api_providers_cache and not self.provider.private:
            try:
                dbData += sickrage.app.api.provider_cache.get(self.providerID, show_id, season, episode)['data']
            except Exception:
                pass

        # get data from internal database
        session = sickrage.app.cache_db.session()
        dbData += [x.as_dict() for x in session.query(CacheDB.Provider).filter_by(provider=self.providerID, series_id=show_id, season=season).filter(
            CacheDB.Provider.episodes.contains("|{}|".format(episode)))]

        for curResult in dbData:
            show_object = find_show(int(curResult["series_id"]))
            if not show_object:
                continue

            result = self.provider.get_result()

            # ignore invalid and private IP address urls
            if not validate_url(curResult["url"]):
                if not curResult["url"].startswith('magnet'):
                    continue
            elif is_ip_private(curResult["url"].split(r'//')[-1].split(r'/')[0]):
                continue

            # ignored/required words, and non-tv junk
            if not show_names.filter_bad_releases(curResult["name"]):
                continue

            # get the show object, or if it's not one of our shows then ignore it
            result.show_id = int(curResult["series_id"])

            # skip if provider is anime only and show is not anime
            if self.provider.anime_only and not show_object.is_anime:
                sickrage.app.log.debug("" + str(show_object.name) + " is not an anime, skiping")
                continue

            # get season and ep data (ignoring multi-eps for now)
            curSeason = int(curResult["season"])
            if curSeason == -1:
                continue

            result.season = curSeason
            result.episodes = [int(curEp) for curEp in filter(None, curResult["episodes"].split("|"))]

            result.quality = int(curResult["quality"])
            result.release_group = curResult["release_group"]
            result.version = curResult["version"]

            # make sure we want the episode
            wantEp = False
            for result_episode in result.episodes:
                if show_object.want_episode(result.season, result_episode, result.quality, manualSearch, downCurQuality):
                    wantEp = True

            if not wantEp:
                sickrage.app.log.info("Skipping " + curResult["name"] + " because we don't want an episode that's " + Quality.qualityStrings[result.quality])
                continue

            # build a result object
            result.name = curResult["name"]
            result.url = curResult["url"]

            sickrage.app.log.info("Found cached {} result {}".format(result.type, result.name))

            result.seeders = curResult.get("seeders", -1)
            result.leechers = curResult.get("leechers", -1)
            result.size = curResult.get("size", -1)
            result.content = None

            # add it to the list
            if episode not in cache_results:
                cache_results[int(episode)] = [result]
            else:
                cache_results[int(episode)] += [result]

        # datetime stamp this search so cache gets cleared
        self.last_search = datetime.datetime.today()

        return cache_results
예제 #2
0
def pick_best_result(results, season_pack=False):
    """
    Find the best result out of a list of search results for a show

    :param results: list of result objects
    :param show_id: Show ID we check for
    :return: best result object
    """

    results = results if isinstance(results, list) else [results]

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

    best_result = None

    # find the best result for the current episode
    for cur_result in results:
        show_obj = find_show(cur_result.show_id)

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

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

        any_qualities, best_qualities = Quality.split_quality(show_obj.quality)
        if cur_result.quality not in any_qualities + best_qualities:
            sickrage.app.log.debug(
                cur_result.name +
                " is a quality we know we don't want, rejecting it")
            continue

        # check if seeders meet out minimum requirements, disgard result if it does not
        if hasattr(cur_result.provider,
                   'minseed') and cur_result.seeders not in (-1, None):
            if int(cur_result.seeders) < min(cur_result.provider.minseed, 1):
                sickrage.app.log.info(
                    "Discarding torrent because it doesn't meet the minimum seeders: {}. Seeders:  "
                    "{}".format(cur_result.name, cur_result.seeders))
                continue

        # check if leechers meet out minimum requirements, disgard result if it does not
        if hasattr(cur_result.provider,
                   'minleech') and cur_result.leechers not in (-1, None):
            if int(cur_result.leechers) < min(cur_result.provider.minleech, 0):
                sickrage.app.log.info(
                    "Discarding torrent because it doesn't meet the minimum leechers: {}. Leechers:  "
                    "{}".format(cur_result.name, cur_result.leechers))
                continue

        if show_obj.rls_ignore_words and show_names.contains_at_least_one_word(
                cur_result.name, show_obj.rls_ignore_words):
            sickrage.app.log.info("Ignoring " + cur_result.name +
                                  " based on ignored words filter: " +
                                  show_obj.rls_ignore_words)
            continue

        if show_obj.rls_require_words and not show_names.contains_at_least_one_word(
                cur_result.name, show_obj.rls_require_words):
            sickrage.app.log.info("Ignoring " + cur_result.name +
                                  " based on required words filter: " +
                                  show_obj.rls_require_words)
            continue

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

        if hasattr(cur_result, 'size'):
            if FailedHistory.has_failed(cur_result.name, cur_result.size,
                                        cur_result.provider.name):
                sickrage.app.log.info(cur_result.name +
                                      " has previously failed, rejecting it")
                continue

            # quality definition video file size constraints check
            try:
                if cur_result.size:
                    quality_size = sickrage.app.config.quality_sizes[
                        cur_result.quality]

                    if season_pack and not len(cur_result.episodes):
                        episode_count = len([
                            x for x in show_obj.episodes
                            if x.season == cur_result.season
                        ])
                        file_size = float(cur_result.size / episode_count /
                                          1000000)
                    else:
                        file_size = float(cur_result.size /
                                          len(cur_result.episodes) / 1000000)

                    if file_size > quality_size:
                        raise Exception(
                            "Ignoring " + cur_result.name +
                            " with size: {} based on quality size filter: {}".
                            format(file_size, quality_size))
            except Exception as e:
                sickrage.app.log.info(e)
                continue

        # verify result content
        # if not cur_result.provider.private:
        #     if cur_result.type in ["nzb", "torrent"] and not cur_result.provider.get_content(cur_result.url):
        #         if not sickrage.app.config.download_unverified_magnet_link and cur_result.url.startswith('magnet'):
        #             sickrage.app.log.info("Ignoring {} because we are unable to verify the download url".format(cur_result.name))
        #             continue

        if not best_result:
            best_result = cur_result
        elif cur_result.quality in best_qualities and (
                best_result.quality < cur_result.quality
                or best_result.quality not in best_qualities):
            best_result = cur_result
        elif cur_result.quality in any_qualities and best_result.quality not in best_qualities and best_result.quality < cur_result.quality:
            best_result = cur_result
        elif best_result.quality == cur_result.quality:
            if "proper" in cur_result.name.lower(
            ) or "repack" in cur_result.name.lower():
                best_result = cur_result
            elif "internal" in best_result.name.lower(
            ) and "internal" not in cur_result.name.lower():
                best_result = cur_result
            elif "xvid" in best_result.name.lower(
            ) and "x264" in cur_result.name.lower():
                sickrage.app.log.info("Preferring " + cur_result.name +
                                      " (x264 over xvid)")
                best_result = cur_result

    if best_result:
        sickrage.app.log.debug("Picked " + best_result.name + " as the best")
    else:
        sickrage.app.log.debug("No result picked.")

    return best_result
예제 #3
0
 def _test_filterBadReleases(self, name, expected):
     result = show_names.filter_bad_releases(name)
     self.assertEqual(result, expected)
예제 #4
0
    def search_cache(self,
                     series_id,
                     series_provider_id,
                     season,
                     episode,
                     manualSearch=False,
                     downCurQuality=False):
        cache_results = {}
        dbData = []

        # get data from external database
        if sickrage.app.config.general.enable_sickrage_api and not self.provider.private:
            resp = sickrage.app.api.provider.get_search_result(
                self.providerID, series_id, season, episode)
            if resp and 'data' in resp:
                dbData += resp['data']

        # get data from internal database
        session = sickrage.app.cache_db.session()
        dbData += [
            x.as_dict() for x in session.query(CacheDB.Provider).filter_by(
                provider=self.providerID, series_id=series_id, season=season).
            filter(CacheDB.Provider.episodes.contains("|{}|".format(episode)))
        ]

        for curResult in dbData:
            result = self.provider.get_result()

            result.series_id = int(curResult["series_id"])
            result.series_provider_id = curResult["series_provider_id"]

            # convert to series provider id enum
            if not isinstance(result.series_provider_id, SeriesProviderID):
                result.series_provider_id = SeriesProviderID[
                    curResult["series_provider_id"]]

            # get series, if it's not one of our shows then ignore it
            series = find_show(result.series_id, result.series_provider_id)
            if not series or series.series_provider_id != series_provider_id:
                continue

            # ignored/required words, and non-tv junk
            if not show_names.filter_bad_releases(curResult["name"]):
                continue

            # skip if provider is anime only and show is not anime
            if self.provider.anime_only and not series.is_anime:
                sickrage.app.log.debug("" + str(series.name) +
                                       " is not an anime, skiping")
                continue

            # get season and ep data (ignoring multi-eps for now)
            curSeason = int(curResult["season"])
            if curSeason == -1:
                continue

            result.season = curSeason
            result.episodes = [
                int(curEp)
                for curEp in filter(None, curResult["episodes"].split("|"))
            ]

            result.quality = Qualities(curResult["quality"])
            result.release_group = curResult["release_group"]
            result.version = curResult["version"]

            # make sure we want the episode
            wantEp = False
            for result_episode in result.episodes:
                if series.want_episode(result.season, result_episode,
                                       result.quality, manualSearch,
                                       downCurQuality):
                    wantEp = True

            if not wantEp:
                sickrage.app.log.info(
                    "Skipping " + curResult["name"] +
                    " because we don't want an episode that's " +
                    result.quality.display_name)
                continue

            # build a result object
            result.name = curResult["name"]
            result.url = curResult["url"]

            sickrage.app.log.info("Found cached {} result {}".format(
                result.provider_type, result.name))

            result.seeders = curResult.get("seeders", -1)
            result.leechers = curResult.get("leechers", -1)
            result.size = curResult.get("size", -1)
            result.content = None

            # add it to the list
            if episode not in cache_results:
                cache_results[int(episode)] = [result]
            else:
                cache_results[int(episode)] += [result]

        # datetime stamp this search so cache gets cleared
        self.last_search = datetime.datetime.today()

        return cache_results