S3 for other controolers
This commit is contained in:
@@ -36,7 +36,7 @@
|
|||||||
v-for="(item, i) in items"
|
v-for="(item, i) in items"
|
||||||
:key="i"
|
:key="i"
|
||||||
class="item">
|
class="item">
|
||||||
<img :src="`/uploads/images/category/shafafiat/${item.icon}`" alt="شفافیت" />
|
<img :src="item.icon" alt="شفافیت" />
|
||||||
<div class="parent">
|
<div class="parent">
|
||||||
<div class="right"></div>
|
<div class="right"></div>
|
||||||
<div class="left"></div>
|
<div class="left"></div>
|
||||||
|
|||||||
@@ -8,13 +8,19 @@ const {
|
|||||||
checkValidations,
|
checkValidations,
|
||||||
} = require("../plugins/controllersHelperFunctions");
|
} = require("../plugins/controllersHelperFunctions");
|
||||||
const News = require("../models/News");
|
const News = require("../models/News");
|
||||||
const sharp = require("sharp");
|
|
||||||
const fs = require("fs");
|
|
||||||
const { extname } = require("path");
|
const { extname } = require("path");
|
||||||
|
const {
|
||||||
|
deleteCategoryImage,
|
||||||
|
deleteShafafiatIcon,
|
||||||
|
uploadProcessedImage,
|
||||||
|
uploadShafafiatIcon,
|
||||||
|
uploadTermsFile,
|
||||||
|
deleteTermsFile,
|
||||||
|
getStoredImageName,
|
||||||
|
} = require("../plugins/categoryImageStorage");
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
const titleFilterRegex = new RegExp("/", "g");
|
const titleFilterRegex = new RegExp("/", "g");
|
||||||
const noCover = "/img/no-cover.jpg";
|
|
||||||
const coverNewsWidth = 400;
|
const coverNewsWidth = 400;
|
||||||
const coverNewsHeight = 400;
|
const coverNewsHeight = 400;
|
||||||
const coverQuality = 100;
|
const coverQuality = 100;
|
||||||
@@ -411,34 +417,13 @@ module.exports.addCategory = [
|
|||||||
image.mimetype.split("/")[1]
|
image.mimetype.split("/")[1]
|
||||||
}`;
|
}`;
|
||||||
try {
|
try {
|
||||||
const target = sharp(image.data);
|
await uploadProcessedImage(
|
||||||
await target
|
image.data,
|
||||||
.resize(coverNewsWidth, coverNewsHeight, { fit: "cover" })
|
imageName,
|
||||||
.jpeg({ quality: coverQuality })
|
coverNewsWidth,
|
||||||
.toFile(`./static/uploads/images/category/${imageName}`);
|
coverNewsHeight,
|
||||||
|
coverQuality
|
||||||
/**
|
);
|
||||||
* if exist old pic delete it from file
|
|
||||||
*/
|
|
||||||
// if (targetNews.cover !== noCover && !targetNews.imported) {
|
|
||||||
// let oldPic = `./static${targetNews.cover}`;
|
|
||||||
//
|
|
||||||
// if (await fs.existsSync(oldPic)) {
|
|
||||||
// fs.unlink(oldPic, (err) => {
|
|
||||||
// if (err) return res500(res, err?.message);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (targetNews.thumbCover !== noCover && !targetNews.imported) {
|
|
||||||
// let oldPic = `./static${targetNews.thumbCover}`;
|
|
||||||
//
|
|
||||||
// if (await fs.existsSync(oldPic)) {
|
|
||||||
// fs.unlink(oldPic, (err) => {
|
|
||||||
// if (err) return res500(res, err?.message);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
create.managerCover = imageName;
|
create.managerCover = imageName;
|
||||||
await create.save();
|
await create.save();
|
||||||
@@ -461,33 +446,12 @@ module.exports.addCategory = [
|
|||||||
const ext = extname(image.name);
|
const ext = extname(image.name);
|
||||||
const imageName = `shafafiat_icon_${Date.now()}${ext}`;
|
const imageName = `shafafiat_icon_${Date.now()}${ext}`;
|
||||||
try {
|
try {
|
||||||
await image.mv(
|
await uploadShafafiatIcon(
|
||||||
`${process.cwd()}/static/uploads/images/category/shafafiat/${imageName}`
|
image.data,
|
||||||
|
imageName,
|
||||||
|
image.mimetype
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
|
||||||
* if exist old pic delete it from file
|
|
||||||
*/
|
|
||||||
// if (targetNews.cover !== noCover && !targetNews.imported) {
|
|
||||||
// let oldPic = `./static${targetNews.cover}`;
|
|
||||||
//
|
|
||||||
// if (await fs.existsSync(oldPic)) {
|
|
||||||
// fs.unlink(oldPic, (err) => {
|
|
||||||
// if (err) return res500(res, err?.message);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (targetNews.thumbCover !== noCover && !targetNews.imported) {
|
|
||||||
// let oldPic = `./static${targetNews.thumbCover}`;
|
|
||||||
//
|
|
||||||
// if (await fs.existsSync(oldPic)) {
|
|
||||||
// fs.unlink(oldPic, (err) => {
|
|
||||||
// if (err) return res500(res, err?.message);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
create.icon = imageName;
|
create.icon = imageName;
|
||||||
await create.save();
|
await create.save();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -812,24 +776,15 @@ module.exports.updateCategory = [
|
|||||||
image.mimetype.split("/")[1]
|
image.mimetype.split("/")[1]
|
||||||
}`;
|
}`;
|
||||||
try {
|
try {
|
||||||
const target = sharp(image.data);
|
await deleteCategoryImage(targetCategory, "managerCover");
|
||||||
await target
|
|
||||||
.resize(coverNewsWidth, coverNewsHeight, { fit: "cover" })
|
|
||||||
.jpeg({ quality: coverQuality })
|
|
||||||
.toFile(`./static/uploads/images/category/${imageName}`);
|
|
||||||
|
|
||||||
/**
|
await uploadProcessedImage(
|
||||||
* if exist old pic delete it from file
|
image.data,
|
||||||
*/
|
imageName,
|
||||||
if (targetCategory.managerCover !== noCover) {
|
coverNewsWidth,
|
||||||
let oldPic = `./static${targetCategory.managerCover}`;
|
coverNewsHeight,
|
||||||
|
coverQuality
|
||||||
if (await fs.existsSync(oldPic)) {
|
);
|
||||||
fs.unlink(oldPic, (err) => {
|
|
||||||
if (err) return res500(res, err?.message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
targetCategory.managerCover = imageName;
|
targetCategory.managerCover = imageName;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -839,7 +794,6 @@ module.exports.updateCategory = [
|
|||||||
|
|
||||||
if (req.files?.icon) {
|
if (req.files?.icon) {
|
||||||
const image = req.files.icon;
|
const image = req.files.icon;
|
||||||
console.log(image);
|
|
||||||
if (!_sr.supportedImageFormats.includes(image.mimetype.split("/")[1])) {
|
if (!_sr.supportedImageFormats.includes(image.mimetype.split("/")[1])) {
|
||||||
return res.status(422).json({
|
return res.status(422).json({
|
||||||
validation: {
|
validation: {
|
||||||
@@ -852,30 +806,17 @@ module.exports.updateCategory = [
|
|||||||
const ext = extname(image.name);
|
const ext = extname(image.name);
|
||||||
const imageName = `shafafiat_icon_${Date.now()}${ext}`;
|
const imageName = `shafafiat_icon_${Date.now()}${ext}`;
|
||||||
try {
|
try {
|
||||||
await image.mv(
|
await deleteShafafiatIcon(
|
||||||
`${process.cwd()}/static/uploads/images/category/shafafiat/${imageName}`
|
getStoredImageName(targetCategory, "icon")
|
||||||
);
|
);
|
||||||
// const target = sharp(image.data)
|
|
||||||
// await target
|
|
||||||
// .resize(coverNewsWidth, coverNewsHeight, {fit: 'cover'})
|
|
||||||
// .jpeg({quality: coverQuality})
|
|
||||||
// .toFile(`./static/uploads/images/category/shafafiat/${imageName}`);
|
|
||||||
|
|
||||||
/**
|
await uploadShafafiatIcon(
|
||||||
* if exist old pic delete it from file
|
image.data,
|
||||||
*/
|
imageName,
|
||||||
if (targetCategory.icon !== noCover) {
|
image.mimetype
|
||||||
let oldPic = `./static${targetCategory.icon}`;
|
);
|
||||||
|
|
||||||
if (await fs.existsSync(oldPic)) {
|
|
||||||
fs.unlink(oldPic, (err) => {
|
|
||||||
if (err) return res500(res, err?.message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
targetCategory.icon = imageName;
|
targetCategory.icon = imageName;
|
||||||
console.log(targetCategory);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return res500(res, e?.message);
|
return res500(res, e?.message);
|
||||||
}
|
}
|
||||||
@@ -1223,52 +1164,59 @@ module.exports.getParent = [
|
|||||||
module.exports.addTermsFileToCategory = [
|
module.exports.addTermsFileToCategory = [
|
||||||
[body("termsTitle").notEmpty().withMessage(_sr["fa"].required.title)],
|
[body("termsTitle").notEmpty().withMessage(_sr["fa"].required.title)],
|
||||||
checkValidations(validationResult),
|
checkValidations(validationResult),
|
||||||
(req, res) => {
|
async (req, res) => {
|
||||||
if (!req.files?.file)
|
try {
|
||||||
return res
|
if (!req.files?.file)
|
||||||
.status(422)
|
return res
|
||||||
.json({ validation: { file: { msg: _sr["fa"].required.file } } });
|
.status(422)
|
||||||
if (req.files?.file.mimetype.split("/")[1] !== "pdf")
|
.json({ validation: { file: { msg: _sr["fa"].required.file } } });
|
||||||
return res
|
if (req.files?.file.mimetype.split("/")[1] !== "pdf")
|
||||||
.status(422)
|
return res
|
||||||
.json({ validation: { file: { msg: "فقط فرمت PDF قابل قبول است" } } });
|
.status(422)
|
||||||
|
.json({ validation: { file: { msg: "فقط فرمت PDF قابل قبول است" } } });
|
||||||
|
|
||||||
const data = { title: req.body.termsTitle };
|
const category = await Category.findById(req.params.categoryId);
|
||||||
const file = req.files.file;
|
if (!category) return res404(res, "category not found");
|
||||||
const fileName =
|
|
||||||
req.body.termsTitle.replace(titleFilterRegex, "-") +
|
|
||||||
"_" +
|
|
||||||
Date.now() +
|
|
||||||
".pdf";
|
|
||||||
file.mv(`./static/uploads/files/terms/${fileName}`);
|
|
||||||
data.file = fileName;
|
|
||||||
|
|
||||||
Category.findById(req.params.categoryId, (err, category) => {
|
const fileName =
|
||||||
if (err || !category) return res404(res, err);
|
req.body.termsTitle.replace(titleFilterRegex, "-") +
|
||||||
category.terms.push(data);
|
"_" +
|
||||||
category.save((err) => {
|
Date.now() +
|
||||||
if (err) return res500(res, err);
|
".pdf";
|
||||||
else return res.json({ message: _sr["fa"].response.success_save });
|
|
||||||
|
await uploadTermsFile(req.files.file.data, fileName);
|
||||||
|
|
||||||
|
category.terms.push({
|
||||||
|
title: req.body.termsTitle,
|
||||||
|
file: fileName,
|
||||||
});
|
});
|
||||||
});
|
await category.save();
|
||||||
|
|
||||||
|
return res.json({ message: _sr["fa"].response.success_save });
|
||||||
|
} catch (err) {
|
||||||
|
return res500(res, err);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
module.exports.removeTermsFileFromCategory = [
|
module.exports.removeTermsFileFromCategory = [
|
||||||
(req, res) => {
|
async (req, res) => {
|
||||||
Category.findOne({ "terms._id": req.params.fileId }, (err, category) => {
|
try {
|
||||||
if (err || !category) return res404(res, err);
|
const category = await Category.findOne({ "terms._id": req.params.fileId });
|
||||||
const file = category.terms.id(req.params.fileId);
|
if (!category) return res404(res, "not found");
|
||||||
if (!file) return res404(res, "not found");
|
|
||||||
file.remove();
|
const termsFile = category.terms.id(req.params.fileId);
|
||||||
fs.unlink(`./static/${file.file}`, (err) => {
|
if (!termsFile) return res404(res, "not found");
|
||||||
if (err) console.log(err);
|
|
||||||
});
|
const fileName = getStoredImageName(termsFile, "file");
|
||||||
category.save((err) => {
|
termsFile.remove();
|
||||||
if (err) return res500(res, err);
|
await deleteTermsFile(fileName);
|
||||||
else return res.json({ message: _sr["fa"].response.success_remove });
|
await category.save();
|
||||||
});
|
|
||||||
});
|
return res.json({ message: _sr["fa"].response.success_remove });
|
||||||
|
} catch (err) {
|
||||||
|
return res500(res, err);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
const {body, validationResult} = require('express-validator');
|
const {body, validationResult} = require('express-validator');
|
||||||
const sharp = require('sharp');
|
|
||||||
const {_sr} = require('../plugins/serverResponses');
|
const {_sr} = require('../plugins/serverResponses');
|
||||||
const {res404, res500, hasWhiteSpaces, isLatinCharactersWithSymbol, generateRandomDigits} = require('../plugins/controllersHelperFunctions');
|
const {res404, res500, hasWhiteSpaces, isLatinCharactersWithSymbol, generateRandomDigits} = require('../plugins/controllersHelperFunctions');
|
||||||
const Content = require('../models/Content');
|
const Content = require('../models/Content');
|
||||||
const fs = require('fs');
|
const {
|
||||||
|
deleteContentImages,
|
||||||
|
uploadProcessedImage,
|
||||||
|
} = require('../plugins/contentImageStorage');
|
||||||
|
|
||||||
|
|
||||||
////// variables
|
////// variables
|
||||||
@@ -85,26 +87,23 @@ module.exports.addContent = [
|
|||||||
const imageName = `manager_${Date.now()}_${create._id}.${image.mimetype.split('/')[1]}`;
|
const imageName = `manager_${Date.now()}_${create._id}.${image.mimetype.split('/')[1]}`;
|
||||||
const thumbName = 'thumb_' + imageName
|
const thumbName = 'thumb_' + imageName
|
||||||
try {
|
try {
|
||||||
const target = sharp(image.data)
|
await uploadProcessedImage(
|
||||||
await target
|
image.data,
|
||||||
.resize(profileWidth, profileHeight, {
|
imageName,
|
||||||
fit: 'cover'
|
profileWidth,
|
||||||
})
|
profileHeight,
|
||||||
.jpeg({
|
profileQuality
|
||||||
quality: profileQuality
|
);
|
||||||
})
|
await uploadProcessedImage(
|
||||||
.toFile(`./static/uploads/images/content/${imageName}`)
|
image.data,
|
||||||
await target
|
thumbName,
|
||||||
.resize(profileThumbWidth, profileThumbHeight, {
|
profileThumbWidth,
|
||||||
fit: 'cover'
|
profileThumbHeight,
|
||||||
})
|
profileThumbQuality
|
||||||
.jpeg({
|
);
|
||||||
quality: profileThumbQuality
|
|
||||||
})
|
|
||||||
.toFile(`./static/uploads/images/content/${thumbName}`)
|
|
||||||
|
|
||||||
create.cover = imageName;
|
create.cover = imageName;
|
||||||
create.thumb = imageName;
|
create.thumb = thumbName;
|
||||||
|
|
||||||
await create.save();
|
await create.save();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -180,42 +179,22 @@ module.exports.updateContent = [
|
|||||||
const imageName = `manager_${Date.now()}_${targetContent._id}.${image.mimetype.split('/')[1]}`;
|
const imageName = `manager_${Date.now()}_${targetContent._id}.${image.mimetype.split('/')[1]}`;
|
||||||
const thumbName = 'thumb_' + imageName
|
const thumbName = 'thumb_' + imageName
|
||||||
try {
|
try {
|
||||||
const target = sharp(image.data)
|
await deleteContentImages(targetContent);
|
||||||
await target
|
|
||||||
.resize(profileWidth, profileHeight, {
|
|
||||||
fit: 'cover'
|
|
||||||
})
|
|
||||||
.jpeg({
|
|
||||||
quality: profileQuality
|
|
||||||
})
|
|
||||||
.toFile(`./static/uploads/images/content/${imageName}`)
|
|
||||||
await target
|
|
||||||
.resize(profileThumbWidth, profileThumbHeight, {
|
|
||||||
fit: 'cover'
|
|
||||||
})
|
|
||||||
.jpeg({
|
|
||||||
quality: profileThumbQuality
|
|
||||||
})
|
|
||||||
.toFile(`./static/uploads/images/content/${thumbName}`)
|
|
||||||
|
|
||||||
/**
|
await uploadProcessedImage(
|
||||||
* if exist old pic delete it from file
|
image.data,
|
||||||
*/
|
imageName,
|
||||||
if (targetContent.cover) {
|
profileWidth,
|
||||||
const oldPic = `./static${targetContent.cover}`
|
profileHeight,
|
||||||
const oldThumb = `./static${targetContent.thumb}`
|
profileQuality
|
||||||
|
);
|
||||||
if (fs.existsSync(oldPic)) {
|
await uploadProcessedImage(
|
||||||
fs.unlink(oldPic, (err) => {
|
image.data,
|
||||||
if (err) return res500(res, err?.message);
|
thumbName,
|
||||||
});
|
profileThumbWidth,
|
||||||
}
|
profileThumbHeight,
|
||||||
if (fs.existsSync(oldThumb)) {
|
profileThumbQuality
|
||||||
fs.unlink(oldThumb, (err) => {
|
);
|
||||||
if (err) return res500(res, err?.message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
targetContent.cover = imageName;
|
targetContent.cover = imageName;
|
||||||
targetContent.thumb = thumbName;
|
targetContent.thumb = thumbName;
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
|
const {PassThrough} = require('stream')
|
||||||
const archiver = require('archiver')
|
const archiver = require('archiver')
|
||||||
const moment = require('moment')
|
const moment = require('moment')
|
||||||
const jwt = require('jsonwebtoken')
|
const jwt = require('jsonwebtoken')
|
||||||
const {secretKey} = require('../authentication')
|
const {secretKey} = require('../authentication')
|
||||||
const {_sr} = require('../plugins/serverResponses')
|
const {_sr} = require('../plugins/serverResponses')
|
||||||
|
const {
|
||||||
|
appendS3UploadsToArchive,
|
||||||
|
uploadBackupArchive,
|
||||||
|
deleteOldBackups,
|
||||||
|
} = require('../plugins/backupStorage')
|
||||||
// models
|
// models
|
||||||
const Category = require('../models/Category')
|
const Category = require('../models/Category')
|
||||||
const Comment = require('../models/Comment')
|
const Comment = require('../models/Comment')
|
||||||
@@ -21,6 +27,8 @@ const Slider = require('../models/Slider')
|
|||||||
const User = require('../models/User')
|
const User = require('../models/User')
|
||||||
const YearBanner = require('../models/YearBanner')
|
const YearBanner = require('../models/YearBanner')
|
||||||
|
|
||||||
|
const hostFullError = '<h1 style="margin-top: 150px;text-align: center;direction: rtl;color: red;">فضای هاست پر میباشد.لطفا نسبت به پاک کردن بکاپ های قبلی یا افزایش فضای هاست اقدام فرمایید.</h1>'
|
||||||
|
|
||||||
module.exports.createBackUp = [
|
module.exports.createBackUp = [
|
||||||
// check user token and permission to backup
|
// check user token and permission to backup
|
||||||
async (req, res, next) => {
|
async (req, res, next) => {
|
||||||
@@ -85,86 +93,72 @@ module.exports.createBackUp = [
|
|||||||
|
|
||||||
const [categories, comments, contactus, contents, galleries, homepage, links, meetings, news, newsFiles, services, sliders, users, yearBanner, occasion] = await Promise.all(dataBaseQueries)
|
const [categories, comments, contactus, contents, galleries, homepage, links, meetings, news, newsFiles, services, sliders, users, yearBanner, occasion] = await Promise.all(dataBaseQueries)
|
||||||
|
|
||||||
if (await !fs.existsSync('./backup/database')) await fs.mkdirSync('./backup/database')
|
const dateStr = moment(Date.now()).format('YYYY-MM-DD')
|
||||||
|
const backupName = `backup_${dateStr}.zip`
|
||||||
await Promise.all([
|
|
||||||
fs.writeFileSync(`./backup/database/categories_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(categories)),
|
|
||||||
fs.writeFileSync(`./backup/database/comments_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(comments)),
|
|
||||||
fs.writeFileSync(`./backup/database/contactus_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(contactus)),
|
|
||||||
fs.writeFileSync(`./backup/database/contents_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(contents)),
|
|
||||||
fs.writeFileSync(`./backup/database/galleries_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(galleries)),
|
|
||||||
fs.writeFileSync(`./backup/database/homepage_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(homepage)),
|
|
||||||
fs.writeFileSync(`./backup/database/links_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(links)),
|
|
||||||
fs.writeFileSync(`./backup/database/meetings_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(meetings)),
|
|
||||||
fs.writeFileSync(`./backup/database/news_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(news)),
|
|
||||||
fs.writeFileSync(`./backup/database/newsFiles_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(newsFiles)),
|
|
||||||
fs.writeFileSync(`./backup/database/services_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(services)),
|
|
||||||
fs.writeFileSync(`./backup/database/sliders_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(sliders)),
|
|
||||||
fs.writeFileSync(`./backup/database/users_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(users)),
|
|
||||||
fs.writeFileSync(`./backup/database/yearBanner_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(yearBanner)),
|
|
||||||
fs.writeFileSync(`./backup/database/occasion_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(occasion))
|
|
||||||
])
|
|
||||||
|
|
||||||
/////////////////// create backup zip file
|
|
||||||
|
|
||||||
const backupName = 'backup_' + moment(Date.now()).format('YYYY-MM-DD') + '.zip'
|
|
||||||
// create a file to stream archive data to.
|
|
||||||
const output = fs.createWriteStream(`./backup/${backupName}`)
|
|
||||||
const archive = archiver('zip', {
|
const archive = archiver('zip', {
|
||||||
zlib: {level: 9} // Sets the compression level.
|
zlib: {level: 9}
|
||||||
})
|
})
|
||||||
|
const output = new PassThrough()
|
||||||
|
const chunks = []
|
||||||
|
|
||||||
|
output.on('data', (chunk) => chunks.push(chunk))
|
||||||
|
|
||||||
// listen for all archive data to be written
|
|
||||||
// 'close' event is fired only when a file descriptor is involved
|
|
||||||
output.on('close', function () {
|
|
||||||
console.log(archive.pointer() + ' total bytes')
|
|
||||||
console.log('archiver has been finalized and the output file descriptor has closed.')
|
|
||||||
return res.download(`./backup/${backupName}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
// This event is fired when the data source is drained no matter what was the data source.
|
|
||||||
// It is not part of this library but rather from the NodeJS Stream API.
|
|
||||||
// @see: https://nodejs.org/api/stream.html#stream_event_end
|
|
||||||
output.on('end', function () {
|
|
||||||
console.log('Data has been drained')
|
|
||||||
return res.status(500).send('<h1 style="margin-top: 150px;text-align: center;direction: rtl;color: red;">فضای هاست پر میباشد.لطفا نسبت به پاک کردن بکاپ های قبلی یا افزایش فضای هاست اقدام فرمایید.</h1>')
|
|
||||||
})
|
|
||||||
|
|
||||||
// good practice to catch warnings (ie stat failures and other non-blocking errors)
|
|
||||||
archive.on('warning', function (err) {
|
archive.on('warning', function (err) {
|
||||||
|
|
||||||
if (err.code === 'ENOENT') {
|
if (err.code === 'ENOENT') {
|
||||||
// log warning
|
|
||||||
console.log('On archiver warning -- ENOENT error code', err)
|
console.log('On archiver warning -- ENOENT error code', err)
|
||||||
} else {
|
} else {
|
||||||
// throw error
|
|
||||||
console.log('On archiver warning -- other error codes ', err)
|
console.log('On archiver warning -- other error codes ', err)
|
||||||
}
|
}
|
||||||
return res.status(500).send('<h1 style="margin-top: 150px;text-align: center;direction: rtl;color: red;">فضای هاست پر میباشد.لطفا نسبت به پاک کردن بکاپ های قبلی یا افزایش فضای هاست اقدام فرمایید.</h1>')
|
return res.status(500).send(hostFullError)
|
||||||
})
|
})
|
||||||
|
|
||||||
// good practice to catch this error explicitly
|
|
||||||
archive.on('error', function (err) {
|
archive.on('error', function (err) {
|
||||||
// throw err
|
|
||||||
console.log(err)
|
console.log(err)
|
||||||
return res.status(500).json({message: 'مشکلی پیش آمده'})
|
return res.status(500).json({message: 'مشکلی پیش آمده'})
|
||||||
})
|
})
|
||||||
|
|
||||||
// pipe archive data to the file
|
archive.pipe(output)
|
||||||
await archive.pipe(output)
|
|
||||||
|
|
||||||
// append files from a sub-directory and naming it `new-subdir` within the archive
|
const databaseExports = [
|
||||||
await archive.directory(`./static/uploads/`, 'uploads')
|
['categories', categories],
|
||||||
await archive.directory(`./backup/database/`, 'database')
|
['comments', comments],
|
||||||
|
['contactus', contactus],
|
||||||
|
['contents', contents],
|
||||||
|
['galleries', galleries],
|
||||||
|
['homepage', homepage],
|
||||||
|
['links', links],
|
||||||
|
['meetings', meetings],
|
||||||
|
['news', news],
|
||||||
|
['newsFiles', newsFiles],
|
||||||
|
['services', services],
|
||||||
|
['sliders', sliders],
|
||||||
|
['users', users],
|
||||||
|
['yearBanner', yearBanner],
|
||||||
|
['occasion', occasion],
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const [name, data] of databaseExports) {
|
||||||
|
archive.append(JSON.stringify(data), {name: `database/${name}_${dateStr}.json`})
|
||||||
|
}
|
||||||
|
|
||||||
|
await appendS3UploadsToArchive(archive)
|
||||||
|
|
||||||
// finalize the archive (ie we are done appending files but streams have to finish yet)
|
|
||||||
// 'close', 'end' or 'finish' may be fired right after calling this method so register to them beforehand
|
|
||||||
await archive.finalize()
|
await archive.finalize()
|
||||||
|
|
||||||
await fs.rmdirSync('./backup/database', {recursive: true})
|
await new Promise((resolve, reject) => {
|
||||||
|
output.on('end', resolve)
|
||||||
|
output.on('error', reject)
|
||||||
|
})
|
||||||
|
|
||||||
|
const buffer = Buffer.concat(chunks)
|
||||||
|
|
||||||
|
await uploadBackupArchive(buffer, backupName)
|
||||||
|
|
||||||
|
res.setHeader('Content-Type', 'application/zip')
|
||||||
|
res.setHeader('Content-Disposition', `attachment; filename="${backupName}"`)
|
||||||
|
return res.send(buffer)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return res.status(500).send('<h1 style="margin-top: 150px;text-align: center;direction: rtl;color: red;">فضای هاست پر میباشد.لطفا نسبت به پاک کردن بکاپ های قبلی یا افزایش فضای هاست اقدام فرمایید.</h1>')
|
return res.status(500).send(hostFullError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -173,12 +167,18 @@ module.exports.createBackUp = [
|
|||||||
module.exports.removeOldBackups = [
|
module.exports.removeOldBackups = [
|
||||||
async (req, res) => {
|
async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const files = await fs.readdirSync('./backup')
|
await deleteOldBackups()
|
||||||
for await (const file of files) {
|
|
||||||
const isDirectory = await fs.statSync(`./backup/${file}`).isDirectory()
|
if (fs.existsSync('./backup')) {
|
||||||
if (isDirectory) await fs.rmdirSync(`./backup/${file}`, {recursive: true})
|
const files = fs.readdirSync('./backup')
|
||||||
else await fs.unlinkSync(`./backup/${file}`)
|
for (const file of files) {
|
||||||
|
const filePath = `./backup/${file}`
|
||||||
|
const isDirectory = fs.statSync(filePath).isDirectory()
|
||||||
|
if (isDirectory) fs.rmdirSync(filePath, {recursive: true})
|
||||||
|
else fs.unlinkSync(filePath)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.json({message: _sr['fa'].response.success_remove})
|
return res.json({message: _sr['fa'].response.success_remove})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return res.status(500).json({message: e})
|
return res.status(500).json({message: e})
|
||||||
|
|||||||
@@ -10,8 +10,11 @@ const {
|
|||||||
hasWhiteSpaces,
|
hasWhiteSpaces,
|
||||||
isLatinCharactersWithSymbol
|
isLatinCharactersWithSymbol
|
||||||
} = require('../plugins/controllersHelperFunctions');
|
} = require('../plugins/controllersHelperFunctions');
|
||||||
const fs = require('fs');
|
const {
|
||||||
const sharp = require('sharp');
|
deleteCandidateImage,
|
||||||
|
deleteElectionCandidateImages,
|
||||||
|
uploadProcessedImage,
|
||||||
|
} = require('../plugins/electionImageStorage');
|
||||||
|
|
||||||
////// variables
|
////// variables
|
||||||
const profileWidth = 300;
|
const profileWidth = 300;
|
||||||
@@ -292,17 +295,7 @@ module.exports.deletOneElection = [
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (deleteElection.candidates.length) {
|
if (deleteElection.candidates.length) {
|
||||||
const targetDir = `./static/uploads/images/election/`;
|
await deleteElectionCandidateImages(deleteElection);
|
||||||
|
|
||||||
const getFiles = fs.readdirSync(targetDir);
|
|
||||||
|
|
||||||
for (const file of getFiles) {
|
|
||||||
if (file.includes(deleteElection._id)) {
|
|
||||||
fs.unlink(`./static/uploads/images/election/${file}`, (err) => {
|
|
||||||
if (err) console.log(err)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await deleteElection.deleteOne();
|
await deleteElection.deleteOne();
|
||||||
@@ -457,16 +450,13 @@ module.exports.addCandidate = [
|
|||||||
}
|
}
|
||||||
const imageName = 'candidate_' + Date.now() + '_' + targetElection._id + '.jpg';
|
const imageName = 'candidate_' + Date.now() + '_' + targetElection._id + '.jpg';
|
||||||
data.profilePic = imageName;
|
data.profilePic = imageName;
|
||||||
const target = sharp(image.data)
|
await uploadProcessedImage(
|
||||||
await target
|
image.data,
|
||||||
.resize(profileWidth, profileHeight, {
|
imageName,
|
||||||
fit: 'cover'
|
profileWidth,
|
||||||
})
|
profileHeight,
|
||||||
.toFormat('jpg')
|
profileQuality
|
||||||
.jpeg({
|
);
|
||||||
quality: profileQuality
|
|
||||||
})
|
|
||||||
.toFile(`./static/uploads/images/election/${imageName}`)
|
|
||||||
|
|
||||||
|
|
||||||
targetElection.candidates.push(data);
|
targetElection.candidates.push(data);
|
||||||
@@ -528,29 +518,16 @@ module.exports.updateCandidate = [
|
|||||||
return res.status(422).json({validation: {profilePic: {msg: _sr['fa'].format.image}}});
|
return res.status(422).json({validation: {profilePic: {msg: _sr['fa'].format.image}}});
|
||||||
}
|
}
|
||||||
const imageName = 'candidate_' + Date.now() + '_' + targetElection._id + '.jpg';
|
const imageName = 'candidate_' + Date.now() + '_' + targetElection._id + '.jpg';
|
||||||
const target = sharp(image.data)
|
await deleteCandidateImage(candidate);
|
||||||
await target
|
|
||||||
.resize(profileWidth, profileHeight, {
|
|
||||||
fit: 'cover'
|
|
||||||
})
|
|
||||||
.toFormat('jpg')
|
|
||||||
.jpeg({
|
|
||||||
quality: profileQuality
|
|
||||||
})
|
|
||||||
.toFile(`./static/uploads/images/election/${imageName}`)
|
|
||||||
|
|
||||||
/**
|
await uploadProcessedImage(
|
||||||
* if exist old pic delete it from file
|
image.data,
|
||||||
*/
|
imageName,
|
||||||
if (candidate.profilePic) {
|
profileWidth,
|
||||||
const oldPic = `./static${candidate.profilePic}`;
|
profileHeight,
|
||||||
|
profileQuality
|
||||||
|
);
|
||||||
|
|
||||||
if (fs.existsSync(oldPic)) {
|
|
||||||
fs.unlink(oldPic, (err) => {
|
|
||||||
if (err) return res500(res, err?.message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
candidate.profilePic = imageName;
|
candidate.profilePic = imageName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,15 +563,7 @@ module.exports.deleteCandidate = [
|
|||||||
|
|
||||||
if (!candidate) return res404(res, `کاندید مورد نظر پیدا نشد`);
|
if (!candidate) return res404(res, `کاندید مورد نظر پیدا نشد`);
|
||||||
|
|
||||||
if (candidate.profilePic) {
|
await deleteCandidateImage(candidate);
|
||||||
const oldPic = `./static${candidate.profilePic}`;
|
|
||||||
|
|
||||||
if (fs.existsSync(oldPic)) {
|
|
||||||
fs.unlink(oldPic, (err) => {
|
|
||||||
if (err) return res500(res, err?.message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await targetElection.candidates.id(candidateId).remove();
|
await targetElection.candidates.id(candidateId).remove();
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ const {
|
|||||||
body,
|
body,
|
||||||
validationResult
|
validationResult
|
||||||
} = require('express-validator');
|
} = require('express-validator');
|
||||||
const sharp = require('sharp');
|
|
||||||
const {
|
const {
|
||||||
_sr
|
_sr
|
||||||
} = require('../plugins/serverResponses');
|
} = require('../plugins/serverResponses');
|
||||||
@@ -14,7 +13,10 @@ const {
|
|||||||
isLatinCharactersWithSymbol,
|
isLatinCharactersWithSymbol,
|
||||||
generateRandomDigits
|
generateRandomDigits
|
||||||
} = require('../plugins/controllersHelperFunctions');
|
} = require('../plugins/controllersHelperFunctions');
|
||||||
const fs = require('fs');
|
const {
|
||||||
|
deleteLinksImage,
|
||||||
|
uploadProcessedImage,
|
||||||
|
} = require('../plugins/linksImageStorage');
|
||||||
|
|
||||||
////// variables
|
////// variables
|
||||||
const profileWidth = 50;
|
const profileWidth = 50;
|
||||||
@@ -108,15 +110,13 @@ module.exports.addLinks = [
|
|||||||
}
|
}
|
||||||
const imageName = `links_${Date.now()}_${createLinks._id}.${image.mimetype.split('/')[1]}`;
|
const imageName = `links_${Date.now()}_${createLinks._id}.${image.mimetype.split('/')[1]}`;
|
||||||
try {
|
try {
|
||||||
const target = sharp(image.data)
|
await uploadProcessedImage(
|
||||||
await target
|
image.data,
|
||||||
.resize(profileWidth, profileHeight, {
|
imageName,
|
||||||
fit: 'cover'
|
profileWidth,
|
||||||
})
|
profileHeight,
|
||||||
.jpeg({
|
profileQuality
|
||||||
quality: profileQuality
|
);
|
||||||
})
|
|
||||||
.toFile(`./static/uploads/images/links/${imageName}`);
|
|
||||||
|
|
||||||
createLinks.icon = imageName;
|
createLinks.icon = imageName;
|
||||||
|
|
||||||
@@ -243,28 +243,15 @@ module.exports.updateLinks = [
|
|||||||
}
|
}
|
||||||
const imageName = `links_${Date.now()}_${targetLinks._id}.${image.mimetype.split('/')[1]}`;
|
const imageName = `links_${Date.now()}_${targetLinks._id}.${image.mimetype.split('/')[1]}`;
|
||||||
try {
|
try {
|
||||||
const target = sharp(image.data)
|
await deleteLinksImage(targetLinks, 'icon');
|
||||||
await target
|
|
||||||
.resize(profileWidth, profileHeight, {
|
|
||||||
fit: 'cover'
|
|
||||||
})
|
|
||||||
.jpeg({
|
|
||||||
quality: profileQuality
|
|
||||||
})
|
|
||||||
.toFile(`./static/uploads/images/links/${imageName}`);
|
|
||||||
|
|
||||||
/**
|
await uploadProcessedImage(
|
||||||
* if exist old pic delete it from file
|
image.data,
|
||||||
*/
|
imageName,
|
||||||
if (targetLinks.icon) {
|
profileWidth,
|
||||||
var oldPic = `./static${targetLinks.icon}`;
|
profileHeight,
|
||||||
|
profileQuality
|
||||||
if (fs.existsSync(oldPic)) {
|
);
|
||||||
fs.unlink(oldPic, (err) => {
|
|
||||||
if (err) return res500(res, err?.message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
targetLinks.icon = imageName;
|
targetLinks.icon = imageName;
|
||||||
targetLinks.linksStatus = true;
|
targetLinks.linksStatus = true;
|
||||||
@@ -312,15 +299,7 @@ module.exports.deletOneLinks = [
|
|||||||
return res500(res, `شما اجازه حذف این پیوند را ندارید`);
|
return res500(res, `شما اجازه حذف این پیوند را ندارید`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetLinks.icon) {
|
await deleteLinksImage(targetLinks, 'icon');
|
||||||
var oldPic = `./static${targetLinks.icon}`;
|
|
||||||
|
|
||||||
if (fs.existsSync(oldPic)) {
|
|
||||||
fs.unlink(oldPic, (error) => {
|
|
||||||
if (error) return res500(res, error?.message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** delete links */
|
/** delete links */
|
||||||
await targetLinks.deleteOne();
|
await targetLinks.deleteOne();
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ const Occasion = require('../models/Occasion');
|
|||||||
const {body, validationResult} = require('express-validator');
|
const {body, validationResult} = require('express-validator');
|
||||||
const {_sr} = require('../plugins/serverResponses');
|
const {_sr} = require('../plugins/serverResponses');
|
||||||
const {res404, res500} = require('../plugins/controllersHelperFunctions');
|
const {res404, res500} = require('../plugins/controllersHelperFunctions');
|
||||||
const fs = require('fs');
|
const {
|
||||||
const sharp = require('sharp');
|
deleteOccasionImage,
|
||||||
|
uploadProcessedImage,
|
||||||
|
} = require('../plugins/occasionImageStorage');
|
||||||
const moment = require('moment-jalaali');
|
const moment = require('moment-jalaali');
|
||||||
|
|
||||||
////// variables
|
////// variables
|
||||||
@@ -63,16 +65,13 @@ module.exports.addOccasion = [
|
|||||||
}
|
}
|
||||||
|
|
||||||
const imageName = `occasion_${addOccasion._id}_${Date.now()}.jpg`;
|
const imageName = `occasion_${addOccasion._id}_${Date.now()}.jpg`;
|
||||||
const target = sharp(image.data)
|
await uploadProcessedImage(
|
||||||
await target
|
image.data,
|
||||||
.resize(occasionWidth, occasionHeight, {
|
imageName,
|
||||||
fit: 'cover'
|
occasionWidth,
|
||||||
})
|
occasionHeight,
|
||||||
.toFormat('jpg')
|
occasionQuality
|
||||||
.jpeg({
|
);
|
||||||
quality: occasionQuality
|
|
||||||
})
|
|
||||||
.toFile(`./static/uploads/images/occasion/${imageName}`);
|
|
||||||
|
|
||||||
addOccasion.status = true;
|
addOccasion.status = true;
|
||||||
addOccasion.mainCover = imageName;
|
addOccasion.mainCover = imageName;
|
||||||
@@ -132,26 +131,15 @@ module.exports.updateOccasion = [
|
|||||||
}
|
}
|
||||||
|
|
||||||
const imageName = `occasion_${targetOccasion._id}_${Date.now()}.jpg`;
|
const imageName = `occasion_${targetOccasion._id}_${Date.now()}.jpg`;
|
||||||
const target = sharp(image.data)
|
await deleteOccasionImage(targetOccasion, 'mainCover');
|
||||||
await target
|
|
||||||
.resize(occasionWidth, occasionHeight, {
|
|
||||||
fit: 'cover'
|
|
||||||
})
|
|
||||||
.toFormat('jpg')
|
|
||||||
.jpeg({
|
|
||||||
quality: occasionQuality
|
|
||||||
})
|
|
||||||
.toFile(`./static/uploads/images/occasion/${imageName}`);
|
|
||||||
|
|
||||||
if (targetOccasion.mainCover) {
|
await uploadProcessedImage(
|
||||||
var oldPic = `./static${targetOccasion.mainCover}`;
|
image.data,
|
||||||
|
imageName,
|
||||||
if (fs.existsSync(oldPic)) {
|
occasionWidth,
|
||||||
fs.unlink(oldPic, (err) => {
|
occasionHeight,
|
||||||
if (err) return res500(res, err?.message);
|
occasionQuality
|
||||||
});
|
);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
targetOccasion.status = true;
|
targetOccasion.status = true;
|
||||||
targetOccasion.mainCover = imageName;
|
targetOccasion.mainCover = imageName;
|
||||||
@@ -184,15 +172,7 @@ module.exports.deleteOccasion = [
|
|||||||
return res404(res, `مناسبت مورد نظر پیدا نشد`);
|
return res404(res, `مناسبت مورد نظر پیدا نشد`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetOccasion.mainCover) {
|
await deleteOccasionImage(targetOccasion, 'mainCover');
|
||||||
var oldPic = `./static${targetOccasion.mainCover}`;
|
|
||||||
|
|
||||||
if (fs.existsSync(oldPic)) {
|
|
||||||
fs.unlink(oldPic, (err) => {
|
|
||||||
if (err) return res500(res, err?.message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await targetOccasion.deleteOne();
|
await targetOccasion.deleteOne();
|
||||||
|
|
||||||
|
|||||||
@@ -1,109 +1,148 @@
|
|||||||
|
const fs = require("fs/promises");
|
||||||
|
const os = require("os");
|
||||||
|
const path = require("path");
|
||||||
|
const axios = require("axios");
|
||||||
const { body, validationResult } = require("express-validator");
|
const { body, validationResult } = require("express-validator");
|
||||||
const { _sr } = require("../plugins/serverResponses");
|
const { _sr } = require("../plugins/serverResponses");
|
||||||
const { checkValidations } = require("../plugins/controllersHelperFunctions");
|
const { checkValidations } = require("../plugins/controllersHelperFunctions");
|
||||||
const Book = require("../models/Book");
|
const Book = require("../models/Book");
|
||||||
var convertapi = require('convertapi')('6zZB0nquI5V3P3Vg');
|
const {
|
||||||
|
uploadPdf,
|
||||||
|
uploadBookSlide,
|
||||||
|
deletePdf,
|
||||||
|
deleteBookSlide,
|
||||||
|
} = require("../plugins/bookImageStorage");
|
||||||
|
const convertapi = require("convertapi")("6zZB0nquI5V3P3Vg");
|
||||||
|
|
||||||
module.exports.AddPDF = [
|
module.exports.AddPDF = [
|
||||||
[
|
[body("title").notEmpty().withMessage(_sr["fa"].required.title)],
|
||||||
body('title')
|
checkValidations(validationResult),
|
||||||
.notEmpty().withMessage(_sr['fa'].required.title)
|
async (req, res) => {
|
||||||
],
|
let tmpDir;
|
||||||
checkValidations(validationResult),
|
|
||||||
async (req, res) => {
|
try {
|
||||||
try {
|
const firstbook = [];
|
||||||
const firstbook = [];
|
|
||||||
|
if (!req.files?.file) {
|
||||||
if (!req.files?.file) {
|
return res
|
||||||
return res.status(422).json({ validation: { file: { msg: _sr['fa'].required.file } } });
|
.status(422)
|
||||||
}
|
.json({ validation: { file: { msg: _sr["fa"].required.file } } });
|
||||||
|
}
|
||||||
if (req.files?.file.mimetype.split('/')[1] !== 'pdf') {
|
|
||||||
return res.status(422).json({ validation: { file: { msg: 'فقط فرمت PDF قابل قبول است' } } });
|
if (req.files?.file.mimetype.split("/")[1] !== "pdf") {
|
||||||
}
|
return res
|
||||||
|
.status(422)
|
||||||
const book = await Book.findById(req.body.bookId);
|
.json({ validation: { file: { msg: "فقط فرمت PDF قابل قبول است" } } });
|
||||||
const bookId = book ? book._id : null;
|
}
|
||||||
|
|
||||||
const data = { title: req.body.title };
|
const book = await Book.findById(req.body.bookId);
|
||||||
const file = req.files.file;
|
const bookId = book ? book._id : null;
|
||||||
const fileName = req.body.title.replace(Date.now(), '-') + '_' + Date.now() + '.pdf';
|
|
||||||
const imageName = req.body.title.replace(Date.now(), '-') + '_' + Date.now();
|
const file = req.files.file;
|
||||||
|
const fileName =
|
||||||
const filePath = `./static/uploads/pdf/${fileName}`;
|
req.body.title.replace(Date.now(), "-") + "_" + Date.now() + ".pdf";
|
||||||
|
const imageName =
|
||||||
await file.mv(filePath);
|
req.body.title.replace(Date.now(), "-") + "_" + Date.now();
|
||||||
data.file = fileName;
|
|
||||||
|
const { url: pdfUrl } = await uploadPdf(file.data, fileName);
|
||||||
const convertPromise = convertapi.convert('jpg', {
|
|
||||||
File: filePath
|
tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "book-"));
|
||||||
}, 'pdf');
|
const tmpPdfPath = path.join(tmpDir, fileName);
|
||||||
|
await fs.writeFile(tmpPdfPath, file.data);
|
||||||
const result = await convertPromise;
|
|
||||||
const savedFiles = await result.saveFiles(`./static/uploads/books/${imageName}.jpeg`);
|
const result = await convertapi.convert(
|
||||||
|
"jpg",
|
||||||
const imagePath = `https://ostan-mr.ir/uploads/books/${imageName}.jpeg`;
|
{ File: tmpPdfPath },
|
||||||
firstbook.push(imagePath);
|
"pdf"
|
||||||
|
);
|
||||||
if (bookId) {
|
|
||||||
const update = await Book.findByIdAndUpdate(
|
const convertedResponse = await axios.get(result.files[0].url, {
|
||||||
{_id:bookId},
|
responseType: "arraybuffer",
|
||||||
{ $push: { slides: imagePath } },
|
});
|
||||||
{ upsert: true }
|
const imagePath = await uploadBookSlide(
|
||||||
);
|
Buffer.from(convertedResponse.data),
|
||||||
return res.status(201).json({ msg: "اسلاید کتاب اضافه شد", Data: update });
|
imageName
|
||||||
} else {
|
);
|
||||||
const newBook = new Book({
|
firstbook.push(imagePath);
|
||||||
title: req.body.title,
|
|
||||||
uri: `https://ostan-mr.ir/uploads/pdf/${fileName}`,
|
if (bookId) {
|
||||||
slides: firstbook
|
const update = await Book.findByIdAndUpdate(
|
||||||
});
|
{ _id: bookId },
|
||||||
await newBook.save();
|
{ $push: { slides: imagePath } },
|
||||||
return res.status(201).json({ msg: "کتاب ایجاد شد", Data: newBook });
|
{ upsert: true }
|
||||||
}
|
);
|
||||||
|
return res
|
||||||
} catch (error) {
|
.status(201)
|
||||||
console.error(error);
|
.json({ msg: "اسلاید کتاب اضافه شد", Data: update });
|
||||||
return res.status(500).json({ msg: "خطایی در پردازش فایل رخ داد", error: error.message });
|
}
|
||||||
}
|
|
||||||
|
const newBook = new Book({
|
||||||
|
title: req.body.title,
|
||||||
|
uri: pdfUrl,
|
||||||
|
slides: firstbook,
|
||||||
|
});
|
||||||
|
await newBook.save();
|
||||||
|
return res.status(201).json({ msg: "کتاب ایجاد شد", Data: newBook });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return res.status(500).json({
|
||||||
|
msg: "خطایی در پردازش فایل رخ داد",
|
||||||
|
error: error.message,
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
if (tmpDir) {
|
||||||
|
await fs.rm(tmpDir, { recursive: true, force: true }).catch(() => {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
module.exports.GetAll = [
|
module.exports.GetAll = [
|
||||||
async (req, res,next) => {
|
async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const Books = await Book.find({});
|
const Books = await Book.find({});
|
||||||
return res.status(200).json({ Books });
|
return res.status(200).json({ Books });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error)
|
next(error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
module.exports.GetOne = [
|
module.exports.GetOne = [
|
||||||
async (req, res,next) => {
|
async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const id = req.params.id
|
const id = req.params.id;
|
||||||
const book = await Book.findById(id);
|
const book = await Book.findById(id);
|
||||||
return res.status(200).json({ msg: book });
|
return res.status(200).json({ msg: book });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error)
|
next(error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
module.exports.DeleteOne = [
|
module.exports.DeleteOne = [
|
||||||
async(req,res,next)=>{
|
async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const book = await Book.deleteOne({_id:req.params.id})
|
const book = await Book.findById(req.params.id);
|
||||||
if(!book){
|
if (!book) {
|
||||||
return res.status(200).json({ msg: 'کتاب وجود ندارد ' });
|
return res.status(200).json({ msg: "کتاب وجود ندارد " });
|
||||||
}
|
}
|
||||||
return res.status(200).json({ msg: 'کتاب حذف شد' });
|
|
||||||
} catch (error) {
|
const uri = book.get("uri", null, { getters: false });
|
||||||
next(error)
|
if (uri) {
|
||||||
}
|
await deletePdf(uri.split("/").pop());
|
||||||
|
}
|
||||||
|
|
||||||
|
const slides = book.get("slides", [], { getters: false }) || [];
|
||||||
|
for (const slide of slides) {
|
||||||
|
const imageName = slide.split("/").pop().replace(/\.jpeg$/i, "");
|
||||||
|
await deleteBookSlide(imageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
await book.deleteOne();
|
||||||
|
return res.status(200).json({ msg: "کتاب حذف شد" });
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
}
|
}
|
||||||
]
|
},
|
||||||
|
];
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ const {
|
|||||||
body,
|
body,
|
||||||
validationResult
|
validationResult
|
||||||
} = require('express-validator');
|
} = require('express-validator');
|
||||||
const sharp = require('sharp');
|
|
||||||
const {
|
const {
|
||||||
_sr
|
_sr
|
||||||
} = require('../plugins/serverResponses');
|
} = require('../plugins/serverResponses');
|
||||||
@@ -14,7 +13,10 @@ const {
|
|||||||
isLatinCharactersWithSymbol,
|
isLatinCharactersWithSymbol,
|
||||||
generateRandomDigits
|
generateRandomDigits
|
||||||
} = require('../plugins/controllersHelperFunctions');
|
} = require('../plugins/controllersHelperFunctions');
|
||||||
const fs = require('fs');
|
const {
|
||||||
|
deleteSliderImage,
|
||||||
|
uploadProcessedImage,
|
||||||
|
} = require('../plugins/sliderImageStorage');
|
||||||
|
|
||||||
////// variables
|
////// variables
|
||||||
const profileWidth = 600;
|
const profileWidth = 600;
|
||||||
@@ -113,15 +115,13 @@ module.exports.addSlider = [
|
|||||||
}
|
}
|
||||||
const imageName = `slider_${Date.now()}_${createSlider._id}.${image.mimetype.split('/')[1]}`;
|
const imageName = `slider_${Date.now()}_${createSlider._id}.${image.mimetype.split('/')[1]}`;
|
||||||
try {
|
try {
|
||||||
const target = sharp(image.data)
|
await uploadProcessedImage(
|
||||||
await target
|
image.data,
|
||||||
.resize(profileWidth, profileHeight, {
|
imageName,
|
||||||
fit: 'cover'
|
profileWidth,
|
||||||
})
|
profileHeight,
|
||||||
.jpeg({
|
profileQuality
|
||||||
quality: profileQuality
|
);
|
||||||
})
|
|
||||||
.toFile(`./static/uploads/images/slider/${imageName}`);
|
|
||||||
|
|
||||||
createSlider.cover = imageName;
|
createSlider.cover = imageName;
|
||||||
|
|
||||||
@@ -253,28 +253,15 @@ module.exports.updateSlider = [
|
|||||||
}
|
}
|
||||||
const imageName = `slider_${Date.now()}_${targetSlider._id}.${image.mimetype.split('/')[1]}`;
|
const imageName = `slider_${Date.now()}_${targetSlider._id}.${image.mimetype.split('/')[1]}`;
|
||||||
try {
|
try {
|
||||||
const target = sharp(image.data)
|
await deleteSliderImage(targetSlider, "cover");
|
||||||
await target
|
|
||||||
.resize(profileWidth, profileHeight, {
|
|
||||||
fit: 'cover'
|
|
||||||
})
|
|
||||||
.jpeg({
|
|
||||||
quality: profileQuality
|
|
||||||
})
|
|
||||||
.toFile(`./static/uploads/images/slider/${imageName}`);
|
|
||||||
|
|
||||||
/**
|
await uploadProcessedImage(
|
||||||
* if exist old pic delete it from file
|
image.data,
|
||||||
*/
|
imageName,
|
||||||
if (targetSlider.cover) {
|
profileWidth,
|
||||||
var oldPic = `./static${targetSlider.cover}`;
|
profileHeight,
|
||||||
|
profileQuality
|
||||||
if (fs.existsSync(oldPic)) {
|
);
|
||||||
fs.unlink(oldPic, (err) => {
|
|
||||||
if (err) return res500(res, err?.message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
targetSlider.cover = imageName;
|
targetSlider.cover = imageName;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -322,15 +309,7 @@ module.exports.deletOneSlider = [
|
|||||||
return res500(res, `شما اجازه حذف این اسلایدر را ندارید`);
|
return res500(res, `شما اجازه حذف این اسلایدر را ندارید`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetSlider.cover) {
|
await deleteSliderImage(targetSlider, "cover");
|
||||||
var oldPic = `./static${targetSlider.cover}`;
|
|
||||||
|
|
||||||
if (fs.existsSync(oldPic)) {
|
|
||||||
fs.unlink(oldPic, (error) => {
|
|
||||||
if (error) return res500(res, error?.message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** delete slider */
|
/** delete slider */
|
||||||
await targetSlider.deleteOne();
|
await targetSlider.deleteOne();
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ const {
|
|||||||
body,
|
body,
|
||||||
validationResult
|
validationResult
|
||||||
} = require('express-validator');
|
} = require('express-validator');
|
||||||
const sharp = require('sharp');
|
|
||||||
const {
|
const {
|
||||||
_sr
|
_sr
|
||||||
} = require('../plugins/serverResponses');
|
} = require('../plugins/serverResponses');
|
||||||
@@ -14,7 +13,10 @@ const {
|
|||||||
isLatinCharactersWithSymbol,
|
isLatinCharactersWithSymbol,
|
||||||
generateRandomDigits
|
generateRandomDigits
|
||||||
} = require('../plugins/controllersHelperFunctions');
|
} = require('../plugins/controllersHelperFunctions');
|
||||||
const fs = require('fs');
|
const {
|
||||||
|
deleteSliderImage,
|
||||||
|
uploadProcessedImage,
|
||||||
|
} = require('../plugins/sliderImageStorage');
|
||||||
|
|
||||||
////// variables
|
////// variables
|
||||||
const profileWidth = 880;
|
const profileWidth = 880;
|
||||||
@@ -113,15 +115,13 @@ module.exports.addSlider = [
|
|||||||
}
|
}
|
||||||
const imageName = `slider_${Date.now()}_${createSlider._id}.${image.mimetype.split('/')[1]}`;
|
const imageName = `slider_${Date.now()}_${createSlider._id}.${image.mimetype.split('/')[1]}`;
|
||||||
try {
|
try {
|
||||||
const target = sharp(image.data)
|
await uploadProcessedImage(
|
||||||
await target
|
image.data,
|
||||||
.resize(profileWidth, profileHeight, {
|
imageName,
|
||||||
fit: 'cover'
|
profileWidth,
|
||||||
})
|
profileHeight,
|
||||||
.jpeg({
|
profileQuality
|
||||||
quality: profileQuality
|
);
|
||||||
})
|
|
||||||
.toFile(`./static/uploads/images/slider/${imageName}`);
|
|
||||||
|
|
||||||
createSlider.cover = imageName;
|
createSlider.cover = imageName;
|
||||||
|
|
||||||
@@ -253,28 +253,15 @@ module.exports.updateSlider = [
|
|||||||
}
|
}
|
||||||
const imageName = `slider_${Date.now()}_${targetSlider._id}.${image.mimetype.split('/')[1]}`;
|
const imageName = `slider_${Date.now()}_${targetSlider._id}.${image.mimetype.split('/')[1]}`;
|
||||||
try {
|
try {
|
||||||
const target = sharp(image.data)
|
await deleteSliderImage(targetSlider, "cover");
|
||||||
await target
|
|
||||||
.resize(profileWidth, profileHeight, {
|
|
||||||
fit: 'cover'
|
|
||||||
})
|
|
||||||
.jpeg({
|
|
||||||
quality: profileQuality
|
|
||||||
})
|
|
||||||
.toFile(`./static/uploads/images/slider/${imageName}`);
|
|
||||||
|
|
||||||
/**
|
await uploadProcessedImage(
|
||||||
* if exist old pic delete it from file
|
image.data,
|
||||||
*/
|
imageName,
|
||||||
if (targetSlider.cover) {
|
profileWidth,
|
||||||
var oldPic = `./static${targetSlider.cover}`;
|
profileHeight,
|
||||||
|
profileQuality
|
||||||
if (fs.existsSync(oldPic)) {
|
);
|
||||||
fs.unlink(oldPic, (err) => {
|
|
||||||
if (err) return res500(res, err?.message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
targetSlider.cover = imageName;
|
targetSlider.cover = imageName;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -322,15 +309,7 @@ module.exports.deletOneSlider = [
|
|||||||
return res500(res, `شما اجازه حذف این اسلایدر را ندارید`);
|
return res500(res, `شما اجازه حذف این اسلایدر را ندارید`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetSlider.cover) {
|
await deleteSliderImage(targetSlider, "cover");
|
||||||
var oldPic = `./static${targetSlider.cover}`;
|
|
||||||
|
|
||||||
if (fs.existsSync(oldPic)) {
|
|
||||||
fs.unlink(oldPic, (error) => {
|
|
||||||
if (error) return res500(res, error?.message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** delete slider */
|
/** delete slider */
|
||||||
await targetSlider.deleteOne();
|
await targetSlider.deleteOne();
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ const { rateLimit } = require("express-rate-limit");
|
|||||||
const bcrypt = require("bcryptjs");
|
const bcrypt = require("bcryptjs");
|
||||||
const jwt = require("jsonwebtoken");
|
const jwt = require("jsonwebtoken");
|
||||||
const crypto = require("crypto");
|
const crypto = require("crypto");
|
||||||
const sharp = require("sharp");
|
|
||||||
const { secretKey } = require("./../authentication");
|
const { secretKey } = require("./../authentication");
|
||||||
const { _sr } = require("../plugins/serverResponses");
|
const { _sr } = require("../plugins/serverResponses");
|
||||||
const {
|
const {
|
||||||
@@ -14,7 +13,10 @@ const {
|
|||||||
isLatinCharactersWithSymbol,
|
isLatinCharactersWithSymbol,
|
||||||
generateRandomDigits,
|
generateRandomDigits,
|
||||||
} = require("../plugins/controllersHelperFunctions");
|
} = require("../plugins/controllersHelperFunctions");
|
||||||
const fs = require("fs");
|
const {
|
||||||
|
deleteUserImage,
|
||||||
|
uploadProcessedImage,
|
||||||
|
} = require("../plugins/userImageStorage");
|
||||||
const nodemailer = require("nodemailer");
|
const nodemailer = require("nodemailer");
|
||||||
const Category = require("../models/Category");
|
const Category = require("../models/Category");
|
||||||
const Logger = require("../models/Logger");
|
const Logger = require("../models/Logger");
|
||||||
@@ -566,15 +568,13 @@ module.exports.registerAdmin = [
|
|||||||
image.mimetype.split("/")[1];
|
image.mimetype.split("/")[1];
|
||||||
data.profilePic = imageName;
|
data.profilePic = imageName;
|
||||||
try {
|
try {
|
||||||
const target = sharp(image.data);
|
await uploadProcessedImage(
|
||||||
await target
|
image.data,
|
||||||
.resize(profileWidth, profileHeight, {
|
imageName,
|
||||||
fit: "cover",
|
profileWidth,
|
||||||
})
|
profileHeight,
|
||||||
.jpeg({
|
profileQuality
|
||||||
quality: profileQuality,
|
);
|
||||||
})
|
|
||||||
.toFile(`./static/uploads/images/users/${imageName}`);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return res500(res, e?.message);
|
return res500(res, e?.message);
|
||||||
}
|
}
|
||||||
@@ -713,18 +713,7 @@ module.exports.deleteOneUser = [
|
|||||||
.json({ message: `شما نمیتوانید این کاربر را حذف کنید` });
|
.json({ message: `شما نمیتوانید این کاربر را حذف کنید` });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
await deleteUserImage(user, "profilePic");
|
||||||
* if exist old pic delete it from file
|
|
||||||
*/
|
|
||||||
if (user.profilePic) {
|
|
||||||
var oldPic = `./static${user.profilePic}`;
|
|
||||||
|
|
||||||
if (fs.existsSync(oldPic)) {
|
|
||||||
fs.unlink(oldPic, (err) => {
|
|
||||||
if (err) return res500(res, err?.message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** delete user */
|
/** delete user */
|
||||||
await user.deleteOne();
|
await user.deleteOne();
|
||||||
@@ -922,28 +911,15 @@ module.exports.updateUser = [
|
|||||||
image.mimetype.split("/")[1];
|
image.mimetype.split("/")[1];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const target = sharp(image.data);
|
await deleteUserImage(user, "profilePic");
|
||||||
await target
|
|
||||||
.resize(profileWidth, profileHeight, {
|
|
||||||
fit: "cover",
|
|
||||||
})
|
|
||||||
.jpeg({
|
|
||||||
quality: profileQuality,
|
|
||||||
})
|
|
||||||
.toFile(`./static/uploads/images/users/${imageName}`);
|
|
||||||
|
|
||||||
/**
|
await uploadProcessedImage(
|
||||||
* if exist old pic delete it from file
|
image.data,
|
||||||
*/
|
imageName,
|
||||||
if (user.profilePic) {
|
profileWidth,
|
||||||
var oldPic = `./static${user.profilePic}`;
|
profileHeight,
|
||||||
|
profileQuality
|
||||||
if (fs.existsSync(oldPic)) {
|
);
|
||||||
fs.unlink(oldPic, (err) => {
|
|
||||||
if (err) return res500(res, err?.message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return res500(res, e?.message);
|
return res500(res, e?.message);
|
||||||
}
|
}
|
||||||
@@ -1129,28 +1105,15 @@ module.exports.updateProfile = [
|
|||||||
image.mimetype.split("/")[1];
|
image.mimetype.split("/")[1];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const target = sharp(image.data);
|
await deleteUserImage(user, "profilePic");
|
||||||
await target
|
|
||||||
.resize(profileWidth, profileHeight, {
|
|
||||||
fit: "cover",
|
|
||||||
})
|
|
||||||
.jpeg({
|
|
||||||
quality: profileQuality,
|
|
||||||
})
|
|
||||||
.toFile(`./static/uploads/images/users/${imageName}`);
|
|
||||||
|
|
||||||
/**
|
await uploadProcessedImage(
|
||||||
* if exist old pic delete it from file
|
image.data,
|
||||||
*/
|
imageName,
|
||||||
if (user.profilePic) {
|
profileWidth,
|
||||||
var oldPic = `./static${user.profilePic}`;
|
profileHeight,
|
||||||
|
profileQuality
|
||||||
if (fs.existsSync(oldPic)) {
|
);
|
||||||
fs.unlink(oldPic, (err) => {
|
|
||||||
if (err) return res500(res, err?.message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return res500(res, e?.message);
|
return res500(res, e?.message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ const YearBanner = require('../models/YearBanner');
|
|||||||
const {body, validationResult, checkSchema} = require('express-validator');
|
const {body, validationResult, checkSchema} = require('express-validator');
|
||||||
const {_sr} = require('../plugins/serverResponses');
|
const {_sr} = require('../plugins/serverResponses');
|
||||||
const {res404, res500} = require('../plugins/controllersHelperFunctions');
|
const {res404, res500} = require('../plugins/controllersHelperFunctions');
|
||||||
const fs = require('fs');
|
const {uploadProcessedImage} = require('../plugins/yearBannerImageStorage');
|
||||||
const sharp = require('sharp');
|
|
||||||
|
|
||||||
////// variables
|
////// variables
|
||||||
const yearBannerWidth = 1920
|
const yearBannerWidth = 1920
|
||||||
@@ -51,12 +50,13 @@ module.exports.updateYearBanner = [
|
|||||||
|
|
||||||
imageName = `mainPage_cover.jpg`;
|
imageName = `mainPage_cover.jpg`;
|
||||||
|
|
||||||
const target = sharp(image.data)
|
await uploadProcessedImage(
|
||||||
await target
|
image.data,
|
||||||
.resize(yearBannerWidth, yearBannerHeight, {fit: 'cover'})
|
imageName,
|
||||||
.toFormat('jpg')
|
yearBannerWidth,
|
||||||
.jpeg({quality: yearBannerQuality})
|
yearBannerHeight,
|
||||||
.toFile(`./static/uploads/images/mainCover/${imageName}`);
|
yearBannerQuality
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (yearBanner) {
|
if (yearBanner) {
|
||||||
|
|||||||
+22
-7
@@ -1,16 +1,31 @@
|
|||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const mongoosePaginate = require('mongoose-paginate-v2');
|
const mongoosePaginate = require('mongoose-paginate-v2');
|
||||||
|
const s3Storage = require('../plugins/s3Storage');
|
||||||
|
|
||||||
|
function pdfUri(uri) {
|
||||||
function PDF(pdf) {
|
if (!uri) return null;
|
||||||
if (pdf) return '/uploads/files/ReadOnly-PDF' + pdf
|
if (uri.startsWith('http://') || uri.startsWith('https://')) return uri;
|
||||||
|
const fileName = uri.startsWith('/') ? uri.split('/').pop() : uri;
|
||||||
|
return s3Storage.getPublicUrl(`uploads/pdf/${fileName}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function slideUrl(slide) {
|
||||||
|
if (!slide) return null;
|
||||||
|
if (slide.startsWith('http://') || slide.startsWith('https://')) return slide;
|
||||||
|
const imageName = slide.startsWith('/') ? slide.split('/').pop() : slide;
|
||||||
|
const key = imageName.endsWith('.jpeg')
|
||||||
|
? `uploads/books/${imageName}`
|
||||||
|
: `uploads/books/${imageName}.jpeg`;
|
||||||
|
return s3Storage.getPublicUrl(key);
|
||||||
|
}
|
||||||
|
|
||||||
const BookSchema = mongoose.Schema({
|
const BookSchema = mongoose.Schema({
|
||||||
title: String,
|
title: String,
|
||||||
uri: String,
|
uri: { type: String, get: pdfUri, default: null },
|
||||||
slides:{
|
slides: {
|
||||||
default:[],
|
default: [],
|
||||||
type:Array
|
type: [String],
|
||||||
|
get: (slides) => (slides || []).map(slideUrl),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
const mongoose = require("mongoose");
|
const mongoose = require("mongoose");
|
||||||
|
const s3Storage = require("../plugins/s3Storage");
|
||||||
|
|
||||||
function autoPopulateSubs(next) {
|
function autoPopulateSubs(next) {
|
||||||
this.populate({
|
this.populate({
|
||||||
@@ -14,12 +15,21 @@ function autoPopulateSubs(next) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function file(file) {
|
function file(file) {
|
||||||
return "/uploads/files/terms/" + file;
|
if (!file) return null;
|
||||||
|
if (file.startsWith("http://") || file.startsWith("https://")) return file;
|
||||||
|
return s3Storage.getPublicUrl(`uploads/files/terms/${file}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function image(img) {
|
function image(img) {
|
||||||
if (img) return "/uploads/images/category/" + img;
|
if (!img) return "/img/no-cover.jpg";
|
||||||
else return "/img/no-cover.jpg";
|
if (img.startsWith("http://") || img.startsWith("https://")) return img;
|
||||||
|
return s3Storage.getPublicUrl(`uploads/images/category/${img}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function shafafiatIcon(icon) {
|
||||||
|
if (!icon) return null;
|
||||||
|
if (icon.startsWith("http://") || icon.startsWith("https://")) return icon;
|
||||||
|
return s3Storage.getPublicUrl(`uploads/images/category/shafafiat/${icon}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const CategoryTermsFile = mongoose.Schema({
|
const CategoryTermsFile = mongoose.Schema({
|
||||||
@@ -71,7 +81,7 @@ const CategorySchema = mongoose.Schema({
|
|||||||
managerName: String,
|
managerName: String,
|
||||||
managerDescription: String,
|
managerDescription: String,
|
||||||
/** if category was shafafiat this icon is for that */
|
/** if category was shafafiat this icon is for that */
|
||||||
icon: String,
|
icon: { type: String, get: shafafiatIcon, default: null },
|
||||||
});
|
});
|
||||||
|
|
||||||
CategorySchema.index({ parent: 1, childs: 1 });
|
CategorySchema.index({ parent: 1, childs: 1 });
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
|
const s3Storage = require('../plugins/s3Storage');
|
||||||
|
|
||||||
function image(img) {
|
function image(img) {
|
||||||
if (img) return '/uploads/images/content/' + img
|
if (!img) return null;
|
||||||
|
if (img.startsWith('http://') || img.startsWith('https://')) return img;
|
||||||
|
return s3Storage.getPublicUrl(`uploads/images/content/${img}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const mongoosePaginate = require('mongoose-paginate-v2');
|
const mongoosePaginate = require('mongoose-paginate-v2');
|
||||||
|
const s3Storage = require('../plugins/s3Storage');
|
||||||
|
|
||||||
function image(img) {
|
function image(img) {
|
||||||
if (img) return '/uploads/images/election/' + img
|
if (!img) return null;
|
||||||
|
if (img.startsWith('http://') || img.startsWith('https://')) return img;
|
||||||
|
return s3Storage.getPublicUrl(`uploads/images/election/${img}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const CandidatesSchema = mongoose.Schema({
|
const CandidatesSchema = mongoose.Schema({
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
|
const s3Storage = require('../plugins/s3Storage');
|
||||||
|
|
||||||
function image(img) {
|
function image(img) {
|
||||||
if (img) return '/uploads/images/links/' + img
|
if (!img) return null;
|
||||||
|
if (img.startsWith('http://') || img.startsWith('https://')) return img;
|
||||||
|
return s3Storage.getPublicUrl(`uploads/images/links/${img}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const LinksSchema = mongoose.Schema({
|
const LinksSchema = mongoose.Schema({
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const mongoosePaginate = require('mongoose-paginate-v2');
|
const mongoosePaginate = require('mongoose-paginate-v2');
|
||||||
|
const s3Storage = require('../plugins/s3Storage');
|
||||||
|
|
||||||
function image(img) {
|
function image(img) {
|
||||||
if (img) return '/uploads/images/occasion/' + img
|
if (!img) return null;
|
||||||
|
if (img.startsWith('http://') || img.startsWith('https://')) return img;
|
||||||
|
return s3Storage.getPublicUrl(`uploads/images/occasion/${img}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const OccasionSchema = mongoose.Schema({
|
const OccasionSchema = mongoose.Schema({
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const mongoosePaginate = require('mongoose-paginate-v2');
|
const mongoosePaginate = require('mongoose-paginate-v2');
|
||||||
|
const s3Storage = require('../plugins/s3Storage');
|
||||||
|
|
||||||
function image(img) {
|
function image(img) {
|
||||||
if (img) return '/uploads/images/slider/' + img
|
if (!img) return null;
|
||||||
|
if (img.startsWith('http://') || img.startsWith('https://')) return img;
|
||||||
|
return s3Storage.getPublicUrl(`uploads/images/slider/${img}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SliderSchema = mongoose.Schema({
|
const SliderSchema = mongoose.Schema({
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const mongoosePaginate = require('mongoose-paginate-v2');
|
const mongoosePaginate = require('mongoose-paginate-v2');
|
||||||
|
const s3Storage = require('../plugins/s3Storage');
|
||||||
|
|
||||||
function image(img) {
|
function image(img) {
|
||||||
if (img) return '/uploads/images/users/' + img
|
if (!img) return null;
|
||||||
|
if (img.startsWith('http://') || img.startsWith('https://')) return img;
|
||||||
|
return s3Storage.getPublicUrl(`uploads/images/users/${img}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const AdminSchema = mongoose.Schema({
|
const AdminSchema = mongoose.Schema({
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
|
const s3Storage = require('../plugins/s3Storage');
|
||||||
|
|
||||||
function image(img) {
|
function image(img) {
|
||||||
if (img) return '/uploads/images/mainCover/' + img
|
if (!img) return null;
|
||||||
|
if (img.startsWith('http://') || img.startsWith('https://')) return img;
|
||||||
|
return s3Storage.getPublicUrl(`uploads/images/mainCover/${img}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const YearBannerSchema = mongoose.Schema({
|
const YearBannerSchema = mongoose.Schema({
|
||||||
|
|||||||
@@ -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,
|
S3Client,
|
||||||
PutObjectCommand,
|
PutObjectCommand,
|
||||||
DeleteObjectCommand,
|
DeleteObjectCommand,
|
||||||
|
ListObjectsV2Command,
|
||||||
|
GetObjectCommand,
|
||||||
} = require("@aws-sdk/client-s3");
|
} = require("@aws-sdk/client-s3");
|
||||||
|
|
||||||
const config = {
|
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 = {
|
module.exports = {
|
||||||
isConfigured,
|
isConfigured,
|
||||||
getPublicUrl,
|
getPublicUrl,
|
||||||
uploadBuffer,
|
uploadBuffer,
|
||||||
deleteObject,
|
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