mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 19:15:58 +01:00 
			
		
		
		
	refactor: use existing sets for topics (instead of topicRemote, etc.)
This commit is contained in:
		| @@ -7,6 +7,7 @@ const topics = require('../topics'); | |||||||
| const posts = require('../posts'); | const posts = require('../posts'); | ||||||
| const utils = require('../utils'); | const utils = require('../utils'); | ||||||
| const pubsub = require('../pubsub'); | const pubsub = require('../pubsub'); | ||||||
|  | const slugify = require('../slugify'); | ||||||
|  |  | ||||||
| const activitypub = module.parent.exports; | const activitypub = module.parent.exports; | ||||||
| const Notes = module.exports; | const Notes = module.exports; | ||||||
| @@ -98,7 +99,7 @@ Notes.assertTopic = async (uid, id) => { | |||||||
|  |  | ||||||
| 	const chain = Array.from(await Notes.getParentChain(uid, id)); | 	const chain = Array.from(await Notes.getParentChain(uid, id)); | ||||||
| 	let { pid: mainPid, tid, uid: authorId, timestamp, name, content } = chain[chain.length - 1]; | 	let { pid: mainPid, tid, uid: authorId, timestamp, name, content } = chain[chain.length - 1]; | ||||||
| 	const members = await db.isSortedSetMembers(`tidRemote:${tid}:posts`, chain.map(p => p.pid)); | 	const members = await db.isSortedSetMembers(`tid:${tid}:posts`, chain.map(p => p.pid)); | ||||||
| 	if (tid && members.every(Boolean)) { | 	if (tid && members.every(Boolean)) { | ||||||
| 		// All cached, return early. | 		// All cached, return early. | ||||||
| 		winston.info('[notes/assertTopic] No new notes to process.'); | 		winston.info('[notes/assertTopic] No new notes to process.'); | ||||||
| @@ -121,17 +122,21 @@ Notes.assertTopic = async (uid, id) => { | |||||||
| 		unprocessed.map(n => n.timestamp), | 		unprocessed.map(n => n.timestamp), | ||||||
| 	]; | 	]; | ||||||
|  |  | ||||||
|  | 	// mainPid doesn't belong in posts zset | ||||||
|  | 	ids.pop(); | ||||||
|  | 	timestamps.pop(); | ||||||
|  |  | ||||||
| 	await Promise.all([ | 	await Promise.all([ | ||||||
| 		db.setObject(`topicRemote:${tid}`, { | 		db.setObject(`topic:${tid}`, { | ||||||
| 			tid, | 			tid, | ||||||
| 			uid: authorId, | 			uid: authorId, | ||||||
| 			cid: cid || -1, | 			cid: cid || -1, | ||||||
| 			mainPid, | 			mainPid, | ||||||
| 			title, | 			title, | ||||||
| 			slug: `../world/${tid}`, | 			slug: `${tid}/${slugify(title)}`, | ||||||
| 			timestamp, | 			timestamp, | ||||||
| 		}), | 		}), | ||||||
| 		db.sortedSetAdd(`tidRemote:${tid}:posts`, timestamps, ids), | 		db.sortedSetAdd(`tid:${tid}:posts`, timestamps, ids), | ||||||
| 		Notes.assert(uid, unprocessed), | 		Notes.assert(uid, unprocessed), | ||||||
| 	]); | 	]); | ||||||
| 	await Promise.all([ // must be done after .assert() | 	await Promise.all([ // must be done after .assert() | ||||||
| @@ -145,20 +150,20 @@ Notes.assertTopic = async (uid, id) => { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| Notes.updateTopicCounts = async function (tid) { | Notes.updateTopicCounts = async function (tid) { | ||||||
| 	const pids = await db.getSortedSetMembers(`tidRemote:${tid}:posts`); | 	const pids = await db.getSortedSetMembers(`tid:${tid}:posts`); | ||||||
| 	let uids = await db.getObjectsFields(pids.map(p => `post:${p}`), ['uid']); | 	let uids = await db.getObjectsFields(pids.map(p => `post:${p}`), ['uid']); | ||||||
| 	uids = uids.reduce((set, { uid }) => { | 	uids = uids.reduce((set, { uid }) => { | ||||||
| 		set.add(uid); | 		set.add(uid); | ||||||
| 		return set; | 		return set; | ||||||
| 	}, new Set()); | 	}, new Set()); | ||||||
|  |  | ||||||
| 	db.setObject(`topicRemote:${tid}`, { | 	db.setObject(`topic:${tid}`, { | ||||||
| 		postercount: uids.size, | 		postercount: uids.size, | ||||||
| 		postcount: pids.length, | 		postcount: pids.length, | ||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| Notes.getTopicPosts = async (tid, uid, start, stop) => { | Notes.getTopicPosts = async (tid, uid, start, stop) => { | ||||||
| 	const pids = await db.getSortedSetRange(`tidRemote:${tid}:posts`, start, stop); | 	const pids = await db.getSortedSetRange(`tid:${tid}:posts`, start, stop); | ||||||
| 	return await posts.getPostsByPids(pids, uid); | 	return await posts.getPostsByPids(pids, uid); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -13,6 +13,19 @@ const intFields = [ | |||||||
| 	'minTags', 'maxTags', 'postQueue', 'subCategoriesPerPage', | 	'minTags', 'maxTags', 'postQueue', 'subCategoriesPerPage', | ||||||
| ]; | ]; | ||||||
|  |  | ||||||
|  | const worldCategory = { | ||||||
|  | 	cid: -1, | ||||||
|  | 	name: 'World', | ||||||
|  | 	description: '[[error:invalid-data]]', | ||||||
|  | 	descriptionParsed: 'what', | ||||||
|  | 	icon: 'fa-globe', | ||||||
|  | 	bgColor: '#0000ff', | ||||||
|  | 	color: '#ffffff', | ||||||
|  | 	slug: '../world', | ||||||
|  | 	parentCid: 0, | ||||||
|  | 	disabled: 0, // todo | ||||||
|  | }; | ||||||
|  |  | ||||||
| module.exports = function (Categories) { | module.exports = function (Categories) { | ||||||
| 	Categories.getCategoriesFields = async function (cids, fields) { | 	Categories.getCategoriesFields = async function (cids, fields) { | ||||||
| 		if (!Array.isArray(cids) || !cids.length) { | 		if (!Array.isArray(cids) || !cids.length) { | ||||||
| @@ -21,6 +34,12 @@ module.exports = function (Categories) { | |||||||
|  |  | ||||||
| 		const keys = cids.map(cid => `category:${cid}`); | 		const keys = cids.map(cid => `category:${cid}`); | ||||||
| 		const categories = await db.getObjects(keys, fields); | 		const categories = await db.getObjects(keys, fields); | ||||||
|  |  | ||||||
|  | 		// Handle cid -1 | ||||||
|  | 		if (cids.includes(-1)) { | ||||||
|  | 			categories.splice(cids.indexOf(-1), 1, worldCategory); | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		const result = await plugins.hooks.fire('filter:category.getFields', { | 		const result = await plugins.hooks.fire('filter:category.getFields', { | ||||||
| 			cids: cids, | 			cids: cids, | ||||||
| 			categories: categories, | 			categories: categories, | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ | |||||||
|  |  | ||||||
| const nconf = require('nconf'); | const nconf = require('nconf'); | ||||||
| const qs = require('querystring'); | const qs = require('querystring'); | ||||||
|  | const validator = require('validator'); | ||||||
|  |  | ||||||
| const user = require('../user'); | const user = require('../user'); | ||||||
| const meta = require('../meta'); | const meta = require('../meta'); | ||||||
| @@ -9,14 +10,11 @@ const topics = require('../topics'); | |||||||
| const categories = require('../categories'); | const categories = require('../categories'); | ||||||
| const posts = require('../posts'); | const posts = require('../posts'); | ||||||
| const privileges = require('../privileges'); | const privileges = require('../privileges'); | ||||||
| const activitypub = require('../activitypub'); |  | ||||||
| const helpers = require('./helpers'); | const helpers = require('./helpers'); | ||||||
| const pagination = require('../pagination'); | const pagination = require('../pagination'); | ||||||
| const utils = require('../utils'); | const utils = require('../utils'); | ||||||
| const analytics = require('../analytics'); | const analytics = require('../analytics'); | ||||||
|  |  | ||||||
| const activitypubController = require('./activitypub'); |  | ||||||
|  |  | ||||||
| const topicsController = module.exports; | const topicsController = module.exports; | ||||||
|  |  | ||||||
| const url = nconf.get('url'); | const url = nconf.get('url'); | ||||||
| @@ -24,14 +22,10 @@ const relative_path = nconf.get('relative_path'); | |||||||
| const upload_url = nconf.get('upload_url'); | const upload_url = nconf.get('upload_url'); | ||||||
|  |  | ||||||
| topicsController.get = async function getTopic(req, res, next) { | topicsController.get = async function getTopic(req, res, next) { | ||||||
| 	if (req.params.topic_id === 'remote' && activitypub.helpers.isUri(req.query.resource)) { |  | ||||||
| 		return activitypubController.topics.get(req, res, next); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	const tid = req.params.topic_id; | 	const tid = req.params.topic_id; | ||||||
| 	if ( | 	if ( | ||||||
| 		(req.params.post_index && !utils.isNumber(req.params.post_index) && req.params.post_index !== 'unread') || | 		(req.params.post_index && !utils.isNumber(req.params.post_index) && req.params.post_index !== 'unread') || | ||||||
| 		!utils.isNumber(tid) | 		(!utils.isNumber(tid) && !validator.isUUID(tid)) | ||||||
| 	) { | 	) { | ||||||
| 		return next(); | 		return next(); | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -23,8 +23,7 @@ module.exports = function (SocketTopics) { | |||||||
| 			throw new Error('[[error:no-privileges]]'); | 			throw new Error('[[error:no-privileges]]'); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		const setPrefix = validator.isUUID(String(data.tid)) ? 'tidRemote' : 'tid'; | 		const set = data.topicPostSort === 'most_votes' ? `tid:${data.tid}:posts:votes` : `tid:${data.tid}:posts`; | ||||||
| 		const set = data.topicPostSort === 'most_votes' ? `${setPrefix}:${data.tid}:posts:votes` : `${setPrefix}:${data.tid}:posts`; |  | ||||||
| 		const reverse = data.topicPostSort === 'newest_to_oldest' || data.topicPostSort === 'most_votes'; | 		const reverse = data.topicPostSort === 'newest_to_oldest' || data.topicPostSort === 'most_votes'; | ||||||
| 		let start = Math.max(0, parseInt(data.after, 10)); | 		let start = Math.max(0, parseInt(data.after, 10)); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ module.exports = function (Topics) { | |||||||
| 			fields.push('timestamp'); | 			fields.push('timestamp'); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		const keys = tids.map(tid => `${validator.isUUID(String(tid)) ? 'topicRemote' : 'topic'}:${tid}`); | 		const keys = tids.map(tid => `topic:${tid}`); | ||||||
| 		const topics = await db.getObjects(keys, fields); | 		const topics = await db.getObjects(keys, fields); | ||||||
| 		const result = await plugins.hooks.fire('filter:topic.getFields', { | 		const result = await plugins.hooks.fire('filter:topic.getFields', { | ||||||
| 			tids: tids, | 			tids: tids, | ||||||
| @@ -63,13 +63,11 @@ module.exports = function (Topics) { | |||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	Topics.setTopicField = async function (tid, field, value) { | 	Topics.setTopicField = async function (tid, field, value) { | ||||||
| 		const setPrefix = validator.isUUID(String(tid)) ? 'topicRemote' : 'topic'; | 		await db.setObjectField(`topic:${tid}`, field, value); | ||||||
| 		await db.setObjectField(`${setPrefix}:${tid}`, field, value); |  | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	Topics.setTopicFields = async function (tid, data) { | 	Topics.setTopicFields = async function (tid, data) { | ||||||
| 		const setPrefix = validator.isUUID(String(tid)) ? 'topicRemote' : 'topic'; | 		await db.setObject(`topic:${tid}`, data); | ||||||
| 		await db.setObject(`${setPrefix}:${tid}`, data); |  | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	Topics.deleteTopicField = async function (tid, field) { | 	Topics.deleteTopicField = async function (tid, field) { | ||||||
|   | |||||||
| @@ -231,10 +231,9 @@ module.exports = function (Topics) { | |||||||
| 	Topics.getLatestUndeletedReply = async function (tid) { | 	Topics.getLatestUndeletedReply = async function (tid) { | ||||||
| 		let isDeleted = false; | 		let isDeleted = false; | ||||||
| 		let index = 0; | 		let index = 0; | ||||||
| 		const setPrefix = validator.isUUID(String(tid)) ? 'tidRemote' : 'tid'; |  | ||||||
| 		do { | 		do { | ||||||
| 			/* eslint-disable no-await-in-loop */ | 			/* eslint-disable no-await-in-loop */ | ||||||
| 			const pids = await db.getSortedSetRevRange(`${setPrefix}:${tid}:posts`, index, index); | 			const pids = await db.getSortedSetRevRange(`tid:${tid}:posts`, index, index); | ||||||
| 			if (!pids.length) { | 			if (!pids.length) { | ||||||
| 				return null; | 				return null; | ||||||
| 			} | 			} | ||||||
| @@ -312,7 +311,7 @@ module.exports = function (Topics) { | |||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	async function incrementFieldAndUpdateSortedSet(tid, field, by, set) { | 	async function incrementFieldAndUpdateSortedSet(tid, field, by, set) { | ||||||
| 		const value = await db.incrObjectFieldBy(`${validator.isUUID(String(tid)) ? 'topicRemote' : 'topic'}:${tid}`, field, by); | 		const value = await db.incrObjectFieldBy(`topic:${tid}`, field, by); | ||||||
| 		await db[Array.isArray(set) ? 'sortedSetsAdd' : 'sortedSetAdd'](set, value, tid); | 		await db[Array.isArray(set) ? 'sortedSetsAdd' : 'sortedSetAdd'](set, value, tid); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -70,13 +70,19 @@ module.exports = function (Topics) { | |||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	Topics.updateRecent = async function (tid, timestamp) { | 	Topics.updateRecent = async function (tid, timestamp) { | ||||||
| 		let data = { tid: tid, timestamp: timestamp }; | 		let data = { tid, timestamp }; | ||||||
|  |  | ||||||
|  | 		// Topics in /world are excluded from /recent | ||||||
|  | 		const cid = await Topics.getTopicField(tid, 'cid'); | ||||||
|  | 		if (cid === -1) { | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		if (plugins.hooks.hasListeners('filter:topics.updateRecent')) { | 		if (plugins.hooks.hasListeners('filter:topics.updateRecent')) { | ||||||
| 			data = await plugins.hooks.fire('filter:topics.updateRecent', { tid: tid, timestamp: timestamp }); | 			data = await plugins.hooks.fire('filter:topics.updateRecent', data); | ||||||
| 		} | 		} | ||||||
| 		if (data && data.tid && data.timestamp) { | 		if (data && data.tid && data.timestamp) { | ||||||
| 			const setPrefix = validator.isUUID(String(data.tid)) ? 'topicsRemote' : 'topics'; | 			await db.sortedSetAdd(`topics:recent`, data.timestamp, data.tid); | ||||||
| 			await db.sortedSetAdd(`${setPrefix}:recent`, data.timestamp, data.tid); |  | ||||||
| 		} | 		} | ||||||
| 	}; | 	}; | ||||||
| }; | }; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user