|
|
|
@ -120,31 +120,32 @@ async function generateForCategory(req, res, next) {
|
|
|
|
|
if (meta.config['feeds:disableRSS'] || !parseInt(cid, 10)) {
|
|
|
|
|
return next();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const [userPrivileges, category] = await Promise.all([
|
|
|
|
|
const uid = req.uid || req.query.uid || 0;
|
|
|
|
|
const [userPrivileges, category, tids] = await Promise.all([
|
|
|
|
|
privileges.categories.get(cid, req.uid),
|
|
|
|
|
categories.getCategoryById({
|
|
|
|
|
cid: cid,
|
|
|
|
|
set: `cid:${cid}:tids`,
|
|
|
|
|
reverse: true,
|
|
|
|
|
categories.getCategoryData(cid),
|
|
|
|
|
db.getSortedSetRevIntersect({
|
|
|
|
|
sets: ['topics:tid', `cid:${cid}:tids:lastposttime`],
|
|
|
|
|
start: 0,
|
|
|
|
|
stop: 25,
|
|
|
|
|
uid: req.uid || req.query.uid || 0,
|
|
|
|
|
weights: [1, 0],
|
|
|
|
|
}),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
if (!category) {
|
|
|
|
|
if (!category || !category.name) {
|
|
|
|
|
return next();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (await validateTokenIfRequiresLogin(!userPrivileges.read, cid, req, res)) {
|
|
|
|
|
let topicsData = await topics.getTopicsByTids(tids, uid);
|
|
|
|
|
topicsData = await user.blocks.filter(uid, topicsData);
|
|
|
|
|
const feed = await generateTopicsFeed({
|
|
|
|
|
uid: req.uid || req.query.uid || 0,
|
|
|
|
|
uid: uid,
|
|
|
|
|
title: category.name,
|
|
|
|
|
description: category.description,
|
|
|
|
|
feed_url: `/category/${cid}.rss`,
|
|
|
|
|
site_url: `/category/${category.cid}`,
|
|
|
|
|
}, category.topics);
|
|
|
|
|
}, topicsData, 'timestamp');
|
|
|
|
|
|
|
|
|
|
sendFeed(feed, res);
|
|
|
|
|
}
|
|
|
|
@ -169,61 +170,47 @@ async function generateForTopics(req, res, next) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function generateForRecent(req, res, next) {
|
|
|
|
|
if (meta.config['feeds:disableRSS']) {
|
|
|
|
|
return next();
|
|
|
|
|
}
|
|
|
|
|
let token = null;
|
|
|
|
|
if (req.query.token && req.query.uid) {
|
|
|
|
|
token = await db.getObjectField(`user:${req.query.uid}`, 'rss_token');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await sendTopicsFeed({
|
|
|
|
|
uid: token && token === req.query.token ? req.query.uid : req.uid,
|
|
|
|
|
await generateSorted({
|
|
|
|
|
title: 'Recently Active Topics',
|
|
|
|
|
description: 'A list of topics that have been active within the past 24 hours',
|
|
|
|
|
feed_url: '/recent.rss',
|
|
|
|
|
site_url: '/recent',
|
|
|
|
|
}, 'topics:recent', res);
|
|
|
|
|
sort: 'recent',
|
|
|
|
|
timestampField: 'lastposttime',
|
|
|
|
|
term: 'alltime',
|
|
|
|
|
}, req, res, next);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function generateForTop(req, res, next) {
|
|
|
|
|
if (meta.config['feeds:disableRSS']) {
|
|
|
|
|
return next();
|
|
|
|
|
}
|
|
|
|
|
const term = terms[req.params.term] || 'day';
|
|
|
|
|
|
|
|
|
|
let token = null;
|
|
|
|
|
if (req.query.token && req.query.uid) {
|
|
|
|
|
token = await db.getObjectField(`user:${req.query.uid}`, 'rss_token');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const uid = token && token === req.query.token ? req.query.uid : req.uid;
|
|
|
|
|
|
|
|
|
|
const result = await topics.getSortedTopics({
|
|
|
|
|
uid: uid,
|
|
|
|
|
start: 0,
|
|
|
|
|
stop: 19,
|
|
|
|
|
term: term,
|
|
|
|
|
sort: 'votes',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const feed = await generateTopicsFeed({
|
|
|
|
|
uid: uid,
|
|
|
|
|
await generateSorted({
|
|
|
|
|
title: 'Top Voted Topics',
|
|
|
|
|
description: 'A list of topics that have received the most votes',
|
|
|
|
|
feed_url: `/top/${req.params.term || 'daily'}.rss`,
|
|
|
|
|
site_url: `/top/${req.params.term || 'daily'}`,
|
|
|
|
|
}, result.topics);
|
|
|
|
|
|
|
|
|
|
sendFeed(feed, res);
|
|
|
|
|
sort: 'votes',
|
|
|
|
|
timestampField: 'timestamp',
|
|
|
|
|
term: 'day',
|
|
|
|
|
}, req, res, next);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function generateForPopular(req, res, next) {
|
|
|
|
|
await generateSorted({
|
|
|
|
|
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'}`,
|
|
|
|
|
sort: 'posts',
|
|
|
|
|
timestampField: 'timestamp',
|
|
|
|
|
term: 'day',
|
|
|
|
|
}, req, res, next);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function generateSorted(options, req, res, next) {
|
|
|
|
|
if (meta.config['feeds:disableRSS']) {
|
|
|
|
|
return next();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const term = terms[req.params.term] || 'day';
|
|
|
|
|
const term = terms[req.params.term] || options.term;
|
|
|
|
|
|
|
|
|
|
let token = null;
|
|
|
|
|
if (req.query.token && req.query.uid) {
|
|
|
|
@ -232,33 +219,43 @@ async function generateForPopular(req, res, next) {
|
|
|
|
|
|
|
|
|
|
const uid = token && token === req.query.token ? req.query.uid : req.uid;
|
|
|
|
|
|
|
|
|
|
const result = await topics.getSortedTopics({
|
|
|
|
|
const params = {
|
|
|
|
|
uid: uid,
|
|
|
|
|
start: 0,
|
|
|
|
|
stop: 19,
|
|
|
|
|
term: term,
|
|
|
|
|
sort: 'posts',
|
|
|
|
|
});
|
|
|
|
|
sort: options.sort,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const { cid } = req.query;
|
|
|
|
|
if (cid) {
|
|
|
|
|
if (!await privileges.categories.can('topics:read', cid, uid)) {
|
|
|
|
|
return helpers.notAllowed(req, res);
|
|
|
|
|
}
|
|
|
|
|
params.cids = [cid];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const result = await topics.getSortedTopics(params);
|
|
|
|
|
const feed = await generateTopicsFeed({
|
|
|
|
|
uid: 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'}`,
|
|
|
|
|
}, result.topics);
|
|
|
|
|
title: options.title,
|
|
|
|
|
description: options.description,
|
|
|
|
|
feed_url: options.feed_url,
|
|
|
|
|
site_url: options.site_url,
|
|
|
|
|
}, result.topics, options.timestampField);
|
|
|
|
|
|
|
|
|
|
sendFeed(feed, res);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function sendTopicsFeed(options, set, res) {
|
|
|
|
|
async function sendTopicsFeed(options, set, res, timestampField) {
|
|
|
|
|
const start = options.hasOwnProperty('start') ? options.start : 0;
|
|
|
|
|
const stop = options.hasOwnProperty('stop') ? options.stop : 19;
|
|
|
|
|
const topicData = await topics.getTopicsFromSet(set, options.uid, start, stop);
|
|
|
|
|
const feed = await generateTopicsFeed(options, topicData.topics);
|
|
|
|
|
const feed = await generateTopicsFeed(options, topicData.topics, timestampField);
|
|
|
|
|
sendFeed(feed, res);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function generateTopicsFeed(feedOptions, feedTopics) {
|
|
|
|
|
async function generateTopicsFeed(feedOptions, feedTopics, timestampField) {
|
|
|
|
|
feedOptions.ttl = 60;
|
|
|
|
|
feedOptions.feed_url = nconf.get('url') + feedOptions.feed_url;
|
|
|
|
|
feedOptions.site_url = nconf.get('url') + feedOptions.site_url;
|
|
|
|
@ -268,14 +265,14 @@ async function generateTopicsFeed(feedOptions, feedTopics) {
|
|
|
|
|
const feed = new rss(feedOptions);
|
|
|
|
|
|
|
|
|
|
if (feedTopics.length > 0) {
|
|
|
|
|
feed.pubDate = new Date(feedTopics[0].lastposttime).toUTCString();
|
|
|
|
|
feed.pubDate = new Date(feedTopics[0][timestampField]).toUTCString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function addFeedItem(topicData) {
|
|
|
|
|
const feedItem = {
|
|
|
|
|
title: utils.stripHTMLTags(topicData.title, utils.tags),
|
|
|
|
|
url: `${nconf.get('url')}/topic/${topicData.slug}`,
|
|
|
|
|
date: new Date(topicData.lastposttime).toUTCString(),
|
|
|
|
|
date: new Date(topicData[timestampField]).toUTCString(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (topicData.deleted) {
|
|
|
|
|