Skip to content

Commit 8ef1f0c

Browse files
committed
v2: basic search support. #318
1 parent 83b9348 commit 8ef1f0c

File tree

3 files changed

+38
-10
lines changed

3 files changed

+38
-10
lines changed

src/reader/_app/v2/__init__.py

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import itertools
12
from functools import partial
23

34
from flask import abort
@@ -8,9 +9,13 @@
89
from flask import url_for
910
from jinja2_fragments.flask import render_block
1011

12+
from reader import InvalidSearchQueryError
13+
14+
from .. import EntryProxy
1115
from .. import get_reader
1216
from .. import stream_template
1317
from .forms import EntryFilter
18+
from .forms import SearchEntryFilter
1419

1520

1621
blueprint = Blueprint(
@@ -22,30 +27,43 @@
2227
def entries():
2328
reader = get_reader()
2429

25-
# TODO: search
30+
# TODO: search improvements
31+
# TODO: search bug: first search uses recent
2632
# TODO: paqgination
2733
# TODO: read time
2834

29-
form = EntryFilter(request.args)
35+
if request.args.get('q', '').strip():
36+
form = SearchEntryFilter(request.args)
37+
else:
38+
form = EntryFilter(request.args)
3039

3140
if form.args != request.args.to_dict():
3241
return redirect(url_for('.entries', **form.args))
3342

34-
kwargs = dict(form.data)
35-
del kwargs['search']
36-
3743
feed = None
3844
if form.feed.data:
3945
feed = reader.get_feed(form.feed.data, None)
4046
if not feed:
4147
abort(404)
4248

43-
get_entries = reader.get_entries
49+
kwargs = dict(form.data)
50+
if query := kwargs.pop('search', None):
51+
52+
def get_entries(**kwargs):
53+
for sr in reader.search_entries(query, **kwargs):
54+
yield EntryProxy(sr, reader.get_entry(sr))
4455

45-
if form.validate():
46-
entries = get_entries(**kwargs, limit=64)
4756
else:
48-
entries = []
57+
get_entries = reader.get_entries
58+
59+
entries = []
60+
if form.validate():
61+
try:
62+
entries = eager_iterator(get_entries(**kwargs, limit=64))
63+
except StopIteration:
64+
pass
65+
except InvalidSearchQueryError as e:
66+
form.search.errors.append(f"invalid query: {e}")
4967

5068
return stream_template(
5169
'v2/entries.html',
@@ -55,6 +73,14 @@ def entries():
5573
)
5674

5775

76+
def eager_iterator(it):
77+
it = iter(it)
78+
try:
79+
return itertools.chain([next(it)], it)
80+
except StopIteration:
81+
return it
82+
83+
5884
@blueprint.route('/mark-as', methods=['POST'])
5985
def mark_as():
6086
reader = get_reader()

src/reader/_app/v2/forms.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ class EntryFilter(PresetsMixin, Form):
135135

136136
class SearchEntryFilter(EntryFilter):
137137
sort = RadioField(
138-
"sort", choices=ENTRY_SORT_CHOICES + ['relevant'], default='relevant'
138+
"sort", choices=['relevant'] + ENTRY_SORT_CHOICES, default='relevant'
139139
)
140140

141141

src/reader/_app/v2/templates/v2/entries.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949

5050

5151
<form>
52+
{# TODO: if data or error #}
5253
{% if form.search.data %}{{ macros.input(form.search, 'search') }}{% endif %}
5354
{% if form.feed_tags.data %}{{ macros.input(form.feed_tags, 'tag') }}{% endif %}
5455
<div class="collapse mb-3" id="nav-more">
@@ -107,6 +108,7 @@ <h2 class="h5 mb-1" style="font-size: 1.125rem">
107108
{%- endif %}
108109
</h2>
109110

111+
{# TODO: show marked search results; title too! #}
110112
{% set summary = entry.get_content(prefer_summary=True).value | striptags | trim %}
111113
{% if summary %}
112114
<p class="small mb-2">

0 commit comments

Comments
 (0)