6
src/remote/activitypub/misc/get-emoji-names.ts
Normal file
6
src/remote/activitypub/misc/get-emoji-names.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import parse from '../../../mfm/parse';
|
||||
|
||||
export default function(text: string) {
|
||||
if (!text) return [];
|
||||
return parse(text).filter(t => t.type === 'emoji').map(t => (t as any).emoji);
|
||||
}
|
5
src/remote/activitypub/models/icon.ts
Normal file
5
src/remote/activitypub/models/icon.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export type IIcon = {
|
||||
type: string;
|
||||
mediaType?: string;
|
||||
url?: string;
|
||||
};
|
@ -10,6 +10,9 @@ import { resolvePerson, updatePerson } from './person';
|
||||
import { resolveImage } from './image';
|
||||
import { IRemoteUser, IUser } from '../../../models/user';
|
||||
import htmlToMFM from '../../../mfm/html-to-mfm';
|
||||
import Emoji from '../../../models/emoji';
|
||||
import { ITag } from './tag';
|
||||
import { toUnicode } from 'punycode';
|
||||
|
||||
const log = debug('misskey:activitypub');
|
||||
|
||||
@ -93,6 +96,10 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
|
||||
// テキストのパース
|
||||
const text = note._misskey_content ? note._misskey_content : htmlToMFM(note.content);
|
||||
|
||||
await extractEmojis(note.tag, actor.host).catch(e => {
|
||||
console.log(`extractEmojis: ${e}`);
|
||||
});
|
||||
|
||||
// ユーザーの情報が古かったらついでに更新しておく
|
||||
if (actor.updatedAt == null || Date.now() - actor.updatedAt.getTime() > 1000 * 60 * 60 * 24) {
|
||||
updatePerson(note.attributedTo);
|
||||
@ -135,3 +142,35 @@ export async function resolveNote(value: string | IObject, resolver?: Resolver):
|
||||
// 添付されてきたNote Objectは偽装されている可能性があるため、常にuriを指定してサーバーフェッチを行う。
|
||||
return await createNote(uri, resolver);
|
||||
}
|
||||
|
||||
async function extractEmojis(tags: ITag[], host_: string) {
|
||||
const host = toUnicode(host_.toLowerCase());
|
||||
|
||||
if (!tags) return [];
|
||||
|
||||
const eomjiTags = tags.filter(tag => tag.type === 'Emoji' && tag.icon && tag.icon.url);
|
||||
|
||||
return await Promise.all(
|
||||
eomjiTags.map(async tag => {
|
||||
const name = tag.name.replace(/^:/, '').replace(/:$/, '');
|
||||
|
||||
const exists = await Emoji.findOne({
|
||||
host,
|
||||
name
|
||||
});
|
||||
|
||||
if (exists) {
|
||||
return exists;
|
||||
}
|
||||
|
||||
log(`register emoji host=${host}, name=${name}`);
|
||||
|
||||
return await Emoji.insert({
|
||||
host,
|
||||
name,
|
||||
url: tag.icon.url,
|
||||
aliases: [],
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
12
src/remote/activitypub/models/tag.ts
Normal file
12
src/remote/activitypub/models/tag.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { IIcon } from "./icon";
|
||||
|
||||
/***
|
||||
* tag (ActivityPub)
|
||||
*/
|
||||
export type ITag = {
|
||||
id: string;
|
||||
type: string;
|
||||
name?: string;
|
||||
updated?: Date;
|
||||
icon?: IIcon;
|
||||
};
|
14
src/remote/activitypub/renderer/emoji.ts
Normal file
14
src/remote/activitypub/renderer/emoji.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { IEmoji } from '../../../models/emoji';
|
||||
import config from '../../../config';
|
||||
|
||||
export default (emoji: IEmoji) => ({
|
||||
id: `${config.url}/emojis/${emoji.name}`,
|
||||
type: 'Emoji',
|
||||
name: `:${emoji.name}:`,
|
||||
updated: emoji.updatedAt != null ? emoji.updatedAt.toISOString() : new Date().toISOString,
|
||||
icon: {
|
||||
type: 'Image',
|
||||
mediaType: 'image/png', //Mei-TODO
|
||||
url: emoji.url
|
||||
}
|
||||
});
|
@ -1,12 +1,16 @@
|
||||
import renderDocument from './document';
|
||||
import renderHashtag from './hashtag';
|
||||
import renderMention from './mention';
|
||||
import renderEmoji from './emoji';
|
||||
import config from '../../../config';
|
||||
import DriveFile, { IDriveFile } from '../../../models/drive-file';
|
||||
import Note, { INote } from '../../../models/note';
|
||||
import User from '../../../models/user';
|
||||
import toHtml from '../misc/get-note-html';
|
||||
import parseMfm from '../../../mfm/parse';
|
||||
import getEmojiNames from '../misc/get-emoji-names';
|
||||
import Emoji, { IEmoji } from '../../../models/emoji';
|
||||
import { unique } from '../../../prelude/array';
|
||||
|
||||
export default async function renderNote(note: INote, dive = true): Promise<any> {
|
||||
const promisedFiles: Promise<IDriveFile[]> = note.fileIds
|
||||
@ -75,10 +79,6 @@ export default async function renderNote(note: INote, dive = true): Promise<any>
|
||||
|
||||
const hashtagTags = (note.tags || []).map(tag => renderHashtag(tag));
|
||||
const mentionTags = mentionedUsers.map(u => renderMention(u));
|
||||
const tag = [
|
||||
...hashtagTags,
|
||||
...mentionTags,
|
||||
];
|
||||
|
||||
const files = await promisedFiles;
|
||||
|
||||
@ -108,12 +108,24 @@ export default async function renderNote(note: INote, dive = true): Promise<any>
|
||||
}).join('');
|
||||
}
|
||||
|
||||
const content = toHtml(Object.assign({}, note, { text }));
|
||||
|
||||
const emojiNames = unique(getEmojiNames(content));
|
||||
const emojis = await getEmojis(emojiNames);
|
||||
const apemojis = emojis.map(emoji => renderEmoji(emoji));
|
||||
|
||||
const tag = [
|
||||
...hashtagTags,
|
||||
...mentionTags,
|
||||
...apemojis,
|
||||
];
|
||||
|
||||
return {
|
||||
id: `${config.url}/notes/${note._id}`,
|
||||
type: 'Note',
|
||||
attributedTo,
|
||||
summary: note.cw,
|
||||
content: toHtml(Object.assign({}, note, { text })),
|
||||
content,
|
||||
_misskey_content: text,
|
||||
published: note.createdAt.toISOString(),
|
||||
to,
|
||||
@ -124,3 +136,18 @@ export default async function renderNote(note: INote, dive = true): Promise<any>
|
||||
tag
|
||||
};
|
||||
}
|
||||
|
||||
async function getEmojis(names: string[]): Promise<IEmoji[]> {
|
||||
if (names == null || names.length < 1) return [];
|
||||
|
||||
const emojis = await Promise.all(
|
||||
names.map(async name => {
|
||||
return await Emoji.findOne({
|
||||
name,
|
||||
host: null
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
return emojis.filter(emoji => emoji != null);
|
||||
}
|
||||
|
Reference in New Issue
Block a user