diff --git a/src/seedpass/cli.py b/src/seedpass/cli.py index f423dea..620678c 100644 --- a/src/seedpass/cli.py +++ b/src/seedpass/cli.py @@ -113,7 +113,7 @@ def main(ctx: typer.Context, fingerprint: Optional[str] = fingerprint_option) -> def entry_list( ctx: typer.Context, sort: str = typer.Option( - "index", "--sort", help="Sort by 'index', 'label', or 'username'" + "index", "--sort", help="Sort by 'index', 'label', or 'updated'" ), kind: Optional[str] = typer.Option(None, "--kind", help="Filter by entry type"), archived: bool = typer.Option(False, "--archived", help="Include archived"), diff --git a/src/seedpass/core/entry_management.py b/src/seedpass/core/entry_management.py index ad0bc2e..406cfa8 100644 --- a/src/seedpass/core/entry_management.py +++ b/src/seedpass/core/entry_management.py @@ -922,10 +922,17 @@ class EntryManager: include_archived: bool = False, verbose: bool = True, ) -> List[Tuple[int, str, Optional[str], Optional[str], bool]]: - """List entries in the index with optional sorting and filtering. + """List entries sorted and filtered according to the provided options. - By default archived entries are omitted unless ``include_archived`` is - ``True``. + Parameters + ---------- + sort_by: + Field to sort by. Supported values are ``"index"``, ``"label"`` and + ``"updated"``. + filter_kind: + Optional entry kind to restrict the results. + + Archived entries are omitted unless ``include_archived`` is ``True``. """ try: data = self._load_index() @@ -941,11 +948,14 @@ class EntryManager: idx_str, entry = item if sort_by == "index": return int(idx_str) - if sort_by in {"website", "label"}: + if sort_by == "label": + # labels are stored in the index so no additional + # decryption is required when sorting return entry.get("label", entry.get("website", "")).lower() - if sort_by == "username": - return entry.get("username", "").lower() - raise ValueError("sort_by must be 'index', 'label', or 'username'") + if sort_by == "updated": + # sort newest first + return -int(entry.get("updated", 0)) + raise ValueError("sort_by must be 'index', 'label', or 'updated'") sorted_items = sorted(entries_data.items(), key=sort_key) diff --git a/src/tests/test_list_entries_sort_filter.py b/src/tests/test_list_entries_sort_filter.py index 68d693f..4361008 100644 --- a/src/tests/test_list_entries_sort_filter.py +++ b/src/tests/test_list_entries_sort_filter.py @@ -19,29 +19,35 @@ def setup_entry_manager(tmp_path: Path) -> EntryManager: return EntryManager(vault, backup_mgr) -def test_sort_by_website(): +def test_sort_by_label(): with TemporaryDirectory() as tmpdir: tmp_path = Path(tmpdir) em = setup_entry_manager(tmp_path) idx0 = em.add_entry("b.com", 8, "user1") idx1 = em.add_entry("A.com", 8, "user2") - result = em.list_entries(sort_by="website") + result = em.list_entries(sort_by="label") assert result == [ (idx1, "A.com", "user2", "", False), (idx0, "b.com", "user1", "", False), ] -def test_sort_by_username(): +def test_sort_by_updated(): with TemporaryDirectory() as tmpdir: tmp_path = Path(tmpdir) em = setup_entry_manager(tmp_path) - idx0 = em.add_entry("alpha.com", 8, "Charlie") - idx1 = em.add_entry("beta.com", 8, "alice") - result = em.list_entries(sort_by="username") + idx0 = em.add_entry("alpha.com", 8, "u0") + idx1 = em.add_entry("beta.com", 8, "u1") + + data = em._load_index(force_reload=True) + data["entries"][str(idx0)]["updated"] = 1 + data["entries"][str(idx1)]["updated"] = 2 + em._save_index(data) + + result = em.list_entries(sort_by="updated") assert result == [ - (idx1, "beta.com", "alice", "", False), - (idx0, "alpha.com", "Charlie", "", False), + (idx1, "beta.com", "u1", "", False), + (idx0, "alpha.com", "u0", "", False), ]