From 52b2d670e52dd96a236a64a3b5c9c0e812538c7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 13 Sep 2019 23:34:52 -0400 Subject: [PATCH] refactor: async/await --- src/socket.io/categories.js | 298 ++++++++++++++---------------------- src/socket.io/flags.js | 116 +++++--------- 2 files changed, 156 insertions(+), 258 deletions(-) diff --git a/src/socket.io/categories.js b/src/socket.io/categories.js index c65cbba9be..67a55b3662 100644 --- a/src/socket.io/categories.js +++ b/src/socket.io/categories.js @@ -1,223 +1,153 @@ 'use strict'; -var async = require('async'); +const categories = require('../categories'); +const privileges = require('../privileges'); +const user = require('../user'); +const topics = require('../topics'); +const apiController = require('../controllers/api'); -var categories = require('../categories'); -var privileges = require('../privileges'); -var user = require('../user'); -var topics = require('../topics'); -var apiController = require('../controllers/api'); +const SocketCategories = module.exports; -var SocketCategories = module.exports; - -SocketCategories.getRecentReplies = function (socket, cid, callback) { - categories.getRecentReplies(cid, socket.uid, 4, callback); +SocketCategories.getRecentReplies = async function (socket, cid) { + return await categories.getRecentReplies(cid, socket.uid, 4); }; -SocketCategories.get = function (socket, data, callback) { - async.waterfall([ - function (next) { - async.parallel({ - isAdmin: async.apply(user.isAdministrator, socket.uid), - categories: function (next) { - async.waterfall([ - async.apply(categories.getCidsByPrivilege, 'categories:cid', socket.uid, 'find'), - async.apply(categories.getCategoriesData), - ], next); - }, - }, next); - }, - function (results, next) { - results.categories = results.categories.filter(function (category) { - return category && (!category.disabled || results.isAdmin); - }); - - next(null, results.categories); - }, - ], callback); +SocketCategories.get = async function (socket) { + async function getCategories() { + const cids = await categories.getCidsByPrivilege('categories:cid', socket.uid, 'find'); + return await categories.getCategoriesData(cids); + } + const [isAdmin, categoriesData] = await Promise.all([ + user.isAdministrator(socket.uid), + getCategories(), + ]); + return categoriesData.filter(category => category && (!category.disabled || isAdmin)); }; -SocketCategories.getWatchedCategories = function (socket, data, callback) { - async.waterfall([ - function (next) { - async.parallel({ - categories: async.apply(categories.getCategoriesByPrivilege, 'cid:0:children', socket.uid, 'find'), - ignoredCids: async.apply(user.getIgnoredCategories, socket.uid), - }, next); - }, - function (results, next) { - var watchedCategories = results.categories.filter(function (category) { - return category && !results.ignoredCids.includes(String(category.cid)); - }); - - next(null, watchedCategories); - }, - ], callback); +SocketCategories.getWatchedCategories = async function (socket) { + const [categoriesData, ignoredCids] = await Promise.all([ + categories.getCategoriesByPrivilege('cid:0:children', socket.uid, 'find'), + user.getIgnoredCategories(socket.uid), + ]); + return categoriesData.filter(category => category && !ignoredCids.includes(String(category.cid))); }; -SocketCategories.loadMore = function (socket, data, callback) { +SocketCategories.loadMore = async function (socket, data) { if (!data) { - return callback(new Error('[[error:invalid-data]]')); + throw new Error('[[error:invalid-data]]'); } data.query = data.query || {}; - var userPrivileges; - async.waterfall([ - function (next) { - async.parallel({ - privileges: function (next) { - privileges.categories.get(data.cid, socket.uid, next); - }, - settings: function (next) { - user.getSettings(socket.uid, next); - }, - targetUid: function (next) { - if (data.query.author) { - user.getUidByUserslug(data.query.author, next); - } else { - next(); - } - }, - }, next); - }, - function (results, next) { - userPrivileges = results.privileges; - if (!userPrivileges.read) { - return callback(new Error('[[error:no-privileges]]')); - } - var infScrollTopicsPerPage = 20; - var sort = data.sort || data.categoryTopicSort; - - var start = Math.max(0, parseInt(data.after, 10)); - - if (data.direction === -1) { - start -= infScrollTopicsPerPage; - } - - var stop = start + infScrollTopicsPerPage - 1; - - start = Math.max(0, start); - stop = Math.max(0, stop); - categories.getCategoryTopics({ - uid: socket.uid, - cid: data.cid, - start: start, - stop: stop, - sort: sort, - settings: results.settings, - query: data.query, - tag: data.query.tag, - targetUid: results.targetUid, - }, next); - }, - function (data, next) { - categories.modifyTopicsByPrivilege(data.topics, userPrivileges); - - data.privileges = userPrivileges; - data.template = { - category: true, - name: 'category', - }; - - next(null, data); - }, - ], callback); + const [userPrivileges, settings, targetUid] = await Promise.all([ + privileges.categories.get(data.cid, socket.uid), + user.getSettings(socket.uid), + user.getUidByUserslug(data.query.author), + ]); + + if (!userPrivileges.read) { + throw new Error('[[error:no-privileges]]'); + } + + const infScrollTopicsPerPage = 20; + const sort = data.sort || data.categoryTopicSort; + + let start = Math.max(0, parseInt(data.after, 10)); + + if (data.direction === -1) { + start -= infScrollTopicsPerPage; + } + + let stop = start + infScrollTopicsPerPage - 1; + + start = Math.max(0, start); + stop = Math.max(0, stop); + const result = await categories.getCategoryTopics({ + uid: socket.uid, + cid: data.cid, + start: start, + stop: stop, + sort: sort, + settings: settings, + query: data.query, + tag: data.query.tag, + targetUid: targetUid, + }); + categories.modifyTopicsByPrivilege(data.topics, userPrivileges); + + result.privileges = userPrivileges; + result.template = { + category: true, + name: 'category', + }; + return result; }; -SocketCategories.getTopicCount = function (socket, cid, callback) { - categories.getCategoryField(cid, 'topic_count', callback); +SocketCategories.getTopicCount = async function (socket, cid) { + return await categories.getCategoryField(cid, 'topic_count'); }; -SocketCategories.getCategoriesByPrivilege = function (socket, privilege, callback) { - categories.getCategoriesByPrivilege('categories:cid', socket.uid, privilege, callback); +SocketCategories.getCategoriesByPrivilege = async function (socket, privilege) { + return await categories.getCategoriesByPrivilege('categories:cid', socket.uid, privilege); }; -SocketCategories.getMoveCategories = function (socket, data, callback) { - SocketCategories.getSelectCategories(socket, data, callback); +SocketCategories.getMoveCategories = async function (socket, data) { + return await SocketCategories.getSelectCategories(socket, data); }; -SocketCategories.getSelectCategories = function (socket, data, callback) { - async.waterfall([ - function (next) { - async.parallel({ - isAdmin: async.apply(user.isAdministrator, socket.uid), - categories: function (next) { - categories.buildForSelect(socket.uid, 'find', next); - }, - }, next); - }, - function (results, next) { - results.categories = results.categories.filter(function (category) { - return category && (!category.disabled || results.isAdmin) && !category.link; - }); - - next(null, results.categories); - }, - ], callback); +SocketCategories.getSelectCategories = async function (socket) { + const [isAdmin, categoriesData] = await Promise.all([ + user.isAdministrator(socket.uid), + categories.buildForSelect(socket.uid, 'find'), + ]); + return categoriesData.filter(category => category && (!category.disabled || isAdmin) && !category.link); }; -SocketCategories.setWatchState = function (socket, data, callback) { +SocketCategories.setWatchState = async function (socket, data) { if (!data || !data.cid || !data.state) { - return callback(new Error('[[error:invalid-data]]')); + throw new Error('[[error:invalid-data]]'); } - ignoreOrWatch(function (uid, cid, next) { - user.setCategoryWatchState(uid, cid, categories.watchStates[data.state], next); - }, socket, data, callback); + await ignoreOrWatch(async function (uid, cid) { + await user.setCategoryWatchState(uid, cid, categories.watchStates[data.state]); + }, socket, data); }; -SocketCategories.watch = function (socket, data, callback) { - ignoreOrWatch(user.watchCategory, socket, data, callback); +SocketCategories.watch = async function (socket, data) { + await ignoreOrWatch(user.watchCategory, socket, data); }; -SocketCategories.ignore = function (socket, data, callback) { - ignoreOrWatch(user.ignoreCategory, socket, data, callback); +SocketCategories.ignore = async function (socket, data) { + await ignoreOrWatch(user.ignoreCategory, socket, data); }; -function ignoreOrWatch(fn, socket, data, callback) { - var targetUid = socket.uid; - var cids = [parseInt(data.cid, 10)]; +async function ignoreOrWatch(fn, socket, data) { + let targetUid = socket.uid; + const cids = [parseInt(data.cid, 10)]; if (data.hasOwnProperty('uid')) { targetUid = data.uid; } - - async.waterfall([ - function (next) { - user.isAdminOrGlobalModOrSelf(socket.uid, targetUid, next); - }, - function (next) { - categories.getAllCidsFromSet('categories:cid', next); - }, - function (cids, next) { - categories.getCategoriesFields(cids, ['cid', 'parentCid'], next); - }, - function (categoryData, next) { - // filter to subcategories of cid - var cat; - do { - cat = categoryData.find(function (c) { - return !cids.includes(c.cid) && cids.includes(c.parentCid); - }); - if (cat) { - cids.push(cat.cid); - } - } while (cat); - - async.each(cids, function (cid, next) { - fn(targetUid, cid, next); - }, next); - }, - function (next) { - topics.pushUnreadCount(targetUid, next); - }, - function (next) { - next(null, cids); - }, - ], callback); + await user.isAdminOrGlobalModOrSelf(socket.uid, targetUid); + const allCids = await categories.getAllCidsFromSet('categories:cid'); + const categoryData = await categories.getCategoriesFields(allCids, ['cid', 'parentCid']); + + // filter to subcategories of cid + let cat; + do { + cat = categoryData.find(c => !cids.includes(c.cid) && cids.includes(c.parentCid)); + if (cat) { + cids.push(cat.cid); + } + } while (cat); + + await Promise.all(cids.map(cid => fn(targetUid, cid))); + await topics.pushUnreadCount(targetUid); + return cids; } -SocketCategories.isModerator = function (socket, cid, callback) { - user.isModerator(socket.uid, cid, callback); +SocketCategories.isModerator = async function (socket, cid) { + return await user.isModerator(socket.uid, cid); }; -SocketCategories.getCategory = function (socket, cid, callback) { - apiController.getCategoryData(cid, socket.uid, callback); +SocketCategories.getCategory = async function (socket, cid) { + return await apiController.getCategoryData(cid, socket.uid); }; + +require('../promisify')(SocketCategories); diff --git a/src/socket.io/flags.js b/src/socket.io/flags.js index 6c3e7725ca..90115e470e 100644 --- a/src/socket.io/flags.js +++ b/src/socket.io/flags.js @@ -1,97 +1,65 @@ 'use strict'; -var async = require('async'); +const user = require('../user'); +const flags = require('../flags'); -var user = require('../user'); -var flags = require('../flags'); +const SocketFlags = module.exports; -var SocketFlags = module.exports; - -SocketFlags.create = function (socket, data, callback) { +SocketFlags.create = async function (socket, data) { if (!socket.uid) { - return callback(new Error('[[error:not-logged-in]]')); + throw new Error('[[error:not-logged-in]]'); } if (!data || !data.type || !data.id || !data.reason) { - return callback(new Error('[[error:invalid-data]]')); + throw new Error('[[error:invalid-data]]'); } + await flags.validate({ + uid: socket.uid, + type: data.type, + id: data.id, + }); - async.waterfall([ - async.apply(flags.validate, { - uid: socket.uid, - type: data.type, - id: data.id, - }), - function (next) { - // If we got here, then no errors occurred - flags.create(data.type, data.id, socket.uid, data.reason, next); - }, - function (flagObj, next) { - flags.notify(flagObj, socket.uid); - next(null, flagObj); - }, - ], callback); + const flagObj = await flags.create(data.type, data.id, socket.uid, data.reason); + await flags.notify(flagObj, socket.uid); + return flagObj; }; -SocketFlags.update = function (socket, data, callback) { +SocketFlags.update = async function (socket, data) { if (!data || !(data.flagId && data.data)) { - return callback(new Error('[[error:invalid-data]]')); + throw new Error('[[error:invalid-data]]'); } - var payload = {}; - - async.waterfall([ - function (next) { - async.parallel([ - async.apply(user.isAdminOrGlobalMod, socket.uid), - async.apply(user.isModeratorOfAnyCategory, socket.uid), - ], function (err, results) { - next(err, results[0] || results[1]); - }); - }, - function (allowed, next) { - if (!allowed) { - return next(new Error('[[no-privileges]]')); - } - - // Translate form data into object - payload = data.data.reduce(function (memo, cur) { - memo[cur.name] = cur.value; - return memo; - }, payload); + const allowed = await user.isPrivileged(socket.uid); + if (!allowed) { + throw new Error('[[no-privileges]]'); + } + let payload = {}; + // Translate form data into object + payload = data.data.reduce(function (memo, cur) { + memo[cur.name] = cur.value; + return memo; + }, payload); - flags.update(data.flagId, socket.uid, payload, next); - }, - async.apply(flags.getHistory, data.flagId), - ], callback); + await flags.update(data.flagId, socket.uid, payload); + return await flags.getHistory(data.flagId); }; -SocketFlags.appendNote = function (socket, data, callback) { +SocketFlags.appendNote = async function (socket, data) { if (!data || !(data.flagId && data.note)) { - return callback(new Error('[[error:invalid-data]]')); + throw new Error('[[error:invalid-data]]'); } - async.waterfall([ - function (next) { - async.parallel([ - async.apply(user.isAdminOrGlobalMod, socket.uid), - async.apply(user.isModeratorOfAnyCategory, socket.uid), - ], function (err, results) { - next(err, results[0] || results[1]); - }); - }, - function (allowed, next) { - if (!allowed) { - return next(new Error('[[no-privileges]]')); - } + const allowed = await user.isPrivileged(socket.uid); + if (!allowed) { + throw new Error('[[no-privileges]]'); + } + await flags.appendNote(data.flagId, socket.uid, data.note); - flags.appendNote(data.flagId, socket.uid, data.note, next); - }, - function (next) { - async.parallel({ - notes: async.apply(flags.getNotes, data.flagId), - history: async.apply(flags.getHistory, data.flagId), - }, next); - }, - ], callback); + const [notes, history] = await Promise.all([ + flags.getNotes(data.flagId), + flags.getHistory(data.flagId), + ]); + return { notes: notes, history: history }; }; + +require('../promisify')(SocketFlags);