mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +01:00
refactor: generate a topic id when asserting a new topic
This commit is contained in:
@@ -73,14 +73,17 @@ Notes.getParentChain = async (uid, input) => {
|
||||
return chain;
|
||||
};
|
||||
|
||||
Notes.assertParentChain = async (chain) => {
|
||||
Notes.assertParentChain = async (chain, tid) => {
|
||||
const data = [];
|
||||
chain.reduce((child, parent) => {
|
||||
data.push([`pid:${parent.pid}:replies`, child.timestamp, child.pid]);
|
||||
return parent;
|
||||
});
|
||||
|
||||
await db.sortedSetAddBulk(data);
|
||||
await Promise.all([
|
||||
db.sortedSetAddBulk(data),
|
||||
db.setObjectBulk(chain.map(post => [`post:${post.pid}`, { tid }])),
|
||||
]);
|
||||
};
|
||||
|
||||
Notes.assertTopic = async (uid, id) => {
|
||||
@@ -92,22 +95,22 @@ Notes.assertTopic = async (uid, id) => {
|
||||
*/
|
||||
|
||||
const chain = Array.from(await Notes.getParentChain(uid, id));
|
||||
const { pid: 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));
|
||||
if (members.every(Boolean)) {
|
||||
if (tid && members.every(Boolean)) {
|
||||
// All cached, return early.
|
||||
winston.info('[notes/assertTopic] No new notes to process.');
|
||||
return tid;
|
||||
}
|
||||
|
||||
let title = name || utils.stripHTMLTags(content);
|
||||
if (title.length > 256) {
|
||||
title = `${title.slice(0, 256)}...`;
|
||||
}
|
||||
|
||||
tid = tid || utils.generateUUID();
|
||||
const cid = await topics.getTopicField(tid, 'cid');
|
||||
|
||||
let title = name || utils.decodeHTMLEntities(utils.stripHTMLTags(content));
|
||||
if (title.length > 64) {
|
||||
title = `${title.slice(0, 64)}...`;
|
||||
}
|
||||
|
||||
const unprocessed = chain.filter((p, idx) => !members[idx]);
|
||||
winston.info(`[notes/assertTopic] ${unprocessed.length} new note(s) found.`);
|
||||
|
||||
@@ -121,16 +124,16 @@ Notes.assertTopic = async (uid, id) => {
|
||||
tid,
|
||||
uid: authorId,
|
||||
cid: cid || -1,
|
||||
mainPid: tid,
|
||||
mainPid,
|
||||
title,
|
||||
slug: `remote?resource=${encodeURIComponent(tid)}`,
|
||||
slug: `../world/${tid}`,
|
||||
timestamp,
|
||||
}),
|
||||
db.sortedSetAdd(`tidRemote:${tid}:posts`, timestamps, ids),
|
||||
Notes.assert(uid, unprocessed),
|
||||
]);
|
||||
await Promise.all([ // must be done after .assert()
|
||||
Notes.assertParentChain(chain),
|
||||
Notes.assertParentChain(chain, tid),
|
||||
Notes.updateTopicCounts(tid),
|
||||
topics.updateLastPostTimeFromLastPid(tid),
|
||||
topics.updateTeaser(tid),
|
||||
|
||||
@@ -44,14 +44,13 @@ controller.get = async function (req, res, next) {
|
||||
* Ideally we would use the existing topicsController.get...
|
||||
* this controller may be a stopgap towards that end goal.
|
||||
*/
|
||||
const pid = await notes.resolveId(req.uid, req.query.resource);
|
||||
if (pid !== req.query.resource) {
|
||||
return helpers.redirect(res, `/topic/remote?resource=${pid}`, true);
|
||||
}
|
||||
// const pid = await notes.resolveId(req.uid, req.query.resource);
|
||||
// if (pid !== req.query.resource) {
|
||||
// return helpers.redirect(res, `/topic/remote?resource=${pid}`, true);
|
||||
// }
|
||||
|
||||
const tid = await notes.assertTopic(req.uid, req.query.resource);
|
||||
|
||||
let postIndex = Math.max(1, await db.sortedSetRank(`tidRemote:${tid}:posts`, req.query.resource));
|
||||
const tid = req.params.topic_id;
|
||||
let postIndex = parseInt(req.params.post_index, 10) || 1;
|
||||
const [
|
||||
userPrivileges,
|
||||
settings,
|
||||
|
||||
@@ -61,6 +61,7 @@ function modifyPost(post, fields) {
|
||||
if (activitypub.helpers.isUri(post.pid)) {
|
||||
intFields.splice(intFields.indexOf('pid'), 1);
|
||||
intFields.splice(intFields.indexOf('uid'), 1);
|
||||
intFields.splice(intFields.indexOf('tid'), 1);
|
||||
}
|
||||
db.parseIntFields(post, intFields, fields);
|
||||
if (post.hasOwnProperty('upvotes') && post.hasOwnProperty('downvotes')) {
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
const helpers = require('./helpers');
|
||||
|
||||
module.exports = function (app, middleware, controllers) {
|
||||
helpers.setupPageRoute(app, '/world/:view?', [middleware.activitypub.enabled], controllers.activitypub.topics.list);
|
||||
helpers.setupPageRoute(app, '/world', [middleware.activitypub.enabled], controllers.activitypub.topics.list);
|
||||
helpers.setupPageRoute(app, '/world/:topic_id/:post_index?', [middleware.activitypub.enabled], controllers.activitypub.topics.get);
|
||||
|
||||
/**
|
||||
* These controllers only respond if the sender is making an json+activitypub style call (i.e. S2S-only)
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
const validator = require('validator');
|
||||
|
||||
const topics = require('../../topics');
|
||||
const privileges = require('../../privileges');
|
||||
const meta = require('../../meta');
|
||||
const utils = require('../../utils');
|
||||
const social = require('../../social');
|
||||
const activitypub = require('../../activitypub');
|
||||
|
||||
module.exports = function (SocketTopics) {
|
||||
SocketTopics.loadMore = async function (socket, data) {
|
||||
@@ -22,7 +23,7 @@ module.exports = function (SocketTopics) {
|
||||
throw new Error('[[error:no-privileges]]');
|
||||
}
|
||||
|
||||
const setPrefix = activitypub.helpers.isUri(data.tid) ? 'tidRemote' : 'tid';
|
||||
const setPrefix = validator.isUUID(String(data.tid)) ? 'tidRemote' : 'tid';
|
||||
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';
|
||||
let start = Math.max(0, parseInt(data.after, 10));
|
||||
|
||||
@@ -7,7 +7,6 @@ const categories = require('../categories');
|
||||
const utils = require('../utils');
|
||||
const translator = require('../translator');
|
||||
const plugins = require('../plugins');
|
||||
const activitypub = require('../activitypub');
|
||||
|
||||
const intFields = [
|
||||
'tid', 'cid', 'uid', 'mainPid', 'postcount',
|
||||
@@ -27,7 +26,7 @@ module.exports = function (Topics) {
|
||||
fields.push('timestamp');
|
||||
}
|
||||
|
||||
const keys = tids.map(tid => `${activitypub.helpers.isUri(tid) ? 'topicRemote' : 'topic'}:${tid}`);
|
||||
const keys = tids.map(tid => `${validator.isUUID(String(tid)) ? 'topicRemote' : 'topic'}:${tid}`);
|
||||
const topics = await db.getObjects(keys, fields);
|
||||
const result = await plugins.hooks.fire('filter:topic.getFields', {
|
||||
tids: tids,
|
||||
@@ -64,12 +63,12 @@ module.exports = function (Topics) {
|
||||
};
|
||||
|
||||
Topics.setTopicField = async function (tid, field, value) {
|
||||
const setPrefix = activitypub.helpers.isUri(tid) ? 'topicRemote' : 'topic';
|
||||
const setPrefix = validator.isUUID(String(tid)) ? 'topicRemote' : 'topic';
|
||||
await db.setObjectField(`${setPrefix}:${tid}`, field, value);
|
||||
};
|
||||
|
||||
Topics.setTopicFields = async function (tid, data) {
|
||||
const setPrefix = activitypub.helpers.isUri(tid) ? 'topicRemote' : 'topic';
|
||||
const setPrefix = validator.isUUID(String(tid)) ? 'topicRemote' : 'topic';
|
||||
await db.setObject(`${setPrefix}:${tid}`, data);
|
||||
};
|
||||
|
||||
@@ -98,7 +97,7 @@ function modifyTopic(topic, fields) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (activitypub.helpers.isUri(topic.tid)) {
|
||||
if (validator.isUUID(String(topic.tid))) {
|
||||
intFields.splice(intFields.indexOf('uid'), 1);
|
||||
intFields.splice(intFields.indexOf('tid'), 1);
|
||||
}
|
||||
|
||||
@@ -72,10 +72,10 @@ Topics.getTopicsByTids = async function (tids, options) {
|
||||
const topics = await Topics.getTopicsData(tids);
|
||||
const uids = _.uniq(topics
|
||||
.map(t => t && t.uid && t.uid.toString())
|
||||
.filter(v => utils.isNumber(v) || activitypub.helpers.isUri(v)));
|
||||
.filter(v => utils.isNumber(v) || validator.isUUID(String(v))));
|
||||
const cids = _.uniq(topics
|
||||
.map(t => t && t.cid && t.cid.toString())
|
||||
.filter(v => utils.isNumber(v) || activitypub.helpers.isUri(v)));
|
||||
.filter(v => utils.isNumber(v) || validator.isUUID(String(v))));
|
||||
const guestTopics = topics.filter(t => t && t.uid === 0);
|
||||
|
||||
async function loadGuestHandles() {
|
||||
|
||||
@@ -231,7 +231,7 @@ module.exports = function (Topics) {
|
||||
Topics.getLatestUndeletedReply = async function (tid) {
|
||||
let isDeleted = false;
|
||||
let index = 0;
|
||||
const setPrefix = activitypub.helpers.isUri(tid) ? 'tidRemote' : 'tid';
|
||||
const setPrefix = validator.isUUID(String(tid)) ? 'tidRemote' : 'tid';
|
||||
do {
|
||||
/* eslint-disable no-await-in-loop */
|
||||
const pids = await db.getSortedSetRevRange(`${setPrefix}:${tid}:posts`, index, index);
|
||||
@@ -312,7 +312,7 @@ module.exports = function (Topics) {
|
||||
};
|
||||
|
||||
async function incrementFieldAndUpdateSortedSet(tid, field, by, set) {
|
||||
const value = await db.incrObjectFieldBy(`${activitypub.helpers.isUri(tid) ? 'topicRemote' : 'topic'}:${tid}`, field, by);
|
||||
const value = await db.incrObjectFieldBy(`${validator.isUUID(String(tid)) ? 'topicRemote' : 'topic'}:${tid}`, field, by);
|
||||
await db[Array.isArray(set) ? 'sortedSetsAdd' : 'sortedSetAdd'](set, value, tid);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const validator = require('validator');
|
||||
|
||||
const db = require('../database');
|
||||
const plugins = require('../plugins');
|
||||
const posts = require('../posts');
|
||||
const activitypub = require('../activitypub');
|
||||
|
||||
module.exports = function (Topics) {
|
||||
const terms = {
|
||||
@@ -74,7 +75,7 @@ module.exports = function (Topics) {
|
||||
data = await plugins.hooks.fire('filter:topics.updateRecent', { tid: tid, timestamp: timestamp });
|
||||
}
|
||||
if (data && data.tid && data.timestamp) {
|
||||
const setPrefix = activitypub.helpers.isUri(data.tid) ? 'topicsRemote' : 'topics';
|
||||
const setPrefix = validator.isUUID(String(data.tid)) ? 'topicsRemote' : 'topics';
|
||||
await db.sortedSetAdd(`${setPrefix}:recent`, data.timestamp, data.tid);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user