S3 : add news

This commit is contained in:
2026-06-19 12:11:18 +03:30
parent 1c40eb958b
commit 99a9f9ace5
11 changed files with 1002 additions and 247 deletions
+86 -137
View File
@@ -1,6 +1,5 @@
const News = require("../models/News");
const { body, validationResult } = require("express-validator");
const sharp = require("sharp");
const { _sr } = require("../plugins/serverResponses");
const {
res404,
@@ -14,9 +13,13 @@ const fs = require("fs");
const NewsFile = require("../models/NewsFile");
const Polls = require("../models/Polls");
const moment = require("moment-jalaali");
const {
getStoredImageName,
deleteNewsImage,
uploadProcessedImage,
} = require("../plugins/newsImageStorage");
////// variables
const noCover = "/img/no-cover.jpg";
const coverNewsWidth = 1920;
const coverNewsHeight = 1080;
const coverQuality = 100;
@@ -111,31 +114,23 @@ const handleFileUploads = async (req, res, targetNews) => {
if (req.files.cover) {
const image = req.files.cover;
if (!_sr.supportedImageFormats.includes(image.mimetype.split("/")[1])) {
if (!validateNewsImage(image)) {
throw new Error(_sr["fa"].format.image);
}
// حذف کاور قدیمی در صورت وجود
if (targetNews.cover && targetNews.cover !== noCover) {
const oldCoverPath = `./static/uploads/images/news/${targetNews.cover}`;
if (fs.existsSync(oldCoverPath)) {
fs.unlinkSync(oldCoverPath);
}
}
await deleteNewsImage(targetNews, "cover");
const imageName = `news_cover_${timestamp}_${targetNews._id}.${
image.mimetype.split("/")[1]
}`;
try {
const target = sharp(image.data);
await target
.resize(coverNewsWidth, coverNewsHeight, {
fit: "cover",
})
.jpeg({
quality: coverQuality,
})
.toFile(`./static/uploads/images/news/${imageName}`);
await processAndUploadNewsImage(
image.data,
imageName,
coverNewsWidth,
coverNewsHeight,
coverQuality
);
targetNews.cover = imageName;
hasCover = true;
@@ -143,28 +138,20 @@ const handleFileUploads = async (req, res, targetNews) => {
throw new Error(e?.message);
}
// اگر thumbCover ارسال نشده، از همین تصویر thumbCover بسازیم
if (!req.files.thumbCover) {
if (targetNews.thumbCover && targetNews.thumbCover !== noCover) {
const oldThumbPath = `./static/uploads/images/news/${targetNews.thumbCover}`;
if (fs.existsSync(oldThumbPath)) {
fs.unlinkSync(oldThumbPath);
}
}
await deleteNewsImage(targetNews, "thumbCover");
const thumbImageName = `news_thumb_${timestamp}_${targetNews._id}.${
image.mimetype.split("/")[1]
}`;
try {
const target = sharp(image.data);
await target
.resize(thumbCoverNewsWidth, thumbCoverNewsHeight, {
fit: "cover",
})
.jpeg({
quality: thumbCoverQuality,
})
.toFile(`./static/uploads/images/news/${thumbImageName}`);
await processAndUploadNewsImage(
image.data,
thumbImageName,
thumbCoverNewsWidth,
thumbCoverNewsHeight,
thumbCoverQuality
);
targetNews.thumbCover = thumbImageName;
hasThumb = true;
@@ -176,31 +163,23 @@ const handleFileUploads = async (req, res, targetNews) => {
if (req.files.thumbCover) {
const image = req.files.thumbCover;
if (!_sr.supportedImageFormats.includes(image.mimetype.split("/")[1])) {
if (!validateNewsImage(image)) {
throw new Error(_sr["fa"].format.image);
}
// حذف thumb قدیمی در صورت وجود
if (targetNews.thumbCover && targetNews.thumbCover !== noCover) {
const oldThumbPath = `./static/uploads/images/news/${targetNews.thumbCover}`;
if (fs.existsSync(oldThumbPath)) {
fs.unlinkSync(oldThumbPath);
}
}
await deleteNewsImage(targetNews, "thumbCover");
const thumbImageName = `news_thumb_${timestamp}_${targetNews._id}.${
image.mimetype.split("/")[1]
}`;
try {
const target = sharp(image.data);
await target
.resize(thumbCoverNewsWidth, thumbCoverNewsHeight, {
fit: "cover",
})
.jpeg({
quality: thumbCoverQuality,
})
.toFile(`./static/uploads/images/news/${thumbImageName}`);
await processAndUploadNewsImage(
image.data,
thumbImageName,
thumbCoverNewsWidth,
thumbCoverNewsHeight,
thumbCoverQuality
);
targetNews.thumbCover = thumbImageName;
hasThumb = true;
@@ -208,28 +187,20 @@ const handleFileUploads = async (req, res, targetNews) => {
throw new Error(e?.message);
}
// اگر cover ارسال نشده، از همین تصویر cover بسازیم
if (!req.files.cover) {
if (targetNews.cover && targetNews.cover !== noCover) {
const oldCoverPath = `./static/uploads/images/news/${targetNews.cover}`;
if (fs.existsSync(oldCoverPath)) {
fs.unlinkSync(oldCoverPath);
}
}
await deleteNewsImage(targetNews, "cover");
const coverImageName = `news_cover_${timestamp}_${targetNews._id}.${
image.mimetype.split("/")[1]
}`;
try {
const target = sharp(image.data);
await target
.resize(coverNewsWidth, coverNewsHeight, {
fit: "cover",
})
.jpeg({
quality: coverQuality,
})
.toFile(`./static/uploads/images/news/${coverImageName}`);
await processAndUploadNewsImage(
image.data,
coverImageName,
coverNewsWidth,
coverNewsHeight,
coverQuality
);
targetNews.cover = coverImageName;
hasCover = true;
@@ -239,14 +210,24 @@ const handleFileUploads = async (req, res, targetNews) => {
}
}
// به‌روزرسانی وضعیت خبر - خبر کامل است اگر حداقل یکی از تصاویر آپلود شده باشد یا قبلاً موجود باشد
const currentHasCover = targetNews.cover && targetNews.cover !== noCover;
const currentHasThumb =
targetNews.thumbCover && targetNews.thumbCover !== noCover;
const currentHasCover = getStoredImageName(targetNews, "cover");
const currentHasThumb = getStoredImageName(targetNews, "thumbCover");
targetNews.newsStatus =
hasCover || hasThumb || currentHasCover || currentHasThumb;
};
const processAndUploadNewsImage = async (
imageData,
imageName,
width,
height,
quality
) => uploadProcessedImage(imageData, imageName, width, height, quality);
const validateNewsImage = (image) => {
return _sr.supportedImageFormats.includes(image.mimetype.split("/")[1]);
};
/////////////////////////////////////////////////////////////////////// admin
module.exports.addNews = [
[
@@ -488,9 +469,7 @@ module.exports.addNews = [
if (req.files.cover) {
const image = req.files.cover;
if (
!_sr.supportedImageFormats.includes(image.mimetype.split("/")[1])
) {
if (!validateNewsImage(image)) {
return res.status(422).json({
validation: {
cover: {
@@ -503,15 +482,13 @@ module.exports.addNews = [
image.mimetype.split("/")[1]
}`;
try {
const target = sharp(image.data);
await target
.resize(coverNewsWidth, coverNewsHeight, {
fit: "cover",
})
.jpeg({
quality: coverQuality,
})
.toFile(`./static/uploads/images/news/${imageName}`);
await processAndUploadNewsImage(
image.data,
imageName,
coverNewsWidth,
coverNewsHeight,
coverQuality
);
createNews.cover = imageName;
hasCover = true;
@@ -519,21 +496,18 @@ module.exports.addNews = [
return res500(res, e?.message);
}
// اگر thumbCover ارسال نشده، از همین تصویر thumbCover بسازیم
if (!req.files.thumbCover) {
const thumbImageName = `news_thumb_${timestamp}_${createNews._id}.${
image.mimetype.split("/")[1]
}`;
try {
const target = sharp(image.data);
await target
.resize(thumbCoverNewsWidth, thumbCoverNewsHeight, {
fit: "cover",
})
.jpeg({
quality: thumbCoverQuality,
})
.toFile(`./static/uploads/images/news/${thumbImageName}`);
await processAndUploadNewsImage(
image.data,
thumbImageName,
thumbCoverNewsWidth,
thumbCoverNewsHeight,
thumbCoverQuality
);
createNews.thumbCover = thumbImageName;
hasThumb = true;
@@ -545,9 +519,7 @@ module.exports.addNews = [
if (req.files.thumbCover) {
const image = req.files.thumbCover;
if (
!_sr.supportedImageFormats.includes(image.mimetype.split("/")[1])
) {
if (!validateNewsImage(image)) {
return res.status(422).json({
validation: {
thumbCover: {
@@ -560,15 +532,13 @@ module.exports.addNews = [
image.mimetype.split("/")[1]
}`;
try {
const target = sharp(image.data);
await target
.resize(thumbCoverNewsWidth, thumbCoverNewsHeight, {
fit: "cover",
})
.jpeg({
quality: thumbCoverQuality,
})
.toFile(`./static/uploads/images/news/${thumbImageName}`);
await processAndUploadNewsImage(
image.data,
thumbImageName,
thumbCoverNewsWidth,
thumbCoverNewsHeight,
thumbCoverQuality
);
createNews.thumbCover = thumbImageName;
hasThumb = true;
@@ -576,21 +546,18 @@ module.exports.addNews = [
return res500(res, e?.message);
}
// اگر cover ارسال نشده، از همین تصویر cover بسازیم
if (!req.files.cover) {
const coverImageName = `news_cover_${timestamp}_${createNews._id}.${
image.mimetype.split("/")[1]
}`;
try {
const target = sharp(image.data);
await target
.resize(coverNewsWidth, coverNewsHeight, {
fit: "cover",
})
.jpeg({
quality: coverQuality,
})
.toFile(`./static/uploads/images/news/${coverImageName}`);
await processAndUploadNewsImage(
image.data,
coverImageName,
coverNewsWidth,
coverNewsHeight,
coverQuality
);
createNews.cover = coverImageName;
hasCover = true;
@@ -600,7 +567,6 @@ module.exports.addNews = [
}
}
// خبر کامل است اگر حداقل یکی از تصاویر آپلود شده باشد
createNews.newsStatus = hasCover || hasThumb;
await createNews.save();
}
@@ -987,30 +953,13 @@ module.exports.deletOneNews = [
return res500(res, `شما اجازه حذف این خبر را ندارید`);
}
if (targetNews.cover !== noCover) {
oldPic = `./static${targetNews.cover}`;
if (fs.existsSync(oldPic)) {
fs.unlink(oldPic, (error) => {
if (error) return res500(res, error?.message);
});
}
}
if (targetNews.thumbCover !== noCover) {
oldPic = `./static${targetNews.thumbCover}`;
if (fs.existsSync(oldPic)) {
fs.unlink(oldPic, (error) => {
if (error) return res500(res, error?.message);
});
}
}
await deleteNewsImage(targetNews, "cover");
await deleteNewsImage(targetNews, "thumbCover");
await targetNews.deleteOne();
await Comment.deleteMany({ modelRef: targetNews._id });
x;
return res.json(targetNews);
} catch (error) {
return res500(res, error);
+35 -45
View File
@@ -4,11 +4,12 @@ const {_sr} = require('../plugins/serverResponses')
const {res404, res500} = require('../plugins/controllersHelperFunctions')
const News = require('../models/News')
const Category = require('../models/Category')
const sharp = require('sharp')
const fs = require('fs')
const {
deleteNewsImage,
uploadProcessedImage,
} = require('../plugins/newsImageStorage')
////// variables
const noCover = '/img/no-cover.jpg'
const limit = 5;
const limitDetails = 11;
const titleFilterRegex = new RegExp('/', 'g')
@@ -187,19 +188,23 @@ module.exports.addNewsFile = [
})
const imageName = `news_${Date.now()}_${createNewsFile._id}.${image.mimetype.split('/')[1]}`;
try {
const target = sharp(image.data)
await target
.resize(coverNewsWidth, coverNewsHeight, {fit: 'cover'})
.jpeg({quality: coverQuality})
.toFile(`./static/uploads/images/news/${imageName}`);
await uploadProcessedImage(
image.data,
imageName,
coverNewsWidth,
coverNewsHeight,
coverQuality
);
await uploadProcessedImage(
image.data,
`thumb_${imageName}`,
thumbCoverNewsWidth,
thumbCoverNewsHeight,
thumbCoverQuality
);
createNewsFile.cover = imageName;
await target
.resize(thumbCoverNewsWidth, thumbCoverNewsHeight, {fit: 'cover'})
.jpeg({quality: thumbCoverQuality})
.toFile(`./static/uploads/images/news/thumb_${imageName}`);
createNewsFile.thumbCover = `thumb_${imageName}`;
await createNewsFile.save();
@@ -375,39 +380,24 @@ module.exports.updateNewsFile = [
}
const imageName = `news_${Date.now()}_${targetNewsFile._id}.${image.mimetype.split('/')[1]}`;
try {
const target = sharp(image.data)
await target
.resize(coverNewsWidth, coverNewsHeight, {fit: 'cover'})
.jpeg({quality: coverQuality})
.toFile(`./static/uploads/images/news/${imageName}`);
await deleteNewsImage(targetNewsFile, "cover");
await deleteNewsImage(targetNewsFile, "thumbCover");
await target
.resize(thumbCoverNewsWidth, thumbCoverNewsHeight, {fit: 'cover'})
.jpeg({quality: thumbCoverQuality})
.toFile(`./static/uploads/images/news/thumb_${imageName}`);
await uploadProcessedImage(
image.data,
imageName,
coverNewsWidth,
coverNewsHeight,
coverQuality
);
/**
* if exist old pic delete it from file
*/
if (targetNewsFile.cover !== noCover) {
let oldPic = `./static${targetNewsFile.cover}`;
if (await fs.existsSync(oldPic)) {
fs.unlink(oldPic, (err) => {
if (err) return res500(res, err?.message);
});
}
}
if (targetNewsFile.thumbCover !== noCover) {
let oldPic = `./static${targetNewsFile.thumbCover}`;
if (await fs.existsSync(oldPic)) {
fs.unlink(oldPic, (err) => {
if (err) return res500(res, err?.message);
});
}
}
await uploadProcessedImage(
image.data,
`thumb_${imageName}`,
thumbCoverNewsWidth,
thumbCoverNewsHeight,
thumbCoverQuality
);
targetNewsFile.cover = imageName;
targetNewsFile.thumbCover = `thumb_${imageName}`;