mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-08 23:38:49 +00:00
Merge pull request #640 from PR0M3TH3AN/codex/modify-entry-listing-with-sort-and-filter
Update entry listing options
This commit is contained in:
@@ -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"),
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
@@ -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),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user