def estimate(self, entry): if not all(field in entry for field in ['series_name', 'series_season', 'series_episode']): return with Session() as session: series = session.query(Series).filter(Series.name == entry['series_name']).first() if not series: return episodes = (session.query(Episode).join(Episode.series). filter(Episode.season != None). filter(Series.id == series.id). filter(Episode.season == func.max(Episode.season).select()). order_by(desc(Episode.number)).limit(2).all()) if len(episodes) < 2: return # If last two eps were not contiguous, don't guess if episodes[0].number != episodes[1].number + 1: return # If first_seen in None, return if episodes[0].first_seen is None or episodes[1].first_seen is None: return last_diff = episodes[0].first_seen - episodes[1].first_seen # If last eps were grabbed close together, we might be catching up, don't guess # Or, if last eps were too far apart, don't guess # TODO: What range? if last_diff < timedelta(days=2) or last_diff > timedelta(days=10): return # Estimate next season somewhat more than a normal episode break if entry['series_season'] > episodes[0].season: # TODO: How big should this be? return episodes[0].first_seen + multiply_timedelta(last_diff, 2) # Estimate next episode comes out about same length as last ep span, with a little leeway return episodes[0].first_seen + multiply_timedelta(last_diff, 0.9)
def estimate(self, entry): if all(field in entry for field in ['series_name', 'series_season', 'series_episode']): # Try to get airdate from tvrage first if api_tvrage: season = entry['series_season'] if entry.get('series_id_type') == 'sequence': # Tvrage has absolute numbered shows under season 1 season = 1 log.debug("Querying release estimation for %s S%02dE%02d ..." % (entry['series_name'], season, entry['series_episode'])) try: series_info = lookup_series(name=entry['series_name']) except LookupError as e: log.debug('tvrage lookup error: %s' % e) else: if series_info: try: episode_info = series_info.find_episode(season, entry['series_episode']) if episode_info: return episode_info.airdate else: # If episode does not exist in tvrage database, we always return a future date log.verbose('%s S%02dE%02d does not exist in tvrage database, assuming unreleased', series_info.name, season, entry['series_episode']) return datetime.now() + timedelta(weeks=4) except Exception as e: log.exception(e) else: log.debug('No series info obtained from TVRage to %s' % entry['series_name']) log.debug('No episode info obtained from TVRage for %s season %s episode %s' % (entry['series_name'], entry['series_season'], entry['series_episode'])) # If no results from tvrage, estimate a date based on series history session = Session() series = session.query(Series).filter(Series.name == entry['series_name']).first() if not series: return episodes = (session.query(Episode).join(Episode.series). filter(Episode.season != None). filter(Series.id == series.id). filter(Episode.season == func.max(Episode.season).select()). order_by(desc(Episode.number)).limit(2).all()) if len(episodes) < 2: return # If last two eps were not contiguous, don't guess if episodes[0].number != episodes[1].number + 1: return last_diff = episodes[0].first_seen - episodes[1].first_seen # If last eps were grabbed close together, we might be catching up, don't guess # Or, if last eps were too far apart, don't guess # TODO: What range? if last_diff < timedelta(days=2) or last_diff > timedelta(days=10): return # Estimate next season somewhat more than a normal episode break if entry['series_season'] > episodes[0].season: # TODO: How big should this be? return episodes[0].first_seen + multiply_timedelta(last_diff, 2) # Estimate next episode comes out about same length as last ep span, with a little leeway return episodes[0].first_seen + multiply_timedelta(last_diff, 0.9)
def interval_expired(self, config, task, entries): """ Maintain some limit levels so that we don't hammer search sites with unreasonable amount of queries. :return: Entries that are up for ``config['interval']`` """ config.setdefault('interval', '5 hour') interval = parse_timedelta(config['interval']) if task.options.discover_now: log.info('Ignoring interval because of --discover-now') result = [] interval_count = 0 with Session() as session: for entry in entries: discover_entry = ( session.query(DiscoverEntry) .filter(DiscoverEntry.title == entry['title']) .filter(DiscoverEntry.task == task.name) .first() ) if not discover_entry: log.debug('%s -> No previous run recorded', entry['title']) discover_entry = DiscoverEntry(entry['title'], task.name) session.add(discover_entry) if ( not task.is_rerun and task.options.discover_now ) or not discover_entry.last_execution: # First time we execute (and on --discover-now) we randomize time to avoid clumping delta = multiply_timedelta(interval, random.random()) discover_entry.last_execution = datetime.datetime.now() - delta else: next_time = discover_entry.last_execution + interval log.debug( 'last_time: %r, interval: %s, next_time: %r, ', discover_entry.last_execution, config['interval'], next_time, ) if datetime.datetime.now() < next_time: log.debug('interval not met') interval_count += 1 entry.reject('discover interval not met') entry.complete() continue discover_entry.last_execution = datetime.datetime.now() log.trace('interval passed for %s', entry['title']) result.append(entry) if interval_count and not task.is_rerun: log.verbose( 'Discover interval of %s not met for %s entries. Use --discover-now to override.', config['interval'], interval_count, ) return result
def interval_expired(self, config, task, entries): """ Maintain some limit levels so that we don't hammer search sites with unreasonable amount of queries. :return: Entries that are up for ``config['interval']`` """ config.setdefault('interval', '5 hour') interval = parse_timedelta(config['interval']) if task.options.discover_now: log.info('Ignoring interval because of --discover-now') result = [] interval_count = 0 with Session() as session: for entry in entries: discover_entry = ( session.query(DiscoverEntry) .filter(DiscoverEntry.title == entry['title']) .filter(DiscoverEntry.task == task.name) .first() ) if not discover_entry: log.debug('%s -> No previous run recorded', entry['title']) discover_entry = DiscoverEntry(entry['title'], task.name) session.add(discover_entry) if ( not task.is_rerun and task.options.discover_now ) or not discover_entry.last_execution: # First time we execute (and on --discover-now) we randomize time to avoid clumping delta = multiply_timedelta(interval, random.random()) discover_entry.last_execution = datetime.datetime.now() - delta else: next_time = discover_entry.last_execution + interval log.debug( 'last_time: %r, interval: %s, next_time: %r, ', discover_entry.last_execution, config['interval'], next_time, ) if datetime.datetime.now() < next_time: log.debug('interval not met') interval_count += 1 entry.reject('discover interval not met') entry.complete() continue discover_entry.last_execution = datetime.datetime.now() log.trace('interval passed for %s', entry['title']) result.append(entry) if interval_count and not task.is_rerun: log.verbose( 'Discover interval of %s not met for %s entries. Use --discover-now to override.', config['interval'], interval_count, ) return result
def estimate(self, entry): if all(field in entry for field in ['series_name', 'series_season', 'series_episode']): # Try to get airdate from tvrage first if api_tvrage: season = entry['series_season'] if entry.get('series_id_type') == 'sequence': # Tvrage has absolute numbered shows under season 1 season = 1 log.debug("Querying release estimation for %s S%02dE%02d ..." % (entry['series_name'], season, entry['series_episode'])) try: series_info = lookup_series(name=entry['series_name']) except LookupError as e: log.debug('tvrage lookup error: %s' % e) else: if series_info: try: episode_info = series_info.find_episode(season, entry['series_episode']) if episode_info: return episode_info.airdate else: # If episode does not exist in tvrage database, we always return a future date log.verbose('%s S%02dE%02d does not exist in tvrage database, assuming unreleased', series_info.name, season, entry['series_episode']) return datetime.now() + timedelta(weeks=4) except Exception as e: log.exception(e) else: log.debug('No series info obtained from TVRage to %s' % entry['series_name']) log.debug('No episode info obtained from TVRage for %s season %s episode %s' % (entry['series_name'], entry['series_season'], entry['series_episode'])) # If no results from tvrage, estimate a date based on series history with contextlib.closing(Session()) as session: series = session.query(Series).filter(Series.name == entry['series_name']).first() if not series: return episodes = (session.query(Episode).join(Episode.series). filter(Episode.season != None). filter(Series.id == series.id). filter(Episode.season == func.max(Episode.season).select()). order_by(desc(Episode.number)).limit(2).all()) if len(episodes) < 2: return # If last two eps were not contiguous, don't guess if episodes[0].number != episodes[1].number + 1: return last_diff = episodes[0].first_seen - episodes[1].first_seen # If last eps were grabbed close together, we might be catching up, don't guess # Or, if last eps were too far apart, don't guess # TODO: What range? if last_diff < timedelta(days=2) or last_diff > timedelta(days=10): return # Estimate next season somewhat more than a normal episode break if entry['series_season'] > episodes[0].season: # TODO: How big should this be? return episodes[0].first_seen + multiply_timedelta(last_diff, 2) # Estimate next episode comes out about same length as last ep span, with a little leeway return episodes[0].first_seen + multiply_timedelta(last_diff, 0.9)