fix: skip Frigate API upload for object-mode jobs, preserve object output dir
- upload_to_frigate() now only processes face-mode jobs; object crops are saved to the output directory as the deliverable (Frigate has no API for object classifier training data — it must be copied manually) - execute_jobs() only wipes the output dir for face mode; object crops accumulate across runs as intended Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+23
-5
@@ -90,9 +90,11 @@ def execute_jobs(jobs: list[dict]) -> None:
|
|||||||
|
|
||||||
job_task = progress.add_task(f"Processing {name}...", total=len(assets))
|
job_task = progress.add_task(f"Processing {name}...", total=len(assets))
|
||||||
person_dir = os.path.join(Config.OUTPUT_DIR, name)
|
person_dir = os.path.join(Config.OUTPUT_DIR, name)
|
||||||
if os.path.isdir(person_dir):
|
# Face crops are transient (uploaded then discarded); wipe before each run.
|
||||||
|
# Object crops are the deliverable; preserve them across runs.
|
||||||
|
if mode == "face" and os.path.isdir(person_dir):
|
||||||
shutil.rmtree(person_dir)
|
shutil.rmtree(person_dir)
|
||||||
os.makedirs(person_dir)
|
os.makedirs(person_dir, exist_ok=True)
|
||||||
|
|
||||||
# Track filename → asset_id mapping for upload dedup
|
# Track filename → asset_id mapping for upload dedup
|
||||||
asset_map: dict[str, str] = {}
|
asset_map: dict[str, str] = {}
|
||||||
@@ -160,9 +162,25 @@ def execute_jobs(jobs: list[dict]) -> None:
|
|||||||
def upload_to_frigate(jobs: list[dict]) -> None:
|
def upload_to_frigate(jobs: list[dict]) -> None:
|
||||||
"""Upload processed face crops to Frigate via API with detailed logging.
|
"""Upload processed face crops to Frigate via API with detailed logging.
|
||||||
|
|
||||||
|
Only runs for face-mode jobs. Object-mode crops are saved to the output
|
||||||
|
directory as the deliverable and must be copied to Frigate manually.
|
||||||
|
|
||||||
After each successful upload, records the Immich asset ID in the
|
After each successful upload, records the Immich asset ID in the
|
||||||
upload tracker so it is skipped on future runs.
|
upload tracker so it is skipped on future runs.
|
||||||
"""
|
"""
|
||||||
|
face_jobs = [j for j in jobs if j["config"].get("mode", "face") == "face"]
|
||||||
|
|
||||||
|
if not face_jobs:
|
||||||
|
rprint("[dim]No face-mode jobs to upload.[/dim]")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Notify user about object-mode jobs that were skipped
|
||||||
|
object_jobs = [j for j in jobs if j["config"].get("mode") == "object"]
|
||||||
|
for job in object_jobs:
|
||||||
|
name = job["person"]["name"]
|
||||||
|
person_dir = os.path.join(Config.OUTPUT_DIR, name)
|
||||||
|
rprint(f" [dim]📁 {name} (object): crops saved to {person_dir} — copy to Frigate manually[/dim]")
|
||||||
|
|
||||||
frigate_url = os.environ.get("FRIGATE_URL", "")
|
frigate_url = os.environ.get("FRIGATE_URL", "")
|
||||||
if not frigate_url:
|
if not frigate_url:
|
||||||
rprint("[yellow]⚠️ FRIGATE_URL not set, skipping upload.[/yellow]")
|
rprint("[yellow]⚠️ FRIGATE_URL not set, skipping upload.[/yellow]")
|
||||||
@@ -175,7 +193,7 @@ def upload_to_frigate(jobs: list[dict]) -> None:
|
|||||||
# from the asset_map stored on each job during execute_jobs()
|
# from the asset_map stored on each job during execute_jobs()
|
||||||
filename_to_asset_id: dict[str, dict[str, str]] = {}
|
filename_to_asset_id: dict[str, dict[str, str]] = {}
|
||||||
total_files = 0
|
total_files = 0
|
||||||
for job in jobs:
|
for job in face_jobs:
|
||||||
name = job["person"]["name"]
|
name = job["person"]["name"]
|
||||||
asset_map = job.get("asset_map", {})
|
asset_map = job.get("asset_map", {})
|
||||||
filename_to_asset_id[name] = asset_map
|
filename_to_asset_id[name] = asset_map
|
||||||
@@ -185,7 +203,7 @@ def upload_to_frigate(jobs: list[dict]) -> None:
|
|||||||
rprint(" [yellow]No images found to upload.[/yellow]")
|
rprint(" [yellow]No images found to upload.[/yellow]")
|
||||||
return
|
return
|
||||||
|
|
||||||
rprint(f" People: [bold]{len(jobs)}[/bold], Total images: [bold]{total_files}[/bold]")
|
rprint(f" People: [bold]{len(face_jobs)}[/bold], Total images: [bold]{total_files}[/bold]")
|
||||||
|
|
||||||
uploaded, failed = 0, 0
|
uploaded, failed = 0, 0
|
||||||
max_retries = 2
|
max_retries = 2
|
||||||
@@ -199,7 +217,7 @@ def upload_to_frigate(jobs: list[dict]) -> None:
|
|||||||
) as progress:
|
) as progress:
|
||||||
upload_task = progress.add_task("[green]Uploading to Frigate", total=total_files)
|
upload_task = progress.add_task("[green]Uploading to Frigate", total=total_files)
|
||||||
|
|
||||||
for job in jobs:
|
for job in face_jobs:
|
||||||
name = job["person"]["name"]
|
name = job["person"]["name"]
|
||||||
# URL-encode the name for the API (handles spaces, special chars)
|
# URL-encode the name for the API (handles spaces, special chars)
|
||||||
encoded_name = quote(name, safe="")
|
encoded_name = quote(name, safe="")
|
||||||
|
|||||||
Reference in New Issue
Block a user