Implement temporary storage monitoring and clean up system maintenance features
This commit is contained in:
+132
@@ -1074,5 +1074,137 @@ def get_upload_file(filename: str):
|
||||
raise HTTPException(status_code=404, detail="File not found.")
|
||||
return FileResponse(file_path)
|
||||
|
||||
class CleanupTempRequest(BaseModel):
|
||||
paths: List[str] | None = None
|
||||
|
||||
def get_dir_stats(path: str) -> tuple[int, int]:
|
||||
total_size = 0
|
||||
total_files = 0
|
||||
if not os.path.exists(path):
|
||||
return 0, 0
|
||||
for root, dirs, files in os.walk(path):
|
||||
for f in files:
|
||||
fp = os.path.join(root, f)
|
||||
try:
|
||||
if os.path.exists(fp):
|
||||
total_size += os.path.getsize(fp)
|
||||
total_files += 1
|
||||
except Exception:
|
||||
pass
|
||||
return total_size, total_files
|
||||
|
||||
@app.get("/api/system/temp-info")
|
||||
def get_temp_info():
|
||||
temp_folders = []
|
||||
|
||||
# 1. Collect all potential temp root directories
|
||||
# Default temp root
|
||||
temp_roots = {upscaler.TEMP_DIR}
|
||||
|
||||
# Custom temp roots from jobs db
|
||||
for job in jobs_db.values():
|
||||
if getattr(job, "temp_dir", None):
|
||||
temp_roots.add(job.temp_dir)
|
||||
|
||||
# 2. Scan folders inside the temp roots
|
||||
seen_paths = set()
|
||||
for root_dir in temp_roots:
|
||||
if not os.path.exists(root_dir):
|
||||
continue
|
||||
try:
|
||||
for item in os.listdir(root_dir):
|
||||
item_path = os.path.join(root_dir, item)
|
||||
if not os.path.isdir(item_path):
|
||||
continue
|
||||
if item_path in seen_paths:
|
||||
continue
|
||||
seen_paths.add(item_path)
|
||||
|
||||
# Check if it corresponds to a job_id (which is usually a UUID)
|
||||
job_id = item
|
||||
job = jobs_db.get(job_id)
|
||||
|
||||
size_bytes, file_count = get_dir_stats(item_path)
|
||||
|
||||
if job:
|
||||
job_status = job.status
|
||||
video_name = os.path.basename(job.video_path)
|
||||
else:
|
||||
job_status = "orphaned"
|
||||
video_name = "Unknown Video (Orphaned)"
|
||||
|
||||
temp_folders.append({
|
||||
"job_id": job_id,
|
||||
"path": item_path,
|
||||
"size_bytes": size_bytes,
|
||||
"file_count": file_count,
|
||||
"status": job_status,
|
||||
"video_name": video_name
|
||||
})
|
||||
except Exception as e:
|
||||
print(f"Error scanning temp root {root_dir}: {e}")
|
||||
|
||||
return {"temp_folders": temp_folders}
|
||||
|
||||
@app.post("/api/system/temp-cleanup")
|
||||
def cleanup_temp(req: CleanupTempRequest):
|
||||
import shutil
|
||||
cleaned = []
|
||||
errors = []
|
||||
|
||||
# Identify active job IDs
|
||||
active_statuses = ["analyzing", "extracting", "upscaling", "restoring_faces", "interpolating", "assembling"]
|
||||
active_job_ids = {job.job_id for job in jobs_db.values() if job.status in active_statuses}
|
||||
|
||||
# Get current temp folder status
|
||||
temp_info = get_temp_info()
|
||||
folders = temp_info["temp_folders"]
|
||||
|
||||
target_paths = req.paths if req.paths is not None else [f["path"] for f in folders]
|
||||
|
||||
for f in folders:
|
||||
path = f["path"]
|
||||
if path not in target_paths:
|
||||
continue
|
||||
|
||||
# Safety checks:
|
||||
if f["job_id"] in active_job_ids:
|
||||
errors.append(f"Cannot clean up active job {f['job_id']}")
|
||||
continue
|
||||
|
||||
resolved_path = os.path.realpath(path)
|
||||
is_sub_of_temp = resolved_path.startswith(os.path.realpath(upscaler.TEMP_DIR))
|
||||
|
||||
if not is_sub_of_temp:
|
||||
for job in jobs_db.values():
|
||||
if getattr(job, "temp_dir", None):
|
||||
if resolved_path.startswith(os.path.realpath(job.temp_dir)):
|
||||
is_sub_of_temp = True
|
||||
break
|
||||
|
||||
if not is_sub_of_temp:
|
||||
errors.append(f"Safety constraint: Path {path} is not in a valid temp root.")
|
||||
continue
|
||||
|
||||
try:
|
||||
if os.path.exists(path):
|
||||
shutil.rmtree(path)
|
||||
cleaned.append(path)
|
||||
|
||||
# Update DB state if needed
|
||||
job = jobs_db.get(f["job_id"])
|
||||
if job and job.status in ["paused", "interrupted", "failed"]:
|
||||
job.status = "interrupted"
|
||||
job.progress = 0.0
|
||||
job.current_frame = 0
|
||||
job.eta = "Temp files cleaned. Will restart on resume."
|
||||
else:
|
||||
cleaned.append(path)
|
||||
except Exception as e:
|
||||
errors.append(f"Error removing {path}: {str(e)}")
|
||||
|
||||
save_jobs_db()
|
||||
return {"cleaned": cleaned, "errors": errors}
|
||||
|
||||
# Mount static folder
|
||||
app.mount("/", StaticFiles(directory=os.path.join(upscaler.BASE_DIR, "static"), html=True), name="static")
|
||||
|
||||
Reference in New Issue
Block a user