mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-02 12:05:57 +01:00
feat: note attachments via link preview plugin
This commit is contained in:
@@ -213,7 +213,6 @@ Mocks.note = async (post) => {
|
|||||||
const id = `${nconf.get('url')}/post/${post.pid}`;
|
const id = `${nconf.get('url')}/post/${post.pid}`;
|
||||||
const published = new Date(parseInt(post.timestamp, 10)).toISOString();
|
const published = new Date(parseInt(post.timestamp, 10)).toISOString();
|
||||||
|
|
||||||
|
|
||||||
// todo: post visibility
|
// todo: post visibility
|
||||||
const to = new Set([activitypub._constants.publicAddress]);
|
const to = new Set([activitypub._constants.publicAddress]);
|
||||||
const cc = new Set([`${nconf.get('url')}/uid/${post.user.uid}/followers`]);
|
const cc = new Set([`${nconf.get('url')}/uid/${post.user.uid}/followers`]);
|
||||||
@@ -281,6 +280,13 @@ Mocks.note = async (post) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let attachment = await posts.attachments.get(post.pid) || [];
|
||||||
|
attachment = attachment.map(({ mediaType, url }) => ({
|
||||||
|
type: 'Document',
|
||||||
|
mediaType,
|
||||||
|
url,
|
||||||
|
}));
|
||||||
|
|
||||||
const object = {
|
const object = {
|
||||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||||
id,
|
id,
|
||||||
@@ -298,7 +304,7 @@ Mocks.note = async (post) => {
|
|||||||
content: post.content,
|
content: post.content,
|
||||||
source,
|
source,
|
||||||
tag,
|
tag,
|
||||||
attachment: [], // todo... requires refactoring of link preview plugin
|
attachment,
|
||||||
// replies: {} todo...
|
// replies: {} todo...
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const winston = require('winston');
|
const winston = require('winston');
|
||||||
const crypto = require('crypto');
|
|
||||||
const nconf = require('nconf');
|
const nconf = require('nconf');
|
||||||
|
|
||||||
const db = require('../database');
|
const db = require('../database');
|
||||||
@@ -135,7 +134,7 @@ Notes.assert = async (uid, input, options = { skipChecks: false }) => {
|
|||||||
_activitypub: mainPost._activitypub,
|
_activitypub: mainPost._activitypub,
|
||||||
}),
|
}),
|
||||||
Notes.updateLocalRecipients(mainPid, { to, cc }),
|
Notes.updateLocalRecipients(mainPid, { to, cc }),
|
||||||
Notes.saveAttachments(mainPid, attachment),
|
posts.attachments.update(mainPid, attachment),
|
||||||
]);
|
]);
|
||||||
unprocessed.pop();
|
unprocessed.pop();
|
||||||
}
|
}
|
||||||
@@ -148,7 +147,7 @@ Notes.assert = async (uid, input, options = { skipChecks: false }) => {
|
|||||||
await Promise.all([
|
await Promise.all([
|
||||||
topics.reply(post),
|
topics.reply(post),
|
||||||
Notes.updateLocalRecipients(post.pid, { to, cc }),
|
Notes.updateLocalRecipients(post.pid, { to, cc }),
|
||||||
Notes.saveAttachments(post.pid, attachment),
|
posts.attachments.update(post.pid, attachment),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Category announce
|
// Category announce
|
||||||
@@ -228,38 +227,6 @@ Notes.updateLocalRecipients = async (id, { to, cc }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
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) => {
|
Notes.getParentChain = async (uid, input) => {
|
||||||
// Traverse upwards via `inReplyTo` until you find the root-level Note
|
// Traverse upwards via `inReplyTo` until you find the root-level Note
|
||||||
const id = activitypub.helpers.isUri(input) ? input : input.id;
|
const id = activitypub.helpers.isUri(input) ? input : input.id;
|
||||||
|
|||||||
54
src/posts/attachments.js
Normal file
54
src/posts/attachments.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const crypto = require('crypto');
|
||||||
|
|
||||||
|
const db = require('../database');
|
||||||
|
|
||||||
|
const Attachments = module.exports;
|
||||||
|
|
||||||
|
Attachments.get = async (pid) => {
|
||||||
|
const hashes = await db.getSortedSetMembers(`post:${pid}:attachments`);
|
||||||
|
const keys = hashes.map(hash => `attachment:${hash}`);
|
||||||
|
const attachments = (await db.getObjects(keys)).filter(Boolean);
|
||||||
|
|
||||||
|
return attachments;
|
||||||
|
};
|
||||||
|
|
||||||
|
Attachments.update = async (pid, attachments) => {
|
||||||
|
if (!attachments) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bulkOps = {
|
||||||
|
hash: [],
|
||||||
|
zset: {
|
||||||
|
score: [],
|
||||||
|
value: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
attachments.filter(Boolean).forEach(({ _type, 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}`;
|
||||||
|
|
||||||
|
if (_type) {
|
||||||
|
_type = 'attachment';
|
||||||
|
}
|
||||||
|
|
||||||
|
bulkOps.hash.push([key, { _type, 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:${pid}:attachments`, bulkOps.zset.score, bulkOps.zset.value),
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// todo
|
||||||
|
// Attachments.remove = async (pid) => { ... }
|
||||||
@@ -27,6 +27,8 @@ require('./queue')(Posts);
|
|||||||
require('./diffs')(Posts);
|
require('./diffs')(Posts);
|
||||||
require('./uploads')(Posts);
|
require('./uploads')(Posts);
|
||||||
|
|
||||||
|
Posts.attachments = require('./attachments');
|
||||||
|
|
||||||
Posts.exists = async function (pids) {
|
Posts.exists = async function (pids) {
|
||||||
return await db.exists(
|
return await db.exists(
|
||||||
Array.isArray(pids) ? pids.map(pid => `post:${pid}`) : `post:${pids}`
|
Array.isArray(pids) ? pids.map(pid => `post:${pid}`) : `post:${pids}`
|
||||||
|
|||||||
Reference in New Issue
Block a user