Skip to content

Commit bab0786

Browse files
committed
[IMP] Set all article of a feed as read. Search in feed articles
1 parent 9656884 commit bab0786

File tree

8 files changed

+113
-10
lines changed

8 files changed

+113
-10
lines changed

README.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,24 @@ pipx install lugus
2323

2424
![main page screenshot](https://raw.githubusercontent.com/OpenCode/lugus/main/readme/home.png)
2525

26+
### Search
27+
28+
#### Generic Search
29+
30+
![generic search](https://raw.githubusercontent.com/OpenCode/lugus/main/readme/search.png)
31+
32+
#### Title Search
33+
34+
![title search](https://raw.githubusercontent.com/OpenCode/lugus/main/readme/search_title.png)
35+
36+
#### Content Search
37+
38+
![content search](https://raw.githubusercontent.com/OpenCode/lugus/main/readme/search_content.png)
39+
40+
#### Multiple Search
41+
42+
![multi search](https://raw.githubusercontent.com/OpenCode/lugus/main/readme/search_multi.png)
43+
2644
### New Feed Screen
2745

2846
![new feed page screenshot](https://raw.githubusercontent.com/OpenCode/lugus/main/readme/new_feed.png)
@@ -33,13 +51,11 @@ pipx install lugus
3351
- [ ] Import existing OPML files
3452
- [ ] Export feeds as OPML file
3553
- [ ] Set article as unread
36-
- [ ] Set a feed as read
3754
- [ ] Set an article as favorite
3855
- [ ] Tags system for articles
3956
- [ ] Add notes on articles
4057
- [ ] Feeds auto-sync
4158
- [ ] Edit existing feeds
42-
- [ ] Search articles by name/content
4359
- [ ] Support for Windows
4460

4561
## License

readme/home.png

-38.3 KB
Loading

readme/search.png

218 KB
Loading

readme/search_content.png

183 KB
Loading

readme/search_multi.png

236 KB
Loading

readme/search_title.png

181 KB
Loading

src/lugus/lugus.py

Lines changed: 73 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,20 @@ def update(self, table, id_record, values):
7878
)
7979
self.connection.commit()
8080

81+
def update_where(self, table, where, values):
82+
cursor = self.connection.cursor()
83+
cursor.execute(
84+
"UPDATE %s SET %s WHERE %s" % (
85+
table,
86+
", ".join([
87+
f"{v[0]} = {self._convert_value(v[1])}"
88+
for v in values
89+
]),
90+
where,
91+
)
92+
)
93+
self.connection.commit()
94+
8195
def read(self, table, id_record):
8296
if isinstance(id_record, str):
8397
id_record = int(id_record.lower().replace("id-", ""))
@@ -269,18 +283,41 @@ class Articles(Vertical):
269283
recomposes = reactive(0, recompose=True)
270284
feed = reactive(False, recompose=True)
271285
filter_articles_type = reactive("", recompose=True)
286+
filter_articles = reactive("", recompose=True)
272287

273288
def compose(self) -> ComposeResult:
274289
articles = []
275290
if self.feed and self.feed.data:
276291
data = self.feed.data
292+
# Filter by Read/Unread
277293
if self.filter_articles_type == "unread":
278294
read = " AND read = 0"
279295
elif self.filter_articles_type == "read":
280296
read = " AND read = 1"
281297
else:
282298
read = ""
283-
articles = self.orm.search("article", ["id", "date", "title"], where=f"feed_id = {data["id"]}{read}")
299+
# Filter by Title/Content
300+
if self.filter_articles:
301+
filters = self.filter_articles.split(",")
302+
filter_text = ""
303+
for filter in filters:
304+
filter = filter.strip().replace("\"", "")
305+
if filter:
306+
if filter.lower().startswith("title:"):
307+
filter = filter.replace("title:", "")
308+
filter_text = f"{filter_text} AND title LIKE \"%{filter}%\""
309+
elif filter.lower().startswith("content:"):
310+
filter = filter.replace("content:", "")
311+
filter_text = f"{filter_text} AND content LIKE \"%{filter}%\""
312+
else:
313+
filter_text = f"{filter_text} AND (title LIKE \"%{filter}%\" OR content LIKE \"%{filter}%\")"
314+
else:
315+
filter_text = ""
316+
articles = self.orm.search(
317+
"article",
318+
["id", "date", "title"],
319+
where=f"feed_id = {data["id"]}{read}{filter_text}",
320+
)
284321
yield ListView(
285322
*[
286323
ListItem(
@@ -298,15 +335,24 @@ def compose(self) -> ComposeResult:
298335

299336
class ArticlesArea(Vertical):
300337

338+
orm = ORM()
339+
301340
def compose(self) -> ComposeResult:
302-
yield Select(
303-
(
304-
("Unread", "unread"),
305-
("Read", "read"),
306-
("All", "all"),
341+
yield Horizontal(
342+
Select(
343+
(
344+
("Unread", "unread"),
345+
("Read", "read"),
346+
("All", "all"),
347+
),
348+
value="unread",
349+
id="filter_articles_type",
307350
),
308-
value="unread",
309-
id="filter_articles_type",
351+
Input(
352+
placeholder="Search " + Emoji.replace(":magnifying_glass_tilted_left:"),
353+
id="search_articles",
354+
),
355+
classes="w100 hauto mb1",
310356
)
311357
yield Articles(
312358
id="articles"
@@ -317,6 +363,11 @@ def select_changed(self, event: Select.Changed) -> None:
317363
if event.select.id == "filter_articles_type":
318364
self.query_one("#articles").filter_articles_type = event.value
319365

366+
@on(Input.Changed)
367+
def filter_articles(self, event: Input.Changed) -> None:
368+
if event.input.id == "search_articles":
369+
self.query_one("#articles").filter_articles = event.value
370+
320371

321372
class Reader(Vertical):
322373

@@ -357,6 +408,7 @@ class LugusApp(App):
357408
("c", "open_configuration", "Configs"),
358409
("question_mark", "article_data", "Article Raw Data"),
359410
("r", "article_read", "Set Article as Read"),
411+
("a", "all_articles_read", "Set all Feed Articles as Read"),
360412
("o", "read_online", "Read Online"),
361413
]
362414

@@ -492,6 +544,19 @@ def action_article_read(self) -> None:
492544
def action_open_configuration(self) -> None:
493545
self.status = "configuration"
494546

547+
def action_all_articles_read(self) -> None:
548+
feed = self.query_one("#articles").feed
549+
if not feed:
550+
self.notify("Select a feed", severity="warning")
551+
else:
552+
self.orm.update_where(
553+
"article",
554+
f"feed_id = {feed.data["id"]} AND read = 0",
555+
[("read", 1)],
556+
)
557+
self.query_one("#sidebar").recomposes += 1
558+
self.query_one("#articles").recomposes += 1
559+
495560
def action_read_online(self) -> None:
496561
reader = self.query_one("#reader")
497562
if not reader.id_article:

src/lugus/style.tcss

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,26 @@ Screen {
22
layout: horizontal;
33
}
44

5+
.wauto {
6+
width: auto;
7+
}
8+
59
.w100 {
610
width: 100%;
711
}
812

13+
.hauto {
14+
height: auto;
15+
}
16+
917
.h100 {
1018
height: 100%;
1119
}
1220

21+
.mb1 {
22+
margin-bottom: 1;
23+
}
24+
1325
.full_form {
1426
width: 100%;
1527
height: 100%;
@@ -129,3 +141,13 @@ Screen {
129141
width: 100%;
130142
}
131143

144+
#filter_articles_type {
145+
width: 30%;
146+
height: auto;
147+
}
148+
149+
#search_articles {
150+
width: 70%;
151+
height: auto;
152+
}
153+

0 commit comments

Comments
 (0)