upload: deel 01

This commit is contained in:
kodi
2026-03-13 13:44:41 +01:00
parent 24d47dce8c
commit 8d1ff79912
13 changed files with 505 additions and 4 deletions
+56 -1
View File
@@ -3,7 +3,7 @@ from __future__ import annotations
from pathlib import Path
from backend.app.api.errors import AppError
from backend.app.api.schemas import DeleteResponse, FileInfoResponse, MkdirResponse, RenameResponse, SaveResponse, ViewResponse
from backend.app.api.schemas import DeleteResponse, FileInfoResponse, MkdirResponse, RenameResponse, SaveResponse, UploadResponse, ViewResponse
from backend.app.db.history_repository import HistoryRepository
from backend.app.fs.filesystem_adapter import FilesystemAdapter
from backend.app.security.path_guard import PathGuard
@@ -204,6 +204,61 @@ class FileOpsService:
self._record_history_error(operation="delete", path=path, error=error)
raise error
def upload(self, target_path: str, upload_file) -> UploadResponse:
destination_relative = None
history_path = target_path
try:
resolved_target = self._path_guard.resolve_directory_path(target_path)
filename = Path(upload_file.filename or "").name
safe_name = self._path_guard.validate_name(filename, field="name")
destination_relative = self._join_relative(resolved_target.relative, safe_name)
history_path = destination_relative
resolved_destination = self._path_guard.resolve_path(destination_relative)
if resolved_destination.absolute.exists():
raise AppError(
code="already_exists",
message="Target path already exists",
status_code=409,
details={"path": resolved_destination.relative},
)
saved = self._filesystem.write_uploaded_file(resolved_destination.absolute, upload_file.file)
self._record_history(
operation="upload",
status="completed",
destination=resolved_destination.relative,
path=resolved_destination.relative,
finished_at=self._now_iso(),
)
return UploadResponse(
path=resolved_destination.relative,
size=saved["size"],
modified=saved["modified"],
)
except AppError as exc:
self._record_history_error(
operation="upload",
destination=destination_relative,
path=history_path,
error=exc,
)
raise
except OSError as exc:
error = AppError(
code="io_error",
message="Filesystem operation failed",
status_code=500,
details={"reason": str(exc)},
)
self._record_history_error(
operation="upload",
destination=destination_relative,
path=history_path,
error=error,
)
raise error
def view(self, path: str, for_edit: bool = False) -> ViewResponse:
resolved_target = self._path_guard.resolve_existing_path(path)