fix: v0.5.21 — diversity cap, fetch rejection, tracker isolation, merge dedup, env parsing

- diversity: cap k-medoids seed count at target so _cluster_aware_selection
  never returns more images than requested (violated MAX_AUTO_IMAGES when
  remaining capacity was 1-4 slots); add early return for limit=0 to
  prevent k-medoids from running with a zero budget; slice return to target
  as a final guard
- executor: mark_rejected() when fetch_full_image returns None so assets
  that can't be fetched (both original and preview) aren't retried every run
- executor: wrap mark_uploaded() in its own try/except so a SQLite disk-full
  error after a successful HTTP 200 doesn't retry the Frigate POST (duplicate
  upload) — the upload succeeded; only the tracker write failed
- cli: apply skip_ids deduplication to the re-fetched people list after a
  partial merge (some groups succeed, some fail) so unmerged duplicates
  don't produce two jobs for the same Frigate folder
- jobs: strip whitespace from SKIP_PEOPLE/ONLY_PEOPLE elements on split
  so "Alice, Bob" (space after comma) correctly matches "Bob"
This commit is contained in:
2026-06-15 03:56:57 +00:00
parent 95fb39ed50
commit 0602c4ac04
6 changed files with 60 additions and 13 deletions
+20 -7
View File
@@ -149,6 +149,10 @@ def execute_jobs(jobs: list[dict]) -> None:
# Use full-resolution for final output when configured
if use_full_res:
img = fetch_full_image(asset["id"])
if img is None:
# Both original and preview fallback failed — mark rejected
# so this asset isn't retried on every future run.
mark_rejected(asset["id"], person_name=name)
else:
resp = requests.get(
f"{Config.IMMICH_URL}/api/assets/{asset['id']}/thumbnail?size=preview&format=JPEG",
@@ -498,13 +502,22 @@ def upload_to_frigate(jobs: list[dict]) -> None:
asset_id = asset_map.get(fname)
if asset_id:
mark_uploaded(
asset_id,
person_name=name,
score=score_map.get(fname),
crop_dims=dims_map.get(fname),
frigate_score=pre_fscore,
)
try:
mark_uploaded(
asset_id,
person_name=name,
score=score_map.get(fname),
crop_dims=dims_map.get(fname),
frigate_score=pre_fscore,
)
except Exception as tracker_exc:
# Upload to Frigate succeeded — don't retry on tracker
# failure or we'd upload a duplicate to Frigate.
logger.error(
"Tracker write failed for %s — upload succeeded"
" but asset may be re-selected next run: %s",
fname, tracker_exc,
)
if pre_fscore is not None:
person_has_fscores = True
actually_uploaded.append((fname, asset_id))