fix: restore original dedup/prompt order in jobs.py, move time import to module level in reconcile.py
_build_job no longer calls filter_already_uploaded internally; callers pass pre-filtered assets so there's no double DB hit and the interactive path restores the original prompt order (retry_rejected asked before strategy, so post-dedup count informs the choice). Skip-count rprint restored in auto_configure. Late 'import time' inside reconcile_frigate_mappings moved to module level.
This commit is contained in:
+35
-39
@@ -122,19 +122,16 @@ def _perform_selection(
|
|||||||
|
|
||||||
def _build_job(
|
def _build_job(
|
||||||
person: dict,
|
person: dict,
|
||||||
recent_assets: list,
|
assets: list,
|
||||||
limit: int | str,
|
limit: int | str,
|
||||||
selection_mode: str,
|
selection_mode: str,
|
||||||
retry_rejected: bool = False,
|
|
||||||
quality_replacement: bool = False,
|
quality_replacement: bool = False,
|
||||||
) -> dict | None:
|
) -> dict | None:
|
||||||
"""Build a job dict from pre-fetched assets and parameters. No I/O."""
|
"""Select from pre-filtered assets and build a job dict. No terminal I/O."""
|
||||||
name = person["name"]
|
if not assets:
|
||||||
new_asset_ids = set(filter_already_uploaded([a["id"] for a in recent_assets], retry_rejected=retry_rejected))
|
|
||||||
new_assets = [a for a in recent_assets if a["id"] in new_asset_ids]
|
|
||||||
if not new_assets:
|
|
||||||
return None
|
return None
|
||||||
selected = _perform_selection(new_assets, limit, name, selection_mode, person_id=person["id"])
|
name = person["name"]
|
||||||
|
selected = _perform_selection(assets, limit, name, selection_mode, person_id=person["id"])
|
||||||
if not selected:
|
if not selected:
|
||||||
return None
|
return None
|
||||||
return {
|
return {
|
||||||
@@ -150,7 +147,6 @@ def _configure_person(person: dict, people: list[dict]) -> dict | None:
|
|||||||
name = person["name"]
|
name = person["name"]
|
||||||
console.print(f"\nSelected: [bold green]{name}[/bold green]")
|
console.print(f"\nSelected: [bold green]{name}[/bold green]")
|
||||||
|
|
||||||
# Fetch and filter assets
|
|
||||||
years = IntPrompt.ask("Filter images older than (years)", default=Config.YEARS_FILTER)
|
years = IntPrompt.ask("Filter images older than (years)", default=Config.YEARS_FILTER)
|
||||||
|
|
||||||
console.print(f"Scanning for {name}...")
|
console.print(f"Scanning for {name}...")
|
||||||
@@ -160,36 +156,32 @@ def _configure_person(person: dict, people: list[dict]) -> dict | None:
|
|||||||
|
|
||||||
rprint(f" Found [bold]{len(all_assets)}[/bold] total, [bold]{len(recent_assets)}[/bold] in range ({years} years).")
|
rprint(f" Found [bold]{len(all_assets)}[/bold] total, [bold]{len(recent_assets)}[/bold] in range ({years} years).")
|
||||||
|
|
||||||
# Strategy selection
|
# Ask before strategy so the post-dedup count can inform the choice
|
||||||
|
retry_env = os.environ.get("RETRY_REJECTED", "false").lower() in ("true", "1", "yes")
|
||||||
|
retry_rejected = Confirm.ask("Include previously rejected images?", default=retry_env)
|
||||||
|
|
||||||
|
before_dedup = len(recent_assets)
|
||||||
|
new_asset_ids = set(filter_already_uploaded([a["id"] for a in recent_assets], retry_rejected=retry_rejected))
|
||||||
|
recent_assets = [a for a in recent_assets if a["id"] in new_asset_ids]
|
||||||
|
skipped = before_dedup - len(recent_assets)
|
||||||
|
if skipped:
|
||||||
|
rprint(f" [dim]Skipped {skipped} assets already uploaded to Frigate.[/dim]")
|
||||||
|
|
||||||
|
if not recent_assets:
|
||||||
|
rprint(" [dim]Skipping (0 new images after dedup).[/dim]")
|
||||||
|
return None
|
||||||
|
|
||||||
has_embedding = is_embedding_available()
|
has_embedding = is_embedding_available()
|
||||||
rprint(f"\n[bold cyan]Select Training Strategy for {name}:[/bold cyan]")
|
rprint(f"\n[bold cyan]Select Training Strategy for {name}:[/bold cyan]")
|
||||||
|
|
||||||
limit, selection_mode = _get_strategy_choice(has_embedding)
|
limit, selection_mode = _get_strategy_choice(has_embedding)
|
||||||
if selection_mode == "skip":
|
if selection_mode == "skip":
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# In interactive mode, ask about retry_rejected — use env var as default
|
job = _build_job(person, recent_assets, limit, selection_mode, quality_replacement=Config.QUALITY_REPLACEMENT)
|
||||||
retry_env = os.environ.get("RETRY_REJECTED", "false").lower() in ("true", "1", "yes")
|
|
||||||
retry_rejected = Confirm.ask("Include previously rejected images?", default=retry_env)
|
|
||||||
|
|
||||||
job = _build_job(
|
|
||||||
person,
|
|
||||||
recent_assets,
|
|
||||||
limit,
|
|
||||||
selection_mode,
|
|
||||||
retry_rejected=retry_rejected,
|
|
||||||
quality_replacement=Config.QUALITY_REPLACEMENT,
|
|
||||||
)
|
|
||||||
if job is None:
|
if job is None:
|
||||||
rprint(" [dim]Skipping (0 new images after dedup or selection).[/dim]")
|
rprint(" [dim]Skipping (0 images selected).[/dim]")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Show how many were skipped (dedup info)
|
|
||||||
new_asset_ids = set(filter_already_uploaded([a["id"] for a in recent_assets], retry_rejected=retry_rejected))
|
|
||||||
skipped = len(recent_assets) - len(new_asset_ids)
|
|
||||||
if skipped:
|
|
||||||
rprint(f" [dim]Skipped {skipped} assets already uploaded to Frigate.[/dim]")
|
|
||||||
|
|
||||||
rprint(f" [green]Queued {job['limit']} images for {name}.[/green]")
|
rprint(f" [green]Queued {job['limit']} images for {name}.[/green]")
|
||||||
return job
|
return job
|
||||||
|
|
||||||
@@ -312,16 +304,20 @@ def auto_configure(people: list[dict]) -> list[dict]:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
retry_rejected = os.environ.get("RETRY_REJECTED", "false").lower() in ("true", "1", "yes")
|
retry_rejected = os.environ.get("RETRY_REJECTED", "false").lower() in ("true", "1", "yes")
|
||||||
job = _build_job(
|
before_dedup = len(recent_assets)
|
||||||
person,
|
new_asset_ids = set(filter_already_uploaded([a["id"] for a in recent_assets], retry_rejected=retry_rejected))
|
||||||
recent_assets,
|
recent_assets = [a for a in recent_assets if a["id"] in new_asset_ids]
|
||||||
limit,
|
skipped = before_dedup - len(recent_assets)
|
||||||
selection_mode,
|
if skipped:
|
||||||
retry_rejected=retry_rejected,
|
rprint(f" [dim]Skipped {skipped} assets already uploaded to Frigate.[/dim]")
|
||||||
quality_replacement=quality_replacement,
|
|
||||||
)
|
if not recent_assets:
|
||||||
|
rprint(f" [dim]Skipping {name} (0 new images after dedup).[/dim]")
|
||||||
|
continue
|
||||||
|
|
||||||
|
job = _build_job(person, recent_assets, limit, selection_mode, quality_replacement=quality_replacement)
|
||||||
if job is None:
|
if job is None:
|
||||||
rprint(f" [dim]Skipping {name} (0 new images after dedup or selection).[/dim]")
|
rprint(f" [dim]Skipping {name} (0 images selected).[/dim]")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Apply auto_cap post-selection if needed
|
# Apply auto_cap post-selection if needed
|
||||||
|
|||||||
+1
-2
@@ -1,6 +1,7 @@
|
|||||||
"""Frigate upload post-processing: reconciliation and asset enrichment."""
|
"""Frigate upload post-processing: reconciliation and asset enrichment."""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import time
|
||||||
|
|
||||||
from .frigate_api import get_frigate_person_files
|
from .frigate_api import get_frigate_person_files
|
||||||
from .immich_api import fetch_face_data
|
from .immich_api import fetch_face_data
|
||||||
@@ -30,8 +31,6 @@ def reconcile_frigate_mappings(
|
|||||||
diffing. Until then, the external-upload guard keeps mappings correct at
|
diffing. Until then, the external-upload guard keeps mappings correct at
|
||||||
the cost of occasionally missing them when another client is active.
|
the cost of occasionally missing them when another client is active.
|
||||||
"""
|
"""
|
||||||
import time
|
|
||||||
|
|
||||||
target = len(uploaded)
|
target = len(uploaded)
|
||||||
current_files: set[str] = set()
|
current_files: set[str] = set()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user