From b09ba3fa9ea369783db27e5e46798de7512a063e Mon Sep 17 00:00:00 2001 From: Ethanfel Date: Thu, 16 Apr 2026 14:20:20 +0200 Subject: [PATCH] fix: third-pass review bugs - Switch DELETE /export to query param (path param strips leading /) - Add CropKeyframe Pydantic model for typed keyframe validation - Convert keyframes to tuples before passing to apply_keyframes_to_jobs - Remove dead QFrame import from main.py Co-Authored-By: Claude Opus 4.6 --- main.py | 2 +- server/routes/export.py | 22 +++++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/main.py b/main.py index ed9fb33..8810fd1 100755 --- a/main.py +++ b/main.py @@ -12,7 +12,7 @@ from pathlib import Path from PyQt6.QtWidgets import ( QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, - QLabel, QPushButton, QLineEdit, QFileDialog, QFrame, + QLabel, QPushButton, QLineEdit, QFileDialog, QListWidget, QListWidgetItem, QAbstractItemView, QSplitter, QToolTip, QComboBox, QCheckBox, QSpinBox, QDoubleSpinBox, QMessageBox, QInputDialog, diff --git a/server/routes/export.py b/server/routes/export.py index 6f47714..53d98f6 100644 --- a/server/routes/export.py +++ b/server/routes/export.py @@ -3,7 +3,7 @@ import re import shutil import uuid -from fastapi import APIRouter, HTTPException +from fastapi import APIRouter, HTTPException, Query from pydantic import BaseModel from core.export import ExportRunner @@ -19,6 +19,14 @@ _jobs: dict[str, dict] = {} _VALID_ENCODERS = {"libx264", "h264_nvenc", "h264_vaapi", "h264_qsv", "h264_amf", "h264_videotoolbox"} +class CropKeyframe(BaseModel): + time: float + center: float + ratio: str | None = None + rand_portrait: bool = False + rand_square: bool = False + + class ExportRequest(BaseModel): input_path: str cursor: float @@ -33,7 +41,7 @@ class ExportRequest(BaseModel): category: str = "" profile: str = "default" folder_suffix: str = "" - crop_keyframes: list | None = None + crop_keyframes: list[CropKeyframe] | None = None rand_portrait: bool = False rand_square: bool = False encoder: str = "libx264" @@ -101,8 +109,12 @@ def start_export(req: ExportRequest): # Apply keyframes if provided — returns 6-tuples, strip back to 4 if req.crop_keyframes: + kf_tuples = [ + (kf.time, kf.center, kf.ratio, kf.rand_portrait, kf.rand_square) + for kf in req.crop_keyframes + ] widened = apply_keyframes_to_jobs( - jobs, req.crop_keyframes, + jobs, kf_tuples, req.crop_center, req.portrait_ratio, req.rand_portrait, req.rand_square, ) @@ -176,8 +188,8 @@ def get_export_status(job_id: str): } -@router.delete("/export/{output_path:path}") -def delete_export(output_path: str): +@router.delete("/export") +def delete_export(output_path: str = Query(...)): from ..app import db # Validate path is under EXPORT_DIR real = os.path.realpath(output_path)