Merge branch 'master' into nodebb-loader

This commit is contained in:
Julian Lam
2014-02-23 22:48:11 -05:00
45 changed files with 484 additions and 466 deletions

View File

@@ -13,10 +13,12 @@ var db = require('./../database'),
for (var key in category) {
db.setObjectField('category:' + cid, key, category[key]);
if (key == 'name') {
if (key === 'name') {
// reset slugs if name is updated
var slug = cid + '/' + utils.slugify(category[key]);
db.setObjectField('category:' + cid, 'slug', slug);
} else if (key === 'order') {
db.sortedSetAdd('categories:cid', category[key], cid);
}
}

View File

@@ -18,11 +18,10 @@ var db = require('./database'),
Categories.create = function(data, callback) {
db.incrObjectField('global', 'nextCid', function(err, cid) {
if (err) {
return callback(err, null);
return callback(err);
}
var slug = cid + '/' + utils.slugify(data.name);
db.listAppend('categories:cid', cid);
var category = {
cid: cid,
@@ -36,14 +35,20 @@ var db = require('./database'),
topic_count: 0,
disabled: 0,
order: data.order,
link: "",
link: '',
numRecentReplies: 2,
class: 'col-md-3 col-xs-6',
imageClass: 'default'
};
db.setObject('category:' + cid, category, function(err, data) {
callback(err, category);
db.setObject('category:' + cid, category, function(err) {
if(err) {
return callback(err);
}
db.sortedSetAdd('categories:cid', data.order, cid);
callback(null, category);
});
});
};
@@ -132,6 +137,10 @@ var db = require('./database'),
return callback(err);
}
if (parseInt(topicCount, 10) === 0) {
return callback(null, 1);
}
user.getSettings(uid, function(err, settings) {
if(err) {
return callback(err);
@@ -142,8 +151,8 @@ var db = require('./database'),
});
};
Categories.getAllCategories = function(current_user, callback) {
db.getListRange('categories:cid', 0, -1, function(err, cids) {
Categories.getAllCategories = function(uid, callback) {
db.getSortedSetRange('categories:cid', 0, -1, function(err, cids) {
if(err) {
return callback(err);
}
@@ -152,7 +161,7 @@ var db = require('./database'),
return callback(null, {categories : []});
}
Categories.getCategories(cids, current_user, callback);
Categories.getCategories(cids, uid, callback);
});
};
@@ -311,14 +320,11 @@ var db = require('./database'),
async.map(cids, getCategory, function(err, categories) {
if (err) {
winston.err(err);
return callback(err, null);
return callback(err);
}
categories = categories.filter(function(category) {
return !!category;
}).sort(function(a, b) {
return parseInt(a.order, 10) - parseInt(b.order, 10);
});
callback(null, {

View File

@@ -2,9 +2,14 @@ var Groups = require('./groups'),
User = require('./user'),
async = require('async'),
db = require('./database'),
CategoryTools = {};
CategoryTools.exists = function(cid, callback) {
db.isSortedSetMember('categories:cid', cid, callback);
};
CategoryTools.privileges = function(cid, uid, callback) {
async.parallel({
"+r": function(next) {

View File

@@ -339,7 +339,7 @@ var async = require('async'),
winston.info('Enabling default plugins');
var defaultEnabled = [
'nodebb-plugin-markdown', 'nodebb-plugin-mentions'
'nodebb-plugin-markdown', 'nodebb-plugin-mentions', 'nodebb-widget-essentials'
];
async.each(defaultEnabled, function (pluginId, next) {

View File

@@ -375,11 +375,15 @@ var fs = require('fs'),
dirs = dirs.map(function(file) {
return path.join(npmPluginPath, file);
}).filter(function(file) {
var stats = fs.statSync(file),
isPlugin = file.substr(npmPluginPath.length + 1, 14) === 'nodebb-plugin-' || file.substr(npmPluginPath.length + 1, 14) === 'nodebb-widget-';
if (fs.existsSync(file)) {
var stats = fs.statSync(file),
isPlugin = file.substr(npmPluginPath.length + 1, 14) === 'nodebb-plugin-' || file.substr(npmPluginPath.length + 1, 14) === 'nodebb-widget-';
if (stats.isDirectory() && isPlugin) return true;
else return false;
if (stats.isDirectory() && isPlugin) return true;
else return false;
} else {
return false;
}
});
next(err, dirs);

View File

@@ -20,7 +20,12 @@ var db = require('./database'),
(function(Posts) {
var customUserInfo = {};
Posts.create = function(uid, tid, content, callback) {
Posts.create = function(data, callback) {
var uid = data.uid,
tid = data.tid,
content = data.content,
toPid = data.toPid;
if (uid === null) {
return callback(new Error('invalid-user'), null);
}
@@ -56,6 +61,10 @@ var db = require('./database'),
'deleted': 0
};
if (toPid) {
postData['toPid'] = toPid;
}
db.setObject('post:' + pid, postData, function(err) {
if(err) {
return next(err);
@@ -78,7 +87,7 @@ var db = require('./database'),
function(postData, next) {
postTools.parse(postData.content, function(err, content) {
if(err) {
return next(err, null);
return next(err);
}
postData.content = content;
@@ -294,24 +303,24 @@ var db = require('./database'),
});
},
function(postData, next) {
if (postData.content) {
postTools.parse(postData.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'])).s;
} else {
postData.content = content;
}
next(null, postData);
});
} else {
next(null, postData);
if (!postData.content) {
return next(null, postData);
}
postTools.parse(postData.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'])).s;
} else {
postData.content = content;
}
next(null, postData);
});
}
], callback);
}
@@ -474,31 +483,31 @@ var db = require('./database'),
}
Posts.getPidPage = function(pid, uid, callback) {
Posts.getPostField(pid, 'tid', function(err, tid) {
if(err) {
return callback(err);
}
topics.getPids(tid, function(err, pids) {
if(err) {
return callback(err);
}
var index = pids.indexOf(pid);
if(!pid) {
return callback(new Error('invalid-pid'));
}
var index = 0;
async.waterfall([
function(next) {
Posts.getPostField(pid, 'tid', next);
},
function(tid, next) {
topics.getPids(tid, next);
},
function(pids, next) {
index = pids.indexOf(pid.toString());
if(index === -1) {
return callback(new Error('pid not found'));
return next(new Error('pid not found'));
}
user.getSettings(uid, function(err, settings) {
if(err) {
return callback(err);
}
var page = Math.ceil((index + 1) / settings.postsPerPage);
callback(null, page);
});
});
});
next();
},
function(next) {
user.getSettings(uid, next);
},
function(settings, next) {
next(null, Math.ceil((index + 1) / settings.postsPerPage));
}
], callback);
};
Posts.getPidIndex = function(pid, callback) {

View File

@@ -44,6 +44,7 @@ var path = require('path'),
app.get('/config', function (req, res, next) {
var config = require('../../public/config.json');
config.version = pkg.version;
config.postDelay = meta.config.postDelay;
config.minimumTitleLength = meta.config.minimumTitleLength;
config.maximumTitleLength = meta.config.maximumTitleLength;
@@ -286,6 +287,9 @@ var path = require('path'),
app.get('/unread', function (req, res, next) {
var uid = (req.user) ? req.user.uid : 0;
if(!req.user) {
return res.json(403, 'not-allowed');
}
topics.getUnreadTopics(uid, 0, 19, function (err, data) {
if(err) {
return next(err);
@@ -297,6 +301,9 @@ var path = require('path'),
app.get('/unread/total', function (req, res, next) {
var uid = (req.user) ? req.user.uid : 0;
if(!req.user) {
return res.json(403, 'not-allowed');
}
topics.getTotalUnread(uid, function (err, data) {
if(err) {
return next(err);

View File

@@ -14,6 +14,7 @@ var async = require('async'),
SocketPosts = {};
SocketPosts.reply = function(socket, data, callback) {
if (!socket.uid && !parseInt(meta.config.allowGuestPosting, 10)) {
socket.emit('event:alert', {
title: 'Reply Unsuccessful',
@@ -24,11 +25,13 @@ SocketPosts.reply = function(socket, data, callback) {
return callback(new Error('not-logged-in'));
}
if(!data || !data.topic_id || !data.content) {
if(!data || !data.tid || !data.content) {
return callback(new Error('invalid data'));
}
topics.reply(data.topic_id, socket.uid, data.content, function(err, postData) {
data.uid = socket.uid;
topics.reply(data, function(err, postData) {
if(err) {
if (err.message === 'content-too-short') {
module.parent.exports.emitContentTooShortAlert(socket);

View File

@@ -1,6 +1,7 @@
var async = require('async'),
user = require('../user'),
topics = require('../topics'),
utils = require('./../../public/src/utils'),
SocketUser = {};
SocketUser.exists = function(socket, data, callback) {

View File

@@ -18,15 +18,7 @@ var winston = require('winston'),
(function(ThreadTools) {
ThreadTools.exists = function(tid, callback) {
db.isSortedSetMember('topics:tid', tid, function(err, ismember) {
if (err) {
callback(false);
}
callback(ismember);
});
db.isSortedSetMember('topics:tid', tid, callback);
}
ThreadTools.privileges = function(tid, uid, callback) {

View File

@@ -106,6 +106,12 @@ var async = require('async'),
async.waterfall([
function(next) {
categoryTools.exists(cid, next);
},
function(categoryExists, next) {
if(!categoryExists) {
return next(new Error('category doesn\'t exist'))
}
categoryTools.privileges(cid, uid, next);
},
function(privileges, next) {
@@ -121,7 +127,7 @@ var async = require('async'),
Topics.create({uid: uid, title: title, cid: cid, thumb: thumb}, next);
},
function(tid, next) {
Topics.reply(tid, uid, content, next);
Topics.reply({uid:uid, tid:tid, content:content}, next);
},
function(postData, next) {
threadTools.toggleFollow(postData.tid, uid);
@@ -143,12 +149,22 @@ var async = require('async'),
], callback);
};
Topics.reply = function(tid, uid, content, callback) {
var privileges;
var postData;
Topics.reply = function(data, callback) {
var tid = data.tid,
uid = data.uid,
toPid = data.toPid,
content = data.content,
privileges,
postData;
async.waterfall([
function(next) {
threadTools.exists(tid, next);
},
function(topicExists, next) {
if (!topicExists) {
return next(new Error('topic doesn\'t exist'));
}
threadTools.privileges(tid, uid, next);
},
function(privilegesData, next) {
@@ -170,7 +186,7 @@ var async = require('async'),
return next(new Error('content-too-short'));
}
posts.create(uid, tid, content, next);
posts.create({uid:uid, tid:tid, content:content, toPid:toPid}, next);
},
function(data, next) {
postData = data;
@@ -261,9 +277,9 @@ var async = require('async'),
};
Topics.movePostToTopic = function(pid, tid, callback) {
threadTools.exists(tid, function(exists) {
if(!exists) {
return callback(new Error('Topic doesn\'t exist'));
threadTools.exists(tid, function(err, exists) {
if(err || !exists) {
return callback(err || new Error('Topic doesn\'t exist'));
}
posts.getPostFields(pid, ['deleted', 'tid', 'timestamp'], function(err, postData) {
@@ -422,7 +438,9 @@ var async = require('async'),
if(err) {
return callback(err);
}
if(!parseInt(postCount, 10)) {
return callback(null, 1);
}
user.getSettings(uid, function(err, settings) {
if(err) {
return callback(err);
@@ -445,7 +463,8 @@ var async = require('async'),
function getTopics(set, uid, tids, callback) {
var returnTopics = {
'topics': []
topics: [],
nextStart: 0
};
if (!tids || !tids.length) {
@@ -571,17 +590,13 @@ var async = require('async'),
};
Topics.getUnreadTopics = function(uid, start, stop, callback) {
var unreadTopics = {
'show_markallread_button': 'show',
'no_topics_message': 'hidden',
'topics': []
};
function noUnreadTopics() {
unreadTopics.no_topics_message = '';
unreadTopics.show_markallread_button = 'hidden';
callback(null, unreadTopics);
}
var unreadTopics = {
no_topics_message: '',
show_markallread_button: 'hidden',
nextStart : 0,
topics: []
};
function sendUnreadTopics(topicIds) {
@@ -597,13 +612,8 @@ var async = require('async'),
unreadTopics.topics = topicData;
unreadTopics.nextStart = parseInt(rank, 10) + 1;
if (!topicData || topicData.length === 0) {
unreadTopics.no_topics_message = '';
}
if (uid === 0 || topicData.length === 0) {
unreadTopics.show_markallread_button = 'hidden';
}
unreadTopics.no_topics_message = (!topicData || topicData.length === 0) ? '' : 'hidden';
unreadTopics.show_markallread_button = topicData.length === 0 ? 'hidden' : '';
callback(null, unreadTopics);
});
@@ -618,7 +628,7 @@ var async = require('async'),
if (unreadTids.length) {
sendUnreadTopics(unreadTids);
} else {
noUnreadTopics();
callback(null, unreadTopics);
}
});
};
@@ -766,9 +776,9 @@ var async = require('async'),
};
Topics.getTopicWithPosts = function(tid, current_user, start, end, quiet, callback) {
threadTools.exists(tid, function(exists) {
if (!exists) {
return callback(new Error('Topic tid \'' + tid + '\' not found'));
threadTools.exists(tid, function(err, exists) {
if (err || !exists) {
return callback(err || new Error('Topic tid \'' + tid + '\' not found'));
}
// "quiet" is used for things like RSS feed updating, HTML parsing for non-js users, etc

View File

@@ -7,6 +7,7 @@ var db = require('./database'),
User = require('./user'),
Topics = require('./topics'),
Posts = require('./posts'),
Categories = require('./categories'),
Groups = require('./groups'),
Meta = require('./meta'),
Plugins = require('./plugins'),
@@ -15,13 +16,20 @@ var db = require('./database'),
Upgrade = {},
minSchemaDate = new Date(2014, 0, 4).getTime(), // This value gets updated every new MINOR version
schemaDate, thisSchemaDate;
schemaDate, thisSchemaDate,
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema
latestSchema = new Date(2014, 1, 22).getTime();
Upgrade.check = function(callback) {
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema
var latestSchema = new Date(2014, 1, 20, 20, 25).getTime();
db.get('schemaDate', function(err, value) {
if(!value) {
db.set('schemaDate', latestSchema, function(err) {
callback(true);
});
return;
}
if (parseInt(value, 10) >= latestSchema) {
callback(true);
} else {
@@ -39,9 +47,16 @@ Upgrade.upgrade = function(callback) {
function(next) {
// Prepare for upgrade & check to make sure the upgrade is possible
db.get('schemaDate', function(err, value) {
schemaDate = value;
if(!value) {
db.set('schemaDate', latestSchema, function(err) {
next();
});
schemaDate = latestSchema;
} else {
schemaDate = parseInt(value, 10);
}
if (schemaDate >= minSchemaDate || schemaDate === null) {
if (schemaDate >= minSchemaDate) {
next();
} else {
next(new Error('upgrade-not-possible'));
@@ -691,7 +706,7 @@ Upgrade.upgrade = function(callback) {
if (schemaDate < thisSchemaDate) {
updatesMade = true;
db.setObjectField('widgets:home.tpl', 'motd', JSON.stringify([
{
"widget": "html",
@@ -717,9 +732,9 @@ Upgrade.upgrade = function(callback) {
if (schemaDate < thisSchemaDate) {
updatesMade = true;
var container = '<div class="panel panel-default"><div class="panel-heading">{title}</div><div class="panel-body">{body}</div></div>';
db.setObjectField('widgets:category.tpl', 'sidebar', JSON.stringify([
{
"widget": "recentreplies",
@@ -756,7 +771,7 @@ Upgrade.upgrade = function(callback) {
if (schemaDate < thisSchemaDate) {
updatesMade = true;
db.setObjectField('widgets:home.tpl', 'footer', JSON.stringify([
{
"widget": "forumstats",
@@ -778,7 +793,7 @@ Upgrade.upgrade = function(callback) {
updatesMade = true;
var container = '<div class="panel panel-default"><div class="panel-heading">{title}</div><div class="panel-body">{body}</div></div>';
db.setObjectField('widgets:home.tpl', 'sidebar', JSON.stringify([
{
"widget": "html",
@@ -813,9 +828,62 @@ Upgrade.upgrade = function(callback) {
winston.info('[2014/2/20] Activating NodeBB Essential Widgets - skipped');
next();
}
},
function(next) {
thisSchemaDate = new Date(2014, 1, 22).getTime();
if (schemaDate < thisSchemaDate) {
updatesMade = true;
db.exists('categories:cid', function(err, exists) {
if(err) {
return next(err);
}
if(!exists) {
winston.info('[2014/2/22] Added categories to sorted set - skipped');
return next();
}
db.getListRange('categories:cid', 0, -1, function(err, cids) {
if(err) {
return next(err);
}
if(!Array.isArray(cids)) {
winston.info('[2014/2/22] Add categories to sorted set - skipped (cant find any cids)');
return next();
}
db.rename('categories:cid', 'categories:cid:old', function(err) {
if(err) {
return next(err);
}
async.each(cids, function(cid, next) {
Categories.getCategoryField(cid, 'order', function(err, order) {
if(err) {
return next(err);
}
db.sortedSetAdd('categories:cid', order, cid, next);
});
}, function(err) {
if(err) {
return next(err);
}
winston.info('[2014/2/22] Added categories to sorted set');
db.delete('categories:cid:old', next);
});
});
});
});
} else {
winston.info('[2014/2/22] Added categories to sorted set - skipped');
next();
}
}
// Add new schema updates here
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema IN LINE 17!!!
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema IN LINE 22!!!
], function(err) {
if (!err) {
db.set('schemaDate', thisSchemaDate, function(err) {
@@ -825,6 +893,7 @@ Upgrade.upgrade = function(callback) {
} else {
winston.info('[upgrade] Schema already up to date!');
}
if (callback) {
callback(err);
} else {