fix: v0.5.20 — migration safety, URL normalization, image rejection, atomic writes

- upload_tracker: replace executescript() in _migrate_schema_v2 with
  individual execute() calls inside a transaction so a crash between DROP
  and RENAME rolls back instead of permanently destroying tracked_assets
- frigate_api: _get_frigate_url now strips leading/trailing whitespace
  before rstrip('/') so whitespace-only FRIGATE_URL is treated as unset
- executor: upload_to_frigate now uses _get_frigate_url() eliminating
  double-slash upload paths when FRIGATE_URL has a trailing slash
- executor: corrupt thumbnail (resp.ok=True, Image.open fails) now calls
  mark_rejected() so permanently broken assets are not retried forever
- upload_tracker: reset_person now uses _get_frigate_url() instead of
  inline os.environ.get('FRIGATE_URL', '').strip()
- image_processing: _save_jpeg writes to a .tmp file and calls
  os.replace() so a disk-full error never leaves a truncated JPEG
- cli: _handle_duplicate_people falls back to local deduplication when
  all Immich merges fail, preventing two jobs from overwriting the same
  Frigate folder
- config: _getenv_optional_float now delegates to _getenv_num() like
  _getenv_optional_int, eliminating the inconsistent duplicate
- reconcile: _ts() uses rsplit('.', 1)[0] instead of .replace('.webp','')
  so FIFO mapping works with any Frigate training-file extension
This commit is contained in:
2026-06-15 03:26:51 +00:00
parent 728b84dc8c
commit 95fb39ed50
9 changed files with 82 additions and 35 deletions
+2 -8
View File
@@ -35,14 +35,8 @@ def _getenv_float(name: str, default: float) -> float:
def _getenv_optional_float(name: str) -> float | None:
raw = os.getenv(name, "").strip()
if not raw:
return None
try:
return float(raw)
except ValueError:
logging.warning("%s=%r is not a valid float — ignoring", name, raw)
return None
"""Return float value of env var, or None if unset/empty. Warns and returns None on invalid."""
return _getenv_num(name, None, float)
def _getenv_optional_int(name: str) -> int | None: