Files
mahyargdz 0677918db7 fix cover
2025-07-21 12:45:40 +03:30

1968 lines
55 KiB
JavaScript

const Gallery = require("../models/Gallery");
const { body, validationResult } = require("express-validator");
const sharp = require("sharp");
const crypto = require("crypto");
const { _sr } = require("../plugins/serverResponses");
const { res404, res500 } = require("../plugins/controllersHelperFunctions");
const fs = require("fs");
const moment = require("moment-jalaali");
const Category = require("./../models/Category");
////// variables
const picsWidth = 1920;
const picsHeight = 1080;
const picsQuality = 100;
const limit = 5;
const thumbPicsWidth = 600;
const thumbPicsHeight = 300;
const thumbPicsQuality = 80;
const coverQuality = 100;
const coverWidth = 800;
const coverHeight = 600;
const thumbCoverWidth = 350;
const thumbCoverHeight = 262;
const thumbCoverQuality = 100;
const graphicWidth = 1920;
const graphicHeight = 1080;
const graphicQuality = 100;
const thumbGraphicWidth = 600;
const thumbGraphicHeight = 300;
const thumbGraphicQuality = 80;
const shortTitleFront = 150;
const shortTitlePanel = 20;
const shortSumTitle = 250;
const titleFilterRegex = new RegExp("/", "g");
/////// limit
const imageLimit = 2;
const graphicLimit = 5;
const videoLimit = 20;
////// functions
const _upload = async (fileType, file, galleryId, Hash) => {
try {
const fileName = `gallery_${galleryId}_${Date.now()}.${
file.mimetype.split("/")[1]
}`;
const uploadPath = `./static/uploads/${fileType}s/gallery/${fileName}`;
const thumbUploadPath = `./static/uploads/${fileType}s/gallery/thumb_${fileName}`;
switch (fileType) {
case "image":
try {
const target = sharp(file.data);
await target
.resize(picsWidth, picsHeight, {
fit: "cover",
})
.toFormat("jpg")
.jpeg({
quality: picsQuality,
})
.toFile(uploadPath);
await target
.resize(thumbPicsWidth, thumbPicsHeight, {
fit: "cover",
})
.toFormat("jpg")
.jpeg({
quality: thumbPicsQuality,
})
.toFile(thumbUploadPath);
} catch (error) {
console.log(error);
}
break;
case "graphic":
try {
const target = sharp(file.data);
await target
// .resize(graphicWidth, graphicHeight, {
// fit: 'cover'
// })
.toFormat("jpg")
.jpeg({
quality: graphicQuality,
})
.toFile(uploadPath);
await target
.resize(thumbGraphicWidth, thumbGraphicHeight, {
fit: "cover",
})
.toFormat("jpg")
.jpeg({
quality: thumbGraphicQuality,
})
.toFile(thumbUploadPath);
} catch (error) {
console.log(error);
}
break;
case "video":
await file.mv(uploadPath);
break;
}
return fileName;
} catch (error) {
console.log(error);
return null;
}
};
const _deleteOne = async (fileType, name) => {
try {
let targetFile = `./static/uploads/${fileType}s/gallery/${name}`;
let thumbTargetFile = `./static/uploads/${fileType}s/gallery/thumb_${name}`;
if (fs.existsSync(targetFile)) {
fs.unlink(targetFile, (err) => {
if (err) console.log(err);
});
if (fileType !== "video") {
fs.unlink(thumbTargetFile, (err) => {
if (err) console.log(err);
});
}
return name;
} else {
return null;
}
} catch (error) {
console.log(error);
return null;
}
};
const _deleteAll = async (galleryId, galleryType) => {
try {
const targetDir = `./static/uploads/${galleryType}s/gallery/`;
const getFiles = fs.readdirSync(targetDir);
for (const file of getFiles) {
if (file.includes(galleryId)) {
fs.unlink(`./static/uploads/${galleryType}s/gallery/${file}`, (err) => {
if (err) console.log(err);
});
}
}
} catch (error) {
console.log(error);
}
};
const _deleteCover = async (galleryId) => {
try {
const targetDir = `./static/uploads/images/gallery/`;
const getFiles = fs.readdirSync(targetDir);
for (const file of getFiles) {
if (file.includes(galleryId) && file.includes("cover")) {
fs.unlink(`./static/uploads/images/gallery/${file}`, (err) => {
if (err) console.log(err);
});
}
}
} catch (error) {
console.log(err);
}
};
const _randomGallery = async (queryObject) => {
let setSkip;
try {
let temp = [];
const result = [];
/** total of gallery */
const count = await Gallery.countDocuments(queryObject);
if (count < 4) {
return await Gallery.find(queryObject);
}
/** get random index number */
while (temp.length < 4) {
setSkip = Math.floor(Math.random() * count);
temp.push(setSkip);
/** remove duplicate numbers */
temp = [...new Set(temp)];
}
/** get news and push to result */
for (let i = 0; i < 4; i++) {
const getGalley = await Gallery.findOne(queryObject).skip(temp[i]);
if (getGalley) {
result.push(getGalley);
}
}
/** return result */
return result;
} catch (error) {
console.log(error);
/** return error */
return [];
}
};
const _checkSpecPermission = async (req, category) => {
return (
!req.user.specialPermissions.includes(category._id) && //check parent id exist in special permissions or not
!req.user.specialPermissions.some((item) =>
category?.treeCat?.join().includes(item)
)
);
};
/////////////////////////////////////////////////////////////////////// admin
module.exports.addGallery = [
[
body("title")
.notEmpty()
.withMessage(_sr["fa"].required.title)
.custom((value, { req }) => {
return Gallery.findOne({ title: value }).then((gallery) => {
if (gallery) return Promise.reject(_sr["fa"].duplicated.title);
else return true;
});
}),
// body('summaryTitle')
// .notEmpty().withMessage(_sr['fa'].required.caption),
body("leadTitle").notEmpty().withMessage(_sr["fa"].required.caption),
body("catId")
.isMongoId()
.withMessage(_sr["fa"].required.field)
.if((value, { req }) => {
return req.body.catId;
})
.custom((value) => {
return Category.findOne({
_id: value,
}).then((category) => {
if (!category) return Promise.reject(_sr["fa"].not_found.category);
else return true;
});
}),
body("priority").isNumeric().withMessage(_sr["fa"].format.number),
body("showInHome").isBoolean().withMessage(_sr["fa"].format.boolean),
body("special").isBoolean().withMessage(_sr["fa"].format.boolean),
body("siteMap")
.optional()
.isBoolean()
.withMessage(_sr["fa"].format.boolean),
body("isEmbedded").isBoolean().withMessage(_sr["fa"].format.boolean),
body("publish").isBoolean().withMessage(_sr["fa"].format.boolean),
body("galleryType")
.notEmpty()
.withMessage(_sr["fa"].required.field)
.bail()
.isIn(["image", "video", "graphic"])
.withMessage(
`${_sr["fa"].optional.onlyValid} => 'image' , 'video' , 'graphic`
),
body("keywords")
.if((value) => {
return value;
})
.custom((value) => {
const keywords = _.isString(value) ? JSON.parse(value) : value;
if (!_.isArray(keywords)) {
return Promise.reject(`این فیلد باید به صورت آرایه فرستاده شود`);
}
return true;
}),
body("modelType").custom((value, { req }) => {
if (req.user.portals.join() === portal.join()) {
if (!portal.includes(value)) {
return Promise.reject(_sr["fa"].required.field);
} else {
return true;
}
} else {
return true;
}
}),
// body('metaTagDesc')
// .notEmpty().withMessage(_sr['fa'].required.field),
body("newsFileId")
.optional()
.isMongoId()
.withMessage(`لطفا یک ای دی صحیح ارسال کنید`),
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty())
return res.status(422).json({
validation: errors.mapped(),
});
try {
let {
title,
summaryTitle,
leadTitle,
isEmbedded,
catId,
priority,
showInHome,
special,
siteMap,
publish,
galleryType,
modelType,
keywords,
metaTagDesc,
newsFileId,
favorite,
} = req.body;
/** this code fix problem with array in form data */
keywords = _.isString(keywords) ? JSON.parse(keywords) : keywords;
/** set portals */
modelType =
req.user.portals.join() === portal.join()
? modelType
: req.user.portals[0];
const galleryData = {
title: title?.trim()?.replace(titleFilterRegex, "-"),
summaryTitle: summaryTitle?.trim(),
leadTitle,
catId,
isEmbedded,
newsFileId,
priority,
showInHome,
special,
siteMap,
publish,
galleryType,
keywords,
metaTagDesc: metaTagDesc ? metaTagDesc?.trim() : leadTitle?.trim(),
favorite,
_creator: req.user._id,
modelType,
shortTitleFront: title?.trim()?.slice(0, shortTitleFront),
shortTitlePanel: title?.trim()?.slice(0, shortTitlePanel),
shortSummaryTitle: summaryTitle?.trim()?.slice(0, shortSumTitle),
};
if (catId) {
/** get category with populate parent */
const category = await Category.findOne({
_id: catId,
}).populate({
path: "parent",
populate: {
path: "parent",
model: "Category",
},
});
/** if undefined we have error from database */
if (!category)
return res404(res, `دسته بندی انتخاب شده برای این خبر پیدا نشد`);
/** check special permission */
if (
req.user.specialPermissions.length &&
(await _checkSpecPermission(req, category))
) {
return res.status(403).json({
message: `شما نمیتوانید این دسته بندی را انتخاب کنید`,
});
}
if (category.modelType !== modelType) {
return res.status(403).json({
message: `شما اجازه استفاده از این دسته بندی را ندارید`,
});
}
galleryData.allCat = category.treeCat;
galleryData.rootParent = category.rootParent || category._id;
}
if (special) {
const getSpecGallery = await Gallery.find({ special, modelType });
if (getSpecGallery.length) {
for (const item of getSpecGallery) {
item.special = false;
await item.save();
}
}
}
var createGallery = await Gallery.create(galleryData);
if (!createGallery) {
return res500(res, `مشکلی در اجرای درخواست شما پیش آمده است`);
}
/**
* show result
*/
return res.json(createGallery);
} catch (error) {
console.log(error);
/**
* if we got unkown error show to client
*/
res500(res, error.message);
}
},
];
module.exports.updateGallery = [
[
body("title").notEmpty().withMessage(_sr["fa"].required.title),
// body('summaryTitle')
// .notEmpty().withMessage(_sr['fa'].required.caption),
body("leadTitle").notEmpty().withMessage(_sr["fa"].required.caption),
body("catId")
.isMongoId()
.withMessage(_sr["fa"].required.field)
.if((value, { req }) => {
return req.body.catId;
})
.custom((value) => {
return Category.findOne({
_id: value,
}).then((category) => {
if (!category) return Promise.reject(_sr["fa"].not_found.category);
else return true;
});
}),
// body('priority')
// .isNumeric().withMessage(_sr['fa'].format.number),
body("showInHome").isBoolean().withMessage(_sr["fa"].format.boolean),
body("special").isBoolean().withMessage(_sr["fa"].format.boolean),
body("isEmbedded").isBoolean().withMessage(_sr["fa"].format.boolean),
body("embeddedCode").custom((value, { req }) => {
if (JSON.parse(req.body.isEmbedded) && _.isEmpty(value)) {
return Promise.reject(_sr["fa"].required.field);
} else {
return true;
}
}),
body("siteMap")
.optional()
.isBoolean()
.withMessage(_sr["fa"].format.boolean),
body("publish").isBoolean().withMessage(_sr["fa"].format.boolean),
body("newsFileId")
.optional()
.isMongoId()
.withMessage(`لطفا یک ای دی صحیح ارسال کنید`),
body("galleryType")
.notEmpty()
.withMessage(_sr["fa"].required.field)
.bail()
.isIn(["image", "video", "graphic"])
.withMessage(
`${_sr["fa"].optional.onlyValid} => 'image' , 'video' , 'graphic`
),
body("keywords")
.if((value) => {
return value;
})
.custom((value) => {
const keywords = _.isString(value) ? JSON.parse(value) : value;
if (!_.isArray(keywords)) {
return Promise.reject(`این فیلد باید به صورت آرایه فرستاده شود`);
}
return true;
}),
// body('metaTagDesc')
// .notEmpty().withMessage(_sr['fa'].required.field),
body("modelType").custom((value, { req }) => {
if (req.user.portals.join() === portal.join()) {
if (!portal.includes(value)) {
return Promise.reject(_sr["fa"].required.field);
} else {
return true;
}
} else {
return true;
}
}),
body("customDate")
.optional()
.isString()
.withMessage(`لطفا یک تاریخ صحیح وارد نمایید`),
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty())
return res.status(422).json({
validation: errors.mapped(),
});
try {
/**
* get data from input
*/
let {
title,
summaryTitle,
leadTitle,
catId,
isEmbedded,
embeddedCode,
priority,
showInHome,
special,
siteMap,
publish,
galleryType,
modelType,
keywords,
metaTagDesc,
customDate,
newsFileId,
favorite,
} = req.body;
/** this code fix problem with array in form data */
keywords = _.isString(keywords) ? JSON.parse(keywords) : keywords;
/**
* get id
*/
let galleryId = req.params.id;
let targetGallery = await Gallery.findOne({ _id: galleryId });
if (!targetGallery) {
return res404(res, `گالری مورد نظر پیدا نشد`);
}
if (!req.user.portals.includes(targetGallery.modelType)) {
return res500(res, `شما اجازه آپدیت این گالری را ندارید`);
}
if (targetGallery.title !== title) {
var checkDuppTitle = await Gallery.findOne({
title: title,
});
if (checkDuppTitle) {
return res.status(422).json({
validation: { title: { msg: _sr["fa"].duplicated.title } },
});
}
}
if (targetGallery.galleryType !== galleryType) {
await _deleteAll(targetGallery._id, targetGallery.galleryType);
targetGallery.images = [];
targetGallery.thumbImages = [];
targetGallery.video = null;
targetGallery.graphic = null;
targetGallery.thumbGraphic = null;
targetGallery.galleryType = galleryType;
targetGallery.galleryStatus = false;
}
/** get category with populate parent */
var category = await Category.findOne({
_id: catId,
}).populate({
path: "parent",
populate: {
path: "parent",
model: "Category",
},
});
/** if undefined we have error from database */
if (!category)
return res404(res, `دسته بندی انتخاب شده برای این رسانه پیدا نشد`);
/** check special permission */
if (
req.user.specialPermissions.length &&
(await _checkSpecPermission(req, category))
) {
return res.status(403).json({
message: `شما مجاز به انتخاب این دسته بندی نمی باشید`,
});
}
if (category.modelType !== modelType) {
return res.status(403).json({
message: `محدوده انتخاب شده شما با محدوده دسته بندی همخوانی ندارد`,
});
}
if (catId && targetGallery.catId !== catId) {
targetGallery.allCat = category.treeCat;
targetGallery.rootParent = category.rootParent || category._id;
}
if (isEmbedded === "true" && galleryType === "video") {
await _deleteOne(galleryType, targetGallery.video);
targetGallery.video = null;
targetGallery.galleryStatus = false;
}
if (special) {
const getSpecGallery = await Gallery.find({ special, modelType });
if (getSpecGallery.length) {
for (const item of getSpecGallery) {
item.special = false;
await item.save();
}
}
}
targetGallery.title = title?.trim()?.replace(titleFilterRegex, "-");
targetGallery.summaryTitle = summaryTitle?.trim();
targetGallery.leadTitle = leadTitle;
targetGallery.isEmbedded = isEmbedded;
targetGallery.embeddedCode = embeddedCode;
if (!_.isEmpty(embeddedCode) && targetGallery.galleryType === "video")
targetGallery.galleryStatus = true;
targetGallery.catId = catId;
// targetGallery.priority = priority;
targetGallery.showInHome = showInHome;
targetGallery.special = special;
targetGallery.siteMap = siteMap;
targetGallery.publish = publish;
targetGallery.modelType = modelType;
targetGallery.keywords = keywords;
targetGallery.metaTagDesc = metaTagDesc?.trim() || leadTitle?.trim();
targetGallery.favorite = favorite;
targetGallery.shortTitleFront = title?.slice(0, shortTitleFront);
targetGallery.shortTitlePanel = title?.slice(0, shortTitlePanel);
targetGallery.shortSummaryTitle = summaryTitle
?.trim()
.slice(0, shortSumTitle);
targetGallery.customDate = customDate || targetGallery.created_at;
targetGallery.newsFileId = newsFileId;
targetGallery._updatedBy = req.user._id;
if (customDate)
targetGallery.customDateHistory.push({
customDate,
_updatedBy: req.user._id,
});
await targetGallery.save();
/**
* show result
*/
return res.json(targetGallery);
} catch (error) {
return res500(res, error.message);
}
},
];
module.exports.deletOneGallery = [
async (req, res) => {
try {
var galleryId = req.params.id;
var targetGallery = await Gallery.findOne({ _id: galleryId });
/** check gallery exist or not */
if (!targetGallery) {
return res404(res, `گالری مورد نظر پیدا نشد`);
}
if (!req.user.portals.includes(targetGallery.modelType)) {
return res500(res, `شما اجازه پاک کردن این گالری را ندارید`);
}
await _deleteAll(targetGallery._id, targetGallery.galleryType);
await _deleteCover(targetGallery._id);
/** delete gallery */
await targetGallery.deleteOne();
/**
* show result
*/
return res.json(targetGallery);
} catch (error) {
/**
* if we got unkown error show to client
*/
return res500(res, error);
}
},
];
module.exports.getOneGallery = [
async (req, res) => {
try {
var galleryId = req.params.id;
// var findQuery = req.user.portals.length == 2 ? {_id : galleryId} : {_id : galleryId , modelType : req.user.portals[0]};
var gallery = await Gallery.findOne({ _id: galleryId }).populate("catId");
if (!gallery) {
return res404(res, `گالری مورد نظر پیدا نشد`);
}
if (!req.user.portals.includes(gallery.modelType)) {
return res500(res, `شما اجازه دسترسی به اطلاعات این گالری را ندارید`);
}
/**
* show result
*/
return res.json(gallery);
} catch (error) {
/**
* if we got unkown error show to client
*/
res500(res, error);
}
},
];
module.exports.getAll = [
async (req, res) => {
try {
var findQuery =
req.user.portals.join() === portal.join()
? {}
: { modelType: req.user.portals[0] };
// @todo can change it
if (req.user.specialPermissions.length) {
findQuery.catId = { $in: req.user.specialPermissions };
}
/** get all gallery */
var allGallery = await Gallery.paginate(findQuery, {
page: req.query.page,
limit,
populate: [
{
path: "_creator",
select: {
firstName: 1,
lastName: 1,
profilePic: 1,
},
},
{ path: "catId" },
],
sort: {
customDate: -1,
},
});
/** if null we have error */
if (!allGallery) {
return res500(
res,
`مشکلی در گرفتن گالری ها پیش آمده لطفا با پشتیبانی تماس بگیرید`
);
}
/** show result to client */
return res.json(allGallery);
} catch (error) {
/** if we have unknown error show it */
return res500(res, error.message);
}
},
];
module.exports.search = [
async (req, res) => {
try {
let findQuery = {};
findQuery["$and"] = [];
findQuery["$or"] = [];
if (req.user.portals.length) {
findQuery.modelType = {
$in: req.user.portals,
};
}
var {
term,
catId,
showInHome,
portals,
galleryStatus,
publish,
galleryType,
date,
} = req.body;
/** search by term */
if (term && !_.isEmpty(term)) {
findQuery["$or"].push({
title: {
$regex: ".*" + term + ".*",
},
});
}
/** search by catId */
if (req.user.specialPermissions.length) {
findQuery.catId = { $in: req.user.specialPermissions };
} else if (catId && !_.isEmpty(catId)) {
findQuery["$and"].push({
catId,
});
}
/** search by galleryType */
if (galleryType && !_.isEmpty(galleryType)) {
findQuery["$and"].push({
galleryType,
});
}
/** search by publish */
if (!_.isUndefined(publish) && _.isBoolean(publish)) {
findQuery["$and"].push({
publish,
});
}
/** search by portals */
if (req.user.portals.length) {
findQuery.modelType = {
$in: req.user.portals,
};
} else if (portals && !_.isEmpty(portals)) {
findQuery["$and"].push({
modelType: {
$in: portals,
},
});
}
/** search by galleryStatus */
if (!_.isUndefined(galleryStatus) && _.isBoolean(galleryStatus)) {
findQuery["$and"].push({
galleryStatus,
});
}
/** search by date */
if (date && !_.isEmpty(date)) {
if (date.length === 1) {
findQuery["$and"].push({
created_at: {
$gte: moment(date[0]).startOf("days"),
$lt: moment(date[0]).endOf("days"),
},
});
} else {
findQuery["$and"].push({
created_at: {
$gte: new Date(date[0]),
$lt: new Date(date[1]),
},
});
}
}
_.isEmpty(findQuery["$and"]) && delete findQuery["$and"];
_.isEmpty(findQuery["$or"]) && delete findQuery["$or"];
/** get gallery */
var gallery = await Gallery.paginate(findQuery, {
page: req.query.page,
limit,
populate: [
{
path: "_creator",
select: {
firstName: 1,
lastName: 1,
profilePic: 1,
},
},
{ path: "catId" },
],
sort: {
customDate: -1,
},
});
/** show result */
return res.json(gallery);
} catch (error) {
return res500(res, error?.message);
}
},
];
/////////////////////////////////////////////////////////////////////// manage gallery files
/// Develope
module.exports.uploadPDF = [
[
body("title").notEmpty().withMessage(_sr["fa"].required.title).bail(),
body("pdf").notEmpty().withMessage(_sr["fa"].required.field).bail(),
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({
validation: errors.mapped(),
});
}
try {
const { title, pdf } = req.body;
if (!req.files || !req.files.file) {
return res.status(422).json({
validation: { file: { msg: `لطفا یک فایل ارسال کنید` } },
});
}
const file = req.files.file;
const mb = file.size / (1024 * 1024);
if (fileType === "image" && mb > imageLimit) {
return res.status(422).json({
validation: {
file: { msg: `${_sr["fa"].max_char.data_size} 5 مگابایت` },
},
});
}
if (fileType === "graphic" && mb > graphicLimit) {
return res.status(422).json({
validation: {
file: { msg: `${_sr["fa"].max_char.data_size} 10 مگابایت` },
},
});
}
if (fileType === "video" && mb > videoLimit) {
return res.status(422).json({
validation: {
file: { msg: `${_sr["fa"].max_char.data_size} 50 مگابایت` },
},
});
}
if (
fileType === "image" &&
!_sr.supportedImageFormats.includes(file.mimetype.split("/")[1])
) {
return res.status(422).json({
validation: { file: { msg: _sr["fa"].format.image } },
});
}
if (
fileType === "video" &&
!_sr.supportedVideoFormats.includes(file.mimetype.split("/")[1])
) {
return res.status(422).json({
validation: { file: { msg: _sr["fa"].format.video } },
});
}
if (!req.user.portals.includes(targetGallery.modelType)) {
return res
.status(500)
.json({ msg: `شما اجازه آپلود فایل برای این گالری را ندارید` });
}
if (targetGallery.galleryType !== fileType) {
return res.status(422).json({
validation: {
file: {
msg: `شما اجازه آپلود فایل با تایپ متفاوت از گالری ندارید`,
},
},
});
}
const fileName = await _upload(fileType, file, targetGallery._id);
switch (fileType) {
case "image":
targetGallery.uidImage.push(fileHash);
targetGallery.images.push(fileName);
targetGallery.thumbImages.push(`thumb_${fileName}`);
break;
case "video":
if (
targetGallery.video &&
(await fs.existsSync(`./static/${targetGallery?.video}`))
) {
fs.unlink(`./static/${targetGallery.video}`, (err) => {
if (err) return res.status(500).json({ msg: err.message });
});
}
targetGallery.video = fileName;
break;
case "graphic":
if (
targetGallery.graphic &&
(await fs.existsSync(`./static/${targetGallery?.graphic}`))
) {
fs.unlink(`./static/${targetGallery.graphic}`, (err) => {
if (err) return res.status(500).json({ msg: err.message });
});
fs.unlink(`./static/${targetGallery.thumbGraphic}`, (err) => {
if (err) return res.status(500).json({ msg: err.message });
});
}
targetGallery.graphic = fileName;
targetGallery.thumbGraphic = `thumb_${fileName}`;
break;
}
targetGallery.galleryStatus = Boolean(targetGallery.cover);
targetGallery._updatedBy = req.user._id;
targetGallery.imageNames = req.files.file;
await targetGallery.save();
const gallery = await Gallery.findById(targetGallery._id);
return res.json(gallery);
} catch (error) {
console.log(error.message);
return res.status(500).json({ msg: error.message });
}
},
];
module.exports.uploadFile = [
[
body("galleryId")
.notEmpty()
.withMessage(_sr["fa"].required.title)
.bail()
.custom((value, { req }) => {
return Gallery.findOne({ _id: value }).then((gallery) => {
if (!gallery) return Promise.reject(_sr["fa"].not_found.item_id);
else return true;
});
}),
body("fileType")
.notEmpty()
.withMessage(_sr["fa"].required.field)
.bail()
.isIn(["image", "video", "graphic"])
.withMessage(
`${_sr["fa"].optional.onlyValid} => 'image' , 'video' , 'graphic'`
),
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({
validation: errors.mapped(),
});
}
try {
const { galleryId, fileType } = req.body;
if (!req.files || !req.files.file) {
return res.status(422).json({
validation: { file: { msg: `لطفا یک فایل ارسال کنید` } },
});
}
const file = req.files.file;
const fileBuffer = file.data;
const fileHash = crypto
.createHash("md5")
.update(fileBuffer)
.digest("hex");
const targetGallery = await Gallery.findOne({ _id: galleryId });
if (!targetGallery) {
return res.status(404).json({ msg: `گالری پیدا نشد` });
}
const Hash = targetGallery.uidImage.map((path) =>
path.replace("/uploads/images/gallery/", "")
);
if (Hash.includes(fileHash)) {
return res.status(200).json({ msg: `این فایل قبلا بارگذاری شده` });
}
const mb = file.size / (1024 * 1024);
if (fileType === "image" && mb > imageLimit) {
return res.status(422).json({
validation: {
file: { msg: `${_sr["fa"].max_char.data_size} 5 مگابایت` },
},
});
}
if (fileType === "graphic" && mb > graphicLimit) {
return res.status(422).json({
validation: {
file: { msg: `${_sr["fa"].max_char.data_size} 10 مگابایت` },
},
});
}
if (fileType === "video" && mb > videoLimit) {
return res.status(422).json({
validation: {
file: { msg: `${_sr["fa"].max_char.data_size} 50 مگابایت` },
},
});
}
if (
fileType === "image" &&
!_sr.supportedImageFormats.includes(file.mimetype.split("/")[1])
) {
return res.status(422).json({
validation: { file: { msg: _sr["fa"].format.image } },
});
}
if (
fileType === "video" &&
!_sr.supportedVideoFormats.includes(file.mimetype.split("/")[1])
) {
return res.status(422).json({
validation: { file: { msg: _sr["fa"].format.video } },
});
}
if (!req.user.portals.includes(targetGallery.modelType)) {
return res
.status(500)
.json({ msg: `شما اجازه آپلود فایل برای این گالری را ندارید` });
}
if (targetGallery.galleryType !== fileType) {
return res.status(422).json({
validation: {
file: {
msg: `شما اجازه آپلود فایل با تایپ متفاوت از گالری ندارید`,
},
},
});
}
const fileName = await _upload(fileType, file, targetGallery._id);
switch (fileType) {
case "image":
targetGallery.uidImage.push(fileHash);
targetGallery.images.push(fileName);
targetGallery.thumbImages.push(`thumb_${fileName}`);
break;
case "video":
if (
targetGallery.video &&
(await fs.existsSync(`./static/${targetGallery?.video}`))
) {
fs.unlink(`./static/${targetGallery.video}`, (err) => {
if (err) return res.status(500).json({ msg: err.message });
});
}
targetGallery.video = fileName;
break;
case "graphic":
if (
targetGallery.graphic &&
(await fs.existsSync(`./static/${targetGallery?.graphic}`))
) {
fs.unlink(`./static/${targetGallery.graphic}`, (err) => {
if (err) return res.status(500).json({ msg: err.message });
});
fs.unlink(`./static/${targetGallery.thumbGraphic}`, (err) => {
if (err) return res.status(500).json({ msg: err.message });
});
}
targetGallery.graphic = fileName;
targetGallery.thumbGraphic = `thumb_${fileName}`;
break;
}
// Update the uidImage with the new fileHash
targetGallery.galleryStatus = Boolean(targetGallery.cover);
targetGallery._updatedBy = req.user._id;
targetGallery.imageNames = req.files.file;
await targetGallery.save();
const gallery = await Gallery.findById(targetGallery._id);
/**
* show result
*/
return res.json(gallery);
} catch (error) {
console.log(error.message);
/**
* if we got unknown error show to client
*/
return res.status(500).json({ msg: error.message });
}
},
];
// module.exports.uploadFile = [
// [
// body('galleryId')
// .notEmpty().withMessage(_sr['fa'].required.title)
// .bail()
// .custom((value, {req}) => {
// return Gallery.findOne({_id: value})
// .then(gallery => {
// if (!gallery) return Promise.reject(_sr['fa'].not_found.item_id);
// else return true
// })
// }),
// body('fileType')
// .notEmpty().withMessage(_sr['fa'].required.field)
// .bail()
// .isIn(['image', 'video', 'graphic']).withMessage(`${_sr['fa'].optional.onlyValid} => 'image' , 'video' , 'graphic'`),
//
// ],
// async (req, res) => {
//
// const errors = validationResult(req)
// if (!errors.isEmpty()) return res.status(422).json({
// validation: errors.mapped()
// });
//
// try {
// let {
// galleryId,
// fileType,
// } = req.body;
//
// if (!req.files || !req.files.file) {
// return res.status(422).json({
// validation: {file: {msg: `لطفا یک فایل ارسال کنید`}}
// });
// }
//
// var file = req.files.file;
// const fileBuffer = file.data;
// const fileHash = crypto.createHash('md5').update(fileBuffer).digest('hex');
//
// const ImageValid = await Gallery.findOne({ _id: galleryId });
// if (!ImageValid) return res404(res, `گالری پیدا نشد`);
//
// const existingFileHashes = ImageValid.fileHashes || [];
// if (existingFileHashes.includes(fileHash)) {
// return res.status(422).json({
// validation: { file: { msg: `این فایل قبلاً آپلود شده است` } }
// });
// }
// /** start convert byte to mb */
// var mb = file.size / (1024 * 1024);
//
// /** check limit size of image */
// if (fileType === 'image' && mb > imageLimit) {
// return res.status(422).json({
// validation: {file: {msg: `${_sr['fa'].max_char.data_size} 5 مگابایت`}}
// });
// }
//
// /** check limit size of graphics */
// if (fileType === 'graphic' && mb > graphicLimit) {
// return res.status(422).json({
// validation: {file: {msg: `${_sr['fa'].max_char.data_size} 10 مگابایت`}}
// });
// }
//
// /** check limit size of video */
// if (fileType === 'video' && mb > videoLimit) {
// return res.status(422).json({
// validation: {file: {msg: `${_sr['fa'].max_char.data_size} 50 مگابایت`}}
// });
// }
//
// /** check format of image */
// if (fileType === 'image' && !_sr.supportedImageFormats.includes(file.mimetype.split('/')[1])) {
// return res.status(422).json({
// validation: {file: {msg: _sr['fa'].format.image}}
// });
// }
//
// /** check format of video */
// if (fileType === 'video' && !_sr.supportedVideoFormats.includes(file.mimetype.split('/')[1])) {
// return res.status(422).json({
// validation: {file: {msg: _sr['fa'].format.video}}
// });
// }
//
// var targetGallery = await Gallery.findOne({_id: galleryId});
//
//
// if (!targetGallery) return res404(res, `گالری پیدا نشد`);
//
// /** check portal type */
// if (!req.user.portals.includes(targetGallery.modelType)) {
// return res500(res, `شما اجازه آپلود فایل برای این گالری را ندارید`);
// }
//
// /** check type of input with gallery type */
// if (targetGallery.galleryType !== fileType) {
// return res.status(422).json({
// validation: {file: {msg: `شما اجازه آپلود فایل با تایپ متفاوت از گالری ندارید`}}
// });
// }
//
// /** upload pic or video get name */
// var fileName = await _upload(fileType, file, targetGallery._id);
//
//
// // if(fileType == 'image'){
// // targetGallery.images.push(fileName);
// // targetGallery.thumbImages.push(`thumb_${fileName}`);
// // }else{
// // if(targetGallery.video){
// // fs.unlink(`./static/${targetGallery.video}`, (err) => {
// // if (err) res500(res , err.message);
// // });
// // }
// // targetGallery.video = fileName;
// // }
//
// switch (fileType) {
// case 'image':
// targetGallery.images.push(fileName);
// targetGallery.thumbImages.push(`thumb_${fileName}`);
// break;
// case 'video':
// if (targetGallery.video && await fs.existsSync(`./static/${targetGallery?.video}`)) {
// fs.unlink(`./static/${targetGallery.video}`, (err) => {
// if (err) return res500(res, err.message);
// });
// }
// targetGallery.video = fileName;
// break;
// case 'graphic':
// if (targetGallery.graphic && await fs.existsSync(`./static/${targetGallery?.graphic}`)) {
// fs.unlink(`./static/${targetGallery.graphic}`, (err) => {
// if (err) return res500(res, err.message);
// });
// fs.unlink(`./static/${targetGallery.thumbGraphic}`, (err) => {
// if (err) return res500(res, err.message);
// });
// }
// targetGallery.graphic = fileName;
// targetGallery.thumbGraphic = `thumb_${fileName}`;
// break;
// }
//
// targetGallery.galleryStatus = Boolean(targetGallery.cover);
// targetGallery._updatedBy = req.user._id;
// targetGallery.imageNames = req.files.file
// await targetGallery.save();
//
// var gallery = await Gallery.findById(targetGallery._id);
//
// /**
// * show result
// */
// return res.json(gallery);
// } catch (error) {
// console.log(error.message);
// /**
// * if we got unkown error show to client
// */
// return res500(res, error.message);
// }
// }
// ]
module.exports.deleteFile = [
[
body("galleryId")
.notEmpty()
.withMessage(_sr["fa"].required.title)
.bail()
.custom((value, { req }) => {
return Gallery.findOne({ _id: value }).then((gallery) => {
if (!gallery) return Promise.reject(_sr["fa"].not_found.item_id);
else return true;
});
}),
body("name").notEmpty().withMessage(_sr["fa"].required.field),
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty())
return res.status(422).json({
validation: errors.mapped(),
});
try {
const { galleryId, name } = req.body;
const targetGallery = await Gallery.findOne({ _id: galleryId }).lean();
if (!targetGallery) return res404(res, `گالری مورد نظر پیدا نشد`);
/** check portal type */
if (!req.user.portals.includes(targetGallery.modelType))
return res500(res, `شما اجازه حذف فایل برای این گالری را ندارید`);
if (
(targetGallery.images.length === 0 &&
targetGallery.galleryType === "image") ||
(!targetGallery.video && targetGallery.galleryType === "video")
)
return res404(res, `عکس یا فیلم درخواست شده پیدا نشد`);
let deleteFile = await _deleteOne(targetGallery.galleryType, name);
// if (!deleteFile) return res404(res, `عکس درخواست شده پیدا نشد`);
/** update gallery after delete file */
let imageArr = [];
if (
targetGallery.galleryType === "image" ||
targetGallery.galleryType === "graphic"
) {
let index = targetGallery.images.findIndex((item) => {
return item.includes(deleteFile || name);
});
if (index > -1) {
targetGallery.images.splice(index, 1);
targetGallery.thumbImages.splice(index, 1);
}
} else {
targetGallery.video = null;
}
targetGallery.galleryStatus = !!targetGallery.images.length;
var gallery = await Gallery.findByIdAndUpdate(
targetGallery._id,
targetGallery,
{ new: true }
);
/**
* show result
*/
return res.json(gallery);
} catch (error) {
console.log(error);
/**
* if we got unkown error show to client
*/
return res500(res, error.message);
}
},
];
// module.exports.uploadCover = [
// [
// body('galleryId')
// .notEmpty().withMessage(_sr['fa'].required.title)
// .bail()
// .custom((value, {req}) => {
// return Gallery.findOne({_id: value})
// .then(gallery => {
// if (!gallery) return Promise.reject(_sr['fa'].not_found.item_id);
// else return true
// })
// }),
// ],
// async (req, res) => {
//
// const errors = validationResult(req)
// if (!errors.isEmpty()) return res.status(422).json({
// validation: errors.mapped()
// });
//
// try {
// const {
// galleryId,
// } = req.body;
//
// if (!req.files || !req.files.file) {
// return res.status(422).json({
// validation: {file: {msg: `لطفا یک فایل ارسال کنید`}}
// });
// }
//
// const file = req.files.file;
//
// /** start convert byte to mb */
// const mb = file.size ;
//
// /** check limit size of image */
// if (mb > 5) {
// return res.status(422).json({
// validation: {file: {msg: `${_sr['fa'].max_char.data_size} 5 مگابایت`}}
// });
// }
//
// /** check format of image */
// if (!_sr.supportedImageFormats.includes(file.mimetype.split('/')[1])) {
// return res.status(422).json({
// validation: {file: {msg: _sr['fa'].format.image}}
// });
// }
//
// let targetGallery = await Gallery.findOne({_id: galleryId});
//
//
// if (!targetGallery) {
// return res404(res, `گالری پیدا نشد`);
// }
//
// /** check portal type */
// if (!req.user.portals.includes(targetGallery.modelType)) {
// return res500(res, `شما اجازه آپلود فایل برای این گالری را ندارید`);
// }
//
// const imageName = `cover_gallery_${Date.now()}_${targetGallery._id}.jpg`;
// const thumbImg = `thumb_${imageName}`;
// try {
// const target = sharp(file.data)
// await target
// .resize(coverWidth, coverHeight, {
// fit: 'cover'
// })
// .toFormat('jpg')
// .jpeg({
// quality: coverQuality
// })
// .toFile(`./static/uploads/images/gallery/${imageName}`);
//
// await target
// .resize(thumbCoverWidth, thumbCoverHeight, {
// fit: 'cover'
// })
// .toFormat('jpg')
// .jpeg({
// quality: thumbCoverQuality
// })
// .toFile(`./static/uploads/images/gallery/${thumbImg}`);
//
//
// /**
// * if exist old pic delete it from file
// */
// if (targetGallery.cover) {
// let oldPic = `./static${targetGallery.cover}`;
//
// if (fs.existsSync(oldPic)) {
// fs.unlink(oldPic, (err) => {
// if (err) return res500(res, err?.message);
// });
// }
// }
//
// if (targetGallery.thumbCover) {
// let oldPic = `./static${targetGallery.thumbCover}`;
//
// if (fs.existsSync(oldPic)) {
// fs.unlink(oldPic, (err) => {
// if (err) return res500(res, err?.message);
// });
// }
// }
//
// targetGallery.cover = imageName;
// targetGallery.thumbCover = thumbImg;
//
// targetGallery.galleryStatus = targetGallery.images.length ||
// targetGallery.video ||
// targetGallery.graphic ? true : false;
//
// } catch (e) {
// return res500(res, e?.message);
// }
//
// await targetGallery.save();
//
// const gallery = await Gallery.findById(targetGallery._id);
//
// /**
// * show result
// */
// return res.json(gallery);
// } catch (error) {
// console.log(error);
// /**
// * if we got unkown error show to client
// */
// return res500(res, error.message);
// }
// }
// ]
// Prod
//Develope
module.exports.uploadCover = [
[
body("galleryId")
.notEmpty()
.withMessage(_sr["fa"].required.title)
.bail()
.isMongoId()
.withMessage("آی دی گالری نامعتبر است")
.bail()
.custom(async (value, { req }) => {
try {
const gallery = await Gallery.findById(value);
if (!gallery) {
return Promise.reject(_sr["fa"].not_found.item_id);
}
return true;
} catch (error) {
return Promise.reject("آی دی گالری نامعتبر است");
}
}),
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({
validation: errors.mapped(),
});
}
try {
const { galleryId } = req.body;
// Debug logging
console.log("galleryId received:", galleryId);
console.log("req.body:", req.body);
if (!galleryId) {
return res.status(422).json({
validation: { galleryId: { msg: `آی دی گالری الزامی است` } },
});
}
if (!req.files || !req.files.file) {
return res.status(422).json({
validation: { file: { msg: `لطفا یک فایل ارسال کنید` } },
});
}
const file = req.files.file;
// Find the gallery record with better error handling
let targetGallery;
try {
targetGallery = await Gallery.findById(galleryId);
console.log("targetGallery found:", !!targetGallery);
} catch (dbError) {
console.error("Database error:", dbError);
return res.status(422).json({
validation: { galleryId: { msg: `آی دی گالری نامعتبر است` } },
});
}
if (!targetGallery) {
return res404(res, `گالری پیدا نشد`);
}
// Check if user object exists and has portals
if (!req.user || !req.user.portals) {
return res.status(401).json({ message: `اطلاعات کاربری نامعتبر است` });
}
/** check portal type */
if (!req.user.portals.includes(targetGallery.modelType)) {
return res500(res, `شما اجازه آپلود فایل برای این گالری را ندارید`);
}
/** start convert byte to mb */
const mb = file.size / (1024 * 1024); // Convert bytes to megabytes
/** check limit size of image */
if (mb > 5) {
return res.status(422).json({
validation: {
file: { msg: `${_sr["fa"].max_char.data_size} 5 مگابایت` },
},
});
}
/** check format of image */
if (!_sr.supportedImageFormats.includes(file.mimetype.split("/")[1])) {
return res.status(422).json({
validation: { file: { msg: _sr["fa"].format.image } },
});
}
const imageName = `cover_gallery_${Date.now()}_${targetGallery._id}.jpg`;
const thumbImg = `thumb_${imageName}`;
try {
const target = sharp(file.data);
await target
.resize(coverWidth, coverHeight, {
fit: "cover",
})
.toFormat("jpg")
.jpeg({
quality: coverQuality,
})
.toFile(`./static/uploads/images/gallery/${imageName}`);
await target
.resize(thumbCoverWidth, thumbCoverHeight, {
fit: "cover",
})
.toFormat("jpg")
.jpeg({
quality: thumbCoverQuality,
})
.toFile(`./static/uploads/images/gallery/${thumbImg}`);
/**
* if exist old pic delete it from file
*/
if (targetGallery.cover) {
let oldPic = `./static/uploads/images/gallery/${targetGallery.cover}`;
if (fs.existsSync(oldPic)) {
fs.unlink(oldPic, (err) => {
if (err) console.log("Error deleting old cover:", err);
});
}
}
if (targetGallery.thumbCover) {
let oldThumbPic = `./static/uploads/images/gallery/${targetGallery.thumbCover}`;
if (fs.existsSync(oldThumbPic)) {
fs.unlink(oldThumbPic, (err) => {
if (err) console.log("Error deleting old thumb cover:", err);
});
}
}
// Update gallery record with new cover images
targetGallery.cover = imageName;
targetGallery.thumbCover = thumbImg;
targetGallery.galleryStatus =
Boolean(targetGallery.cover) ||
Boolean(targetGallery.images?.length) ||
Boolean(targetGallery.video) ||
Boolean(targetGallery.graphic);
targetGallery._updatedBy = req.user._id;
await targetGallery.save();
// Return the updated gallery
const gallery = await Gallery.findById(targetGallery._id);
return res.json(gallery);
} catch (e) {
return res500(res, e?.message);
}
} catch (error) {
console.log(error);
return res500(res, error.message);
}
},
];
////////////////////////////////////////////////////////////////////// get gallery
module.exports.getGalleryPublic = [
async (req, res) => {
try {
const { type, page } = req.query;
const catId = req.params.catId;
const findQuery = {};
findQuery.galleryType = type;
findQuery.galleryStatus = true;
findQuery.catId = catId;
let setLimit = 9;
const getGallery = await Gallery.paginate(findQuery, {
page: page || 1,
limit: setLimit,
populate: {
path: "_creator",
select: "firstName lastName",
},
sort: { customDate: -1 },
});
const favorites = await Gallery.find({ ...findQuery, favorite: true });
const result = {
all: getGallery,
favorites: favorites,
};
return res.json(result);
} catch (error) {
return res500(res, error?.message);
}
},
];
module.exports.GetArchive = [
async (req, res) => {
try {
const Archive = await Gallery.find({ images: { $exists: true } });
res.status(200).json(Archive);
} catch (e) {
res.status(500).json({ msg: e.message });
}
},
];
module.exports.getAllGallery = [
async (req, res) => {
try {
const { type, page, portal } = req.query;
let findQuery = {};
findQuery.galleryType = type;
findQuery.galleryStatus = true;
findQuery.publish = true;
findQuery.modelType = portal;
let setLimit = 13;
const getGallery = await Gallery.paginate(findQuery, {
page: page || 1,
limit: setLimit,
populate: {
path: "_creator",
select: "firstName lastName",
},
sort: { customDate: -1 },
});
const favorites = await Gallery.find({
...findQuery,
favorite: true,
}).sort({ customDate: -1 });
const hero = await Gallery.findOne({ ...findQuery, special: true }).sort({
customDate: -1,
});
const result = {
all: getGallery,
hero: hero,
favorites: favorites,
};
return res.json(result);
} catch (error) {
return res500(res, error?.message);
}
},
];
module.exports.viewGallery = [
async (req, res) => {
try {
const galleryTitle = req.params.title;
let targetGallery = await Gallery.findOne({
_id: galleryTitle,
galleryStatus: true,
publish: true,
}).populate("_creator", { firstName: 1, lastName: 1, profilePic: 1 });
if (!targetGallery) {
return res404(res, `گالری مورد نطر پیدا نشد`);
}
++targetGallery.userViews;
await targetGallery.save();
return res.json(targetGallery);
} catch (error) {
return res500(res, error?.message);
}
},
];
module.exports.getRelated = [
async (req, res) => {
try {
const { type, title } = req.query;
const targetGallery = await Gallery.findById(title);
if (!targetGallery) {
return res.json([]);
}
let findQuery = {};
findQuery.galleryType = type;
findQuery._id = {
$ne: title,
};
findQuery.galleryStatus = true;
findQuery.publish = true;
const getGallery = await Gallery.find(findQuery)
.populate({
path: "_creator",
select: "firstName lastName",
})
.limit(4)
.sort({
customDate: -1,
});
return res.json(getGallery);
} catch (error) {
return res500(res, error?.message);
}
},
];