refactor note content processing

Refactor the content processing into a separate function so it can be
reused in a updateNote function to be created.
This commit is contained in:
Johann150 2023-05-29 12:46:59 +02:00
parent 3ae8049d81
commit d74b7d2eec
Signed by untrusted user: Johann150
GPG key ID: 9EE6577A2A06F8F1
2 changed files with 62 additions and 39 deletions

View file

@ -59,6 +59,56 @@ export function validateNote(object: IObject): Error | null {
return null; return null;
} }
/**
* Function to process the content of a note, reusable in createNote and updateNote.
*/
async function processContent(note: IPost, quoteUri: string | null):
Promise<{
cw: string | null,
files: DriveFile[],
text: string | null,
apEmoji: Emoji[],
apHashtags: string[],
url: string,
name: string
}>
{
// Attachments handling
// TODO: attachments are not necessarily images
const limit = promiseLimit(2);
const attachments = toArray(note.attachment);
const files = note.attachment
// If the note is marked as sensitive, the images should be marked sensitive too.
.map(attach => attach.sensitive |= note.sensitive)
? (await Promise.all(note.attachment.map(x => limit(() => resolveImage(actor, x, resolver)) as Promise<DriveFile>)))
.filter(image => image != null)
: [];
// text parsing
let text: string | null = null;
if (note.source?.mediaType === 'text/x.misskeymarkdown' && typeof note.source.content === 'string') {
text = note.source.content;
} else if (typeof note.content === 'string') {
text = fromHtml(note.content, quoteUri);
}
const emojis = await extractEmojis(note.tag || [], extractDbHost(getApId(note))).catch(e => {
apLogger.info(`extractEmojis: ${e}`);
return [] as Emoji[];
});
return {
cw: note.summary === '' ? null : note.summary,
files,
text,
apEmojis: emojis.map(emoji => emoji.name),
apHashtags: await extractApHashtags(note.tag),
url: getOneApHrefNullable(note.url),
name: note.name,
};
}
/** /**
* Fetch Note. * Fetch Note.
* *
@ -108,19 +158,6 @@ export async function createNote(value: string | IObject, resolver: Resolver, si
let isTalk = note._misskey_talk && visibility === 'specified'; let isTalk = note._misskey_talk && visibility === 'specified';
const apMentions = await extractApMentions(note.tag, resolver); const apMentions = await extractApMentions(note.tag, resolver);
const apHashtags = await extractApHashtags(note.tag);
// Attachments handling
// TODO: attachments are not necessarily images
// If the note is marked as sensitive, the images should be marked sensitive too.
const limit = promiseLimit(2);
note.attachment = toArray(note.attachment);
const files = note.attachment
.map(attach => attach.sensitive = note.sensitive)
? (await Promise.all(note.attachment.map(x => limit(() => resolveImage(actor, x, resolver)) as Promise<DriveFile>)))
.filter(image => image != null)
: [];
// Reply handling // Reply handling
const reply: Note | null = note.inReplyTo const reply: Note | null = note.inReplyTo
@ -197,16 +234,6 @@ export async function createNote(value: string | IObject, resolver: Resolver, si
} }
} }
const cw = note.summary === '' ? null : note.summary;
// text parsing
let text: string | null = null;
if (note.source?.mediaType === 'text/x.misskeymarkdown' && typeof note.source.content === 'string') {
text = note.source.content;
} else if (typeof note.content === 'string') {
text = fromHtml(note.content, quote?.uri);
}
// vote // vote
if (reply && reply.hasPoll) { if (reply && reply.hasPoll) {
const poll = await Polls.findOneByOrFail({ noteId: reply.id }); const poll = await Polls.findOneByOrFail({ noteId: reply.id });
@ -229,38 +256,34 @@ export async function createNote(value: string | IObject, resolver: Resolver, si
} }
} }
const emojis = await extractEmojis(note.tag || [], actor.host).catch(e => {
apLogger.info(`extractEmojis: ${e}`);
return [] as Emoji[];
});
const apEmojis = emojis.map(emoji => emoji.name);
const poll = await extractPollFromQuestion(note, resolver).catch(() => undefined); const poll = await extractPollFromQuestion(note, resolver).catch(() => undefined);
const processedContent = await processContent(note, quote?.uri);
if (isTalk) { if (isTalk) {
for (const recipient of visibleUsers) { for (const recipient of visibleUsers) {
await createMessage(actor, recipient, undefined, text || undefined, (files && files.length > 0) ? files[0] : null, object.id); await createMessage(
actor,
recipient,
undefined,
processedContent.text,
processedContent.files[0] ?? null,
object.id
);
} }
return null; return null;
} else { } else {
return await post(actor, { return await post(actor, {
...processedContent,
createdAt: note.published ? new Date(note.published) : null, createdAt: note.published ? new Date(note.published) : null,
files,
reply, reply,
renote: quote, renote: quote,
name: note.name,
cw,
text,
localOnly: false, localOnly: false,
visibility, visibility,
visibleUsers, visibleUsers,
apMentions, apMentions,
apHashtags,
apEmojis,
poll, poll,
uri: note.id, uri: note.id,
url: getOneApHrefNullable(note.url),
}, silent); }, silent);
} }
} }

View file

@ -1,7 +1,7 @@
import { toArray } from '@/prelude/array.js'; import { toArray } from '@/prelude/array.js';
import { IObject, isHashtag, IApHashtag, isLink, ILink } from '../type.js'; import { IObject, isHashtag, IApHashtag, isLink, ILink } from '../type.js';
export function extractApHashtags(tags: IObject | IObject[] | null | undefined) { export function extractApHashtags(tags: IObject | IObject[] | null | undefined): string[] {
if (tags == null) return []; if (tags == null) return [];
const hashtags = extractApHashtagObjects(tags); const hashtags = extractApHashtagObjects(tags);