fix: close library upload flow and harden image storage
Community checks / verify (push) Skipped
Verify Frame Flow / verify (push) Successful in 8m9s

This commit is contained in:
渡口浪人
2026-10-24 00:38:00 +08:00
parent 0859871363
commit 1494904b12
39 changed files with 1471 additions and 240 deletions
+16 -10
View File
@@ -1,6 +1,7 @@
"""Opt-in local retention, protecting stars, current content and durable references."""
import re
import shutil
import time
from datetime import UTC, datetime, timedelta
@@ -80,7 +81,19 @@ class LocalRetention:
def stats(self):
rows = self.inspect()
protected = self.protected()
disk = shutil.disk_usage(self.service.settings.data_dir)
low_space = disk.free < max(512 * 1024 * 1024, int(disk.total * 0.05))
return {
"disk": {
"total_bytes": disk.total,
"used_bytes": disk.used,
"free_bytes": disk.free,
"low_space": low_space,
},
"pending_file_cleanup": len(
self.service.db.all("SELECT id FROM asset_file_journal")
)
+ len(self.service.db.all("SELECT id FROM asset_file_moves")),
"policy": self.config().model_dump(),
"total_bytes": sum(x[2] for x in rows),
"asset_count": len(rows),
@@ -92,6 +105,7 @@ class LocalRetention:
return {}
if not dry_run:
self.last = time.monotonic()
self.service.assets.recover_files()
config = self.config()
if not config.enabled:
return {"deleted": 0, "bytes_freed": 0, "disabled": True}
@@ -101,7 +115,7 @@ class LocalRetention:
total = sum(x[2] for x in rows)
removed = []
freed = 0
for row, path, size in rows:
for row, _path, size in rows:
# Manual uploaded photos are never removed by automatic retention.
if row["id"] in protected or row["kind"] not in ("generated", "cache"):
continue
@@ -119,15 +133,7 @@ class LocalRetention:
total -= size
freed += size
if not dry_run:
path.unlink(missing_ok=True)
for table, key in [
("asset_metadata", "asset_id"),
("asset_sources", "asset_id"),
("assets", "id"),
]:
self.service.db.execute(
f"DELETE FROM {table} WHERE {key}=?", (row["id"],)
)
self.service.libraries.remove_asset(row["id"])
result = {"deleted": len(removed), "bytes_freed": freed, "dry_run": dry_run}
if not dry_run:
self.service.db.execute(