mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-02 20:16:04 +01:00
refactor: post announce logic to save to separate zset instead of to topic events, closes #12536
This commit is contained in:
@@ -173,23 +173,7 @@ inbox.announce = async (req) => {
|
|||||||
winston.info(`[activitypub/inbox/announce] Parsing id ${pid}`);
|
winston.info(`[activitypub/inbox/announce] Parsing id ${pid}`);
|
||||||
|
|
||||||
if (!cid) { // Topic events from actors followed by users only
|
if (!cid) { // Topic events from actors followed by users only
|
||||||
// No double-announce allowed
|
await activitypub.notes.announce.add(pid, actor, timestamp);
|
||||||
const existing = await topics.events.find(tid, {
|
|
||||||
type: 'announce',
|
|
||||||
uid: actor,
|
|
||||||
pid,
|
|
||||||
});
|
|
||||||
if (existing.length) {
|
|
||||||
await topics.events.purge(tid, existing);
|
|
||||||
}
|
|
||||||
|
|
||||||
await topics.events.log(tid, {
|
|
||||||
type: 'announce',
|
|
||||||
uid: actor,
|
|
||||||
href: `/post/${encodeURIComponent(pid)}`,
|
|
||||||
pid,
|
|
||||||
timestamp,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -389,17 +373,7 @@ inbox.undo = async (req) => {
|
|||||||
winston.verbose(`[activitypub/inbox/undo] Attempted to undo announce of ${id} but couldn't find it, so doing nothing.`);
|
winston.verbose(`[activitypub/inbox/undo] Attempted to undo announce of ${id} but couldn't find it, so doing nothing.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const tid = await posts.getPostField(id, 'tid');
|
await activitypub.notes.announce.remove(id, actor);
|
||||||
const existing = await topics.events.find(tid, {
|
|
||||||
type: 'announce',
|
|
||||||
uid: actor,
|
|
||||||
pid: id,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (existing.length) {
|
|
||||||
await topics.events.purge(tid, existing);
|
|
||||||
}
|
|
||||||
|
|
||||||
notifications.rescind(`announce:post:${id}:uid:${actor}`);
|
notifications.rescind(`announce:post:${id}:uid:${actor}`);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -304,3 +304,49 @@ Notes.getCategoryFollowers = async (cid) => {
|
|||||||
|
|
||||||
return uids;
|
return uids;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Notes.announce = {};
|
||||||
|
|
||||||
|
Notes.announce.list = async ({ pid, tid }) => {
|
||||||
|
let pids = [];
|
||||||
|
if (pid) {
|
||||||
|
pids = [pid];
|
||||||
|
} else if (tid) {
|
||||||
|
let mainPid;
|
||||||
|
([pids, mainPid] = await Promise.all([
|
||||||
|
db.getSortedSetMembers(`tid:${tid}:posts`),
|
||||||
|
topics.getTopicField(tid, 'mainPid'),
|
||||||
|
]));
|
||||||
|
pids.unshift(mainPid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pids.length) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const keys = pids.map(pid => `pid:${pid}:announces`);
|
||||||
|
let announces = await db.getSortedSetsMembersWithScores(keys);
|
||||||
|
announces = announces.reduce((memo, cur, idx) => {
|
||||||
|
if (cur.length) {
|
||||||
|
const pid = pids[idx];
|
||||||
|
cur.forEach(({ value: actor, score: timestamp }) => {
|
||||||
|
memo.push({ pid, actor, timestamp });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return memo;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return announces;
|
||||||
|
};
|
||||||
|
|
||||||
|
Notes.announce.add = async (pid, actor, timestamp = Date.now()) => {
|
||||||
|
await db.sortedSetAdd(`pid:${pid}:announces`, timestamp, actor);
|
||||||
|
};
|
||||||
|
|
||||||
|
Notes.announce.remove = async (pid, actor) => {
|
||||||
|
await db.sortedSetRemove(`pid:${pid}:announces`, actor);
|
||||||
|
};
|
||||||
|
|
||||||
|
Notes.announce.removeAll = async (pid) => {
|
||||||
|
await db.delete(`pid:${pid}:announces`);
|
||||||
|
};
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ const categories = require('../categories');
|
|||||||
const plugins = require('../plugins');
|
const plugins = require('../plugins');
|
||||||
const translator = require('../translator');
|
const translator = require('../translator');
|
||||||
const privileges = require('../privileges');
|
const privileges = require('../privileges');
|
||||||
|
const activitypub = require('../activitypub');
|
||||||
const utils = require('../utils');
|
const utils = require('../utils');
|
||||||
const helpers = require('../helpers');
|
const helpers = require('../helpers');
|
||||||
|
|
||||||
@@ -176,6 +177,19 @@ async function modifyEvent({ tid, uid, eventIds, timestamps, events }) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add post announces
|
||||||
|
const announces = await activitypub.notes.announce.list({ tid });
|
||||||
|
announces.forEach(({ actor, pid, timestamp }) => {
|
||||||
|
events.push({
|
||||||
|
type: 'announce',
|
||||||
|
uid: actor,
|
||||||
|
href: `/post/${encodeURIComponent(pid)}`,
|
||||||
|
pid,
|
||||||
|
timestamp,
|
||||||
|
});
|
||||||
|
timestamps.push(timestamp);
|
||||||
|
});
|
||||||
|
|
||||||
const [users, fromCategories, userSettings] = await Promise.all([
|
const [users, fromCategories, userSettings] = await Promise.all([
|
||||||
getUserInfo(events.map(event => event.uid).filter(Boolean)),
|
getUserInfo(events.map(event => event.uid).filter(Boolean)),
|
||||||
getCategoryInfo(events.map(event => event.fromCid).filter(Boolean)),
|
getCategoryInfo(events.map(event => event.fromCid).filter(Boolean)),
|
||||||
|
|||||||
38
src/upgrades/4.0.0/announces_zset.js
Normal file
38
src/upgrades/4.0.0/announces_zset.js
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const db = require('../../database');
|
||||||
|
const batch = require('../../batch');
|
||||||
|
const topics = require('../../topics');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'Save ActivityPub Announces in their own per-post sorted set',
|
||||||
|
timestamp: Date.UTC(2024, 4, 1),
|
||||||
|
method: async function () {
|
||||||
|
const { progress } = this;
|
||||||
|
const bulkOp = [];
|
||||||
|
|
||||||
|
await batch.processSortedSet('topics:tid', async (tids, next) => {
|
||||||
|
await Promise.all(tids.map(async (tid) => {
|
||||||
|
const announces = await topics.events.find(tid, {
|
||||||
|
type: 'announce',
|
||||||
|
});
|
||||||
|
|
||||||
|
if (announces.length) {
|
||||||
|
await Promise.all(announces.map(async (eid) => {
|
||||||
|
const event = await db.getObject(`topicEvent:${eid}`);
|
||||||
|
if (['uid', 'pid', 'timestamp'].every(prop => event.hasOwnProperty(prop))) {
|
||||||
|
bulkOp.push([`pid:${event.pid}:announces`, event.timestamp, event.uid]);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
console.log('piurging', tid);
|
||||||
|
await topics.events.purge(tid, announces);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
progress.incr(tids.length);
|
||||||
|
}, { progress });
|
||||||
|
|
||||||
|
await db.sortedSetAddBulk(bulkOp);
|
||||||
|
},
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user