diff --git a/README.md b/README.md index 6be3697..f085c67 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,12 @@ ask_before_marking_as_read = false # If set to true, displays posts marked as read in the current session. show_read = false +# Specifies by which attribute the posts will be sorted. +sort_by = "title" # "published_date", "read_status" + +# Specifies the sorting order. +sort_order = "desc" # "descending", "asc", "ascending" + [client] # Maximum times (in seconds) to wait for all request operations. timeout = 300 diff --git a/pyproject.toml b/pyproject.toml index 1f4e69f..633ee35 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "lazyfeed" -version = "0.1.31" +version = "0.1.35" description = "lazyfeed is a fast, modern and simple terminal base RSS/Atom reader built using textual." license = "MIT" readme = "README.md" diff --git a/src/lazyfeed/config_template.toml b/src/lazyfeed/config_template.toml index e3b49b5..868e2fd 100644 --- a/src/lazyfeed/config_template.toml +++ b/src/lazyfeed/config_template.toml @@ -10,6 +10,12 @@ ask_before_marking_as_read = false # If set to true, displays posts marked as read in the current session. show_read = false +# Specifies by which attribute the posts will be sorted. +sort_by = "title" # "published_date", "read_status" + +# Specifies the sorting order. +sort_order = "desc" # "descending", "asc", "ascending" + [client] # Maximum times (in seconds) to wait for all request operations. timeout = 300 diff --git a/src/lazyfeed/repositories.py b/src/lazyfeed/repositories.py index 1fc0e58..01767fc 100644 --- a/src/lazyfeed/repositories.py +++ b/src/lazyfeed/repositories.py @@ -1,4 +1,4 @@ -from sqlalchemy import select, update +from sqlalchemy import asc, select, update from sqlalchemy.orm import Session from lazyfeed.models import Feed, Post @@ -52,17 +52,17 @@ class PostRepository(Repository[Post]): def __init__(self, session: Session) -> None: super().__init__(session, Post) - def get_by_attributes(self, **kwargs) -> list[Post]: - return ( - self.session.query(Post) - .order_by(Post.published_at.desc()) - .filter_by(**kwargs) - .all() - ) - - def get_all(self) -> list[Post]: - stmt = select(Post).order_by(Post.published_at.desc()) - return self.session.scalars(stmt).all() + def get_sorted(self, sort_by: str, ascending: bool, **kwargs) -> list[Post]: + sort_mapping = { + "title": Post.title, + "published_date": Post.published_at, + "read_status": Post.read, + } + + sort_criteria = sort_mapping.get(sort_by, Post.published_at) + sort_order = sort_criteria.asc() if ascending else sort_criteria.desc() + + return self.session.query(Post).order_by(sort_order).filter_by(**kwargs).all() def mark_all_as_read(self) -> None: stmt = update(Post).where(Post.read == False).values(read=True) diff --git a/src/lazyfeed/settings.py b/src/lazyfeed/settings.py index 950b773..1713fea 100644 --- a/src/lazyfeed/settings.py +++ b/src/lazyfeed/settings.py @@ -26,6 +26,8 @@ class AppSettings(BaseModel): auto_mark_as_read: bool = False ask_before_marking_as_read: bool = False show_read: bool = False + sort_by: str = "title" + sort_order: str = "descending" class Settings(BaseSettings): diff --git a/src/lazyfeed/tabloid.py b/src/lazyfeed/tabloid.py index 2fcef84..ce93d79 100644 --- a/src/lazyfeed/tabloid.py +++ b/src/lazyfeed/tabloid.py @@ -64,8 +64,12 @@ def action_mark_as_fav(self) -> None: async def on_key(self, event: events.Key) -> None: if event.key == "g": - self.first_key_pressed = "g" - self.first_key_time = time.time() + if self.first_key_pressed == "g": + self.action_scroll_top() + self.first_key_pressed = None + else: + self.first_key_pressed = "g" + self.first_key_time = time.time() elif self.first_key_pressed == "g": if time.time() - self.first_key_time < 0.5: action_map = { diff --git a/src/lazyfeed/tui.py b/src/lazyfeed/tui.py index ae1f725..f4ea46b 100644 --- a/src/lazyfeed/tui.py +++ b/src/lazyfeed/tui.py @@ -94,7 +94,7 @@ def open_item(self, message: Tabloid.OpenPost) -> None: self.open_url(post_in_db.url) self.post_repository.update(message.post_id, read=True) - row_removed = self._pop_row(f"{post_in_db.id}") + row_removed = self._pop_post(f"{post_in_db.id}") if not row_removed: self.tabloid.update_cell( @@ -146,7 +146,7 @@ def mark_item_as_read(self, message: Tabloid.MarkPostAsRead) -> None: return self.post_repository.update(message.post_id, read=not post_in_db.read) - row_removed = self._pop_row(f"{post_in_db.id}") + row_removed = self._pop_post(f"{post_in_db.id}") if row_removed: return @@ -163,7 +163,7 @@ def check_confirmation(response: bool | None) -> None: self._mark_all_post_as_read() if self._settings.app.ask_before_marking_as_read: - self.app.push_screen( + self.push_screen( ConfirmModal("Are you sure that you want to mark all items as read?"), check_confirmation, ) @@ -210,7 +210,7 @@ def _gen_row_content(self, post: Post) -> tuple[str, str, str]: return saved, fav, label - def _pop_row(self, row_id: str) -> bool: + def _pop_post(self, row_id: str) -> bool: if self.active_view == ActiveView.PENDING and not self._settings.app.show_read: self.tabloid.remove_row(row_id) return True @@ -219,10 +219,16 @@ def _pop_row(self, row_id: str) -> bool: def _load_posts(self, **kwargs) -> None: self.tabloid.clear() - if not kwargs: - posts = self.post_repository.get_all() - else: - posts = self.post_repository.get_by_attributes(**kwargs) + + sort_by = self._settings.app.sort_by + sort_order = self._settings.app.sort_order + sort_order_ascending = sort_order == "ascending" or sort_order == "asc" + + posts = self.post_repository.get_sorted( + sort_by=sort_by, + ascending=sort_order_ascending, + **kwargs, + ) for post in posts: self.tabloid.add_row(*self._gen_row_content(post), key=f"{post.id}") diff --git a/uv.lock b/uv.lock index 25c73d2..b87f716 100644 --- a/uv.lock +++ b/uv.lock @@ -281,7 +281,7 @@ wheels = [ [[package]] name = "lazyfeed" -version = "0.1.29" +version = "0.1.34" source = { editable = "." } dependencies = [ { name = "aiohttp" },