def validate(self, data): try: qualities.get(data) except ValueError as e: self.errors.add(e.message) return False return True
def prepare_config(self, config): if not isinstance(config, dict): config = {'quality': config} if isinstance(config.get('quality'), basestring): config['quality'] = [config['quality']] # Convert all config parameters from strings to their associated quality object if 'quality' in config: config['quality'] = [quals.get(q) for q in config['quality']] for key in ['min', 'max']: if key in config: config[key] = quals.get(config[key]) return config
def process_timeframe(self, feed, config, eps, series_name): """Runs the timeframe logic to determine if we should wait for a better quality. Saves current best to backlog if timeframe has not expired. Returns: True - if we should keep the quality (or qualities) restriction False - if the quality restriction should be released, due to timeframe expiring """ if 'timeframe' not in config: return True best = eps[0] # parse options amount, unit = config['timeframe'].split(' ') log.debug('amount: %r unit: %r' % (amount, unit)) params = {unit: int(amount)} try: timeframe = timedelta(**params) except TypeError: raise PluginWarning('Invalid time format', log) # Make sure we only start timing from the first seen quality that matches min and max requirements. min_quality = config.get('min_quality') and qualities.get(config['min_quality']) max_quality = config.get('max_quality') and qualities.get(config['max_quality']) first_seen = self.get_first_seen(feed.session, best, min_quality, max_quality) expires = first_seen + timeframe log.debug('timeframe: %s, first_seen: %s, expires: %s' % (timeframe, first_seen, expires)) stop = feed.manager.options.stop_waiting.lower() == series_name.lower() if expires <= datetime.now() or stop: # Expire timeframe, accept anything log.info('Timeframe expired, releasing quality restriction.') return False else: # verbose waiting, add to backlog diff = expires - datetime.now() hours, remainder = divmod(diff.seconds, 3600) hours += diff.days * 24 minutes, seconds = divmod(remainder, 60) entry = self.parser2entry[best] log.info('Timeframe waiting %s for %sh:%smin, currently best is %s' % \ (series_name, hours, minutes, entry['title'])) # add best entry to backlog (backlog is able to handle duplicate adds) if self.backlog: self.backlog.add_backlog(feed, entry) return True
def on_task_start(self, task, config): if isinstance(config, basestring): config = {'any': config} assume = namedtuple('assume', ['target', 'quality']) self.assumptions = [] for target, quality in list(config.items()): log.verbose('New assumption: %s is %s' % (target, quality)) try: target = qualities.Requirements(target) except ValueError: raise plugin.PluginError( '%s is not a valid quality. Forgetting assumption.' % target) try: quality = qualities.get(quality) except ValueError: raise plugin.PluginError( '%s is not a valid quality. Forgetting assumption.' % quality) self.assumptions.append(assume(target, quality)) self.assumptions.sort( key=lambda assumption: self.precision(assumption.target), reverse=True) for assumption in self.assumptions: log.debug('Target %s - Priority %s' % (assumption.target, self.precision(assumption.target)))
def process_quality(self, feed, config, eps): quality = qualities.get(config['quality']) # scan for quality for ep in eps: if quality == ep.quality: entry = self.parser2entry[ep] log.debug('Series accepting. %s meets quality %s' % (entry['title'], quality)) self.accept_series(feed, ep, 'quality met') return True
def validate_quality(self, quality): # Check that the quality is valid # Make sure quality is in the format we expect if quality.upper() == 'ANY': return 'ANY' elif qualities.get(quality, False): return qualities.common_name(quality) else: raise QueueError('ERROR! Unknown quality `%s`' % quality, errno=1)
def process_min_max_quality(self, config, eps): """Filters eps that do not fall between min_quality and max_quality. :returns: A list of eps that are in the acceptable range """ min = qualities.get(config.get('min_quality', ''), qualities.UNKNOWN) max = qualities.get(config.get('max_quality', ''), qualities.max()) log.debug('min: %s max: %s' % (min, max)) result = [] # see if any of the eps match accepted qualities for ep in eps: quality = ep.quality log.debug('ep: %s min: %s max: %s' % (ep.data, min.value, max.value,)) if quality <= max and quality >= min: result.append(ep) if not result: log.debug('no quality meets requirements') return result
def validate_quality(quality): # Check that the quality is valid # Make sure quality is in the format we expect if isinstance(quality, qualities.Quality): if quality.value <= 0: return 'ANY' return quality.name elif quality.upper() == 'ANY': return 'ANY' elif qualities.get(quality, False): return qualities.common_name(quality) else: raise QueueError('ERROR! Unknown quality `%s`' % quality, errno=1)
def operate(self, op, other): if hasattr(other, 'value'): value = other.value elif isinstance(other, basestring): qual = qualities.get(other, False) if qual: value = qual.value else: raise ValueError('%s is not a valid quality' % other) else: raise TypeError('%r cannot be compared to a quality' % other) whens = dict((quality.name, quality.value) for quality in qualities.all()) return op(case(value=self.__clause_element__(), whens=whens, else_=0), value)
def process_quality(self, feed, config, eps): """ Accepts first episode matching the quality configured for the series. :return: True if accepted something """ quality = qualities.get(config['quality']) # scan for quality for ep in eps: if quality == ep.quality: entry = self.parser2entry[ep] log.debug('Series accepting. %s meets quality %s' % (entry['title'], quality)) feed.accept(self.parser2entry[ep], 'quality met') return True
def on_task_start(self, task, config): if isinstance(config, basestring): config = {'any': config} assume = namedtuple('assume', ['target', 'quality']) self.assumptions = [] for target, quality in config.items(): log.verbose('New assumption: %s is %s' % (target, quality)) try: target = qualities.Requirements(target) except: raise plugin.PluginError('%s is not a valid quality. Forgetting assumption.' % target) try: quality = qualities.get(quality) except: raise plugin.PluginError('%s is not a valid quality. Forgetting assumption.' % quality) self.assumptions.append(assume(target, quality)) self.assumptions.sort(key=lambda assumption: self.precision(assumption.target), reverse=True) for assumption in self.assumptions: log.debug('Target %s - Priority %s' % (assumption.target, self.precision(assumption.target)))
def on_task_start(self, task, config): if isinstance(config, basestring): config = {"any": config} assume = namedtuple("assume", ["target", "quality"]) self.assumptions = [] for target, quality in config.items(): log.verbose("New assumption: %s is %s" % (target, quality)) try: target = qualities.Requirements(target) except ValueError: raise plugin.PluginError("%s is not a valid quality. Forgetting assumption." % target) try: quality = qualities.get(quality) except ValueError: raise plugin.PluginError("%s is not a valid quality. Forgetting assumption." % quality) self.assumptions.append(assume(target, quality)) self.assumptions.sort(key=lambda assumption: self.precision(assumption.target), reverse=True) for assumption in self.assumptions: log.debug("Target %s - Priority %s" % (assumption.target, self.precision(assumption.target)))
def process_qualities(self, feed, config, eps): """Handles all modes that can accept more than one quality per episode. (qualities, upgrade) Returns: True - if at least one wanted quality has been downloaded or accepted False - if no wanted qualities have been accepted """ # Get list of already downloaded qualities downloaded_qualities = [r.quality for r in self.get_downloaded(feed.session, eps[0].name, eps[0].identifier)] log.debug('downloaded_qualities: %s' % downloaded_qualities) # If quality is configured, make sure it is defined in wanted qualities if config.get('quality'): config.setdefault('qualities', []).append(config['quality']) # If qualities key is configured, we only want qualities defined in it. wanted_qualities = set([qualities.get(name) for name in config.get('qualities', [])]) log.debug('Wanted qualities: %s' % wanted_qualities) def wanted(quality): """Returns True if we want this quality based on the config options.""" wanted = not wanted_qualities or quality in wanted_qualities if config.get('upgrade'): wanted = wanted and quality > max(downloaded_qualities or [qualities.UNKNOWN]) return wanted for ep in eps: log.debug('ep: %s quality: %s' % (ep.data, ep.quality)) if not wanted(ep.quality): log.debug('%s is unwanted quality' % ep.quality) continue if ep.quality in downloaded_qualities: feed.reject(self.parser2entry[ep], 'quality downloaded') else: feed.accept(self.parser2entry[ep], 'quality wanted') downloaded_qualities.append(ep.quality) # don't accept more of these return bool(downloaded_qualities)
def add_episode_term(self, episode): self.term_names.append("Episode %02d" % episode) T411API_DOMAIN_URL = "api.t411.li" T411API_CATEGORY_TREE_PATH = "/categories/tree/" T411API_AUTH_PATH = "/auth" T411API_TERMS_PATH = "/terms/tree/" T411API_SEARCH_PATH = "/torrents/search/" T411API_DOWNLOAD_PATH = "/torrents/download/" T411API_DETAILS_PATH = "/torrents/details/" T411_TERM_TYPE_ID_VIDEO_QUALITY = 7 T411_VIDEO_QUALITY_MAP = { 8: qualities.get("bluray"), 1171: qualities.get("bluray"), 17: qualities.get("bluray 1080p"), 1220: qualities.get("remux"), 13: qualities.get("dvdrip"), 14: qualities.get("dvdrip"), 10: qualities.get("dvdrip"), 1208: qualities.get("bluray 1080p"), 1218: qualities.get("bluray 720p"), 16: qualities.get("bluray 1080p"), 1219: qualities.get("bluray"), 15: qualities.get("bluray 720p"), 11: qualities.get("tvrip"), 1162: qualities.get("hdtv 1080p"), 12: qualities.get("hdtv 720p"), 18: qualities.get("ppvrip"),
def is_quality(instance): if not isinstance(instance, str_types): return True return qualities.get(instance)
def getter(self): return qualities.get(getattr(self, text_attr))
def add_episode_term(self, episode): self.term_names.append("Episode %02d" % episode) T411API_DOMAIN_URL = "api.t411.ai" T411API_CATEGORY_TREE_PATH = "/categories/tree/" T411API_AUTH_PATH = "/auth" T411API_TERMS_PATH = "/terms/tree/" T411API_SEARCH_PATH = "/torrents/search/" T411API_DOWNLOAD_PATH = "/torrents/download/" T411API_DETAILS_PATH = "/torrents/details/" T411_TERM_TYPE_ID_VIDEO_QUALITY = 7 T411_VIDEO_QUALITY_MAP = { 8: qualities.get("bluray"), 1171: qualities.get("bluray"), 17: qualities.get("bluray 1080p"), 1220: qualities.get("remux"), 13: qualities.get("dvdrip"), 14: qualities.get("dvdrip"), 10: qualities.get("dvdrip"), 1208: qualities.get("bluray 1080p"), 1218: qualities.get("bluray 720p"), 16: qualities.get("bluray 1080p"), 1219: qualities.get("bluray"), 15: qualities.get("bluray 720p"), 11: qualities.get("tvrip"), 1162: qualities.get("hdtv 1080p"), 12: qualities.get("hdtv 720p"), 18: qualities.get("ppvrip"),
def test_get(self): assert qualities.get('foobar') is qualities.UNKNOWN, 'unknown not returned' assert qualities.get('foobar', default='xxx') is not qualities.UNKNOWN, 'arg default not returned'