feat: download - fase 01
This commit is contained in:
Binary file not shown.
@@ -61,6 +61,19 @@ async def info(
|
||||
return service.info(path=path)
|
||||
|
||||
|
||||
@router.get("/download")
|
||||
async def download(
|
||||
path: str,
|
||||
service: FileOpsService = Depends(get_file_ops_service),
|
||||
) -> StreamingResponse:
|
||||
prepared = service.prepare_download(path=path)
|
||||
return StreamingResponse(
|
||||
prepared["content"],
|
||||
headers=prepared["headers"],
|
||||
media_type=prepared["content_type"],
|
||||
)
|
||||
|
||||
|
||||
@router.get("/video")
|
||||
async def video(
|
||||
path: str,
|
||||
|
||||
Binary file not shown.
@@ -353,6 +353,32 @@ class FileOpsService:
|
||||
height=metadata["height"],
|
||||
)
|
||||
|
||||
def prepare_download(self, path: str) -> dict:
|
||||
resolved_target = self._path_guard.resolve_existing_path(path)
|
||||
|
||||
if resolved_target.absolute.is_dir():
|
||||
raise AppError(
|
||||
code="type_conflict",
|
||||
message="Source must be a file",
|
||||
status_code=409,
|
||||
details={"path": resolved_target.relative},
|
||||
)
|
||||
if not resolved_target.absolute.is_file():
|
||||
raise AppError(
|
||||
code="type_conflict",
|
||||
message="Unsupported path type for download",
|
||||
status_code=409,
|
||||
details={"path": resolved_target.relative},
|
||||
)
|
||||
|
||||
return {
|
||||
"content": self._filesystem.stream_file(resolved_target.absolute),
|
||||
"headers": {
|
||||
"Content-Disposition": f'attachment; filename="{resolved_target.absolute.name}"',
|
||||
},
|
||||
"content_type": self._content_type_for(resolved_target.absolute) or "application/octet-stream",
|
||||
}
|
||||
|
||||
def save(self, path: str, content: str, expected_modified: str) -> SaveResponse:
|
||||
resolved_target = self._path_guard.resolve_existing_path(path)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user