From 697dd37670c20670eac40cabab061de81ca1471d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 18 Nov 2021 13:11:05 -0500 Subject: [PATCH] refactor: change category feed so it is not updated on every reply allow cid query param for recent/top/popular feeds --- src/routes/feeds.js | 117 +++++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 60 deletions(-) diff --git a/src/routes/feeds.js b/src/routes/feeds.js index 7ace7cf216..c3bda30473 100644 --- a/src/routes/feeds.js +++ b/src/routes/feeds.js @@ -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) {