Merge remote-tracking branch 'origin/master' into develop

This commit is contained in:
Julian Lam
2018-01-29 18:11:30 -05:00
16 changed files with 124 additions and 78 deletions

View File

@@ -113,7 +113,7 @@ helpers.getUserDataByUserSlug = function (userslug, callerUID, callback) {
userData.fullname = '';
}
if (isAdmin || isSelf || (isGlobalModerator && !results.isTargetAdmin)) {
if (isAdmin || isSelf || ((isGlobalModerator || isModerator) && !results.isTargetAdmin)) {
userData.ips = results.ips;
}

View File

@@ -3,9 +3,12 @@
var async = require('async');
var nconf = require('nconf');
var topics = require('../topics');
var meta = require('../meta');
var user = require('../user');
var helpers = require('./helpers');
var pagination = require('../pagination');
var popularController = module.exports;
@@ -19,6 +22,7 @@ var terms = {
};
popularController.get = function (req, res, next) {
var page = parseInt(req.query.page, 10) || 1;
var term = terms[req.params.term];
if (!term && req.params.term) {
@@ -38,19 +42,25 @@ popularController.get = function (req, res, next) {
return res.render('popular', anonCache[term]);
}
}
var settings;
async.waterfall([
function (next) {
topics.getPopular(term, req.uid, meta.config.topicsPerList, next);
user.getSettings(req.uid, next);
},
function (topics) {
var data = {
title: meta.config.homePageTitle || '[[pages:home]]',
topics: topics,
'feeds:disableRSS': parseInt(meta.config['feeds:disableRSS'], 10) === 1,
rssFeedUrl: nconf.get('relative_path') + '/popular/' + (req.params.term || 'daily') + '.rss',
term: term,
};
function (_settings, next) {
settings = _settings;
var start = Math.max(0, (page - 1) * settings.topicsPerPage);
var stop = start + settings.topicsPerPage - 1;
topics.getPopularTopics(term, req.uid, start, stop, next);
},
function (data) {
var pageCount = Math.max(1, Math.ceil(data.topicCount / settings.topicsPerPage));
data.title = meta.config.homePageTitle || '[[pages:home]]';
data['feeds:disableRSS'] = parseInt(meta.config['feeds:disableRSS'], 10) === 1;
data.rssFeedUrl = nconf.get('relative_path') + '/popular/' + (req.params.term || 'alltime') + '.rss';
data.term = term;
data.pagination = pagination.create(page, pageCount, req.query);
if (req.originalUrl.startsWith(nconf.get('relative_path') + '/api/popular') || req.originalUrl.startsWith(nconf.get('relative_path') + '/popular')) {
data.title = '[[pages:popular-' + term + ']]';

View File

@@ -99,13 +99,14 @@ middleware.routeTouchIcon = function (req, res) {
if (meta.config['brand:touchIcon'] && validator.isURL(meta.config['brand:touchIcon'])) {
return res.redirect(meta.config['brand:touchIcon']);
}
var iconPath = '../../public';
var iconPath = '';
if (meta.config['brand:touchIcon']) {
iconPath += meta.config['brand:touchIcon'].replace(/assets\/uploads/, 'uploads');
iconPath = path.join(nconf.get('upload_path'), meta.config['brand:touchIcon'].replace(/assets\/uploads/, ''));
} else {
iconPath += '/logo.png';
iconPath = path.join(nconf.get('base_dir'), 'public/logo.png');
}
return res.sendFile(path.join(__dirname, iconPath), {
return res.sendFile(iconPath, {
maxAge: req.app.enabled('cache') ? 5184000000 : 0,
});
};

View File

@@ -13,6 +13,7 @@ var meta = require('../meta');
var helpers = require('../controllers/helpers');
var privileges = require('../privileges');
var db = require('../database');
var utils = require('../utils');
var controllers404 = require('../controllers/404.js');
module.exports = function (app, middleware) {
@@ -105,7 +106,7 @@ function generateForTopic(req, res, callback) {
var author = topicData.posts.length ? topicData.posts[0].username : '';
var feed = new rss({
title: topicData.title,
title: utils.stripHTMLTags(topicData.title, utils.stripTags),
description: description,
feed_url: nconf.get('url') + '/topic/' + tid + '.rss',
site_url: nconf.get('url') + '/topic/' + topicData.slug,
@@ -124,7 +125,7 @@ function generateForTopic(req, res, callback) {
dateStamp = new Date(parseInt(parseInt(postData.edited, 10) === 0 ? postData.timestamp : postData.edited, 10)).toUTCString();
feed.item({
title: 'Reply to ' + topicData.title + ' on ' + dateStamp,
title: 'Reply to ' + utils.stripHTMLTags(topicData.title, utils.stripTags) + ' on ' + dateStamp,
description: postData.content,
url: nconf.get('url') + '/post/' + postData.pid,
author: postData.user ? postData.user.username : '',
@@ -252,16 +253,16 @@ function generateForPopular(req, res, next) {
async.waterfall([
function (next) {
topics.getPopular(term, req.uid, 19, next);
topics.getPopularTopics(term, req.uid, 0, 19, next);
},
function (topics, next) {
function (result, next) {
generateTopicsFeed({
uid: req.uid,
title: 'Popular Topics',
description: 'A list of topics that are sorted by post count',
feed_url: '/popular/' + (req.params.term || 'daily') + '.rss',
site_url: '/popular/' + (req.params.term || 'daily'),
}, topics, next);
}, result.topics, next);
},
function (feed) {
sendFeed(feed, res);
@@ -300,7 +301,7 @@ function generateTopicsFeed(feedOptions, feedTopics, callback) {
async.each(feedTopics, function (topicData, next) {
var feedItem = {
title: topicData.title,
title: utils.stripHTMLTags(topicData.title, utils.stripTags),
url: nconf.get('url') + '/topic/' + topicData.slug,
date: new Date(parseInt(topicData.lastposttime, 10)).toUTCString(),
};

View File

@@ -88,37 +88,37 @@ module.exports = function (SocketTopics) {
};
SocketTopics.loadMoreUnreadTopics = function (socket, data, callback) {
if (!data || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) {
return callback(new Error('[[error:invalid-data]]'));
}
var start = parseInt(data.after, 10);
var stop = start + Math.max(0, Math.min(meta.config.topicsPerPage || 20, parseInt(data.count, 10) || meta.config.topicsPerPage || 20) - 1);
topics.getUnreadTopics({ cid: data.cid, uid: socket.uid, start: start, stop: stop, filter: data.filter }, callback);
loadData(data, callback, function (start, stop) {
topics.getUnreadTopics({ cid: data.cid, uid: socket.uid, start: start, stop: stop, filter: data.filter }, callback);
});
};
SocketTopics.loadMoreRecentTopics = function (socket, data, callback) {
if (!data || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) {
return callback(new Error('[[error:invalid-data]]'));
}
loadData(data, callback, function (start, stop) {
topics.getRecentTopics(data.cid, socket.uid, start, stop, data.filter, callback);
});
};
var start = parseInt(data.after, 10);
var stop = start + Math.max(0, Math.min(meta.config.topicsPerPage || 20, parseInt(data.count, 10) || meta.config.topicsPerPage || 20) - 1);
topics.getRecentTopics(data.cid, socket.uid, start, stop, data.filter, callback);
SocketTopics.loadMorePopularTopics = function (socket, data, callback) {
loadData(data, callback, function (start, stop) {
topics.getPopularTopics(data.term, socket.uid, start, stop, callback);
});
};
SocketTopics.loadMoreTopTopics = function (socket, data, callback) {
loadData(data, callback, function (start, stop) {
topics.getTopTopics(data.cid, socket.uid, start, stop, data.filter, callback);
});
};
function loadData(data, callback, loadFn) {
if (!data || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) {
return callback(new Error('[[error:invalid-data]]'));
}
var start = parseInt(data.after, 10);
var stop = start + Math.max(0, Math.min(meta.config.topicsPerPage || 20, parseInt(data.count, 10) || meta.config.topicsPerPage || 20) - 1);
topics.getTopTopics(data.cid, socket.uid, start, stop, data.filter, callback);
};
loadFn(start, stop);
}
SocketTopics.loadMoreFromSet = function (socket, data, callback) {
if (!data || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0 || !data.set) {

View File

@@ -2,39 +2,50 @@
'use strict';
var async = require('async');
var db = require('../database');
var privileges = require('../privileges');
module.exports = function (Topics) {
Topics.getPopular = function (term, uid, count, callback) {
count = parseInt(count, 10) || 20;
if (term === 'alltime') {
return getAllTimePopular(uid, count, callback);
}
async.waterfall([
function (next) {
Topics.getLatestTidsFromSet('topics:tid', 0, -1, term, next);
Topics.getPopularTopics(term, uid, 0, count - 1, next);
},
function (tids, next) {
getTopics(tids, uid, count, next);
function (data, next) {
next(null, data.topics);
},
], callback);
};
function getAllTimePopular(uid, count, callback) {
Topics.getPopularTopics = function (term, uid, start, stop, callback) {
var popularTopics = {
nextStart: 0,
topicCount: 0,
topics: [],
};
async.waterfall([
function (next) {
Topics.getTopicsFromSet('topics:posts', uid, 0, count - 1, next);
if (term === 'alltime') {
db.getSortedSetRevRange('topics:posts', 0, 199, next);
} else {
Topics.getLatestTidsFromSet('topics:tid', 0, -1, term, next);
}
},
function (data, next) {
data.topics.sort(sortPopular);
next(null, data.topics);
function (tids, next) {
popularTopics.topicCount = tids.length;
getTopics(tids, uid, start, stop, next);
},
function (topics, next) {
popularTopics.topics = topics;
popularTopics.nextStart = stop + 1;
next(null, popularTopics);
},
], callback);
}
};
function getTopics(tids, uid, count, callback) {
function getTopics(tids, uid, start, stop, callback) {
async.waterfall([
function (next) {
Topics.getTopicsFields(tids, ['tid', 'postcount', 'deleted'], next);
@@ -42,7 +53,7 @@ module.exports = function (Topics) {
function (topics, next) {
tids = topics.filter(function (topic) {
return topic && parseInt(topic.deleted, 10) !== 1;
}).sort(sortPopular).slice(0, count).map(function (topic) {
}).sort(sortPopular).slice(start, stop !== -1 ? stop - 1 : undefined).map(function (topic) {
return topic.tid;
});
privileges.topics.filterTids('read', tids, uid, next);

View File

@@ -106,14 +106,14 @@ Digest.send = function (data, callback) {
function (next) {
async.parallel({
notifications: async.apply(user.notifications.getDailyUnread, userObj.uid),
topics: async.apply(topics.getPopular, data.interval, userObj.uid, 10),
popular: async.apply(topics.getPopularTopics, data.interval, userObj.uid, 0, 9),
}, next);
},
function (data, next) {
var notifications = data.notifications.filter(Boolean);
// If there are no notifications and no new topics, don't bother sending a digest
if (!notifications.length && !data.topics.length) {
if (!notifications.length && !data.popular.topics.length) {
return next();
}
@@ -124,7 +124,7 @@ Digest.send = function (data, callback) {
});
// Fix relative paths in topic data
data.topics = data.topics.map(function (topicObj) {
data.popular.topics = data.popular.topics.map(function (topicObj) {
var user = topicObj.hasOwnProperty('teaser') && topicObj.teaser !== undefined ? topicObj.teaser.user : topicObj.user;
if (user && user.picture && utils.isRelativeUrl(user.picture)) {
user.picture = nconf.get('base_url') + user.picture;
@@ -138,7 +138,7 @@ Digest.send = function (data, callback) {
username: userObj.username,
userslug: userObj.userslug,
notifications: notifications,
recent: data.topics,
recent: data.popular.topics,
interval: data.interval,
showUnsubscribe: true,
}, function (err) {