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