Merge pull request #640 from PR0M3TH3AN/codex/modify-entry-listing-with-sort-and-filter

Update entry listing options
This commit is contained in:
thePR0M3TH3AN
2025-07-18 15:29:41 -04:00
committed by GitHub
3 changed files with 32 additions and 16 deletions

View File

@@ -113,7 +113,7 @@ def main(ctx: typer.Context, fingerprint: Optional[str] = fingerprint_option) ->
def entry_list( def entry_list(
ctx: typer.Context, ctx: typer.Context,
sort: str = typer.Option( 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"), kind: Optional[str] = typer.Option(None, "--kind", help="Filter by entry type"),
archived: bool = typer.Option(False, "--archived", help="Include archived"), archived: bool = typer.Option(False, "--archived", help="Include archived"),

View File

@@ -922,10 +922,17 @@ class EntryManager:
include_archived: bool = False, include_archived: bool = False,
verbose: bool = True, verbose: bool = True,
) -> List[Tuple[int, str, Optional[str], Optional[str], bool]]: ) -> 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 Parameters
``True``. ----------
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: try:
data = self._load_index() data = self._load_index()
@@ -941,11 +948,14 @@ class EntryManager:
idx_str, entry = item idx_str, entry = item
if sort_by == "index": if sort_by == "index":
return int(idx_str) 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() return entry.get("label", entry.get("website", "")).lower()
if sort_by == "username": if sort_by == "updated":
return entry.get("username", "").lower() # sort newest first
raise ValueError("sort_by must be 'index', 'label', or 'username'") 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) sorted_items = sorted(entries_data.items(), key=sort_key)

View File

@@ -19,29 +19,35 @@ def setup_entry_manager(tmp_path: Path) -> EntryManager:
return EntryManager(vault, backup_mgr) return EntryManager(vault, backup_mgr)
def test_sort_by_website(): def test_sort_by_label():
with TemporaryDirectory() as tmpdir: with TemporaryDirectory() as tmpdir:
tmp_path = Path(tmpdir) tmp_path = Path(tmpdir)
em = setup_entry_manager(tmp_path) em = setup_entry_manager(tmp_path)
idx0 = em.add_entry("b.com", 8, "user1") idx0 = em.add_entry("b.com", 8, "user1")
idx1 = em.add_entry("A.com", 8, "user2") idx1 = em.add_entry("A.com", 8, "user2")
result = em.list_entries(sort_by="website") result = em.list_entries(sort_by="label")
assert result == [ assert result == [
(idx1, "A.com", "user2", "", False), (idx1, "A.com", "user2", "", False),
(idx0, "b.com", "user1", "", False), (idx0, "b.com", "user1", "", False),
] ]
def test_sort_by_username(): def test_sort_by_updated():
with TemporaryDirectory() as tmpdir: with TemporaryDirectory() as tmpdir:
tmp_path = Path(tmpdir) tmp_path = Path(tmpdir)
em = setup_entry_manager(tmp_path) em = setup_entry_manager(tmp_path)
idx0 = em.add_entry("alpha.com", 8, "Charlie") idx0 = em.add_entry("alpha.com", 8, "u0")
idx1 = em.add_entry("beta.com", 8, "alice") idx1 = em.add_entry("beta.com", 8, "u1")
result = em.list_entries(sort_by="username")
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 == [ assert result == [
(idx1, "beta.com", "alice", "", False), (idx1, "beta.com", "u1", "", False),
(idx0, "alpha.com", "Charlie", "", False), (idx0, "alpha.com", "u0", "", False),
] ]