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)
Esempio n. 2
0
    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)
Esempio n. 3
0
    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
Esempio n. 4
0
    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
Esempio n. 5
0
    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)