S3 for other controolers
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
const s3Storage = require("./s3Storage");
|
||||
|
||||
const BACKUP_PREFIX = "backup";
|
||||
const UPLOADS_PREFIX = "uploads";
|
||||
|
||||
const appendS3UploadsToArchive = async (archive) => {
|
||||
const keys = await s3Storage.listObjects(UPLOADS_PREFIX);
|
||||
|
||||
for (const key of keys) {
|
||||
const buffer = await s3Storage.getObjectBuffer(key);
|
||||
archive.append(buffer, { name: key });
|
||||
}
|
||||
};
|
||||
|
||||
const uploadBackupArchive = async (buffer, fileName) => {
|
||||
await s3Storage.uploadBuffer(
|
||||
`${BACKUP_PREFIX}/${fileName}`,
|
||||
buffer,
|
||||
"application/zip"
|
||||
);
|
||||
};
|
||||
|
||||
const deleteOldBackups = async () => {
|
||||
await s3Storage.deleteObjectsByPrefix(BACKUP_PREFIX);
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
BACKUP_PREFIX,
|
||||
UPLOADS_PREFIX,
|
||||
appendS3UploadsToArchive,
|
||||
uploadBackupArchive,
|
||||
deleteOldBackups,
|
||||
};
|
||||
@@ -0,0 +1,48 @@
|
||||
const s3Storage = require("./s3Storage");
|
||||
|
||||
const PDF_PREFIX = "uploads/pdf";
|
||||
const BOOK_SLIDE_PREFIX = "uploads/books";
|
||||
|
||||
const uploadPdf = async (fileData, fileName) => {
|
||||
const key = `${PDF_PREFIX}/${fileName}`;
|
||||
await s3Storage.uploadBuffer(key, fileData, "application/pdf");
|
||||
return {
|
||||
fileName,
|
||||
url: s3Storage.getPublicUrl(key),
|
||||
};
|
||||
};
|
||||
|
||||
const uploadBookSlide = async (buffer, imageName) => {
|
||||
const key = `${BOOK_SLIDE_PREFIX}/${imageName}.jpeg`;
|
||||
await s3Storage.uploadBuffer(key, buffer, "image/jpeg");
|
||||
return s3Storage.getPublicUrl(key);
|
||||
};
|
||||
|
||||
const deletePdf = async (fileName) => {
|
||||
if (!fileName) return;
|
||||
|
||||
try {
|
||||
await s3Storage.deleteObject(`${PDF_PREFIX}/${fileName}`);
|
||||
} catch (error) {
|
||||
console.log("Failed to delete PDF from S3:", error?.message);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteBookSlide = async (imageName) => {
|
||||
if (!imageName) return;
|
||||
|
||||
try {
|
||||
await s3Storage.deleteObject(`${BOOK_SLIDE_PREFIX}/${imageName}.jpeg`);
|
||||
} catch (error) {
|
||||
console.log("Failed to delete book slide from S3:", error?.message);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
PDF_PREFIX,
|
||||
BOOK_SLIDE_PREFIX,
|
||||
uploadPdf,
|
||||
uploadBookSlide,
|
||||
deletePdf,
|
||||
deleteBookSlide,
|
||||
};
|
||||
@@ -0,0 +1,94 @@
|
||||
const sharp = require("sharp");
|
||||
const s3Storage = require("./s3Storage");
|
||||
|
||||
const CATEGORY_IMAGE_PREFIX = "uploads/images/category";
|
||||
const CATEGORY_SHAFAFIAT_PREFIX = "uploads/images/category/shafafiat";
|
||||
const TERMS_FILE_PREFIX = "uploads/files/terms";
|
||||
|
||||
const getStoredImageName = (doc, field) =>
|
||||
doc.get(field, null, { getters: false });
|
||||
|
||||
const deleteCategoryImage = async (doc, field) => {
|
||||
const fileName = getStoredImageName(doc, field);
|
||||
if (!fileName) return;
|
||||
|
||||
try {
|
||||
await s3Storage.deleteObject(`${CATEGORY_IMAGE_PREFIX}/${fileName}`);
|
||||
} catch (error) {
|
||||
console.log(`Failed to delete ${field} from S3:`, error?.message);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteShafafiatIcon = async (fileName) => {
|
||||
if (!fileName) return;
|
||||
|
||||
try {
|
||||
await s3Storage.deleteObject(`${CATEGORY_SHAFAFIAT_PREFIX}/${fileName}`);
|
||||
} catch (error) {
|
||||
console.log("Failed to delete shafafiat icon from S3:", error?.message);
|
||||
}
|
||||
};
|
||||
|
||||
const uploadProcessedImage = async (
|
||||
imageData,
|
||||
imageName,
|
||||
width,
|
||||
height,
|
||||
quality
|
||||
) => {
|
||||
const buffer = await sharp(imageData)
|
||||
.resize(width, height, { fit: "cover" })
|
||||
.jpeg({ quality })
|
||||
.toBuffer();
|
||||
|
||||
await s3Storage.uploadBuffer(
|
||||
`${CATEGORY_IMAGE_PREFIX}/${imageName}`,
|
||||
buffer,
|
||||
"image/jpeg"
|
||||
);
|
||||
|
||||
return imageName;
|
||||
};
|
||||
|
||||
const uploadShafafiatIcon = async (fileData, fileName, contentType) => {
|
||||
await s3Storage.uploadBuffer(
|
||||
`${CATEGORY_SHAFAFIAT_PREFIX}/${fileName}`,
|
||||
fileData,
|
||||
contentType
|
||||
);
|
||||
|
||||
return fileName;
|
||||
};
|
||||
|
||||
const uploadTermsFile = async (fileData, fileName) => {
|
||||
await s3Storage.uploadBuffer(
|
||||
`${TERMS_FILE_PREFIX}/${fileName}`,
|
||||
fileData,
|
||||
"application/pdf"
|
||||
);
|
||||
|
||||
return fileName;
|
||||
};
|
||||
|
||||
const deleteTermsFile = async (fileName) => {
|
||||
if (!fileName) return;
|
||||
|
||||
try {
|
||||
await s3Storage.deleteObject(`${TERMS_FILE_PREFIX}/${fileName}`);
|
||||
} catch (error) {
|
||||
console.log("Failed to delete terms file from S3:", error?.message);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
CATEGORY_IMAGE_PREFIX,
|
||||
CATEGORY_SHAFAFIAT_PREFIX,
|
||||
TERMS_FILE_PREFIX,
|
||||
getStoredImageName,
|
||||
deleteCategoryImage,
|
||||
deleteShafafiatIcon,
|
||||
uploadProcessedImage,
|
||||
uploadShafafiatIcon,
|
||||
uploadTermsFile,
|
||||
deleteTermsFile,
|
||||
};
|
||||
@@ -0,0 +1,52 @@
|
||||
const sharp = require("sharp");
|
||||
const s3Storage = require("./s3Storage");
|
||||
|
||||
const CONTENT_IMAGE_PREFIX = "uploads/images/content";
|
||||
|
||||
const getStoredImageName = (doc, field) =>
|
||||
doc.get(field, null, { getters: false });
|
||||
|
||||
const deleteContentImage = async (doc, field) => {
|
||||
const fileName = getStoredImageName(doc, field);
|
||||
if (!fileName) return;
|
||||
|
||||
try {
|
||||
await s3Storage.deleteObject(`${CONTENT_IMAGE_PREFIX}/${fileName}`);
|
||||
} catch (error) {
|
||||
console.log(`Failed to delete ${field} from S3:`, error?.message);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteContentImages = async (doc) => {
|
||||
await deleteContentImage(doc, "cover");
|
||||
await deleteContentImage(doc, "thumb");
|
||||
};
|
||||
|
||||
const uploadProcessedImage = async (
|
||||
imageData,
|
||||
imageName,
|
||||
width,
|
||||
height,
|
||||
quality
|
||||
) => {
|
||||
const buffer = await sharp(imageData)
|
||||
.resize(width, height, { fit: "cover" })
|
||||
.jpeg({ quality })
|
||||
.toBuffer();
|
||||
|
||||
await s3Storage.uploadBuffer(
|
||||
`${CONTENT_IMAGE_PREFIX}/${imageName}`,
|
||||
buffer,
|
||||
"image/jpeg"
|
||||
);
|
||||
|
||||
return imageName;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
CONTENT_IMAGE_PREFIX,
|
||||
getStoredImageName,
|
||||
deleteContentImage,
|
||||
deleteContentImages,
|
||||
uploadProcessedImage,
|
||||
};
|
||||
@@ -0,0 +1,58 @@
|
||||
const sharp = require("sharp");
|
||||
const s3Storage = require("./s3Storage");
|
||||
|
||||
const ELECTION_IMAGE_PREFIX = "uploads/images/election";
|
||||
|
||||
const getStoredImageName = (doc, field) =>
|
||||
doc.get(field, null, { getters: false });
|
||||
|
||||
const deleteElectionImage = async (fileName) => {
|
||||
if (!fileName) return;
|
||||
|
||||
try {
|
||||
await s3Storage.deleteObject(`${ELECTION_IMAGE_PREFIX}/${fileName}`);
|
||||
} catch (error) {
|
||||
console.log(`Failed to delete election image from S3:`, error?.message);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteCandidateImage = async (candidate) => {
|
||||
const fileName = getStoredImageName(candidate, "profilePic");
|
||||
await deleteElectionImage(fileName);
|
||||
};
|
||||
|
||||
const deleteElectionCandidateImages = async (election) => {
|
||||
for (const candidate of election.candidates) {
|
||||
await deleteCandidateImage(candidate);
|
||||
}
|
||||
};
|
||||
|
||||
const uploadProcessedImage = async (
|
||||
imageData,
|
||||
imageName,
|
||||
width,
|
||||
height,
|
||||
quality
|
||||
) => {
|
||||
const buffer = await sharp(imageData)
|
||||
.resize(width, height, { fit: "cover" })
|
||||
.jpeg({ quality })
|
||||
.toBuffer();
|
||||
|
||||
await s3Storage.uploadBuffer(
|
||||
`${ELECTION_IMAGE_PREFIX}/${imageName}`,
|
||||
buffer,
|
||||
"image/jpeg"
|
||||
);
|
||||
|
||||
return imageName;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
ELECTION_IMAGE_PREFIX,
|
||||
getStoredImageName,
|
||||
deleteElectionImage,
|
||||
deleteCandidateImage,
|
||||
deleteElectionCandidateImages,
|
||||
uploadProcessedImage,
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
const sharp = require("sharp");
|
||||
const s3Storage = require("./s3Storage");
|
||||
|
||||
const LINKS_IMAGE_PREFIX = "uploads/images/links";
|
||||
|
||||
const getStoredImageName = (doc, field) =>
|
||||
doc.get(field, null, { getters: false });
|
||||
|
||||
const deleteLinksImage = async (doc, field) => {
|
||||
const fileName = getStoredImageName(doc, field);
|
||||
if (!fileName) return;
|
||||
|
||||
try {
|
||||
await s3Storage.deleteObject(`${LINKS_IMAGE_PREFIX}/${fileName}`);
|
||||
} catch (error) {
|
||||
console.log(`Failed to delete ${field} from S3:`, error?.message);
|
||||
}
|
||||
};
|
||||
|
||||
const uploadProcessedImage = async (
|
||||
imageData,
|
||||
imageName,
|
||||
width,
|
||||
height,
|
||||
quality
|
||||
) => {
|
||||
const buffer = await sharp(imageData)
|
||||
.resize(width, height, { fit: "cover" })
|
||||
.jpeg({ quality })
|
||||
.toBuffer();
|
||||
|
||||
await s3Storage.uploadBuffer(
|
||||
`${LINKS_IMAGE_PREFIX}/${imageName}`,
|
||||
buffer,
|
||||
"image/jpeg"
|
||||
);
|
||||
|
||||
return imageName;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
LINKS_IMAGE_PREFIX,
|
||||
getStoredImageName,
|
||||
deleteLinksImage,
|
||||
uploadProcessedImage,
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
const sharp = require("sharp");
|
||||
const s3Storage = require("./s3Storage");
|
||||
|
||||
const OCCASION_IMAGE_PREFIX = "uploads/images/occasion";
|
||||
|
||||
const getStoredImageName = (doc, field) =>
|
||||
doc.get(field, null, { getters: false });
|
||||
|
||||
const deleteOccasionImage = async (doc, field) => {
|
||||
const fileName = getStoredImageName(doc, field);
|
||||
if (!fileName) return;
|
||||
|
||||
try {
|
||||
await s3Storage.deleteObject(`${OCCASION_IMAGE_PREFIX}/${fileName}`);
|
||||
} catch (error) {
|
||||
console.log(`Failed to delete ${field} from S3:`, error?.message);
|
||||
}
|
||||
};
|
||||
|
||||
const uploadProcessedImage = async (
|
||||
imageData,
|
||||
imageName,
|
||||
width,
|
||||
height,
|
||||
quality
|
||||
) => {
|
||||
const buffer = await sharp(imageData)
|
||||
.resize(width, height, { fit: "cover" })
|
||||
.jpeg({ quality })
|
||||
.toBuffer();
|
||||
|
||||
await s3Storage.uploadBuffer(
|
||||
`${OCCASION_IMAGE_PREFIX}/${imageName}`,
|
||||
buffer,
|
||||
"image/jpeg"
|
||||
);
|
||||
|
||||
return imageName;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
OCCASION_IMAGE_PREFIX,
|
||||
getStoredImageName,
|
||||
deleteOccasionImage,
|
||||
uploadProcessedImage,
|
||||
};
|
||||
@@ -2,6 +2,8 @@ const {
|
||||
S3Client,
|
||||
PutObjectCommand,
|
||||
DeleteObjectCommand,
|
||||
ListObjectsV2Command,
|
||||
GetObjectCommand,
|
||||
} = require("@aws-sdk/client-s3");
|
||||
|
||||
const config = {
|
||||
@@ -85,9 +87,54 @@ const deleteObject = async (key) => {
|
||||
);
|
||||
};
|
||||
|
||||
const listObjects = async (prefix = "") => {
|
||||
const keys = [];
|
||||
let continuationToken;
|
||||
|
||||
do {
|
||||
const response = await getClient().send(
|
||||
new ListObjectsV2Command({
|
||||
Bucket: config.bucket,
|
||||
Prefix: normalizeKey(prefix),
|
||||
ContinuationToken: continuationToken,
|
||||
})
|
||||
);
|
||||
|
||||
for (const item of response.Contents || []) {
|
||||
if (item.Key) keys.push(item.Key);
|
||||
}
|
||||
|
||||
continuationToken = response.IsTruncated
|
||||
? response.NextContinuationToken
|
||||
: undefined;
|
||||
} while (continuationToken);
|
||||
|
||||
return keys;
|
||||
};
|
||||
|
||||
const getObjectBuffer = async (key) => {
|
||||
const response = await getClient().send(
|
||||
new GetObjectCommand({
|
||||
Bucket: config.bucket,
|
||||
Key: normalizeKey(key),
|
||||
})
|
||||
);
|
||||
|
||||
return Buffer.from(await response.Body.transformToByteArray());
|
||||
};
|
||||
|
||||
const deleteObjectsByPrefix = async (prefix) => {
|
||||
const keys = await listObjects(prefix);
|
||||
|
||||
await Promise.all(keys.map((key) => deleteObject(key)));
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
isConfigured,
|
||||
getPublicUrl,
|
||||
uploadBuffer,
|
||||
deleteObject,
|
||||
listObjects,
|
||||
getObjectBuffer,
|
||||
deleteObjectsByPrefix,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
const sharp = require("sharp");
|
||||
const s3Storage = require("./s3Storage");
|
||||
|
||||
const SLIDER_IMAGE_PREFIX = "uploads/images/slider";
|
||||
|
||||
const getStoredImageName = (doc, field) =>
|
||||
doc.get(field, null, { getters: false });
|
||||
|
||||
const deleteSliderImage = async (doc, field) => {
|
||||
const fileName = getStoredImageName(doc, field);
|
||||
if (!fileName) return;
|
||||
|
||||
try {
|
||||
await s3Storage.deleteObject(`${SLIDER_IMAGE_PREFIX}/${fileName}`);
|
||||
} catch (error) {
|
||||
console.log(`Failed to delete ${field} from S3:`, error?.message);
|
||||
}
|
||||
};
|
||||
|
||||
const uploadProcessedImage = async (
|
||||
imageData,
|
||||
imageName,
|
||||
width,
|
||||
height,
|
||||
quality
|
||||
) => {
|
||||
const buffer = await sharp(imageData)
|
||||
.resize(width, height, { fit: "cover" })
|
||||
.jpeg({ quality })
|
||||
.toBuffer();
|
||||
|
||||
await s3Storage.uploadBuffer(
|
||||
`${SLIDER_IMAGE_PREFIX}/${imageName}`,
|
||||
buffer,
|
||||
"image/jpeg"
|
||||
);
|
||||
|
||||
return imageName;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
SLIDER_IMAGE_PREFIX,
|
||||
getStoredImageName,
|
||||
deleteSliderImage,
|
||||
uploadProcessedImage,
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
const sharp = require("sharp");
|
||||
const s3Storage = require("./s3Storage");
|
||||
|
||||
const USER_IMAGE_PREFIX = "uploads/images/users";
|
||||
|
||||
const getStoredImageName = (doc, field) =>
|
||||
doc.get(field, null, { getters: false });
|
||||
|
||||
const deleteUserImage = async (doc, field) => {
|
||||
const fileName = getStoredImageName(doc, field);
|
||||
if (!fileName) return;
|
||||
|
||||
try {
|
||||
await s3Storage.deleteObject(`${USER_IMAGE_PREFIX}/${fileName}`);
|
||||
} catch (error) {
|
||||
console.log(`Failed to delete ${field} from S3:`, error?.message);
|
||||
}
|
||||
};
|
||||
|
||||
const uploadProcessedImage = async (
|
||||
imageData,
|
||||
imageName,
|
||||
width,
|
||||
height,
|
||||
quality
|
||||
) => {
|
||||
const buffer = await sharp(imageData)
|
||||
.resize(width, height, { fit: "cover" })
|
||||
.jpeg({ quality })
|
||||
.toBuffer();
|
||||
|
||||
await s3Storage.uploadBuffer(
|
||||
`${USER_IMAGE_PREFIX}/${imageName}`,
|
||||
buffer,
|
||||
"image/jpeg"
|
||||
);
|
||||
|
||||
return imageName;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
USER_IMAGE_PREFIX,
|
||||
getStoredImageName,
|
||||
deleteUserImage,
|
||||
uploadProcessedImage,
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
const sharp = require("sharp");
|
||||
const s3Storage = require("./s3Storage");
|
||||
|
||||
const YEAR_BANNER_IMAGE_PREFIX = "uploads/images/mainCover";
|
||||
|
||||
const getStoredImageName = (doc, field) =>
|
||||
doc.get(field, null, { getters: false });
|
||||
|
||||
const deleteYearBannerImage = async (doc, field) => {
|
||||
const fileName = getStoredImageName(doc, field);
|
||||
if (!fileName) return;
|
||||
|
||||
try {
|
||||
await s3Storage.deleteObject(`${YEAR_BANNER_IMAGE_PREFIX}/${fileName}`);
|
||||
} catch (error) {
|
||||
console.log(`Failed to delete ${field} from S3:`, error?.message);
|
||||
}
|
||||
};
|
||||
|
||||
const uploadProcessedImage = async (
|
||||
imageData,
|
||||
imageName,
|
||||
width,
|
||||
height,
|
||||
quality
|
||||
) => {
|
||||
const buffer = await sharp(imageData)
|
||||
.resize(width, height, { fit: "cover" })
|
||||
.jpeg({ quality })
|
||||
.toBuffer();
|
||||
|
||||
await s3Storage.uploadBuffer(
|
||||
`${YEAR_BANNER_IMAGE_PREFIX}/${imageName}`,
|
||||
buffer,
|
||||
"image/jpeg"
|
||||
);
|
||||
|
||||
return imageName;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
YEAR_BANNER_IMAGE_PREFIX,
|
||||
getStoredImageName,
|
||||
deleteYearBannerImage,
|
||||
uploadProcessedImage,
|
||||
};
|
||||
Reference in New Issue
Block a user