1475 lines
48 KiB
JavaScript
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);
|
|
}
|
|
}
|
|
]
|