|
|
|
@ -2,83 +2,121 @@
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
var async = require('async');
|
|
|
|
|
|
|
|
|
|
var meta = require('../meta');
|
|
|
|
|
var db = require('../database');
|
|
|
|
|
var plugins = require('../plugins');
|
|
|
|
|
|
|
|
|
|
var LRU = require('lru-cache');
|
|
|
|
|
|
|
|
|
|
var cache = LRU({
|
|
|
|
|
max: 500,
|
|
|
|
|
length: function () { return 1; },
|
|
|
|
|
maxAge: 1000 * 60 * 60,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
module.exports = function (User) {
|
|
|
|
|
User.settingsCache = cache;
|
|
|
|
|
|
|
|
|
|
User.getSettings = function (uid, callback) {
|
|
|
|
|
if (!parseInt(uid, 10)) {
|
|
|
|
|
return onSettingsLoaded(0, {}, callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
db.getObject('user:' + uid + ':settings', function (err, settings) {
|
|
|
|
|
if (err) {
|
|
|
|
|
return callback(err);
|
|
|
|
|
}
|
|
|
|
|
var cached = cache.get('user:' + uid + ':settings');
|
|
|
|
|
if (cached) {
|
|
|
|
|
return onSettingsLoaded(uid, cached || {}, callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onSettingsLoaded(uid, settings || {}, callback);
|
|
|
|
|
});
|
|
|
|
|
async.waterfall([
|
|
|
|
|
function (next) {
|
|
|
|
|
db.getObject('user:' + uid + ':settings', next);
|
|
|
|
|
},
|
|
|
|
|
function (settings, next) {
|
|
|
|
|
settings = settings || {};
|
|
|
|
|
settings.uid = uid;
|
|
|
|
|
cache.set('user:' + uid + ':settings', settings);
|
|
|
|
|
onSettingsLoaded(uid, settings || {}, next);
|
|
|
|
|
},
|
|
|
|
|
], callback);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
User.getMultipleUserSettings = function (uids, callback) {
|
|
|
|
|
function getFromCache(next) {
|
|
|
|
|
var settings = uids.map(function (uid) {
|
|
|
|
|
return cache.get('user:' + uid + ':settings') || {};
|
|
|
|
|
});
|
|
|
|
|
async.map(settings, function (setting, next) {
|
|
|
|
|
onSettingsLoaded(setting.uid, setting, next);
|
|
|
|
|
}, next);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!Array.isArray(uids) || !uids.length) {
|
|
|
|
|
return callback(null, []);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var keys = uids.map(function (uid) {
|
|
|
|
|
return 'user:' + uid + ':settings';
|
|
|
|
|
var nonCachedUids = uids.filter(function (uid) {
|
|
|
|
|
return !cache.has('user:' + uid + ':settings');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
db.getObjects(keys, function (err, settings) {
|
|
|
|
|
if (err) {
|
|
|
|
|
return callback(err);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < settings.length; i += 1) {
|
|
|
|
|
settings[i] = settings[i] || {};
|
|
|
|
|
settings[i].uid = uids[i];
|
|
|
|
|
}
|
|
|
|
|
if (!nonCachedUids.length) {
|
|
|
|
|
return getFromCache(callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async.map(settings, function (setting, next) {
|
|
|
|
|
onSettingsLoaded(setting.uid, setting, next);
|
|
|
|
|
}, callback);
|
|
|
|
|
var keys = nonCachedUids.map(function (uid) {
|
|
|
|
|
return 'user:' + uid + ':settings';
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
async.waterfall([
|
|
|
|
|
function (next) {
|
|
|
|
|
db.getObjects(keys, next);
|
|
|
|
|
},
|
|
|
|
|
function (settings, next) {
|
|
|
|
|
settings.forEach(function (userSettings, index) {
|
|
|
|
|
userSettings = userSettings || {};
|
|
|
|
|
userSettings.uid = nonCachedUids[index];
|
|
|
|
|
cache.set('user:' + userSettings.uid + ':settings', userSettings);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
getFromCache(next);
|
|
|
|
|
},
|
|
|
|
|
], callback);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function onSettingsLoaded(uid, settings, callback) {
|
|
|
|
|
plugins.fireHook('filter:user.getSettings', { uid: uid, settings: settings }, function (err, data) {
|
|
|
|
|
if (err) {
|
|
|
|
|
return callback(err);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
settings = data.settings;
|
|
|
|
|
|
|
|
|
|
var defaultTopicsPerPage = parseInt(meta.config.topicsPerPage, 10) || 20;
|
|
|
|
|
var defaultPostsPerPage = parseInt(meta.config.postsPerPage, 10) || 20;
|
|
|
|
|
|
|
|
|
|
settings.showemail = parseInt(getSetting(settings, 'showemail', 0), 10) === 1;
|
|
|
|
|
settings.showfullname = parseInt(getSetting(settings, 'showfullname', 0), 10) === 1;
|
|
|
|
|
settings.openOutgoingLinksInNewTab = parseInt(getSetting(settings, 'openOutgoingLinksInNewTab', 0), 10) === 1;
|
|
|
|
|
settings.dailyDigestFreq = getSetting(settings, 'dailyDigestFreq', 'off');
|
|
|
|
|
settings.usePagination = parseInt(getSetting(settings, 'usePagination', 0), 10) === 1;
|
|
|
|
|
settings.topicsPerPage = Math.min(settings.topicsPerPage ? parseInt(settings.topicsPerPage, 10) : defaultTopicsPerPage, defaultTopicsPerPage);
|
|
|
|
|
settings.postsPerPage = Math.min(settings.postsPerPage ? parseInt(settings.postsPerPage, 10) : defaultPostsPerPage, defaultPostsPerPage);
|
|
|
|
|
settings.userLang = settings.userLang || meta.config.defaultLang || 'en-GB';
|
|
|
|
|
settings.topicPostSort = getSetting(settings, 'topicPostSort', 'oldest_to_newest');
|
|
|
|
|
settings.categoryTopicSort = getSetting(settings, 'categoryTopicSort', 'newest_to_oldest');
|
|
|
|
|
settings.followTopicsOnCreate = parseInt(getSetting(settings, 'followTopicsOnCreate', 1), 10) === 1;
|
|
|
|
|
settings.followTopicsOnReply = parseInt(getSetting(settings, 'followTopicsOnReply', 0), 10) === 1;
|
|
|
|
|
settings.sendChatNotifications = parseInt(getSetting(settings, 'sendChatNotifications', 0), 10) === 1;
|
|
|
|
|
settings.sendPostNotifications = parseInt(getSetting(settings, 'sendPostNotifications', 0), 10) === 1;
|
|
|
|
|
settings.restrictChat = parseInt(getSetting(settings, 'restrictChat', 0), 10) === 1;
|
|
|
|
|
settings.topicSearchEnabled = parseInt(getSetting(settings, 'topicSearchEnabled', 0), 10) === 1;
|
|
|
|
|
settings.delayImageLoading = parseInt(getSetting(settings, 'delayImageLoading', 1), 10) === 1;
|
|
|
|
|
settings.bootswatchSkin = settings.bootswatchSkin || meta.config.bootswatchSkin || 'default';
|
|
|
|
|
settings.scrollToMyPost = parseInt(getSetting(settings, 'scrollToMyPost', 1), 10) === 1;
|
|
|
|
|
|
|
|
|
|
callback(null, settings);
|
|
|
|
|
});
|
|
|
|
|
async.waterfall([
|
|
|
|
|
function (next) {
|
|
|
|
|
plugins.fireHook('filter:user.getSettings', { uid: uid, settings: settings }, next);
|
|
|
|
|
},
|
|
|
|
|
function (data, next) {
|
|
|
|
|
settings = data.settings;
|
|
|
|
|
|
|
|
|
|
var defaultTopicsPerPage = parseInt(meta.config.topicsPerPage, 10) || 20;
|
|
|
|
|
var defaultPostsPerPage = parseInt(meta.config.postsPerPage, 10) || 20;
|
|
|
|
|
|
|
|
|
|
settings.showemail = parseInt(getSetting(settings, 'showemail', 0), 10) === 1;
|
|
|
|
|
settings.showfullname = parseInt(getSetting(settings, 'showfullname', 0), 10) === 1;
|
|
|
|
|
settings.openOutgoingLinksInNewTab = parseInt(getSetting(settings, 'openOutgoingLinksInNewTab', 0), 10) === 1;
|
|
|
|
|
settings.dailyDigestFreq = getSetting(settings, 'dailyDigestFreq', 'off');
|
|
|
|
|
settings.usePagination = parseInt(getSetting(settings, 'usePagination', 0), 10) === 1;
|
|
|
|
|
settings.topicsPerPage = Math.min(settings.topicsPerPage ? parseInt(settings.topicsPerPage, 10) : defaultTopicsPerPage, defaultTopicsPerPage);
|
|
|
|
|
settings.postsPerPage = Math.min(settings.postsPerPage ? parseInt(settings.postsPerPage, 10) : defaultPostsPerPage, defaultPostsPerPage);
|
|
|
|
|
settings.userLang = settings.userLang || meta.config.defaultLang || 'en-GB';
|
|
|
|
|
settings.topicPostSort = getSetting(settings, 'topicPostSort', 'oldest_to_newest');
|
|
|
|
|
settings.categoryTopicSort = getSetting(settings, 'categoryTopicSort', 'newest_to_oldest');
|
|
|
|
|
settings.followTopicsOnCreate = parseInt(getSetting(settings, 'followTopicsOnCreate', 1), 10) === 1;
|
|
|
|
|
settings.followTopicsOnReply = parseInt(getSetting(settings, 'followTopicsOnReply', 0), 10) === 1;
|
|
|
|
|
settings.sendChatNotifications = parseInt(getSetting(settings, 'sendChatNotifications', 0), 10) === 1;
|
|
|
|
|
settings.sendPostNotifications = parseInt(getSetting(settings, 'sendPostNotifications', 0), 10) === 1;
|
|
|
|
|
settings.restrictChat = parseInt(getSetting(settings, 'restrictChat', 0), 10) === 1;
|
|
|
|
|
settings.topicSearchEnabled = parseInt(getSetting(settings, 'topicSearchEnabled', 0), 10) === 1;
|
|
|
|
|
settings.delayImageLoading = parseInt(getSetting(settings, 'delayImageLoading', 1), 10) === 1;
|
|
|
|
|
settings.bootswatchSkin = settings.bootswatchSkin || meta.config.bootswatchSkin || 'default';
|
|
|
|
|
settings.scrollToMyPost = parseInt(getSetting(settings, 'scrollToMyPost', 1), 10) === 1;
|
|
|
|
|
next(null, settings);
|
|
|
|
|
},
|
|
|
|
|
], callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getSetting(settings, key, defaultValue) {
|
|
|
|
@ -138,6 +176,7 @@ module.exports = function (User) {
|
|
|
|
|
User.updateDigestSetting(uid, data.dailyDigestFreq, next);
|
|
|
|
|
},
|
|
|
|
|
function (next) {
|
|
|
|
|
cache.del('user:' + uid + ':settings');
|
|
|
|
|
User.getSettings(uid, next);
|
|
|
|
|
},
|
|
|
|
|
], callback);
|
|
|
|
@ -160,8 +199,9 @@ module.exports = function (User) {
|
|
|
|
|
|
|
|
|
|
User.setSetting = function (uid, key, value, callback) {
|
|
|
|
|
if (!parseInt(uid, 10)) {
|
|
|
|
|
return callback();
|
|
|
|
|
return setImmediate(callback);
|
|
|
|
|
}
|
|
|
|
|
cache.del('user:' + uid + ':settings');
|
|
|
|
|
db.setObjectField('user:' + uid + ':settings', key, value, callback);
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|