S3 gallery
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
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,
|
||||
};
|
||||
Reference in New Issue
Block a user