Files
ostandari/server/controllers/newsController.js
T
2024-10-21 10:22:26 +03:30

1475 lines
48 KiB
JavaScript

const News = require('../models/News');
const {body, validationResult} = require('express-validator');
const sharp = require('sharp');
const {_sr} = require('../plugins/serverResponses');
const {res404, res500, checkValidations} = require('../plugins/controllersHelperFunctions');
const Category = require('../models/Category');
const Comment = require('../models/Comment');
const User = require('../models/User')
const fs = require('fs');
const NewsFile = require('../models/NewsFile');
const Polls = require('../models/Polls');
const moment = require('moment-jalaali');
////// variables
const noCover = '/img/no-cover.jpg'
const coverNewsWidth = 1920;
const coverNewsHeight = 1080;
const coverQuality = 100;
const thumbCoverNewsWidth = 600;
const thumbCoverNewsHeight = 300;
const thumbCoverQuality = 100;
const limit = 20;
const newsPerPageLimit = 16;
const galleryPerPageLimit = 5;
const shortTitleFront = 150
const shortTitlePanel = 20
const shortSumTitle = 250
const titleFilterRegex = new RegExp('/', 'g')
// helper functions
const changePriority = async (catId, modelType) => {
try {
const getAllNews = await News.find({
catId,
modelType,
priority: true
});
for (const item of getAllNews) {
item.priority = false;
await item.save();
}
return true
} catch (error) {
console.log(error)
return false
}
}
const randomNews = async (queryObject) => {
let setSkip;
try {
let temp = [];
const result = [];
/** total of news */
const count = await News.countDocuments(queryObject);
if (count < 3) {
return await News.find(queryObject);
}
/** get random index number */
while (temp.length < 3) {
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 < 3; i++) {
const getNews = await News.findOne(queryObject).skip(temp[i]);
if (getNews) {
result.push(getNews);
}
}
/** 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.addNews = [
[
body('title')
.notEmpty().withMessage(_sr['fa'].required.title)
.custom((value) => {
return News.findOne({
title: value
})
.then(news => {
if (news) 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')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('allowComment')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('showInHome')
.isBoolean().withMessage(_sr['fa'].format.boolean),
body('notifications')
.isBoolean().withMessage(_sr['fa'].format.boolean),
// body('slider')
// .optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('special')
.isBoolean().withMessage(_sr['fa'].format.boolean),
body('siteMap')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('publish')
.isBoolean().withMessage(_sr['fa'].format.boolean),
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')
.optional(),
body('modelType')
.custom((value, {
req
}) => {
if (req.user.portals.join() === portal.join()) {
if (!portal.includes(value)) {
return Promise.reject(`${_sr['fa'].optional.onlyValid} => ${portal}`);
} else {
return true
}
} else {
return true
}
}),
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,
catId,
PublisherId,
priority,
allowComment,
showInHome,
special,
notifications,
siteMap,
publish,
pageContent,
content,
keywords,
metaTagDesc,
modelType,
// slider,
newsFileId
} = req.body;
keywords = _.isString(keywords) ? JSON.parse(keywords) : keywords;
/** set portals */
modelType = (req.user.portals.join() === portal.join()) ? modelType : req.user.portals[0];
// const isPublisher = await User.findById(PublisherId)
// if(!isPublisher){
// return res.status(404).json({message:"کاربر وجود ندارد"})
// }
// if(!isPublisher.scope.includes('PublisherNews')){
// return res.status(401).json({message:"شما دسترسی برای انتشار را ندارید"})
// }
if (newsFileId) {
let checkNewsFile = await NewsFile.findOne({
_id: newsFileId
});
if (!checkNewsFile) {
return res404(res, `پرونده خبری انخاب شده وجود ندارد`);
}
if (checkNewsFile.modelType !== modelType) {
return res.status(422).json({
validation: {
newsFileId: {
msg: `نوع خبر مورد نظر با نوع پرونده خبری متفاوت است`
}
}
});
}
}
const newsData = {
title: title?.trim()?.replace(titleFilterRegex, '/'),
summaryTitle: summaryTitle?.trim(),
leadTitle: leadTitle?.trim(),
catId,
priority,
showInHome,
publish,
pageContent,
PublisherId,
special,
content,
allowComment,
notifications,
siteMap,
keywords,
// slider,
_creator: req.user._id,
_updatedBy: req.user._id,
metaTagDesc: metaTagDesc ? metaTagDesc : leadTitle,
modelType,
newsFileId,
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: `شما اجازه استفاده از این دسته بندی را ندارید`
});
}
newsData.allCat = category.treeCat;
newsData.rootParent = category.rootParent || category._id;
if (priority === 'true') {
await changePriority(category._id, modelType);
}
}
const createNews = await News.create(newsData);
if (!createNews) {
return res500(res, `error in add news to data base`);
}
/**
* if we have pic upload to server
*/
if (req.files) {
let flagCover = false
let flagThumb = false
if (req.files.cover) {
const image = req.files.cover;
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({
validation: {
cover: {
msg: _sr['fa'].format.image
}
}
});
}
const imageName = `news_${Date.now()}_${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/${imageName}`);
createNews.cover = imageName;
flagCover = true
} catch (e) {
return res500(res, e?.message);
}
if (!req.files.thumbCover){
const imageName = `news_${Date.now()}_${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/thumb_${imageName}`);
createNews.thumbCover = `thumb_${imageName}`;
flagThumb = true
} catch (e) {
return res500(res, e?.message);
}
}
}
if (req.files.thumbCover) {
const image = req.files.thumbCover;
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({
validation: {
thumbCover: {
msg: _sr['fa'].format.image
}
}
});
}
const imageName = `news_${Date.now()}_${createNews._id}.${image.mimetype.split('/')[1]}`;
try {
const target = sharp(image.data)
await target
.jpeg({
quality: thumbCoverQuality
})
.toFile(`./static/uploads/images/news/thumb_${imageName}`);
createNews.thumbCover = `thumb_${imageName}`;
flagThumb = true
} catch (e) {
return res500(res, e?.message);
}
if (!req.files.cover){
const imageName = `news_${Date.now()}_${createNews._id}.${image.mimetype.split('/')[1]}`;
try {
const target = sharp(image.data)
await target
.jpeg({
quality: coverQuality
})
.toFile(`./static/uploads/images/news/${imageName}`);
createNews.cover = imageName;
flagCover = true
} catch (e) {
return res500(res, e?.message);
}
}
}
createNews.newsStatus = (flagCover && flagThumb)
await createNews.save();
}
/**
* show result
*/
return res.json(createNews);
} catch (error) {
console.log(error);
/**
* if we got unkown error show to client
*/
res500(res, error.message);
}
}
]
module.exports.addAllNews = [
async (req, res) => {
try {
// // const parsedData = req.files.file
// const {rootParent, category, creator, catIdOstan} = req.body
// const rawFile = await fs.readFileSync(`./server/csvjson.json`)
// const parsedData = await JSON.parse(rawFile)
//
// // console.log(parsedData)
//
// const posts = []
//
// // dynamic
// // const rootParent = '60e95a43111ba696ea3d5171' // فرمانداری ها
// // const category = '60e95c7d111ba696ea3d5301' // فرماندای شهرستان خنداب
//
// // static
// // const creator = '60eaaf8db36930ef88d3d377'
//
// const newArray = []
//
// for (const item of parsedData) {
// if (item.term_taxonomy_id.toString() === catIdOstan) {
// // console.log(item.term_taxonomy_id)
// newArray.push(item)
// }
// }
//
// console.log('-- posts length: ', newArray.length)
//
// let index = 0
// for (const item of newArray) {
// const newPost = new News({
// title: item.post_title,
// shortTitlePanel: item.post_title,
// shortTitleFront: item.post_title,
// summaryTitle: item.post_title,
// leadTitle: '',
// shortSummaryTitle: item.post_title,
// customDate: item.post_date,
// /// ****************************************
// catId: category,
// /// ****************************************
// allCat: [],
// newsFileId: null,
// /// ****************************************
// rootParent: rootParent,
// /// ****************************************
// priority: false,
// allowComment: false,
// showInHome: false,
// slider: false,
// publish: true,
// pageContent: item.post_content,
// cover: null,
// thumbCover: null,
// userViews: 200,
// special: false,
// notifications: false,
// _creator: creator,
// _updatedBy: creator,
// siteMap: true,
// keywords: [],
// metaTagDesc: item.post_title,
// newsStatus: true,
// modelType: 'ostandari',
// attachments: [],
// imported: true
// })
// await newPost.save()
// if (index === newArray.length - 1) console.log('---- data entry finished')
// index++
// }
const news = await News.find({catId : '60e931d5111ba696ea3d483b'})
// const regex = new RegExp('/', 'g')
let index = 0
for await (const item of news) {
console.log(index)
// item.title = item.title.replace(regex, ',')
item.catId = '60e931fc111ba696ea3d485b'
item.allCat = ['60e931d5111ba696ea3d483b']
await item.save()
if (index === news.length - 1) console.log('update finished')
index++
}
/**
* show result
*/
return res.json(news);
} catch (error) {
console.log(error);
/**
* if we got unkown error show to client
*/
return res500(res, error.message);
}
}
]
module.exports.updateNews = [
[
body('title').notEmpty().withMessage(_sr['fa'].required.title),
body('leadTitle').notEmpty().withMessage(_sr['fa'].required.field),
body('catId')
.notEmpty().withMessage(_sr['fa'].required.field)
.bail()
.isMongoId().withMessage('شناسه دسته بندی معتبر نیست')
.bail()
.custom(value => {
return Category.findById(value).then(category => {
if (!category) {
return Promise.reject(_sr['fa'].not_found.category);
}
});
}),
body('priority').optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('allowComment').optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('notifications').isBoolean().withMessage(_sr['fa'].format.boolean),
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('publish').isBoolean().withMessage(_sr['fa'].format.boolean),
body('keywords')
.optional()
.custom(value => {
try {
const keywords = _.isString(value) ? JSON.parse(value) : value;
if (!Array.isArray(keywords)) {
throw new Error('این فیلد باید به صورت آرایه فرستاده شود');
}
return true;
} catch (error) {
throw new Error('این فیلد باید به صورت آرایه فرستاده شود');
}
}),
body('metaTagDesc').optional(),
body('modelType').custom((value, { req }) => {
if (req.user.portals.join() === portal.join()) {
if (!portal.includes(value)) {
return Promise.reject(`${_sr['fa'].optional.onlyValid} => ${portal}`);
}
}
return true;
}),
body('newsFileId').optional().isMongoId().withMessage('شناسه فایل خبری معتبر نیست'),
body('customDate').optional().isString().withMessage('لطفا یک تاریخ صحیح وارد نمایید'),
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ validation: errors.mapped() });
}
try {
const { title, summaryTitle, leadTitle, catId, priority, notifications, showInHome, special, siteMap, content, publish, pageContent, allowComment, keywords, metaTagDesc, modelType, newsFileId, customDate } = req.body;
let parsedKeywords = keywords;
if (_.isString(keywords)) {
parsedKeywords = JSON.parse(keywords);
}
const newsId = req.params.id;
const targetNews = await News.findById(newsId).populate('catId');
if (!targetNews) {
return res404(res, 'خبر مورد نظر پیدا نشد');
}
if (req.user.specialPermissions.length && await _checkSpecPermission(req, targetNews.catId)) {
return res.status(403).json({ message: 'شما اجازه بروزرسانی این خبر را ندارید' });
}
if (!req.user.portals.includes(targetNews.modelType)) {
return res500(res, 'شما اجازه آپدیت این خبر را ندارید');
}
if (targetNews.title !== title) {
const checkDuppTitle = await News.findOne({ title });
if (checkDuppTitle) {
return res.status(422).json({ validation: { title: { msg: _sr['fa'].duplicated.title } } });
}
}
const category = await Category.findById(catId).populate({
path: 'parent',
populate: {
path: 'parent',
model: 'Category'
}
});
if (catId && targetNews.catId.toString() !== catId.toString()) {
targetNews.allCat = category.treeCat;
targetNews.rootParent = category.rootParent || category._id;
}
if (priority === 'true') {
await changePriority(category._id, modelType);
}
if (newsFileId) {
const checkNewsFile = await NewsFile.findById(newsFileId);
if (!checkNewsFile) {
return res404(res, 'پرونده خبری انخاب شده وجود ندارد');
}
if (checkNewsFile.modelType !== modelType) {
return res.status(422).json({
validation: {
newsFileId: { msg: 'نوع خبر مورد نظر با نوع پرونده خبری متفاوت است' }
}
});
}
}
if (req.files) {
await handleFileUploads(req, res, targetNews);
}
Object.assign(targetNews, {
title: title.trim().replace(titleFilterRegex, '/'),
summaryTitle: summaryTitle?.trim(),
leadTitle: leadTitle?.trim(),
catId,
priority,
notifications,
showInHome,
special,
siteMap,
publish,
allowComment,
content,
pageContent,
keywords: parsedKeywords,
metaTagDesc: metaTagDesc?.trim() || leadTitle?.trim(),
newsFileId,
shortTitleFront: title.slice(0, shortTitleFront),
shortTitlePanel: title.slice(0, shortTitlePanel),
shortSummaryTitle: summaryTitle?.trim()?.slice(0, shortSumTitle),
customDate: customDate || targetNews.created_at,
_updatedBy: req.user._id
});
if (customDate) {
targetNews.customDateHistory.push({
customDate,
_updatedBy: req.user._id
});
}
await targetNews.save();
return res.json(targetNews);
} catch (error) {
return res500(res, error.message);
}
}
];
module.exports.MostViewdNews = [
async (req,res)=>{
const thirtyDaysAgo = new Date();
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
try {
const mostViewedNews = await News.find({
customDate: { $gte: thirtyDaysAgo }
}).sort({ userViews: -1 }).limit(10);
return res.status(200).json({mostViewedNews})
} catch (error) {
res.status(500).send('خطا');
}
}
]
module.exports.deletOneNews = [
async (req, res) => {
let oldPic;
try {
const newsId = req.params.id;
const targetNews = await News.findOne({
_id: newsId
}).populate('catId');
/** check news exist or not */
if (!targetNews) {
return res404(res, `خبر مورد نظر پیدا نشد`);
}
/** check special permission */
if (req.user.specialPermissions.length && await _checkSpecPermission(req, targetNews.catId)) {
return res.status(403).json({
message: `شما مجاز به حذف این خبر نمی باشید`
});
}
if (targetNews?.superNews && req.user._id.toString() !== targetNews._creator.toString()){
return res.status(403).json({
message: `شما مجاز به حذف این خبر نمی باشید`
});
}
/** check access portal */
if (!req.user.portals.includes(targetNews.modelType)) {
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 targetNews.deleteOne();
await Comment.deleteMany({modelRef: targetNews._id});
x
return res.json(targetNews);
} catch (error) {
return res500(res, error);
}
}
]
module.exports.deleteAllNews = [
async (req, res) => {
try {
await News.deleteMany({imported: true})
return res.json('ok');
} catch (error) {
/**
* if we got unkown error show to client
*/
return res500(res, error.message);
}
}
]
module.exports.getOneNews = [
async (req, res) => {
try {
const newsId = req.params.id;
const findQuery = {
_id: newsId
};
const news = await News.findOne(findQuery).populate('catId');
if (!news) {
return res404(res, `خبر مورد نظر پیدا نشد`);
}
/** check special permission */
if (req.user.specialPermissions.length && await _checkSpecPermission(req, news.catId)) {
return res.status(403).json({
message: `شما مجاز به دیدن اطلاعات این خبر نمی باشید`
});
}
/** check access portal */
if (!req.user.portals.includes(news.modelType)) {
return res.status(403).json({
message: `شما اجازه دسترسی به اطلاعات این خبر را ندارید`
});
}
/**
* show result
*/
return res.json(news);
} catch (error) {
/**
* if we got unknown error show to client
*/
res500(res, error);
}
}
]
module.exports.getAll = [
async (req, res) => {
try {
let findQuery = {};
// @todo can change it
if (req.user.specialPermissions.length) {
findQuery.catId = {$in: req.user.specialPermissions}
}
if (req.user.portals.length) {
findQuery.modelType = {
$in: req.user.portals
};
}
/** get all news */
// var allNews = await News.find(findQuery).populate('_creator', {
// firstName: 1,
// lastName: 1,
// profilePic: 1
// })
// .populate('catId')
// .sort({
// created_at: -1
// });
let allNews = await News.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 (!allNews) {
return res500(res, `مشکلی در گرفتن اطلاعات پیش آمده است`);
}
/** show result to client */
return res.json(allNews);
} catch (error) {
console.log(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'] = [];
let {
term,
catId,
showInHome,
publish,
portals,
status,
notifications,
special,
newsFile,
date
} = req.body;
/** search by term */
if (term && !_.isEmpty(term)) {
findQuery['$or'].push(
{
title: {
$regex: '.*' + term + '.*'
},
},
{
summaryTitle: {
$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 showInHome */
if (!_.isUndefined(showInHome) && _.isBoolean(showInHome)) {
findQuery['$and'].push({
showInHome
});
}
/** 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 status */
if (!_.isUndefined(status) && _.isBoolean(status)) {
findQuery['$and'].push({
newsStatus: status
})
}
/** search by notifications */
if (!_.isUndefined(notifications) && _.isBoolean(notifications)) {
findQuery['$and'].push({
notifications
});
}
/** search by special */
if (!_.isUndefined(special) && _.isBoolean(special)) {
findQuery['$and'].push({
special
});
}
/** search by special */
if (newsFile && !_.isEmpty(newsFile)) {
findQuery['$and'].push({
newsFileId: newsFile
});
}
/** search by date */
if (date && !_.isEmpty(date)) {
if (date.length === 1) {
findQuery['$and'].push({
customDate: {
$gte: moment(date[0]).startOf('days'),
$lt: moment(date[0]).endOf('days')
}
});
} else {
findQuery['$and'].push({
customDate: {
$gte: new Date(date[0]),
$lt: new Date(date[1])
}
});
}
}
_.isEmpty(findQuery['$and']) && delete findQuery['$and'];
_.isEmpty(findQuery['$or']) && delete findQuery['$or'];
/** get news */
const news = await News.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(news);
} catch (error) {
return res500(res, error?.message)
}
}
]
module.exports.searchForSlider = [
async (req, res) => {
try {
var findQuery = {publish : true , newsStatus : true};
findQuery['$and'] = [];
findQuery['$or'] = [];
let term = req.params.title;
/** search by term */
if (term && !_.isEmpty(term)) {
findQuery['$or'].push(
{
title: {
$regex: '.*' + term + '.*'
},
}
);
}
_.isEmpty(findQuery['$and']) && delete findQuery['$and'];
_.isEmpty(findQuery['$or']) && delete findQuery['$or'];
/** get news */
var news = await News.find(findQuery);
/** show result */
return res.json(news);
} catch (error) {
return res500(res, error?.message)
}
}
]
//////////// add attachment file to category
module.exports.addAttachmentToNews = [
[
body('attTitle')
.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 قابل قبول است'}}})
const data = {title: req.body.attTitle}
const file = req.files.file
const fileName = req.body.attTitle.replace(titleFilterRegex, '-') + '_' + Date.now() + '.pdf'
file.mv(`./static/uploads/files/newsAttachments/${fileName}`)
data.file = fileName
News.findById(req.params.newsId, (err, news) => {
if (err || !news) return res404(res, err)
news.attachments.push(data)
news.save(err => {
if (err) return res500(res, err)
else return res.json({message: _sr['fa'].response.success_save})
})
})
}
]
module.exports.removeAttachmentFromNews = [
(req, res) => {
News.findOne({'attachments._id': req.params.fileId}, (err, news) => {
if (err || !news) return res404(res, err)
const file = news.attachments.id(req.params.fileId)
if (!file) return res404(res, 'not found')
file.remove()
fs.unlink(`./static/${file.file}`, err => {
if (err) console.log(err)
})
news.save(err => {
if (err) return res500(res, err)
else return res.json({message: _sr['fa'].response.success_remove})
})
})
}
]
/////////////////////////////////////////////////////////////////////// public
module.exports.EDITNEWS = [
async(req,res)=>{
}
]
module.exports.viewNews = [
async (req, res) => {
try {
var newsTitle = req.params.title;
var targetNews = await News.findOne({
_id: newsTitle,
newsStatus: true,
publish: true
})
.populate('_creator', {
firstName: 1,
lastName: 1,
profilePic: 1
})
.populate({
path: 'catId',
select: 'title'
});
if (!targetNews) {
return res404(res, `خبر مورد نطر پیدا نشد`);
}
++targetNews.userViews;
await targetNews.save();
/** get comments */
var comments = await Comment.find({
modelRef: targetNews._id,
allowShow: true
});
var result = {
news: targetNews,
comments
};
return res.json(result);
} catch (error) {
return res500(res, error?.message);
}
}
]
module.exports.FilterNews = [
async (req,res)=>{
const length = parseInt(req.params.length);
const views = parseInt(req.params.userViews);
try {
const news = await News.find().sort({ date: -1 }).limit(length);
const filteredNews = await News.find({
userViews: { $gte: views },
}).sort({ date: -1 });
res.json({filteredNews, news});
} catch (error) {
res.status(500).json({ message: error.message });
}
}
]
module.exports.OstandarNews = [
async (req,res)=>{
try {
const news = await News.find({modelType:"ostandari"})
res.status(200).json(news)
}catch (e) {
return res.status(500).json(e.message)
}
}
]
module.exports.getNewsByCategory = [
async (req, res) => {
try {
const catTitle = req.params.title;
const page = req.query.page;
/** check category */
const targetCategory = await Category.findOne({
title: catTitle
});
if (!targetCategory) {
return res404(res, `دسته بندی مورد نظر پیدا نشد`);
}
const requests = [
// priority news
News.findOne({
catId: targetCategory._id,
publish: true,
newsStatus: true,
priority: true
}),
// news
News.paginate({
catId: targetCategory._id,
publish: true,
newsStatus: true,
priority: false
},
{
page: page || 1,
limit: newsPerPageLimit,
sort: {customDate: -1}
}),
//news file
NewsFile.find({catId: targetCategory._id, publish: true}),
// special
News.find({
catId: targetCategory._id,
publish: true,
newsStatus: true,
special: true
}).sort({customDate: -1}),
// events
News.find({
catId: targetCategory._id,
publish: true,
newsStatus: true,
notifications: true
}).sort({customDate: -1}),
//polls
Polls.find({
catId: targetCategory._id,
publish: true,
startDate: {$lte: new Date()},
endDate: {$gte: new Date()}
}),
// latestNews
News.find({
publish: true,
newsStatus: true
}).sort({_id: -1}).limit(8)
];
const fetch = await Promise.all(requests);
const [heroNews, news, newsFile, specials, events, polls, latestNews] = fetch;
const result = {
category: targetCategory,
heroNews,
news,
newsFile,
specials,
events,
polls,
latestNews
}
return res.json(result);
} catch (error) {
return res500(res, error?.message);
}
}
]
module.exports.getAllNews = [
async (req, res) => {
try {
let {
flag,
catId,
portal,
limit,
page
} = req.query;
var findQuery = {};
var setLimit = parseInt(limit) || 10;
var setSort = {};
findQuery.modelType = portal;
findQuery.newsStatus = true;
findQuery.publish = true;
switch (flag) {
case 'category':
setLimit = 20
setSort.customDate = -1
findQuery.rootParent = catId
break
case 'all':
setLimit = 20
setSort.customDate = -1
break;
case 'new':
setSort.customDate = -1;
setLimit = 5;
break;
case 'slider':
findQuery.slider = true;
setSort.customDate = -1;
setLimit = 3;
break;
case 'special':
findQuery.special = true;
setSort.customDate = -1;
setLimit = 4;
break;
case 'random':
var result = await randomNews(findQuery);
return res.json(result);
case 'popular':
setSort.userViews = -1;
setSort.customDate = -1;
setLimit = 5;
break;
case 'events':
findQuery.notifications = true;
findQuery.showInHome = true;
setSort.customDate = -1;
setLimit = 5;
break;
default:
return res.json([]);
}
var getNews = await News.paginate(findQuery, {page: page || 1, limit: setLimit, sort: setSort});
return res.json(getNews);
} catch (error) {
return res500(res, error?.message);
}
}
]
module.exports.getSections = [
async (req, res) => {
try {
const portal = req.query.portal;
let result = {};
result.sectionOne = [];
result.sectionTwo = [];
result.sectionThree = [];
let getSectionsTitle = await Category.find({
$or: [
{showInSectionOne: true},
{showInSectionTwo: true},
{showInSectionThree: true},
],
modelType: portal
});
for (const item of getSectionsTitle) {
let section = {};
let news = await News.find({
catId: item._id,
showInHome: true,
publish: true,
modelType: portal
}).limit(limit).sort({_id: -1});
section.nameTag = item.title;
section.data = news;
if (item.showInSectionOne) {
result.sectionOne = section;
}
if (item.showInSectionTwo) {
result.sectionTwo = section;
}
if (item.showInSectionThree) {
result.sectionThree.push(section);
}
}
// let findQuery = {};
// let setLimit = parseInt(limit) || 10;
// let setSort = {};
// let setSkip = parseInt(skip) || 0;
// findQuery.modelType = portal;
// findQuery.newsStatus = true;
// findQuery.publish = true;
return res.json(result);
} catch (error) {
return res500(res, error?.message);
}
}
]
/** @todo mabe change it in future */
module.exports.getRelated = [
async (req, res) => {
try {
const {
portal,
title
} = req.query;
let getNews = {};
let findQuery = {};
findQuery.modelType = portal;
findQuery._id = {
$ne: title
};
findQuery.newsStatus = true;
findQuery.publish = true;
const targetNews = await News.findById(title)
if (targetNews) {
findQuery.catId = targetNews.catId;
getNews = await randomNews(findQuery);
}
return res.json(getNews);
} catch (error) {
return res500(res, error?.message);
}
}
]