refactor: cleanup audit findings — dedup helpers, prune orphan scores, cache has_frigate_scores
- upload_tracker: extract _pick_mapped_file() private helper; get_lowest_quality_mapped_file and get_most_redundant_mapped_file are now one-liners over the same body - upload_tracker: remove_frigate_file now also prunes the corresponding frigate_scores entry, preventing unbounded accumulation of orphaned score entries across replacement cycles - frigate_api: get_frigate_face_counts delegates to get_all_frigate_person_files, eliminating the duplicated "name != 'train' and isinstance(files, list)" filter body - executor: cache has_frigate_scores(name) as person_has_fscores before the per-file loop; refresh it after each remove_frigate_file call and after each scored upload, eliminating two redundant disk reads per at-cap file iteration - executor: casefold() both sides of the recognize_face person-name comparison so a Frigate casing normalization or manual-registration casing mismatch does not silently suppress scoring Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+14
-18
@@ -22,24 +22,6 @@ def _get_faces_data() -> dict | None:
|
||||
return None
|
||||
|
||||
|
||||
def get_frigate_face_counts() -> dict[str, int] | None:
|
||||
"""Return {person_name: training_image_count} from Frigate's train directory.
|
||||
|
||||
Returns None if FRIGATE_URL is not set or the API is unreachable, so callers
|
||||
can distinguish "API unavailable" from "person has 0 images."
|
||||
"""
|
||||
data = _get_faces_data()
|
||||
if data is None:
|
||||
return None
|
||||
# Response: {person_name: [file, ...], "train": [...], ...}
|
||||
# "train" is a flat pending list, not a person — skip it.
|
||||
return {
|
||||
name: len(files)
|
||||
for name, files in data.items()
|
||||
if name != "train" and isinstance(files, list)
|
||||
}
|
||||
|
||||
|
||||
def get_all_frigate_person_files() -> dict[str, list[str]] | None:
|
||||
"""Return {person_name: [filename, ...]} for every person in Frigate.
|
||||
|
||||
@@ -49,6 +31,8 @@ def get_all_frigate_person_files() -> dict[str, list[str]] | None:
|
||||
data = _get_faces_data()
|
||||
if data is None:
|
||||
return None
|
||||
# Response: {person_name: [file, ...], "train": [...], ...}
|
||||
# "train" is a flat pending list, not a person — skip it.
|
||||
return {
|
||||
name: files
|
||||
for name, files in data.items()
|
||||
@@ -56,6 +40,18 @@ def get_all_frigate_person_files() -> dict[str, list[str]] | None:
|
||||
}
|
||||
|
||||
|
||||
def get_frigate_face_counts() -> dict[str, int] | None:
|
||||
"""Return {person_name: training_image_count} from Frigate's train directory.
|
||||
|
||||
Returns None if FRIGATE_URL is not set or the API is unreachable, so callers
|
||||
can distinguish "API unavailable" from "person has 0 images."
|
||||
"""
|
||||
all_files = get_all_frigate_person_files()
|
||||
if all_files is None:
|
||||
return None
|
||||
return {name: len(files) for name, files in all_files.items()}
|
||||
|
||||
|
||||
def get_frigate_person_files(person_name: str) -> list[str] | None:
|
||||
"""Return the list of training filenames for a person in Frigate.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user