示例#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)
示例#2
0
def update_feed_tags(data):
    feed_url = data['feed-url']
    feed_tags = set(data['feed-tags'].split())

    reader = get_reader()
    tags = set(reader.get_feed_tags(feed_url))

    for tag in tags - feed_tags:
        reader.remove_feed_tag(feed_url, tag)
    for tag in feed_tags - tags:
        reader.add_feed_tag(feed_url, tag)
示例#3
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
示例#4
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)
示例#5
0
def entries():
    show = request.args.get('show', 'unread')
    read = {'all': None, 'unread': False, 'read': True}[show]

    has_enclosures = request.args.get('has-enclosures')
    has_enclosures = {None: None, 'no': False, 'yes': True}[has_enclosures]

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

    if not request.args.get('q'):
        sort = request.args.get('sort', 'recent')
        assert sort in ('recent', 'random')
    else:
        sort = request.args.get('sort', 'relevant')
        assert sort in ('relevant', 'recent', 'random')

    reader = get_reader()

    feed_url = request.args.get('feed')
    feed = None
    feed_tags = None
    if feed_url:
        feed = reader.get_feed(feed_url, None)
        if not feed:
            abort(404)
        feed_tags = list(reader.get_feed_tags(feed))

    args = request.args.copy()
    query = args.pop('q', None)
    if query is None:

        def get_entries(**kwargs):
            yield from reader.get_entries(sort=sort, **kwargs)

        get_entry_counts = reader.get_entry_counts

    elif not query:
        # if the query is '', it's not a search
        args.pop('sort', None)
        return redirect(url_for('.entries', **args))

    else:

        def get_entries(**kwargs):
            for sr in reader.search_entries(query, sort=sort, **kwargs):
                yield EntryProxy(sr, reader.get_entry(sr))

        def get_entry_counts(**kwargs):
            return reader.search_entry_counts(query, **kwargs)

    # TODO: render the actual search result, not the entry
    # TODO: catch and flash syntax errors
    # TODO: don't show search box if search is not enabled

    error = None

    # TODO: duplicated from feeds()
    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('.entries', **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(
                'entries.html', feed=feed, feed_tags=feed_tags, error=error
            )

    kwargs = dict(
        feed=feed_url,
        read=read,
        has_enclosures=has_enclosures,
        important=important,
        feed_tags=tags,
    )
    entries = get_entries(**kwargs, limit=request.args.get('limit', type=int))

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

    try:
        first = next(entries)
        entries = itertools.chain([first], entries)
    except StopIteration:
        pass
    except InvalidSearchQueryError as e:
        error = f"invalid search query: {e}"
    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

    entries = list(entries)

    entries_data = None
    if feed_url:
        entries_data = [e.id for e in entries]

    # Ensure flashed messages get removed from the session,
    # otherwise they keep adding up and never disappear.
    # Assumes the template will call get_flashed_messages() at some point.
    # https://github.com/lemon24/reader/issues/81
    get_flashed_messages()

    return stream_template(
        'entries.html',
        entries=entries,
        feed=feed,
        feed_tags=feed_tags,
        entries_data=entries_data,
        error=error,
        counts=counts,
    )