feat: delete non empty folders

This commit is contained in:
kodi
2026-03-14 07:48:29 +01:00
parent f092007998
commit d84b3da561
16 changed files with 218 additions and 11 deletions
+1 -1
View File
@@ -31,7 +31,7 @@ async def delete(
request: DeleteRequest,
service: FileOpsService = Depends(get_file_ops_service),
) -> DeleteResponse:
return service.delete(path=request.path)
return service.delete(path=request.path, recursive=request.recursive)
@router.post("/upload", response_model=UploadResponse)
+1
View File
@@ -52,6 +52,7 @@ class RenameResponse(BaseModel):
class DeleteRequest(BaseModel):
path: str
recursive: bool = False
class DeleteResponse(BaseModel):
@@ -104,6 +104,9 @@ class FilesystemAdapter:
def delete_empty_directory(self, path: Path) -> None:
path.rmdir()
def delete_directory_recursive(self, path: Path) -> None:
shutil.rmtree(path)
def copy_file(self, source: str, destination: str, on_progress: callable | None = None) -> None:
src = Path(source)
dst = Path(destination)
+11 -8
View File
@@ -158,7 +158,7 @@ class FileOpsService:
self._record_history_error(operation="rename", source=path, destination=new_name, path=path, error=error)
raise error
def delete(self, path: str) -> DeleteResponse:
def delete(self, path: str, recursive: bool = False) -> DeleteResponse:
try:
resolved_target = self._path_guard.resolve_existing_path(path)
@@ -166,13 +166,16 @@ class FileOpsService:
self._filesystem.delete_file(resolved_target.absolute)
elif resolved_target.absolute.is_dir():
if not self._filesystem.is_directory_empty(resolved_target.absolute):
raise AppError(
code="directory_not_empty",
message="Directory is not empty",
status_code=409,
details={"path": resolved_target.relative},
)
self._filesystem.delete_empty_directory(resolved_target.absolute)
if not recursive:
raise AppError(
code="directory_not_empty",
message="Directory is not empty",
status_code=409,
details={"path": resolved_target.relative},
)
self._filesystem.delete_directory_recursive(resolved_target.absolute)
else:
self._filesystem.delete_empty_directory(resolved_target.absolute)
else:
raise AppError(
code="type_conflict",