예제 #1
0
    def on_search_complete(self, entry, task=None, identified_by=None, **kwargs):
        """Decides whether we should look for next ep/season based on whether we found/accepted any episodes."""
        with Session() as session:
            series = session.query(Series).filter(Series.name == entry['series_name']).first()
            latest = get_latest_release(series)
            db_release = (session.query(Release).join(Release.episode).join(Episode.series).
                       filter(Series.name == entry['series_name']).
                       filter(Episode.season == entry['series_season']).
                       filter(Episode.number == entry['series_episode']).first())

            if entry.accepted:
                log.debug('%s %s was accepted, rerunning to look for next ep.' %
                          (entry['series_name'], entry['series_id']))
                self.rerun_entries.append(self.search_entry(series,
                                                            entry['series_season'],
                                                            entry['series_episode'] + 1,
                                                            task))
                task.rerun()
            elif db_release:
                # There are know releases of this episode, but none were accepted
                return
            elif latest and identified_by == 'ep' and (
                    entry['series_season'] == latest.season and entry['series_episode'] == latest.number + 1):
                # We searched for next predicted episode of this season unsuccessfully, try the next season
                self.rerun_entries.append(self.search_entry(series, latest.season + 1, 1, task))
                log.debug('%s %s not found, rerunning to look for next season' %
                          (entry['series_name'], entry['series_id']))
                task.rerun()
예제 #2
0
 def on_search_complete(self,
                        entry,
                        task=None,
                        identified_by=None,
                        **kwargs):
     with closing(Session()) as session:
         series = session.query(Series).filter(
             Series.name == entry['series_name']).first()
         latest = get_latest_release(series)
         episode = (session.query(Episode).join(Episode.series).filter(
             Series.name == entry['series_name']).filter(
                 Episode.season == entry['series_season']).filter(
                     Episode.number == entry['series_episode']).first())
         if entry.accepted or (episode and len(episode.releases) > 0):
             self.try_next_season.pop(entry['series_name'], None)
             task.rerun()
         elif latest and latest.season == entry['series_season']:
             if identified_by != 'ep':
                 # Do not try next season if this is not an 'ep' show
                 return
             if entry['series_name'] not in self.try_next_season:
                 self.try_next_season[entry['series_name']] = True
                 task.rerun()
             else:
                 # Don't try a second time
                 self.try_next_season[entry['series_name']] = False
예제 #3
0
    def on_search_complete(self, entry, task=None, identified_by=None, **kwargs):
        """Decides whether we should look for next ep/season based on whether we found/accepted any episodes."""
        with Session() as session:
            series = session.query(Series).filter(Series.name == entry['series_name']).first()
            latest = get_latest_release(series)
            db_release = (session.query(EpisodeRelease).join(EpisodeRelease.episode).join(Episode.series).
                          filter(Series.name == entry['series_name']).
                          filter(Episode.season == entry['series_season']).
                          filter(Episode.number == entry['series_episode']).first())

            if entry.accepted:
                log.debug('%s %s was accepted, rerunning to look for next ep.' %
                          (entry['series_name'], entry['series_id']))
                self.rerun_entries.append(self.search_entry(series,
                                                            entry['series_season'],
                                                            entry['series_episode'] + 1,
                                                            task))
                # Increase rerun limit by one if we have matches, this way
                # we keep searching as long as matches are found!
                # TODO: this should ideally be in discover so it would be more generic
                task.max_reruns += 1
                task.rerun(plugin='next_series_episodes', reason='Look for next episode')
            elif db_release:
                # There are know releases of this episode, but none were accepted
                return
            elif latest and identified_by == 'ep' and (
                            entry['series_season'] == latest.season and entry['series_episode'] == latest.number + 1):
                # We searched for next predicted episode of this season unsuccessfully, try the next season
                self.rerun_entries.append(self.search_entry(series, latest.season + 1, 1, task))
                log.debug('%s %s not found, rerunning to look for next season' %
                          (entry['series_name'], entry['series_id']))
                task.rerun(plugin='next_series_episodes', reason='Look for next season')
예제 #4
0
    def on_search_complete(self, entry, task=None, identified_by=None, **kwargs):
        """Decides whether we should look for next ep/season based on whether we found/accepted any episodes."""
        with Session() as session:
            series = session.query(Series).filter(Series.name == entry['series_name']).first()
            latest = get_latest_release(series)
            db_release = (session.query(Release).join(Release.episode).join(Episode.series).
                          filter(Series.name == entry['series_name']).
                          filter(Episode.season == entry['series_season']).
                          filter(Episode.number == entry['series_episode']).first())

            if entry.accepted:
                log.debug('%s %s was accepted, rerunning to look for next ep.' %
                          (entry['series_name'], entry['series_id']))
                self.rerun_entries.append(self.search_entry(series,
                                                            entry['series_season'],
                                                            entry['series_episode'] + 1,
                                                            task))
                # Increase rerun limit by one if we have matches, this way
                # we keep searching as long as matches are found!
                # TODO: this should ideally be in discover so it would be more generic
                task.max_reruns += 1
                task.rerun(plugin='next_series_episodes', reason='Look for next episode')
            elif db_release:
                # There are know releases of this episode, but none were accepted
                return
            elif latest and identified_by == 'ep' and (
                    entry['series_season'] == latest.season and entry['series_episode'] == latest.number + 1):
                # We searched for next predicted episode of this season unsuccessfully, try the next season
                self.rerun_entries.append(self.search_entry(series, latest.season + 1, 1, task))
                log.debug('%s %s not found, rerunning to look for next season' %
                          (entry['series_name'], entry['series_id']))
                task.rerun(plugin='next_series_episodes', reason='Look for next season')
예제 #5
0
파일: series.py 프로젝트: ARLahan/Flexget
def display_summary(options):
    """
    Display series summary.
    :param options: argparse options from the CLI
    """
    formatting = ' %-30s %-10s %-10s %-20s'
    console(formatting % ('Name', 'Latest', 'Age', 'Downloaded'))
    console('-' * 79)

    session = Session()
    try:
        query = (session.query(Series).outerjoin(Series.episodes).outerjoin(Episode.releases).
                 outerjoin(Series.in_tasks).group_by(Series.id))
        if options.configured == 'configured':
            query = query.having(func.count(SeriesTask.id) >= 1)
        elif options.configured == 'unconfigured':
            query = query.having(func.count(SeriesTask.id) < 1)
        if options.premieres:
            query = (query.having(func.max(Episode.season) <= 1).having(func.max(Episode.number) <= 2).
                     having(func.count(SeriesTask.id) < 1)).filter(Release.downloaded == True)
        if options.new:
            query = query.having(func.max(Episode.first_seen) > datetime.now() - timedelta(days=options.new))
        if options.stale:
            query = query.having(func.max(Episode.first_seen) < datetime.now() - timedelta(days=options.stale))
        for series in query.order_by(Series.name).yield_per(10):
            series_name = series.name
            if len(series_name) > 30:
                series_name = series_name[:27] + '...'

            new_ep = ' '
            behind = 0
            status = 'N/A'
            age = 'N/A'
            episode_id = 'N/A'
            latest = get_latest_release(series)
            if latest:
                if latest.first_seen > datetime.now() - timedelta(days=2):
                    new_ep = '>'
                behind = new_eps_after(latest)
                status = get_latest_status(latest)
                age = latest.age
                episode_id = latest.identifier

            if behind:
                episode_id += ' +%s' % behind

            console(new_ep + formatting[1:] % (series_name, episode_id, age, status))
            if behind >= 3:
                console(' ! Latest download is %d episodes behind, this may require '
                        'manual intervention' % behind)

        console('-' * 79)
        console(' > = new episode ')
        console(' Use `flexget series show NAME` to get detailed information')
    finally:
        session.close()
예제 #6
0
def series_details(show, begin=False, latest=False):
    series_dict = {
        'id': show.id,
        'name': show.name,
        'alternate_names': [n.alt_name for n in show.alternate_names],
        'in_tasks': [_show.name for _show in show.in_tasks]
    }
    if begin:
        series_dict['begin_episode'] = show.begin.to_dict() if show.begin else None
    if latest:
        latest_ep = series.get_latest_release(show)
        series_dict['latest_episode'] = latest_ep.to_dict() if latest_ep else None
        if latest_ep:
            series_dict['latest_episode']['latest_release'] = latest_ep.latest_release.to_dict()
    return series_dict
예제 #7
0
파일: series.py 프로젝트: jawilson/Flexget
def series_details(show, begin=False, latest=False):
    series_dict = {
        "id": show.id,
        "name": show.name,
        "alternate_names": [n.alt_name for n in show.alternate_names],
        "in_tasks": [_show.name for _show in show.in_tasks],
    }
    if begin:
        series_dict["begin_episode"] = show.begin.to_dict() if show.begin else None
    if latest:
        latest_ep = series.get_latest_release(show)
        series_dict["latest_episode"] = latest_ep.to_dict() if latest_ep else None
        if latest_ep:
            series_dict["latest_episode"]["latest_release"] = latest_ep.latest_release.to_dict()
    return series_dict
예제 #8
0
def get_series_details(show):
    latest_ep = series.get_latest_release(show)
    begin_ep = show.begin

    if begin_ep:
        begin_ep_id = begin_ep.id
        begin_ep_identifier = begin_ep.identifier
    else:
        begin_ep_id = begin_ep_identifier = None

    begin = {
        'episode_id': begin_ep_id,
        'episode_identifier': begin_ep_identifier
    }

    if latest_ep:
        latest_ep_id = latest_ep.id
        latest_ep_identifier = latest_ep.identifier
        latest_ep_age = latest_ep.age
        new_eps_after_latest_ep = series.new_eps_after(latest_ep)
        release = get_release_details(
            sorted(latest_ep.downloaded_releases,
                   key=lambda release: release.first_seen
                   if release.downloaded else None,
                   reverse=True)[0])
    else:
        latest_ep_id = latest_ep_identifier = latest_ep_age = new_eps_after_latest_ep = release = None

    latest = {
        'episode_id': latest_ep_id,
        'episode_identifier': latest_ep_identifier,
        'episode_age': latest_ep_age,
        'number_of_episodes_behind': new_eps_after_latest_ep,
        'last_downloaded_release': release
    }

    show_item = {
        'show_id': show.id,
        'show_name': show.name,
        'alternate_names': [n.alt_name for n in show.alternate_names],
        'begin_episode': begin,
        'latest_downloaded_episode': latest,
        'in_tasks': [_show.name for _show in show.in_tasks]
    }
    return show_item
예제 #9
0
def get_series_details(show):
    latest_ep = series.get_latest_release(show)
    begin_ep = show.begin

    if begin_ep:
        begin_ep_id = begin_ep.id
        begin_ep_identifier = begin_ep.identifier
    else:
        begin_ep_id = begin_ep_identifier = None

    begin = {
        'episode_id': begin_ep_id,
        'episode_identifier': begin_ep_identifier
    }

    if latest_ep:
        latest_ep_id = latest_ep.id
        latest_ep_identifier = latest_ep.identifier
        latest_ep_age = latest_ep.age
        new_eps_after_latest_ep = series.new_eps_after(latest_ep)
        release = get_release_details(
            sorted(latest_ep.downloaded_releases,
                   key=lambda release: release.first_seen if release.downloaded else None, reverse=True)[0])
    else:
        latest_ep_id = latest_ep_identifier = latest_ep_age = new_eps_after_latest_ep = release = None

    latest = {
        'episode_id': latest_ep_id,
        'episode_identifier': latest_ep_identifier,
        'episode_age': latest_ep_age,
        'number_of_episodes_behind': new_eps_after_latest_ep,
        'last_downloaded_release': release
    }

    show_item = {
        'show_id': show.id,
        'show_name': show.name,
        'alternate_names': [n.alt_name for n in show.alternate_names],
        'begin_episode': begin,
        'latest_downloaded_episode': latest,
        'in_tasks': [_show.name for _show in show.in_tasks]
    }
    return show_item
예제 #10
0
 def on_search_complete(self, entry, task=None, identified_by=None, **kwargs):
     series = task.session.query(Series).filter(Series.name == entry['series_name']).first()
     latest = get_latest_release(series)
     episode = (task.session.query(Episode).join(Episode.series).
                filter(Series.name == entry['series_name']).
                filter(Episode.season == entry['series_season']).
                filter(Episode.number == entry['series_episode']).
                first())
     if entry.accepted or (episode and len(episode.releases) > 0):
         self.try_next_season.pop(entry['series_name'], None)
         task.rerun()
     elif latest and latest.season == entry['series_season']:
         if identified_by != 'ep':
             # Do not try next season if this is not an 'ep' show
             return
         if entry['series_name'] not in self.try_next_season:
             self.try_next_season[entry['series_name']] = True
             task.rerun()
         else:
             # Don't try a second time
             self.try_next_season[entry['series_name']] = False
예제 #11
0
    def on_search_complete(self,
                           entry,
                           task=None,
                           identified_by=None,
                           **kwargs):
        """Decides whether we should look for next ep/season based on whether we found/accepted any episodes."""
        with Session() as session:
            series = session.query(Series).filter(
                Series.name == entry['series_name']).first()
            latest = get_latest_release(series)
            db_release = (session.query(Release).join(Release.episode).join(
                Episode.series).filter(
                    Series.name == entry['series_name']).filter(
                        Episode.season == entry['series_season']).filter(
                            Episode.number == entry['series_episode']).first())

            if entry.accepted:
                log.debug(
                    '%s %s was accepted, rerunning to look for next ep.' %
                    (entry['series_name'], entry['series_id']))
                self.rerun_entries.append(
                    self.search_entry(series, entry['series_season'],
                                      entry['series_episode'] + 1, task))
                task.rerun()
            elif db_release:
                # There are know releases of this episode, but none were accepted
                return
            elif latest and identified_by == 'ep' and (
                    entry['series_season'] == latest.season
                    and entry['series_episode'] == latest.number + 1):
                # We searched for next predicted episode of this season unsuccessfully, try the next season
                self.rerun_entries.append(
                    self.search_entry(series, latest.season + 1, 1, task))
                log.debug(
                    '%s %s not found, rerunning to look for next season' %
                    (entry['series_name'], entry['series_id']))
                task.rerun()
    def on_task_input(self, task, config):
        if not config:
            return
        if isinstance(config, bool):
            config = {}

        if task.is_rerun:
            # Just return calculated next eps on reruns
            entries = self.rerun_entries
            self.rerun_entries = []
            return entries
        else:
            self.rerun_entries = []

        threshold = config.get('threshold')

        entries = []
        impossible = {}
        with Session() as session:
            for seriestask in session.query(SeriesTask).filter(SeriesTask.name == task.name).all():
                series = seriestask.series
                log.trace('evaluating %s', series.name)
                if not series:
                    # TODO: How can this happen?
                    log.debug('Found SeriesTask item without series specified. Cleaning up.')
                    session.delete(seriestask)
                    continue

                if series.identified_by not in ['ep']:
                    log.trace('unsupported identified_by scheme')
                    reason = series.identified_by or 'auto'
                    impossible.setdefault(reason, []).append(series.name)
                    continue

                low_season = 0
                # Don't look for seasons older than begin ep
                if series.begin and series.begin.season and series.begin.season > 1:
                    low_season = max(series.begin.season - 1, 0)

                new_season = None
                check_downloaded = not config.get('backfill')
                latest_season = get_latest_release(series, downloaded=check_downloaded)
                if latest_season:
                    if latest_season.season <= low_season:
                        latest_season = new_season = low_season + 1
                    elif latest_season.season in series.completed_seasons:
                        latest_season = new_season = latest_season.season + 1
                    else:
                        latest_season = latest_season.season
                else:
                    latest_season = low_season + 1

                if (latest_season - low_season > MAX_SEASON_DIFF_WITHOUT_BEGIN and not series.begin) or (
                        series.begin and latest_season - series.begin.season > MAX_SEASON_DIFF_WITH_BEGIN):
                    if series.begin:
                        log.error('Series `%s` has a begin episode set (`%s`), but the season currently being processed'
                                  ' (%s) is %s seasons later than it. To prevent emitting incorrect seasons, this '
                                  'series will not emit unless the begin episode is adjusted to a season that is less '
                                  'than %s seasons from season %s.', series.name, series.begin.identifier,
                                  latest_season, (latest_season - series.begin.season), MAX_SEASON_DIFF_WITH_BEGIN,
                                  latest_season)
                    else:
                        log.error('Series `%s` does not have a begin episode set and continuing this task would result '
                                  'in more than %s seasons being emitted. To prevent emitting incorrect seasons, this '
                                  'series will not emit unless the begin episode is set in your series config or by '
                                  'using the CLI subcommand `series begin "%s" <SxxExx>`.', series.name,
                                  MAX_SEASON_DIFF_WITHOUT_BEGIN, series.name)
                    continue
                for season in range(latest_season, low_season, -1):
                    if season in series.completed_seasons:
                        log.debug('season %s is marked as completed, skipping', season)
                        continue
                    if threshold is not None and series.episodes_for_season(season) > threshold:
                        log.debug('season %s has met threshold of threshold of %s, skipping', season, threshold)
                        continue
                    log.trace('Evaluating season %s for series `%s`', season, series.name)
                    latest = get_latest_release(series, season=season, downloaded=check_downloaded)
                    if series.begin and season == series.begin.season and (not latest or latest < series.begin):
                        # In case series.begin season is already completed, look in next available season
                        lookup_season = series.begin.season
                        while lookup_season in series.completed_seasons:
                            lookup_season += 1
                        entries.append(self.search_entry(series, lookup_season, task))
                    elif latest:
                        entries.append(self.search_entry(series, latest.season, task))
                    # First iteration of a new season with no show begin and show has downloads
                    elif new_season and season == new_season:
                        entries.append(self.search_entry(series, season, task))
                    else:
                        if config.get('from_start') or config.get('backfill'):
                            entries.append(self.search_entry(series, season, task))
                        else:
                            log.verbose('Series `%s` has no history. Set the begin option in your config, '
                                        'or use the CLI subcommand `series begin "%s" <SxxExx>` '
                                        'to set the first episode to emit', series.name, series.name)
                            break
                    # Skip older seasons if we are not in backfill mode
                    if not config.get('backfill'):
                        log.debug('backfill is not enabled; skipping older seasons')
                        break

        for reason, series in impossible.items():
            log.verbose('Series `%s` with identified_by value `%s` are not supported. ',
                        ', '.join(sorted(series)), reason)

        return entries
예제 #13
0
    def on_task_input(self, task, config):
        if not config:
            return
        if isinstance(config, bool):
            config = {}

        if task.is_rerun:
            # Just return calculated next eps on reruns
            entries = self.rerun_entries
            self.rerun_entries = []
            return entries
        else:
            self.rerun_entries = []

        entries = []
        impossible = {}
        with Session() as session:
            for seriestask in session.query(SeriesTask).filter(SeriesTask.name == task.name).all():
                series = seriestask.series
                log.trace('evaluating %s', series.name)
                if not series:
                    # TODO: How can this happen?
                    log.debug('Found SeriesTask item without series specified. Cleaning up.')
                    session.delete(seriestask)
                    continue

                if series.identified_by not in ['ep', 'sequence']:
                    log.trace('unsupported identified_by scheme')
                    reason = series.identified_by or 'auto'
                    impossible.setdefault(reason, []).append(series.name)
                    continue

                low_season = 0 if series.identified_by == 'ep' else -1
                # Don't look for seasons older than begin ep
                if series.begin and series.begin.season and series.begin.season > 1:
                    # begin-1 or the range() loop will never get to the begin season
                    low_season = max(series.begin.season - 1, 0)

                new_season = None
                check_downloaded = not config.get('backfill')
                latest_season = get_latest_release(series, downloaded=check_downloaded)
                if latest_season:
                    if latest_season.season <= low_season:
                        latest_season = new_season = low_season + 1
                    elif latest_season.season in series.completed_seasons:
                        latest_season = new_season = latest_season.season + 1
                    else:
                        latest_season = latest_season.season
                else:
                    latest_season = low_season + 1

                for season in range(latest_season, low_season, -1):
                    if season in series.completed_seasons:
                        log.debug('season %s is marked as completed, skipping', season)
                        continue
                    log.trace('Evaluating episodes for series %s, season %d', series.name, season)
                    latest = get_latest_release(series, season=season, downloaded=check_downloaded)
                    if series.begin and season == series.begin.season and (not latest or latest < series.begin):
                        # In case series.begin season is already completed, look in next available season
                        lookup_season = series.begin.season
                        ep_number = series.begin.number
                        while lookup_season in series.completed_seasons:
                            lookup_season += 1
                            # If season number was bumped, start looking for ep 1
                            ep_number = 1
                        entries.append(self.search_entry(series, lookup_season, ep_number, task))
                    elif latest and not config.get('backfill'):
                        entries.append(self.search_entry(series, latest.season, latest.number + 1, task))
                    elif latest:
                        start_at_ep = 1
                        episodes_this_season = (session.query(Episode).
                                                filter(Episode.series_id == series.id).
                                                filter(Episode.season == season))
                        if series.identified_by == 'sequence':
                            # Don't look for missing too far back with sequence shows
                            start_at_ep = max(latest.number - 10, 1)
                            episodes_this_season = episodes_this_season.filter(Episode.number >= start_at_ep)
                        latest_ep_this_season = episodes_this_season.order_by(desc(Episode.number)).first()
                        if latest_ep_this_season:
                            downloaded_this_season = (episodes_this_season.join(Episode.releases).
                                                      filter(EpisodeRelease.downloaded == True).all())
                            # Calculate the episodes we still need to get from this season
                            if series.begin and series.begin.season == season:
                                start_at_ep = max(start_at_ep, series.begin.number)
                            eps_to_get = list(range(start_at_ep, latest_ep_this_season.number + 1))
                            for ep in downloaded_this_season:
                                try:
                                    eps_to_get.remove(ep.number)
                                except ValueError:
                                    pass
                            entries.extend(self.search_entry(series, season, x, task, rerun=False) for x in eps_to_get)
                            # If we have already downloaded the latest known episode, try the next episode
                            if latest_ep_this_season.releases:
                                entries.append(
                                    self.search_entry(series, season, latest_ep_this_season.number + 1, task))
                        else:
                            # No episode means that latest is a season pack, emit episode 1
                            entries.append(self.search_entry(series, season, 1, task))
                    # First iteration of a new season with no show begin and show has downloads
                    elif new_season and season == new_season:
                        entries.append(self.search_entry(series, season, 1, task))
                    else:
                        if config.get('from_start') or config.get('backfill'):
                            entries.append(self.search_entry(series, season, 1, task))
                        else:
                            log.verbose('Series `%s` has no history. Set begin option, '
                                        'or use CLI `series begin` '
                                        'subcommand to set first episode to emit', series.name)
                            break
                    # Skip older seasons if we are not in backfill mode
                    if not config.get('backfill'):
                        log.debug('backfill is not enabled; skipping older seasons')
                        break

        for reason, series in impossible.items():
            log.verbose('Series `%s` with identified_by value `%s` are not supported. ',
                        ', '.join(sorted(series)), reason)

        return entries
예제 #14
0
    def on_task_input(self, task, config):
        if not config:
            return
        if isinstance(config, bool):
            config = {}

        if task.is_rerun:
            # Just return calculated next eps on reruns
            entries = self.rerun_entries
            self.rerun_entries = []
            return entries
        else:
            self.rerun_entries = []

        entries = []
        impossible = {}
        with Session() as session:
            for seriestask in session.query(SeriesTask).filter(SeriesTask.name == task.name).all():
                series = seriestask.series
                log.trace('evaluating %s', series.name)
                if not series:
                    # TODO: How can this happen?
                    log.debug('Found SeriesTask item without series specified. Cleaning up.')
                    session.delete(seriestask)
                    continue

                if series.identified_by not in ['ep']:
                    log.trace('unsupported identified_by scheme')
                    reason = series.identified_by or 'auto'
                    impossible.setdefault(reason, []).append(series.name)
                    continue

                low_season = 0

                check_downloaded = not config.get('backfill')
                latest_season = get_latest_release(series, downloaded=check_downloaded)
                if latest_season:
                    latest_season = latest_season.season + 1 if latest_season.season in series.completed_seasons \
                        else latest_season.season
                else:
                    latest_season = low_season + 1

                for season in range(latest_season, low_season, -1):
                    if season in series.completed_seasons:
                        log.debug('season %s is marked as completed, skipping', season)
                        continue
                    log.trace('Adding episodes for series %s season %d', series.name, season)
                    latest = get_latest_release(series, season=season, downloaded=check_downloaded)
                    if series.begin and (not latest or latest < series.begin):
                        # In case series.begin season is already completed, look in next available season
                        lookup_season = series.begin.season
                        while lookup_season in series.completed_seasons:
                            lookup_season += 1
                        entries.append(self.search_entry(series, lookup_season, task))
                    elif latest:
                        entries.append(self.search_entry(series, latest.season, task))
                    else:
                        if config.get('from_start') or config.get('backfill'):
                            entries.append(self.search_entry(series, season, 1, task))
                        else:
                            log.verbose('Series `%s` has no history. Set begin option, '
                                        'or use CLI `series begin` '
                                        'subcommand to set first episode to emit', series.name)
                            break
                    # Skip older seasons if we are not in backfill mode
                    if not config.get('backfill'):
                        break
                    # Don't look for seasons older than begin ep
                    if series.begin and series.begin.season >= season:
                        break

        for reason, series in impossible.items():
            log.verbose('Series `%s` with identified_by value `%s` are not supported. ',
                        ', '.join(sorted(series)), reason)

        return entries
예제 #15
0
def display_summary(options):
    """
    Display series summary.
    :param options: argparse options from the CLI
    """
    porcelain = options.table_type == 'porcelain'
    with Session() as session:
        kwargs = {
            'configured': options.configured,
            'premieres': options.premieres,
            'session': session,
            'sort_by': options.sort_by,
            'descending': options.order
        }
        if options.new:
            kwargs['status'] = 'new'
            kwargs['days'] = options.new
        elif options.stale:
            kwargs['status'] = 'stale'
            kwargs['days'] = options.stale
        if options.sort_by == 'name':
            kwargs['sort_by'] = 'show_name'
        else:
            kwargs['sort_by'] = 'last_download_date'

        query = get_series_summary(**kwargs)
        header = ['Name', 'Latest', 'Age', 'Downloaded', 'Identified By']
        for index, value in enumerate(header):
            if value.lower() == options.sort_by:
                header[index] = colorize(SORT_COLUMN_COLOR, value)

        table_data = [header]
        for series in query:
            name_column = series.name

            behind = (0, )
            latest_release = '-'
            age_col = '-'
            episode_id = '-'
            latest = get_latest_release(series)
            identifier_type = series.identified_by
            if identifier_type == 'auto':
                identifier_type = colorize('yellow', 'auto')
            if latest:
                behind = new_entities_after(latest)
                latest_release = get_latest_status(latest)
                # colorize age
                age_col = latest.age
                if latest.age_timedelta is not None:
                    if latest.age_timedelta < timedelta(days=1):
                        age_col = colorize(NEW_EP_COLOR, latest.age)
                    elif latest.age_timedelta < timedelta(days=3):
                        age_col = colorize(FRESH_EP_COLOR, latest.age)
                    elif latest.age_timedelta > timedelta(days=400):
                        age_col = colorize(OLD_EP_COLOR, latest.age)
                episode_id = latest.identifier
            if not porcelain:
                if behind[0] > 0:
                    name_column += colorize(
                        BEHIND_EP_COLOR,
                        ' {} {} behind'.format(behind[0], behind[1]))

            table_data.append([
                name_column, episode_id, age_col, latest_release,
                identifier_type
            ])
    try:
        table = TerminalTable(options.table_type,
                              table_data,
                              wrap_columns=[3],
                              drop_columns=[4, 3, 2])
        console(table.output)
    except TerminalTableError as e:
        console('ERROR: %s' % str(e))
        return
    if not porcelain:
        if not query.count():
            console('Use `flexget series list all` to view all known series.')
        else:
            console(
                'Use `flexget series show NAME` to get detailed information.')
예제 #16
0
파일: series.py 프로젝트: sean797/Flexget
def display_summary(options):
    """
    Display series summary.
    :param options: argparse options from the CLI
    """
    formatting = ' %-30s %-10s %-10s %-20s'
    console(formatting % ('Name', 'Latest', 'Age', 'Downloaded'))
    console('-' * 79)

    session = Session()
    try:
        query = (session.query(Series).outerjoin(Series.episodes).outerjoin(
            Episode.releases).outerjoin(Series.in_tasks).group_by(Series.id))
        if options.configured == 'configured':
            query = query.having(func.count(SeriesTask.id) >= 1)
        elif options.configured == 'unconfigured':
            query = query.having(func.count(SeriesTask.id) < 1)
        if options.premieres:
            query = (query.having(func.max(Episode.season) <= 1).having(
                func.max(Episode.number) <= 2).having(
                    func.count(SeriesTask.id) < 1)).filter(
                        Release.downloaded == True)
        if options.new:
            query = query.having(
                func.max(Episode.first_seen) > datetime.now() -
                timedelta(days=options.new))
        if options.stale:
            query = query.having(
                func.max(Episode.first_seen) < datetime.now() -
                timedelta(days=options.stale))
        for series in query.order_by(Series.name).yield_per(10):
            series_name = series.name
            if len(series_name) > 30:
                series_name = series_name[:27] + '...'

            new_ep = ' '
            behind = 0
            status = 'N/A'
            age = 'N/A'
            episode_id = 'N/A'
            latest = get_latest_release(series)
            if latest:
                if latest.first_seen > datetime.now() - timedelta(days=2):
                    new_ep = '>'
                behind = new_eps_after(latest)
                status = get_latest_status(latest)
                age = latest.age
                episode_id = latest.identifier

            if behind:
                episode_id += ' +%s' % behind

            console(new_ep + formatting[1:] %
                    (series_name, episode_id, age, status))
            if behind >= 3:
                console(
                    ' ! Latest download is %d episodes behind, this may require '
                    'manual intervention' % behind)

        console('-' * 79)
        console(' > = new episode ')
        console(' Use `flexget series show NAME` to get detailed information')
    finally:
        session.close()
예제 #17
0
파일: series.py 프로젝트: Davst/Flexget
def display_summary(options):
    """
    Display series summary.
    :param options: argparse options from the CLI
    """
    porcelain = options.table_type == 'porcelain'
    with Session() as session:
        kwargs = {'configured': options.configured,
                  'premieres': options.premieres,
                  'session': session,
                  'sort_by': options.sort_by,
                  'descending': options.order}
        if options.new:
            kwargs['status'] = 'new'
            kwargs['days'] = options.new
        elif options.stale:
            kwargs['status'] = 'stale'
            kwargs['days'] = options.stale
        if options.sort_by == 'name':
            kwargs['sort_by'] = 'show_name'
        else:
            kwargs['sort_by'] = 'last_download_date'

        query = get_series_summary(**kwargs)
        header = ['Name', 'Latest', 'Age', 'Downloaded', 'Identified By']
        for index, value in enumerate(header):
            if value.lower() == options.sort_by:
                header[index] = colorize(SORT_COLUMN_COLOR, value)
        footer = 'Use `flexget series show NAME` to get detailed information'
        table_data = [header]
        for series in query:
            name_column = series.name

            new_ep = False
            behind = 0
            latest_release = '-'
            age_col = '-'
            episode_id = '-'
            latest = get_latest_release(series)
            identifier_type = series.identified_by
            if identifier_type == 'auto':
                identifier_type = colorize('yellow', 'auto')
            if latest:
                behind = new_eps_after(latest)
                latest_release = get_latest_status(latest)
                # colorize age
                age_col = latest.age
                if latest.age_timedelta is not None:
                    if latest.age_timedelta < timedelta(days=1):
                        age_col = colorize(NEW_EP_COLOR, latest.age)
                    elif latest.age_timedelta < timedelta(days=3):
                        age_col = colorize(FRESH_EP_COLOR, latest.age)
                    elif latest.age_timedelta > timedelta(days=400):
                        age_col = colorize(OLD_EP_COLOR, latest.age)
                episode_id = latest.identifier
            if not porcelain:
                if behind > 0:
                    name_column += colorize(BEHIND_EP_COLOR, ' {} behind'.format(behind))

            table_data.append([name_column, episode_id, age_col, latest_release, identifier_type])
    table = TerminalTable(options.table_type, table_data, wrap_columns=[3], drop_columns=[4, 3, 2])
    try:
        console(table.output)
    except TerminalTableError as e:
        console('ERROR: %s' % str(e))
        return
    if not porcelain:
        console(footer)
예제 #18
0
    def on_task_input(self, task, config):
        if not config:
            return
        if isinstance(config, bool):
            config = {}
        if not task.is_rerun:
            self.try_next_season = {}
        entries = []
        for seriestask in task.session.query(SeriesTask).filter(SeriesTask.name == task.name).all():
            series = seriestask.series
            if not series:
                # TODO: How can this happen?
                log.debug("Found SeriesTask item without series specified. Cleaning up.")
                task.session.delete(seriestask)
                continue

            if series.identified_by not in ["ep", "sequence"]:
                log.verbose(
                    "Can only emit ep or sequence based series. `%s` is identified_by %s"
                    % (series.name, series.identified_by or "auto")
                )
                continue

            low_season = 0 if series.identified_by == "ep" else -1

            latest_season = get_latest_release(series)
            if latest_season:
                latest_season = latest_season.season
            else:
                latest_season = low_season + 1

            if self.try_next_season.get(series.name):
                entries.append(self.search_entry(series, latest_season + 1, 1, task))
            else:
                for season in xrange(latest_season, low_season, -1):
                    log.debug("Adding episodes for %d" % latest_season)
                    check_downloaded = not config.get("backfill")
                    latest = get_latest_release(series, season=season, downloaded=check_downloaded)
                    if series.begin and (not latest or latest < series.begin):
                        entries.append(self.search_entry(series, series.begin.season, series.begin.number, task))
                    elif latest:
                        start_at_ep = 1
                        episodes_this_season = (
                            task.session.query(Episode)
                            .filter(Episode.series_id == series.id)
                            .filter(Episode.season == season)
                        )
                        if series.identified_by == "sequence":
                            # Don't look for missing too far back with sequence shows
                            start_at_ep = max(latest.number - 10, 1)
                            episodes_this_season = episodes_this_season.filter(Episode.number >= start_at_ep)
                        latest_ep_this_season = episodes_this_season.order_by(desc(Episode.number)).first()
                        downloaded_this_season = (
                            episodes_this_season.join(Episode.releases).filter(Release.downloaded == True).all()
                        )
                        # Calculate the episodes we still need to get from this season
                        if series.begin and series.begin.season == season:
                            start_at_ep = max(start_at_ep, series.begin.number)
                        eps_to_get = range(start_at_ep, latest_ep_this_season.number + 1)
                        for ep in downloaded_this_season:
                            try:
                                eps_to_get.remove(ep.number)
                            except ValueError:
                                pass
                        entries.extend(self.search_entry(series, season, x, task, rerun=False) for x in eps_to_get)
                        # If we have already downloaded the latest known episode, try the next episode
                        if latest_ep_this_season.releases:
                            entries.append(self.search_entry(series, season, latest_ep_this_season.number + 1, task))
                    else:
                        if config.get("from_start") or config.get("backfill"):
                            entries.append(self.search_entry(series, season, 1, task))
                        else:
                            log.verbose(
                                "Series `%s` has no history. Set begin option, or use CLI `series begin` "
                                "subcommand to set first episode to emit" % series.name
                            )
                            continue

                    if not config.get("backfill"):
                        break

        return entries
예제 #19
0
    def on_task_input(self, task, config):
        if not config:
            return
        if isinstance(config, bool):
            config = {}

        if task.is_rerun:
            # Just return calculated next eps on reruns
            entries = self.rerun_entries
            self.rerun_entries = []
            return entries
        else:
            self.rerun_entries = []

        entries = []
        impossible = {}
        with Session() as session:
            for seriestask in session.query(SeriesTask).filter(
                    SeriesTask.name == task.name).all():
                series = seriestask.series
                log.trace('evaluating %s', series.name)
                if not series:
                    # TODO: How can this happen?
                    log.debug(
                        'Found SeriesTask item without series specified. Cleaning up.'
                    )
                    session.delete(seriestask)
                    continue

                if series.identified_by not in ['ep']:
                    log.trace('unsupported identified_by scheme')
                    reason = series.identified_by or 'auto'
                    impossible.setdefault(reason, []).append(series.name)
                    continue

                low_season = 0
                # Don't look for seasons older than begin ep
                if series.begin and series.begin.season and series.begin.season > 1:
                    low_season = max(series.begin.season - 1, 0)

                new_season = None
                check_downloaded = not config.get('backfill')
                latest_season = get_latest_release(series,
                                                   downloaded=check_downloaded)
                if latest_season:
                    if latest_season.season <= low_season:
                        latest_season = new_season = low_season + 1
                    elif latest_season.season in series.completed_seasons:
                        latest_season = new_season = latest_season.season + 1
                    else:
                        latest_season = latest_season.season
                else:
                    latest_season = low_season + 1

                if (latest_season - low_season > MAX_SEASON_DIFF_WITHOUT_BEGIN
                        and not series.begin) or (
                            series.begin and latest_season -
                            series.begin.season > MAX_SEASON_DIFF_WITH_BEGIN):
                    if series.begin:
                        log.error(
                            'Series `%s` has a begin episode set (`%s`), but the season currently being processed '
                            '(%s) is %s seasons later than it. To prevent emitting incorrect seasons, this '
                            'series will not emit unless the begin episode is adjusted to a season that is less '
                            'than %s seasons from season %s.', series.name,
                            series.begin.identifier, latest_season,
                            (latest_season - series.begin.season),
                            MAX_SEASON_DIFF_WITH_BEGIN, latest_season)
                    else:
                        log.error(
                            'Series `%s` does not have a begin episode set and continuing this task would result '
                            'in more than %s seasons being emitted. To prevent emitting incorrect seasons, this '
                            'series will not emit unless the begin episode is set in your series config or by '
                            'using the CLI subcommand `series begin "%s" <SxxExx>`.',
                            series.name, MAX_SEASON_DIFF_WITHOUT_BEGIN,
                            series.name)
                    continue
                for season in range(latest_season, low_season, -1):
                    if season in series.completed_seasons:
                        log.debug('season %s is marked as completed, skipping',
                                  season)
                        continue
                    log.trace('Evaluating season %s for series `%s`', season,
                              series.name)
                    latest = get_latest_release(series,
                                                season=season,
                                                downloaded=check_downloaded)
                    if series.begin and season == series.begin.season and (
                            not latest or latest < series.begin):
                        # In case series.begin season is already completed, look in next available season
                        lookup_season = series.begin.season
                        while lookup_season in series.completed_seasons:
                            lookup_season += 1
                        entries.append(
                            self.search_entry(series, lookup_season, task))
                    elif latest:
                        entries.append(
                            self.search_entry(series, latest.season, task))
                    # First iteration of a new season with no show begin and show has downloads
                    elif new_season and season == new_season:
                        entries.append(self.search_entry(series, season, task))
                    else:
                        if config.get('from_start') or config.get('backfill'):
                            entries.append(
                                self.search_entry(series, season, task))
                        else:
                            log.verbose(
                                'Series `%s` has no history. Set the begin option in your config, '
                                'or use the CLI subcommand `series begin "%s" <SxxExx>` '
                                'to set the first episode to emit',
                                series.name, series.name)
                            break
                    # Skip older seasons if we are not in backfill mode
                    if not config.get('backfill'):
                        log.debug(
                            'backfill is not enabled; skipping older seasons')
                        break

        for reason, series in impossible.items():
            log.verbose(
                'Series `%s` with identified_by value `%s` are not supported. ',
                ', '.join(sorted(series)), reason)

        return entries
예제 #20
0
파일: series.py 프로젝트: m-hume/Flexget
def display_summary(options):
    """
    Display series summary.
    :param options: argparse options from the CLI
    """
    with Session() as session:
        kwargs = {'configured': options.configured,
                  'premieres': options.premieres,
                  'session': session}
        if options.new:
            kwargs['status'] = 'new'
            kwargs['days'] = options.new
        elif options.stale:
            kwargs['status'] = 'stale'
            kwargs['days'] = options.stale

        query = get_series_summary(**kwargs)

        if options.porcelain:
            formatting = '%-30s %s %-10s %s %-10s %s %-20s'
            console(formatting % ('Name', '|', 'Latest', '|', 'Age', '|', 'Downloaded'))
        else:
            formatting = ' %-30s %-10s %-10s %-20s'
            console('-' * 79)
            console(formatting % ('Name', 'Latest', 'Age', 'Downloaded'))
            console('-' * 79)

        for series in query.order_by(Series.name).yield_per(10):
            series_name = series.name
            if len(series_name) > 30:
                series_name = series_name[:27] + '...'

            new_ep = ' '
            behind = 0
            status = 'N/A'
            age = 'N/A'
            episode_id = 'N/A'
            latest = get_latest_release(series)
            if latest:
                if latest.first_seen > datetime.now() - timedelta(days=2):
                    if options.porcelain:
                        pass
                    else:
                        new_ep = '>'
                behind = new_eps_after(latest)
                status = get_latest_status(latest)
                age = latest.age
                episode_id = latest.identifier

            if behind:
                episode_id += ' +%s' % behind

            if options.porcelain:
                console(formatting % (series_name, '|', episode_id, '|', age, '|', status))
            else:
                console(new_ep + formatting[1:] % (series_name, episode_id, age, status))
            if behind >= 3:
                console(' ! Latest download is %d episodes behind, this may require '
                        'manual intervention' % behind)

        if options.porcelain:
            pass
        else:
            console('-' * 79)
            console(' > = new episode ')
            console(' Use `flexget series show NAME` to get detailed information')
예제 #21
0
def display_summary(options):
    """
    Display series summary.
    :param options: argparse options from the CLI
    """
    porcelain = options.table_type == 'porcelain'
    configured = options.configured or os.environ.get(ENV_LIST_CONFIGURED, 'configured')
    premieres = True if (os.environ.get(ENV_LIST_PREMIERES) == 'yes' or
                         options.premieres) else False
    sort_by = options.sort_by or os.environ.get(ENV_LIST_SORTBY_FIELD, 'name')
    if options.order is not None:
        descending = True if options.order == 'desc' else False
    else:
        descending = True if os.environ.get(ENV_LIST_SORTBY_ORDER) == 'desc' else False
    with Session() as session:
        kwargs = {'configured': configured,
                  'premieres': premieres,
                  'session': session,
                  'sort_by': sort_by,
                  'descending': descending}
        if sort_by == 'name':
            kwargs['sort_by'] = 'show_name'
        else:
            kwargs['sort_by'] = 'last_download_date'

        query = get_series_summary(**kwargs)
        header = ['Name', 'Begin', 'Last Encountered', 'Age', 'Downloaded', 'Identified By']
        for index, value in enumerate(header):
            if value.lower() == options.sort_by:
                header[index] = colorize(SORT_COLUMN_COLOR, value)

        table_data = [header]
        for series in query:
            name_column = series.name

            behind = (0,)
            begin = series.begin.identifier if series.begin else '-'
            latest_release = '-'
            age_col = '-'
            episode_id = '-'
            latest = get_latest_release(series)
            identifier_type = series.identified_by
            if identifier_type == 'auto':
                identifier_type = colorize('yellow', 'auto')
            if latest:
                behind = new_entities_after(latest)
                latest_release = get_latest_status(latest)
                # colorize age
                age_col = latest.age
                if latest.age_timedelta is not None:
                    if latest.age_timedelta < timedelta(days=1):
                        age_col = colorize(NEW_EP_COLOR, latest.age)
                    elif latest.age_timedelta < timedelta(days=3):
                        age_col = colorize(FRESH_EP_COLOR, latest.age)
                    elif latest.age_timedelta > timedelta(days=400):
                        age_col = colorize(OLD_EP_COLOR, latest.age)
                episode_id = latest.identifier
            if not porcelain:
                if behind[0] > 0:
                    name_column += colorize(BEHIND_EP_COLOR, ' {} {} behind'.format(behind[0], behind[1]))

            table_data.append([name_column, begin, episode_id, age_col, latest_release, identifier_type])
    try:
        table = TerminalTable(options.table_type, table_data, wrap_columns=[3], drop_columns=[4, 3, 2])
        console(table.output)
    except TerminalTableError as e:
        console('ERROR: %s' % str(e))
        return
    if not porcelain:
        if not query.count():
            console('Use `flexget series list all` to view all known series.')
        else:
            console('Use `flexget series show NAME` to get detailed information.')
예제 #22
0
    def on_task_input(self, task, config):
        if not config:
            return
        if isinstance(config, bool):
            config = {}

        if task.is_rerun:
            # Just return calculated next eps on reruns
            entries = self.rerun_entries
            self.rerun_entries = []
            return entries
        else:
            self.rerun_entries = []

        entries = []
        impossible = {}
        with Session() as session:
            for seriestask in session.query(SeriesTask).filter(
                    SeriesTask.name == task.name).all():
                series = seriestask.series
                log.trace('evaluating %s', series.name)
                if not series:
                    # TODO: How can this happen?
                    log.debug(
                        'Found SeriesTask item without series specified. Cleaning up.'
                    )
                    session.delete(seriestask)
                    continue

                if series.identified_by not in ['ep']:
                    log.trace('unsupported identified_by scheme')
                    reason = series.identified_by or 'auto'
                    impossible.setdefault(reason, []).append(series.name)
                    continue

                low_season = 0

                check_downloaded = not config.get('backfill')
                latest_season = get_latest_release(series,
                                                   downloaded=check_downloaded)
                if latest_season:
                    latest_season = latest_season.season + 1 if latest_season.season in series.completed_seasons \
                        else latest_season.season
                else:
                    latest_season = low_season + 1

                for season in range(latest_season, low_season, -1):
                    if season in series.completed_seasons:
                        log.debug('season %s is marked as completed, skipping',
                                  season)
                        continue
                    log.trace('Adding episodes for series %s season %d',
                              series.name, season)
                    latest = get_latest_release(series,
                                                season=season,
                                                downloaded=check_downloaded)
                    if series.begin and (not latest or latest < series.begin):
                        # In case series.begin season is already completed, look in next available season
                        lookup_season = series.begin.season
                        while lookup_season in series.completed_seasons:
                            lookup_season += 1
                        entries.append(
                            self.search_entry(series, lookup_season, task))
                    elif latest:
                        entries.append(
                            self.search_entry(series, latest.season, task))
                    else:
                        if config.get('from_start') or config.get('backfill'):
                            entries.append(
                                self.search_entry(series, season, 1, task))
                        else:
                            log.verbose(
                                'Series `%s` has no history. Set begin option, '
                                'or use CLI `series begin` '
                                'subcommand to set first episode to emit',
                                series.name)
                            break
                    # Skip older seasons if we are not in backfill mode
                    if not config.get('backfill'):
                        break
                    # Don't look for seasons older than begin ep
                    if series.begin and series.begin.season >= season:
                        break

        for reason, series in impossible.items():
            log.verbose(
                'Series `%s` with identified_by value `%s` are not supported. ',
                ', '.join(sorted(series)), reason)

        return entries
예제 #23
0
def display_summary(options):
    """
    Display series summary.
    :param options: argparse options from the CLI
    """
    with Session() as session:
        kwargs = {
            'configured': options.configured,
            'premieres': options.premieres,
            'session': session
        }
        if options.new:
            kwargs['status'] = 'new'
            kwargs['days'] = options.new
        elif options.stale:
            kwargs['status'] = 'stale'
            kwargs['days'] = options.stale

        query = get_series_summary(**kwargs)

        if options.porcelain:
            formatting = '%-30s %s %-10s %s %-10s %s %-20s'
            console(formatting %
                    ('Name', '|', 'Latest', '|', 'Age', '|', 'Downloaded'))
        else:
            formatting = ' %-30s %-10s %-10s %-20s'
            console('-' * 79)
            console(formatting % ('Name', 'Latest', 'Age', 'Downloaded'))
            console('-' * 79)

        for series in query.order_by(Series.name).yield_per(10):
            series_name = series.name
            if len(series_name) > 30:
                series_name = series_name[:27] + '...'

            new_ep = ' '
            behind = 0
            status = 'N/A'
            age = 'N/A'
            episode_id = 'N/A'
            latest = get_latest_release(series)
            if latest:
                if latest.first_seen > datetime.now() - timedelta(days=2):
                    if options.porcelain:
                        pass
                    else:
                        new_ep = '>'
                behind = new_eps_after(latest)
                status = get_latest_status(latest)
                age = latest.age
                episode_id = latest.identifier

            if behind:
                episode_id += ' +%s' % behind

            if options.porcelain:
                console(formatting %
                        (series_name, '|', episode_id, '|', age, '|', status))
            else:
                console(new_ep + formatting[1:] %
                        (series_name, episode_id, age, status))
            if behind >= 3:
                console(
                    ' ! Latest download is %d episodes behind, this may require '
                    'manual intervention' % behind)

        if options.porcelain:
            pass
        else:
            console('-' * 79)
            console(' > = new episode ')
            console(
                ' Use `flexget series show NAME` to get detailed information')
예제 #24
0
    def on_task_input(self, task, config):
        if not config:
            return
        if isinstance(config, bool):
            config = {}

        if task.is_rerun:
            # Just return calculated next eps on reruns
            entries = self.rerun_entries
            self.rerun_entries = []
            return entries
        else:
            self.rerun_entries = []

        entries = []
        with Session() as session:
            for seriestask in session.query(SeriesTask).filter(SeriesTask.name == task.name).all():
                series = seriestask.series
                if not series:
                    # TODO: How can this happen?
                    log.debug('Found SeriesTask item without series specified. Cleaning up.')
                    session.delete(seriestask)
                    continue

                if series.identified_by not in ['ep', 'sequence']:
                    log.verbose('Can only emit ep or sequence based series. '
                                '`%s` is identified_by %s' %
                                (series.name, series.identified_by or 'auto'))
                    continue

                low_season = 0 if series.identified_by == 'ep' else -1

                check_downloaded = not config.get('backfill')
                latest_season = get_latest_release(series, downloaded=check_downloaded)
                if latest_season:
                    latest_season = latest_season.season
                else:
                    latest_season = low_season + 1

                for season in range(latest_season, low_season, -1):
                    log.debug('Adding episodes for season %d' % season)
                    latest = get_latest_release(series, season=season, downloaded=check_downloaded)
                    if series.begin and (not latest or latest < series.begin):
                        entries.append(self.search_entry(series, series.begin.season, series.begin.number, task))
                    elif latest and not config.get('backfill'):
                        entries.append(self.search_entry(series, latest.season, latest.number + 1, task))
                    elif latest:
                        start_at_ep = 1
                        episodes_this_season = (session.query(Episode).
                                                filter(Episode.series_id == series.id).
                                                filter(Episode.season == season))
                        if series.identified_by == 'sequence':
                            # Don't look for missing too far back with sequence shows
                            start_at_ep = max(latest.number - 10, 1)
                            episodes_this_season = episodes_this_season.filter(Episode.number >= start_at_ep)
                        latest_ep_this_season = episodes_this_season.order_by(desc(Episode.number)).first()
                        downloaded_this_season = (episodes_this_season.join(Episode.releases).
                                                  filter(Release.downloaded == True).all())
                        # Calculate the episodes we still need to get from this season
                        if series.begin and series.begin.season == season:
                            start_at_ep = max(start_at_ep, series.begin.number)
                        eps_to_get = list(range(start_at_ep, latest_ep_this_season.number + 1))
                        for ep in downloaded_this_season:
                            try:
                                eps_to_get.remove(ep.number)
                            except ValueError:
                                pass
                        entries.extend(self.search_entry(series, season, x, task, rerun=False) for x in eps_to_get)
                        # If we have already downloaded the latest known episode, try the next episode
                        if latest_ep_this_season.releases:
                            entries.append(self.search_entry(series, season, latest_ep_this_season.number + 1, task))
                    else:
                        if config.get('from_start') or config.get('backfill'):
                            entries.append(self.search_entry(series, season, 1, task))
                        else:
                            log.verbose('Series `%s` has no history. Set begin option, '
                                        'or use CLI `series begin` '
                                        'subcommand to set first episode to emit' % series.name)
                            break
                    # Skip older seasons if we are not in backfill mode
                    if not config.get('backfill'):
                        break
                    # Don't look for seasons older than begin ep
                    if series.begin and series.begin.season >= season:
                        break

        return entries
예제 #25
0
    def on_task_input(self, task, config):
        if not config:
            return
        if isinstance(config, bool):
            config = {}

        if task.is_rerun:
            # Just return calculated next eps on reruns
            entries = self.rerun_entries
            self.rerun_entries = []
            return entries
        else:
            self.rerun_entries = []

        entries = []
        impossible = {}
        with Session() as session:
            for seriestask in session.query(SeriesTask).filter(
                    SeriesTask.name == task.name).all():
                series = seriestask.series
                log.trace('evaluating %s', series.name)
                if not series:
                    # TODO: How can this happen?
                    log.debug(
                        'Found SeriesTask item without series specified. Cleaning up.'
                    )
                    session.delete(seriestask)
                    continue

                if series.identified_by not in ['ep', 'sequence']:
                    log.trace('unsupported identified_by scheme')
                    reason = series.identified_by or 'auto'
                    impossible.setdefault(reason, []).append(series.name)
                    continue

                low_season = 0 if series.identified_by == 'ep' else -1
                # Don't look for seasons older than begin ep
                if series.begin and series.begin.season and series.begin.season > 1:
                    # begin-1 or the range() loop will never get to the begin season
                    low_season = max(series.begin.season - 1, 0)

                new_season = None
                check_downloaded = not config.get('backfill')
                latest_season = get_latest_release(series,
                                                   downloaded=check_downloaded)
                if latest_season:
                    if latest_season.season <= low_season:
                        latest_season = new_season = low_season + 1
                    elif latest_season.season in series.completed_seasons:
                        latest_season = new_season = latest_season.season + 1
                    else:
                        latest_season = latest_season.season
                else:
                    latest_season = low_season + 1

                for season in range(latest_season, low_season, -1):
                    if season in series.completed_seasons:
                        log.debug('season %s is marked as completed, skipping',
                                  season)
                        continue
                    log.trace('Evaluating episodes for series %s, season %d',
                              series.name, season)
                    latest = get_latest_release(series,
                                                season=season,
                                                downloaded=check_downloaded)
                    if series.begin and season == series.begin.season and (
                            not latest or latest < series.begin):
                        # In case series.begin season is already completed, look in next available season
                        lookup_season = series.begin.season
                        ep_number = series.begin.number
                        while lookup_season in series.completed_seasons:
                            lookup_season += 1
                            # If season number was bumped, start looking for ep 1
                            ep_number = 1
                        entries.append(
                            self.search_entry(series, lookup_season, ep_number,
                                              task))
                    elif latest and not config.get('backfill'):
                        entries.append(
                            self.search_entry(series, latest.season,
                                              latest.number + 1, task))
                    elif latest:
                        start_at_ep = 1
                        episodes_this_season = (session.query(Episode).filter(
                            Episode.series_id == series.id).filter(
                                Episode.season == season))
                        if series.identified_by == 'sequence':
                            # Don't look for missing too far back with sequence shows
                            start_at_ep = max(latest.number - 10, 1)
                            episodes_this_season = episodes_this_season.filter(
                                Episode.number >= start_at_ep)
                        latest_ep_this_season = episodes_this_season.order_by(
                            desc(Episode.number)).first()
                        if latest_ep_this_season:
                            downloaded_this_season = (
                                episodes_this_season.join(
                                    Episode.releases).filter(
                                        EpisodeRelease.downloaded ==
                                        True).all())
                            # Calculate the episodes we still need to get from this season
                            if series.begin and series.begin.season == season:
                                start_at_ep = max(start_at_ep,
                                                  series.begin.number)
                            eps_to_get = list(
                                range(start_at_ep,
                                      latest_ep_this_season.number + 1))
                            for ep in downloaded_this_season:
                                try:
                                    eps_to_get.remove(ep.number)
                                except ValueError:
                                    pass
                            entries.extend(
                                self.search_entry(
                                    series, season, x, task, rerun=False)
                                for x in eps_to_get)
                            # If we have already downloaded the latest known episode, try the next episode
                            if latest_ep_this_season.releases:
                                entries.append(
                                    self.search_entry(
                                        series, season,
                                        latest_ep_this_season.number + 1,
                                        task))
                        else:
                            # No episode means that latest is a season pack, emit episode 1
                            entries.append(
                                self.search_entry(series, season, 1, task))
                    # First iteration of a new season with no show begin and show has downloads
                    elif new_season and season == new_season:
                        entries.append(
                            self.search_entry(series, season, 1, task))
                    else:
                        if config.get('from_start') or config.get('backfill'):
                            entries.append(
                                self.search_entry(series, season, 1, task))
                        else:
                            log.verbose(
                                'Series `%s` has no history. Set begin option, '
                                'or use CLI `series begin` '
                                'subcommand to set first episode to emit',
                                series.name)
                            break
                    # Skip older seasons if we are not in backfill mode
                    if not config.get('backfill'):
                        log.debug(
                            'backfill is not enabled; skipping older seasons')
                        break

        for reason, series in impossible.items():
            log.verbose(
                'Series `%s` with identified_by value `%s` are not supported. ',
                ', '.join(sorted(series)), reason)

        return entries
예제 #26
0
    def on_task_input(self, task, config):
        if not config:
            return
        if isinstance(config, bool):
            config = {}

        if task.is_rerun:
            # Just return calculated next eps on reruns
            entries = self.rerun_entries
            self.rerun_entries = []
            return entries
        else:
            self.rerun_entries = []

        entries = []
        with Session() as session:
            for seriestask in session.query(SeriesTask).filter(
                    SeriesTask.name == task.name).all():
                series = seriestask.series
                if not series:
                    # TODO: How can this happen?
                    log.debug(
                        'Found SeriesTask item without series specified. Cleaning up.'
                    )
                    session.delete(seriestask)
                    continue

                if series.identified_by not in ['ep', 'sequence']:
                    log.verbose('Can only emit ep or sequence based series. '
                                '`%s` is identified_by %s' %
                                (series.name, series.identified_by or 'auto'))
                    continue

                low_season = 0 if series.identified_by == 'ep' else -1

                check_downloaded = not config.get('backfill')
                latest_season = get_latest_release(series,
                                                   downloaded=check_downloaded)
                if latest_season:
                    latest_season = latest_season.season
                else:
                    latest_season = low_season + 1

                for season in range(latest_season, low_season, -1):
                    log.debug('Adding episodes for season %d' % season)
                    latest = get_latest_release(series,
                                                season=season,
                                                downloaded=check_downloaded)
                    if series.begin and (not latest or latest < series.begin):
                        entries.append(
                            self.search_entry(series, series.begin.season,
                                              series.begin.number, task))
                    elif latest and not config.get('backfill'):
                        entries.append(
                            self.search_entry(series, latest.season,
                                              latest.number + 1, task))
                    elif latest:
                        start_at_ep = 1
                        episodes_this_season = (session.query(Episode).filter(
                            Episode.series_id == series.id).filter(
                                Episode.season == season))
                        if series.identified_by == 'sequence':
                            # Don't look for missing too far back with sequence shows
                            start_at_ep = max(latest.number - 10, 1)
                            episodes_this_season = episodes_this_season.filter(
                                Episode.number >= start_at_ep)
                        latest_ep_this_season = episodes_this_season.order_by(
                            desc(Episode.number)).first()
                        downloaded_this_season = (episodes_this_season.join(
                            Episode.releases).filter(
                                Release.downloaded == True).all())
                        # Calculate the episodes we still need to get from this season
                        if series.begin and series.begin.season == season:
                            start_at_ep = max(start_at_ep, series.begin.number)
                        eps_to_get = list(
                            range(start_at_ep,
                                  latest_ep_this_season.number + 1))
                        for ep in downloaded_this_season:
                            try:
                                eps_to_get.remove(ep.number)
                            except ValueError:
                                pass
                        entries.extend(
                            self.search_entry(
                                series, season, x, task, rerun=False)
                            for x in eps_to_get)
                        # If we have already downloaded the latest known episode, try the next episode
                        if latest_ep_this_season.releases:
                            entries.append(
                                self.search_entry(
                                    series, season,
                                    latest_ep_this_season.number + 1, task))
                    else:
                        if config.get('from_start') or config.get('backfill'):
                            entries.append(
                                self.search_entry(series, season, 1, task))
                        else:
                            log.verbose(
                                'Series `%s` has no history. Set begin option, '
                                'or use CLI `series begin` '
                                'subcommand to set first episode to emit' %
                                series.name)
                            break
                    # Skip older seasons if we are not in backfill mode
                    if not config.get('backfill'):
                        break
                    # Don't look for seasons older than begin ep
                    if series.begin and series.begin.season >= season:
                        break

        return entries