S3 : news controller
This commit is contained in:
@@ -9,14 +9,15 @@ const {
|
|||||||
const Category = require("../models/Category");
|
const Category = require("../models/Category");
|
||||||
const Comment = require("../models/Comment");
|
const Comment = require("../models/Comment");
|
||||||
const User = require("../models/User");
|
const User = require("../models/User");
|
||||||
const fs = require("fs");
|
|
||||||
const NewsFile = require("../models/NewsFile");
|
const NewsFile = require("../models/NewsFile");
|
||||||
const Polls = require("../models/Polls");
|
const Polls = require("../models/Polls");
|
||||||
const moment = require("moment-jalaali");
|
const moment = require("moment-jalaali");
|
||||||
const {
|
const {
|
||||||
getStoredImageName,
|
getStoredImageName,
|
||||||
deleteNewsImage,
|
deleteNewsImage,
|
||||||
|
deleteNewsAttachment,
|
||||||
uploadProcessedImage,
|
uploadProcessedImage,
|
||||||
|
uploadNewsAttachment,
|
||||||
} = require("../plugins/newsImageStorage");
|
} = require("../plugins/newsImageStorage");
|
||||||
|
|
||||||
////// variables
|
////// variables
|
||||||
@@ -463,112 +464,16 @@ module.exports.addNews = [
|
|||||||
* if we have pic upload to server
|
* if we have pic upload to server
|
||||||
*/
|
*/
|
||||||
if (req.files) {
|
if (req.files) {
|
||||||
let hasCover = false;
|
try {
|
||||||
let hasThumb = false;
|
await handleFileUploads(req, res, createNews);
|
||||||
const timestamp = Date.now();
|
await createNews.save();
|
||||||
|
} catch (error) {
|
||||||
if (req.files.cover) {
|
return res.status(422).json({
|
||||||
const image = req.files.cover;
|
validation: {
|
||||||
if (!validateNewsImage(image)) {
|
cover: { msg: error.message },
|
||||||
return res.status(422).json({
|
},
|
||||||
validation: {
|
});
|
||||||
cover: {
|
|
||||||
msg: _sr["fa"].format.image,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const imageName = `news_cover_${timestamp}_${createNews._id}.${
|
|
||||||
image.mimetype.split("/")[1]
|
|
||||||
}`;
|
|
||||||
try {
|
|
||||||
await processAndUploadNewsImage(
|
|
||||||
image.data,
|
|
||||||
imageName,
|
|
||||||
coverNewsWidth,
|
|
||||||
coverNewsHeight,
|
|
||||||
coverQuality
|
|
||||||
);
|
|
||||||
|
|
||||||
createNews.cover = imageName;
|
|
||||||
hasCover = true;
|
|
||||||
} catch (e) {
|
|
||||||
return res500(res, e?.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!req.files.thumbCover) {
|
|
||||||
const thumbImageName = `news_thumb_${timestamp}_${createNews._id}.${
|
|
||||||
image.mimetype.split("/")[1]
|
|
||||||
}`;
|
|
||||||
try {
|
|
||||||
await processAndUploadNewsImage(
|
|
||||||
image.data,
|
|
||||||
thumbImageName,
|
|
||||||
thumbCoverNewsWidth,
|
|
||||||
thumbCoverNewsHeight,
|
|
||||||
thumbCoverQuality
|
|
||||||
);
|
|
||||||
|
|
||||||
createNews.thumbCover = thumbImageName;
|
|
||||||
hasThumb = true;
|
|
||||||
} catch (e) {
|
|
||||||
return res500(res, e?.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.files.thumbCover) {
|
|
||||||
const image = req.files.thumbCover;
|
|
||||||
if (!validateNewsImage(image)) {
|
|
||||||
return res.status(422).json({
|
|
||||||
validation: {
|
|
||||||
thumbCover: {
|
|
||||||
msg: _sr["fa"].format.image,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const thumbImageName = `news_thumb_${timestamp}_${createNews._id}.${
|
|
||||||
image.mimetype.split("/")[1]
|
|
||||||
}`;
|
|
||||||
try {
|
|
||||||
await processAndUploadNewsImage(
|
|
||||||
image.data,
|
|
||||||
thumbImageName,
|
|
||||||
thumbCoverNewsWidth,
|
|
||||||
thumbCoverNewsHeight,
|
|
||||||
thumbCoverQuality
|
|
||||||
);
|
|
||||||
|
|
||||||
createNews.thumbCover = thumbImageName;
|
|
||||||
hasThumb = true;
|
|
||||||
} catch (e) {
|
|
||||||
return res500(res, e?.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!req.files.cover) {
|
|
||||||
const coverImageName = `news_cover_${timestamp}_${createNews._id}.${
|
|
||||||
image.mimetype.split("/")[1]
|
|
||||||
}`;
|
|
||||||
try {
|
|
||||||
await processAndUploadNewsImage(
|
|
||||||
image.data,
|
|
||||||
coverImageName,
|
|
||||||
coverNewsWidth,
|
|
||||||
coverNewsHeight,
|
|
||||||
coverQuality
|
|
||||||
);
|
|
||||||
|
|
||||||
createNews.cover = coverImageName;
|
|
||||||
hasCover = true;
|
|
||||||
} catch (e) {
|
|
||||||
return res500(res, e?.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
createNews.newsStatus = hasCover || hasThumb;
|
|
||||||
await createNews.save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -956,6 +861,11 @@ module.exports.deletOneNews = [
|
|||||||
await deleteNewsImage(targetNews, "cover");
|
await deleteNewsImage(targetNews, "cover");
|
||||||
await deleteNewsImage(targetNews, "thumbCover");
|
await deleteNewsImage(targetNews, "thumbCover");
|
||||||
|
|
||||||
|
for (const attachment of targetNews.attachments) {
|
||||||
|
const fileName = attachment.get("file", null, { getters: false });
|
||||||
|
await deleteNewsAttachment(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
await targetNews.deleteOne();
|
await targetNews.deleteOne();
|
||||||
|
|
||||||
await Comment.deleteMany({ modelRef: targetNews._id });
|
await Comment.deleteMany({ modelRef: targetNews._id });
|
||||||
@@ -970,13 +880,22 @@ module.exports.deletOneNews = [
|
|||||||
module.exports.deleteAllNews = [
|
module.exports.deleteAllNews = [
|
||||||
async (req, res) => {
|
async (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
const importedNews = await News.find({ imported: true });
|
||||||
|
|
||||||
|
for (const news of importedNews) {
|
||||||
|
await deleteNewsImage(news, "cover");
|
||||||
|
await deleteNewsImage(news, "thumbCover");
|
||||||
|
|
||||||
|
for (const attachment of news.attachments) {
|
||||||
|
const fileName = attachment.get("file", null, { getters: false });
|
||||||
|
await deleteNewsAttachment(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await News.deleteMany({ imported: true });
|
await News.deleteMany({ imported: true });
|
||||||
|
|
||||||
return res.json("ok");
|
return res.json("ok");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
/**
|
|
||||||
* if we got unkown error show to client
|
|
||||||
*/
|
|
||||||
return res500(res, error.message);
|
return res500(res, error.message);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1271,52 +1190,65 @@ module.exports.searchForSlider = [
|
|||||||
module.exports.addAttachmentToNews = [
|
module.exports.addAttachmentToNews = [
|
||||||
[body("attTitle").notEmpty().withMessage(_sr["fa"].required.title)],
|
[body("attTitle").notEmpty().withMessage(_sr["fa"].required.title)],
|
||||||
checkValidations(validationResult),
|
checkValidations(validationResult),
|
||||||
(req, res) => {
|
async (req, res) => {
|
||||||
if (!req.files?.file)
|
try {
|
||||||
return res
|
if (!req.files?.file) {
|
||||||
.status(422)
|
return res
|
||||||
.json({ validation: { file: { msg: _sr["fa"].required.file } } });
|
.status(422)
|
||||||
if (req.files?.file.mimetype.split("/")[1] !== "pdf")
|
.json({ validation: { file: { msg: _sr["fa"].required.file } } });
|
||||||
return res
|
}
|
||||||
.status(422)
|
|
||||||
.json({ validation: { file: { msg: "فقط فرمت PDF قابل قبول است" } } });
|
|
||||||
|
|
||||||
const data = { title: req.body.attTitle };
|
if (req.files.file.mimetype.split("/")[1] !== "pdf") {
|
||||||
const file = req.files.file;
|
return res
|
||||||
const fileName =
|
.status(422)
|
||||||
req.body.attTitle.replace(titleFilterRegex, "-") +
|
.json({ validation: { file: { msg: "فقط فرمت PDF قابل قبول است" } } });
|
||||||
"_" +
|
}
|
||||||
Date.now() +
|
|
||||||
".pdf";
|
|
||||||
file.mv(`./static/uploads/files/newsAttachments/${fileName}`);
|
|
||||||
data.file = fileName;
|
|
||||||
|
|
||||||
News.findById(req.params.newsId, (err, news) => {
|
const news = await News.findById(req.params.newsId);
|
||||||
if (err || !news) return res404(res, err);
|
if (!news) {
|
||||||
news.attachments.push(data);
|
return res404(res, "خبر مورد نظر پیدا نشد");
|
||||||
news.save((err) => {
|
}
|
||||||
if (err) return res500(res, err);
|
|
||||||
else return res.json({ message: _sr["fa"].response.success_save });
|
const fileName =
|
||||||
});
|
req.body.attTitle.replace(titleFilterRegex, "-") +
|
||||||
});
|
"_" +
|
||||||
|
Date.now() +
|
||||||
|
".pdf";
|
||||||
|
|
||||||
|
await uploadNewsAttachment(req.files.file.data, fileName);
|
||||||
|
|
||||||
|
news.attachments.push({ title: req.body.attTitle, file: fileName });
|
||||||
|
await news.save();
|
||||||
|
|
||||||
|
return res.json({ message: _sr["fa"].response.success_save });
|
||||||
|
} catch (error) {
|
||||||
|
return res500(res, error.message);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
module.exports.removeAttachmentFromNews = [
|
module.exports.removeAttachmentFromNews = [
|
||||||
(req, res) => {
|
async (req, res) => {
|
||||||
News.findOne({ "attachments._id": req.params.fileId }, (err, news) => {
|
try {
|
||||||
if (err || !news) return res404(res, err);
|
const news = await News.findOne({ "attachments._id": req.params.fileId });
|
||||||
const file = news.attachments.id(req.params.fileId);
|
if (!news) {
|
||||||
if (!file) return res404(res, "not found");
|
return res404(res, "not found");
|
||||||
file.remove();
|
}
|
||||||
fs.unlink(`./static/${file.file}`, (err) => {
|
|
||||||
if (err) console.log(err);
|
const attachment = news.attachments.id(req.params.fileId);
|
||||||
});
|
if (!attachment) {
|
||||||
news.save((err) => {
|
return res404(res, "not found");
|
||||||
if (err) return res500(res, err);
|
}
|
||||||
else return res.json({ message: _sr["fa"].response.success_remove });
|
|
||||||
});
|
const fileName = attachment.get("file", null, { getters: false });
|
||||||
});
|
attachment.remove();
|
||||||
|
await deleteNewsAttachment(fileName);
|
||||||
|
await news.save();
|
||||||
|
|
||||||
|
return res.json({ message: _sr["fa"].response.success_remove });
|
||||||
|
} catch (error) {
|
||||||
|
return res500(res, error.message);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -8,12 +8,14 @@ function image(img) {
|
|||||||
return s3Storage.getPublicUrl(`uploads/images/news/${img}`);
|
return s3Storage.getPublicUrl(`uploads/images/news/${img}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function file(file) {
|
function attachmentFile(file) {
|
||||||
return '/uploads/files/newsAttachments/' + file
|
if (!file) return null;
|
||||||
|
if (file.startsWith('http://') || file.startsWith('https://')) return file;
|
||||||
|
return s3Storage.getPublicUrl(`uploads/files/newsAttachments/${file}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const NewsAttachmentSchema = mongoose.Schema({
|
const NewsAttachmentSchema = mongoose.Schema({
|
||||||
file: {type: String, get: file},
|
file: {type: String, get: attachmentFile},
|
||||||
title: String
|
title: String
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ const sharp = require("sharp");
|
|||||||
const s3Storage = require("./s3Storage");
|
const s3Storage = require("./s3Storage");
|
||||||
|
|
||||||
const NEWS_IMAGE_PREFIX = "uploads/images/news";
|
const NEWS_IMAGE_PREFIX = "uploads/images/news";
|
||||||
|
const NEWS_ATTACHMENT_PREFIX = "uploads/files/newsAttachments";
|
||||||
|
|
||||||
const getStoredImageName = (doc, field) =>
|
const getStoredImageName = (doc, field) =>
|
||||||
doc.get(field, null, { getters: false });
|
doc.get(field, null, { getters: false });
|
||||||
@@ -38,9 +39,36 @@ const uploadProcessedImage = async (
|
|||||||
return imageName;
|
return imageName;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const uploadNewsAttachment = async (
|
||||||
|
fileData,
|
||||||
|
fileName,
|
||||||
|
contentType = "application/pdf"
|
||||||
|
) => {
|
||||||
|
await s3Storage.uploadBuffer(
|
||||||
|
`${NEWS_ATTACHMENT_PREFIX}/${fileName}`,
|
||||||
|
fileData,
|
||||||
|
contentType
|
||||||
|
);
|
||||||
|
|
||||||
|
return fileName;
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteNewsAttachment = async (fileName) => {
|
||||||
|
if (!fileName) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await s3Storage.deleteObject(`${NEWS_ATTACHMENT_PREFIX}/${fileName}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(`Failed to delete attachment from S3:`, error?.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
NEWS_IMAGE_PREFIX,
|
NEWS_IMAGE_PREFIX,
|
||||||
|
NEWS_ATTACHMENT_PREFIX,
|
||||||
getStoredImageName,
|
getStoredImageName,
|
||||||
deleteNewsImage,
|
deleteNewsImage,
|
||||||
uploadProcessedImage,
|
uploadProcessedImage,
|
||||||
|
uploadNewsAttachment,
|
||||||
|
deleteNewsAttachment,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user