fix(images): bound digit-string seeds and isolate each card's parse

A seed recorded as a 5000-digit string reached int(), which raises
ValueError past Python's integer string limit, and the listing answered
500. A digit-string seed now has at most 20 digits (2**64 fits), and the
conversion falls back to no seed on ValueError.

Each card's parse is also guarded in the page builder: an unexpected
error in one file's records logs a warning and gives that card no seed
and no first-line title, and the rest of the page still lists.
This commit is contained in:
Vito Sansevero
2026-10-19 23:30:14 -07:00
parent 48f23499d3
commit 46e0f6cf79
4 changed files with 100 additions and 11 deletions
+20 -3
View File
@@ -2351,6 +2351,23 @@ class ImageRoutesMixin:
self.logger.warning("Workspace link summaries could not be read")
return {}
def _card_parse(self, path: Path, records: dict | None) -> tuple:
"""One card's ``(seed, parsed positive)``; ``(None, None)`` on any error.
One file's unexpected parse failure must not fail the whole page: its
card shows no seed and withholds a first-line title.
"""
try:
params = header_params(records)
return card_seed(params), parsed_positive(params)
except Exception:
self.logger.warning(
"Workspace card facts could not be parsed for %s",
path.name,
exc_info=True,
)
return None, None
def _format_workspace_page(
self, page: list[tuple], *, linked: bool = True
) -> list[dict]:
@@ -2384,10 +2401,10 @@ class ImageRoutesMixin:
continue
# Parsed after the handle closes, so a concurrent rename or delete
# (which Windows refuses on open files) is not held up by it.
params = header_params(records)
image["seed"] = card_seed(params)
seed, positive = self._card_parse(path, records)
image["seed"] = seed
summary = summaries.get(str(path)) or _unavailable_link()
image["linked"] = _card_link(summary, parsed_positive(params))
image["linked"] = _card_link(summary, positive)
if linked:
# Image cards carry the star; Library previews show none.
favorites = self._workspace_favorites(page)