fix: add upload images #50
@@ -23,7 +23,9 @@
|
|||||||
"esbenp.prettier-vscode",
|
"esbenp.prettier-vscode",
|
||||||
"PeterSchmalfeldt.explorer-exclude",
|
"PeterSchmalfeldt.explorer-exclude",
|
||||||
"redhat.java",
|
"redhat.java",
|
||||||
"ryanluker.vscode-coverage-gutters"
|
"ryanluker.vscode-coverage-gutters",
|
||||||
|
"ms-python.black-formatter",
|
||||||
|
"ms-python.python"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
+20
-17
@@ -1,49 +1,52 @@
|
|||||||
import uuid
|
import uuid
|
||||||
import io
|
import io
|
||||||
import magic
|
|
||||||
from fastapi import FastAPI, Request, HTTPException
|
from fastapi import FastAPI, Request, HTTPException
|
||||||
from fastapi.responses import FileResponse
|
from fastapi.responses import FileResponse
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
import filetype
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
||||||
STORAGE_DIR = Path("images")
|
STORAGE_DIR = Path("images")
|
||||||
STORAGE_DIR.mkdir(exist_ok=True)
|
STORAGE_DIR.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
@app.post("/")
|
@app.post("/")
|
||||||
async def upload_image(request: Request):
|
async def upload_image(request: Request):
|
||||||
body = await request.body()
|
body = await request.body()
|
||||||
if not body:
|
|
||||||
raise HTTPException(status_code=400, detail="Body trống")
|
|
||||||
|
|
||||||
mime = magic.Magic(mime=True)
|
if not body:
|
||||||
content_type = mime.from_buffer(body)
|
raise HTTPException(status_code=400, detail="Dữ liệu trống")
|
||||||
|
|
||||||
if not content_type.startswith("image/"):
|
kind = filetype.guess(body)
|
||||||
raise HTTPException(status_code=400, detail=f"Định dạng không hỗ trợ: {content_type}")
|
if kind is None or not kind.mime.startswith("image/"):
|
||||||
|
mime_type = kind.mime if kind else "không xác định"
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400, detail=f"Định dạng {mime_type} không được hỗ trợ"
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
img_data = io.BytesIO(body)
|
img = Image.open(io.BytesIO(body))
|
||||||
img = Image.open(img_data)
|
|
||||||
|
|
||||||
random_filename = f"{uuid.uuid4()}.webp"
|
random_filename = f"{uuid.uuid4()}.webp"
|
||||||
file_path = STORAGE_DIR / random_filename
|
file_path = STORAGE_DIR / random_filename
|
||||||
|
|
||||||
img.save(file_path, format="WEBP", quality=80)
|
img.save(file_path, format="WEBP", quality=80)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"status": "success",
|
||||||
|
"filename": random_filename,
|
||||||
|
"original_type": kind.mime,
|
||||||
|
}
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise HTTPException(status_code=500, detail=f"Lỗi xử lý ảnh: {str(e)}")
|
raise HTTPException(status_code=500, detail=f"Lỗi xử lý ảnh: {str(e)}")
|
||||||
|
|
||||||
return {
|
|
||||||
"status": "success",
|
|
||||||
"original_format": content_type,
|
|
||||||
"filename": random_filename
|
|
||||||
}
|
|
||||||
|
|
||||||
@app.get("/{name}")
|
@app.get("/{name}")
|
||||||
async def get_image(name: str):
|
async def get_image(name: str):
|
||||||
file_path = STORAGE_DIR / name
|
file_path = STORAGE_DIR / name
|
||||||
if not file_path.exists():
|
if not file_path.exists():
|
||||||
raise HTTPException(status_code=404, detail="NotFoundImage")
|
raise HTTPException(status_code=404, detail="NotFoundImage")
|
||||||
return FileResponse(file_path)
|
return FileResponse(file_path)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
fastapi
|
fastapi
|
||||||
uvicorn
|
uvicorn
|
||||||
python-multipart
|
python-multipart
|
||||||
python-magic
|
Pillow
|
||||||
Pillow
|
filetype
|
||||||
@@ -2,15 +2,14 @@ package com.drinkool.controller;
|
|||||||
|
|
||||||
import com.drinkool.services.FileService;
|
import com.drinkool.services.FileService;
|
||||||
import io.smallrye.mutiny.Uni;
|
import io.smallrye.mutiny.Uni;
|
||||||
|
import io.vertx.mutiny.core.buffer.Buffer;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.ws.rs.GET;
|
import jakarta.ws.rs.GET;
|
||||||
import jakarta.ws.rs.POST;
|
import jakarta.ws.rs.POST;
|
||||||
import jakarta.ws.rs.Path;
|
import jakarta.ws.rs.Path;
|
||||||
import jakarta.ws.rs.PathParam;
|
import jakarta.ws.rs.PathParam;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
import java.io.File;
|
|
||||||
import org.eclipse.microprofile.rest.client.inject.RestClient;
|
import org.eclipse.microprofile.rest.client.inject.RestClient;
|
||||||
import org.jboss.resteasy.reactive.RestForm;
|
|
||||||
|
|
||||||
@Path("/api/file")
|
@Path("/api/file")
|
||||||
public class FileController {
|
public class FileController {
|
||||||
@@ -20,8 +19,8 @@ public class FileController {
|
|||||||
FileService fileService;
|
FileService fileService;
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
public Uni<Response> upload(@RestForm File file) {
|
public Uni<Response> upload(Buffer body) {
|
||||||
return fileService.upload(file);
|
return fileService.upload(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
package com.drinkool.services;
|
package com.drinkool.services;
|
||||||
|
|
||||||
import io.smallrye.mutiny.Uni;
|
import io.smallrye.mutiny.Uni;
|
||||||
|
import io.vertx.mutiny.core.buffer.Buffer;
|
||||||
import jakarta.ws.rs.GET;
|
import jakarta.ws.rs.GET;
|
||||||
import jakarta.ws.rs.POST;
|
import jakarta.ws.rs.POST;
|
||||||
import jakarta.ws.rs.Path;
|
import jakarta.ws.rs.Path;
|
||||||
import jakarta.ws.rs.PathParam;
|
import jakarta.ws.rs.PathParam;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
import java.io.File;
|
|
||||||
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
|
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
|
||||||
import org.jboss.resteasy.reactive.RestForm;
|
|
||||||
|
|
||||||
@RegisterRestClient(configKey = "file")
|
@RegisterRestClient(configKey = "file")
|
||||||
@Path("/")
|
@Path("/")
|
||||||
public interface FileService {
|
public interface FileService {
|
||||||
@POST
|
@POST
|
||||||
Uni<Response> upload(@RestForm File file);
|
Uni<Response> upload(Buffer body);
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("/{name}")
|
@Path("/{name}")
|
||||||
|
|||||||
Reference in New Issue
Block a user