Fix preview media sync for per-root preview directories

This commit is contained in:
ibs0d 2026-03-09 21:03:41 +11:00
parent 566166779d
commit 8a57561b15
2 changed files with 37 additions and 5 deletions

View File

@ -6,9 +6,9 @@ from peewee_migrate import Router
from playhouse.sqlite_ext import SqliteExtDatabase
from playhouse.sqliteq import SqliteQueueDatabase
from frigate.models import Recordings, RecordingsToDelete
from frigate.models import Previews, Recordings, RecordingsToDelete
from frigate.test.const import TEST_DB, TEST_DB_CLEANUPS
from frigate.util.media import sync_recordings
from frigate.util.media import sync_previews, sync_recordings
class TestMediaSync(unittest.TestCase):
@ -19,7 +19,7 @@ class TestMediaSync(unittest.TestCase):
migrate_db.close()
self.db = SqliteQueueDatabase(TEST_DB)
models = [Recordings, RecordingsToDelete]
models = [Previews, Recordings, RecordingsToDelete]
self.db.bind(models)
self.root_a = tempfile.mkdtemp()
@ -81,6 +81,24 @@ class TestMediaSync(unittest.TestCase):
assert result.files_checked == 0
assert result.orphans_found == 0
def test_sync_previews_scans_configured_recording_roots(self):
preview_dir = os.path.join(self.root_b, "preview", "front_door")
os.makedirs(preview_dir, exist_ok=True)
orphan_path = os.path.join(preview_dir, "100-200.mp4")
with open(orphan_path, "w"):
pass
result = sync_previews(
dry_run=True,
force=True,
recordings_roots=[self.root_a, self.root_b],
)
assert result.files_checked == 1
assert result.orphans_found == 1
assert orphan_path in result.orphan_paths
if __name__ == "__main__":
unittest.main()

View File

@ -506,7 +506,11 @@ def sync_review_thumbnails(dry_run: bool = False, force: bool = False) -> SyncRe
return result
def sync_previews(dry_run: bool = False, force: bool = False) -> SyncResult:
def sync_previews(
dry_run: bool = False,
force: bool = False,
recordings_roots: list[str] | None = None,
) -> SyncResult:
"""Sync preview files - delete files not referenced by any preview record.
Preview files can exist in camera-specific recording roots at:
@ -528,6 +532,12 @@ def sync_previews(dry_run: bool = False, force: bool = False) -> SyncResult:
for path in preview_paths
if path and path.endswith(".mp4")
}
# Include configured recordings roots so orphaned previews are found even
# when they are not referenced by any DB row.
for root in recordings_roots or [RECORD_DIR]:
preview_dirs.add(os.path.join(root, "preview"))
preview_dirs.add(os.path.join(CLIPS_DIR, "previews"))
preview_files: list[str] = []
@ -809,7 +819,11 @@ def sync_all_media(
results.review_thumbnails = sync_review_thumbnails(dry_run=dry_run, force=force)
if sync_all or "previews" in media_types:
results.previews = sync_previews(dry_run=dry_run, force=force)
results.previews = sync_previews(
dry_run=dry_run,
force=force,
recordings_roots=recordings_roots,
)
if sync_all or "exports" in media_types:
results.exports = sync_exports(dry_run=dry_run, force=force)