fix(download): optimize processing and match API contract

This commit is contained in:
HappyOnigiri
2026-03-05 13:53:12 +09:00
parent 530c4f934d
commit 49033c0600
4 changed files with 18 additions and 16 deletions
+2 -2
View File
@@ -1864,7 +1864,7 @@ def _process_image_for_download(
return buffer.getvalue()
@routes.post("/meld/api/download/zip")
@routes.post("/meld/download/zip")
async def download_zip(request: web.Request) -> web.Response:
try:
data = await request.json()
@@ -1924,7 +1924,7 @@ async def download_zip(request: web.Request) -> web.Response:
return web.json_response(ApiResponse(success=False, error=str(e)).to_dict(), status=500)
@routes.post("/meld/api/download/raw")
@routes.post("/meld/download/raw")
async def download_raw(request: web.Request) -> web.Response:
try:
data = await request.json()
+9 -7
View File
@@ -189,7 +189,7 @@ const fetchImageBlob = async (
resizeValue: number,
resizeFilter: string,
): Promise<{ blob: Blob; filename: string }> => {
const res = await api.fetchApi("/meld/api/download/raw", {
const res = await api.fetchApi("/meld/download/raw", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ imageId, removeMetadata, resizeMode, resizeValue, resizeFilter }),
@@ -232,6 +232,13 @@ export const downloadZipImages = async (
let i = 0;
let totalBytes = 0;
for (const imageId of imageIds) {
// Guard: check entry count limit before fetching
if (i >= MAX_ZIP_FILES) {
throw new Error(
`ZIP entry limit reached (${MAX_ZIP_FILES} files). Please reduce the number of images.`,
);
}
onProgress?.(i, total);
const { blob, filename } = await fetchImageBlob(
imageId,
@@ -241,12 +248,7 @@ export const downloadZipImages = async (
resizeFilter,
);
// Guard: check entry count and total byte size limits before adding to zip
if (i >= MAX_ZIP_FILES) {
throw new Error(
`ZIP entry limit reached (${MAX_ZIP_FILES} files). Please reduce the number of images.`,
);
}
// Guard: check total byte size limit before adding to zip
totalBytes += blob.size;
if (totalBytes > MAX_ZIP_BYTES) {
throw new Error(
@@ -498,7 +498,7 @@ export const DownloadModal: React.FC<DownloadModalProps> = ({ imageIds, onSucces
role="progressbar"
aria-label="Download progress"
aria-valuemin={0}
aria-valuemax={downloadProgress.total}
aria-valuemax={100}
aria-valuenow={Math.round(
(downloadProgress.current / Math.max(1, downloadProgress.total)) * 100,
)}
+6 -6
View File
@@ -6505,7 +6505,7 @@ const Eg = (e) => {
let n = e.replace(/\\/g, "/").split("/").pop() ?? "";
return n = n.replace(/\.\./g, "").replace(/[\x00-\x1f\x7f]/g, "").trim(), !n || n.length > 255 ? t : n;
}, bf = async (e, t, n, r, l) => {
const a = await te.fetchApi("/meld/api/download/raw", {
const a = await te.fetchApi("/meld/download/raw", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ imageId: e, removeMetadata: t, resizeMode: n, resizeValue: r, resizeFilter: l })
@@ -6523,6 +6523,10 @@ const Eg = (e) => {
const o = (await import("./jszip.min.js").then((x) => x.j)).default, i = new o(), c = e.length, d = /* @__PURE__ */ new Set();
let p = 0, v = 0;
for (const x of e) {
if (p >= Rc)
throw new Error(
`ZIP entry limit reached (${Rc} files). Please reduce the number of images.`
);
a == null || a(p, c);
const { blob: _, filename: f } = await bf(
x,
@@ -6531,10 +6535,6 @@ const Eg = (e) => {
r,
l
);
if (p >= Rc)
throw new Error(
`ZIP entry limit reached (${Rc} files). Please reduce the number of images.`
);
if (v += _.size, v > Dc)
throw new Error(
`ZIP size limit reached (${Dc / 1024 / 1024 / 1024} GB). Please reduce the number of images.`
@@ -8344,7 +8344,7 @@ const vy = ({ imageIds: e, onSuccess: t, onClose: n }) => {
role: "progressbar",
"aria-label": "Download progress",
"aria-valuemin": 0,
"aria-valuemax": g.total,
"aria-valuemax": 100,
"aria-valuenow": Math.round(
g.current / Math.max(1, g.total) * 100
),