예제 #1
0
def isFinalResult(result):
    """
    Checks if the given result is good enough quality that we can stop searching for other ones.

    :param result: quality to check
    :return: True if the result is the highest quality in both the any/best quality lists else False
    """

    logger.log(
        u"Checking if we should keep searching after we've found " +
        result.name, logger.DEBUG)

    show_obj = result.episodes[0].show

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

    # if there is a re-download 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 re-download 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
예제 #2
0
def isFinalResult(result):
    """
    Checks if the given result is good enough quality that we can stop searching for other ones.

    :param result: quality to check
    :return: True if the result is the highest quality in both the any/best quality lists else False
    """

    logger.log("Checking if we should keep searching after we've found " + result.name, logger.DEBUG)

    show_obj = result.episodes[0].show

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

    # if there is a re-download 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 re-download 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
예제 #3
0
    def massEditSubmit(self, paused=None, season_folders=None, quality_preset=False,
                       anyQualities=[], bestQualities=[], toEdit=None, *args, **kwargs):

        dir_map = {}
        for cur_arg in kwargs:
            if not cur_arg.startswith('orig_root_dir_'):
                continue
            which_index = cur_arg.replace('orig_root_dir_', '')
            end_dir = kwargs['new_root_dir_'+which_index]
            dir_map[kwargs[cur_arg]] = end_dir

        showIDs = toEdit.split("|")
        errors = []
        for curShow in showIDs:
            curErrors = []
            showObj = helpers.findCertainShow(sickbeard.showList, int(curShow))
            if not showObj:
                continue

            cur_root_dir = ek.ek(os.path.dirname, showObj._location)
            cur_show_dir = ek.ek(os.path.basename, showObj._location)
            if cur_root_dir in dir_map and cur_root_dir != dir_map[cur_root_dir]:
                new_show_dir = ek.ek(os.path.join, dir_map[cur_root_dir], cur_show_dir)
                logger.log(u"For show "+showObj.name+" changing dir from "+showObj._location+" to "+new_show_dir)
            else:
                new_show_dir = showObj._location
            
            if paused == 'keep':
                new_paused = showObj.paused
            else:
                new_paused = True if paused == 'enable' else False
            new_paused = 'on' if new_paused else 'off'

            if season_folders == 'keep':
                new_season_folders = showObj.seasonfolders
            else:
                new_season_folders = True if season_folders == 'enable' else False
            new_season_folders = 'on' if new_season_folders else 'off'

            if quality_preset == 'keep':
                anyQualities, bestQualities = Quality.splitQuality(showObj.quality)
            
            curErrors += Home().editShow(curShow, new_show_dir, anyQualities, bestQualities, new_season_folders, new_paused, directCall=True)

            if curErrors:
                logger.log(u"Errors: "+str(curErrors), logger.ERROR)
                errors.append('<b>%s:</b><br />\n<ul>' % showObj.name + '\n'.join(['<li>%s</li>' % error for error in curErrors]) + "</ul>")

        if len(errors) > 0:
            ui.notifications.error('%d error%s while saving changes:' % (len(errors), "" if len(errors) == 1 else "s"),
                        "<br />\n".join(errors))

        redirect("/manage")
예제 #4
0
파일: search.py 프로젝트: Thraxis/pymedusa
def isFirstBestMatch(result):
    """
    Check if the given result is a best quality match and if we want to stop searching providers here.

    :param result: to check
    :return: True if the result is the best quality match else False
    """
    logger.log(u"Checking if we should stop searching for a better quality for for episode " + result.name,
               logger.DEBUG)

    show_obj = result.episodes[0].show

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

    return result.quality in best_qualities if best_qualities else False
예제 #5
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.
    """

    logging.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
예제 #6
0
def isFirstBestMatch(result):
    """
    Checks if the given result is a best quality match and if we want to stop searching providers here.

    :param result: to check
    :return: True if the result is the best quality match else False
    """

    logger.log(u"Checking if we should stop searching for a better quality for for episode " + result.name,
               logger.DEBUG)

    show_obj = result.episodes[0].show

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

    return result.quality in best_qualities if best_qualities else False
예제 #7
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.
    """

    logger.log(
        u"Checking if we should archive our first best quality match for for episode "
        + result.name, logger.DEBUG)

    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
예제 #8
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]

    logger.log(
        u"Picking the best result out of " + str([x.name for x in results]),
        logger.DEBUG)

    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

        logger.log(u"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:
            logger.log(
                cur_result.name +
                " is a quality we know we don't want, rejecting it",
                logger.DEBUG)
            continue

        if show.rls_ignore_words and show_name_helpers.containsAtLeastOneWord(
                cur_result.name, cur_result.show.rls_ignore_words):
            logger.log(
                u"Ignoring " + cur_result.name +
                " based on ignored words filter: " + show.rls_ignore_words,
                logger.INFO)
            continue

        if show.rls_require_words and not show_name_helpers.containsAtLeastOneWord(
                cur_result.name, cur_result.show.rls_require_words):
            logger.log(
                u"Ignoring " + cur_result.name +
                " based on required words filter: " + show.rls_require_words,
                logger.INFO)
            continue

        if not show_name_helpers.filterBadReleases(cur_result.name,
                                                   parse=False):
            logger.log(
                u"Ignoring " + cur_result.name +
                " because its not a valid scene release that we want, ignoring it",
                logger.INFO)
            continue

        if hasattr(cur_result, 'size'):
            if sickbeard.USE_FAILED_DOWNLOADS and failed_history.hasFailed(
                    cur_result.name, cur_result.size,
                    cur_result.provider.name):
                logger.log(cur_result.name +
                           u" 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():
                logger.log(u"Preferring " + cur_result.name +
                           " (x264 over xvid)")
                bestResult = cur_result

    if bestResult:
        logger.log(u"Picked " + bestResult.name + " as the best", logger.DEBUG)
    else:
        logger.log(u"No result picked.", logger.DEBUG)

    return bestResult
예제 #9
0
def pickBestResult(results, show):  # pylint: disable=too-many-branches
    """
    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]

    logger.log(
        "Picking the best result out of " + str([x.name for x in results]),
        logger.DEBUG)

    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

        logger.log("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:
            logger.log(
                cur_result.name +
                " is a quality we know we don't want, rejecting it",
                logger.DEBUG)
            continue

        if not show_name_helpers.filter_bad_releases(
                cur_result.name, parse=False, show=show):
            continue

        if hasattr(cur_result, 'size'):
            if sickbeard.USE_FAILED_DOWNLOADS and failed_history.hasFailed(
                    cur_result.name, cur_result.size,
                    cur_result.provider.name):
                logger.log(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 "real" in cur_result.name.lower(
            ) or "repack" in cur_result.name.lower():
                logger.log("Preferring " + cur_result.name +
                           " (repack/proper/real over nuked)")
                bestResult = cur_result
            elif "internal" in bestResult.name.lower(
            ) and "internal" not in cur_result.name.lower():
                logger.log("Preferring " + cur_result.name +
                           " (normal instead of internal)")
                bestResult = cur_result
            elif "xvid" in bestResult.name.lower(
            ) and "x264" in cur_result.name.lower():
                logger.log("Preferring " + cur_result.name +
                           " (x264 over xvid)")
                bestResult = cur_result

    if bestResult:
        logger.log("Picked " + bestResult.name + " as the best", logger.DEBUG)
    else:
        logger.log("No result picked.", logger.DEBUG)

    return bestResult
예제 #10
0
class BinNewzProvider(generic.NZBProvider):
    allowedGroups = {
        'abmulti': 'alt.binaries.multimedia',
        'abtvseries': 'alt.binaries.tvseries',
        'abtv': 'alt.binaries.tv',
        'a.b.teevee': 'alt.binaries.teevee',
        'abstvdivxf': 'alt.binaries.series.tv.divx.french',
        'abhdtvx264fr': 'alt.binaries.hdtv.x264.french',
        'abmom': 'alt.binaries.mom',
        'abhdtv': 'alt.binaries.hdtv',
        'abboneless': 'alt.binaries.boneless',
        'abhdtvf': 'alt.binaries.hdtv.french',
        'abhdtvx264': 'alt.binaries.hdtv.x264',
        'absuperman': 'alt.binaries.superman',
        'abechangeweb': 'alt.binaries.echange-web',
        'abmdfvost': 'alt.binaries.movies.divx.french.vost',
        'abdvdr': 'alt.binaries.dvdr',
        'abmzeromov': 'alt.binaries.movies.zeromovies',
        'abcfaf': 'alt.binaries.cartoons.french.animes-fansub',
        'abcfrench': 'alt.binaries.cartoons.french',
        'abgougouland': 'alt.binaries.gougouland',
        'abroger': 'alt.binaries.roger',
        'abtatu': 'alt.binaries.tatu',
        'abstvf': 'alt.binaries.series.tv.french',
        'abmdfreposts': 'alt.binaries.movies.divx.french.reposts',
        'abmdf': 'alt.binaries.movies.french',
        'ab.aa': 'alt.binaries.aa',
        'abspectdf': 'alt.binaries.spectacles.divx.french'
    }

    qualityCategories = {3: ['24', '7', '56'], 500: ['44', '53']}

    qualityMinSize = {
        (Quality.SDTV, Quality.SDDVD):
        130,
        Quality.HDTV:
        500,
        (Quality.HDWEBDL, Quality.HDBLURAY, Quality.FULLHDBLURAY, Quality.FULLHDTV, Quality.FULLHDWEBDL):
        600
    }

    url = "http://www.binnews.in/"
    supportsBacklog = True
    nzbDownloaders = [BinSearch(), NZBIndex(), NZBClub()]

    def __init__(self):
        generic.NZBProvider.__init__(self, "BinnewZ")

    def isEnabled(self):
        return sickbeard.BINNEWZ

    def _get_season_search_strings(self, show, season, episode=None):
        showNam = show_name_helpers.allPossibleShowNames(show)
        showNames = list(set(showNam))
        result = []
        global globepid
        global searchstringlist
        searchstringlist = []
        globepid = show.tvdbid
        for showName in showNames:
            result.append(showName + ".saison %2d" % season)
        return result

    def _get_episode_search_strings(self, ep_obj, french=None):
        strings = []
        showNam = show_name_helpers.allPossibleShowNames(ep_obj.show)
        showNames = list(set(showNam))
        global globepid
        global searchstringlist
        searchstringlist = []
        myDB = db.DBConnection()
        epidr = myDB.select(
            "SELECT episode_id from tv_episodes where tvdbid=?",
            [ep_obj.tvdbid])
        globepid = epidr[0][0]
        for showName in showNames:
            strings.append("%s S%02dE%02d" %
                           (showName, ep_obj.season, ep_obj.episode))
            strings.append("%s S%02dE%d" %
                           (showName, ep_obj.season, ep_obj.episode))
            strings.append("%s S%dE%02d" %
                           (showName, ep_obj.season, ep_obj.episode))
            strings.append("%s %dx%d" %
                           (showName, ep_obj.season, ep_obj.episode))
            strings.append("%s S%02d E%02d" %
                           (showName, ep_obj.season, ep_obj.episode))
            strings.append("%s S%02d E%d" %
                           (showName, ep_obj.season, ep_obj.episode))
            strings.append("%s S%d E%02d" %
                           (showName, ep_obj.season, ep_obj.episode))
            strings.append("%s S%02dEp%02d" %
                           (showName, ep_obj.season, ep_obj.episode))
            strings.append("%s S%02dEp%d" %
                           (showName, ep_obj.season, ep_obj.episode))
            strings.append("%s S%dEp%02d" %
                           (showName, ep_obj.season, ep_obj.episode))
            strings.append("%s S%02d Ep%02d" %
                           (showName, ep_obj.season, ep_obj.episode))
            strings.append("%s S%02d Ep%d" %
                           (showName, ep_obj.season, ep_obj.episode))
            strings.append("%s S%d Ep%02d" %
                           (showName, ep_obj.season, ep_obj.episode))
            strings.append("%s S%02d Ep %02d" %
                           (showName, ep_obj.season, ep_obj.episode))
            strings.append("%s S%02d Ep %d" %
                           (showName, ep_obj.season, ep_obj.episode))
            strings.append("%s S%d Ep %02d" %
                           (showName, ep_obj.season, ep_obj.episode))
        return strings

    def _get_title_and_url(self, item):
        cleanTitle = re.sub(r'(\s*\[[\w\s]+\-\w+\])', "", item.title)
        return cleanTitle, item.refererURL

    def getQuality(self, item):
        return item.quality

    def buildUrl(self, searchString, quality):
        if quality in self.qualityCategories:
            data = {
                'chkInit': '1',
                'edTitre': searchString,
                'chkTitre': 'on',
                'chkFichier': 'on',
                'chkCat': 'on',
                'cats[]': self.qualityCategories[quality],
                'edAge': '',
                'edYear': ''
            }
        else:
            data = {
                'b_submit': 'BinnewZ',
                'cats[]': 'all',
                'edSearchAll': searchString,
                'sections[]': 'all'
            }
        return data

    #wtf with the signature change...
    def _doSearch(self,
                  searchString=None,
                  show=None,
                  season=None,
                  french=None):
        if searchString is None:
            return []
        logger.log("BinNewz : Searching for " + searchString, logger.DEBUG)
        data = self.buildUrl(searchString, show.quality)
        try:
            soup = BeautifulSoup(
                urllib2.urlopen("http://www.binnews.in/_bin/search2.php",
                                urllib.urlencode(data, True)))
        except Exception, e:
            logger.log(u"Error trying to load BinNewz response: " + e,
                       logger.ERROR)
            return []

        results = []
        tables = soup.findAll("table", id="tabliste")
        for table in tables:
            if len(results) > 5:
                break
            rows = table.findAll("tr")
            for row in rows:

                cells = row.select("> td")
                if len(cells) < 11:
                    continue

                name = cells[2].text.strip()
                language = cells[3].find("img").get("src")

                if show:
                    if show.audio_lang == "fr" or french:
                        if not "_fr" in language:
                            continue
                    elif show.audio_lang == "en":
                        if "_fr" in language:
                            continue

                # blacklist_groups = [ "alt.binaries.multimedia" ]
                blacklist_groups = []

                newgroupLink = cells[4].find("a")
                newsgroup = None
                if newgroupLink.contents:
                    newsgroup = newgroupLink.contents[0]
                    if newsgroup in self.allowedGroups:
                        newsgroup = self.allowedGroups[newsgroup]
                    else:
                        logger.log(u"Unknown binnewz newsgroup: " + newsgroup,
                                   logger.ERROR)
                        continue
                    if newsgroup in blacklist_groups:
                        logger.log(
                            u"Ignoring result, newsgroup is blacklisted: " +
                            newsgroup, logger.WARNING)
                        continue

                filename = cells[5].contents[0]

                acceptedQualities = Quality.splitQuality(show.quality)[0]
                quality = Quality.nameQuality(filename)
                if quality == Quality.UNKNOWN:
                    quality = self.getReleaseQuality(name)
                if quality not in acceptedQualities:
                    continue
                if filename in searchstringlist:
                    continue

                minSize = self.qualityMinSize[
                    quality] if quality in self.qualityMinSize else 100
                searchItems = []
                #multiEpisodes = False

                rangeMatcher = re.search(
                    "(?i).*(?<![\s\.\-_])[\s\.\-_]+s?(?:aison)?[\s\.\-_]*\d{1,2}[\s\.\-_]?(?:x|dvd|[eéEÉ](?:p|pisodes?)?)[\s\.\-_]*(\d{1,2})(?:(?:[\s\.\-_]*(?:[aàAÀ,/\-\.\s\&_]|et|and|to|x)[\s\.\-_]*(?:x|dvd|[eéEÉ](?:p|pisodes?)?)?[\s\.\-_]*([0-9]{1,2})))+.*",
                    name)
                if rangeMatcher:
                    rangeStart = int(rangeMatcher.group(1))
                    rangeEnd = int(rangeMatcher.group(2))
                    if filename.find("*") != -1:
                        for i in range(rangeStart, rangeEnd + 1):
                            searchItem = filename.replace("**", str(i))
                            searchItem = searchItem.replace("*", str(i))
                            searchItems.append(searchItem)
                    #else:
                    #    multiEpisodes = True

                if len(searchItems) == 0:
                    searchItems.append(filename)

                for searchItem in searchItems:
                    for downloader in self.nzbDownloaders:
                        searchstringlist.append(searchItem)
                        logger.log("Searching for download : " + name +
                                   ", search string = " + searchItem + " on " +
                                   downloader.__class__.__name__)
                        try:
                            binsearch_result = downloader.search(
                                searchItem, minSize, newsgroup)
                            if binsearch_result:
                                links = []
                                if french:
                                    binsearch_result.audio_langs = 'fr'
                                else:
                                    binsearch_result.audio_langs = show.audio_lang
                                binsearch_result.title = searchString
                                binsearch_result.quality = quality
                                myDB = db.DBConnection()
                                listlink = myDB.select(
                                    "SELECT link from episode_links where episode_id =?",
                                    [globepid])
                                for dlink in listlink:
                                    links.append(dlink[0])
                                if binsearch_result.nzburl in links:
                                    continue
                                else:
                                    results.append(binsearch_result)
                                    logger.log("Found : " + searchItem +
                                               " on " +
                                               downloader.__class__.__name__)
                                    break
                        except Exception, e:
                            logger.log(
                                "Searching from " +
                                downloader.__class__.__name__ + " failed : " +
                                str(e), logger.ERROR)
예제 #11
0
파일: search.py 프로젝트: adaur/SickRage
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]

    logger.log(u"Picking the best result out of " + str([x.name for x in results]), logger.DEBUG)

    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

        logger.log(u"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:
            logger.log(cur_result.name + " is a quality we know we don't want, rejecting it", logger.DEBUG)
            continue

        if show.rls_ignore_words and show_name_helpers.containsAtLeastOneWord(cur_result.name, cur_result.show.rls_ignore_words):
            logger.log(u"Ignoring " + cur_result.name + " based on ignored words filter: " + show.rls_ignore_words,
                       logger.INFO)
            continue

        if show.rls_require_words and not show_name_helpers.containsAtLeastOneWord(cur_result.name, cur_result.show.rls_require_words):
            logger.log(u"Ignoring " + cur_result.name + " based on required words filter: " + show.rls_require_words,
                       logger.INFO)
            continue

        if not show_name_helpers.filterBadReleases(cur_result.name, parse=False):
            logger.log(u"Ignoring " + cur_result.name + " because its not a valid scene release that we want, ignoring it",
                       logger.INFO)
            continue

        if hasattr(cur_result, 'size'):
            if sickbeard.USE_FAILED_DOWNLOADS and failed_history.hasFailed(cur_result.name, cur_result.size,
                                                                           cur_result.provider.name):
                logger.log(cur_result.name + u" 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():
                logger.log(u"Preferring " + cur_result.name + " (x264 over xvid)")
                bestResult = cur_result

    if bestResult:
        logger.log(u"Picked " + bestResult.name + " as the best", logger.DEBUG)
    else:
        logger.log(u"No result picked.", logger.DEBUG)

    return bestResult
예제 #12
0
def render_body(context, **pageargs):
    __M_caller = context.caller_stack._push_frame()
    try:
        __M_locals = __M_dict_builtin(pageargs=pageargs)
        show = context.get('show', UNDEFINED)
        int = context.get('int', UNDEFINED)
        len = context.get('len', UNDEFINED)
        filter = context.get('filter', UNDEFINED)
        sorted = context.get('sorted', UNDEFINED)
        _ = context.get('_', UNDEFINED)
        __M_writer = context.writer()
        __M_writer(u'\n\n')

        if show is not UNDEFINED:
            __quality = int(show.quality)
        else:
            __quality = int(sickbeard.QUALITY_DEFAULT)

        anyQualities, bestQualities = Quality.splitQuality(__quality)
        overall_quality = Quality.combineQualities(anyQualities, bestQualities)
        selected = None

        __M_locals_builtin_stored = __M_locals_builtin()
        __M_locals.update(
            __M_dict_builtin([
                (__M_key, __M_locals_builtin_stored[__M_key]) for __M_key in [
                    '__quality', 'anyQualities', 'overall_quality', 'selected',
                    'bestQualities'
                ] if __M_key in __M_locals_builtin_stored
            ]))
        __M_writer(
            u'\n\n<div class="row">\n    <div class="col-md-12">\n        <select id="qualityPreset" name="quality_preset" class="form-control input-sm input100" title="qualityPreset">\n            <option value="0">Custom</option>\n'
        )
        for curPreset in qualityPresets:
            __M_writer(u'                <option value="')
            __M_writer(unicode(curPreset))
            __M_writer(u'" ')
            __M_writer(
                unicode(
                    ('', 'selected="selected"')[curPreset == overall_quality]))
            __M_writer(u' ')
            __M_writer(
                unicode(('', 'style="padding-left: 15px;"'
                         )[qualityPresetStrings[curPreset].endswith("0p")]))
            __M_writer(u'>')
            __M_writer(unicode(qualityPresetStrings[curPreset]))
            __M_writer(u'</option>\n')
        __M_writer(
            u'        </select>\n    </div>\n</div>\n<div class="row">\n    <div class="col-md-12">\n        <div id="customQualityWrapper">\n            <div id="customQuality" style="padding-left: 0;">\n                '
        )
        __M_writer(
            unicode(
                _('<p><b><u>Preferred</u></b> qualities will replace those in <b><u>allowed</u></b>, even if they are lower.</p>'
                  )))
        __M_writer(
            u'\n\n                <div style="padding-right: 40px; text-align: left; float: left;">\n                    <h5>'
        )
        __M_writer(unicode(_('Allowed')))
        __M_writer(u'</h5>\n                    ')
        anyQualityList = filter(lambda x: x > Quality.NONE,
                                Quality.qualityStrings)

        __M_locals_builtin_stored = __M_locals_builtin()
        __M_locals.update(
            __M_dict_builtin([(__M_key, __M_locals_builtin_stored[__M_key])
                              for __M_key in ['anyQualityList']
                              if __M_key in __M_locals_builtin_stored]))
        __M_writer(
            u'\n                    <select id="anyQualities" name="anyQualities" multiple="multiple" size="'
        )
        __M_writer(unicode(len(anyQualityList)))
        __M_writer(
            u'" class="form-control form-control-inline input-sm" title="anyQualities">\n'
        )
        for curQuality in sorted(anyQualityList):
            __M_writer(u'                            <option value="')
            __M_writer(unicode(curQuality))
            __M_writer(u'" ')
            __M_writer(
                unicode(
                    ('', 'selected="selected"')[curQuality in anyQualities]))
            __M_writer(u'>')
            __M_writer(unicode(Quality.qualityStrings[curQuality]))
            __M_writer(u'</option>\n')
        __M_writer(
            u'                    </select>\n                </div>\n\n                <div style="text-align: left; float: left;">\n                    <h5>'
        )
        __M_writer(unicode(_('Preferred')))
        __M_writer(u'</h5>\n                    ')
        bestQualityList = filter(lambda x: Quality.SDTV <= x < Quality.UNKNOWN,
                                 Quality.qualityStrings)

        __M_locals_builtin_stored = __M_locals_builtin()
        __M_locals.update(
            __M_dict_builtin([(__M_key, __M_locals_builtin_stored[__M_key])
                              for __M_key in ['bestQualityList']
                              if __M_key in __M_locals_builtin_stored]))
        __M_writer(
            u'\n                    <select id="bestQualities" name="bestQualities" multiple="multiple" size="'
        )
        __M_writer(unicode(len(bestQualityList)))
        __M_writer(
            u'" class="form-control form-control-inline input-sm" title="bestQualities">\n'
        )
        for curQuality in sorted(bestQualityList):
            __M_writer(u'                            <option value="')
            __M_writer(unicode(curQuality))
            __M_writer(u'" ')
            __M_writer(
                unicode(
                    ('', 'selected="selected"')[curQuality in bestQualities]))
            __M_writer(u'>')
            __M_writer(unicode(Quality.qualityStrings[curQuality]))
            __M_writer(u'</option>\n')
        __M_writer(
            u'                    </select>\n                </div>\n            </div>\n        </div>\n    </div>\n</div>\n'
        )
        return ''
    finally:
        context.caller_stack._pop_frame()
예제 #13
0
    def massEditSubmit(self, paused=None, default_ep_status=None,
                       anime=None, sports=None, scene=None, flatten_folders=None, quality_preset=None,
                       subtitles=None, air_by_date=None, anyQualities=[], bestQualities=[], toEdit=None, *args,
                       **kwargs):
        allowed_qualities = anyQualities
        preferred_qualities = bestQualities

        dir_map = {}
        for cur_arg in kwargs:
            if not cur_arg.startswith('orig_root_dir_'):
                continue
            which_index = cur_arg.replace('orig_root_dir_', '')
            end_dir = kwargs['new_root_dir_{index}'.format(index=which_index)]
            dir_map[kwargs[cur_arg]] = end_dir

        show_ids = toEdit.split('|')
        errors = []
        for cur_show in show_ids:
            cur_errors = []
            show_obj = Show.find(sickbeard.showList, int(cur_show))
            if not show_obj:
                continue

            cur_root_dir = ek(os.path.dirname, show_obj._location)  # pylint: disable=protected-access
            cur_show_dir = ek(os.path.basename, show_obj._location)  # pylint: disable=protected-access
            if cur_root_dir in dir_map and cur_root_dir != dir_map[cur_root_dir]:
                new_show_dir = ek(os.path.join, dir_map[cur_root_dir], cur_show_dir)
                logger.log(u'For show {show.name} changing dir from {show.location} to {location}'.format
                           (show=show_obj, location=new_show_dir))  # pylint: disable=protected-access
            else:
                new_show_dir = show_obj._location  # pylint: disable=protected-access

            if paused == 'keep':
                new_paused = show_obj.paused
            else:
                new_paused = True if paused == 'enable' else False
            new_paused = 'on' if new_paused else 'off'

            if default_ep_status == 'keep':
                new_default_ep_status = show_obj.default_ep_status
            else:
                new_default_ep_status = default_ep_status

            if anime == 'keep':
                new_anime = show_obj.anime
            else:
                new_anime = True if anime == 'enable' else False
            new_anime = 'on' if new_anime else 'off'

            if sports == 'keep':
                new_sports = show_obj.sports
            else:
                new_sports = True if sports == 'enable' else False
            new_sports = 'on' if new_sports else 'off'

            if scene == 'keep':
                new_scene = show_obj.is_scene
            else:
                new_scene = True if scene == 'enable' else False
            new_scene = 'on' if new_scene else 'off'

            if air_by_date == 'keep':
                new_air_by_date = show_obj.air_by_date
            else:
                new_air_by_date = True if air_by_date == 'enable' else False
            new_air_by_date = 'on' if new_air_by_date else 'off'

            if flatten_folders == 'keep':
                new_flatten_folders = show_obj.flatten_folders
            else:
                new_flatten_folders = True if flatten_folders == 'enable' else False
            new_flatten_folders = 'on' if new_flatten_folders else 'off'

            if subtitles == 'keep':
                new_subtitles = show_obj.subtitles
            else:
                new_subtitles = True if subtitles == 'enable' else False

            new_subtitles = 'on' if new_subtitles else 'off'

            if quality_preset == 'keep':
                allowed_qualities, preferred_qualities = Quality.splitQuality(show_obj.quality)
            elif try_int(quality_preset, None):
                preferred_qualities = []

            exceptions_list = []

            cur_errors += self.editShow(cur_show, new_show_dir, allowed_qualities,
                                        preferred_qualities, exceptions_list,
                                        defaultEpStatus=new_default_ep_status,
                                        flatten_folders=new_flatten_folders,
                                        paused=new_paused, sports=new_sports,
                                        subtitles=new_subtitles, anime=new_anime,
                                        scene=new_scene, air_by_date=new_air_by_date,
                                        directCall=True)

            if cur_errors:
                logger.log(u'Errors: {errors}'.format(errors=cur_errors), logger.ERROR)
                errors.append(
                    '<b>{show}:</b>\n<ul>{errors}</ul>'.format(
                        show=show_obj.name,
                        errors=' '.join(['<li>{error}</li>'.format(error=error)
                                         for error in cur_errors])
                    )
                )
        if errors:
            ui.notifications.error(
                '{num} error{s} while saving changes:'.format(
                    num=len(errors),
                    s='s' if len(errors) > 1 else ''),
                ' '.join(errors)
            )

        return self.redirect('/manage/')
예제 #14
0
def render_body(context, **pageargs):
    __M_caller = context.caller_stack._push_frame()
    try:
        __M_locals = __M_dict_builtin(pageargs=pageargs)
        enable_anime_options = context.get('enable_anime_options', UNDEFINED)
        bool = context.get('bool', UNDEFINED)
        _ = context.get('_', UNDEFINED)
        __M_writer = context.writer()

        import sickbeard
        from sickbeard.common import SKIPPED, WANTED, IGNORED
        from sickbeard.common import Quality, statusStrings

        __M_locals_builtin_stored = __M_locals_builtin()
        __M_locals.update(
            __M_dict_builtin([(__M_key, __M_locals_builtin_stored[__M_key])
                              for __M_key in [
                                  'IGNORED', 'SKIPPED', 'sickbeard',
                                  'statusStrings', 'WANTED', 'Quality'
                              ] if __M_key in __M_locals_builtin_stored]))
        __M_writer(
            u'\n    <div class="field-pair row">\n        <div class="col-lg-3 col-md-4 col-sm-5 col-xs-12">\n            <span class="component-title">'
        )
        __M_writer(unicode(_('Preferred Quality')))
        __M_writer(
            u'</span>\n        </div>\n        <div class="col-lg-9 col-md-8 col-sm-7 col-xs-12 component-desc">\n            '
        )
        anyQualities, bestQualities = Quality.splitQuality(
            sickbeard.QUALITY_DEFAULT)

        __M_locals_builtin_stored = __M_locals_builtin()
        __M_locals.update(
            __M_dict_builtin([(__M_key, __M_locals_builtin_stored[__M_key])
                              for __M_key in ['anyQualities', 'bestQualities']
                              if __M_key in __M_locals_builtin_stored]))
        __M_writer(u'\n            ')
        runtime._include_file(context, u'/inc_qualityChooser.mako',
                              _template_uri)
        __M_writer(u'\n        </div>\n    </div>\n    <br>\n\n')
        if sickbeard.USE_SUBTITLES:
            __M_writer(
                u'        <div class="field-pair row">\n            <div class="col-lg-3 col-md-4 col-sm-5 col-xs-12">\n                <span class="component-title">'
            )
            __M_writer(unicode(_('Subtitles')))
            __M_writer(
                u'</span>\n            </div>\n            <div class="col-lg-9 col-md-8 col-sm-7 col-xs-12 component-desc">\n                <input type="checkbox" name="subtitles" id="subtitles" '
            )
            __M_writer(
                unicode(
                    ('',
                     'checked="checked"')[bool(sickbeard.SUBTITLES_DEFAULT)]))
            __M_writer(u' />\n                <label for="subtitles">')
            __M_writer(unicode(_('Download subtitles for this show?')))
            __M_writer(
                u'</label>\n            </div>\n            <div class="col-lg-3 col-md-4 col-sm-5 col-xs-12">\n                <span class="component-title">'
            )
            __M_writer(unicode(_('Use SR Metdata')))
            __M_writer(
                u'</span>\n            </div>\n            <div class="col-lg-9 col-md-8 col-sm-7 col-xs-12 component-desc">\n                <input type="checkbox" id="subtitles_sr_metadata" name="subtitles_sr_metadata"  />\n                <label for="subtitles_sr_metadata">'
            )
            __M_writer(
                unicode(
                    _('use SickRage metadata when searching for subtitle, <br />this will override the autodiscovered metadata'
                      )))
            __M_writer(
                u'</label>\n            </div>\n        </div>\n        <br>\n'
            )
        __M_writer(
            u'\n    <div class="field-pair row">\n        <div class="col-lg-3 col-md-4 col-sm-5 col-xs-12">\n            <span class="component-title">'
        )
        __M_writer(unicode(_('Status for previously aired episodes')))
        __M_writer(
            u'</span>\n        </div>\n        <div class="col-lg-9 col-md-8 col-sm-7 col-xs-12 component-desc">\n            <select name="defaultStatus" id="statusSelect" class="form-control form-control-inline input-sm" title="defaultStatus">\n'
        )
        for curStatus in [SKIPPED, WANTED, IGNORED]:
            __M_writer(u'                    <option value="')
            __M_writer(unicode(curStatus))
            __M_writer(u'" ')
            __M_writer(
                unicode(('', 'selected="selected"'
                         )[sickbeard.STATUS_DEFAULT == curStatus]))
            __M_writer(u'>')
            __M_writer(unicode(statusStrings[curStatus]))
            __M_writer(u'</option>\n')
        __M_writer(
            u'            </select>\n        </div>\n    </div>\n    <br>\n\n    <div class="field-pair row">\n        <div class="col-lg-3 col-md-4 col-sm-5 col-xs-12">\n            <span class="component-title">'
        )
        __M_writer(unicode(_('Status for all future episodes')))
        __M_writer(
            u'</span>\n        </div>\n        <div class="col-lg-9 col-md-8 col-sm-7 col-xs-12 component-desc">\n            <select name="defaultStatusAfter" id="statusSelectAfter" class="form-control form-control-inline input-sm">\n'
        )
        for curStatus in [SKIPPED, WANTED, IGNORED]:
            __M_writer(u'                    <option value="')
            __M_writer(unicode(curStatus))
            __M_writer(u'" ')
            __M_writer(
                unicode(('', 'selected="selected"'
                         )[sickbeard.STATUS_DEFAULT_AFTER == curStatus]))
            __M_writer(u'>')
            __M_writer(unicode(statusStrings[curStatus]))
            __M_writer(u'</option>\n')
        __M_writer(
            u'            </select>\n        </div>\n    </div>\n    <br>\n\n    <div class="field-pair row">\n        <div class="col-lg-3 col-md-4 col-sm-5 col-xs-12">\n            <span class="component-title">'
        )
        __M_writer(unicode(_('Season Folders')))
        __M_writer(
            u'</span>\n        </div>\n        <div class="col-lg-9 col-md-8 col-sm-7 col-xs-12 component-desc">\n            <input type="checkbox" name="season_folders" id="season_folders" '
        )
        __M_writer(
            unicode(
                ('',
                 'checked="checked"')[bool(sickbeard.SEASON_FOLDERS_DEFAULT)]))
        __M_writer(u'/>\n            <label for="season_folders">')
        __M_writer(unicode(_('Group episodes by season folder?')))
        __M_writer(u'</label>\n        </div>\n    </div>\n    <br>\n\n')
        if enable_anime_options:
            __M_writer(
                u'        <div class="field-pair row">\n            <div class="col-lg-3 col-md-4 col-sm-5 col-xs-12">\n                <span class="component-title">'
            )
            __M_writer(unicode(_('Anime')))
            __M_writer(
                u'</span>\n            </div>\n            <div class="col-lg-9 col-md-8 col-sm-7 col-xs-12 component-desc">\n                <input type="checkbox" name="anime" id="anime" '
            )
            __M_writer(
                unicode(
                    ('', 'checked="checked"')[bool(sickbeard.ANIME_DEFAULT)]))
            __M_writer(u' />\n                <label for="anime">')
            __M_writer(unicode(_('Is this show an Anime?')))
            __M_writer(
                u'</label>\n            </div>\n        </div>\n        <br>\n'
            )
        __M_writer(
            u'\n    <div class="field-pair row">\n        <div class="col-lg-3 col-md-4 col-sm-5 col-xs-12">\n            <span class="component-title">'
        )
        __M_writer(unicode(_('Scene Numbering')))
        __M_writer(
            u'</span>\n        </div>\n        <div class="col-lg-9 col-md-8 col-sm-7 col-xs-12 component-desc">\n            <input type="checkbox" name="scene" id="scene" '
        )
        __M_writer(
            unicode(('', 'checked="checked"')[bool(sickbeard.SCENE_DEFAULT)]))
        __M_writer(u' />\n            <label for="scene">')
        __M_writer(unicode(_('Is this show scene numbered?')))
        __M_writer(
            u'</label>\n        </div>\n    </div>\n    <br>\n    <div class="field-pair row">\n        <div class="col-lg-3 col-md-4 col-sm-5 col-xs-12">\n            <span class="component-title">\n                <input class="btn btn-inline" type="button" id="saveDefaultsButton" value="'
        )
        __M_writer(unicode(_('Save as default')))
        __M_writer(
            u'" disabled="disabled" />\n            </span>\n        </div>\n        <div class="col-lg-9 col-md-8 col-sm-7 col-xs-12 component-desc">\n            <label>'
        )
        __M_writer(unicode(_('Use current values as the defaults')))
        __M_writer(u'</label>\n        </div>\n    </div>\n\n')
        if enable_anime_options:
            __M_writer(u'        ')
            import sickbeard.blackandwhitelist

            __M_locals_builtin_stored = __M_locals_builtin()
            __M_locals.update(
                __M_dict_builtin([(__M_key, __M_locals_builtin_stored[__M_key])
                                  for __M_key in ['sickbeard']
                                  if __M_key in __M_locals_builtin_stored]))
            __M_writer(u'\n        ')
            runtime._include_file(context, u'/inc_blackwhitelist.mako',
                                  _template_uri)
            __M_writer(u'\n')
        else:
            __M_writer(
                u'        <input type="hidden" name="anime" id="anime" value="0" />\n'
            )
        return ''
    finally:
        context.caller_stack._pop_frame()
예제 #15
0
def makeSceneSeasonSearchString (show, segment, extraSearchType=None):

    myDB = db.DBConnection()

    if show.air_by_date:
        numseasons = 0
        
        # the search string for air by date shows is just 
        seasonStrings = [segment]
    
    elif show.absolute_numbering:
        numseasons = 0
        episodeNumbersSQLResult = myDB.select("SELECT absolute_episode, status FROM tv_episodes WHERE showid = ? and season = ?", [show.tvdbid, segment])
        
        # get show qualities
        bestQualities = Quality.splitQuality(show.quality)
        
        # compile a list of all the episode numbers we need in this 'season'
        seasonStrings = []
        for episodeNumberResult in episodeNumbersSQLResult:
            
            # get quality of the episode
            curCompositeStatus = int(episodeNumberResult["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:
                seasonStrings.append("%d" % episodeNumberResult["absolute_episode"])
            
    else:
        numseasonsSQlResult = myDB.select("SELECT COUNT(DISTINCT season) as numseasons FROM tv_episodes WHERE showid = ? and season != 0", [show.tvdbid])
        numseasons = int(numseasonsSQlResult[0][0])

        seasonStrings = ["S%02d" % segment]
        # since nzbmatrix allows more than one search per request we search SxEE results too
        if extraSearchType == "nzbmatrix":
            seasonStrings.append("%ix" % segment)

    showNames = set(makeSceneShowSearchStrings(show))

    toReturn = []
    term_list = []

    # 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:
                    toReturn.append(curShow + "." + cur_season)
        
        # nzbmatrix is special, we build a search string just for them
        elif extraSearchType == "nzbmatrix":
            if numseasons == 1:
                toReturn.append('"'+curShow+'"')
            elif numseasons == 0:
                if show.absolute_numbering:
                    term_list = ['(+"'+curShow+'"+"'+x+'")' for x in seasonStrings]
                    toReturn.append('.'.join(term_list))
                else:
                    toReturn.append('"'+curShow+' '+str(segment).replace('-',' ')+'"')
            else:
                term_list = [x+'*' for x in seasonStrings]
                if show.air_by_date:
                    term_list = ['"'+x+'"' for x in term_list]

                toReturn.append('+"'+curShow+'" +('+','.join(term_list)+')')

    return toReturn
예제 #16
0
def pickBestResult(results, show):  # pylint: disable=too-many-branches
    """
    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]

    logger.log(
        "Picking the best result out of " + str([x.name for x in results]),
        logger.DEBUG)

    preferredWords = [i.strip() for i in sickbeard.PREFERRED_WORDS.split(',')]

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

        cur_result.searcher_score = 0
        nameLower = cur_result.name.lower()

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

        logger.log("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:
            logger.log(
                cur_result.name +
                " is a quality we know we don't want, rejecting it",
                logger.DEBUG)
            continue

        if not show_name_helpers.filter_bad_releases(
                cur_result.name, parse=False, show=show):
            continue

        cur_result.searcher_score += (cur_result.quality * 100)

        if hasattr(cur_result, 'size'):
            if sickbeard.USE_FAILED_DOWNLOADS and failed_history.hasFailed(
                    cur_result.name, cur_result.size,
                    cur_result.provider.name):
                logger.log(cur_result.name +
                           " has previously failed, rejecting it")
                cur_result.searcher_score = -1
                continue

        for i in preferredWords:
            if i.lower() in nameLower:
                logger.log('Found preferred word {} in {}'.format(
                    i, cur_result.name))
                cur_result.searcher_score += 1

    results.sort(key=lambda x: x.searcher_score, reverse=True)

    if len(results) == 0 or results[0].searcher_score == -1:
        logger.log("No result picked.", logger.DEBUG)
        return None
    else:
        acceptableResults = list(
            i for i in results
            if i.searcher_score == results[0].searcher_score)

    if len(acceptableResults) == 1:
        logger.log("Picked " + acceptableResults[0].name + " as the best",
                   logger.DEBUG)
        return acceptableResults[0]
    else:
        logger.log('Found {} acceptable results.'.format(
            len(acceptableResults)))
        bestResult = None
        for result in acceptableResults:
            nameLower = result.name.lower()
            if any(i in nameLower for i in ('proper', 'real', 'repack')):
                logger.log("Preferring " + result.name +
                           " (repack/proper/real over nuked)")
                bestResult = result
                break
            elif 'internal' in nameLower:
                logger.log('Lowering preferece for {} (internal)'.format(
                    result.name))
                result.searcher_score -= 10
            elif "xvid" in nameLower:
                logger.log('Lowering preferece for {} (xvid)'.format(
                    result.name))
                result.searcher_score -= 1

        if not bestResult:
            bestResult = sorted(acceptableResults,
                                key=lambda x: x.searcher_score,
                                reverse=True)[0]

        logger.log("Picked " + bestResult.name + " as the best", logger.DEBUG)
        return bestResult
예제 #17
0
class BinNewzProvider(NZBProvider):
    allowedGroups = {
        'abmulti': 'alt.binaries.multimedia',
        'ab.moovee': 'alt.binaries.moovee',
        'abtvseries': 'alt.binaries.tvseries',
        'abtv': 'alt.binaries.tv',
        'a.b.teevee': 'alt.binaries.teevee',
        'abstvdivxf': 'alt.binaries.series.tv.divx.french',
        'abhdtvx264fr': 'alt.binaries.hdtv.x264.french',
        'abmom': 'alt.binaries.mom',
        'abhdtv': 'alt.binaries.hdtv',
        'abboneless': 'alt.binaries.boneless',
        'abhdtvf': 'alt.binaries.hdtv.french',
        'abhdtvx264': 'alt.binaries.hdtv.x264',
        'absuperman': 'alt.binaries.superman',
        'abechangeweb': 'alt.binaries.echange-web',
        'abmdfvost': 'alt.binaries.movies.divx.french.vost',
        'abdvdr': 'alt.binaries.dvdr',
        'abmzeromov': 'alt.binaries.movies.zeromovies',
        'abcfaf': 'alt.binaries.cartoons.french.animes-fansub',
        'abcfrench': 'alt.binaries.cartoons.french',
        'abgougouland': 'alt.binaries.gougouland',
        'abroger': 'alt.binaries.roger',
        'abtatu': 'alt.binaries.tatu',
        'abstvf': 'alt.binaries.series.tv.french',
        'abmdfreposts': 'alt.binaries.movies.divx.french.reposts',
        'abmdf': 'alt.binaries.movies.french',
        'abhdtvfrepost': 'alt.binaries.hdtv.french.repost',
        'abmmkv': 'alt.binaries.movies.mkv',
        'abf-tv': 'alt.binaries.french-tv',
        'abmdfo': 'alt.binaries.movies.divx.french.old',
        'abmf': 'alt.binaries.movies.french',
        'ab.movies': 'alt.binaries.movies',
        'a.b.french': 'alt.binaries.french',
        'a.b.3d': 'alt.binaries.3d',
        'ab.dvdrip': 'alt.binaries.dvdrip',
        'ab.welovelori': 'alt.binaries.welovelori',
        'abblu-ray': 'alt.binaries.blu-ray',
        'ab.bloaf': 'alt.binaries.bloaf',
        'ab.hdtv.german': 'alt.binaries.hdtv.german',
        'abmd': 'alt.binaries.movies.divx',
        'ab.ath': 'alt.binaries.ath',
        'a.b.town': 'alt.binaries.town',
        'a.b.u-4all': 'alt.binaries.u-4all',
        'ab.amazing': 'alt.binaries.amazing',
        'ab.astronomy': 'alt.binaries.astronomy',
        'ab.nospam.cheer': 'alt.binaries.nospam.cheerleaders',
        'ab.worms': 'alt.binaries.worms',
        'abcores': 'alt.binaries.cores',
        'abdvdclassics': 'alt.binaries.dvd.classics',
        'abdvdf': 'alt.binaries.dvd.french',
        'abdvds': 'alt.binaries.dvds',
        'abmdfrance': 'alt.binaries.movies.divx.france',
        'abmisc': 'alt.binaries.misc',
        'abnl': 'alt.binaries.nl',
        'abx': 'alt.binaries.x',
        'abdivxf': 'alt.binaries.divx.french'
    }

    qualityCategories = {3: ['24', '7', '56'], 500: ['44', '53', '59']}

    qualityMinSize = {
        (Quality.SDTV, Quality.SDDVD):
        130,
        Quality.HDTV:
        500,
        (Quality.HDWEBDL, Quality.HDBLURAY, Quality.FULLHDBLURAY, Quality.FULLHDTV, Quality.FULLHDWEBDL):
        600
    }

    url = "http://www.binnews.in/"
    supportsBacklog = True
    nzbDownloaders = [BinSearch(), NZBIndex(),
                      NZBClub()]  #[BinSearch(), NZBIndex(), NZBClub()]

    def __init__(self):
        NZBProvider.__init__(self, "BinnewZ")

    #def is_enabled(self):
    #    return sickbeard.BINNEWZ

    def _get_season_search_strings(self, episode):
        showNam = show_name_helpers.allPossibleShowNames(episode.show)
        showNames = list(set(showNam))
        result = []
        global searchstringlist
        searchstringlist = []
        for showName in showNames:
            result.append(showName + ".saison %2d" % episode.season)
        return result

    def _get_episode_search_strings(self, episode, add_string=''):
        strings = []
        showNam = show_name_helpers.allPossibleShowNames(episode.show)
        showNames = list(set(showNam))
        global searchstringlist
        searchstringlist = []
        for showName in showNames:
            strings.append(
                "%s S%02dE%02d" %
                (showName, episode.scene_season, episode.scene_episode))
            strings.append(
                "%s S%02dE%d" %
                (showName, episode.scene_season, episode.scene_episode))
            strings.append(
                "%s S%dE%02d" %
                (showName, episode.scene_season, episode.scene_episode))
            strings.append(
                "%s %dx%d" %
                (showName, episode.scene_season, episode.scene_episode))
            strings.append(
                "%s S%02d E%02d" %
                (showName, episode.scene_season, episode.scene_episode))
            strings.append(
                "%s S%02d E%d" %
                (showName, episode.scene_season, episode.scene_episode))
            strings.append(
                "%s S%d E%02d" %
                (showName, episode.scene_season, episode.scene_episode))
            strings.append(
                "%s S%02dEp%02d" %
                (showName, episode.scene_season, episode.scene_episode))
            strings.append(
                "%s S%02dEp%d" %
                (showName, episode.scene_season, episode.scene_episode))
            strings.append(
                "%s S%dEp%02d" %
                (showName, episode.scene_season, episode.scene_episode))
            strings.append(
                "%s S%02d Ep%02d" %
                (showName, episode.scene_season, episode.scene_episode))
            strings.append(
                "%s S%02d Ep%d" %
                (showName, episode.scene_season, episode.scene_episode))
            strings.append(
                "%s S%d Ep%02d" %
                (showName, episode.scene_season, episode.scene_episode))
            strings.append(
                "%s S%02d Ep %02d" %
                (showName, episode.scene_season, episode.scene_episode))
            strings.append(
                "%s S%02d Ep %d" %
                (showName, episode.scene_season, episode.scene_episode))
            strings.append(
                "%s S%d Ep %02d" %
                (showName, episode.scene_season, episode.scene_episode))
        return strings

    def _get_title_and_url(self, item):
        cleanTitle = re.sub(r'(\s*\[[\w\s]+\-\w+\])', "", item.title)
        return cleanTitle, item.refererURL

    def get_quality(self, item, anime=False):
        return item.quality

    def buildUrl(self, searchString, quality):
        if quality in self.qualityCategories:
            data = {
                'chkInit': '1',
                'edTitre': searchString,
                'chkTitre': 'on',
                'chkFichier': 'on',
                'chkCat': 'on',
                'cats[]': self.qualityCategories[quality],
                'edAge': '',
                'edYear': ''
            }
        else:
            data = {
                'b_submit': 'BinnewZ',
                'cats[]': 'all',
                'edSearchAll': searchString,
                'sections[]': 'all'
            }
        return data

    def search(self, search_params, age=0, ep_obj=None):
        if search_params is None:
            return []
        logger.log("BinNewz : Searching for " + search_params, logger.DEBUG)
        data = self.buildUrl(search_params.replace('!', ''),
                             ep_obj.show.quality)
        try:
            soup = BeautifulSoup(
                urllib2.urlopen("http://www.binnews.in/_bin/search2.php",
                                urllib.urlencode(data, True)), "html5lib")
        except Exception, e:
            logger.log(u"Error trying to load BinNewz response: " + e,
                       logger.ERROR)
            return []

        results = []
        tables = soup.findAll("table", id="tabliste")
        for table in tables:
            if len(results) > 5:
                break
            rows = table.findAll("tr")
            for row in rows:

                cells = row.select("> td")
                if len(cells) < 11:
                    continue

                name = cells[2].text.strip()
                language = cells[3].find("img").get("src")

                if not "_fr" in language and not "_frq" in language:
                    continue

                detectedlang = ''

                if "_fr" in language:
                    detectedlang = ' truefrench '
                else:
                    detectedlang = ' french '

                # blacklist_groups = [ "alt.binaries.multimedia" ]
                blacklist_groups = []

                newgroupLink = cells[4].find("a")
                newsgroup = None
                if newgroupLink.contents:
                    newsgroup = newgroupLink.contents[0]
                    if newsgroup in self.allowedGroups:
                        newsgroup = self.allowedGroups[newsgroup]
                    else:
                        logger.log(u"Unknown binnewz newsgroup: " + newsgroup,
                                   logger.ERROR)
                        continue
                    if newsgroup in blacklist_groups:
                        logger.log(
                            u"Ignoring result, newsgroup is blacklisted: " +
                            newsgroup, logger.WARNING)
                        continue

                filename = cells[5].contents[0]

                acceptedQualities = Quality.splitQuality(
                    ep_obj.show.quality)[0]
                quality = Quality.nameQuality(filename)
                if quality == Quality.UNKNOWN:
                    quality = self.getReleaseQuality(name)
                if quality not in acceptedQualities:
                    continue
                if filename in searchstringlist:
                    continue

                minSize = self.qualityMinSize[
                    quality] if quality in self.qualityMinSize else 100
                searchItems = []
                #multiEpisodes = False

                rangeMatcher = re.search(
                    "(?i).*(?<![\s\.\-_])[\s\.\-_]+s?(?:aison)?[\s\.\-_]*\d{1,2}[\s\.\-_]?(?:x|dvd|[eéEÉ](?:p|pisodes?)?)[\s\.\-_]*(\d{1,2})(?:(?:[\s\.\-_]*(?:[aàAÀ,/\-\.\s\&_]|et|and|to|x)[\s\.\-_]*(?:x|dvd|[eéEÉ](?:p|pisodes?)?)?[\s\.\-_]*([0-9]{1,2})))+.*",
                    name)
                if rangeMatcher:
                    rangeStart = int(rangeMatcher.group(1))
                    rangeEnd = int(rangeMatcher.group(2))
                    if filename.find("*") != -1:
                        for i in range(rangeStart, rangeEnd + 1):
                            searchItem = filename.replace("**", str(i))
                            searchItem = searchItem.replace("*", str(i))
                            searchItems.append(searchItem)
                    #else:
                    #    multiEpisodes = True

                if len(searchItems) == 0:
                    searchItems.append(filename)

                for searchItem in searchItems:
                    for downloader in self.nzbDownloaders:
                        searchstringlist.append(searchItem)
                        logger.log("Searching for download : " + name +
                                   ", search string = " + searchItem + " on " +
                                   downloader.__class__.__name__)
                        try:
                            binsearch_result = downloader.search(
                                searchItem, minSize, newsgroup)
                            if binsearch_result:
                                binsearch_result.title = search_params
                                binsearch_result.quality = quality
                                #nzbdata = binsearch_result.getNZB()
                                results.append(binsearch_result)
                                logger.log("Found : " + searchItem + " on " +
                                           downloader.__class__.__name__)
                                break
                        except Exception, e:
                            logger.log(
                                "Searching from " +
                                downloader.__class__.__name__ + " failed : " +
                                str(e), logger.ERROR)
예제 #18
0
def pickBestResult(results, show):  # pylint: disable=too-many-branches
    """
    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]

    logger.log("Picking the best result out of " + str([x.name for x in results]), logger.DEBUG)

    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

        logger.log("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:
            logger.log(cur_result.name + " is a quality we know we don't want, rejecting it", logger.DEBUG)
            continue

        if not show_name_helpers.filter_bad_releases(cur_result.name, parse=False, show=show):
            continue

        if hasattr(cur_result, 'size'):
            if sickbeard.USE_FAILED_DOWNLOADS and failed_history.hasFailed(cur_result.name, cur_result.size,
                                                                           cur_result.provider.name):
                logger.log(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 "real" in cur_result.name.lower() or "repack" in cur_result.name.lower():
                logger.log("Preferring " + cur_result.name + " (repack/proper/real over nuked)")
                bestResult = cur_result
            elif "internal" in bestResult.name.lower() and "internal" not in cur_result.name.lower():
                logger.log("Preferring " + cur_result.name + " (normal instead of internal)")
                bestResult = cur_result
            elif "xvid" in bestResult.name.lower() and "x264" in cur_result.name.lower():
                logger.log("Preferring " + cur_result.name + " (x264 over xvid)")
                bestResult = cur_result

    if bestResult:
        logger.log("Picked " + bestResult.name + " as the best", logger.DEBUG)
    else:
        logger.log("No result picked.", logger.DEBUG)

    return bestResult
예제 #19
0
    def massEditSubmit(self,
                       paused=None,
                       default_ep_status=None,
                       anime=None,
                       sports=None,
                       scene=None,
                       season_folders=None,
                       quality_preset=None,
                       subtitles=None,
                       air_by_date=None,
                       anyQualities=None,
                       bestQualities=None,
                       toEdit=None,
                       *args,
                       **kwargs):
        dir_map = {}
        for cur_arg in filter(lambda x: x.startswith('orig_root_dir_'),
                              kwargs):
            dir_map[kwargs[cur_arg]] = ek(
                six.text_type, kwargs[cur_arg.replace('orig_root_dir_',
                                                      'new_root_dir_')],
                'utf-8')

        showIDs = toEdit.split("|")
        errors = []
        for curShow in showIDs:
            curErrors = []
            show_obj = Show.find(sickbeard.showList, int(curShow or 0))
            if not show_obj:
                continue

            cur_root_dir = self.__gooey_path(show_obj._location, 'dirname')
            cur_show_dir = self.__gooey_path(show_obj._location, 'basename')
            if cur_root_dir and dir_map.get(
                    cur_root_dir
            ) and cur_root_dir != dir_map.get(cur_root_dir):
                new_show_dir = ek(os.path.join, dir_map[cur_root_dir],
                                  cur_show_dir)
                logger.log("For show " + show_obj.name +
                           " changing dir from " + show_obj._location +
                           " to " + new_show_dir)
            else:
                new_show_dir = show_obj._location

            new_paused = ('off', 'on')[(paused == 'enable',
                                        show_obj.paused)[paused == 'keep']]
            new_default_ep_status = (
                default_ep_status,
                show_obj.default_ep_status)[default_ep_status == 'keep']
            new_anime = ('off', 'on')[(anime == 'enable',
                                       show_obj.anime)[anime == 'keep']]
            new_sports = ('off', 'on')[(sports == 'enable',
                                        show_obj.sports)[sports == 'keep']]
            new_scene = ('off', 'on')[(scene == 'enable',
                                       show_obj.scene)[scene == 'keep']]
            new_air_by_date = (
                'off', 'on')[(air_by_date == 'enable',
                              show_obj.air_by_date)[air_by_date == 'keep']]
            new_season_folders = ('off', 'on')[(
                season_folders == 'enable',
                show_obj.season_folders)[season_folders == 'keep']]
            new_subtitles = ('off',
                             'on')[(subtitles == 'enable',
                                    show_obj.subtitles)[subtitles == 'keep']]

            if quality_preset == 'keep':
                anyQualities, bestQualities = Quality.splitQuality(
                    show_obj.quality)
            elif try_int(quality_preset, None):
                bestQualities = []

            exceptions_list = []

            curErrors += self.editShow(curShow,
                                       new_show_dir,
                                       anyQualities,
                                       bestQualities,
                                       exceptions_list,
                                       defaultEpStatus=new_default_ep_status,
                                       season_folders=new_season_folders,
                                       paused=new_paused,
                                       sports=new_sports,
                                       subtitles=new_subtitles,
                                       anime=new_anime,
                                       scene=new_scene,
                                       air_by_date=new_air_by_date,
                                       directCall=True)

            if curErrors:
                logger.log("Errors: " + str(curErrors), logger.ERROR)
                errors.append(
                    '<b>{0}:</b>\n<ul>'.format(show_obj.name) + ' '.join(
                        ['<li>{0}</li>'.format(error)
                         for error in curErrors]) + "</ul>")

        if len(errors) > 0:
            ui.notifications.error(
                _('{num_errors:d} error{plural} while saving changes:').format(
                    num_errors=len(errors),
                    plural="" if len(errors) == 1 else "s"), " ".join(errors))

        return self.redirect("/manage/")
예제 #20
0
파일: search.py 프로젝트: Thraxis/pymedusa
def pickBestResult(results, show):  # pylint: disable=too-many-branches
    """
    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]

    logger.log(u"Picking the best result out of " + str([x.name for x in results]), logger.DEBUG)

    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

        logger.log(u"Quality of " + cur_result.name + u" is " + Quality.qualityStrings[cur_result.quality])

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

        if cur_result.quality not in anyQualities + bestQualities:
            logger.log(cur_result.name + u" is a quality we know we don't want, rejecting it", logger.DEBUG)
            continue

        # If doesnt have min seeders OR min leechers then discard it
        if cur_result.seeders not in (-1, None) and cur_result.leechers not in (-1, None) \
            and hasattr(cur_result.provider, 'minseed') and hasattr(cur_result.provider, 'minleech') \
            and (int(cur_result.seeders) < int(cur_result.provider.minseed) or
                 int(cur_result.leechers) < int(cur_result.provider.minleech)):
            logger.log(u"Discarding torrent because it doesn't meet the minimum provider setting "
                       u"S:{0} L:{1}. Result has S:{2} L:{3}".format
                       (cur_result.provider.minseed, cur_result.provider.minleech,
                        cur_result.seeders, cur_result.leechers))
            continue

        show_words = show_name_helpers.show_words(cur_result.show)
        ignore_words = show_words.ignore_words
        require_words = show_words.require_words
        found_ignore_word = show_name_helpers.containsAtLeastOneWord(cur_result.name, ignore_words)
        found_require_word = show_name_helpers.containsAtLeastOneWord(cur_result.name, require_words)

        if ignore_words and found_ignore_word:
            logger.log(u"Ignoring " + cur_result.name + u" based on ignored words filter: " + found_ignore_word,
                       logger.INFO)
            continue

        if require_words and not found_require_word:
            logger.log(u"Ignoring " + cur_result.name + u" based on required words filter: " + require_words,
                       logger.INFO)
            continue

        if not show_name_helpers.filterBadReleases(cur_result.name, parse=False):
            continue

        if hasattr(cur_result, 'size'):
            if sickbeard.USE_FAILED_DOWNLOADS and failed_history.hasFailed(cur_result.name, cur_result.size,
                                                                           cur_result.provider.name):
                logger.log(cur_result.name + u" has previously failed, rejecting it")
                continue
        preferred_words = ''
        if sickbeard.PREFERRED_WORDS:
            preferred_words = sickbeard.PREFERRED_WORDS.lower().split(',')
        undesired_words = ''
        if sickbeard.UNDESIRED_WORDS:
            undesired_words = sickbeard.UNDESIRED_WORDS.lower().split(',')

        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 any(ext in cur_result.name.lower() for ext in preferred_words):
                logger.log(u"Preferring " + cur_result.name + u" (preferred words)")
                bestResult = cur_result
            if cur_result.proper_tags:
                logger.log(u"Preferring " + cur_result.name + u" (repack/proper/real/rerip over nuked)")
                bestResult = cur_result
            elif "internal" in bestResult.name.lower() and "internal" not in cur_result.name.lower():
                logger.log(u"Preferring " + cur_result.name + u" (normal instead of internal)")
                bestResult = cur_result
            elif "xvid" in bestResult.name.lower() and "x264" in cur_result.name.lower():
                logger.log(u"Preferring " + cur_result.name + u" (x264 over xvid)")
                bestResult = cur_result
            if any(ext in bestResult.name.lower() and ext not in cur_result.name.lower() for ext in undesired_words):
                logger.log(u"Dont want this release " + cur_result.name + u" (contains undesired word(s))")
                bestResult = cur_result

    if bestResult:
        logger.log(u"Picked " + bestResult.name + u" as the best", logger.DEBUG)
    else:
        logger.log(u"No result picked.", logger.DEBUG)

    return bestResult
예제 #21
0
def render_renderQualityPill(context,
                             quality,
                             showTitle=False,
                             overrideClass=None):
    __M_caller = context.caller_stack._push_frame()
    try:
        set = context.get('set', UNDEFINED)
        _ = context.get('_', UNDEFINED)
        __M_writer = context.writer()
        __M_writer(u'\n')

        # Build a string of quality names to use as title attribute
        if showTitle:
            allowed_qualities, preferred_qualities = Quality.splitQuality(
                quality)
            title = _('Allowed Quality:') + '\n'
            for curQual in allowed_qualities or [None]:
                title += "  " + Quality.qualityStrings[curQual] + "\n"

            title += "\n" + _('Preferred Quality:') + "\n"
            for curQual in preferred_qualities or [None]:
                title += "  " + Quality.qualityStrings[curQual] + "\n"
        else:
            title = ""

        sum_allowed_qualities = quality & 0xFFFF
        sum_preferred_qualities = quality >> 16
        set_hdtv = {Quality.HDTV, Quality.RAWHDTV, Quality.FULLHDTV}
        set_webdl = {
            Quality.HDWEBDL, Quality.FULLHDWEBDL, Quality.UHD_4K_WEBDL,
            Quality.UHD_8K_WEBDL
        }
        set_bluray = {
            Quality.HDBLURAY, Quality.FULLHDBLURAY, Quality.UHD_4K_BLURAY,
            Quality.UHD_8K_BLURAY
        }
        set_1080p = {
            Quality.FULLHDTV, Quality.FULLHDWEBDL, Quality.FULLHDBLURAY
        }
        set_720p = {
            Quality.HDTV, Quality.RAWHDTV, Quality.HDWEBDL, Quality.HDBLURAY
        }
        set_uhd_4k = {
            Quality.UHD_4K_TV, Quality.UHD_4K_BLURAY, Quality.UHD_4K_WEBDL
        }
        set_uhd_8k = {
            Quality.UHD_8K_TV, Quality.UHD_8K_BLURAY, Quality.UHD_8K_WEBDL
        }

        # If allowed and preferred qualities are the same, show pill as allowed quality
        if sum_allowed_qualities == sum_preferred_qualities:
            quality = sum_allowed_qualities

        if quality in qualityPresets:
            cssClass = qualityPresetStrings[quality]
            qualityString = qualityPresetStrings[quality]
        elif quality in Quality.combinedQualityStrings:
            cssClass = Quality.cssClassStrings[quality]
            qualityString = Quality.combinedQualityStrings[quality]
        elif quality in Quality.qualityStrings:
            cssClass = Quality.cssClassStrings[quality]
            qualityString = Quality.qualityStrings[quality]
        # Check if all sources are HDTV
        elif set(allowed_qualities).issubset(set_hdtv) and set(
                preferred_qualities).issubset(set_hdtv):
            cssClass = Quality.cssClassStrings[Quality.ANYHDTV]
            qualityString = 'HDTV'
        # Check if all sources are WEB-DL
        elif set(allowed_qualities).issubset(set_webdl) and set(
                preferred_qualities).issubset(set_webdl):
            cssClass = Quality.cssClassStrings[Quality.ANYWEBDL]
            qualityString = 'WEB-DL'
        # Check if all sources are BLURAY
        elif set(allowed_qualities).issubset(set_bluray) and set(
                preferred_qualities).issubset(set_bluray):
            cssClass = Quality.cssClassStrings[Quality.ANYBLURAY]
            qualityString = 'BLURAY'
        # Check if all resolutions are 1080p
        elif set(allowed_qualities).issubset(set_1080p) and set(
                preferred_qualities).issubset(set_1080p):
            cssClass = Quality.cssClassStrings[Quality.FULLHDBLURAY]
            qualityString = '1080p'
        # Check if all resolutions are 720p
        elif set(allowed_qualities).issubset(set_720p) and set(
                preferred_qualities).issubset(set_720p):
            cssClass = Quality.cssClassStrings[Quality.HDBLURAY]
            qualityString = '720p'
        # Check if all resolutions are 4K UHD
        elif set(allowed_qualities).issubset(set_uhd_4k) and set(
                preferred_qualities).issubset(set_uhd_4k):
            cssClass = Quality.cssClassStrings[Quality.HDBLURAY]
            qualityString = '4K-UHD'
        # Check if all resolutions are 8K UHD
        elif set(allowed_qualities).issubset(set_uhd_8k) and set(
                preferred_qualities).issubset(set_uhd_8k):
            cssClass = Quality.cssClassStrings[Quality.HDBLURAY]
            qualityString = '8K-UHD'
        else:
            cssClass = "Custom"
            qualityString = "Custom"

        cssClass = overrideClass or "quality " + cssClass

        __M_writer(u'\n<span title="')
        __M_writer(filters.html_escape(unicode(title)))
        __M_writer(u'" class="')
        __M_writer(unicode(cssClass))
        __M_writer(u'">')
        __M_writer(unicode(qualityString))
        __M_writer(u'</span>')
        return ''
    finally:
        context.caller_stack._pop_frame()