mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-02-04 21:59:51 +01:00
Merge branch 'master' of github.com:designcreateplay/NodeBB
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
'use strict';
|
||||
|
||||
|
||||
/* globals define, app, templates, translator, socket, bootbox, config, ajaxify, RELATIVE_PATH */
|
||||
|
||||
define(['composer', 'forum/pagination', 'forum/topic/fork'], function(composer, pagination, fork) {
|
||||
var Topic = {},
|
||||
infiniteLoaderActive = false,
|
||||
scrollingToPost = false,
|
||||
@@ -196,97 +201,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
}
|
||||
});
|
||||
|
||||
$('.fork_thread').on('click', function() {
|
||||
var pids = [];
|
||||
var forkModal = $('#fork-thread-modal'),
|
||||
forkCommit = forkModal.find('#fork_thread_commit');
|
||||
forkModal.removeClass('hide');
|
||||
forkModal.css('position', 'fixed')
|
||||
.css('left', Math.max(0, (($(window).width() - $(forkModal).outerWidth()) / 2) + $(window).scrollLeft()) + 'px')
|
||||
.css('top', '0px')
|
||||
.css('z-index', '2000');
|
||||
|
||||
showNoPostsSelected();
|
||||
|
||||
forkModal.find('.close,#fork_thread_cancel').on('click', closeForkModal);
|
||||
forkModal.find('#fork-title').on('change', checkForkButtonEnable);
|
||||
$('#post-container').on('click', 'li', togglePostSelection);
|
||||
forkCommit.on('click', createTopicFromPosts);
|
||||
|
||||
function createTopicFromPosts() {
|
||||
socket.emit('topics.createTopicFromPosts', {
|
||||
title: forkModal.find('#fork-title').val(),
|
||||
pids: pids
|
||||
}, function(err) {
|
||||
if(err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
translator.get('topic:fork_success', function(translated) {
|
||||
app.alertSuccess(translated);
|
||||
});
|
||||
|
||||
function removePost() {
|
||||
$(this).remove();
|
||||
}
|
||||
|
||||
for(var i=0; i<pids.length; ++i) {
|
||||
$('#post-container li[data-pid="' + pids[i] + '"]').fadeOut(500, removePost);
|
||||
}
|
||||
closeForkModal();
|
||||
});
|
||||
}
|
||||
|
||||
function togglePostSelection() {
|
||||
|
||||
var newPid = $(this).attr('data-pid');
|
||||
|
||||
if($(this).attr('data-index') === '0') {
|
||||
return;
|
||||
}
|
||||
|
||||
if(newPid) {
|
||||
var index = pids.indexOf(newPid);
|
||||
if(index === -1) {
|
||||
pids.push(newPid);
|
||||
$(this).css('opacity', '0.5');
|
||||
} else {
|
||||
pids.splice(index, 1);
|
||||
$(this).css('opacity', '1.0');
|
||||
}
|
||||
|
||||
if(pids.length) {
|
||||
pids.sort();
|
||||
forkModal.find('#fork-pids').html(pids.toString());
|
||||
} else {
|
||||
showNoPostsSelected();
|
||||
}
|
||||
checkForkButtonEnable();
|
||||
}
|
||||
}
|
||||
|
||||
function closeForkModal() {
|
||||
for(var i=0; i<pids.length; ++i) {
|
||||
$('#post-container li[data-pid="' + pids[i] + '"]').css('opacity', 1);
|
||||
}
|
||||
forkModal.addClass('hide');
|
||||
$('#post-container').off('click', 'li');
|
||||
}
|
||||
|
||||
function checkForkButtonEnable() {
|
||||
if(forkModal.find('#fork-title').length && pids.length) {
|
||||
forkCommit.removeAttr('disabled');
|
||||
} else {
|
||||
forkCommit.attr('disabled', true);
|
||||
}
|
||||
}
|
||||
|
||||
function showNoPostsSelected() {
|
||||
translator.get('topic:fork_no_pids', function(translated) {
|
||||
forkModal.find('#fork-pids').html(translated);
|
||||
});
|
||||
}
|
||||
});
|
||||
fork.init();
|
||||
}
|
||||
|
||||
fixDeleteStateForPosts();
|
||||
@@ -441,7 +356,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
$('#post-container').on('click', '.favourite', function() {
|
||||
var pid = $(this).parents('.post-row').attr('data-pid');
|
||||
|
||||
var method = $(this).attr('data-favourited') == 'false' ? 'posts.favourite' : 'posts.unfavourite';
|
||||
var method = $(this).attr('data-favourited') === 'false' ? 'posts.favourite' : 'posts.unfavourite';
|
||||
|
||||
socket.emit(method, {
|
||||
pid: pid,
|
||||
@@ -649,9 +564,9 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
activeEl.find('a').each(function(index, element) {
|
||||
if(element) {
|
||||
var uid = $(element).attr('data-uid');
|
||||
absent = data.users.every(function(user) {
|
||||
return parseInt(user.uid, 10) !== parseInt(uid, 10);
|
||||
});
|
||||
var absent = data.users.every(function(user) {
|
||||
return parseInt(user.uid, 10) !== parseInt(uid, 10);
|
||||
});
|
||||
|
||||
if (absent) {
|
||||
$(element).remove();
|
||||
@@ -659,11 +574,11 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
}
|
||||
});
|
||||
|
||||
var i=0;
|
||||
var i=0, icon;
|
||||
// add self
|
||||
for(i = 0; i<data.users.length; ++i) {
|
||||
if(parseInt(data.users[i].uid, 10) === parseInt(app.uid, 10)) {
|
||||
var icon = createUserIcon(data.users[i].uid, data.users[i].picture, data.users[i].userslug, data.users[i].username);
|
||||
icon = createUserIcon(data.users[i].uid, data.users[i].picture, data.users[i].userslug, data.users[i].username);
|
||||
activeEl.prepend(icon);
|
||||
data.users.splice(i, 1);
|
||||
break;
|
||||
@@ -671,7 +586,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
}
|
||||
// add other users
|
||||
for(i=0; i<data.users.length; ++i) {
|
||||
icon = createUserIcon(data.users[i].uid, data.users[i].picture, data.users[i].userslug, data.users[i].username)
|
||||
icon = createUserIcon(data.users[i].uid, data.users[i].picture, data.users[i].userslug, data.users[i].username);
|
||||
activeEl.append(icon);
|
||||
if(activeEl.children().length > 8) {
|
||||
break;
|
||||
@@ -688,12 +603,13 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
activeEl.append(anonLink);
|
||||
|
||||
var title = '';
|
||||
if(remainingUsers && anonymousCount)
|
||||
if(remainingUsers && anonymousCount) {
|
||||
title = remainingUsers + ' more user(s) and ' + anonymousCount + ' guest(s)';
|
||||
else if(remainingUsers)
|
||||
} else if(remainingUsers) {
|
||||
title = remainingUsers + ' more user(s)';
|
||||
else
|
||||
} else {
|
||||
title = anonymousCount + ' guest(s)';
|
||||
}
|
||||
|
||||
anonLink.tooltip({
|
||||
placement: 'top',
|
||||
@@ -884,7 +800,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
|
||||
socket.on('event:post_deleted', function(data) {
|
||||
if (data.pid) {
|
||||
toggle_post_delete_state(data.pid);
|
||||
toggle_post_delete_state(data.pid);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -913,7 +829,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
|
||||
votes.html(currentVotes).attr('data-votes', currentVotes);
|
||||
reputationElements.html(reputation).attr('data-reputation', reputation);
|
||||
};
|
||||
}
|
||||
|
||||
function adjust_favourites(value, pid, uid) {
|
||||
var favourites = $('li[data-pid="' + pid + '"] .favouriteCount'),
|
||||
@@ -922,7 +838,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
currentFavourites += value;
|
||||
|
||||
favourites.html(currentFavourites).attr('data-favourites', currentFavourites);
|
||||
};
|
||||
}
|
||||
|
||||
function set_follow_state(state, alert) {
|
||||
|
||||
@@ -937,7 +853,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
type: 'success'
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function set_locked_state(locked, alert) {
|
||||
translator.translate('<i class="fa fa-fw fa-' + (locked ? 'un': '') + 'lock"></i> [[topic:thread_tools.' + (locked ? 'un': '') + 'lock]]', function(translated) {
|
||||
@@ -960,7 +876,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
}
|
||||
|
||||
thread_state.locked = locked ? '1' : '0';
|
||||
};
|
||||
}
|
||||
|
||||
function set_delete_state(deleted) {
|
||||
var threadEl = $('#post-container');
|
||||
@@ -977,7 +893,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
} else {
|
||||
$('#thread-deleted').remove();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function set_pinned_state(pinned, alert) {
|
||||
translator.translate('<i class="fa fa-fw fa-thumb-tack"></i> [[topic:thread_tools.' + (pinned ? 'unpin' : 'pin') + ']]', function(translated) {
|
||||
@@ -994,7 +910,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
}
|
||||
thread_state.pinned = pinned ? '1' : '0';
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function toggle_post_delete_state(pid) {
|
||||
var postEl = $('#post-container li[data-pid="' + pid + '"]');
|
||||
@@ -1006,7 +922,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
|
||||
updatePostCount();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function toggle_post_tools(pid, isDeleted) {
|
||||
var postEl = $('#post-container li[data-pid="' + pid + '"]');
|
||||
@@ -1016,7 +932,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
translator.translate(isDeleted ? ' [[topic:restore]]' : ' [[topic:delete]]', function(translated) {
|
||||
postEl.find('.delete').find('span').html(translated);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
$(window).on('scroll', updateHeader);
|
||||
$(window).trigger('action:topic.loaded');
|
||||
@@ -1231,7 +1147,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
}
|
||||
|
||||
if(after) {
|
||||
translated.insertAfter(after)
|
||||
translated.insertAfter(after);
|
||||
} else if(before) {
|
||||
translated.insertBefore(before);
|
||||
} else {
|
||||
@@ -1250,16 +1166,16 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
|
||||
function parseAndTranslatePosts(data, callback) {
|
||||
templates.preload_template('topic', function() {
|
||||
templates['topic'].parse({posts: []});
|
||||
var html = templates.prepare(templates['topic'].blocks['posts']).parse(data);
|
||||
templates.topic.parse({posts: []});
|
||||
var html = templates.prepare(templates.topic.blocks.posts).parse(data);
|
||||
translator.translate(html, callback);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function onNewPostsLoaded(html, posts) {
|
||||
for (var x = 0, numPosts = posts.length; x < numPosts; x++) {
|
||||
socket.emit('posts.getPrivileges', posts[x].pid, function(err, privileges) {
|
||||
function getPostPrivileges(pid) {
|
||||
socket.emit('posts.getPrivileges', pid, function(err, privileges) {
|
||||
if(err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
@@ -1267,6 +1183,10 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
});
|
||||
}
|
||||
|
||||
for (var x = 0, numPosts = posts.length; x < numPosts; x++) {
|
||||
getPostPrivileges(posts[x].pid);
|
||||
}
|
||||
|
||||
infiniteLoaderActive = false;
|
||||
|
||||
app.populateOnlineUsers();
|
||||
|
||||
115
public/src/forum/topic/fork.js
Normal file
115
public/src/forum/topic/fork.js
Normal file
@@ -0,0 +1,115 @@
|
||||
'use strict';
|
||||
|
||||
/* globals define, app, translator, socket */
|
||||
|
||||
define(function() {
|
||||
|
||||
var Fork = {},
|
||||
forkModal,
|
||||
forkCommit,
|
||||
pids = [];
|
||||
|
||||
Fork.init = function() {
|
||||
$('.fork_thread').on('click', onForkThreadClicked);
|
||||
};
|
||||
|
||||
function onForkThreadClicked() {
|
||||
forkModal = $('#fork-thread-modal');
|
||||
forkCommit = forkModal.find('#fork_thread_commit');
|
||||
pids.length = 0;
|
||||
|
||||
showForkModal();
|
||||
showNoPostsSelected();
|
||||
|
||||
forkModal.find('.close,#fork_thread_cancel').on('click', closeForkModal);
|
||||
forkModal.find('#fork-title').on('change', checkForkButtonEnable);
|
||||
$('#post-container').on('click', 'li[data-pid]', function() {
|
||||
togglePostSelection($(this));
|
||||
});
|
||||
|
||||
forkCommit.on('click', createTopicFromPosts);
|
||||
}
|
||||
|
||||
function showForkModal() {
|
||||
forkModal.removeClass('hide')
|
||||
.css('position', 'fixed')
|
||||
.css('left', Math.max(0, (($(window).width() - $(forkModal).outerWidth()) / 2) + $(window).scrollLeft()) + 'px')
|
||||
.css('top', '0px')
|
||||
.css('z-index', '2000');
|
||||
}
|
||||
|
||||
function createTopicFromPosts() {
|
||||
socket.emit('topics.createTopicFromPosts', {
|
||||
title: forkModal.find('#fork-title').val(),
|
||||
pids: pids
|
||||
}, function(err) {
|
||||
function fadeOutAndRemove(pid) {
|
||||
$('#post-container li[data-pid="' + pid + '"]').fadeOut(500, function() {
|
||||
$(this).remove();
|
||||
});
|
||||
}
|
||||
|
||||
if(err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
app.alertSuccess('[[topic:fork_success]]');
|
||||
|
||||
for(var i=0; i<pids.length; ++i) {
|
||||
fadeOutAndRemove(pids[i]);
|
||||
}
|
||||
closeForkModal();
|
||||
});
|
||||
}
|
||||
|
||||
function togglePostSelection(post) {
|
||||
var newPid = post.attr('data-pid');
|
||||
|
||||
if(parseInt(post.attr('data-index'), 10) === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(newPid) {
|
||||
var index = pids.indexOf(newPid);
|
||||
if(index === -1) {
|
||||
pids.push(newPid);
|
||||
post.css('opacity', '0.5');
|
||||
} else {
|
||||
pids.splice(index, 1);
|
||||
post.css('opacity', '1.0');
|
||||
}
|
||||
|
||||
if(pids.length) {
|
||||
pids.sort();
|
||||
forkModal.find('#fork-pids').html(pids.toString());
|
||||
} else {
|
||||
showNoPostsSelected();
|
||||
}
|
||||
checkForkButtonEnable();
|
||||
}
|
||||
}
|
||||
|
||||
function showNoPostsSelected() {
|
||||
translator.get('topic:fork_no_pids', function(translated) {
|
||||
forkModal.find('#fork-pids').html(translated);
|
||||
});
|
||||
}
|
||||
|
||||
function checkForkButtonEnable() {
|
||||
if(forkModal.find('#fork-title').length && pids.length) {
|
||||
forkCommit.removeAttr('disabled');
|
||||
} else {
|
||||
forkCommit.attr('disabled', true);
|
||||
}
|
||||
}
|
||||
|
||||
function closeForkModal() {
|
||||
for(var i=0; i<pids.length; ++i) {
|
||||
$('#post-container li[data-pid="' + pids[i] + '"]').css('opacity', 1);
|
||||
}
|
||||
forkModal.addClass('hide');
|
||||
$('#post-container').off('click', 'li[data-pid]');
|
||||
}
|
||||
|
||||
return Fork;
|
||||
});
|
||||
@@ -13,30 +13,23 @@ usersController.search = function(req, res, next) {
|
||||
});
|
||||
};
|
||||
|
||||
usersController.latest = function(req, res, next) {
|
||||
user.getUsers('users:joindate', 0, 49, function(err, users) {
|
||||
res.render('admin/users', {
|
||||
search_display: 'none',
|
||||
loadmore_display: 'block',
|
||||
users: users,
|
||||
yourid: req.user.uid
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
usersController.sortByPosts = function(req, res, next) {
|
||||
user.getUsers('users:postcount', 0, 49, function(err, users) {
|
||||
res.render('admin/users', {
|
||||
search_display: 'none',
|
||||
loadmore_display: 'block',
|
||||
users: users,
|
||||
yourid: req.user.uid
|
||||
});
|
||||
});
|
||||
getUsers('users:postcount', req, res, next);
|
||||
};
|
||||
|
||||
usersController.sortByReputation = function(req, res, next) {
|
||||
user.getUsers('users:reputation', 0, 49, function(err, users) {
|
||||
getUsers('users:reputation', req, res, next);
|
||||
};
|
||||
|
||||
usersController.sortByJoinDate = function(req, res, next) {
|
||||
getUsers('users:joindate', req, res, next);
|
||||
};
|
||||
|
||||
function getUsers(set, req, res, next) {
|
||||
user.getUsers(set, 0, 49, function(err, users) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
res.render('admin/users', {
|
||||
search_display: 'none',
|
||||
loadmore_display: 'block',
|
||||
@@ -44,17 +37,7 @@ usersController.sortByReputation = function(req, res, next) {
|
||||
yourid: req.user.uid
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
usersController.sortByJoinDate = function(req, res, next) {
|
||||
user.getUsers('users:joindate', 0, 49, function(err, users) {
|
||||
res.render('admin/users', {
|
||||
search_display: 'none',
|
||||
users: users,
|
||||
yourid: req.user.uid
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
usersController.getCSV = function(req, res, next) {
|
||||
user.getUsersCSV(function(err, data) {
|
||||
|
||||
@@ -65,16 +65,6 @@ categoriesController.get = function(req, res, next) {
|
||||
page = req.query.page || 1,
|
||||
uid = req.user ? req.user.uid : 0;
|
||||
|
||||
if (!req.params.slug && !res.locals.isAPI) {
|
||||
categories.getCategoryField(cid, 'slug', function(err, slug) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
res.redirect('/category/' + slug);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
categoryTools.privileges(cid, uid, function(err, categoryPrivileges) {
|
||||
|
||||
@@ -18,16 +18,6 @@ topicsController.get = function(req, res, next) {
|
||||
uid = req.user ? req.user.uid : 0,
|
||||
privileges;
|
||||
|
||||
if (!req.params.slug && !res.locals.isAPI) {
|
||||
topics.getTopicField(tid, 'slug', function(err, slug) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
res.redirect('/topic/' + slug);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
threadTools.privileges(tid, ((req.user) ? req.user.uid || 0 : 0), function(err, userPrivileges) {
|
||||
|
||||
@@ -60,33 +60,22 @@ usersController.getOnlineUsers = function(req, res, next) {
|
||||
};
|
||||
|
||||
usersController.getUsersSortedByPosts = function(req, res, next) {
|
||||
user.getUsers('users:postcount', 0, 49, function (err, data) {
|
||||
var userData = {
|
||||
search_display: 'none',
|
||||
loadmore_display: 'block',
|
||||
users: data,
|
||||
show_anon: 'hide'
|
||||
};
|
||||
|
||||
res.render('users', userData);
|
||||
});
|
||||
getUsers('users:postcount', res, next);
|
||||
};
|
||||
|
||||
usersController.getUsersSortedByReputation = function(req, res, next) {
|
||||
user.getUsers('users:reputation', 0, 49, function (err, data) {
|
||||
var userData = {
|
||||
search_display: 'none',
|
||||
loadmore_display: 'block',
|
||||
users: data,
|
||||
show_anon: 'hide'
|
||||
};
|
||||
|
||||
res.render('users', userData);
|
||||
});
|
||||
getUsers('users:reputation', res, next);
|
||||
};
|
||||
|
||||
usersController.getUsersSortedByJoinDate = function(req, res, next) {
|
||||
user.getUsers('users:joindate', 0, 49, function (err, data) {
|
||||
getUsers('users:joindate', res, next);
|
||||
};
|
||||
|
||||
function getUsers(set, res, next) {
|
||||
user.getUsers(set, 0, 49, function (err, data) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
var userData = {
|
||||
search_display: 'none',
|
||||
loadmore_display: 'block',
|
||||
@@ -96,7 +85,7 @@ usersController.getUsersSortedByJoinDate = function(req, res, next) {
|
||||
|
||||
res.render('users', userData);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
usersController.getUsersForSearch = function(req, res, next) {
|
||||
var data = {
|
||||
|
||||
118
src/logger.js
118
src/logger.js
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
/*
|
||||
* Logger module: ability to dynamically turn on/off logging for http requests & socket.io events
|
||||
*/
|
||||
@@ -34,25 +36,22 @@ var opts = {
|
||||
opts.express.app = app;
|
||||
/* Open log file stream & initialize express logging if meta.config.logger* variables are set */
|
||||
Logger.setup();
|
||||
}
|
||||
};
|
||||
|
||||
Logger.setup = function() {
|
||||
Logger.setup_one('loggerPath', meta.config.loggerPath);
|
||||
}
|
||||
};
|
||||
|
||||
Logger.setup_one = function(key,value) {
|
||||
Logger.setup_one = function(key, value) {
|
||||
/*
|
||||
* 1. Open the logger stream: stdout or file
|
||||
* 2. Re-initialize the express logger hijack
|
||||
*/
|
||||
switch(key) {
|
||||
case 'loggerPath': {
|
||||
Logger.setup_one_log(value);
|
||||
Logger.express_open();
|
||||
}
|
||||
default: return;
|
||||
if (key === 'loggerPath') {
|
||||
Logger.setup_one_log(value);
|
||||
Logger.express_open();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Logger.setup_one_log = function(value) {
|
||||
/*
|
||||
@@ -61,20 +60,23 @@ var opts = {
|
||||
*/
|
||||
if(meta.config.loggerStatus > 0 || meta.config.loggerIOStatus) {
|
||||
var stream = Logger.open(value);
|
||||
if(stream) opts.streams.log.f = stream;
|
||||
else opts.streams.log.f = process.stdout;
|
||||
if(stream) {
|
||||
opts.streams.log.f = stream;
|
||||
} else {
|
||||
opts.streams.log.f = process.stdout;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Logger.close(opts.streams.log);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Logger.open = function(value) {
|
||||
/* Open the streams to log to: either a path or stdout */
|
||||
var stream;
|
||||
if(value) {
|
||||
if(fs.existsSync(value)) {
|
||||
stats = fs.statSync(value);
|
||||
var stats = fs.statSync(value);
|
||||
if(stats) {
|
||||
if(stats.isDirectory()) {
|
||||
stream = fs.createWriteStream(path.join(value, 'nodebb.log'), {flags: 'a'});
|
||||
@@ -96,12 +98,14 @@ var opts = {
|
||||
stream = process.stdout;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
};
|
||||
|
||||
Logger.close = function(stream) {
|
||||
if(stream.f != process.stdout && stream.f != null) stream.end();
|
||||
if(stream.f !== process.stdout && stream.f) {
|
||||
stream.end();
|
||||
}
|
||||
stream.f = null;
|
||||
}
|
||||
};
|
||||
|
||||
Logger.monitorConfig = function(socket, data) {
|
||||
/*
|
||||
@@ -110,10 +114,10 @@ var opts = {
|
||||
Logger.setup_one(data.key,data.value);
|
||||
Logger.io_close(socket);
|
||||
Logger.io(socket);
|
||||
}
|
||||
};
|
||||
|
||||
Logger.express_open = function() {
|
||||
if(opts.express.set != 1) {
|
||||
if(opts.express.set !== 1) {
|
||||
opts.express.set = 1;
|
||||
opts.express.app.use(Logger.expressLogger);
|
||||
}
|
||||
@@ -121,7 +125,7 @@ var opts = {
|
||||
* Always initialize "ofn" (original function) with the original logger function
|
||||
*/
|
||||
opts.express.ofn = express.logger({stream : opts.streams.log.f});
|
||||
}
|
||||
};
|
||||
|
||||
Logger.expressLogger = function(req,res,next) {
|
||||
/*
|
||||
@@ -134,7 +138,7 @@ var opts = {
|
||||
} else {
|
||||
return next();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Logger.prepare_io_string = function(_type, _uid, _args) {
|
||||
/*
|
||||
@@ -145,82 +149,74 @@ var opts = {
|
||||
try {
|
||||
return 'io: '+_uid+' '+_type+' '+util.inspect(Array.prototype.slice.call(_args))+'\n';
|
||||
} catch(err) {
|
||||
winston.info("Logger.prepare_io_string: Failed",err)
|
||||
winston.info("Logger.prepare_io_string: Failed", err);
|
||||
return "error";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Logger.io_close = function(socket) {
|
||||
/*
|
||||
* Restore all hijacked sockets to their original emit/on functions
|
||||
*/
|
||||
var clients = socket.io.sockets.clients();
|
||||
for(var v in clients) {
|
||||
var client = clients[v];
|
||||
|
||||
if(client.oEmit != undefined && client.oEmit != client.emit) {
|
||||
clients.forEach(function(client) {
|
||||
if(client.oEmit && client.oEmit !== client.emit) {
|
||||
client.emit = client.oEmit;
|
||||
}
|
||||
|
||||
if(client.$oEmit != undefined && client.$oEmit != client.$emit) {
|
||||
if(client.$oEmit && client.$oEmit !== client.$emit) {
|
||||
client.$emit = client.$oEmit;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Logger.io = function(socket) {
|
||||
/*
|
||||
* Go through all of the currently established sockets & hook their .emit/.on
|
||||
*/
|
||||
if(socket == undefined && socket.io.sockets == undefined) {
|
||||
if(!socket && !socket.io.sockets) {
|
||||
return;
|
||||
}
|
||||
|
||||
var clients = socket.io.sockets.clients();
|
||||
for(var v in clients) {
|
||||
var client = clients[v];
|
||||
Logger.io_one(client,client.state.user.uid);
|
||||
}
|
||||
}
|
||||
|
||||
Logger.io_one = function(socket,uid) {
|
||||
clients.forEach(function(client) {
|
||||
Logger.io_one(client, client.uid);
|
||||
});
|
||||
};
|
||||
|
||||
Logger.io_one = function(socket, uid) {
|
||||
/*
|
||||
* This function replaces a socket's .emit/.on functions in order to intercept events
|
||||
*/
|
||||
if(socket != undefined && meta.config.loggerIOStatus > 0) {
|
||||
if(socket && meta.config.loggerIOStatus > 0) {
|
||||
|
||||
(function() {
|
||||
function override(method, name, errorMsg) {
|
||||
return function() {
|
||||
if(opts.streams.log.f) {
|
||||
opts.streams.log.f.write(Logger.prepare_io_string(name, uid, arguments));
|
||||
}
|
||||
|
||||
try {
|
||||
method.apply(socket, arguments);
|
||||
} catch(err) {
|
||||
winston.info(errorMsg, err);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// courtesy of: http://stackoverflow.com/a/9674248
|
||||
var user = uid
|
||||
if(!user) user = "?"
|
||||
socket.oEmit = socket.emit;
|
||||
var emit = socket.emit;
|
||||
socket.emit = function() {
|
||||
if(opts.streams.log.f != null) {
|
||||
opts.streams.log.f.write(Logger.prepare_io_string("emit", uid, arguments));
|
||||
}
|
||||
socket.emit = override(emit, 'emit', 'Logger.io_one: emit.apply: Failed');
|
||||
|
||||
try {
|
||||
emit.apply(socket, arguments);
|
||||
} catch(err) {
|
||||
winston.info("Logger.io_one: emit.apply: Failed", err);
|
||||
}
|
||||
};
|
||||
socket.$oEmit = socket.$emit;
|
||||
var $emit = socket.$emit;
|
||||
socket.$emit = function() {
|
||||
socket.$emit = override($emit, 'on', 'Logger.io_one: $emit.apply: Failed');
|
||||
|
||||
if(opts.streams.log.f != null) {
|
||||
opts.streams.log.f.write(Logger.prepare_io_string("on",uid,arguments));
|
||||
}
|
||||
try {
|
||||
$emit.apply(socket, arguments);
|
||||
} catch(err) {
|
||||
winston.info("Logger.io_one: $emit.apply: Failed", err);
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}(exports));
|
||||
|
||||
@@ -14,6 +14,8 @@ var app,
|
||||
translator = require('./../../public/src/translator'),
|
||||
user = require('./../user'),
|
||||
db = require('./../database'),
|
||||
categories = require('./../categories'),
|
||||
topics = require('./../topics'),
|
||||
|
||||
controllers = {
|
||||
api: require('./../controllers/api')
|
||||
@@ -49,9 +51,31 @@ middleware.redirectToAccountIfLoggedIn = function(req, res, next) {
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
middleware.addSlug = function(req, res, next) {
|
||||
function redirect(method, id, name) {
|
||||
method(id, 'slug', function(err, slug) {
|
||||
if (err || !slug) {
|
||||
return next(err);
|
||||
}
|
||||
res.redirect(name + slug);
|
||||
});
|
||||
}
|
||||
|
||||
if (!req.params.slug) {
|
||||
if (req.params.category_id) {
|
||||
redirect(categories.getCategoryField, req.params.category_id, '/category/');
|
||||
} else if (req.params.topic_id) {
|
||||
redirect(topics.getTopicField, req.params.topic_id, '/topic/');
|
||||
} else {
|
||||
return next();
|
||||
}
|
||||
return;
|
||||
}
|
||||
next();
|
||||
};
|
||||
|
||||
middleware.prepareAPI = function(req, res, next) {
|
||||
res.locals.isAPI = true;
|
||||
next();
|
||||
|
||||
@@ -26,8 +26,8 @@ function userRoutes(app, middleware, controllers) {
|
||||
app.get('/admin/users/search', middleware.admin.buildHeader, controllers.admin.users.search);
|
||||
app.get('/api/admin/users/search', controllers.admin.users.search);
|
||||
|
||||
app.get('/admin/users/latest', middleware.admin.buildHeader, controllers.admin.users.latest);
|
||||
app.get('/api/admin/users/latest', controllers.admin.users.latest);
|
||||
app.get('/admin/users/latest', middleware.admin.buildHeader, controllers.admin.users.sortByJoinDate);
|
||||
app.get('/api/admin/users/latest', controllers.admin.users.sortByJoinDate);
|
||||
|
||||
app.get('/admin/users/sort-posts', middleware.admin.buildHeader, controllers.admin.users.sortByPosts);
|
||||
app.get('/api/admin/users/sort-posts', controllers.admin.users.sortByPosts);
|
||||
@@ -76,7 +76,7 @@ module.exports = function(app, middleware, controllers) {
|
||||
app.all('/api/admin/*', middleware.admin.isAdmin, middleware.prepareAPI);
|
||||
app.all('/admin/*', middleware.admin.isAdmin);
|
||||
app.get('/admin', middleware.admin.isAdmin);
|
||||
|
||||
|
||||
mainRoutes(app, middleware, controllers);
|
||||
userRoutes(app, middleware, controllers);
|
||||
forumRoutes(app, middleware, controllers);
|
||||
|
||||
@@ -48,7 +48,7 @@ function staticRoutes(app, middleware, controllers) {
|
||||
}
|
||||
|
||||
function topicRoutes(app, middleware, controllers) {
|
||||
app.get('/topic/:topic_id/:slug?', middleware.buildHeader, controllers.topics.get);
|
||||
app.get('/topic/:topic_id/:slug?', middleware.buildHeader, middleware.addSlug, controllers.topics.get);
|
||||
app.get('/api/topic/:topic_id/:slug?', controllers.topics.get);
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ function categoryRoutes(app, middleware, controllers) {
|
||||
app.get('/unread/total', middleware.buildHeader, middleware.authenticate, controllers.categories.unreadTotal);
|
||||
app.get('/api/unread/total', middleware.authenticate, controllers.categories.unreadTotal);
|
||||
|
||||
app.get('/category/:category_id/:slug?', middleware.buildHeader, controllers.categories.get);
|
||||
app.get('/category/:category_id/:slug?', middleware.buildHeader, middleware.addSlug, controllers.categories.get);
|
||||
app.get('/api/category/:category_id/:slug?', controllers.categories.get);
|
||||
}
|
||||
|
||||
|
||||
@@ -67,15 +67,8 @@ Sockets.init = function(server) {
|
||||
|
||||
socket.uid = parseInt(uid, 10);
|
||||
|
||||
/* Need to save some state for the logger & maybe some other modules later on */
|
||||
socket.state = {
|
||||
user : {
|
||||
uid : uid
|
||||
}
|
||||
};
|
||||
|
||||
/* If meta.config.loggerIOStatus > 0, logger.io_one will hook into this socket */
|
||||
logger.io_one(socket,uid);
|
||||
logger.io_one(socket, uid);
|
||||
|
||||
if (uid) {
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ var bcrypt = require('bcryptjs'),
|
||||
require('./user/follow')(User);
|
||||
require('./user/profile')(User);
|
||||
require('./user/admin')(User);
|
||||
require('./user/delete')(User);
|
||||
require('./user/settings')(User);
|
||||
require('./user/search')(User);
|
||||
|
||||
|
||||
@@ -2,14 +2,7 @@
|
||||
'use strict';
|
||||
|
||||
var async = require('async'),
|
||||
db = require('./../database'),
|
||||
posts = require('./../posts'),
|
||||
user = require('./../user'),
|
||||
topics = require('./../topics'),
|
||||
categories = require('./../categories'),
|
||||
plugins = require('./../plugins'),
|
||||
events = require('./../events'),
|
||||
groups = require('./../groups');
|
||||
db = require('./../database');
|
||||
|
||||
|
||||
module.exports = function(User) {
|
||||
@@ -59,319 +52,4 @@ module.exports = function(User) {
|
||||
User.unban = function(uid, callback) {
|
||||
User.setUserField(uid, 'banned', 0, callback);
|
||||
};
|
||||
|
||||
User.delete = function(adminUid, uid, callback) {
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
deletePosts(uid, next);
|
||||
},
|
||||
function(next) {
|
||||
deleteTopics(uid, next);
|
||||
},
|
||||
function(next) {
|
||||
events.logAdminUserDelete(adminUid, uid, next);
|
||||
}
|
||||
], function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
deleteAccount(uid, callback);
|
||||
});
|
||||
};
|
||||
|
||||
function deletePosts(uid, callback) {
|
||||
deleteSortedSetElements('uid:' + uid + ':posts', deletePost, callback);
|
||||
}
|
||||
|
||||
function deletePost(pid, callback) {
|
||||
async.parallel([
|
||||
function(next) {
|
||||
deletePostFromTopic(pid, next);
|
||||
},
|
||||
function(next) {
|
||||
deletePostFromCategoryRecentPosts(pid, next);
|
||||
},
|
||||
function(next) {
|
||||
deletePostFromUsersFavourites(pid, next);
|
||||
},
|
||||
function(next) {
|
||||
deletePostFromUsersVotes(pid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetRemove('posts:pid', pid, next);
|
||||
}
|
||||
], function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
plugins.fireHook('action:post.delete', pid);
|
||||
db.delete('post:' + pid, callback);
|
||||
});
|
||||
}
|
||||
|
||||
function deletePostFromTopic(pid, callback) {
|
||||
posts.getPostFields(pid, ['tid', 'deleted'], function(err, postData) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
db.sortedSetRemove('tid:' + postData.tid + ':posts', pid, function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
if (parseInt(postData.deleted, 10) === 0) {
|
||||
db.decrObjectField('global', 'postCount', callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function deletePostFromCategoryRecentPosts(pid, callback) {
|
||||
db.getSortedSetRange('categories:cid', 0, -1, function(err, cids) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
async.each(cids, function(cid, next) {
|
||||
db.sortedSetRemove('categories:recent_posts:cid:' + cid, pid, next);
|
||||
}, callback);
|
||||
});
|
||||
}
|
||||
|
||||
function deletePostFromUsersFavourites(pid, callback) {
|
||||
db.getSetMembers('pid:' + pid + ':users_favourited', function(err, uids) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
async.each(uids, function(uid, next) {
|
||||
db.sortedSetRemove('uid:' + uid + ':favourites', pid, next);
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
db.delete('pid:' + pid + ':users_favourited', callback);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function deletePostFromUsersVotes(pid, callback) {
|
||||
async.parallel({
|
||||
upvoters: function(next) {
|
||||
db.getSetMembers('pid:' + pid + ':upvote', next);
|
||||
},
|
||||
downvoters: function(next) {
|
||||
db.getSetMembers('pid:' + pid + ':downvote', next);
|
||||
}
|
||||
}, function(err, results) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
async.parallel([
|
||||
function(next) {
|
||||
async.each(results.upvoters, function(uid, next) {
|
||||
db.sortedSetRemove('uid:' + uid + ':upvote', pid, next);
|
||||
}, next);
|
||||
},
|
||||
function(next) {
|
||||
async.each(results.downvoters, function(uid, next) {
|
||||
db.sortedSetRemove('uid:' + uid + ':downvote', pid, next);
|
||||
}, next);
|
||||
}
|
||||
], callback);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteTopics(uid, callback) {
|
||||
deleteSortedSetElements('uid:' + uid + ':topics', deleteTopic, callback);
|
||||
}
|
||||
|
||||
function deleteSortedSetElements(set, deleteMethod, callback) {
|
||||
db.getSortedSetRange(set, 0, -1, function(err, ids) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
async.each(ids, deleteMethod, callback);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteTopic(tid, callback) {
|
||||
|
||||
async.parallel([
|
||||
function(next) {
|
||||
db.delete('tid:' + tid + ':followers', next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('tid:' + tid + ':read_by_uid', next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetRemove('topics:tid', tid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetRemove('topics:recent', tid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetRemove('topics:posts', tid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetRemove('topics:views', tid, next);
|
||||
},
|
||||
function(next) {
|
||||
deleteTopicFromCategory(tid, next);
|
||||
}
|
||||
], function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
plugins.fireHook('action:topic.delete', tid);
|
||||
db.delete('topic:' + tid, callback);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteTopicFromCategory(tid, callback) {
|
||||
topics.getTopicFields(tid, ['cid', 'deleted'], function(err, topicData) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
db.sortedSetRemove('categories:' + topicData.cid + ':tid', tid, function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
db.decrObjectField('category:' + topicData.cid, 'topic_count', function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
if (parseInt(topicData.deleted, 10) === 0) {
|
||||
db.decrObjectField('global', 'topicCount', callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function deleteAccount(uid, callback) {
|
||||
user.getUserFields(uid, ['username', 'userslug', 'email'], function(err, userData) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
async.parallel([
|
||||
function(next) {
|
||||
db.deleteObjectField('username:uid', userData.username, next);
|
||||
},
|
||||
function(next) {
|
||||
db.deleteObjectField('userslug:uid', userData.userslug, next);
|
||||
},
|
||||
function(next) {
|
||||
db.deleteObjectField('email:uid', userData.email, next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('uid:' + uid + ':notifications:read', next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('uid:' + uid + ':notifications:unread', next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetRemove('users:joindate', uid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetRemove('users:postcount', uid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetRemove('users:reputation', uid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('uid:' + uid + ':favourites', next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('uid:' + uid + ':topics', next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('uid:' + uid + ':posts', next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('uid:' + uid + ':chats', next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('uid:' + uid + ':ip', next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('uid:' + uid + ':upvote', next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('uid:' + uid + ':downvote', next);
|
||||
},
|
||||
function(next) {
|
||||
deleteUserFromCategoryActiveUsers(uid, next);
|
||||
},
|
||||
function(next) {
|
||||
deleteUserFromFollowers(uid, next);
|
||||
},
|
||||
function(next) {
|
||||
deleteUserFromGroups(uid, next);
|
||||
}
|
||||
], function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
async.parallel([
|
||||
function(next) {
|
||||
db.delete('followers:' + uid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('following:' + uid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('user:' + uid, next);
|
||||
}
|
||||
], callback);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function deleteUserFromCategoryActiveUsers(uid, callback) {
|
||||
db.getSortedSetRange('categories:cid', 0, -1, function(err, cids) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
async.each(cids, function(cid, next) {
|
||||
categories.removeActiveUser(cid, uid, next);
|
||||
}, callback);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteUserFromFollowers(uid, callback) {
|
||||
db.getSetMembers('followers:' + uid, function(err, uids) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
async.each(uids, function(theiruid, next) {
|
||||
db.setRemove('following:' + theiruid, uid, next);
|
||||
}, callback);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteUserFromGroups(uid, callback) {
|
||||
groups.getGroupIds(function(err, gids) {
|
||||
async.each(gids, function(gid, next) {
|
||||
groups.leave(gid, uid, next);
|
||||
}, callback);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
331
src/user/delete.js
Normal file
331
src/user/delete.js
Normal file
@@ -0,0 +1,331 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var async = require('async'),
|
||||
db = require('./../database'),
|
||||
posts = require('./../posts'),
|
||||
user = require('./../user'),
|
||||
topics = require('./../topics'),
|
||||
categories = require('./../categories'),
|
||||
plugins = require('./../plugins'),
|
||||
events = require('./../events'),
|
||||
groups = require('./../groups');
|
||||
|
||||
|
||||
module.exports = function(User) {
|
||||
|
||||
User.delete = function(adminUid, uid, callback) {
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
deletePosts(uid, next);
|
||||
},
|
||||
function(next) {
|
||||
deleteTopics(uid, next);
|
||||
},
|
||||
function(next) {
|
||||
events.logAdminUserDelete(adminUid, uid, next);
|
||||
}
|
||||
], function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
deleteAccount(uid, callback);
|
||||
});
|
||||
};
|
||||
|
||||
function deletePosts(uid, callback) {
|
||||
deleteSortedSetElements('uid:' + uid + ':posts', deletePost, callback);
|
||||
}
|
||||
|
||||
function deletePost(pid, callback) {
|
||||
async.parallel([
|
||||
function(next) {
|
||||
deletePostFromTopic(pid, next);
|
||||
},
|
||||
function(next) {
|
||||
deletePostFromCategoryRecentPosts(pid, next);
|
||||
},
|
||||
function(next) {
|
||||
deletePostFromUsersFavourites(pid, next);
|
||||
},
|
||||
function(next) {
|
||||
deletePostFromUsersVotes(pid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetRemove('posts:pid', pid, next);
|
||||
}
|
||||
], function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
plugins.fireHook('action:post.delete', pid);
|
||||
db.delete('post:' + pid, callback);
|
||||
});
|
||||
}
|
||||
|
||||
function deletePostFromTopic(pid, callback) {
|
||||
posts.getPostFields(pid, ['tid', 'deleted'], function(err, postData) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
db.sortedSetRemove('tid:' + postData.tid + ':posts', pid, function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
if (parseInt(postData.deleted, 10) === 0) {
|
||||
db.decrObjectField('global', 'postCount', callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function deletePostFromCategoryRecentPosts(pid, callback) {
|
||||
db.getSortedSetRange('categories:cid', 0, -1, function(err, cids) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
async.each(cids, function(cid, next) {
|
||||
db.sortedSetRemove('categories:recent_posts:cid:' + cid, pid, next);
|
||||
}, callback);
|
||||
});
|
||||
}
|
||||
|
||||
function deletePostFromUsersFavourites(pid, callback) {
|
||||
db.getSetMembers('pid:' + pid + ':users_favourited', function(err, uids) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
async.each(uids, function(uid, next) {
|
||||
db.sortedSetRemove('uid:' + uid + ':favourites', pid, next);
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
db.delete('pid:' + pid + ':users_favourited', callback);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function deletePostFromUsersVotes(pid, callback) {
|
||||
async.parallel({
|
||||
upvoters: function(next) {
|
||||
db.getSetMembers('pid:' + pid + ':upvote', next);
|
||||
},
|
||||
downvoters: function(next) {
|
||||
db.getSetMembers('pid:' + pid + ':downvote', next);
|
||||
}
|
||||
}, function(err, results) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
async.parallel([
|
||||
function(next) {
|
||||
async.each(results.upvoters, function(uid, next) {
|
||||
db.sortedSetRemove('uid:' + uid + ':upvote', pid, next);
|
||||
}, next);
|
||||
},
|
||||
function(next) {
|
||||
async.each(results.downvoters, function(uid, next) {
|
||||
db.sortedSetRemove('uid:' + uid + ':downvote', pid, next);
|
||||
}, next);
|
||||
}
|
||||
], callback);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteTopics(uid, callback) {
|
||||
deleteSortedSetElements('uid:' + uid + ':topics', deleteTopic, callback);
|
||||
}
|
||||
|
||||
function deleteSortedSetElements(set, deleteMethod, callback) {
|
||||
db.getSortedSetRange(set, 0, -1, function(err, ids) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
async.each(ids, deleteMethod, callback);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteTopic(tid, callback) {
|
||||
|
||||
async.parallel([
|
||||
function(next) {
|
||||
db.delete('tid:' + tid + ':followers', next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('tid:' + tid + ':read_by_uid', next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetRemove('topics:tid', tid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetRemove('topics:recent', tid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetRemove('topics:posts', tid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetRemove('topics:views', tid, next);
|
||||
},
|
||||
function(next) {
|
||||
deleteTopicFromCategory(tid, next);
|
||||
}
|
||||
], function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
plugins.fireHook('action:topic.delete', tid);
|
||||
db.delete('topic:' + tid, callback);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteTopicFromCategory(tid, callback) {
|
||||
topics.getTopicFields(tid, ['cid', 'deleted'], function(err, topicData) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
db.sortedSetRemove('categories:' + topicData.cid + ':tid', tid, function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
db.decrObjectField('category:' + topicData.cid, 'topic_count', function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
if (parseInt(topicData.deleted, 10) === 0) {
|
||||
db.decrObjectField('global', 'topicCount', callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function deleteAccount(uid, callback) {
|
||||
user.getUserFields(uid, ['username', 'userslug', 'email'], function(err, userData) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
async.parallel([
|
||||
function(next) {
|
||||
db.deleteObjectField('username:uid', userData.username, next);
|
||||
},
|
||||
function(next) {
|
||||
db.deleteObjectField('userslug:uid', userData.userslug, next);
|
||||
},
|
||||
function(next) {
|
||||
db.deleteObjectField('email:uid', userData.email, next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('uid:' + uid + ':notifications:read', next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('uid:' + uid + ':notifications:unread', next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetRemove('users:joindate', uid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetRemove('users:postcount', uid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetRemove('users:reputation', uid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('uid:' + uid + ':favourites', next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('uid:' + uid + ':topics', next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('uid:' + uid + ':posts', next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('uid:' + uid + ':chats', next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('uid:' + uid + ':ip', next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('uid:' + uid + ':upvote', next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('uid:' + uid + ':downvote', next);
|
||||
},
|
||||
function(next) {
|
||||
deleteUserFromCategoryActiveUsers(uid, next);
|
||||
},
|
||||
function(next) {
|
||||
deleteUserFromFollowers(uid, next);
|
||||
},
|
||||
function(next) {
|
||||
deleteUserFromGroups(uid, next);
|
||||
}
|
||||
], function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
async.parallel([
|
||||
function(next) {
|
||||
db.delete('followers:' + uid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('following:' + uid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.delete('user:' + uid, next);
|
||||
}
|
||||
], callback);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function deleteUserFromCategoryActiveUsers(uid, callback) {
|
||||
db.getSortedSetRange('categories:cid', 0, -1, function(err, cids) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
async.each(cids, function(cid, next) {
|
||||
categories.removeActiveUser(cid, uid, next);
|
||||
}, callback);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteUserFromFollowers(uid, callback) {
|
||||
db.getSetMembers('followers:' + uid, function(err, uids) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
async.each(uids, function(theiruid, next) {
|
||||
db.setRemove('following:' + theiruid, uid, next);
|
||||
}, callback);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteUserFromGroups(uid, callback) {
|
||||
groups.getGroupIds(function(err, gids) {
|
||||
async.each(gids, function(gid, next) {
|
||||
groups.leave(gid, uid, next);
|
||||
}, callback);
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user