Esempio n. 1
0
def feeds():
    broken = request.args.get('broken')
    broken = {None: None, 'no': False, 'yes': True}[broken]

    updates_enabled = request.args.get('updates-enabled')
    updates_enabled = {None: None, 'no': False, 'yes': True}[updates_enabled]

    sort = request.args.get('sort', 'title')
    assert sort in ('title', 'added')

    error = None

    args = request.args.copy()

    tags_str = tags = args.pop('tags', None)
    if tags is None:
        pass
    elif not tags.strip():
        # if tags is '', it's not a tag filter
        return redirect(url_for('.feeds', **args))
    else:

        try:
            tags = yaml.safe_load(tags)
        except yaml.YAMLError as e:
            error = f"invalid tag query: invalid YAML: {e}: {tags_str}"
            return stream_template('feeds.html', feed_data=[], error=error)

    reader = get_reader()

    kwargs = dict(broken=broken, tags=tags, updates_enabled=updates_enabled)

    with_counts = request.args.get('counts')
    with_counts = {None: None, 'no': False, 'yes': True}[with_counts]
    counts = reader.get_feed_counts(**kwargs) if with_counts else None

    feed_data = []
    try:
        feeds = reader.get_feeds(sort=sort, **kwargs)
        feed_data = ((
            feed,
            list(reader.get_feed_tags(feed)),
            reader.get_entry_counts(feed=feed) if with_counts else None,
        ) for feed in feeds)
    except ValueError as e:
        # TODO: there should be a better way of matching this kind of error
        if 'tag' in str(e).lower():
            error = f"invalid tag query: {e}: {tags_str}"
        else:
            raise

    # Ensure flashed messages get removed from the session.
    # https://github.com/lemon24/reader/issues/81
    get_flashed_messages()

    return stream_template('feeds.html',
                           feed_data=feed_data,
                           error=error,
                           counts=counts)
Esempio n. 2
0
    def iter_tags():
        for tag in itertools.chain([None, True, False], reader.get_feed_tags()):
            feed_counts = None
            entry_counts = None

            if with_counts:
                tags_arg = [tag] if tag is not None else tag
                feed_counts = reader.get_feed_counts(tags=tags_arg)
                entry_counts = reader.get_entry_counts(feed_tags=tags_arg)

            yield tag, feed_counts, entry_counts
Esempio n. 3
0
def tags():
    reader = get_reader()

    with_counts = request.args.get('counts')
    with_counts = {None: None, 'no': False, 'yes': True}[with_counts]

    tags = ((
        tag,
        reader.get_feed_counts(tags=[tag]) if with_counts else None,
        reader.get_entry_counts(feed_tags=[tag]) if with_counts else None,
    ) for tag in itertools.chain([True, False], reader.get_feed_tags()))

    return render_template('tags.html', tags=tags)
Esempio n. 4
0
def update(reader, url, new_only, workers, verbose):
    """Update one or all feeds.

    If URL is not given, update all the feeds.

    Verbosity works like this:

    \b
        : progress bar + final status
        -v: + lines
        -vv: + warnings
        -vvv: + info
        -vvvv: + debug

    """
    if url:

        def make_it():
            try:
                yield url, reader.update_feed(url)
            except ParseError as e:
                yield url, e

        it = make_it()
    else:
        it = reader.update_feeds_iter(new_only=new_only, workers=workers)

    ok_count = 0
    not_modified_count = 0
    error_count = 0
    new_count = 0
    updated_count = 0

    def feed_stats(width=None):
        if not width:
            width, _ = click.get_terminal_size()
        if width < 80:
            return ''
        if width < 105:
            return f"{green(ok_count)}/{red(error_count)}/{not_modified_count}"
        return (
            f"{green(f'{ok_count} ok') if ok_count else '0 ok'}, "
            f"{red(f'{error_count} error') if error_count else '0 error'}, "
            f"{not_modified_count} not modified")

    if url:
        length = 1
    else:
        if not new_only:
            length = reader.get_feed_counts(updates_enabled=True).total
        else:
            # TODO: pending https://github.com/lemon24/reader/issues/217
            length = None

    if not verbose:
        bar_context = click.progressbar(
            it,
            length=length,
            label='update',
            show_pos=True,
            show_eta=True,
            item_show_func=lambda _: feed_stats(),
            file=sys.stderr,
        )

    else:
        bar_context = nullcontext(iter_update_status(it, length))

    try:
        with bar_context as bar:
            for _, value in bar:
                update_status = get_update_status(value)
                if update_status is None:
                    not_modified_count += 1
                elif not update_status:
                    error_count += 1
                else:
                    ok_count += 1
                    new_count += value.new
                    updated_count += value.updated
    finally:
        click.echo(
            f"{feed_stats(9999)}; entries: {new_count} new, {updated_count} updated"
        )