From acf12e3dd8f28f425c488b16df0a7508b0f01e1c Mon Sep 17 00:00:00 2001 From: Baris Usakli Date: Fri, 16 Aug 2019 15:02:45 -0400 Subject: [PATCH] feat: convert search controller to async/await --- src/controllers/search.js | 165 ++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 89 deletions(-) diff --git a/src/controllers/search.js b/src/controllers/search.js index 0ee2ec4cc0..5caef07d92 100644 --- a/src/controllers/search.js +++ b/src/controllers/search.js @@ -1,106 +1,93 @@ 'use strict'; -var async = require('async'); -var validator = require('validator'); +const validator = require('validator'); -var meta = require('../meta'); -var plugins = require('../plugins'); -var search = require('../search'); -var categories = require('../categories'); -var pagination = require('../pagination'); -var privileges = require('../privileges'); -var helpers = require('./helpers'); +const meta = require('../meta'); +const plugins = require('../plugins'); +const search = require('../search'); +const categories = require('../categories'); +const pagination = require('../pagination'); +const privileges = require('../privileges'); +const helpers = require('./helpers'); -var searchController = module.exports; +const searchController = module.exports; -searchController.search = function (req, res, next) { +searchController.search = async function (req, res, next) { if (!plugins.hasListeners('filter:search.query')) { return next(); } - var page = Math.max(1, parseInt(req.query.page, 10)) || 1; + const page = Math.max(1, parseInt(req.query.page, 10)) || 1; const searchOnly = parseInt(req.query.searchOnly, 10) === 1; - async.waterfall([ - function (next) { - privileges.global.can('search:content', req.uid, next); - }, - function (allowed, next) { - if (!allowed) { - return helpers.notAllowed(req, res); - } - - if (req.query.categories && !Array.isArray(req.query.categories)) { - req.query.categories = [req.query.categories]; - } - if (req.query.hasTags && !Array.isArray(req.query.hasTags)) { - req.query.hasTags = [req.query.hasTags]; - } - - var data = { - query: req.query.term, - searchIn: req.query.in || 'posts', - matchWords: req.query.matchWords || 'all', - postedBy: req.query.by, - categories: req.query.categories, - searchChildren: req.query.searchChildren, - hasTags: req.query.hasTags, - replies: req.query.replies, - repliesFilter: req.query.repliesFilter, - timeRange: req.query.timeRange, - timeFilter: req.query.timeFilter, - sortBy: req.query.sortBy || meta.config.searchDefaultSortBy || '', - sortDirection: req.query.sortDirection, - page: page, - itemsPerPage: req.query.itemsPerPage, - uid: req.uid, - qs: req.query, - }; - - async.parallel({ - categories: async.apply(buildCategories, req.uid, searchOnly), - search: async.apply(search.search, data), - }, next); - }, - function (results) { - var searchData = results.search; - - searchData.pagination = pagination.create(page, searchData.pageCount, req.query); - searchData.multiplePages = searchData.pageCount > 1; - searchData.search_query = validator.escape(String(req.query.term || '')); - searchData.term = req.query.term; - - if (searchOnly) { - return res.json(searchData); - } - - results.categories = results.categories.filter(category => category && !category.link); - - var categoriesData = [ - { value: 'all', text: '[[unread:all_categories]]' }, - { value: 'watched', text: '[[category:watched-categories]]' }, - ].concat(results.categories); - - - searchData.categories = categoriesData; - searchData.categoriesCount = Math.max(10, Math.min(20, categoriesData.length)); - searchData.breadcrumbs = helpers.buildBreadcrumbs([{ text: '[[global:search]]' }]); - searchData.expandSearch = !req.query.term; - - searchData.showAsPosts = !req.query.showAs || req.query.showAs === 'posts'; - searchData.showAsTopics = req.query.showAs === 'topics'; - searchData.title = '[[global:header.search]]'; - - searchData.searchDefaultSortBy = meta.config.searchDefaultSortBy || ''; - res.render('search', searchData); - }, - ], next); + const allowed = await privileges.global.can('search:content', req.uid); + if (!allowed) { + return helpers.notAllowed(req, res); + } + + if (req.query.categories && !Array.isArray(req.query.categories)) { + req.query.categories = [req.query.categories]; + } + if (req.query.hasTags && !Array.isArray(req.query.hasTags)) { + req.query.hasTags = [req.query.hasTags]; + } + + const data = { + query: req.query.term, + searchIn: req.query.in || 'posts', + matchWords: req.query.matchWords || 'all', + postedBy: req.query.by, + categories: req.query.categories, + searchChildren: req.query.searchChildren, + hasTags: req.query.hasTags, + replies: req.query.replies, + repliesFilter: req.query.repliesFilter, + timeRange: req.query.timeRange, + timeFilter: req.query.timeFilter, + sortBy: req.query.sortBy || meta.config.searchDefaultSortBy || '', + sortDirection: req.query.sortDirection, + page: page, + itemsPerPage: req.query.itemsPerPage, + uid: req.uid, + qs: req.query, + }; + + const [searchData, categoriesData] = await Promise.all([ + search.search(data), + buildCategories(req.uid, searchOnly), + ]); + + searchData.pagination = pagination.create(page, searchData.pageCount, req.query); + searchData.multiplePages = searchData.pageCount > 1; + searchData.search_query = validator.escape(String(req.query.term || '')); + searchData.term = req.query.term; + + if (searchOnly) { + return res.json(searchData); + } + + searchData.categories = categoriesData; + searchData.categoriesCount = Math.max(10, Math.min(20, categoriesData.length)); + searchData.breadcrumbs = helpers.buildBreadcrumbs([{ text: '[[global:search]]' }]); + searchData.expandSearch = !req.query.term; + + searchData.showAsPosts = !req.query.showAs || req.query.showAs === 'posts'; + searchData.showAsTopics = req.query.showAs === 'topics'; + searchData.title = '[[global:header.search]]'; + + searchData.searchDefaultSortBy = meta.config.searchDefaultSortBy || ''; + res.render('search', searchData); }; -function buildCategories(uid, searchOnly, callback) { +async function buildCategories(uid, searchOnly) { if (searchOnly) { - return setImmediate(callback, null, []); + return []; } - categories.buildForSelect(uid, 'read', callback); + let categoriesData = await categories.buildForSelect(uid, 'read'); + categoriesData = categoriesData.filter(category => category && !category.link); + return [ + { value: 'all', text: '[[unread:all_categories]]' }, + { value: 'watched', text: '[[category:watched-categories]]' }, + ].concat(categoriesData); }