refactor: async/await, remove dupe code for homepage routes

v1.18.x
Barış Soner Uşaklı 6 years ago
parent 1a2a381ae3
commit c9250a01a2

@ -10,8 +10,6 @@ const user = require('../../user');
const languages = require('../../languages'); const languages = require('../../languages');
const meta = require('../../meta'); const meta = require('../../meta');
const plugins = require('../../plugins'); const plugins = require('../../plugins');
const privileges = require('../../privileges');
const categories = require('../../categories');
const notifications = require('../../notifications'); const notifications = require('../../notifications');
const db = require('../../database'); const db = require('../../database');
const helpers = require('../helpers'); const helpers = require('../helpers');
@ -241,49 +239,12 @@ async function getNotificationSettings(userData) {
} }
async function getHomePageRoutes(userData) { async function getHomePageRoutes(userData) {
let cids = await categories.getAllCidsFromSet('cid:0:children'); let routes = await helpers.getHomePageRoutes(userData.uid);
cids = await privileges.categories.filterCids('find', cids, userData.uid);
let categoryData = await categories.getCategoriesFields(cids, ['name', 'slug']);
categoryData = categoryData.map(function (category) {
return {
route: 'category/' + category.slug,
name: 'Category: ' + category.name,
};
});
const data = await plugins.fireHook('filter:homepage.get', { routes: [
{
route: 'categories',
name: 'Categories',
},
{
route: 'unread',
name: 'Unread',
},
{
route: 'recent',
name: 'Recent',
},
{
route: 'top',
name: 'Top',
},
{
route: 'popular',
name: 'Popular',
},
].concat(categoryData, [
{
route: 'custom',
name: 'Custom',
},
]) });
// Set selected for each route // Set selected for each route
var customIdx; var customIdx;
var hasSelected = false; var hasSelected = false;
data.routes = data.routes.map(function (route, idx) { routes = routes.map(function (route, idx) {
if (route.route === userData.settings.homePageRoute) { if (route.route === userData.settings.homePageRoute) {
route.selected = true; route.selected = true;
hasSelected = true; hasSelected = true;
@ -299,8 +260,8 @@ async function getHomePageRoutes(userData) {
}); });
if (!hasSelected && customIdx && userData.settings.homePageRoute !== 'none') { if (!hasSelected && customIdx && userData.settings.homePageRoute !== 'none') {
data.routes[customIdx].selected = true; routes[customIdx].selected = true;
} }
return data.routes; return routes;
} }

@ -1,33 +1,28 @@
'use strict'; 'use strict';
var async = require('async'); const json2csv = require('json-2-csv').json2csv;
var json2csv = require('json-2-csv').json2csv; const util = require('util');
var meta = require('../../meta'); const meta = require('../../meta');
var analytics = require('../../analytics'); const analytics = require('../../analytics');
const utils = require('../../utils');
var errorsController = module.exports; const errorsController = module.exports;
errorsController.get = function (req, res, next) { errorsController.get = async function (req, res) {
async.waterfall([ const data = await utils.promiseParallel({
function (next) { 'not-found': meta.errors.get(true),
async.parallel({ analytics: analytics.getErrorAnalytics(),
'not-found': async.apply(meta.errors.get, true), });
analytics: async.apply(analytics.getErrorAnalytics), res.render('admin/advanced/errors', data);
}, next);
},
function (data) {
res.render('admin/advanced/errors', data);
},
], next);
}; };
errorsController.export = function (req, res, next) { const json2csvAsync = util.promisify(function (data, callback) {
async.waterfall([ json2csv(data, (err, output) => callback(err, output));
async.apply(meta.errors.get, false), });
async.apply(json2csv),
function (csv) { errorsController.export = async function (req, res) {
res.set('Content-Type', 'text/csv').set('Content-Disposition', 'attachment; filename="404.csv"').send(csv); const data = await meta.errors.get(false);
}, const csv = await json2csvAsync(data);
], next); res.set('Content-Type', 'text/csv').set('Content-Disposition', 'attachment; filename="404.csv"').send(csv);
}; };

@ -1,55 +1,44 @@
'use strict'; 'use strict';
var async = require('async'); const db = require('../../database');
const events = require('../../events');
const pagination = require('../../pagination');
var db = require('../../database'); const eventsController = module.exports;
var events = require('../../events');
var pagination = require('../../pagination');
var eventsController = module.exports; eventsController.get = async function (req, res) {
const page = parseInt(req.query.page, 10) || 1;
eventsController.get = function (req, res, next) { const itemsPerPage = parseInt(req.query.perPage, 10) || 20;
var page = parseInt(req.query.page, 10) || 1; const start = (page - 1) * itemsPerPage;
var itemsPerPage = parseInt(req.query.perPage, 10) || 20; const stop = start + itemsPerPage - 1;
var start = (page - 1) * itemsPerPage;
var stop = start + itemsPerPage - 1;
// Limit by date // Limit by date
var from = req.query.start ? new Date(req.query.start) || undefined : undefined; let from = req.query.start ? new Date(req.query.start) || undefined : undefined;
var to = req.query.end ? new Date(req.query.end) || undefined : new Date(); let to = req.query.end ? new Date(req.query.end) || undefined : new Date();
from = from && from.setHours(0, 0, 0, 0); // setHours returns a unix timestamp (Number, not Date) from = from && from.setHours(0, 0, 0, 0); // setHours returns a unix timestamp (Number, not Date)
to = to && to.setHours(23, 59, 59, 999); // setHours returns a unix timestamp (Number, not Date) to = to && to.setHours(23, 59, 59, 999); // setHours returns a unix timestamp (Number, not Date)
var currentFilter = req.query.type || ''; const currentFilter = req.query.type || '';
async.waterfall([ const [eventCount, eventData] = await Promise.all([
function (next) { db.sortedSetCount('events:time' + (currentFilter ? ':' + currentFilter : ''), from || '-inf', to),
async.parallel({ events.getEvents(currentFilter, start, stop, from || '-inf', to),
eventCount: function (next) { ]);
db.sortedSetCount('events:time' + (currentFilter ? ':' + currentFilter : ''), from || '-inf', to, next);
}, const types = [''].concat(events.types).map(function (type) {
events: function (next) { return {
events.getEvents(currentFilter, start, stop, from || '-inf', to, next); value: type,
}, name: type || 'all',
}, next); selected: type === currentFilter,
}, };
function (results) { });
var types = [''].concat(events.types).map(function (type) {
return { const pageCount = Math.max(1, Math.ceil(eventCount / itemsPerPage));
value: type,
name: type || 'all', res.render('admin/advanced/events', {
selected: type === currentFilter, events: eventData,
}; pagination: pagination.create(page, pageCount, req.query),
}); types: types,
query: req.query,
var pageCount = Math.max(1, Math.ceil(results.eventCount / itemsPerPage)); });
res.render('admin/advanced/events', {
events: results.events,
pagination: pagination.create(page, pageCount, req.query),
types: types,
query: req.query,
});
},
], next);
}; };

@ -1,91 +1,62 @@
'use strict'; 'use strict';
var async = require('async'); const validator = require('validator');
var validator = require('validator');
const db = require('../../database');
var db = require('../../database'); const groups = require('../../groups');
var groups = require('../../groups'); const meta = require('../../meta');
var meta = require('../../meta'); const pagination = require('../../pagination');
var pagination = require('../../pagination');
const groupsController = module.exports;
var groupsController = module.exports;
groupsController.list = async function (req, res) {
groupsController.list = function (req, res, next) { const page = parseInt(req.query.page, 10) || 1;
var page = parseInt(req.query.page, 10) || 1; const groupsPerPage = 20;
var groupsPerPage = 20;
var pageCount = 0; let groupNames = await getGroupNames();
const pageCount = Math.ceil(groupNames.length / groupsPerPage);
async.waterfall([ const start = (page - 1) * groupsPerPage;
function (next) { const stop = start + groupsPerPage - 1;
getGroupNames(next);
}, groupNames = groupNames.slice(start, stop + 1);
function (groupNames, next) { const groupData = await groups.getGroupsData(groupNames);
pageCount = Math.ceil(groupNames.length / groupsPerPage); res.render('admin/manage/groups', {
groups: groupData,
var start = (page - 1) * groupsPerPage; pagination: pagination.create(page, pageCount),
var stop = start + groupsPerPage - 1; yourid: req.uid,
});
groupNames = groupNames.slice(start, stop + 1);
groups.getGroupsData(groupNames, next);
},
function (groupData) {
res.render('admin/manage/groups', {
groups: groupData,
pagination: pagination.create(page, pageCount),
yourid: req.uid,
});
},
], next);
}; };
groupsController.get = function (req, res, callback) { groupsController.get = async function (req, res, next) {
var groupName = req.params.name; const groupName = req.params.name;
async.waterfall([ const [groupNames, group] = await Promise.all([
function (next) { getGroupNames(),
async.parallel({ groups.get(groupName, { uid: req.uid, truncateUserList: true, userListCount: 20 }),
groupNames: function (next) { ]);
getGroupNames(next);
}, if (!group) {
group: function (next) { return next();
groups.get(groupName, { uid: req.uid, truncateUserList: true, userListCount: 20 }, next); }
}, group.isOwner = true;
}, next);
}, const groupNameData = groupNames.map(function (name) {
function (result) { return {
if (!result.group) { encodedName: encodeURIComponent(name),
return callback(); displayName: validator.escape(String(name)),
} selected: name === groupName,
result.group.isOwner = true; };
});
result.groupNames = result.groupNames.map(function (name) {
return { res.render('admin/manage/group', {
encodedName: encodeURIComponent(name), group: group,
displayName: validator.escape(String(name)), groupNames: groupNameData,
selected: name === groupName, allowPrivateGroups: meta.config.allowPrivateGroups,
}; maximumGroupNameLength: meta.config.maximumGroupNameLength,
}); maximumGroupTitleLength: meta.config.maximumGroupTitleLength,
});
res.render('admin/manage/group', {
group: result.group,
groupNames: result.groupNames,
allowPrivateGroups: meta.config.allowPrivateGroups,
maximumGroupNameLength: meta.config.maximumGroupNameLength,
maximumGroupTitleLength: meta.config.maximumGroupTitleLength,
});
},
], callback);
}; };
function getGroupNames(callback) { async function getGroupNames() {
async.waterfall([ const groupNames = await db.getSortedSetRange('groups:createtime', 0, -1);
function (next) { return groupNames.filter(name => name !== 'registered-users' && !groups.isPrivilegeGroup(name));
db.getSortedSetRange('groups:createtime', 0, -1, next);
},
function (groupNames, next) {
groupNames = groupNames.filter(function (name) {
return name !== 'registered-users' && !groups.isPrivilegeGroup(name);
});
next(null, groupNames);
},
], callback);
} }

@ -1,58 +1,10 @@
'use strict'; 'use strict';
var async = require('async'); const helpers = require('../helpers');
var categories = require('../../categories'); const homePageController = module.exports;
var privileges = require('../../privileges');
var plugins = require('../../plugins');
var homePageController = module.exports; homePageController.get = async function (req, res) {
const routes = await helpers.getHomePageRoutes(req.uid);
homePageController.get = function (req, res, next) { res.render('admin/general/homepage', { routes: routes });
async.waterfall([
function (next) {
categories.getAllCidsFromSet('categories:cid', next);
},
function (cids, next) {
privileges.categories.filterCids('find', cids, 0, next);
},
function (cids, next) {
categories.getCategoriesFields(cids, ['name', 'slug'], next);
},
function (categoryData, next) {
categoryData = categoryData.map(function (category) {
return {
route: 'category/' + category.slug,
name: 'Category: ' + category.name,
};
});
plugins.fireHook('filter:homepage.get', { routes: [
{
route: 'categories',
name: 'Categories',
},
{
route: 'recent',
name: 'Recent',
},
{
route: 'top',
name: 'Top',
},
{
route: 'popular',
name: 'Popular',
},
].concat(categoryData) }, next);
},
function (data) {
data.routes.push({
route: '',
name: 'Custom',
});
res.render('admin/general/homepage', data);
},
], next);
}; };

@ -1,14 +1,14 @@
'use strict'; 'use strict';
const validator = require('validator'); const validator = require('validator');
var plugins = require('../../plugins'); const plugins = require('../../plugins');
var hooksController = module.exports; const hooksController = module.exports;
hooksController.get = function (req, res) { hooksController.get = function (req, res) {
var hooks = []; const hooks = [];
Object.keys(plugins.loadedHooks).forEach(function (key, hookIndex) { Object.keys(plugins.loadedHooks).forEach(function (key, hookIndex) {
var current = { const current = {
hookName: key, hookName: key,
methods: [], methods: [],
index: 'hook-' + hookIndex, index: 'hook-' + hookIndex,

@ -1,27 +1,24 @@
'use strict'; 'use strict';
var async = require('async'); const os = require('os');
var os = require('os'); const winston = require('winston');
var winston = require('winston'); const nconf = require('nconf');
var nconf = require('nconf'); const exec = require('child_process').exec;
var exec = require('child_process').exec;
var pubsub = require('../../pubsub'); const pubsub = require('../../pubsub');
var rooms = require('../../socket.io/admin/rooms'); const rooms = require('../../socket.io/admin/rooms');
var infoController = module.exports; const infoController = module.exports;
var info = {}; let info = {};
infoController.get = function (req, res) { infoController.get = function (req, res) {
info = {}; info = {};
pubsub.publish('sync:node:info:start'); pubsub.publish('sync:node:info:start');
var timeoutMS = 1000; const timeoutMS = 1000;
setTimeout(function () { setTimeout(function () {
var data = []; const data = [];
Object.keys(info).forEach(function (key) { Object.keys(info).forEach(key => data.push(info[key]));
data.push(info[key]);
});
data.sort(function (a, b) { data.sort(function (a, b) {
if (a.id < b.id) { if (a.id < b.id) {
return -1; return -1;
@ -42,22 +39,22 @@ infoController.get = function (req, res) {
}, timeoutMS); }, timeoutMS);
}; };
pubsub.on('sync:node:info:start', function () { pubsub.on('sync:node:info:start', async function () {
getNodeInfo(function (err, data) { try {
if (err) { const data = await getNodeInfo();
return winston.error(err);
}
data.id = os.hostname() + ':' + nconf.get('port'); data.id = os.hostname() + ':' + nconf.get('port');
pubsub.publish('sync:node:info:end', { data: data, id: data.id }); pubsub.publish('sync:node:info:end', { data: data, id: data.id });
}); } catch (err) {
winston.error(err);
}
}); });
pubsub.on('sync:node:info:end', function (data) { pubsub.on('sync:node:info:end', function (data) {
info[data.id] = data.data; info[data.id] = data.data;
}); });
function getNodeInfo(callback) { async function getNodeInfo() {
var data = { const data = {
process: { process: {
port: nconf.get('port'), port: nconf.get('port'),
pid: process.pid, pid: process.pid,
@ -82,26 +79,16 @@ function getNodeInfo(callback) {
data.process.cpuUsage.system = data.process.cpuUsage.system.toFixed(2); data.process.cpuUsage.system = data.process.cpuUsage.system.toFixed(2);
data.process.memoryUsage.humanReadable = (data.process.memoryUsage.rss / (1024 * 1024)).toFixed(2); data.process.memoryUsage.humanReadable = (data.process.memoryUsage.rss / (1024 * 1024)).toFixed(2);
async.waterfall([ const [stats, gitInfo] = await Promise.all([
function (next) { rooms.getLocalStats(),
async.parallel({ getGitInfo(),
stats: function (next) { ]);
rooms.getLocalStats(next); data.git = gitInfo;
}, data.stats = stats;
gitInfo: function (next) { return data;
getGitInfo(next);
},
}, next);
},
function (results, next) {
data.git = results.gitInfo;
data.stats = results.stats;
next(null, data);
},
], callback);
} }
function getGitInfo(callback) { async function getGitInfo() {
function get(cmd, callback) { function get(cmd, callback) {
exec(cmd, function (err, stdout) { exec(cmd, function (err, stdout) {
if (err) { if (err) {
@ -110,12 +97,10 @@ function getGitInfo(callback) {
callback(null, stdout ? stdout.replace(/\n$/, '') : 'no-git-info'); callback(null, stdout ? stdout.replace(/\n$/, '') : 'no-git-info');
}); });
} }
async.parallel({ const getAsync = require('util').promisify(get);
hash: function (next) { const [hash, branch] = await Promise.all([
get('git rev-parse HEAD', next); getAsync('git rev-parse HEAD'),
}, getAsync('git rev-parse --abbrev-ref HEAD'),
branch: function (next) { ]);
get('git rev-parse --abbrev-ref HEAD', next); return { hash: hash, branch: branch };
},
}, callback);
} }

@ -1,26 +1,18 @@
'use strict'; 'use strict';
var async = require('async'); const languages = require('../../languages');
const meta = require('../../meta');
var languages = require('../../languages'); const languagesController = module.exports;
var meta = require('../../meta');
var languagesController = module.exports; languagesController.get = async function (req, res) {
const languageData = await languages.list();
languageData.forEach(function (language) {
language.selected = language.code === meta.config.defaultLang;
});
languagesController.get = function (req, res, next) { res.render('admin/general/languages', {
async.waterfall([ languages: languageData,
function (next) { autoDetectLang: meta.config.autoDetectLang,
languages.list(next); });
},
function (languages) {
languages.forEach(function (language) {
language.selected = language.code === meta.config.defaultLang;
});
res.render('admin/general/languages', {
languages: languages,
autoDetectLang: meta.config.autoDetectLang,
});
},
], next);
}; };

@ -1,6 +1,6 @@
'use strict'; 'use strict';
var loggerController = module.exports; const loggerController = module.exports;
loggerController.get = function (req, res) { loggerController.get = function (req, res) {
res.render('admin/development/logger', {}); res.render('admin/development/logger', {});

@ -1,24 +1,20 @@
'use strict'; 'use strict';
var async = require('async'); const validator = require('validator');
var validator = require('validator'); const winston = require('winston');
var meta = require('../../meta'); const meta = require('../../meta');
var logsController = module.exports; const logsController = module.exports;
logsController.get = function (req, res, next) { logsController.get = async function (req, res) {
async.waterfall([ let logs = '';
function (next) { try {
meta.logs.get(next); logs = await meta.logs.get();
}, } catch (err) {
function (logs) { winston.error(err);
res.render('admin/advanced/logs', { }
data: validator.escape(logs), res.render('admin/advanced/logs', {
}); data: validator.escape(logs),
}, });
], next);
}; };
module.exports = logsController;

@ -1,43 +1,37 @@
'use strict'; 'use strict';
var async = require('async');
var navigationAdmin = require('../../navigation/admin'); const navigationAdmin = require('../../navigation/admin');
const groups = require('../../groups'); const groups = require('../../groups');
var navigationController = module.exports; const navigationController = module.exports;
navigationController.get = function (req, res, next) { navigationController.get = async function (req, res) {
async.waterfall([ const [admin, allGroups] = await Promise.all([
function (next) { navigationAdmin.getAdmin(),
async.parallel({ groups.getNonPrivilegeGroups('groups:createtime', 0, -1),
admin: async.apply(navigationAdmin.getAdmin), ]);
groups: async.apply(groups.getNonPrivilegeGroups, 'groups:createtime', 0, -1),
}, next); allGroups.sort((a, b) => b.system - a.system);
}, const groupsData = allGroups.map(group => ({ name: group.name, displayName: group.displayName }));
function (result) {
result.groups.sort((a, b) => b.system - a.system); admin.enabled.forEach(function (enabled, index) {
result.groups = result.groups.map(group => ({ name: group.name, displayName: group.displayName })); enabled.index = index;
enabled.selected = index === 0;
result.admin.enabled.forEach(function (enabled, index) {
enabled.index = index; enabled.groups = groupsData.map(function (group) {
enabled.selected = index === 0; return {
displayName: group.displayName,
enabled.groups = result.groups.map(function (group) { selected: enabled.groups.includes(group.name),
return { };
displayName: group.displayName, });
selected: enabled.groups.includes(group.name), });
};
}); admin.available.forEach(function (available) {
}); available.groups = groups;
});
result.admin.available.forEach(function (available) {
available.groups = result.groups; admin.navigation = admin.enabled.slice();
});
res.render('admin/general/navigation', admin);
result.admin.navigation = result.admin.enabled.slice();
res.render('admin/general/navigation', result.admin);
},
], next);
}; };

@ -1,67 +1,58 @@
'use strict'; 'use strict';
var async = require('async'); const nconf = require('nconf');
var nconf = require('nconf'); const winston = require('winston');
var plugins = require('../../plugins'); const plugins = require('../../plugins');
var meta = require('../../meta'); const meta = require('../../meta');
var pluginsController = module.exports; const pluginsController = module.exports;
pluginsController.get = function (req, res, next) { pluginsController.get = async function (req, res) {
async.waterfall([ const [compatible, all] = await Promise.all([
function (next) { getCompatiblePluigns(),
async.parallel({ getAllPlugins(),
compatible: function (next) { ]);
plugins.list(function (err, plugins) {
if (err || !Array.isArray(plugins)) {
plugins = [];
}
next(null, plugins); const compatiblePkgNames = compatible.map(pkgData => pkgData.name);
}); const installedPlugins = compatible.filter(plugin => plugin && plugin.installed);
}, const activePlugins = all.filter(plugin => plugin && plugin.installed && plugin.active);
all: function (next) {
plugins.list(false, function (err, plugins) {
if (err || !Array.isArray(plugins)) {
plugins = [];
}
next(null, plugins); res.render('admin/extend/plugins', {
}); installed: installedPlugins,
}, installedCount: installedPlugins.length,
}, next); activeCount: activePlugins.length,
}, inactiveCount: Math.max(0, installedPlugins.length - activePlugins.length),
function (payload) { upgradeCount: compatible.reduce(function (count, current) {
var compatiblePkgNames = payload.compatible.map(function (pkgData) { if (current.installed && current.outdated) {
return pkgData.name; count += 1;
}); }
var installedPlugins = payload.compatible.filter(function (plugin) { return count;
return plugin && plugin.installed; }, 0),
}); download: compatible.filter(function (plugin) {
var activePlugins = payload.all.filter(function (plugin) { return !plugin.installed;
return plugin && plugin.installed && plugin.active; }),
}); incompatible: all.filter(function (plugin) {
return !compatiblePkgNames.includes(plugin.name);
res.render('admin/extend/plugins', { }),
installed: installedPlugins, submitPluginUsage: meta.config.submitPluginUsage,
installedCount: installedPlugins.length, version: nconf.get('version'),
activeCount: activePlugins.length, });
inactiveCount: Math.max(0, installedPlugins.length - activePlugins.length),
upgradeCount: payload.compatible.reduce(function (count, current) {
if (current.installed && current.outdated) {
count += 1;
}
return count;
}, 0),
download: payload.compatible.filter(function (plugin) {
return !plugin.installed;
}),
incompatible: payload.all.filter(function (plugin) {
return !compatiblePkgNames.includes(plugin.name);
}),
submitPluginUsage: meta.config.submitPluginUsage,
version: nconf.get('version'),
});
},
], next);
}; };
async function getCompatiblePluigns() {
return await getPlugins(true);
}
async function getAllPlugins() {
return await getPlugins(false);
}
async function getPlugins(matching) {
try {
const pluginsData = await plugins.list(matching);
return pluginsData || [];
} catch (err) {
winston.error(err);
return [];
}
}

@ -1,115 +1,76 @@
'use strict'; 'use strict';
var async = require('async'); const validator = require('validator');
var validator = require('validator');
var db = require('../../database'); const db = require('../../database');
var user = require('../../user'); const user = require('../../user');
var topics = require('../../topics'); const topics = require('../../topics');
var categories = require('../../categories'); const categories = require('../../categories');
var pagination = require('../../pagination'); const pagination = require('../../pagination');
var plugins = require('../../plugins'); const plugins = require('../../plugins');
var utils = require('../../utils'); const utils = require('../../utils');
var postQueueController = module.exports; const postQueueController = module.exports;
postQueueController.get = function (req, res, next) { postQueueController.get = async function (req, res) {
var page = parseInt(req.query.page, 10) || 1; const page = parseInt(req.query.page, 10) || 1;
var postsPerPage = 20; const postsPerPage = 20;
var results;
async.waterfall([
function (next) {
async.parallel({
ids: function (next) {
db.getSortedSetRange('post:queue', 0, -1, next);
},
isAdminOrGlobalMod: function (next) {
user.isAdminOrGlobalMod(req.uid, next);
},
moderatedCids: function (next) {
user.getModeratedCids(req.uid, next);
},
}, next);
},
function (_results, next) {
results = _results;
getQueuedPosts(results.ids, next);
},
function (postData) {
postData = postData.filter(function (postData) {
return postData && (results.isAdminOrGlobalMod || results.moderatedCids.includes(String(postData.category.cid)));
});
var pageCount = Math.max(1, Math.ceil(postData.length / postsPerPage)); const [ids, isAdminOrGlobalMod, moderatedCids] = await Promise.all([
var start = (page - 1) * postsPerPage; db.getSortedSetRange('post:queue', 0, -1),
var stop = start + postsPerPage - 1; user.isAdminOrGlobalMod(req.uid),
postData = postData.slice(start, stop + 1); user.getModeratedCids(req.uid),
]);
res.render('admin/manage/post-queue', { let postData = await getQueuedPosts(ids);
title: '[[pages:post-queue]]', postData = postData.filter(p => p && (isAdminOrGlobalMod || moderatedCids.includes(String(p.category.cid))));
posts: postData,
pagination: pagination.create(page, pageCount), const pageCount = Math.max(1, Math.ceil(postData.length / postsPerPage));
}); const start = (page - 1) * postsPerPage;
}, const stop = start + postsPerPage - 1;
], next); postData = postData.slice(start, stop + 1);
res.render('admin/manage/post-queue', {
title: '[[pages:post-queue]]',
posts: postData,
pagination: pagination.create(page, pageCount),
});
}; };
function getQueuedPosts(ids, callback) { async function getQueuedPosts(ids) {
var postData; const keys = ids.map(id => 'post:queue:' + id);
async.waterfall([ const postData = await db.getObjects(keys);
function (next) { postData.forEach(function (data) {
const keys = ids.map(id => 'post:queue:' + id); if (data) {
db.getObjects(keys, next); data.data = JSON.parse(data.data);
}, data.data.timestampISO = utils.toISOString(data.data.timestamp);
function (data, next) { }
postData = data; });
data.forEach(function (data) { const uids = postData.map(data => data && data.uid);
if (data) { const userData = await user.getUsersFields(uids, ['username', 'userslug', 'picture']);
data.data = JSON.parse(data.data); postData.forEach(function (postData, index) {
data.data.timestampISO = utils.toISOString(data.data.timestamp); if (postData) {
} postData.user = userData[index];
return data; postData.data.rawContent = validator.escape(String(postData.data.content));
}); postData.data.title = validator.escape(String(postData.data.title || ''));
const uids = data.map(data => data && data.uid); }
user.getUsersFields(uids, ['username', 'userslug', 'picture'], next); });
},
function (userData, next) { await Promise.all(postData.map(p => addMetaData(p)));
postData.forEach(function (postData, index) { return postData;
if (postData) { }
postData.user = userData[index];
}
});
async.map(postData, function (postData, next) { async function addMetaData(postData) {
if (!postData) { if (!postData) {
return next(null, postData); return;
} }
postData.data.rawContent = validator.escape(String(postData.data.content)); postData.topic = { cid: 0 };
postData.data.title = validator.escape(String(postData.data.title || '')); if (postData.data.cid) {
async.waterfall([ postData.topic = { cid: postData.data.cid };
function (next) { } else if (postData.data.tid) {
if (postData.data.cid) { postData.topic = await topics.getTopicFields(postData.data.tid, ['title', 'cid']);
next(null, { cid: postData.data.cid }); }
} else if (postData.data.tid) { postData.category = await categories.getCategoryData(postData.topic.cid);
topics.getTopicFields(postData.data.tid, ['title', 'cid'], next); const result = await plugins.fireHook('filter:parse.post', { postData: postData.data });
} else { postData.data.content = result.postData.content;
next(null, { cid: 0 });
}
},
function (topicData, next) {
postData.topic = topicData;
categories.getCategoryData(topicData.cid, next);
},
function (categoryData, next) {
postData.category = categoryData;
plugins.fireHook('filter:parse.post', { postData: postData.data }, next);
},
function (result, next) {
postData.data.content = result.postData.content;
next(null, postData);
},
], next);
}, next);
},
], callback);
} }

@ -1,62 +1,52 @@
'use strict'; 'use strict';
var async = require('async'); const categories = require('../../categories');
const privileges = require('../../privileges');
var categories = require('../../categories');
var privileges = require('../../privileges'); const privilegesController = module.exports;
var privilegesController = module.exports; privilegesController.get = async function (req, res) {
const cid = req.params.cid ? parseInt(req.params.cid, 10) : 0;
privilegesController.get = function (req, res, callback) { const [privilegesData, categoriesData] = await Promise.all([
var cid = req.params.cid ? parseInt(req.params.cid, 10) : 0; getPrivileges(cid),
async.waterfall([ getCategories(req.uid),
function (next) { ]);
async.parallel({
privileges: function (next) { categoriesData.unshift({
if (!cid) { cid: 0,
privileges.global.list(next); name: '[[admin/manage/privileges:global]]',
} else { icon: 'fa-list',
privileges.categories.list(cid, next); });
}
}, let selectedCategory;
categories: function (next) { categoriesData.forEach(function (category) {
async.waterfall([ if (category) {
function (next) { category.selected = category.cid === cid;
categories.getAllCidsFromSet('categories:cid', next);
}, if (category.selected) {
function (cids, next) { selectedCategory = category;
categories.getCategories(cids, req.uid, next); }
}, }
function (categoriesData, next) { });
categoriesData = categories.getTree(categoriesData);
categories.buildForSelectCategories(categoriesData, next); res.render('admin/manage/privileges', {
}, privileges: privilegesData,
], next); categories: categoriesData,
}, selectedCategory: selectedCategory,
}, next); cid: cid,
}, });
function (data) {
data.categories.unshift({
cid: 0,
name: '[[admin/manage/privileges:global]]',
icon: 'fa-list',
});
data.categories.forEach(function (category) {
if (category) {
category.selected = category.cid === cid;
if (category.selected) {
data.selected = category;
}
}
});
res.render('admin/manage/privileges', {
privileges: data.privileges,
categories: data.categories,
selectedCategory: data.selected,
cid: cid,
});
},
], callback);
}; };
async function getPrivileges(cid) {
if (!cid) {
return await privileges.global.list();
}
return await privileges.categories.list(cid);
}
async function getCategories(uid) {
const cids = await categories.getAllCidsFromSet('categories:cid');
const categoriesData = await categories.getCategories(cids, uid);
const tree = categories.getTree(categoriesData);
return await categories.buildForSelectCategories(tree);
}

@ -323,4 +323,46 @@ function recursive(category, categoriesData, level) {
} }
} }
helpers.getHomePageRoutes = async function (uid) {
let cids = await categories.getAllCidsFromSet('categories:cid');
cids = await privileges.categories.filterCids('find', cids, uid);
const categoryData = await categories.getCategoriesFields(cids, ['name', 'slug']);
const categoryRoutes = categoryData.map(function (category) {
return {
route: 'category/' + category.slug,
name: 'Category: ' + category.name,
};
});
const routes = [
{
route: 'categories',
name: 'Categories',
},
{
route: 'unread',
name: 'Unread',
},
{
route: 'recent',
name: 'Recent',
},
{
route: 'top',
name: 'Top',
},
{
route: 'popular',
name: 'Popular',
},
].concat(categoryRoutes, [
{
route: 'custom',
name: 'Custom',
},
]);
const data = await plugins.fireHook('filter:homepage.get', { routes: routes });
return data.routes;
};
helpers.async = require('../promisify')(helpers); helpers.async = require('../promisify')(helpers);

@ -1,18 +1,18 @@
'use strict'; 'use strict';
var path = require('path'); const path = require('path');
var fs = require('fs'); const fs = require('fs');
const util = require('util');
var Logs = module.exports; const readFileAsync = util.promisify(fs.readFile);
const truncateAsync = util.promisify(fs.truncate);
const Logs = module.exports;
Logs.path = path.join(__dirname, '..', '..', 'logs', 'output.log'); Logs.path = path.join(__dirname, '..', '..', 'logs', 'output.log');
Logs.get = function (callback) { Logs.get = async function () {
fs.readFile(Logs.path, { return await readFileAsync(Logs.path, 'utf-8');
encoding: 'utf-8',
}, callback);
}; };
Logs.clear = function (callback) { Logs.clear = async function () {
fs.truncate(Logs.path, 0, callback); return await truncateAsync(Logs.path, 0);
}; };

@ -179,3 +179,5 @@ SocketRooms.getLocalStats = function (callback) {
callback(null, socketData); callback(null, socketData);
}; };
require('../../promisify')(SocketRooms);

Loading…
Cancel
Save