update:add ci cd files ==> do not edit those file
This commit is contained in:
@@ -0,0 +1,358 @@
|
||||
const BlogCategory = require('../models/BlogCategory')
|
||||
const BlogPost = require('../models/BlogPost')
|
||||
const mongoose = require('mongoose')
|
||||
const sharp = require('sharp')
|
||||
const fs = require('fs')
|
||||
const {body, validationResult} = require('express-validator')
|
||||
const {res404, res500, checkValidations} = require('../plugins/controllersHelperFunctions')
|
||||
const {_sr} = require('../plugins/serverResponses')
|
||||
|
||||
// variables
|
||||
const coverWidth = 1920
|
||||
const coverHeight = 300
|
||||
const coverQuality = 100
|
||||
|
||||
const coverThumbWidth = 400
|
||||
const coverThumbHeight = 210
|
||||
const coverThumbQuality = 100
|
||||
|
||||
const lastSectionImageWidth = 1920
|
||||
const lastSectionImageHeight = 400
|
||||
const lastSectionImageQuality = 100
|
||||
|
||||
const blogPaginateLimit = 10
|
||||
|
||||
const shortDescriptionLength = 250
|
||||
|
||||
const videoLimit = 150;
|
||||
|
||||
module.exports.create = [
|
||||
[
|
||||
body('en_title')
|
||||
.notEmpty().withMessage(_sr['fa'].required.title)
|
||||
.bail()
|
||||
.custom((value, {req}) => {
|
||||
return BlogPost.findOne({$or: [{'locale.fa.title': value}, {'locale.en.title': value}]})
|
||||
.then(post => {
|
||||
if (post) return Promise.reject(_sr['fa'].duplicated.title)
|
||||
else return true
|
||||
})
|
||||
}),
|
||||
|
||||
body('fa_title')
|
||||
.if((value, {req}) => value)
|
||||
.custom((value, {req}) => {
|
||||
return BlogPost.findOne({$or: [{'locale.fa.title': value}, {'locale.en.title': value}]})
|
||||
.then(post => {
|
||||
if (post) return Promise.reject(_sr['fa'].duplicated.title)
|
||||
else return true
|
||||
})
|
||||
})
|
||||
],
|
||||
checkValidations(validationResult),
|
||||
async (req, res) => {
|
||||
if (!req.files || !req.files.cover) return res.status(422).json({validation: {cover: {msg: _sr['fa'].required.cover}}})
|
||||
if (!_sr.supportedImageFormats.includes(req.files.cover.mimetype.split('/')[1])) return res.status(422).json({validation: {cover: {msg: _sr['fa'].format.image}}})
|
||||
|
||||
const {
|
||||
fa_title,
|
||||
en_title
|
||||
} = req.body
|
||||
|
||||
const data = {
|
||||
locale: {
|
||||
fa: {
|
||||
title: fa_title
|
||||
},
|
||||
en: {
|
||||
title: en_title
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const image = req.files.cover
|
||||
const imageName = 'blog_' + Date.now() + '.jpg'
|
||||
const imageThumb = 'thumb_' + imageName
|
||||
|
||||
try {
|
||||
const target = await sharp(image.data)
|
||||
await target
|
||||
.resize(coverWidth, coverHeight, {fit: 'cover'})
|
||||
.withMetadata()
|
||||
.toFormat('jpg')
|
||||
.jpeg({quality: coverQuality})
|
||||
.toFile(`./static/uploads/images/blog/${imageName}`)
|
||||
|
||||
await target
|
||||
.resize(coverThumbWidth, coverThumbHeight, {fit: 'cover'})
|
||||
.withMetadata()
|
||||
.toFormat('jpg')
|
||||
.jpeg({quality: coverThumbQuality})
|
||||
.toFile(`./static/uploads/images/blog/thumb/${imageThumb}`)
|
||||
|
||||
data.cover = imageName
|
||||
data.thumb = imageThumb
|
||||
} catch (e) {
|
||||
return res500(res, e)
|
||||
}
|
||||
|
||||
const post = new BlogPost(data)
|
||||
post.save((err, data) => {
|
||||
if (err) return res500(res, err)
|
||||
return res.json(data)
|
||||
})
|
||||
}
|
||||
]
|
||||
|
||||
module.exports.getAll = [
|
||||
async (req, res) => {
|
||||
///////////// get available options
|
||||
// '/api/public/blogPosts' --> gets all published posts
|
||||
// '/api/public/blogPosts?getAll=true' --> gets all posts either published or not
|
||||
// '/api/public/blogPosts?limit=4' --> gets only 4 published post of all categories
|
||||
// '/api/public/blogPosts?category=${encodeURIComponent(categoryTitle)}&page=${pageNumber}' --> gets posts depend on the category title and in chunked data
|
||||
|
||||
if (req.query.category) {
|
||||
try {
|
||||
const categoryID = await BlogCategory.findOne({$or: [{'locale.fa.title': req.query.category}, {'locale.en.title': req.query.category}]})
|
||||
const filter = req.query.category === 'all' ? {published: true} : {published: true, category: categoryID._id}
|
||||
BlogPost.paginate(filter, {page: req.query.page, limit: blogPaginateLimit, populate: 'category', sort: {_id: -1}}, (err, posts) => {
|
||||
if (err) return res500(res, {message: _sr['fa'].not_found.item_id})
|
||||
return res.json(posts)
|
||||
})
|
||||
} catch (e) {
|
||||
return res500(res, e)
|
||||
}
|
||||
} else {
|
||||
let query = {published: true}
|
||||
if (req.query.getAll) delete query.published
|
||||
const limit = Number(req.query.limit) || false
|
||||
BlogPost.find(query).sort({_id: -1}).limit(limit).populate('category').exec((err, posts) => {
|
||||
if (err) return res500(res, err)
|
||||
else return res.json(posts)
|
||||
})
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
module.exports.getOne = [
|
||||
(req, res) => {
|
||||
const query = req.params.id
|
||||
const isObjectId = mongoose.isValidObjectId(query)
|
||||
const noCategory = req.query.noCategory
|
||||
const filter = isObjectId ? {_id: query} : {$or: [{'locale.fa.title': query}, {'locale.en.title': query}]}
|
||||
BlogPost.findOne(filter).populate(noCategory ? '' : 'category').exec((err, post) => {
|
||||
if (err || !post) return res404(res, err)
|
||||
else return res.json(post)
|
||||
})
|
||||
}
|
||||
]
|
||||
|
||||
module.exports.update = [
|
||||
[
|
||||
body('en_title')
|
||||
.notEmpty().withMessage(_sr['fa'].required.title)
|
||||
.bail()
|
||||
.custom((value, {req}) => {
|
||||
return BlogPost.findOne({$or: [{'locale.fa.title': value}, {'locale.en.title': value}]})
|
||||
.then(post => {
|
||||
if (post && post._id.toString() !== req.params.id) return Promise.reject(_sr['fa'].duplicated.title)
|
||||
else return true
|
||||
})
|
||||
}),
|
||||
|
||||
body('fa_title')
|
||||
.if((value, {req}) => value)
|
||||
.custom((value, {req}) => {
|
||||
return BlogPost.findOne({$or: [{'locale.fa.title': value}, {'locale.en.title': value}]})
|
||||
.then(post => {
|
||||
if (post && post._id.toString() !== req.params.id) return Promise.reject(_sr['fa'].duplicated.title)
|
||||
else return true
|
||||
})
|
||||
}),
|
||||
|
||||
body('category')
|
||||
.notEmpty().withMessage(_sr['fa'].required.category)
|
||||
.bail()
|
||||
.custom((value, {req}) => {
|
||||
if (mongoose.isValidObjectId(value)) {
|
||||
return BlogCategory.findById(value)
|
||||
.then(category => {
|
||||
if (!category) return Promise.reject(_sr['fa'].not_found.item_id)
|
||||
else return true
|
||||
})
|
||||
} else return Promise.reject(_sr['fa'].required.category)
|
||||
})
|
||||
],
|
||||
checkValidations(validationResult),
|
||||
async (req, res) => {
|
||||
const {
|
||||
fa_title,
|
||||
en_title,
|
||||
fa_description,
|
||||
en_description,
|
||||
fa_short_description,
|
||||
en_short_description,
|
||||
fa_last_section_image_title,
|
||||
en_last_section_image_title,
|
||||
fa_last_section_image_description,
|
||||
en_last_section_image_description,
|
||||
fa_last_section_title,
|
||||
en_last_section_title,
|
||||
fa_last_section_description,
|
||||
en_last_section_description,
|
||||
category,
|
||||
published
|
||||
} = req.body
|
||||
|
||||
const data = {
|
||||
locale: {
|
||||
fa: {
|
||||
title: fa_title || '',
|
||||
description: fa_description || '',
|
||||
short_description: fa_short_description.slice(0, shortDescriptionLength) || '' + ' ... ',
|
||||
last_section_image_title: fa_last_section_image_title || '',
|
||||
last_section_image_description: fa_last_section_image_description || '',
|
||||
last_section_title: fa_last_section_title || '',
|
||||
last_section_description: fa_last_section_description || ''
|
||||
},
|
||||
en: {
|
||||
title: en_title || '',
|
||||
description: en_description || '',
|
||||
short_description: en_short_description.slice(0, shortDescriptionLength) || '' + ' ... ',
|
||||
last_section_image_title: en_last_section_image_title || '',
|
||||
last_section_image_description: en_last_section_image_description || '',
|
||||
last_section_title: en_last_section_title || '',
|
||||
last_section_description: en_last_section_description || ''
|
||||
}
|
||||
},
|
||||
category, published
|
||||
}
|
||||
|
||||
if (req.files) {
|
||||
if (req.files.cover) {
|
||||
if (!_sr.supportedImageFormats.includes(req.files.cover.mimetype.split('/')[1])) return res.status(422).json({validation: {cover: {msg: _sr['fa'].format.image}}})
|
||||
|
||||
const image = req.files.cover
|
||||
const imageName = 'blog_' + Date.now() + '.jpg'
|
||||
const imageThumb = 'thumb_' + imageName
|
||||
|
||||
try {
|
||||
const target = await sharp(image.data)
|
||||
await target
|
||||
.resize(coverWidth, coverHeight, {fit: 'cover'})
|
||||
.withMetadata()
|
||||
.withMetadata()
|
||||
.toFormat('jpg')
|
||||
.jpeg({quality: coverQuality})
|
||||
.toFile(`./static/uploads/images/blog/${imageName}`)
|
||||
|
||||
await target
|
||||
.resize(coverThumbWidth, coverThumbHeight, {fit: 'cover'})
|
||||
.withMetadata()
|
||||
.withMetadata()
|
||||
.toFormat('jpg')
|
||||
.jpeg({quality: coverThumbQuality})
|
||||
.toFile(`./static/uploads/images/blog/thumb/${imageThumb}`)
|
||||
data.cover = imageName
|
||||
data.thumb = imageThumb
|
||||
|
||||
} catch (e) {
|
||||
return res500(res, e)
|
||||
}
|
||||
}
|
||||
|
||||
if (req.files.last_section_image) {
|
||||
if (!_sr.supportedImageFormats.includes(req.files.last_section_image.mimetype.split('/')[1])) return res.status(422).json({validation: {cover: {msg: _sr['fa'].format.image}}})
|
||||
|
||||
const image = req.files.last_section_image
|
||||
const imageName = 'blog_' + Date.now() + '.jpg'
|
||||
const imageThumb = 'thumb_' + imageName
|
||||
|
||||
try {
|
||||
const target = await sharp(image.data)
|
||||
await target
|
||||
.resize(lastSectionImageWidth, lastSectionImageHeight, {fit: 'cover'})
|
||||
.withMetadata()
|
||||
.toFormat('jpg')
|
||||
.jpeg({quality: lastSectionImageQuality})
|
||||
.toFile(`./static/uploads/images/blog/${imageName}`)
|
||||
|
||||
data.last_section_image = imageName
|
||||
|
||||
} catch (e) {
|
||||
return res500(res, e)
|
||||
}
|
||||
}
|
||||
|
||||
if (req.files.video) {
|
||||
const file = req?.files?.video
|
||||
if (file.mimetype.split('/')[1] !== 'mp4') return res.status(422).json({validation: {video: {msg: _sr['fa'].format.video}}})
|
||||
|
||||
///// start convert byte to mb
|
||||
const mb = file.size / (1024 * 1024);
|
||||
|
||||
///// check limit size of video
|
||||
if (mb > videoLimit) {
|
||||
return res.status(422).json({
|
||||
validation: {file: {msg: `${_sr['fa'].max_char.data_size} 150 مگابایت`}}
|
||||
});
|
||||
}
|
||||
|
||||
const videoName = 'blog_' + Date.now() + '.mp4'
|
||||
const uploadPath = `./static/uploads/videos/blog/${videoName}`;
|
||||
|
||||
try {
|
||||
await file.mv(uploadPath);
|
||||
data.video = videoName
|
||||
} catch (e) {
|
||||
return res500(res, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BlogPost.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
|
||||
if (err || !oldData) return res404(res, err)
|
||||
if (req.files && req.files.cover) {
|
||||
fs.unlink(`./static/${oldData.cover}`, (err) => {
|
||||
if (err) console.log(err)
|
||||
})
|
||||
fs.unlink(`./static/${oldData.thumb}`, (err) => {
|
||||
if (err) console.log(err)
|
||||
})
|
||||
}
|
||||
if (req.files && req.files.last_section_image && oldData.last_section_image) {
|
||||
fs.unlink(`./static/${oldData.last_section_image}`, (err) => {
|
||||
if (err) console.log(err)
|
||||
})
|
||||
}
|
||||
if (req.files && req.files.video && oldData.video) {
|
||||
fs.unlink(`./static/${oldData.video}`, (err) => {
|
||||
if (err) console.log(err)
|
||||
})
|
||||
}
|
||||
return res.json({message: _sr['fa'].response.success_save})
|
||||
})
|
||||
}
|
||||
]
|
||||
|
||||
module.exports.delete = [
|
||||
(req, res) => {
|
||||
BlogPost.findByIdAndRemove(req.params.id, (err, data) => {
|
||||
if (err || !data) return res404(res, err)
|
||||
fs.unlink(`./static/${data.cover}`, err => {
|
||||
if (err) console.log(err)
|
||||
})
|
||||
fs.unlink(`./static/${data.thumb}`, err => {
|
||||
if (err) console.log(err)
|
||||
})
|
||||
if (data.last_section_image) fs.unlink(`./static/${data.last_section_image}`, err => {
|
||||
if (err) console.log(err)
|
||||
})
|
||||
if (data.video) fs.unlink(`./static/${data.video}`, err => {
|
||||
if (err) console.log(err)
|
||||
})
|
||||
return res.json({message: _sr['fa'].response.success_remove})
|
||||
})
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user