diff --git a/frigate/record/cleanup.py b/frigate/record/cleanup.py index e7d633748..15adef6d8 100644 --- a/frigate/record/cleanup.py +++ b/frigate/record/cleanup.py @@ -11,7 +11,7 @@ from pathlib import Path from playhouse.sqlite_ext import SqliteExtDatabase from frigate.config import CameraConfig, FrigateConfig, RetainModeEnum -from frigate.const import CACHE_DIR, CLIPS_DIR, MAX_WAL_SIZE +from frigate.const import CACHE_DIR, CLIPS_DIR, MAX_WAL_SIZE, RECORD_DIR from frigate.models import Previews, Recordings, ReviewSegment, UserReviewStatus from frigate.util.builtin import clear_and_unlink from frigate.util.media import remove_empty_directories @@ -376,5 +376,5 @@ class RecordingCleanup(threading.Thread): if counter == 0: self.clean_tmp_clips() maybe_empty_dirs = self.expire_recordings() - remove_empty_directories(maybe_empty_dirs) + remove_empty_directories(Path(RECORD_DIR), maybe_empty_dirs) self.truncate_wal() diff --git a/frigate/util/media.py b/frigate/util/media.py index 26276f6a6..c7de85c9f 100644 --- a/frigate/util/media.py +++ b/frigate/util/media.py @@ -50,22 +50,36 @@ class SyncResult: } -def remove_empty_directories(paths: Iterable[Path]) -> None: +def remove_empty_directories(root: Path, paths: Iterable[Path]) -> None: """ Remove directories if they exist and are empty. Silently ignores non-existent and non-empty directories. + Attempts to remove parent directories as well, stopping at the given root. """ count = 0 - for path in paths: - try: - path.rmdir() - except FileNotFoundError: - continue - except OSError as e: - if e.errno == errno.ENOTEMPTY: + while True: + parents = set() + for path in paths: + if path == root: continue - raise - count += 1 + + try: + path.rmdir() + count += 1 + except FileNotFoundError: + pass + except OSError as e: + if e.errno == errno.ENOTEMPTY: + continue + raise + + parents.add(path.parent) + + if not parents: + break + + paths = parents + logger.debug("Removed {count} empty directories")