Files
ostandari/server/plugins/galleryImageStorage.js
T
2026-06-19 12:35:49 +03:30

192 lines
4.5 KiB
JavaScript

const sharp = require("sharp");
const s3Storage = require("./s3Storage");
const GALLERY_IMAGE_PREFIX = "uploads/images/gallery";
const GALLERY_GRAPHIC_PREFIX = "uploads/graphics/gallery";
const GALLERY_VIDEO_PREFIX = "uploads/videos/gallery";
const getPrefixForFileType = (fileType) => {
switch (fileType) {
case "graphic":
return GALLERY_GRAPHIC_PREFIX;
case "video":
return GALLERY_VIDEO_PREFIX;
default:
return GALLERY_IMAGE_PREFIX;
}
};
const getGalleryObjectKey = (fileType, fileName) =>
`${getPrefixForFileType(fileType)}/${fileName}`;
const getStoredFileName = (doc, field) =>
doc.get(field, null, { getters: false });
const getStoredArray = (doc, field) => {
const value = doc.get(field, null, { getters: false });
return Array.isArray(value) ? value : [];
};
const deleteGalleryFile = async (fileType, fileName) => {
if (!fileName) return;
const baseName = fileName.replace(/^thumb_/, "");
try {
await s3Storage.deleteObject(getGalleryObjectKey(fileType, baseName));
} catch (error) {
console.log(`Failed to delete ${baseName} from S3:`, error?.message);
}
if (fileType !== "video") {
try {
await s3Storage.deleteObject(
getGalleryObjectKey(fileType, `thumb_${baseName}`)
);
} catch (error) {
console.log(`Failed to delete thumb_${baseName} from S3:`, error?.message);
}
}
};
const uploadProcessedImage = async (
imageData,
imageName,
width,
height,
quality,
prefix = GALLERY_IMAGE_PREFIX
) => {
let pipeline = sharp(imageData);
if (width && height) {
pipeline = pipeline.resize(width, height, { fit: "cover" });
}
const buffer = await pipeline.jpeg({ quality }).toBuffer();
await s3Storage.uploadBuffer(
`${prefix}/${imageName}`,
buffer,
"image/jpeg"
);
return imageName;
};
const uploadGalleryVideo = async (fileData, fileName, contentType) => {
await s3Storage.uploadBuffer(
`${GALLERY_VIDEO_PREFIX}/${fileName}`,
fileData,
contentType
);
return fileName;
};
const uploadGalleryFile = async (fileType, file, galleryId, options = {}) => {
const fileName = `gallery_${galleryId}_${Date.now()}.${
file.mimetype.split("/")[1]
}`;
const prefix = getPrefixForFileType(fileType);
switch (fileType) {
case "image":
await uploadProcessedImage(
file.data,
fileName,
options.mainWidth,
options.mainHeight,
options.mainQuality,
prefix
);
await uploadProcessedImage(
file.data,
`thumb_${fileName}`,
options.thumbWidth,
options.thumbHeight,
options.thumbQuality,
prefix
);
break;
case "graphic":
await uploadProcessedImage(
file.data,
fileName,
null,
null,
options.mainQuality,
prefix
);
await uploadProcessedImage(
file.data,
`thumb_${fileName}`,
options.thumbWidth,
options.thumbHeight,
options.thumbQuality,
prefix
);
break;
case "video":
await uploadGalleryVideo(file.data, fileName, file.mimetype);
break;
}
return fileName;
};
const deleteAllGalleryFiles = async (gallery) => {
const galleryType = getStoredFileName(gallery, "galleryType");
if (galleryType === "image") {
const images = getStoredArray(gallery, "images");
for (const fileName of images) {
await deleteGalleryFile("image", fileName);
}
return;
}
if (galleryType === "graphic") {
await deleteGalleryFile("graphic", getStoredFileName(gallery, "graphic"));
return;
}
if (galleryType === "video") {
await deleteGalleryFile("video", getStoredFileName(gallery, "video"));
}
};
const deleteGalleryCover = async (gallery) => {
const cover = getStoredFileName(gallery, "cover");
const thumbCover = getStoredFileName(gallery, "thumbCover");
if (cover) {
try {
await s3Storage.deleteObject(`${GALLERY_IMAGE_PREFIX}/${cover}`);
} catch (error) {
console.log(`Failed to delete cover from S3:`, error?.message);
}
}
if (thumbCover) {
try {
await s3Storage.deleteObject(`${GALLERY_IMAGE_PREFIX}/${thumbCover}`);
} catch (error) {
console.log(`Failed to delete thumb cover from S3:`, error?.message);
}
}
};
module.exports = {
GALLERY_IMAGE_PREFIX,
GALLERY_GRAPHIC_PREFIX,
GALLERY_VIDEO_PREFIX,
getStoredFileName,
getStoredArray,
deleteGalleryFile,
uploadProcessedImage,
uploadGalleryFile,
deleteAllGalleryFiles,
deleteGalleryCover,
};