diff --git a/public/src/forum/users.js b/public/src/forum/users.js index f10c739918..003b795492 100644 --- a/public/src/forum/users.js +++ b/public/src/forum/users.js @@ -63,19 +63,20 @@ define(function() { templates['users'].parse({users:[]}); var html = templates.prepare(templates['users'].blocks['users']).parse({ users: data.users - }), - userListEl = $('#users-container'); + }); - userListEl.html(html); + translator.translate(html, function(translated) { + $('#users-container').html(translated); - if (data && data.users.length === 0) { - $('#user-notfound-notify').html('User not found!'); - $('#user-notfound-notify').parent().addClass('btn-warning label-warning'); - } else { - $('#user-notfound-notify').html(data.users.length + ' user' + (data.users.length > 1 ? 's' : '') + ' found! Search took ' + data.timing + ' ms.'); - $('#user-notfound-notify').parent().addClass('btn-success label-success'); - } + if (data && data.users.length === 0) { + $('#user-notfound-notify').html('User not found!'); + $('#user-notfound-notify').parent().addClass('btn-warning label-warning'); + } else { + $('#user-notfound-notify').html(data.users.length + ' user' + (data.users.length > 1 ? 's' : '') + ' found! Search took ' + data.timing + ' ms.'); + $('#user-notfound-notify').parent().addClass('btn-success label-success'); + } + }); }); }); }, 500); //replace this with global throttling function/constant diff --git a/src/categories/recentreplies.js b/src/categories/recentreplies.js index a5dd10bc4e..825cdc601d 100644 --- a/src/categories/recentreplies.js +++ b/src/categories/recentreplies.js @@ -9,30 +9,20 @@ var async = require('async'), module.exports = function(Categories) { Categories.getRecentReplies = function(cid, uid, count, callback) { - if(count === 0 || !count) { + if(!parseInt(count, 10)) { return callback(null, []); } - CategoryTools.privileges(cid, uid, function(err, privileges) { - if(err) { - return callback(err); + db.getSortedSetRevRange('categories:recent_posts:cid:' + cid, 0, count - 1, function(err, pids) { + if (err) { + return callback(err, []); } - if (!privileges.read) { + if (!pids || !pids.length) { return callback(null, []); } - db.getSortedSetRevRange('categories:recent_posts:cid:' + cid, 0, count - 1, function(err, pids) { - if (err) { - return callback(err, []); - } - - if (!pids || !pids.length) { - return callback(null, []); - } - - posts.getPostSummaryByPids(pids, true, callback); - }); + posts.getPostSummaryByPids(pids, true, callback); }); }; diff --git a/src/controllers/admin/users.js b/src/controllers/admin/users.js index 4cf53b79bd..c2bb41fb80 100644 --- a/src/controllers/admin/users.js +++ b/src/controllers/admin/users.js @@ -26,7 +26,7 @@ usersController.sortByJoinDate = function(req, res, next) { }; function getUsers(set, req, res, next) { - user.getUsers(set, 0, 49, function(err, users) { + user.getUsersFromSet(set, 0, 49, function(err, users) { if (err) { return next(err); } diff --git a/src/controllers/users.js b/src/controllers/users.js index ed6e10dbb5..4d97298c40 100644 --- a/src/controllers/users.js +++ b/src/controllers/users.js @@ -9,7 +9,7 @@ var async = require('async'), usersController.getOnlineUsers = function(req, res, next) { var websockets = require('../socket.io'); - user.getUsers('users:online', 0, 49, function (err, data) { + user.getUsersFromSet('users:online', 0, 49, function (err, data) { if(err) { return next(err); } @@ -72,7 +72,7 @@ usersController.getUsersSortedByJoinDate = function(req, res, next) { }; function getUsers(set, res, next) { - user.getUsers(set, 0, 49, function (err, data) { + user.getUsersFromSet(set, 0, 49, function (err, data) { if (err) { return next(err); } diff --git a/src/posts.js b/src/posts.js index 63572d5104..16cdb89df8 100644 --- a/src/posts.js +++ b/src/posts.js @@ -278,76 +278,85 @@ var db = require('./database'), Posts.getPostSummaryByPids = function(pids, stripTags, callback) { - function getPostSummary(pid, callback) { + function getPostSummary(post, callback) { - async.waterfall([ - function(next) { - Posts.getPostFields(pid, ['pid', 'tid', 'content', 'uid', 'timestamp', 'deleted'], function(err, postData) { - if(err) { - return next(err); - } + post.relativeTime = utils.toISOString(post.timestamp); - if (parseInt(postData.deleted, 10) === 1) { - return callback(null); - } - - postData.relativeTime = utils.toISOString(postData.timestamp); - next(null, postData); - }); - }, - function(postData, next) { - Posts.addUserInfoToPost(postData, function() { - next(null, postData); + async.parallel([ + function(next) { + Posts.addUserInfoToPost(post, function() { + next(null, post); }); }, - function(postData, next) { - topics.getTopicFields(postData.tid, ['title', 'cid', 'slug', 'deleted'], function(err, topicData) { + function(next) { + topics.getTopicFields(post.tid, ['title', 'cid', 'slug', 'deleted'], function(err, topicData) { if (err) { - return callback(err); + return next(err); } else if (parseInt(topicData.deleted, 10) === 1) { - return callback(null); + return callback(); } + categories.getCategoryFields(topicData.cid, ['name', 'icon', 'slug'], function(err, categoryData) { - postData.category = categoryData; + if (err) { + return next(err); + } + + post.category = categoryData; topicData.title = validator.escape(topicData.title); - postData.topic = topicData; - next(null, postData); + post.topic = topicData; + next(); }); }); }, - function(postData, next) { - if (!postData.content) { - return next(null, postData); + function(next) { + if (!post.content) { + return next(); } - postTools.parse(postData.content, function(err, content) { + postTools.parse(post.content, function(err, content) { if(err) { return next(err); } if(stripTags) { var s = S(content); - postData.content = s.stripTags.apply(s, utils.getTagsExcept(['img', 'i', 'p'])).s; + post.content = s.stripTags.apply(s, utils.getTagsExcept(['img', 'i', 'p'])).s; } else { - postData.content = content; + post.content = content; } - next(null, postData); + next(); }); } - ], callback); + ], function(err) { + callback(err, post); + }); } - async.map(pids, getPostSummary, function(err, posts) { - if(err) { + var keys = pids.map(function(pid) { + return 'post:' + pid; + }); + + db.getObjectsFields(keys, ['pid', 'tid', 'content', 'uid', 'timestamp', 'deleted'], function(err, posts) { + if (err) { return callback(err); } posts = posts.filter(function(p) { - return p; + return !!p || parseInt(p.deleted, 10) !== 1; }); - callback(null, posts); + async.map(posts, getPostSummary, function(err, posts) { + if (err) { + return callback(err); + } + + posts = posts.filter(function(post) { + return !!post; + }); + + return callback(null, posts); + }); }); }; diff --git a/src/socket.io/categories.js b/src/socket.io/categories.js index a67e5e53c1..eab02b41ee 100644 --- a/src/socket.io/categories.js +++ b/src/socket.io/categories.js @@ -1,11 +1,24 @@ +'use strict'; + var categories = require('../categories'), + categoryTools = require('../categoryTools'), meta = require('./../meta'), user = require('./../user'), SocketCategories = {}; -SocketCategories.getRecentReplies = function(socket, tid, callback) { - categories.getRecentReplies(tid, socket.uid, 4, callback); +SocketCategories.getRecentReplies = function(socket, cid, callback) { + categoryTools.privileges(cid, socket.uid, function(err, privileges) { + if (err) { + return callback(err); + } + + if (privileges && !privileges.read) { + return callback(null, []); + } + + categories.getRecentReplies(cid, socket.uid, 4, callback); + }); }; SocketCategories.get = function(socket, data, callback) { diff --git a/src/socket.io/user.js b/src/socket.io/user.js index 6ee6657463..0897f56296 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -4,6 +4,7 @@ var async = require('async'), user = require('../user'), topics = require('../topics'), utils = require('./../../public/src/utils'), + meta = require('../meta'), SocketUser = {}; SocketUser.exists = function(socket, data, callback) { @@ -204,10 +205,14 @@ SocketUser.loadMore = function(socket, data, callback) { return callback(new Error('invalid-data')); } + if (!socket.uid && !!parseInt(meta.config.privateUserInfo, 10)) { + return callback(new Error('not-allowed')); + } + var start = data.after, end = start + 19; - user.getUsers(data.set, start, end, function(err, userData) { + user.getUsersFromSet(data.set, start, end, function(err, userData) { if(err) { return callback(err); } @@ -231,7 +236,6 @@ SocketUser.loadMore = function(socket, data, callback) { }; - SocketUser.setStatus = function(socket, status, callback) { var server = require('./index'); user.setUserField(socket.uid, 'status', status, function(err) { diff --git a/src/user.js b/src/user.js index 6706b1c23f..687a67a4b6 100644 --- a/src/user.js +++ b/src/user.js @@ -142,7 +142,18 @@ var bcrypt = require('bcryptjs'), db.incrObjectFieldBy('user:' + uid, field, -value, callback); }; - User.getUsers = function(set, start, stop, callback) { + User.getUsersFromSet = function(set, start, stop, callback) { + async.waterfall([ + function(next) { + db.getSortedSetRevRange(set, start, stop, next); + }, + function(uids, next) { + User.getUsers(uids, next); + } + ], callback); + }; + + User.getUsers = function(uids, callback) { function loadUserInfo(user, callback) { if (!user) { return callback(null, user); @@ -155,13 +166,10 @@ var bcrypt = require('bcryptjs'), function(isAdmin, next) { user.status = !user.status ? 'online' : user.status; user.administrator = isAdmin ? '1':'0'; - if (set === 'users:online') { - return callback(null, user); - } - db.sortedSetScore('users:online', user.uid, next); + db.isSortedSetMember('users:online', user.uid, next); }, - function(score, next) { - if (!score) { + function(isMember, next) { + if (!isMember) { user.status = 'offline'; } next(null, user); @@ -169,17 +177,13 @@ var bcrypt = require('bcryptjs'), ], callback); } - async.waterfall([ - function(next) { - db.getSortedSetRevRange(set, start, stop, next); - }, - function(uids, next) { - User.getMultipleUserFields(uids, ['uid', 'username', 'userslug', 'picture', 'status', 'banned', 'postcount', 'reputation'], next); - }, - function(users, next) { - async.map(users, loadUserInfo, next); + User.getMultipleUserFields(uids, ['uid', 'username', 'userslug', 'picture', 'status', 'banned', 'postcount', 'reputation'], function(err, usersData) { + if (err) { + return callback(err); } - ], callback); + + async.map(usersData, loadUserInfo, callback); + }); }; User.createGravatarURLFromEmail = function(email) { diff --git a/src/user/follow.js b/src/user/follow.js index 4a354521fc..1944e9534f 100644 --- a/src/user/follow.js +++ b/src/user/follow.js @@ -38,7 +38,7 @@ module.exports = function(User) { return callback(err); } - User.getUsersData(uids, callback); + User.getUsers(uids, callback); }); } diff --git a/src/user/search.js b/src/user/search.js index 587f175352..90a17cb521 100644 --- a/src/user/search.js +++ b/src/user/search.js @@ -17,10 +17,8 @@ module.exports = function(User) { query = query.toLowerCase(); - var usernames = Object.keys(usernamesHash), - uids = []; - - uids = usernames.filter(function(username) { + var usernames = Object.keys(usernamesHash); + var uids = usernames.filter(function(username) { return username.toLowerCase().indexOf(query) === 0; }) .slice(0, 10) @@ -31,10 +29,11 @@ module.exports = function(User) { return usernamesHash[username]; }); - User.getUsersData(uids, function(err, userdata) { + User.getUsers(uids, function(err, userdata) { if (err) { return callback(err); } + var diff = process.hrtime(start); var timing = (diff[0] * 1e3 + diff[1] / 1e6).toFixed(1); callback(null, {timing: timing, users: userdata});