From fcd4445a890fc40c81a6ce80b28625f2f0d2c249 Mon Sep 17 00:00:00 2001 From: Baris Usakli Date: Thu, 18 Jul 2019 13:22:17 -0400 Subject: [PATCH] feat: #7743, groups/delete,ownership,posts,user --- src/groups/delete.js | 102 +++++++++++++++------------------------- src/groups/ownership.js | 54 +++++++-------------- src/groups/posts.js | 73 +++++++++------------------- src/groups/user.js | 79 +++++++++---------------------- 4 files changed, 100 insertions(+), 208 deletions(-) diff --git a/src/groups/delete.js b/src/groups/delete.js index f605a044c3..573ea389aa 100644 --- a/src/groups/delete.js +++ b/src/groups/delete.js @@ -1,80 +1,56 @@ 'use strict'; -var async = require('async'); -var plugins = require('../plugins'); -var utils = require('../utils'); -var db = require('./../database'); -var batch = require('../batch'); +const plugins = require('../plugins'); +const utils = require('../utils'); +const db = require('./../database'); +const batch = require('../batch'); module.exports = function (Groups) { - Groups.destroy = function (groupNames, callback) { + Groups.destroy = async function (groupNames) { if (!Array.isArray(groupNames)) { groupNames = [groupNames]; } - var groupsData; - async.waterfall([ - function (next) { - Groups.getGroupsData(groupNames, next); - }, - function (_groupsData, next) { - groupsData = _groupsData.filter(Boolean); - if (!groupsData.length) { - return callback(); - } - - async.parallel([ - function (next) { - var keys = []; - groupNames.forEach(function (groupName) { - keys.push('group:' + groupName, - 'group:' + groupName + ':members', - 'group:' + groupName + ':pending', - 'group:' + groupName + ':invited', - 'group:' + groupName + ':owners', - 'group:' + groupName + ':member:pids' - ); - }); + let groupsData = await Groups.getGroupsData(groupNames); + groupsData = groupsData.filter(Boolean); + if (!groupsData.length) { + return; + } + const keys = []; + groupNames.forEach(function (groupName) { + keys.push('group:' + groupName, + 'group:' + groupName + ':members', + 'group:' + groupName + ':pending', + 'group:' + groupName + ':invited', + 'group:' + groupName + ':owners', + 'group:' + groupName + ':member:pids' + ); + }); + const sets = groupNames.map(groupName => groupName.toLowerCase() + ':' + groupName); + const fields = groupNames.map(groupName => utils.slugify(groupName)); - db.deleteAll(keys, next); - }, - function (next) { - db.sortedSetRemove([ - 'groups:createtime', - 'groups:visible:createtime', - 'groups:visible:memberCount', - ], groupNames, next); - }, - function (next) { - const keys = groupNames.map(groupName => groupName.toLowerCase() + ':' + groupName); - db.sortedSetRemove('groups:visible:name', keys, next); - }, - function (next) { - const fields = groupNames.map(groupName => utils.slugify(groupName)); - db.deleteObjectFields('groupslug:groupname', fields, next); - }, - function (next) { - removeGroupsFromPrivilegeGroups(groupNames, next); - }, - ], function (err) { - next(err); - }); - }, - function (next) { - Groups.resetCache(); - plugins.fireHook('action:groups.destroy', { groups: groupsData }); - next(); - }, - ], callback); + await Promise.all([ + db.deleteAll(keys), + db.sortedSetRemove([ + 'groups:createtime', + 'groups:visible:createtime', + 'groups:visible:memberCount', + ], groupNames), + db.sortedSetRemove('groups:visible:name', sets), + db.deleteObjectFields('groupslug:groupname', fields), + removeGroupsFromPrivilegeGroups(groupNames), + ]); + Groups.resetCache(); + plugins.fireHook('action:groups.destroy', { groups: groupsData }); }; - function removeGroupsFromPrivilegeGroups(groupNames, callback) { - batch.processSortedSet('groups:createtime', function (otherGroups, next) { + async function removeGroupsFromPrivilegeGroups(groupNames) { + await batch.processSortedSet('groups:createtime', async function (otherGroups) { const privilegeGroups = otherGroups.filter(group => Groups.isPrivilegeGroup(group)); const keys = privilegeGroups.map(group => 'group:' + group + ':members'); - db.sortedSetRemove(keys, groupNames, next); + await db.sortedSetRemove(keys, groupNames); }, { batch: 500, - }, callback); + }); } }; diff --git a/src/groups/ownership.js b/src/groups/ownership.js index 527a1b7d0e..728567b442 100644 --- a/src/groups/ownership.js +++ b/src/groups/ownership.js @@ -1,58 +1,40 @@ 'use strict'; -var async = require('async'); -var db = require('../database'); -var plugins = require('../plugins'); +const db = require('../database'); +const plugins = require('../plugins'); module.exports = function (Groups) { Groups.ownership = {}; - Groups.ownership.isOwner = function (uid, groupName, callback) { + Groups.ownership.isOwner = async function (uid, groupName) { if (!(parseInt(uid, 10) > 0)) { - return setImmediate(callback, null, false); + return false; } - db.isSetMember('group:' + groupName + ':owners', uid, callback); + return await db.isSetMember('group:' + groupName + ':owners', uid); }; - Groups.ownership.isOwners = function (uids, groupName, callback) { + Groups.ownership.isOwners = async function (uids, groupName) { if (!Array.isArray(uids)) { - return setImmediate(callback, null, []); + return []; } - db.isSetMembers('group:' + groupName + ':owners', uids, callback); + return await db.isSetMembers('group:' + groupName + ':owners', uids); }; - Groups.ownership.grant = function (toUid, groupName, callback) { + Groups.ownership.grant = async function (toUid, groupName) { // Note: No ownership checking is done here on purpose! - async.waterfall([ - function (next) { - db.setAdd('group:' + groupName + ':owners', toUid, next); - }, - function (next) { - plugins.fireHook('action:group.grantOwnership', { uid: toUid, groupName: groupName }); - next(); - }, - ], callback); + await db.setAdd('group:' + groupName + ':owners', toUid); + plugins.fireHook('action:group.grantOwnership', { uid: toUid, groupName: groupName }); }; - Groups.ownership.rescind = function (toUid, groupName, callback) { + Groups.ownership.rescind = async function (toUid, groupName) { // Note: No ownership checking is done here on purpose! - // If the owners set only contains one member, error out! - async.waterfall([ - function (next) { - db.setCount('group:' + groupName + ':owners', next); - }, - function (numOwners, next) { - if (numOwners <= 1) { - return next(new Error('[[error:group-needs-owner]]')); - } - db.setRemove('group:' + groupName + ':owners', toUid, next); - }, - function (next) { - plugins.fireHook('action:group.rescindOwnership', { uid: toUid, groupName: groupName }); - next(); - }, - ], callback); + const numOwners = await db.setCount('group:' + groupName + ':owners'); + if (numOwners <= 1) { + throw new Error('[[error:group-needs-owner]]'); + } + db.setRemove('group:' + groupName + ':owners', toUid); + plugins.fireHook('action:group.rescindOwnership', { uid: toUid, groupName: groupName }); }; }; diff --git a/src/groups/posts.js b/src/groups/posts.js index 287a0a1683..a96cd9e217 100644 --- a/src/groups/posts.js +++ b/src/groups/posts.js @@ -1,65 +1,36 @@ 'use strict'; -var async = require('async'); - -var db = require('../database'); -var privileges = require('../privileges'); -var posts = require('../posts'); +const db = require('../database'); +const privileges = require('../privileges'); +const posts = require('../posts'); module.exports = function (Groups) { - Groups.onNewPostMade = function (postData, callback) { + Groups.onNewPostMade = async function (postData) { if (!parseInt(postData.uid, 10)) { - return setImmediate(callback); + return; } - var groupNames; - async.waterfall([ - function (next) { - Groups.getUserGroupMembership('groups:visible:createtime', [postData.uid], next); - }, - function (_groupNames, next) { - groupNames = _groupNames[0]; + let groupNames = await Groups.getUserGroupMembership('groups:visible:createtime', [postData.uid]); + groupNames = groupNames[0]; - const keys = groupNames.map(groupName => 'group:' + groupName + ':member:pids'); - db.sortedSetsAdd(keys, postData.timestamp, postData.pid, next); - }, - function (next) { - async.each(groupNames, function (groupName, next) { - truncateMemberPosts(groupName, next); - }, next); - }, - ], callback); + const keys = groupNames.map(groupName => 'group:' + groupName + ':member:pids'); + await db.sortedSetsAdd(keys, postData.timestamp, postData.pid); + await Promise.all(groupNames.map(name => truncateMemberPosts(name))); }; - function truncateMemberPosts(groupName, callback) { - async.waterfall([ - function (next) { - db.getSortedSetRevRange('group:' + groupName + ':member:pids', 10, 10, next); - }, - function (lastPid, next) { - lastPid = lastPid[0]; - if (!parseInt(lastPid, 10)) { - return callback(); - } - db.sortedSetScore('group:' + groupName + ':member:pids', lastPid, next); - }, - function (score, next) { - db.sortedSetsRemoveRangeByScore(['group:' + groupName + ':member:pids'], '-inf', score, next); - }, - ], callback); + async function truncateMemberPosts(groupName) { + let lastPid = await db.getSortedSetRevRange('group:' + groupName + ':member:pids', 10, 10); + lastPid = lastPid[0]; + if (!parseInt(lastPid, 10)) { + return; + } + const score = await db.sortedSetScore('group:' + groupName + ':member:pids', lastPid); + await db.sortedSetsRemoveRangeByScore(['group:' + groupName + ':member:pids'], '-inf', score); } - Groups.getLatestMemberPosts = function (groupName, max, uid, callback) { - async.waterfall([ - function (next) { - db.getSortedSetRevRange('group:' + groupName + ':member:pids', 0, max - 1, next); - }, - function (pids, next) { - privileges.posts.filter('topics:read', pids, uid, next); - }, - function (pids, next) { - posts.getPostSummaryByPids(pids, uid, { stripTags: false }, next); - }, - ], callback); + Groups.getLatestMemberPosts = async function (groupName, max, uid) { + let pids = await db.getSortedSetRevRange('group:' + groupName + ':member:pids', 0, max - 1); + pids = await privileges.posts.filter('topics:read', pids, uid); + return await posts.getPostSummaryByPids(pids, uid, { stripTags: false }); }; }; diff --git a/src/groups/user.js b/src/groups/user.js index c959add132..4cb01ce9e2 100644 --- a/src/groups/user.js +++ b/src/groups/user.js @@ -1,71 +1,34 @@ 'use strict'; -var async = require('async'); - -var db = require('../database'); -var user = require('../user'); +const db = require('../database'); +const user = require('../user'); module.exports = function (Groups) { - Groups.getUsersFromSet = function (set, fields, callback) { - if (typeof fields === 'function') { - callback = fields; - fields = null; + Groups.getUsersFromSet = async function (set, fields) { + const uids = await db.getSetMembers(set); + + if (fields) { + return await user.getUsersFields(uids, fields); } - async.waterfall([ - function (next) { - db.getSetMembers(set, next); - }, - function (uids, next) { - if (fields) { - user.getUsersFields(uids, fields, callback); - } else { - user.getUsersData(uids, next); - } - }, - ], callback); + return await user.getUsersData(uids); }; - Groups.getUserGroups = function (uids, callback) { - Groups.getUserGroupsFromSet('groups:visible:createtime', uids, callback); + Groups.getUserGroups = async function (uids) { + return await Groups.getUserGroupsFromSet('groups:visible:createtime', uids); }; - Groups.getUserGroupsFromSet = function (set, uids, callback) { - async.waterfall([ - function (next) { - Groups.getUserGroupMembership(set, uids, next); - }, - function (memberOf, next) { - async.map(memberOf, function (memberOf, next) { - Groups.getGroupsData(memberOf, next); - }, next); - }, - ], callback); + Groups.getUserGroupsFromSet = async function (set, uids) { + const memberOf = await Groups.getUserGroupMembership(set, uids); + return await Promise.all(memberOf.map(memberOf => Groups.getGroupsData(memberOf))); }; - Groups.getUserGroupMembership = function (set, uids, callback) { - async.waterfall([ - function (next) { - db.getSortedSetRevRange(set, 0, -1, next); - }, - function (groupNames, next) { - async.map(uids, function (uid, next) { - async.waterfall([ - function (next) { - Groups.isMemberOfGroups(uid, groupNames, next); - }, - function (isMembers, next) { - var memberOf = []; - isMembers.forEach(function (isMember, index) { - if (isMember) { - memberOf.push(groupNames[index]); - } - }); - - next(null, memberOf); - }, - ], next); - }, next); - }, - ], callback); + Groups.getUserGroupMembership = async function (set, uids) { + const groupNames = await db.getSortedSetRevRange(set, 0, -1); + return await Promise.all(uids.map(uid => findUserGroups(uid, groupNames))); }; + + async function findUserGroups(uid, groupNames) { + const isMembers = await Groups.isMemberOfGroups(uid, groupNames); + return groupNames.filter((name, i) => isMembers[i]); + } };