Skip to content

Commit

Permalink
chore: move assertTopic to top of file, rename to assert
Browse files Browse the repository at this point in the history
... despite the diff, that's all this commit did
  • Loading branch information
julianlam committed Mar 22, 2024
1 parent e0f6b70 commit 4ee8519
Showing 1 changed file with 111 additions and 111 deletions.
222 changes: 111 additions & 111 deletions src/activitypub/notes.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,115 +15,7 @@ const utils = require('../utils');
const activitypub = module.parent.exports;
const Notes = module.exports;

Notes.updateLocalRecipients = async (id, { to, cc }) => {
const recipients = new Set([...(to || []), ...(cc || [])]);
const uids = new Set();
await Promise.all(Array.from(recipients).map(async (recipient) => {
const { type, id } = await activitypub.helpers.resolveLocalId(recipient);
if (type === 'user' && await user.exists(id)) {
uids.add(parseInt(id, 10));
return;
}

const followedUid = await db.getObjectField('followersUrl:uid', recipient);
if (followedUid) {
const followers = await db.getSortedSetMembers(`followersRemote:${followedUid}`);
if (followers.length) {
uids.add(...followers.map(uid => parseInt(uid, 10)));
}
// return;
}
}));

if (uids.size > 0) {
await db.setAdd(`post:${id}:recipients`, Array.from(uids));
}
};

Notes.saveAttachments = async (id, attachments) => {
if (!attachments) {
return;
}

const bulkOps = {
hash: [],
zset: {
score: [],
value: [],
},
};

attachments.filter(Boolean).forEach(({ mediaType, url, name, width, height }, idx) => {
if (!url) { // only required property
return;
}

const hash = crypto.createHash('sha256').update(url).digest('hex');
const key = `attachment:${hash}`;

bulkOps.hash.push([key, { mediaType, url, name, width, height }]);
bulkOps.zset.score.push(idx);
bulkOps.zset.value.push(hash);
});

await Promise.all([
db.setObjectBulk(bulkOps.hash),
db.sortedSetAdd(`post:${id}:attachments`, bulkOps.zset.score, bulkOps.zset.value),
]);
};

Notes.getParentChain = async (uid, input) => {
// Traverse upwards via `inReplyTo` until you find the root-level Note
const id = activitypub.helpers.isUri(input) ? input : input.id;

const chain = new Set();
const traverse = async (uid, id) => {
// Handle remote reference to local post
const { type, id: localId } = await activitypub.helpers.resolveLocalId(id);
if (type === 'post' && localId) {
return await traverse(uid, localId);
}

const exists = await db.exists(`post:${id}`);
if (exists) {
const postData = await posts.getPostData(id);
chain.add(postData);
if (postData.toPid) {
await traverse(uid, postData.toPid);
} else if (utils.isNumber(id)) { // local pid without toPid, could be OP or reply to OP
const mainPid = await topics.getTopicField(postData.tid, 'mainPid');
if (mainPid !== parseInt(id, 10)) {
await traverse(uid, mainPid);
}
}
} else {
let object;
try {
object = await activitypub.get('uid', uid, id);

// Handle incorrect id passed in
if (id !== object.id) {
return await traverse(uid, object.id);
}

object = await activitypub.mocks.post(object);
if (object) {
chain.add(object);
if (object.toPid) {
await traverse(uid, object.toPid);
}
}
} catch (e) {
winston.warn(`[activitypub/notes/getParentChain] Cannot retrieve ${id}, terminating here.`);
}
}
};

await traverse(uid, id);
return chain;
};

Notes.assertTopic = async (uid, id) => {
Notes.assert = async (uid, id) => {
/**
* Given the id of any post, traverses up to cache the entire threaded context
*
Expand All @@ -144,7 +36,7 @@ Notes.assertTopic = async (uid, id) => {
members.push(await posts.exists(mainPid));
if (tid && members.every(Boolean)) {
// All cached, return early.
winston.verbose('[notes/assertTopic] No new notes to process.');
winston.verbose('[notes/assert] No new notes to process.');
return tid;
}

Expand Down Expand Up @@ -177,7 +69,7 @@ Notes.assertTopic = async (uid, id) => {
return post;
}).filter((p, idx) => !members[idx]);
const count = unprocessed.length;
winston.verbose(`[notes/assertTopic] ${count} new note(s) found.`);
winston.verbose(`[notes/assert] ${count} new note(s) found.`);

const [ids, timestamps] = [
unprocessed.map(n => (utils.isNumber(n.pid) ? parseInt(n.pid, 10) : n.pid)),
Expand Down Expand Up @@ -239,6 +131,114 @@ Notes.assertTopic = async (uid, id) => {
return { tid, count };
};

Notes.updateLocalRecipients = async (id, { to, cc }) => {
const recipients = new Set([...(to || []), ...(cc || [])]);
const uids = new Set();
await Promise.all(Array.from(recipients).map(async (recipient) => {
const { type, id } = await activitypub.helpers.resolveLocalId(recipient);
if (type === 'user' && await user.exists(id)) {
uids.add(parseInt(id, 10));
return;
}

const followedUid = await db.getObjectField('followersUrl:uid', recipient);
if (followedUid) {
const followers = await db.getSortedSetMembers(`followersRemote:${followedUid}`);
if (followers.length) {
uids.add(...followers.map(uid => parseInt(uid, 10)));
}
// return;
}
}));

if (uids.size > 0) {
await db.setAdd(`post:${id}:recipients`, Array.from(uids));
}
};

Notes.saveAttachments = async (id, attachments) => {
if (!attachments) {
return;
}

const bulkOps = {
hash: [],
zset: {
score: [],
value: [],
},
};

attachments.filter(Boolean).forEach(({ mediaType, url, name, width, height }, idx) => {
if (!url) { // only required property
return;
}

const hash = crypto.createHash('sha256').update(url).digest('hex');
const key = `attachment:${hash}`;

bulkOps.hash.push([key, { mediaType, url, name, width, height }]);
bulkOps.zset.score.push(idx);
bulkOps.zset.value.push(hash);
});

await Promise.all([
db.setObjectBulk(bulkOps.hash),
db.sortedSetAdd(`post:${id}:attachments`, bulkOps.zset.score, bulkOps.zset.value),
]);
};

Notes.getParentChain = async (uid, input) => {
// Traverse upwards via `inReplyTo` until you find the root-level Note
const id = activitypub.helpers.isUri(input) ? input : input.id;

const chain = new Set();
const traverse = async (uid, id) => {
// Handle remote reference to local post
const { type, id: localId } = await activitypub.helpers.resolveLocalId(id);
if (type === 'post' && localId) {
return await traverse(uid, localId);
}

const exists = await db.exists(`post:${id}`);
if (exists) {
const postData = await posts.getPostData(id);
chain.add(postData);
if (postData.toPid) {
await traverse(uid, postData.toPid);
} else if (utils.isNumber(id)) { // local pid without toPid, could be OP or reply to OP
const mainPid = await topics.getTopicField(postData.tid, 'mainPid');
if (mainPid !== parseInt(id, 10)) {
await traverse(uid, mainPid);
}
}
} else {
let object;
try {
object = await activitypub.get('uid', uid, id);

// Handle incorrect id passed in
if (id !== object.id) {
return await traverse(uid, object.id);
}

object = await activitypub.mocks.post(object);
if (object) {
chain.add(object);
if (object.toPid) {
await traverse(uid, object.toPid);
}
}
} catch (e) {
winston.warn(`[activitypub/notes/getParentChain] Cannot retrieve ${id}, terminating here.`);
}
}
};

await traverse(uid, id);
return chain;
};

Notes.syncUserInboxes = async function (tid) {
const [pids, { cid, mainPid }] = await Promise.all([
db.getSortedSetMembers(`tid:${tid}:posts`),
Expand Down

0 comments on commit 4ee8519

Please sign in to comment.