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
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
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")
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
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
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
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
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
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
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)
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
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()
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/')
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()
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
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
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)
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
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/")
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
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()