S3 for other controolers

This commit is contained in:
2026-06-19 15:47:02 +03:30
parent c73027540a
commit e95883eb6a
32 changed files with 1073 additions and 650 deletions
+81 -133
View File
@@ -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);
}
},
];
+34 -55
View File
@@ -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;
+63 -63
View File
@@ -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})
+22 -53
View File
@@ -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();
+20 -41
View File
@@ -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();
+20 -40
View File
@@ -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();
+130 -91
View File
@@ -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);
}
]
},
];
+20 -41
View File
@@ -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();
+20 -41
View File
@@ -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();
+28 -65
View File
@@ -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);
}
+8 -8
View File
@@ -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) {