Add automatic image downloading from URLs during menu import

This commit is contained in:
John Mizerek 2026-02-12 20:48:17 -08:00
parent f882e84704
commit 4471ddc92b

View file

@ -23,6 +23,118 @@
*/ */
response = { "OK": false, "steps": [], "errors": [] }; response = { "OK": false, "steps": [], "errors": [] };
itemsDir = expandPath("/uploads/items");
// Helper function: Resize image maintaining aspect ratio, fitting within maxSize box
function resizeToFit(img, maxSize) {
w = imageGetWidth(img);
h = imageGetHeight(img);
if (w <= maxSize && h <= maxSize) return img;
if (w > h) {
newW = maxSize;
newH = int(h * (maxSize / w));
} else {
newH = maxSize;
newW = int(w * (maxSize / h));
}
imageResize(img, newW, newH, "highQuality");
return img;
}
// Helper function: Create square thumbnail (center crop)
function createSquareThumb(img, size) {
thumb = imageCopy(img, 0, 0, imageGetWidth(img), imageGetHeight(img));
w = imageGetWidth(thumb);
h = imageGetHeight(thumb);
// Resize so smallest dimension equals size
if (w > h) {
imageResize(thumb, "", size, "highQuality");
} else {
imageResize(thumb, size, "", "highQuality");
}
// Center crop to square
w = imageGetWidth(thumb);
h = imageGetHeight(thumb);
if (w > h) {
x = int((w - h) / 2);
imageCrop(thumb, x, 0, h, h);
} else if (h > w) {
y = int((h - w) / 2);
imageCrop(thumb, 0, y, w, w);
}
// Final resize to exact size
imageResize(thumb, size, size, "highQuality");
return thumb;
}
// Helper function: Download and save item image from URL
function downloadItemImage(itemID, imageUrl) {
try {
// Skip empty or invalid URLs
if (!len(trim(imageUrl))) return false;
// Make URL absolute if relative
if (left(imageUrl, 2) == "//") {
imageUrl = "https:" & imageUrl;
} else if (left(imageUrl, 1) == "/") {
// Can't resolve relative URL without base - skip
return false;
}
// Download the image
http url="#imageUrl#" method="GET" timeout="30" result="httpResult" {
httpparam type="header" name="User-Agent" value="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36";
}
if (httpResult.statusCode != "200 OK" && !httpResult.statusCode.startsWith("200")) {
return false;
}
// Check if it's actually an image
contentType = structKeyExists(httpResult.responseHeader, "Content-Type") ? httpResult.responseHeader["Content-Type"] : "";
if (!findNoCase("image", contentType)) {
return false;
}
// Write to temp file
tempFile = itemsDir & "/temp_" & itemID & "_" & createUUID() & ".tmp";
fileWrite(tempFile, httpResult.fileContent);
// Read as image
img = imageNew(tempFile);
// Create thumbnail (128x128 square for retina)
thumb = createSquareThumb(img, 128);
thumbPath = itemsDir & "/" & itemID & "_thumb.jpg";
imageWrite(thumb, thumbPath, 0.85);
// Create medium size (400px max)
medium = imageCopy(img, 0, 0, imageGetWidth(img), imageGetHeight(img));
medium = resizeToFit(medium, 400);
mediumPath = itemsDir & "/" & itemID & "_medium.jpg";
imageWrite(medium, mediumPath, 0.85);
// Save full size (max 1200px)
img = resizeToFit(img, 1200);
fullPath = itemsDir & "/" & itemID & ".jpg";
imageWrite(img, fullPath, 0.90);
// Clean up temp file
try { fileDelete(tempFile); } catch (any e) {}
return true;
} catch (any e) {
// Clean up temp file if it exists
if (isDefined("tempFile") && fileExists(tempFile)) {
try { fileDelete(tempFile); } catch (any e2) {}
}
return false;
}
}
try { try {
requestBody = toString(getHttpRequestData().content); requestBody = toString(getHttpRequestData().content);
@ -465,6 +577,7 @@ try {
totalItems = 0; totalItems = 0;
totalLinks = 0; totalLinks = 0;
totalImages = 0;
// Track item order within each category // Track item order within each category
categoryItemOrder = {}; categoryItemOrder = {};
@ -595,9 +708,20 @@ try {
modOrder++; modOrder++;
} }
} }
// Download item image if URL provided
itemImageUrl = "";
if (structKeyExists(item, "imageUrl") && isSimpleValue(item.imageUrl)) {
itemImageUrl = trim(item.imageUrl);
}
if (len(itemImageUrl)) {
if (downloadItemImage(menuItemID, itemImageUrl)) {
totalImages++;
}
}
} }
response.steps.append("Created/updated " & totalItems & " items with " & totalLinks & " modifier links"); response.steps.append("Created/updated " & totalItems & " items with " & totalLinks & " modifier links" & (totalImages > 0 ? " and " & totalImages & " images downloaded" : ""));
response.OK = true; response.OK = true;
response.summary = { response.summary = {
@ -605,7 +729,8 @@ try {
"categoriesProcessed": arrayLen(categories), "categoriesProcessed": arrayLen(categories),
"templatesProcessed": arrayLen(modTemplates), "templatesProcessed": arrayLen(modTemplates),
"itemsProcessed": totalItems, "itemsProcessed": totalItems,
"linksCreated": totalLinks "linksCreated": totalLinks,
"imagesDownloaded": totalImages
}; };
} catch (any e) { } catch (any e) {