From 3f44f4bb3aae337e454e89f9b8ceb3ff21565a52 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 2 Apr 2014 16:54:57 -0400 Subject: [PATCH] closes #1319 --- src/postTools.js | 169 ++++++++++++++++++++--------------------- src/socket.io/index.js | 2 +- src/topics.js | 6 +- src/user.js | 16 +++- 4 files changed, 98 insertions(+), 95 deletions(-) diff --git a/src/postTools.js b/src/postTools.js index 814ea277a2..c9479e2763 100644 --- a/src/postTools.js +++ b/src/postTools.js @@ -141,117 +141,114 @@ var winston = require('winston'), }; PostTools.delete = function(uid, pid, callback) { - var success = function() { - posts.setPostField(pid, 'deleted', 1); - db.decrObjectField('global', 'postCount'); + togglePostDelete(uid, pid, true, callback); + }; - plugins.fireHook('action:post.delete', pid); + PostTools.restore = function(uid, pid, callback) { + togglePostDelete(uid, pid, false, callback); + }; - events.logPostDelete(uid, pid); + function togglePostDelete(uid, pid, isDelete, callback) { + async.waterfall([ + function(next) { + posts.getPostField(pid, 'deleted', next); + }, + function(deleted, next) { + if(parseInt(deleted, 10) === 1 && isDelete) { + return next(new Error('Post already deleted')); + } else if(parseInt(deleted, 10) !== 1 && !isDelete) { + return next(new Error('Post already restored')); + } + PostTools.privileges(pid, uid, next); + }, + function(privileges, next) { + if (!privileges || !privileges.editable) { + return next(new Error('no privileges')); + } + next(); + } + ], function(err) { + if(err) { + return callback(err); + } - posts.getPostFields(pid, ['tid', 'uid'], function(err, postData) { - topics.decreasePostCount(postData.tid); + posts.setPostField(pid, 'deleted', isDelete ? 1 : 0, function(err) { + if (err) { + return callback(err); + } - user.decrementUserFieldBy(postData.uid, 'postcount', 1, function(err, postcount) { - db.sortedSetAdd('users:postcount', postcount, postData.uid); - }); + events[isDelete ? 'logPostDelete' : 'logPostRestore'](uid, pid); - topics.getTopicField(postData.tid, 'cid', function(err, cid) { - if(!err) { - db.sortedSetRemove('categories:recent_posts:cid:' + cid, pid); - } - }); + db.incrObjectFieldBy('global', 'postCount', isDelete ? -1 : 1); - // Delete the thread if it is the last undeleted post - threadTools.getLatestUndeletedPid(postData.tid, function(err, pid) { - if(err) { - return winston.error(err.message); + posts.getPostFields(pid, ['tid', 'uid', 'content'], function(err, postData) { + if (err) { + return callback(err); } - if (!pid) { - threadTools.delete(postData.tid, uid, function(err) { - if (err) { - winston.error('Could not delete topic (tid: ' + postData.tid + ')', err.stack); - } - }); + if (isDelete) { + plugins.fireHook('action:post.delete', pid); } else { - posts.getPostField(pid, 'timestamp', function(err, timestamp) { - topics.updateTimestamp(postData.tid, timestamp); - }); + plugins.fireHook('action:post.restore', postData); } - }); - callback(null); + async.parallel([ + function(next) { + topics[isDelete ? 'decreasePostCount' : 'increasePostCount'](postData.tid, next); + }, + function(next) { + user.incrementUserPostCountBy(postData.uid, isDelete ? -1 : 1, next); + }, + function(next) { + updateTopicTimestamp(postData.tid, next); + }, + function(next) { + addOrRemoveFromCategoryRecentPosts(pid, postData.tid, isDelete, next); + } + ], callback); + }); }); - }; + }); + } - posts.getPostField(pid, 'deleted', function(err, deleted) { - if(parseInt(deleted, 10) === 1) { - return callback(new Error('Post already deleted!')); + function updateTopicTimestamp(tid, callback) { + threadTools.getLatestUndeletedPid(tid, function(err, pid) { + if(err || !pid) { + return callback(err); } - PostTools.privileges(pid, uid, function(err, privileges) { - if (privileges.editable) { - success(); + posts.getPostField(pid, 'timestamp', function(err, timestamp) { + if (err) { + return callback(err); } - }); - }); - }; - - PostTools.restore = function(uid, pid, callback) { - var success = function() { - posts.setPostField(pid, 'deleted', 0); - db.incrObjectField('global', 'postCount'); - - events.logPostRestore(uid, pid); - - posts.getPostFields(pid, ['tid', 'uid', 'content'], function(err, postData) { - topics.increasePostCount(postData.tid); - - user.incrementUserFieldBy(postData.uid, 'postcount', 1); - - threadTools.getLatestUndeletedPid(postData.tid, function(err, pid) { - posts.getPostField(pid, 'timestamp', function(err, timestamp) { - topics.updateTimestamp(postData.tid, timestamp); - - topics.getTopicField(postData.tid, 'cid', function(err, cid) { - if(!err) { - db.sortedSetAdd('categories:recent_posts:cid:' + cid, timestamp, pid); - } - }); - }); - }); - - - plugins.fireHook('action:post.restore', postData); - - // Restore topic if it is the only post - topics.getTopicField(postData.tid, 'postcount', function(err, count) { - if (parseInt(count, 10) === 1) { - threadTools.restore(postData.tid, uid, function(err) { - if(err) { - winston.err(err); - } - }); - } - }); + if (timestamp) { + topics.updateTimestamp(tid, timestamp); + } callback(); }); - }; + }); + } - posts.getPostField(pid, 'deleted', function(err, deleted) { - if(parseInt(deleted, 10) === 0) { - return callback(new Error('Post already restored')); + function addOrRemoveFromCategoryRecentPosts(pid, tid, isDelete, callback) { + topics.getTopicField(tid, 'cid', function(err, cid) { + if (err) { + return callback(err); } - PostTools.privileges(pid, uid, function(err, privileges) { - if (privileges.editable) { - success(); + posts.getPostField(pid, 'timestamp', function(err, timestamp) { + if (err) { + return callback(err); + } + + if (isDelete) { + db.sortedSetRemove('categories:recent_posts:cid:' + cid, pid, callback); + } else { + db.sortedSetAdd('categories:recent_posts:cid:' + cid, timestamp, pid, callback); } }); }); - }; + } PostTools.parse = function(raw, callback) { raw = raw || ''; diff --git a/src/socket.io/index.js b/src/socket.io/index.js index bdd017a4c3..92f8eb1158 100644 --- a/src/socket.io/index.js +++ b/src/socket.io/index.js @@ -286,7 +286,7 @@ function emitTopicPostStats(callback) { }; if (!callback) { - io.sockets.emit('post.stats', null, stats); + io.sockets.emit('meta.getUsageStats', null, stats); } else { callback(null, stats); } diff --git a/src/topics.js b/src/topics.js index 9635b83582..2da58b7245 100644 --- a/src/topics.js +++ b/src/topics.js @@ -230,10 +230,6 @@ var async = require('async'), categoryCache[topicData.cid] = topicInfo.categoryData; userCache[topicData.uid] = topicInfo.user; - if (!topicInfo.teaser) { - return next(null, null); - } - if (!isTopicVisible(topicData, topicInfo)) { return next(null, null); } @@ -242,7 +238,7 @@ var async = require('async'), topicData.locked = parseInt(topicData.locked, 10) === 1; topicData.deleted = parseInt(topicData.deleted, 10) === 1; topicData.unread = !(topicInfo.hasread && parseInt(uid, 10) !== 0); - topicData.unreplied = parseInt(topicData.postcount, 10) === 1; + topicData.unreplied = parseInt(topicData.postcount, 10) <= 1; topicData.category = topicInfo.categoryData; topicData.teaser = topicInfo.teaser; diff --git a/src/user.js b/src/user.js index 30305bb8e8..c5f84bd2e2 100644 --- a/src/user.js +++ b/src/user.js @@ -235,15 +235,25 @@ var bcrypt = require('bcryptjs'), User.onNewPostMade = function(postData) { User.addPostIdToUser(postData.uid, postData.pid, postData.timestamp); - User.incrementUserFieldBy(postData.uid, 'postcount', 1, function(err, newpostcount) { - db.sortedSetAdd('users:postcount', newpostcount, postData.uid); - }); + User.incrementUserPostCountBy(postData.uid, 1); User.setUserField(postData.uid, 'lastposttime', postData.timestamp); }; emitter.on('event:newpost', User.onNewPostMade); + User.incrementUserPostCountBy = function(uid, value, callback) { + User.incrementUserFieldBy(uid, 'postcount', value, function(err, newpostcount) { + if (err) { + if(typeof callback === 'function') { + callback(err); + } + return; + } + db.sortedSetAdd('users:postcount', newpostcount, uid, callback); + }); + }; + User.addPostIdToUser = function(uid, pid, timestamp) { db.sortedSetAdd('uid:' + uid + ':posts', timestamp, pid); };