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_download(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()
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 latest = get_latest_download(series) 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: if self.try_next_season.get(series.name): entries.append(self.search_entry(series, latest.season + 1, 1, task)) else: start_at_ep = 1 episodes_this_season = (task.session.query(Episode). filter(Episode.series_id == series.id). filter(Episode.season == latest.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 == latest.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, latest.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.downloaded_releases: entries.append(self.search_entry(series, latest.season, latest_ep_this_season.number + 1, task)) else: if config.get('from_start'): season = 1 if series.identified_by == 'ep' else 0 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 return entries
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_download(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()