feat: add ci cd files dont edit those files
This commit is contained in:
@@ -0,0 +1,684 @@
|
||||
const NewsFile = require('../models/NewsFile')
|
||||
const {body, validationResult} = require('express-validator')
|
||||
const {_sr} = require('../plugins/serverResponses')
|
||||
const {res404, res500} = require('../plugins/controllersHelperFunctions')
|
||||
const News = require('../models/News')
|
||||
const Category = require('../models/Category')
|
||||
const sharp = require('sharp')
|
||||
const fs = require('fs')
|
||||
|
||||
////// variables
|
||||
const noCover = '/img/no-cover.jpg'
|
||||
const limit = 5;
|
||||
const limitDetails = 11;
|
||||
const titleFilterRegex = new RegExp('/', 'g')
|
||||
|
||||
////// variables
|
||||
const coverNewsWidth = 1000;
|
||||
const coverNewsHeight = 600;
|
||||
const coverQuality = 100;
|
||||
|
||||
const thumbCoverNewsWidth = 600;
|
||||
const thumbCoverNewsHeight = 300;
|
||||
const thumbCoverQuality = 200;
|
||||
|
||||
////// 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)
|
||||
}
|
||||
}
|
||||
|
||||
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.addNewsFile = [
|
||||
[
|
||||
body('title')
|
||||
.notEmpty().withMessage(_sr['fa'].required.title)
|
||||
.custom((value, {req}) => {
|
||||
return NewsFile.findOne({title: value})
|
||||
.then(newsFile => {
|
||||
if (newsFile) return Promise.reject(_sr['fa'].duplicated.title);
|
||||
else return true
|
||||
})
|
||||
}),
|
||||
|
||||
body('description')
|
||||
.optional().isString().withMessage(`نوع مقدار ارسال شده صحیح نمی باشد`),
|
||||
|
||||
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('index')
|
||||
.isNumeric().withMessage(`لطفا ترتیب نمایش را مشخص کنید`),
|
||||
|
||||
body('showInHome')
|
||||
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
||||
|
||||
body('siteMap')
|
||||
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
||||
|
||||
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
|
||||
}
|
||||
})
|
||||
],
|
||||
async (req, res) => {
|
||||
|
||||
const errors = validationResult(req)
|
||||
if (!errors.isEmpty()) return res.status(422).json({
|
||||
validation: errors.mapped()
|
||||
});
|
||||
|
||||
try {
|
||||
let {
|
||||
title,
|
||||
description,
|
||||
catId,
|
||||
index,
|
||||
showInHome,
|
||||
siteMap,
|
||||
modelType
|
||||
} = req.body;
|
||||
|
||||
/** set portals */
|
||||
modelType = (req.user.portals.join() === portal.join()) ? modelType : req.user.portals[0];
|
||||
|
||||
let newsFileData = {
|
||||
title: title.trim().replace(titleFilterRegex, '-'),
|
||||
description: description.trim(),
|
||||
catId,
|
||||
index,
|
||||
showInHome,
|
||||
siteMap,
|
||||
_creator: req.user._id,
|
||||
_updatedBy: req.user._id,
|
||||
modelType
|
||||
};
|
||||
|
||||
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: `شما اجازه استفاده از این دسته بندی را ندارید`
|
||||
});
|
||||
}
|
||||
|
||||
newsFileData.allCat = category.treeCat;
|
||||
newsFileData.rootParent = category.rootParent || category._id;
|
||||
}
|
||||
|
||||
|
||||
const createNewsFile = await NewsFile.create(newsFileData);
|
||||
|
||||
if (!createNewsFile) res500(res, `مشکلی در اضافه کردن پرونده پرونده خبریی پیش آمده است`)
|
||||
|
||||
/**
|
||||
* if we have pic upload to server
|
||||
*/
|
||||
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()}_${createNewsFile._id}.${image.mimetype.split('/')[1]}`;
|
||||
try {
|
||||
const target = sharp(image.data)
|
||||
await target
|
||||
.resize(coverNewsWidth, coverNewsHeight, {fit: 'cover'})
|
||||
.jpeg({quality: coverQuality})
|
||||
.toFile(`./static/uploads/images/news/${imageName}`);
|
||||
|
||||
createNewsFile.cover = imageName;
|
||||
|
||||
await target
|
||||
.resize(thumbCoverNewsWidth, thumbCoverNewsHeight, {fit: 'cover'})
|
||||
.jpeg({quality: thumbCoverQuality})
|
||||
.toFile(`./static/uploads/images/news/thumb_${imageName}`);
|
||||
|
||||
createNewsFile.thumbCover = `thumb_${imageName}`;
|
||||
|
||||
await createNewsFile.save();
|
||||
} catch (e) {
|
||||
return res500(res, e?.message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* show result
|
||||
*/
|
||||
return res.json(createNewsFile);
|
||||
} catch (error) {
|
||||
res500(res, error.message);
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
module.exports.updateNewsFile = [
|
||||
[
|
||||
body('title')
|
||||
.notEmpty().withMessage(_sr['fa'].required.title),
|
||||
|
||||
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('description')
|
||||
.optional().isString().withMessage(`نوع مقدار ارسال شده صحیح نمی باشد`),
|
||||
|
||||
body('index')
|
||||
.isNumeric().withMessage(`لطفا ترتیب نمایش را مشخص کنید`),
|
||||
|
||||
body('showInHome')
|
||||
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
||||
|
||||
body('siteMap')
|
||||
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
||||
|
||||
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
|
||||
}
|
||||
})
|
||||
],
|
||||
async (req, res) => {
|
||||
const errors = validationResult(req)
|
||||
if (!errors.isEmpty()) return res.status(422).json({
|
||||
validation: errors.mapped()
|
||||
});
|
||||
|
||||
try {
|
||||
|
||||
/**
|
||||
* get data from input
|
||||
*/
|
||||
const {
|
||||
title,
|
||||
description,
|
||||
catId,
|
||||
index,
|
||||
showInHome,
|
||||
siteMap,
|
||||
modelType
|
||||
} = req.body;
|
||||
|
||||
/**
|
||||
* get id
|
||||
*/
|
||||
var newsFileId = req.params.id;
|
||||
|
||||
var targetNewsFile = await NewsFile.findById(newsFileId);
|
||||
|
||||
/** check newsFile exist or not */
|
||||
if (!targetNewsFile) return res404(res, `پرونده خبری مورد نظر پیدا نشد`);
|
||||
|
||||
/** check access portal */
|
||||
if (!req.user.portals.includes(targetNewsFile.modelType)) return res.status(403).json({message: `شما اجازه آپدیت این پرونده خبری را ندارید`});
|
||||
|
||||
if (targetNewsFile.title !== title) {
|
||||
var checkDuppTitle = await NewsFile.findOne({
|
||||
title: title
|
||||
});
|
||||
|
||||
if (checkDuppTitle) {
|
||||
return res.status(422).json({validation: {title: {msg: _sr['fa'].duplicated.title}}});
|
||||
}
|
||||
}
|
||||
|
||||
if (modelType !== targetNewsFile.modelType) {
|
||||
/** check have news or not */
|
||||
var checkNews = await News.find({newsFileId: targetNewsFile._id});
|
||||
|
||||
if (checkNews.length) {
|
||||
return res.status(403).json({message: `این پرونده خبری دارای خبر می باشد و شما نمی توانید نوع آن را تغییر دهید`});
|
||||
}
|
||||
}
|
||||
|
||||
/** 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 && targetNewsFile.catId !== catId) {
|
||||
targetNewsFile.allCat = category.treeCat;
|
||||
targetNewsFile.rootParent = category.rootParent || category._id;
|
||||
}
|
||||
|
||||
targetNewsFile.title = title.trim().replace(titleFilterRegex, '-')
|
||||
targetNewsFile.description = description.trim();
|
||||
targetNewsFile.catId = catId;
|
||||
targetNewsFile.index = index;
|
||||
targetNewsFile.showInHome = showInHome;
|
||||
targetNewsFile.siteMap = siteMap;
|
||||
targetNewsFile.modelType = modelType;
|
||||
|
||||
|
||||
/**
|
||||
* if we have pic upload to server
|
||||
*/
|
||||
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()}_${targetNewsFile._id}.${image.mimetype.split('/')[1]}`;
|
||||
try {
|
||||
const target = sharp(image.data)
|
||||
await target
|
||||
.resize(coverNewsWidth, coverNewsHeight, {fit: 'cover'})
|
||||
.jpeg({quality: coverQuality})
|
||||
.toFile(`./static/uploads/images/news/${imageName}`);
|
||||
|
||||
await target
|
||||
.resize(thumbCoverNewsWidth, thumbCoverNewsHeight, {fit: 'cover'})
|
||||
.jpeg({quality: thumbCoverQuality})
|
||||
.toFile(`./static/uploads/images/news/thumb_${imageName}`);
|
||||
|
||||
/**
|
||||
* if exist old pic delete it from file
|
||||
*/
|
||||
if (targetNewsFile.cover !== noCover) {
|
||||
let oldPic = `./static${targetNewsFile.cover}`;
|
||||
|
||||
if (await fs.existsSync(oldPic)) {
|
||||
fs.unlink(oldPic, (err) => {
|
||||
if (err) return res500(res, err?.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (targetNewsFile.thumbCover !== noCover) {
|
||||
let oldPic = `./static${targetNewsFile.thumbCover}`;
|
||||
|
||||
if (await fs.existsSync(oldPic)) {
|
||||
fs.unlink(oldPic, (err) => {
|
||||
if (err) return res500(res, err?.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
targetNewsFile.cover = imageName;
|
||||
targetNewsFile.thumbCover = `thumb_${imageName}`;
|
||||
} catch (e) {
|
||||
return res500(res, e?.message);
|
||||
}
|
||||
}
|
||||
|
||||
await targetNewsFile.save();
|
||||
|
||||
/**
|
||||
* show result
|
||||
*/
|
||||
return res.json(targetNewsFile);
|
||||
|
||||
} catch (error) {
|
||||
return res500(res, error.message);
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
module.exports.deletOneNewsFile = [
|
||||
async (req, res) => {
|
||||
try {
|
||||
var newsFileId = req.params.id;
|
||||
|
||||
var targetNewsFile = await NewsFile.findOne({_id: newsFileId});
|
||||
|
||||
/** check newsFile exist or not */
|
||||
if (!targetNewsFile) {
|
||||
return res404(res, `پرونده خبری مورد نظر پیدا نشد`);
|
||||
}
|
||||
|
||||
/** check access portal */
|
||||
if (!req.user.portals.includes(targetNewsFile.modelType)) {
|
||||
return res.status(403).json({message: `شما اجازه حذف این پرونده خبری را ندارید`});
|
||||
}
|
||||
|
||||
/** check have news or not */
|
||||
var checkNews = await News.find({newsFileId: targetNewsFile._id});
|
||||
|
||||
if (checkNews.length) {
|
||||
return res.status(403).json({message: `این پرونده خبری دارای خبر می باشد و شما نمی توانید آن را حذف دهید`});
|
||||
}
|
||||
|
||||
/** delete newsFile */
|
||||
await targetNewsFile.deleteOne();
|
||||
|
||||
/**
|
||||
* show result
|
||||
*/
|
||||
return res.json(targetNewsFile);
|
||||
|
||||
} catch (error) {
|
||||
res500(res, error);
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
module.exports.deleteAllNewsFile = [
|
||||
async (req, res) => {
|
||||
try {
|
||||
|
||||
} catch (error) {
|
||||
/**
|
||||
* if we got unkown error show to client
|
||||
*/
|
||||
res500(res, error);
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
module.exports.getOneNewsFile = [
|
||||
async (req, res) => {
|
||||
try {
|
||||
var newsFileId = req.params.id;
|
||||
|
||||
var findQuery = {_id: newsFileId};
|
||||
|
||||
var newsFile = await NewsFile.findOne(findQuery).populate('catId');
|
||||
|
||||
if (!newsFile) {
|
||||
return res404(res, `پرونده خبری مورد نظر پیدا نشد`);
|
||||
}
|
||||
|
||||
/** check access portal */
|
||||
if (!req.user.portals.includes(newsFile.modelType)) {
|
||||
return res.status(403).json({message: `شما اجازه دسترسی به اطلاعات این پرونده خبری را ندارید`});
|
||||
}
|
||||
|
||||
/**
|
||||
* show result
|
||||
*/
|
||||
return res.json(newsFile);
|
||||
} catch (error) {
|
||||
res500(res, error);
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
module.exports.getAll = [
|
||||
async (req, res) => {
|
||||
try {
|
||||
|
||||
var 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 newsFile */
|
||||
const allNewsFile = await NewsFile.find(findQuery).populate('_creator', {
|
||||
firstName: 1,
|
||||
lastName: 1,
|
||||
profilePic: 1
|
||||
})
|
||||
.sort({created_at: -1});
|
||||
|
||||
/** if null we have error */
|
||||
if (!allNewsFile) {
|
||||
return res500(res, `مشکلی در گرفتن اطلاعات پیش آمده است`);
|
||||
}
|
||||
|
||||
/** show result to client */
|
||||
return res.json(allNewsFile);
|
||||
} catch (error) {
|
||||
return res500(res, error?.message);
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
module.exports.search = [
|
||||
async (req, res) => {
|
||||
try {
|
||||
var query = {};
|
||||
let populate = [{
|
||||
path: '_creator',
|
||||
select: {firstName: 1, lastName: 1, profilePic: 1}
|
||||
},
|
||||
{
|
||||
path: 'catId'
|
||||
}];
|
||||
|
||||
|
||||
query['$and'] = [];
|
||||
|
||||
var {
|
||||
term,
|
||||
showInHome,
|
||||
catId,
|
||||
portals
|
||||
} = req.body;
|
||||
|
||||
///////////// permissions
|
||||
|
||||
/** search by catId */
|
||||
if (req.user.specialPermissions.length) {
|
||||
query.catId = {$in: req.user.specialPermissions}
|
||||
} else if (catId && !_.isEmpty(catId)) {
|
||||
query['$and'].push({
|
||||
catId
|
||||
});
|
||||
}
|
||||
|
||||
/** search by portals */
|
||||
if (portals && !_.isEmpty(portals)) {
|
||||
query['$and'].push({
|
||||
modelType: {
|
||||
$in: portals
|
||||
}
|
||||
})
|
||||
} else {
|
||||
if (req.user.portals.length) {
|
||||
query.modelType = {$in: req.user.portals};
|
||||
}
|
||||
}
|
||||
|
||||
/** search by term */
|
||||
if (term && !_.isEmpty(term)) {
|
||||
query['$and'].push({
|
||||
$or: [{
|
||||
title: {
|
||||
$regex: '.*' + term + '.*'
|
||||
}
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
/** search by showInHome */
|
||||
if (!_.isUndefined(showInHome) && _.isBoolean(showInHome)) {
|
||||
query['$and'].push({
|
||||
showInHome
|
||||
});
|
||||
}
|
||||
|
||||
_.isEmpty(query['$and']) && delete query['$and'];
|
||||
// _.isEmpty(input['$or']) && delete input['$or'];
|
||||
|
||||
/** get news */
|
||||
const news = await NewsFile.paginate(query, {page: req.query.page, limit, populate, sort: {_id: -1}});
|
||||
|
||||
/** show result */
|
||||
return res.json(news);
|
||||
} catch (error) {
|
||||
return res500(res, error?.message)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
/////////////////////////////////////////////////////////////////////// public
|
||||
module.exports.viewNewsFile = [
|
||||
async (req, res) => {
|
||||
try {
|
||||
const newsFileTitle = req.params.title;
|
||||
|
||||
let targetNewsFile = await NewsFile.findOne({
|
||||
title: newsFileTitle
|
||||
})
|
||||
.populate('_creator', {firstName: 1, lastName: 1, profilePic: 1});
|
||||
|
||||
if (!targetNewsFile) {
|
||||
return res404(res, `پرونده خبری مورد نطر پیدا نشد`);
|
||||
}
|
||||
|
||||
++targetNewsFile.userViews;
|
||||
|
||||
await targetNewsFile.save();
|
||||
|
||||
/** get news */
|
||||
let getNews = await News.paginate({newsFileId: targetNewsFile._id}, {page: req.query.page || 1, limit: limitDetails , sort : {customDate : -1}});
|
||||
|
||||
let result = {
|
||||
newsFile: targetNewsFile,
|
||||
news: getNews
|
||||
};
|
||||
|
||||
return res.json(result);
|
||||
} catch (error) {
|
||||
return res500(res, `مشکلی در اجرای درخواست شما پیش آمده است`);
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
module.exports.getAllNewsFile = [
|
||||
async (req, res) => {
|
||||
try {
|
||||
const {
|
||||
portal,
|
||||
limit,
|
||||
skip
|
||||
} = req.query;
|
||||
|
||||
const findQuery = {};
|
||||
|
||||
const setLimit = parseInt(limit) || 4;
|
||||
const setSort = {index: 1};
|
||||
const setSkip = parseInt(skip) || 0;
|
||||
|
||||
findQuery.modelType = portal;
|
||||
findQuery.publish = true;
|
||||
|
||||
const getNewsFile = await NewsFile.find(findQuery).limit(setLimit).skip(setSkip).sort(setSort);
|
||||
|
||||
return res.json(getNewsFile);
|
||||
} catch (error) {
|
||||
return res500(res, error?.message);
|
||||
}
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user