Пример #1
0
def plugins_summary(manager, options):
    if options.table_type == 'porcelain':
        disable_all_colors()
    header = ['Keyword', 'Phases', 'Flags']
    table_data = [header]
    for plugin in sorted(get_plugins(phase=options.phase, group=options.group)):
        if options.builtins and not plugin.builtin:
            continue
        flags = []
        if plugin.instance.__doc__:
            flags.append('doc')
        if plugin.builtin:
            flags.append('builtin')
        if plugin.debug:
            if not options.debug:
                continue
            flags.append('developers')
        handlers = plugin.phase_handlers
        roles = []
        for phase in handlers:
            priority = handlers[phase].priority
            roles.append('{0}({1})'.format(phase, priority))

        name = colorize('green', plugin.name) if 'builtin' in flags else plugin.name
        table_data.append([name, ', '.join(roles), ', '.join(flags)])

    try:
        table = TerminalTable(options.table_type, table_data, wrap_columns=[1, 2])
        console(table.output)
    except TerminalTableError as e:
        console('ERROR: %s' % str(e))
        return
    console(colorize('green', ' Built-in plugins'))
Пример #2
0
def action_status(options, irc_manager):
    connection = options.irc_connection
    try:
        status = irc_manager.status(connection)
    except ValueError as e:
        console('ERROR: %s' % e.args[0])
        return

    header = ['Name', 'Alive', 'Channels', 'Server']
    table_data = [header]

    for connection in status:
        for name, info in connection.items():
            alive = colorize('green', 'Yes') if info['alive'] else colorize('red', 'No')
            channels = []
            for channel in info['channels']:
                for channel_name, channel_status in channel.items():
                    channels.append(channel_name)
                    if channel_status == IRCChannelStatus.CONNECTED:
                        channels[-1] = colorize('green', '* ' + channels[-1])
            table_data.append(
                [name, alive, ', '.join(channels), '%s:%s' % (info['server'], info['port'])]
            )
    try:
        table = TerminalTable(options.table_type, table_data)
        console(table.output)
        console(colorize('green', ' * Connected channel'))
    except TerminalTableError as e:
        console('ERROR: %s' % e)
Пример #3
0
def plugins_summary(manager, options):
    if options.table_type == 'porcelain':
        disable_colors()
    header = ['Keyword', 'Interfaces', 'Phases', 'Flags']
    table = TerminalTable(*header, table_type=options.table_type)
    for plugin in sorted(
            get_plugins(phase=options.phase, interface=options.interface)):
        if options.builtins and not plugin.builtin:
            continue

        flags = []
        if plugin.instance.__doc__:
            flags.append('doc')
        if plugin.builtin:
            flags.append('builtin')
        if plugin.debug:
            if not options.debug:
                continue
            flags.append('developers')

        handlers = plugin.phase_handlers
        roles = []
        for phase in handlers:
            priority = handlers[phase].priority
            roles.append('{0}({1})'.format(phase, priority))

        name = colorize('green',
                        plugin.name) if 'builtin' in flags else plugin.name
        table.add_row(name, ', '.join(plugin.interfaces), ', '.join(roles),
                      ', '.join(flags))

    table.caption = colorize('green', ' Built-in plugins')
    table.caption_justify = 'left'
    console(table)
Пример #4
0
def action_status(options, irc_manager):
    connection = options.irc_connection
    try:
        status = irc_manager.status(connection)
    except ValueError as e:
        console('ERROR: %s' % e.args[0])
        return

    header = ['Name', 'Alive', 'Channels', 'Server']
    table_data = []

    for connection in status:
        for name, info in connection.items():
            alive = colorize('green', 'Yes') if info['alive'] else colorize(
                'red', 'No')
            channels = []
            for channel in info['channels']:
                for channel_name, channel_status in channel.items():
                    channels.append(channel_name)
                    if channel_status == IRCChannelStatus.CONNECTED:
                        channels[-1] = colorize('green', '* ' + channels[-1])
            table_data.append([
                name, alive, ', '.join(channels),
                '%s:%s' % (info['server'], info['port'])
            ])

    table = TerminalTable(*header, table_type=options.table_type)
    for row in table_data:
        table.add_row(*row)
    console(table)
    console(colorize('green', ' * Connected channel'))
Пример #5
0
def do_cli_summary(manager, options):
    header = [
        'Task',
        'Last execution',
        'Last success',
        'Produced',
        'Accepted',
        'Rejected',
        'Failed',
        'Duration',
    ]
    table_data = [header]

    with Session() as session:
        for task in session.query(db.StatusTask).all():
            ok = (session.query(db.TaskExecution).filter(
                db.TaskExecution.task_id == task.id).filter(
                    db.TaskExecution.succeeded == True).filter(
                        db.TaskExecution.produced > 0).order_by(
                            db.TaskExecution.start.desc()).first())

            if ok is None:
                duration = None
                last_success = '-'
            else:
                duration = ok.end - ok.start
                last_success = ok.start.strftime('%Y-%m-%d %H:%M')

                age = datetime.datetime.utcnow() - ok.start
                if age > timedelta(days=7):
                    last_success = colorize('red', last_success)
                elif age < timedelta(minutes=10):
                    last_success = colorize('green', last_success)
            # Fix weird issue that a task registers StatusTask but without an execution. GH #2022
            last_exec = (task.last_execution_time.strftime('%Y-%m-%d %H:%M')
                         if task.last_execution_time else '-')

            table_data.append([
                task.name,
                last_exec,
                last_success,
                ok.produced if ok is not None else '-',
                ok.accepted if ok is not None else '-',
                ok.rejected if ok is not None else '-',
                ok.failed if ok is not None else '-',
                '%1.fs' %
                duration.total_seconds() if duration is not None else '-',
            ])

    table = TerminalTable(options.table_type, table_data)
    try:
        console(table.output)
    except TerminalTableError as e:
        console('ERROR: %s' % str(e))
Пример #6
0
def pending_list_list(options):
    """List pending list entries"""
    with Session() as session:
        try:
            pending_list = db.get_list_by_exact_name(options.list_name,
                                                     session=session)
        except NoResultFound:
            console('Could not find pending list with name `{}`'.format(
                options.list_name))
            return
        header = ['#', 'Title', '# of fields', 'Approved']
        table_data = [header]
        for entry in db.get_entries_by_list_id(pending_list.id,
                                               order_by='added',
                                               descending=True,
                                               session=session):
            approved = colorize(
                'green', entry.approved) if entry.approved else entry.approved
            table_data.append(
                [entry.id, entry.title,
                 len(entry.entry), approved])
    table = TerminalTable(options.table_type, table_data)
    try:
        console(table.output)
    except TerminalTableError as e:
        console('ERROR: %s' % str(e))
Пример #7
0
def list_entries(options):
    """List pending entries"""
    approved = options.approved
    task_name = options.task_name

    with Session() as session:
        entries = db.list_pending_entries(session=session,
                                          task_name=task_name,
                                          approved=approved)
        header = ['#', 'Task Name', 'Title', 'URL', 'Approved', 'Added']
        table_data = [header]
        for entry in entries:
            table_data.append([
                entry.id,
                entry.task_name,
                entry.title,
                entry.url,
                colorize('green', 'Yes') if entry.approved else 'No',
                entry.added.strftime("%c"),
            ])
    try:
        table = TerminalTable(options.table_type,
                              table_data,
                              wrap_columns=[1, 2, 3],
                              drop_columns=[5, 1, 3])
        console(table.output)
    except TerminalTableError as e:
        console('ERROR: %s' % str(e))
Пример #8
0
def manage_entries(options, selection, approved):
    """Manage pending entries"""
    approved_text = 'approved' if approved else 'pending'
    with Session() as session:
        if selection == 'all':
            entries = db.list_pending_entries(session=session,
                                              approved=not approved)
        else:
            try:
                entry = db.get_entry_by_id(session, selection)
                if entry.approved is approved:
                    console(
                        colorize('red', 'ERROR: ') +
                        'Entry with ID %s is already %s' %
                        (entry.id, approved_text))
                    sys.exit(1)
            except NoResultFound:
                console('Pending entry with ID %s does not exist' % selection)
                sys.exit(1)
            else:
                entries = [entry]
        if not entries:
            console('All entries are already %s' % approved_text)
            return
        for entry in entries:
            if entry.approved is not approved:
                console('Setting pending entry with ID %s status to %s' %
                        (entry.id, approved_text))
                entry.approved = approved
Пример #9
0
def manage_entries(options, selection, approved):
    """Manage pending entries"""
    approved_text = 'approved' if approved else 'pending'
    with Session() as session:
        if selection == 'all':
            entries = db.list_pending_entries(session=session, approved=not approved)
        else:
            try:
                entry = db.get_entry_by_id(session, selection)
                if entry.approved is approved:
                    console(
                        colorize('red', 'ERROR: ')
                        + 'Entry with ID %s is already %s' % (entry.id, approved_text)
                    )
                    sys.exit(1)
            except NoResultFound:
                console('Pending entry with ID %s does not exist' % selection)
                sys.exit(1)
            else:
                entries = [entry]
        if not entries:
            console('All entries are already %s' % approved_text)
            return
        for entry in entries:
            if entry.approved is not approved:
                console(
                    'Setting pending entry with ID %s status to %s' % (entry.id, approved_text)
                )
                entry.approved = approved
Пример #10
0
def list_entries(options):
    """List pending entries"""
    approved = options.approved
    task_name = options.task_name

    with Session() as session:
        entries = db.list_pending_entries(session=session, task_name=task_name, approved=approved)
        header = ['#', 'Task Name', 'Title', 'URL', 'Approved', 'Added']
        table_data = [header]
        for entry in entries:
            table_data.append(
                [
                    entry.id,
                    entry.task_name,
                    entry.title,
                    entry.url,
                    colorize('green', 'Yes') if entry.approved else 'No',
                    entry.added.strftime("%c"),
                ]
            )
    try:
        table = TerminalTable(
            options.table_type, table_data, wrap_columns=[1, 2, 3], drop_columns=[5, 1, 3]
        )
        console(table.output)
    except TerminalTableError as e:
        console('ERROR: %s' % str(e))
Пример #11
0
def do_cli_task(manager, options):
    header = [
        'Start', 'Duration', 'Produced', 'Accepted', 'Rejected', 'Failed',
        'Abort Reason'
    ]
    table_data = [header]
    with Session() as session:
        try:
            task = session.query(db.StatusTask).filter(
                db.StatusTask.name == options.task).one()
        except NoResultFound:
            console(
                'Task name `%s` does not exists or does not have any records' %
                options.task)
            return
        else:
            query = task.executions.order_by(desc(
                db.TaskExecution.start))[:options.limit]
            for ex in reversed(query):
                start = ex.start.strftime('%Y-%m-%d %H:%M')
                start = colorize('green', start) if ex.succeeded else colorize(
                    'red', start)

                if ex.end is not None and ex.start is not None:
                    delta = ex.end - ex.start
                    duration = '%1.fs' % delta.total_seconds()
                else:
                    duration = '?'

                table_data.append([
                    start,
                    duration,
                    ex.produced,
                    ex.accepted,
                    ex.rejected,
                    ex.failed,
                    ex.abort_reason if ex.abort_reason is not None else '',
                ])

    try:
        table = TerminalTable(options.table_type, table_data)
        console(table.output)
    except TerminalTableError as e:
        console('ERROR: %s' % str(e))
Пример #12
0
def do_cli_summary(manager, options):
    header = ['Task', 'Last execution', 'Last success', 'Produced', 'Accepted', 'Rejected', 'Failed', 'Duration']
    table_data = [header]

    with Session() as session:
        for task in session.query(StatusTask).all():
            ok = session.query(TaskExecution). \
                filter(TaskExecution.task_id == task.id). \
                filter(TaskExecution.succeeded == True). \
                filter(TaskExecution.produced > 0). \
                order_by(TaskExecution.start.desc()).first()

            if ok is None:
                duration = None
                last_success = '-'
            else:
                duration = ok.end - ok.start
                last_success = ok.start.strftime('%Y-%m-%d %H:%M')

                age = datetime.datetime.utcnow() - ok.start
                if age > timedelta(days=7):
                    last_success = colorize('red', last_success)
                elif age < timedelta(minutes=10):
                    last_success = colorize('green', last_success)

            table_data.append([
                task.name,
                task.last_execution_time.strftime('%Y-%m-%d %H:%M'),
                last_success,
                ok.produced if ok is not None else '-',
                ok.accepted if ok is not None else '-',
                ok.rejected if ok is not None else '-',
                ok.failed if ok is not None else '-',
                '%1.fs' % duration.total_seconds() if duration is not None else '-',
            ]
            )

    table = TerminalTable(options.table_type, table_data)
    try:
        console(table.output)
    except TerminalTableError as e:
        console('ERROR: %s' % str(e))
Пример #13
0
def do_cli_task(manager, options):
    header = ['Start', 'Duration', 'Produced', 'Accepted', 'Rejected', 'Failed', 'Abort Reason']
    table_data = [header]
    with Session() as session:
        try:
            task = session.query(StatusTask).filter(StatusTask.name == options.task).one()
        except NoResultFound:
            console('Task name `%s` does not exists or does not have any records' % options.task)
            return
        else:
            query = task.executions.order_by(desc(TaskExecution.start))[:options.limit]
            for ex in reversed(query):
                start = ex.start.strftime('%Y-%m-%d %H:%M')
                start = colorize('green', start) if ex.succeeded else colorize('red', start)

                if ex.end is not None and ex.start is not None:
                    delta = ex.end - ex.start
                    duration = '%1.fs' % delta.total_seconds()
                else:
                    duration = '?'

                table_data.append(
                    [
                        start,
                        duration,
                        ex.produced,
                        ex.accepted,
                        ex.rejected,
                        ex.failed,
                        ex.abort_reason if ex.abort_reason is not None else ''
                    ]
                )

    try:
        table = TerminalTable(options.table_type, table_data)
        console(table.output)
    except TerminalTableError as e:
        console('ERROR: %s' % str(e))
Пример #14
0
def pending_list_list(options):
    """List pending list entries"""
    with Session() as session:
        try:
            pending_list = get_list_by_exact_name(options.list_name, session=session)
        except NoResultFound:
            console('Could not find pending list with name `{}`'.format(options.list_name))
            return
        header = ['#', 'Title', '# of fields', 'Approved']
        table_data = [header]
        for entry in get_entries_by_list_id(pending_list.id, order_by='added', descending=True, session=session):
            approved = colorize('green', entry.approved) if entry.approved else entry.approved
            table_data.append([entry.id, entry.title, len(entry.entry), approved])
    table = TerminalTable(options.table_type, table_data)
    try:
        console(table.output)
    except TerminalTableError as e:
        console('ERROR: %s' % str(e))
Пример #15
0
def list_entries(options):
    """List pending entries"""
    approved = options.approved
    task_name = options.task_name

    with Session() as session:
        entries = db.list_pending_entries(session=session,
                                          task_name=task_name,
                                          approved=approved)
        header = ['#', 'Task Name', 'Title', 'URL', 'Approved', 'Added']
        table = TerminalTable(*header, table_type=options.table_type)
        for entry in entries:
            table.add_row(
                str(entry.id),
                entry.task_name,
                entry.title,
                entry.url,
                colorize('green', 'Yes') if entry.approved else 'No',
                entry.added.strftime("%c"),
            )
    console(table)
Пример #16
0
def pending_list_list(options):
    """List pending list entries"""
    with Session() as session:
        try:
            pending_list = db.get_list_by_exact_name(options.list_name,
                                                     session=session)
        except NoResultFound:
            console('Could not find pending list with name `{}`'.format(
                options.list_name))
            return
        header = ['#', 'Title', '# of fields', 'Approved']
        table = TerminalTable(*header, table_type=options.table_type)
        for entry in db.get_entries_by_list_id(pending_list.id,
                                               order_by='added',
                                               descending=True,
                                               session=session):
            approved = colorize(
                'green', entry.approved) if entry.approved else entry.approved
            table.add_row(str(entry.id), entry.title, str(len(entry.entry)),
                          approved)
    console(table)
Пример #17
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.')
Пример #18
0
def display_details(options):
    """Display detailed series information, ie. series show NAME"""
    name = options.series_name
    sort_by = options.sort_by or os.environ.get(ENV_SHOW_SORTBY_FIELD, 'age')
    if options.order is not None:
        reverse = True if options.order == 'desc' else False
    else:
        reverse = True if os.environ.get(ENV_SHOW_SORTBY_ORDER) == 'desc' else False
    with Session() as session:
        name = normalize_series_name(name)
        # Sort by length of name, so that partial matches always show shortest matching title
        matches = shows_by_name(name, session=session)
        if not matches:
            console(colorize(ERROR_COLOR, 'ERROR: Unknown series `%s`' % name))
            return
        # Pick the best matching series
        series = matches[0]
        table_title = colorize('white', series.name)
        if len(matches) > 1:
            warning = (colorize('red', ' WARNING: ') +
                       'Multiple series match to `{}`.\n '
                       'Be more specific to see the results of other matches:\n\n'
                       ' {}'.format(name, ', '.join(s.name for s in matches[1:])))
            if not options.table_type == 'porcelain':
                console(warning)
        header = ['Identifier', 'Last seen', 'Release titles', 'Release Quality', 'Proper']
        table_data = [header]
        entities = get_all_entities(series, session=session, sort_by=sort_by, reverse=reverse)
        for entity in entities:
            if not entity.releases:
                continue
            if entity.identifier is None:
                identifier = colorize(ERROR_COLOR, 'MISSING')
                age = ''
            else:
                identifier = entity.identifier
                age = entity.age
            entity_data = [identifier, age]
            release_titles = []
            release_qualities = []
            release_propers = []
            for release in entity.releases:
                title = release.title
                quality = release.quality.name
                if not release.downloaded:
                    title = colorize(UNDOWNLOADED_RELEASE_COLOR, title)
                    quality = quality
                else:
                    title += ' *'
                    title = colorize(DOWNLOADED_RELEASE_COLOR, title)
                    quality = quality
                release_titles.append(title)
                release_qualities.append(quality)
                release_propers.append('Yes' if release.proper_count > 0 else '')
            entity_data.append('\n'.join(release_titles))
            entity_data.append('\n'.join(release_qualities))
            entity_data.append('\n'.join(release_propers))
            table_data.append(entity_data)
        footer = ' %s \n' % (colorize(DOWNLOADED_RELEASE_COLOR, '* Downloaded'))
        if not series.identified_by:
            footer += ('\n Series plugin is still learning which episode numbering mode is \n'
                       ' correct for this series (identified_by: auto).\n'
                       ' Few duplicate downloads can happen with different numbering schemes\n'
                       ' during this time.')
        else:
            footer += '\n `%s` uses `%s` mode to identify episode numbering.' % (series.name, series.identified_by)
        begin_text = 'option'
        if series.begin:
            footer += ' \n Begin for `%s` is set to `%s`.' % (series.name, series.begin.identifier)
            begin_text = 'and `begin` options'
        footer += ' \n See `identified_by` %s for more information.' % begin_text
    try:
        table = TerminalTable(options.table_type, table_data, table_title, drop_columns=[4, 3, 1])
        console(table.output)
    except TerminalTableError as e:
        console('ERROR: %s' % str(e))
        return
    if not options.table_type == 'porcelain':
        console(footer)
Пример #19
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.')
Пример #20
0
def display_details(options):
    """Display detailed series information, ie. series show NAME"""
    name = options.series_name
    with Session() as session:
        name = normalize_series_name(name)
        # Sort by length of name, so that partial matches always show shortest matching title
        matches = shows_by_name(name, session=session)
        if not matches:
            console(colorize(ERROR_COLOR, 'ERROR: Unknown series `%s`' % name))
            return
        # Pick the best matching series
        series = matches[0]
        table_title = colorize('white', series.name)
        if len(matches) > 1:
            warning = (
                colorize('red', ' WARNING: ') +
                'Multiple series match to `{}`.\n '
                'Be more specific to see the results of other matches:\n\n'
                ' {}'.format(name, ', '.join(s.name for s in matches[1:])))
            if not options.table_type == 'porcelain':
                console(warning)
        header = [
            'Entity ID', 'Latest age', 'Release titles', 'Release Quality',
            'Proper'
        ]
        table_data = [header]
        entities = get_all_entities(series, session=session)
        for entity in entities:
            if entity.identifier is None:
                identifier = colorize(ERROR_COLOR, 'MISSING')
                age = ''
            else:
                identifier = entity.identifier
                age = entity.age
            entity_data = [identifier, age]
            release_titles = []
            release_qualities = []
            release_propers = []
            for release in entity.releases:
                title = release.title
                quality = release.quality.name
                if not release.downloaded:
                    title = colorize(UNDOWNLOADED_RELEASE_COLOR, title)
                    quality = quality
                else:
                    title += ' *'
                    title = colorize(DOWNLOADED_RELEASE_COLOR, title)
                    quality = quality
                release_titles.append(title)
                release_qualities.append(quality)
                release_propers.append(
                    'Yes' if release.proper_count > 0 else '')
            entity_data.append('\n'.join(release_titles))
            entity_data.append('\n'.join(release_qualities))
            entity_data.append('\n'.join(release_propers))
            table_data.append(entity_data)
        footer = ' %s \n' % (colorize(DOWNLOADED_RELEASE_COLOR,
                                      '* Downloaded'))
        if not series.identified_by:
            footer += (
                '\n Series plugin is still learning which episode numbering mode is \n'
                ' correct for this series (identified_by: auto).\n'
                ' Few duplicate downloads can happen with different numbering schemes\n'
                ' during this time.')
        else:
            footer += '\n Series uses `%s` mode to identify episode numbering (identified_by).' % series.identified_by
        footer += ' \n See option `identified_by` for more information.\n'
        if series.begin:
            footer += ' Begin episode for this series set to `%s`.' % series.begin.identifier
    try:
        table = TerminalTable(options.table_type,
                              table_data,
                              table_title,
                              drop_columns=[4, 3, 1])
        console(table.output)
    except TerminalTableError as e:
        console('ERROR: %s' % str(e))
        return
    if not options.table_type == 'porcelain':
        console(footer)
Пример #21
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)
        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)
Пример #22
0
def display_details(options):
    """Display detailed series information, ie. series show NAME"""
    name = options.series_name
    with Session() as session:
        name = normalize_series_name(name)
        # Sort by length of name, so that partial matches always show shortest matching title
        matches = shows_by_name(name, session=session)
        if not matches:
            console(colorize(ERROR_COLOR, 'ERROR: Unknown series `%s`' % name))
            return
        # Pick the best matching series
        series = matches[0]
        table_title = colorize('white', series.name)
        if len(matches) > 1:
            warning = (colorize('red', ' WARNING: ') +
                       'Multiple series match to `{}`.\n '
                       'Be more specific to see the results of other matches:\n\n'
                       ' {}'.format(name, ', '.join(s.name for s in matches[1:])))
            if not options.table_type == 'porcelain':
                console(warning)
        header = ['Episode ID', 'Latest age', 'Release titles', 'Release Quality', 'Proper']
        table_data = [header]
        episodes = show_episodes(series, session=session)
        for episode in episodes:
            if episode.identifier is None:
                identifier = colorize(ERROR_COLOR, 'MISSING')
                age = ''
            else:
                identifier = episode.identifier
                age = episode.age
            ep_data = [identifier, age]
            release_titles = []
            release_qualities = []
            release_propers = []
            for release in episode.releases:
                title = release.title
                quality = release.quality.name
                if not release.downloaded:
                    title = colorize(UNDOWNLOADED_RELEASE_COLOR, title)
                    quality = quality
                else:
                    title = colorize(DOWNLOADED_RELEASE_COLOR, title)
                    quality = quality
                release_titles.append(title)
                release_qualities.append(quality)
                release_propers.append('Yes' if release.proper_count > 0 else '')
            ep_data.append('\n'.join(release_titles))
            ep_data.append('\n'.join(release_qualities))
            ep_data.append('\n'.join(release_propers))
            table_data.append(ep_data)
        footer = (' %s %s\n' % (colorize(DOWNLOADED_RELEASE_COLOR, 'Downloaded'),
                                colorize(UNDOWNLOADED_RELEASE_COLOR, 'Un-downloaded')))
        if not series.identified_by:
            footer += ('\n'
                       ' Series plugin is still learning which episode numbering mode is \n'
                       ' correct for this series (identified_by: auto).\n'
                       ' Few duplicate downloads can happen with different numbering schemes\n'
                       ' during this time.')
        else:
            footer += ' \n Series uses `%s` mode to identify episode numbering (identified_by).' % series.identified_by
        footer += ' \n See option `identified_by` for more information.\n'
        if series.begin:
            footer += ' Begin episode for this series set to `%s`.' % series.begin.identifier
    table = TerminalTable(options.table_type, table_data, table_title, drop_columns=[4, 3, 1])
    try:
        console(table.output)
    except TerminalTableError as e:
        console('ERROR: %s' % str(e))
        return
    if not options.table_type == 'porcelain':
        console(footer)
Пример #23
0
def display_details(options):
    """Display detailed series information, ie. series show NAME"""
    name = options.series_name
    sort_by = options.sort_by or os.environ.get(ENV_SHOW_SORTBY_FIELD, 'age')
    if options.order is not None:
        reverse = True if options.order == 'desc' else False
    else:
        reverse = True if os.environ.get(
            ENV_SHOW_SORTBY_ORDER) == 'desc' else False
    with Session() as session:
        name = flexget.components.series.utils.normalize_series_name(name)
        # Sort by length of name, so that partial matches always show shortest matching title
        matches = db.shows_by_name(name, session=session)
        if not matches:
            console(colorize(ERROR_COLOR, 'ERROR: Unknown series `%s`' % name))
            return
        # Pick the best matching series
        series = matches[0]
        table_title = series.name
        if len(matches) > 1:
            warning = (
                colorize('red', ' WARNING: ') +
                'Multiple series match to `{}`.\n '
                'Be more specific to see the results of other matches:\n\n'
                ' {}'.format(name, ', '.join(s.name for s in matches[1:])))
            if not options.table_type == 'porcelain':
                console(warning)
        header = [
            'Identifier', 'Last seen', 'Release titles', 'Quality', 'Proper'
        ]
        table_data = []
        entities = db.get_all_entities(series,
                                       session=session,
                                       sort_by=sort_by,
                                       reverse=reverse)
        for entity in entities:
            if not entity.releases:
                continue
            if entity.identifier is None:
                identifier = colorize(ERROR_COLOR, 'MISSING')
                age = ''
            else:
                identifier = entity.identifier
                age = entity.age
            entity_data = [identifier, age]
            release_titles = []
            release_qualities = []
            release_propers = []
            for release in entity.releases:
                title = release.title
                quality = release.quality.name
                if not release.downloaded:
                    title = colorize(UNDOWNLOADED_RELEASE_COLOR, title)
                    quality = quality
                else:
                    title += ' *'
                    title = colorize(DOWNLOADED_RELEASE_COLOR, title)
                    quality = quality
                release_titles.append(title)
                release_qualities.append(quality)
                release_propers.append(
                    'Yes' if release.proper_count > 0 else '')
            entity_data.append('\n'.join(release_titles))
            entity_data.append('\n'.join(release_qualities))
            entity_data.append('\n'.join(release_propers))
            table_data.append(entity_data)
        footer = ' %s \n' % (colorize(DOWNLOADED_RELEASE_COLOR,
                                      '* Downloaded'))
        if not series.identified_by:
            footer += (
                '\n Series plugin is still learning which episode numbering mode is \n'
                ' correct for this series (identified_by: auto).\n'
                ' Few duplicate downloads can happen with different numbering schemes\n'
                ' during this time.')
        else:
            footer += '\n `%s` uses `%s` mode to identify episode numbering.' % (
                series.name,
                series.identified_by,
            )
        begin_text = 'option'
        if series.begin:
            footer += ' \n Begin for `%s` is set to `%s`.' % (
                series.name, series.begin.identifier)
            begin_text = 'and `begin` options'
        footer += ' \n See `identified_by` %s for more information.' % begin_text
    table = TerminalTable(*header,
                          table_type=options.table_type,
                          title=table_title)
    for row in table_data:
        table.add_row(*row)
    console(table)
    if not options.table_type == 'porcelain':
        console(footer)
Пример #24
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 = db.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 = TerminalTable(*header, table_type=options.table_type)

        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 = db.get_latest_release(series)
            identifier_type = series.identified_by
            if identifier_type == 'auto':
                identifier_type = colorize('yellow', 'auto')
            if latest:
                behind = db.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.add_row(name_column, begin, episode_id, age_col,
                          latest_release, identifier_type)
    console(table)
    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.')