Add backup recovery center

This commit is contained in:
Philip Guzman
2026-07-01 15:34:58 -07:00
parent c4f1b4535d
commit da72419ce9
9 changed files with 184 additions and 5 deletions
+28
View File
@@ -19,6 +19,7 @@ from serato_doctor.scanner import scan_filesystem
from serato_doctor.repair import (
BACKUP_FOLDER,
apply_duplicate_repair,
list_backups,
plan_duplicate_repair,
restore_backup,
)
@@ -29,6 +30,7 @@ DETAIL_LIMIT = 50
STATIC_FILES = {
"/": ("index.html", "text/html; charset=utf-8"),
"/app.css": ("app.css", "text/css; charset=utf-8"),
"/recovery.css": ("recovery.css", "text/css; charset=utf-8"),
"/app.js": ("app.js", "text/javascript; charset=utf-8"),
}
@@ -269,6 +271,29 @@ def duplicate_repair(
return result
def backup_history(serato: Path) -> dict:
serato = serato.expanduser().resolve()
if not serato.is_dir():
raise ValueError(f"Serato folder does not exist: {serato}")
backups = list_backups(serato)
return {
"total": len(backups),
"size_bytes": sum(backup.size_bytes for backup in backups),
"items": [
{
"path": str(backup.path),
"created_at": backup.created_at,
"keeper": str(backup.keeper),
"replaced": [str(path) for path in backup.replaced],
"size_bytes": backup.size_bytes,
"status": backup.status,
"restored_at": backup.restored_at,
}
for backup in backups
],
}
class SeratoDoctorHandler(BaseHTTPRequestHandler):
def do_GET(self) -> None:
asset = STATIC_FILES.get(self.path)
@@ -293,6 +318,7 @@ class SeratoDoctorHandler(BaseHTTPRequestHandler):
"/api/duplicates/preview",
"/api/duplicates/apply",
"/api/backups/restore",
"/api/backups",
}
if self.path not in allowed:
self._json_response(404, {"error": "Not found"})
@@ -309,6 +335,8 @@ class SeratoDoctorHandler(BaseHTTPRequestHandler):
result = analyze_paths(
Path(payload["serato"]), Path(payload["music"]), roots
)
elif self.path == "/api/backups":
result = backup_history(Path(payload["serato"]))
elif self.path == "/api/backups/restore":
serato = Path(payload["serato"]).expanduser().resolve()
backup = Path(payload["backup"]).expanduser().resolve()