S3 for other controolers
This commit is contained in:
@@ -36,7 +36,7 @@
|
||||
v-for="(item, i) in items"
|
||||
:key="i"
|
||||
class="item">
|
||||
<img :src="`/uploads/images/category/shafafiat/${item.icon}`" alt="شفافیت" />
|
||||
<img :src="item.icon" alt="شفافیت" />
|
||||
<div class="parent">
|
||||
<div class="right"></div>
|
||||
<div class="left"></div>
|
||||
|
||||
@@ -8,13 +8,19 @@ const {
|
||||
checkValidations,
|
||||
} = require("../plugins/controllersHelperFunctions");
|
||||
const News = require("../models/News");
|
||||
const sharp = require("sharp");
|
||||
const fs = require("fs");
|
||||
const { extname } = require("path");
|
||||
const {
|
||||
deleteCategoryImage,
|
||||
deleteShafafiatIcon,
|
||||
uploadProcessedImage,
|
||||
uploadShafafiatIcon,
|
||||
uploadTermsFile,
|
||||
deleteTermsFile,
|
||||
getStoredImageName,
|
||||
} = require("../plugins/categoryImageStorage");
|
||||
|
||||
// variables
|
||||
const titleFilterRegex = new RegExp("/", "g");
|
||||
const noCover = "/img/no-cover.jpg";
|
||||
const coverNewsWidth = 400;
|
||||
const coverNewsHeight = 400;
|
||||
const coverQuality = 100;
|
||||
@@ -411,34 +417,13 @@ module.exports.addCategory = [
|
||||
image.mimetype.split("/")[1]
|
||||
}`;
|
||||
try {
|
||||
const target = sharp(image.data);
|
||||
await target
|
||||
.resize(coverNewsWidth, coverNewsHeight, { fit: "cover" })
|
||||
.jpeg({ quality: coverQuality })
|
||||
.toFile(`./static/uploads/images/category/${imageName}`);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
await uploadProcessedImage(
|
||||
image.data,
|
||||
imageName,
|
||||
coverNewsWidth,
|
||||
coverNewsHeight,
|
||||
coverQuality
|
||||
);
|
||||
|
||||
create.managerCover = imageName;
|
||||
await create.save();
|
||||
@@ -461,33 +446,12 @@ module.exports.addCategory = [
|
||||
const ext = extname(image.name);
|
||||
const imageName = `shafafiat_icon_${Date.now()}${ext}`;
|
||||
try {
|
||||
await image.mv(
|
||||
`${process.cwd()}/static/uploads/images/category/shafafiat/${imageName}`
|
||||
await uploadShafafiatIcon(
|
||||
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;
|
||||
await create.save();
|
||||
} catch (e) {
|
||||
@@ -812,24 +776,15 @@ module.exports.updateCategory = [
|
||||
image.mimetype.split("/")[1]
|
||||
}`;
|
||||
try {
|
||||
const target = sharp(image.data);
|
||||
await target
|
||||
.resize(coverNewsWidth, coverNewsHeight, { fit: "cover" })
|
||||
.jpeg({ quality: coverQuality })
|
||||
.toFile(`./static/uploads/images/category/${imageName}`);
|
||||
await deleteCategoryImage(targetCategory, "managerCover");
|
||||
|
||||
/**
|
||||
* if exist old pic delete it from file
|
||||
*/
|
||||
if (targetCategory.managerCover !== noCover) {
|
||||
let oldPic = `./static${targetCategory.managerCover}`;
|
||||
|
||||
if (await fs.existsSync(oldPic)) {
|
||||
fs.unlink(oldPic, (err) => {
|
||||
if (err) return res500(res, err?.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
await uploadProcessedImage(
|
||||
image.data,
|
||||
imageName,
|
||||
coverNewsWidth,
|
||||
coverNewsHeight,
|
||||
coverQuality
|
||||
);
|
||||
|
||||
targetCategory.managerCover = imageName;
|
||||
} catch (e) {
|
||||
@@ -839,7 +794,6 @@ module.exports.updateCategory = [
|
||||
|
||||
if (req.files?.icon) {
|
||||
const image = req.files.icon;
|
||||
console.log(image);
|
||||
if (!_sr.supportedImageFormats.includes(image.mimetype.split("/")[1])) {
|
||||
return res.status(422).json({
|
||||
validation: {
|
||||
@@ -852,30 +806,17 @@ module.exports.updateCategory = [
|
||||
const ext = extname(image.name);
|
||||
const imageName = `shafafiat_icon_${Date.now()}${ext}`;
|
||||
try {
|
||||
await image.mv(
|
||||
`${process.cwd()}/static/uploads/images/category/shafafiat/${imageName}`
|
||||
await deleteShafafiatIcon(
|
||||
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}`);
|
||||
|
||||
/**
|
||||
* if exist old pic delete it from file
|
||||
*/
|
||||
if (targetCategory.icon !== noCover) {
|
||||
let oldPic = `./static${targetCategory.icon}`;
|
||||
|
||||
if (await fs.existsSync(oldPic)) {
|
||||
fs.unlink(oldPic, (err) => {
|
||||
if (err) return res500(res, err?.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
await uploadShafafiatIcon(
|
||||
image.data,
|
||||
imageName,
|
||||
image.mimetype
|
||||
);
|
||||
|
||||
targetCategory.icon = imageName;
|
||||
console.log(targetCategory);
|
||||
} catch (e) {
|
||||
return res500(res, e?.message);
|
||||
}
|
||||
@@ -1223,52 +1164,59 @@ module.exports.getParent = [
|
||||
module.exports.addTermsFileToCategory = [
|
||||
[body("termsTitle").notEmpty().withMessage(_sr["fa"].required.title)],
|
||||
checkValidations(validationResult),
|
||||
(req, res) => {
|
||||
if (!req.files?.file)
|
||||
return res
|
||||
.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 قابل قبول است" } } });
|
||||
async (req, res) => {
|
||||
try {
|
||||
if (!req.files?.file)
|
||||
return res
|
||||
.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 قابل قبول است" } } });
|
||||
|
||||
const data = { title: req.body.termsTitle };
|
||||
const file = req.files.file;
|
||||
const fileName =
|
||||
req.body.termsTitle.replace(titleFilterRegex, "-") +
|
||||
"_" +
|
||||
Date.now() +
|
||||
".pdf";
|
||||
file.mv(`./static/uploads/files/terms/${fileName}`);
|
||||
data.file = fileName;
|
||||
const category = await Category.findById(req.params.categoryId);
|
||||
if (!category) return res404(res, "category not found");
|
||||
|
||||
Category.findById(req.params.categoryId, (err, category) => {
|
||||
if (err || !category) return res404(res, err);
|
||||
category.terms.push(data);
|
||||
category.save((err) => {
|
||||
if (err) return res500(res, err);
|
||||
else return res.json({ message: _sr["fa"].response.success_save });
|
||||
const fileName =
|
||||
req.body.termsTitle.replace(titleFilterRegex, "-") +
|
||||
"_" +
|
||||
Date.now() +
|
||||
".pdf";
|
||||
|
||||
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 = [
|
||||
(req, res) => {
|
||||
Category.findOne({ "terms._id": req.params.fileId }, (err, category) => {
|
||||
if (err || !category) return res404(res, err);
|
||||
const file = category.terms.id(req.params.fileId);
|
||||
if (!file) return res404(res, "not found");
|
||||
file.remove();
|
||||
fs.unlink(`./static/${file.file}`, (err) => {
|
||||
if (err) console.log(err);
|
||||
});
|
||||
category.save((err) => {
|
||||
if (err) return res500(res, err);
|
||||
else return res.json({ message: _sr["fa"].response.success_remove });
|
||||
});
|
||||
});
|
||||
async (req, res) => {
|
||||
try {
|
||||
const category = await Category.findOne({ "terms._id": req.params.fileId });
|
||||
if (!category) return res404(res, "not found");
|
||||
|
||||
const termsFile = category.terms.id(req.params.fileId);
|
||||
if (!termsFile) return res404(res, "not found");
|
||||
|
||||
const fileName = getStoredImageName(termsFile, "file");
|
||||
termsFile.remove();
|
||||
await deleteTermsFile(fileName);
|
||||
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 sharp = require('sharp');
|
||||
const {_sr} = require('../plugins/serverResponses');
|
||||
const {res404, res500, hasWhiteSpaces, isLatinCharactersWithSymbol, generateRandomDigits} = require('../plugins/controllersHelperFunctions');
|
||||
const Content = require('../models/Content');
|
||||
const fs = require('fs');
|
||||
const {
|
||||
deleteContentImages,
|
||||
uploadProcessedImage,
|
||||
} = require('../plugins/contentImageStorage');
|
||||
|
||||
|
||||
////// variables
|
||||
@@ -85,26 +87,23 @@ module.exports.addContent = [
|
||||
const imageName = `manager_${Date.now()}_${create._id}.${image.mimetype.split('/')[1]}`;
|
||||
const thumbName = 'thumb_' + imageName
|
||||
try {
|
||||
const target = sharp(image.data)
|
||||
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(
|
||||
image.data,
|
||||
imageName,
|
||||
profileWidth,
|
||||
profileHeight,
|
||||
profileQuality
|
||||
);
|
||||
await uploadProcessedImage(
|
||||
image.data,
|
||||
thumbName,
|
||||
profileThumbWidth,
|
||||
profileThumbHeight,
|
||||
profileThumbQuality
|
||||
);
|
||||
|
||||
create.cover = imageName;
|
||||
create.thumb = imageName;
|
||||
create.thumb = thumbName;
|
||||
|
||||
await create.save();
|
||||
} catch (e) {
|
||||
@@ -180,42 +179,22 @@ module.exports.updateContent = [
|
||||
const imageName = `manager_${Date.now()}_${targetContent._id}.${image.mimetype.split('/')[1]}`;
|
||||
const thumbName = 'thumb_' + imageName
|
||||
try {
|
||||
const target = sharp(image.data)
|
||||
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 deleteContentImages(targetContent);
|
||||
|
||||
/**
|
||||
* if exist old pic delete it from file
|
||||
*/
|
||||
if (targetContent.cover) {
|
||||
const oldPic = `./static${targetContent.cover}`
|
||||
const oldThumb = `./static${targetContent.thumb}`
|
||||
|
||||
if (fs.existsSync(oldPic)) {
|
||||
fs.unlink(oldPic, (err) => {
|
||||
if (err) return res500(res, err?.message);
|
||||
});
|
||||
}
|
||||
if (fs.existsSync(oldThumb)) {
|
||||
fs.unlink(oldThumb, (err) => {
|
||||
if (err) return res500(res, err?.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
await uploadProcessedImage(
|
||||
image.data,
|
||||
imageName,
|
||||
profileWidth,
|
||||
profileHeight,
|
||||
profileQuality
|
||||
);
|
||||
await uploadProcessedImage(
|
||||
image.data,
|
||||
thumbName,
|
||||
profileThumbWidth,
|
||||
profileThumbHeight,
|
||||
profileThumbQuality
|
||||
);
|
||||
|
||||
targetContent.cover = imageName;
|
||||
targetContent.thumb = thumbName;
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
const fs = require('fs')
|
||||
const {PassThrough} = require('stream')
|
||||
const archiver = require('archiver')
|
||||
const moment = require('moment')
|
||||
const jwt = require('jsonwebtoken')
|
||||
const {secretKey} = require('../authentication')
|
||||
const {_sr} = require('../plugins/serverResponses')
|
||||
const {
|
||||
appendS3UploadsToArchive,
|
||||
uploadBackupArchive,
|
||||
deleteOldBackups,
|
||||
} = require('../plugins/backupStorage')
|
||||
// models
|
||||
const Category = require('../models/Category')
|
||||
const Comment = require('../models/Comment')
|
||||
@@ -21,6 +27,8 @@ const Slider = require('../models/Slider')
|
||||
const User = require('../models/User')
|
||||
const YearBanner = require('../models/YearBanner')
|
||||
|
||||
const hostFullError = '<h1 style="margin-top: 150px;text-align: center;direction: rtl;color: red;">فضای هاست پر میباشد.لطفا نسبت به پاک کردن بکاپ های قبلی یا افزایش فضای هاست اقدام فرمایید.</h1>'
|
||||
|
||||
module.exports.createBackUp = [
|
||||
// check user token and permission to backup
|
||||
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)
|
||||
|
||||
if (await !fs.existsSync('./backup/database')) await fs.mkdirSync('./backup/database')
|
||||
|
||||
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 dateStr = moment(Date.now()).format('YYYY-MM-DD')
|
||||
const backupName = `backup_${dateStr}.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) {
|
||||
|
||||
if (err.code === 'ENOENT') {
|
||||
// log warning
|
||||
console.log('On archiver warning -- ENOENT error code', err)
|
||||
} else {
|
||||
// throw error
|
||||
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) {
|
||||
// throw err
|
||||
console.log(err)
|
||||
return res.status(500).json({message: 'مشکلی پیش آمده'})
|
||||
})
|
||||
|
||||
// pipe archive data to the file
|
||||
await archive.pipe(output)
|
||||
archive.pipe(output)
|
||||
|
||||
// append files from a sub-directory and naming it `new-subdir` within the archive
|
||||
await archive.directory(`./static/uploads/`, 'uploads')
|
||||
await archive.directory(`./backup/database/`, 'database')
|
||||
const databaseExports = [
|
||||
['categories', categories],
|
||||
['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 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) {
|
||||
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 = [
|
||||
async (req, res) => {
|
||||
try {
|
||||
const files = await fs.readdirSync('./backup')
|
||||
for await (const file of files) {
|
||||
const isDirectory = await fs.statSync(`./backup/${file}`).isDirectory()
|
||||
if (isDirectory) await fs.rmdirSync(`./backup/${file}`, {recursive: true})
|
||||
else await fs.unlinkSync(`./backup/${file}`)
|
||||
await deleteOldBackups()
|
||||
|
||||
if (fs.existsSync('./backup')) {
|
||||
const files = fs.readdirSync('./backup')
|
||||
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})
|
||||
} catch (e) {
|
||||
return res.status(500).json({message: e})
|
||||
|
||||
@@ -10,8 +10,11 @@ const {
|
||||
hasWhiteSpaces,
|
||||
isLatinCharactersWithSymbol
|
||||
} = require('../plugins/controllersHelperFunctions');
|
||||
const fs = require('fs');
|
||||
const sharp = require('sharp');
|
||||
const {
|
||||
deleteCandidateImage,
|
||||
deleteElectionCandidateImages,
|
||||
uploadProcessedImage,
|
||||
} = require('../plugins/electionImageStorage');
|
||||
|
||||
////// variables
|
||||
const profileWidth = 300;
|
||||
@@ -292,17 +295,7 @@ module.exports.deletOneElection = [
|
||||
}
|
||||
|
||||
if (deleteElection.candidates.length) {
|
||||
const targetDir = `./static/uploads/images/election/`;
|
||||
|
||||
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 deleteElectionCandidateImages(deleteElection);
|
||||
}
|
||||
|
||||
await deleteElection.deleteOne();
|
||||
@@ -457,16 +450,13 @@ module.exports.addCandidate = [
|
||||
}
|
||||
const imageName = 'candidate_' + Date.now() + '_' + targetElection._id + '.jpg';
|
||||
data.profilePic = imageName;
|
||||
const target = sharp(image.data)
|
||||
await target
|
||||
.resize(profileWidth, profileHeight, {
|
||||
fit: 'cover'
|
||||
})
|
||||
.toFormat('jpg')
|
||||
.jpeg({
|
||||
quality: profileQuality
|
||||
})
|
||||
.toFile(`./static/uploads/images/election/${imageName}`)
|
||||
await uploadProcessedImage(
|
||||
image.data,
|
||||
imageName,
|
||||
profileWidth,
|
||||
profileHeight,
|
||||
profileQuality
|
||||
);
|
||||
|
||||
|
||||
targetElection.candidates.push(data);
|
||||
@@ -528,29 +518,16 @@ module.exports.updateCandidate = [
|
||||
return res.status(422).json({validation: {profilePic: {msg: _sr['fa'].format.image}}});
|
||||
}
|
||||
const imageName = 'candidate_' + Date.now() + '_' + targetElection._id + '.jpg';
|
||||
const target = sharp(image.data)
|
||||
await target
|
||||
.resize(profileWidth, profileHeight, {
|
||||
fit: 'cover'
|
||||
})
|
||||
.toFormat('jpg')
|
||||
.jpeg({
|
||||
quality: profileQuality
|
||||
})
|
||||
.toFile(`./static/uploads/images/election/${imageName}`)
|
||||
await deleteCandidateImage(candidate);
|
||||
|
||||
/**
|
||||
* if exist old pic delete it from file
|
||||
*/
|
||||
if (candidate.profilePic) {
|
||||
const oldPic = `./static${candidate.profilePic}`;
|
||||
await uploadProcessedImage(
|
||||
image.data,
|
||||
imageName,
|
||||
profileWidth,
|
||||
profileHeight,
|
||||
profileQuality
|
||||
);
|
||||
|
||||
if (fs.existsSync(oldPic)) {
|
||||
fs.unlink(oldPic, (err) => {
|
||||
if (err) return res500(res, err?.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
candidate.profilePic = imageName;
|
||||
}
|
||||
|
||||
@@ -586,15 +563,7 @@ module.exports.deleteCandidate = [
|
||||
|
||||
if (!candidate) return res404(res, `کاندید مورد نظر پیدا نشد`);
|
||||
|
||||
if (candidate.profilePic) {
|
||||
const oldPic = `./static${candidate.profilePic}`;
|
||||
|
||||
if (fs.existsSync(oldPic)) {
|
||||
fs.unlink(oldPic, (err) => {
|
||||
if (err) return res500(res, err?.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
await deleteCandidateImage(candidate);
|
||||
|
||||
await targetElection.candidates.id(candidateId).remove();
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ const {
|
||||
body,
|
||||
validationResult
|
||||
} = require('express-validator');
|
||||
const sharp = require('sharp');
|
||||
const {
|
||||
_sr
|
||||
} = require('../plugins/serverResponses');
|
||||
@@ -14,7 +13,10 @@ const {
|
||||
isLatinCharactersWithSymbol,
|
||||
generateRandomDigits
|
||||
} = require('../plugins/controllersHelperFunctions');
|
||||
const fs = require('fs');
|
||||
const {
|
||||
deleteLinksImage,
|
||||
uploadProcessedImage,
|
||||
} = require('../plugins/linksImageStorage');
|
||||
|
||||
////// variables
|
||||
const profileWidth = 50;
|
||||
@@ -108,15 +110,13 @@ module.exports.addLinks = [
|
||||
}
|
||||
const imageName = `links_${Date.now()}_${createLinks._id}.${image.mimetype.split('/')[1]}`;
|
||||
try {
|
||||
const target = sharp(image.data)
|
||||
await target
|
||||
.resize(profileWidth, profileHeight, {
|
||||
fit: 'cover'
|
||||
})
|
||||
.jpeg({
|
||||
quality: profileQuality
|
||||
})
|
||||
.toFile(`./static/uploads/images/links/${imageName}`);
|
||||
await uploadProcessedImage(
|
||||
image.data,
|
||||
imageName,
|
||||
profileWidth,
|
||||
profileHeight,
|
||||
profileQuality
|
||||
);
|
||||
|
||||
createLinks.icon = imageName;
|
||||
|
||||
@@ -243,28 +243,15 @@ module.exports.updateLinks = [
|
||||
}
|
||||
const imageName = `links_${Date.now()}_${targetLinks._id}.${image.mimetype.split('/')[1]}`;
|
||||
try {
|
||||
const target = sharp(image.data)
|
||||
await target
|
||||
.resize(profileWidth, profileHeight, {
|
||||
fit: 'cover'
|
||||
})
|
||||
.jpeg({
|
||||
quality: profileQuality
|
||||
})
|
||||
.toFile(`./static/uploads/images/links/${imageName}`);
|
||||
await deleteLinksImage(targetLinks, 'icon');
|
||||
|
||||
/**
|
||||
* if exist old pic delete it from file
|
||||
*/
|
||||
if (targetLinks.icon) {
|
||||
var oldPic = `./static${targetLinks.icon}`;
|
||||
|
||||
if (fs.existsSync(oldPic)) {
|
||||
fs.unlink(oldPic, (err) => {
|
||||
if (err) return res500(res, err?.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
await uploadProcessedImage(
|
||||
image.data,
|
||||
imageName,
|
||||
profileWidth,
|
||||
profileHeight,
|
||||
profileQuality
|
||||
);
|
||||
|
||||
targetLinks.icon = imageName;
|
||||
targetLinks.linksStatus = true;
|
||||
@@ -312,15 +299,7 @@ module.exports.deletOneLinks = [
|
||||
return res500(res, `شما اجازه حذف این پیوند را ندارید`);
|
||||
}
|
||||
|
||||
if (targetLinks.icon) {
|
||||
var oldPic = `./static${targetLinks.icon}`;
|
||||
|
||||
if (fs.existsSync(oldPic)) {
|
||||
fs.unlink(oldPic, (error) => {
|
||||
if (error) return res500(res, error?.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
await deleteLinksImage(targetLinks, 'icon');
|
||||
|
||||
/** delete links */
|
||||
await targetLinks.deleteOne();
|
||||
|
||||
@@ -2,8 +2,10 @@ const Occasion = require('../models/Occasion');
|
||||
const {body, validationResult} = require('express-validator');
|
||||
const {_sr} = require('../plugins/serverResponses');
|
||||
const {res404, res500} = require('../plugins/controllersHelperFunctions');
|
||||
const fs = require('fs');
|
||||
const sharp = require('sharp');
|
||||
const {
|
||||
deleteOccasionImage,
|
||||
uploadProcessedImage,
|
||||
} = require('../plugins/occasionImageStorage');
|
||||
const moment = require('moment-jalaali');
|
||||
|
||||
////// variables
|
||||
@@ -63,16 +65,13 @@ module.exports.addOccasion = [
|
||||
}
|
||||
|
||||
const imageName = `occasion_${addOccasion._id}_${Date.now()}.jpg`;
|
||||
const target = sharp(image.data)
|
||||
await target
|
||||
.resize(occasionWidth, occasionHeight, {
|
||||
fit: 'cover'
|
||||
})
|
||||
.toFormat('jpg')
|
||||
.jpeg({
|
||||
quality: occasionQuality
|
||||
})
|
||||
.toFile(`./static/uploads/images/occasion/${imageName}`);
|
||||
await uploadProcessedImage(
|
||||
image.data,
|
||||
imageName,
|
||||
occasionWidth,
|
||||
occasionHeight,
|
||||
occasionQuality
|
||||
);
|
||||
|
||||
addOccasion.status = true;
|
||||
addOccasion.mainCover = imageName;
|
||||
@@ -132,26 +131,15 @@ module.exports.updateOccasion = [
|
||||
}
|
||||
|
||||
const imageName = `occasion_${targetOccasion._id}_${Date.now()}.jpg`;
|
||||
const target = sharp(image.data)
|
||||
await target
|
||||
.resize(occasionWidth, occasionHeight, {
|
||||
fit: 'cover'
|
||||
})
|
||||
.toFormat('jpg')
|
||||
.jpeg({
|
||||
quality: occasionQuality
|
||||
})
|
||||
.toFile(`./static/uploads/images/occasion/${imageName}`);
|
||||
await deleteOccasionImage(targetOccasion, 'mainCover');
|
||||
|
||||
if (targetOccasion.mainCover) {
|
||||
var oldPic = `./static${targetOccasion.mainCover}`;
|
||||
|
||||
if (fs.existsSync(oldPic)) {
|
||||
fs.unlink(oldPic, (err) => {
|
||||
if (err) return res500(res, err?.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
await uploadProcessedImage(
|
||||
image.data,
|
||||
imageName,
|
||||
occasionWidth,
|
||||
occasionHeight,
|
||||
occasionQuality
|
||||
);
|
||||
|
||||
targetOccasion.status = true;
|
||||
targetOccasion.mainCover = imageName;
|
||||
@@ -184,15 +172,7 @@ module.exports.deleteOccasion = [
|
||||
return res404(res, `مناسبت مورد نظر پیدا نشد`);
|
||||
}
|
||||
|
||||
if (targetOccasion.mainCover) {
|
||||
var oldPic = `./static${targetOccasion.mainCover}`;
|
||||
|
||||
if (fs.existsSync(oldPic)) {
|
||||
fs.unlink(oldPic, (err) => {
|
||||
if (err) return res500(res, err?.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
await deleteOccasionImage(targetOccasion, 'mainCover');
|
||||
|
||||
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 { _sr } = require("../plugins/serverResponses");
|
||||
const { checkValidations } = require("../plugins/controllersHelperFunctions");
|
||||
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 = [
|
||||
[
|
||||
body('title')
|
||||
.notEmpty().withMessage(_sr['fa'].required.title)
|
||||
],
|
||||
checkValidations(validationResult),
|
||||
async (req, res) => {
|
||||
try {
|
||||
const firstbook = [];
|
||||
|
||||
if (!req.files?.file) {
|
||||
return res.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 قابل قبول است' } } });
|
||||
}
|
||||
|
||||
const book = await Book.findById(req.body.bookId);
|
||||
const bookId = book ? book._id : null;
|
||||
|
||||
const data = { title: req.body.title };
|
||||
const file = req.files.file;
|
||||
const fileName = req.body.title.replace(Date.now(), '-') + '_' + Date.now() + '.pdf';
|
||||
const imageName = req.body.title.replace(Date.now(), '-') + '_' + Date.now();
|
||||
|
||||
const filePath = `./static/uploads/pdf/${fileName}`;
|
||||
|
||||
await file.mv(filePath);
|
||||
data.file = fileName;
|
||||
|
||||
const convertPromise = convertapi.convert('jpg', {
|
||||
File: filePath
|
||||
}, 'pdf');
|
||||
|
||||
const result = await convertPromise;
|
||||
const savedFiles = await result.saveFiles(`./static/uploads/books/${imageName}.jpeg`);
|
||||
|
||||
const imagePath = `https://ostan-mr.ir/uploads/books/${imageName}.jpeg`;
|
||||
firstbook.push(imagePath);
|
||||
|
||||
if (bookId) {
|
||||
const update = await Book.findByIdAndUpdate(
|
||||
{_id:bookId},
|
||||
{ $push: { slides: imagePath } },
|
||||
{ upsert: true }
|
||||
);
|
||||
return res.status(201).json({ msg: "اسلاید کتاب اضافه شد", Data: update });
|
||||
} else {
|
||||
const newBook = new Book({
|
||||
title: req.body.title,
|
||||
uri: `https://ostan-mr.ir/uploads/pdf/${fileName}`,
|
||||
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 });
|
||||
}
|
||||
[body("title").notEmpty().withMessage(_sr["fa"].required.title)],
|
||||
checkValidations(validationResult),
|
||||
async (req, res) => {
|
||||
let tmpDir;
|
||||
|
||||
try {
|
||||
const firstbook = [];
|
||||
|
||||
if (!req.files?.file) {
|
||||
return res
|
||||
.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 قابل قبول است" } } });
|
||||
}
|
||||
|
||||
const book = await Book.findById(req.body.bookId);
|
||||
const bookId = book ? book._id : null;
|
||||
|
||||
const file = req.files.file;
|
||||
const fileName =
|
||||
req.body.title.replace(Date.now(), "-") + "_" + Date.now() + ".pdf";
|
||||
const imageName =
|
||||
req.body.title.replace(Date.now(), "-") + "_" + Date.now();
|
||||
|
||||
const { url: pdfUrl } = await uploadPdf(file.data, fileName);
|
||||
|
||||
tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "book-"));
|
||||
const tmpPdfPath = path.join(tmpDir, fileName);
|
||||
await fs.writeFile(tmpPdfPath, file.data);
|
||||
|
||||
const result = await convertapi.convert(
|
||||
"jpg",
|
||||
{ File: tmpPdfPath },
|
||||
"pdf"
|
||||
);
|
||||
|
||||
const convertedResponse = await axios.get(result.files[0].url, {
|
||||
responseType: "arraybuffer",
|
||||
});
|
||||
const imagePath = await uploadBookSlide(
|
||||
Buffer.from(convertedResponse.data),
|
||||
imageName
|
||||
);
|
||||
firstbook.push(imagePath);
|
||||
|
||||
if (bookId) {
|
||||
const update = await Book.findByIdAndUpdate(
|
||||
{ _id: bookId },
|
||||
{ $push: { slides: imagePath } },
|
||||
{ upsert: true }
|
||||
);
|
||||
return res
|
||||
.status(201)
|
||||
.json({ msg: "اسلاید کتاب اضافه شد", Data: update });
|
||||
}
|
||||
|
||||
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 = [
|
||||
async (req, res,next) => {
|
||||
try {
|
||||
const Books = await Book.find({});
|
||||
return res.status(200).json({ Books });
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
async (req, res, next) => {
|
||||
try {
|
||||
const Books = await Book.find({});
|
||||
return res.status(200).json({ Books });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
module.exports.GetOne = [
|
||||
async (req, res,next) => {
|
||||
try {
|
||||
const id = req.params.id
|
||||
const book = await Book.findById(id);
|
||||
return res.status(200).json({ msg: book });
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
async (req, res, next) => {
|
||||
try {
|
||||
const id = req.params.id;
|
||||
const book = await Book.findById(id);
|
||||
return res.status(200).json({ msg: book });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
module.exports.DeleteOne = [
|
||||
async(req,res,next)=>{
|
||||
try {
|
||||
const book = await Book.deleteOne({_id:req.params.id})
|
||||
if(!book){
|
||||
return res.status(200).json({ msg: 'کتاب وجود ندارد ' });
|
||||
}
|
||||
return res.status(200).json({ msg: 'کتاب حذف شد' });
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
async (req, res, next) => {
|
||||
try {
|
||||
const book = await Book.findById(req.params.id);
|
||||
if (!book) {
|
||||
return res.status(200).json({ msg: "کتاب وجود ندارد " });
|
||||
}
|
||||
|
||||
const uri = book.get("uri", null, { getters: false });
|
||||
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,
|
||||
validationResult
|
||||
} = require('express-validator');
|
||||
const sharp = require('sharp');
|
||||
const {
|
||||
_sr
|
||||
} = require('../plugins/serverResponses');
|
||||
@@ -14,7 +13,10 @@ const {
|
||||
isLatinCharactersWithSymbol,
|
||||
generateRandomDigits
|
||||
} = require('../plugins/controllersHelperFunctions');
|
||||
const fs = require('fs');
|
||||
const {
|
||||
deleteSliderImage,
|
||||
uploadProcessedImage,
|
||||
} = require('../plugins/sliderImageStorage');
|
||||
|
||||
////// variables
|
||||
const profileWidth = 600;
|
||||
@@ -113,15 +115,13 @@ module.exports.addSlider = [
|
||||
}
|
||||
const imageName = `slider_${Date.now()}_${createSlider._id}.${image.mimetype.split('/')[1]}`;
|
||||
try {
|
||||
const target = sharp(image.data)
|
||||
await target
|
||||
.resize(profileWidth, profileHeight, {
|
||||
fit: 'cover'
|
||||
})
|
||||
.jpeg({
|
||||
quality: profileQuality
|
||||
})
|
||||
.toFile(`./static/uploads/images/slider/${imageName}`);
|
||||
await uploadProcessedImage(
|
||||
image.data,
|
||||
imageName,
|
||||
profileWidth,
|
||||
profileHeight,
|
||||
profileQuality
|
||||
);
|
||||
|
||||
createSlider.cover = imageName;
|
||||
|
||||
@@ -253,28 +253,15 @@ module.exports.updateSlider = [
|
||||
}
|
||||
const imageName = `slider_${Date.now()}_${targetSlider._id}.${image.mimetype.split('/')[1]}`;
|
||||
try {
|
||||
const target = sharp(image.data)
|
||||
await target
|
||||
.resize(profileWidth, profileHeight, {
|
||||
fit: 'cover'
|
||||
})
|
||||
.jpeg({
|
||||
quality: profileQuality
|
||||
})
|
||||
.toFile(`./static/uploads/images/slider/${imageName}`);
|
||||
await deleteSliderImage(targetSlider, "cover");
|
||||
|
||||
/**
|
||||
* if exist old pic delete it from file
|
||||
*/
|
||||
if (targetSlider.cover) {
|
||||
var oldPic = `./static${targetSlider.cover}`;
|
||||
|
||||
if (fs.existsSync(oldPic)) {
|
||||
fs.unlink(oldPic, (err) => {
|
||||
if (err) return res500(res, err?.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
await uploadProcessedImage(
|
||||
image.data,
|
||||
imageName,
|
||||
profileWidth,
|
||||
profileHeight,
|
||||
profileQuality
|
||||
);
|
||||
|
||||
targetSlider.cover = imageName;
|
||||
} catch (e) {
|
||||
@@ -322,15 +309,7 @@ module.exports.deletOneSlider = [
|
||||
return res500(res, `شما اجازه حذف این اسلایدر را ندارید`);
|
||||
}
|
||||
|
||||
if (targetSlider.cover) {
|
||||
var oldPic = `./static${targetSlider.cover}`;
|
||||
|
||||
if (fs.existsSync(oldPic)) {
|
||||
fs.unlink(oldPic, (error) => {
|
||||
if (error) return res500(res, error?.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
await deleteSliderImage(targetSlider, "cover");
|
||||
|
||||
/** delete slider */
|
||||
await targetSlider.deleteOne();
|
||||
|
||||
@@ -3,7 +3,6 @@ const {
|
||||
body,
|
||||
validationResult
|
||||
} = require('express-validator');
|
||||
const sharp = require('sharp');
|
||||
const {
|
||||
_sr
|
||||
} = require('../plugins/serverResponses');
|
||||
@@ -14,7 +13,10 @@ const {
|
||||
isLatinCharactersWithSymbol,
|
||||
generateRandomDigits
|
||||
} = require('../plugins/controllersHelperFunctions');
|
||||
const fs = require('fs');
|
||||
const {
|
||||
deleteSliderImage,
|
||||
uploadProcessedImage,
|
||||
} = require('../plugins/sliderImageStorage');
|
||||
|
||||
////// variables
|
||||
const profileWidth = 880;
|
||||
@@ -113,15 +115,13 @@ module.exports.addSlider = [
|
||||
}
|
||||
const imageName = `slider_${Date.now()}_${createSlider._id}.${image.mimetype.split('/')[1]}`;
|
||||
try {
|
||||
const target = sharp(image.data)
|
||||
await target
|
||||
.resize(profileWidth, profileHeight, {
|
||||
fit: 'cover'
|
||||
})
|
||||
.jpeg({
|
||||
quality: profileQuality
|
||||
})
|
||||
.toFile(`./static/uploads/images/slider/${imageName}`);
|
||||
await uploadProcessedImage(
|
||||
image.data,
|
||||
imageName,
|
||||
profileWidth,
|
||||
profileHeight,
|
||||
profileQuality
|
||||
);
|
||||
|
||||
createSlider.cover = imageName;
|
||||
|
||||
@@ -253,28 +253,15 @@ module.exports.updateSlider = [
|
||||
}
|
||||
const imageName = `slider_${Date.now()}_${targetSlider._id}.${image.mimetype.split('/')[1]}`;
|
||||
try {
|
||||
const target = sharp(image.data)
|
||||
await target
|
||||
.resize(profileWidth, profileHeight, {
|
||||
fit: 'cover'
|
||||
})
|
||||
.jpeg({
|
||||
quality: profileQuality
|
||||
})
|
||||
.toFile(`./static/uploads/images/slider/${imageName}`);
|
||||
await deleteSliderImage(targetSlider, "cover");
|
||||
|
||||
/**
|
||||
* if exist old pic delete it from file
|
||||
*/
|
||||
if (targetSlider.cover) {
|
||||
var oldPic = `./static${targetSlider.cover}`;
|
||||
|
||||
if (fs.existsSync(oldPic)) {
|
||||
fs.unlink(oldPic, (err) => {
|
||||
if (err) return res500(res, err?.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
await uploadProcessedImage(
|
||||
image.data,
|
||||
imageName,
|
||||
profileWidth,
|
||||
profileHeight,
|
||||
profileQuality
|
||||
);
|
||||
|
||||
targetSlider.cover = imageName;
|
||||
} catch (e) {
|
||||
@@ -322,15 +309,7 @@ module.exports.deletOneSlider = [
|
||||
return res500(res, `شما اجازه حذف این اسلایدر را ندارید`);
|
||||
}
|
||||
|
||||
if (targetSlider.cover) {
|
||||
var oldPic = `./static${targetSlider.cover}`;
|
||||
|
||||
if (fs.existsSync(oldPic)) {
|
||||
fs.unlink(oldPic, (error) => {
|
||||
if (error) return res500(res, error?.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
await deleteSliderImage(targetSlider, "cover");
|
||||
|
||||
/** delete slider */
|
||||
await targetSlider.deleteOne();
|
||||
|
||||
@@ -4,7 +4,6 @@ const { rateLimit } = require("express-rate-limit");
|
||||
const bcrypt = require("bcryptjs");
|
||||
const jwt = require("jsonwebtoken");
|
||||
const crypto = require("crypto");
|
||||
const sharp = require("sharp");
|
||||
const { secretKey } = require("./../authentication");
|
||||
const { _sr } = require("../plugins/serverResponses");
|
||||
const {
|
||||
@@ -14,7 +13,10 @@ const {
|
||||
isLatinCharactersWithSymbol,
|
||||
generateRandomDigits,
|
||||
} = require("../plugins/controllersHelperFunctions");
|
||||
const fs = require("fs");
|
||||
const {
|
||||
deleteUserImage,
|
||||
uploadProcessedImage,
|
||||
} = require("../plugins/userImageStorage");
|
||||
const nodemailer = require("nodemailer");
|
||||
const Category = require("../models/Category");
|
||||
const Logger = require("../models/Logger");
|
||||
@@ -566,15 +568,13 @@ module.exports.registerAdmin = [
|
||||
image.mimetype.split("/")[1];
|
||||
data.profilePic = imageName;
|
||||
try {
|
||||
const target = sharp(image.data);
|
||||
await target
|
||||
.resize(profileWidth, profileHeight, {
|
||||
fit: "cover",
|
||||
})
|
||||
.jpeg({
|
||||
quality: profileQuality,
|
||||
})
|
||||
.toFile(`./static/uploads/images/users/${imageName}`);
|
||||
await uploadProcessedImage(
|
||||
image.data,
|
||||
imageName,
|
||||
profileWidth,
|
||||
profileHeight,
|
||||
profileQuality
|
||||
);
|
||||
} catch (e) {
|
||||
return res500(res, e?.message);
|
||||
}
|
||||
@@ -713,18 +713,7 @@ module.exports.deleteOneUser = [
|
||||
.json({ message: `شما نمیتوانید این کاربر را حذف کنید` });
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
});
|
||||
}
|
||||
}
|
||||
await deleteUserImage(user, "profilePic");
|
||||
|
||||
/** delete user */
|
||||
await user.deleteOne();
|
||||
@@ -922,28 +911,15 @@ module.exports.updateUser = [
|
||||
image.mimetype.split("/")[1];
|
||||
|
||||
try {
|
||||
const target = sharp(image.data);
|
||||
await target
|
||||
.resize(profileWidth, profileHeight, {
|
||||
fit: "cover",
|
||||
})
|
||||
.jpeg({
|
||||
quality: profileQuality,
|
||||
})
|
||||
.toFile(`./static/uploads/images/users/${imageName}`);
|
||||
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);
|
||||
});
|
||||
}
|
||||
}
|
||||
await uploadProcessedImage(
|
||||
image.data,
|
||||
imageName,
|
||||
profileWidth,
|
||||
profileHeight,
|
||||
profileQuality
|
||||
);
|
||||
} catch (e) {
|
||||
return res500(res, e?.message);
|
||||
}
|
||||
@@ -1129,28 +1105,15 @@ module.exports.updateProfile = [
|
||||
image.mimetype.split("/")[1];
|
||||
|
||||
try {
|
||||
const target = sharp(image.data);
|
||||
await target
|
||||
.resize(profileWidth, profileHeight, {
|
||||
fit: "cover",
|
||||
})
|
||||
.jpeg({
|
||||
quality: profileQuality,
|
||||
})
|
||||
.toFile(`./static/uploads/images/users/${imageName}`);
|
||||
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);
|
||||
});
|
||||
}
|
||||
}
|
||||
await uploadProcessedImage(
|
||||
image.data,
|
||||
imageName,
|
||||
profileWidth,
|
||||
profileHeight,
|
||||
profileQuality
|
||||
);
|
||||
} catch (e) {
|
||||
return res500(res, e?.message);
|
||||
}
|
||||
|
||||
@@ -2,8 +2,7 @@ const YearBanner = require('../models/YearBanner');
|
||||
const {body, validationResult, checkSchema} = require('express-validator');
|
||||
const {_sr} = require('../plugins/serverResponses');
|
||||
const {res404, res500} = require('../plugins/controllersHelperFunctions');
|
||||
const fs = require('fs');
|
||||
const sharp = require('sharp');
|
||||
const {uploadProcessedImage} = require('../plugins/yearBannerImageStorage');
|
||||
|
||||
////// variables
|
||||
const yearBannerWidth = 1920
|
||||
@@ -51,12 +50,13 @@ module.exports.updateYearBanner = [
|
||||
|
||||
imageName = `mainPage_cover.jpg`;
|
||||
|
||||
const target = sharp(image.data)
|
||||
await target
|
||||
.resize(yearBannerWidth, yearBannerHeight, {fit: 'cover'})
|
||||
.toFormat('jpg')
|
||||
.jpeg({quality: yearBannerQuality})
|
||||
.toFile(`./static/uploads/images/mainCover/${imageName}`);
|
||||
await uploadProcessedImage(
|
||||
image.data,
|
||||
imageName,
|
||||
yearBannerWidth,
|
||||
yearBannerHeight,
|
||||
yearBannerQuality
|
||||
);
|
||||
}
|
||||
|
||||
if (yearBanner) {
|
||||
|
||||
+22
-7
@@ -1,16 +1,31 @@
|
||||
const mongoose = require('mongoose');
|
||||
const mongoosePaginate = require('mongoose-paginate-v2');
|
||||
const s3Storage = require('../plugins/s3Storage');
|
||||
|
||||
|
||||
function PDF(pdf) {
|
||||
if (pdf) return '/uploads/files/ReadOnly-PDF' + pdf
|
||||
function pdfUri(uri) {
|
||||
if (!uri) return null;
|
||||
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({
|
||||
title: String,
|
||||
uri: String,
|
||||
slides:{
|
||||
default:[],
|
||||
type:Array
|
||||
uri: { type: String, get: pdfUri, default: null },
|
||||
slides: {
|
||||
default: [],
|
||||
type: [String],
|
||||
get: (slides) => (slides || []).map(slideUrl),
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const mongoose = require("mongoose");
|
||||
const s3Storage = require("../plugins/s3Storage");
|
||||
|
||||
function autoPopulateSubs(next) {
|
||||
this.populate({
|
||||
@@ -14,12 +15,21 @@ function autoPopulateSubs(next) {
|
||||
}
|
||||
|
||||
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) {
|
||||
if (img) return "/uploads/images/category/" + img;
|
||||
else return "/img/no-cover.jpg";
|
||||
if (!img) 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({
|
||||
@@ -71,7 +81,7 @@ const CategorySchema = mongoose.Schema({
|
||||
managerName: String,
|
||||
managerDescription: String,
|
||||
/** if category was shafafiat this icon is for that */
|
||||
icon: String,
|
||||
icon: { type: String, get: shafafiatIcon, default: null },
|
||||
});
|
||||
|
||||
CategorySchema.index({ parent: 1, childs: 1 });
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
const mongoose = require('mongoose');
|
||||
const s3Storage = require('../plugins/s3Storage');
|
||||
|
||||
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 mongoosePaginate = require('mongoose-paginate-v2');
|
||||
const s3Storage = require('../plugins/s3Storage');
|
||||
|
||||
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({
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
const mongoose = require('mongoose');
|
||||
const s3Storage = require('../plugins/s3Storage');
|
||||
|
||||
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({
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
const mongoose = require('mongoose');
|
||||
const mongoosePaginate = require('mongoose-paginate-v2');
|
||||
const s3Storage = require('../plugins/s3Storage');
|
||||
|
||||
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({
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
const mongoose = require('mongoose');
|
||||
const mongoosePaginate = require('mongoose-paginate-v2');
|
||||
const s3Storage = require('../plugins/s3Storage');
|
||||
|
||||
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({
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
const mongoose = require('mongoose');
|
||||
const mongoosePaginate = require('mongoose-paginate-v2');
|
||||
const s3Storage = require('../plugins/s3Storage');
|
||||
|
||||
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({
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
const mongoose = require('mongoose');
|
||||
const s3Storage = require('../plugins/s3Storage');
|
||||
|
||||
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({
|
||||
|
||||
@@ -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