show disk space reclaimed by media sync (#24189)

This commit is contained in:
Josh Hawkins
2026-09-12 07:30:04 -06:00
committed by Nicolas Mowen
parent d6b93301e2
commit 6d33b31bc6
6 changed files with 112 additions and 8 deletions
+65 -7
View File
@@ -41,6 +41,14 @@ FFPROBE_PATH = (
)
def _file_size(path: str) -> int:
"""Return the size of a file in bytes, or 0 if it cannot be read."""
try:
return os.path.getsize(path)
except OSError:
return 0
@dataclass
class SyncResult:
"""Result of a sync operation."""
@@ -49,6 +57,7 @@ class SyncResult:
files_checked: int = 0
orphans_found: int = 0
orphans_deleted: int = 0
bytes_reclaimed: int = 0
orphan_paths: list[str] = field(default_factory=list)
orphan_db_paths: list[str] = field(default_factory=list)
aborted: bool = False
@@ -60,6 +69,7 @@ class SyncResult:
"files_checked": self.files_checked,
"orphans_found": self.orphans_found,
"orphans_deleted": self.orphans_deleted,
"bytes_reclaimed": self.bytes_reclaimed,
"aborted": self.aborted,
"error": self.error,
}
@@ -235,6 +245,7 @@ def sync_recordings(
return result
if dry_run:
result.bytes_reclaimed = sum(_file_size(f) for f in files_to_delete)
logger.info(
f"Recordings sync (dry run): Found {len(files_to_delete)} orphaned files"
)
@@ -243,11 +254,15 @@ def sync_recordings(
# Delete orphans
logger.info(f"Deleting {len(files_to_delete)} orphaned recordings files")
for file in files_to_delete:
size = _file_size(file)
try:
os.unlink(file)
result.orphans_deleted += 1
except OSError as e:
logger.error(f"Failed to delete {file}: {e}")
continue
result.orphans_deleted += 1
result.bytes_reclaimed += size
logger.debug("End sync recordings.")
@@ -325,6 +340,7 @@ def sync_event_snapshots(dry_run: bool = False, force: bool = False) -> SyncResu
return result
if dry_run:
result.bytes_reclaimed = sum(_file_size(p) for p in orphans)
logger.info(
f"Event snapshots sync (dry run): Found {len(orphans)} orphaned files"
)
@@ -333,11 +349,15 @@ def sync_event_snapshots(dry_run: bool = False, force: bool = False) -> SyncResu
# Delete orphans
logger.info(f"Deleting {len(orphans)} orphaned event snapshot files")
for file_path in orphans:
size = _file_size(file_path)
try:
os.unlink(file_path)
result.orphans_deleted += 1
except OSError as e:
logger.error(f"Failed to delete {file_path}: {e}")
continue
result.orphans_deleted += 1
result.bytes_reclaimed += size
except Exception as e:
logger.error(f"Error syncing event snapshots: {e}")
@@ -421,6 +441,7 @@ def sync_event_thumbnails(dry_run: bool = False, force: bool = False) -> SyncRes
return result
if dry_run:
result.bytes_reclaimed = sum(_file_size(p) for p in orphans)
logger.info(
f"Event thumbnails sync (dry run): Found {len(orphans)} orphaned files"
)
@@ -429,11 +450,15 @@ def sync_event_thumbnails(dry_run: bool = False, force: bool = False) -> SyncRes
# Delete orphans
logger.info(f"Deleting {len(orphans)} orphaned event thumbnail files")
for file_path in orphans:
size = _file_size(file_path)
try:
os.unlink(file_path)
result.orphans_deleted += 1
except OSError as e:
logger.error(f"Failed to delete {file_path}: {e}")
continue
result.orphans_deleted += 1
result.bytes_reclaimed += size
except Exception as e:
logger.error(f"Error syncing event thumbnails: {e}")
@@ -501,6 +526,7 @@ def sync_review_thumbnails(dry_run: bool = False, force: bool = False) -> SyncRe
return result
if dry_run:
result.bytes_reclaimed = sum(_file_size(p) for p in orphans)
logger.info(
f"Review thumbnails sync (dry run): Found {len(orphans)} orphaned files"
)
@@ -509,11 +535,15 @@ def sync_review_thumbnails(dry_run: bool = False, force: bool = False) -> SyncRe
# Delete orphans
logger.info(f"Deleting {len(orphans)} orphaned review thumbnail files")
for file_path in orphans:
size = _file_size(file_path)
try:
os.unlink(file_path)
result.orphans_deleted += 1
except OSError as e:
logger.error(f"Failed to delete {file_path}: {e}")
continue
result.orphans_deleted += 1
result.bytes_reclaimed += size
except Exception as e:
logger.error(f"Error syncing review thumbnails: {e}")
@@ -581,17 +611,22 @@ def sync_previews(dry_run: bool = False, force: bool = False) -> SyncResult:
return result
if dry_run:
result.bytes_reclaimed = sum(_file_size(p) for p in orphans)
logger.info(f"Previews sync (dry run): Found {len(orphans)} orphaned files")
return result
# Delete orphans
logger.info(f"Deleting {len(orphans)} orphaned preview files")
for file_path in orphans:
size = _file_size(file_path)
try:
os.unlink(file_path)
result.orphans_deleted += 1
except OSError as e:
logger.error(f"Failed to delete {file_path}: {e}")
continue
result.orphans_deleted += 1
result.bytes_reclaimed += size
except Exception as e:
logger.error(f"Error syncing previews: {e}")
@@ -673,17 +708,22 @@ def sync_exports(dry_run: bool = False, force: bool = False) -> SyncResult:
return result
if dry_run:
result.bytes_reclaimed = sum(_file_size(p) for p in orphans)
logger.info(f"Exports sync (dry run): Found {len(orphans)} orphaned files")
return result
# Delete orphans
logger.info(f"Deleting {len(orphans)} orphaned export files")
for file_path in orphans:
size = _file_size(file_path)
try:
os.unlink(file_path)
result.orphans_deleted += 1
except OSError as e:
logger.error(f"Failed to delete {file_path}: {e}")
continue
result.orphans_deleted += 1
result.bytes_reclaimed += size
except Exception as e:
logger.error(f"Error syncing exports: {e}")
@@ -733,6 +773,21 @@ class MediaSyncResults:
total += result.orphans_found
return total
@property
def total_bytes_reclaimed(self) -> int:
total = 0
for result in [
self.event_snapshots,
self.event_thumbnails,
self.review_thumbnails,
self.previews,
self.exports,
self.recordings,
]:
if result:
total += result.bytes_reclaimed
return total
@property
def total_orphans_deleted(self) -> int:
total = 0
@@ -764,6 +819,7 @@ class MediaSyncResults:
"files_checked": result.files_checked,
"orphans_found": result.orphans_found,
"orphans_deleted": result.orphans_deleted,
"bytes_reclaimed": result.bytes_reclaimed,
"aborted": result.aborted,
"error": result.error,
}
@@ -771,6 +827,7 @@ class MediaSyncResults:
"files_checked": self.total_files_checked,
"orphans_found": self.total_orphans_found,
"orphans_deleted": self.total_orphans_deleted,
"bytes_reclaimed": self.total_bytes_reclaimed,
}
return results
@@ -874,7 +931,8 @@ def sync_all_media(
logger.info(
f"Media sync complete: checked {results.total_files_checked} files, "
f"found {results.total_orphans_found} orphans, "
f"deleted {results.total_orphans_deleted}"
f"deleted {results.total_orphans_deleted}, "
f"reclaimed {results.total_bytes_reclaimed} bytes"
)
return results