No MFM parsing when remote note (#3470)

* Use tag for hashtag detection of remote note

* No MFM parsing when remote note
This commit is contained in:
MeiMei 2018-12-02 18:05:33 +09:00 committed by syuilo
parent 163cf49f16
commit 3a2dc95850
2 changed files with 35 additions and 9 deletions

View file

@ -10,7 +10,7 @@ import { resolvePerson, updatePerson } from './person';
import { resolveImage } from './image'; import { resolveImage } from './image';
import { IRemoteUser, IUser } from '../../../models/user'; import { IRemoteUser, IUser } from '../../../models/user';
import htmlToMFM from '../../../mfm/html-to-mfm'; import htmlToMFM from '../../../mfm/html-to-mfm';
import Emoji from '../../../models/emoji'; import Emoji, { IEmoji } from '../../../models/emoji';
import { ITag } from './tag'; import { ITag } from './tag';
import { toUnicode } from 'punycode'; import { toUnicode } from 'punycode';
import { unique, concat, difference } from '../../../prelude/array'; import { unique, concat, difference } from '../../../prelude/array';
@ -84,6 +84,8 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
const apMentions = await extractMentionedUsers(actor, note.to, note.cc, resolver); const apMentions = await extractMentionedUsers(actor, note.to, note.cc, resolver);
const apHashtags = await extractHashtags(note.tag);
// 添付ファイル // 添付ファイル
// TODO: attachmentは必ずしもImageではない // TODO: attachmentは必ずしもImageではない
// TODO: attachmentは必ずしも配列ではない // TODO: attachmentは必ずしも配列ではない
@ -108,10 +110,13 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
// テキストのパース // テキストのパース
const text = note._misskey_content ? note._misskey_content : htmlToMFM(note.content); const text = note._misskey_content ? note._misskey_content : htmlToMFM(note.content);
await extractEmojis(note.tag, actor.host).catch(e => { const emojis = await extractEmojis(note.tag, actor.host).catch(e => {
console.log(`extractEmojis: ${e}`); console.log(`extractEmojis: ${e}`);
return [] as IEmoji[];
}); });
const apEmojis = emojis.map(emoji => emoji.name);
// ユーザーの情報が古かったらついでに更新しておく // ユーザーの情報が古かったらついでに更新しておく
if (actor.lastFetchedAt == null || Date.now() - actor.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24) { if (actor.lastFetchedAt == null || Date.now() - actor.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24) {
updatePerson(note.attributedTo); updatePerson(note.attributedTo);
@ -130,6 +135,8 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
visibility, visibility,
visibleUsers, visibleUsers,
apMentions, apMentions,
apHashtags,
apEmojis,
uri: note.id uri: note.id
}, silent); }, silent);
} }
@ -199,3 +206,14 @@ async function extractMentionedUsers(actor: IRemoteUser, to: string[], cc: strin
return users.filter(x => x != null); return users.filter(x => x != null);
} }
function extractHashtags(tags: ITag[]) {
if (!tags) return [];
const hashtags = tags.filter(tag => tag.type === 'Hashtag' && typeof tag.name == 'string');
return hashtags.map(tag => {
const m = tag.name.match(/^#(.+)/);
return m ? m[1] : null;
}).filter(x => x != null);
}

View file

@ -98,6 +98,8 @@ type Option = {
visibility?: string; visibility?: string;
visibleUsers?: IUser[]; visibleUsers?: IUser[];
apMentions?: IUser[]; apMentions?: IUser[];
apHashtags?: string[];
apEmojis?: string[];
uri?: string; uri?: string;
app?: IApp; app?: IApp;
}; };
@ -153,16 +155,22 @@ export default async (user: IUser, data: Option, silent = false) => new Promise<
data.text = data.text.trim(); data.text = data.text.trim();
} }
// Parse MFM let tags = data.apHashtags;
const tokens = data.text ? parse(data.text) : []; let emojis = data.apEmojis;
const cwTokens = data.cw ? parse(data.cw) : []; let mentionedUsers = data.apMentions;
const combinedTokens = tokens.concat(cwTokens);
const tags = extractHashtags(combinedTokens); // Parse MFM if needed
if (!tags || !emojis || !mentionedUsers) {
const tokens = data.text ? parse(data.text) : [];
const cwTokens = data.cw ? parse(data.cw) : [];
const combinedTokens = tokens.concat(cwTokens);
const emojis = extractEmojis(combinedTokens); tags = data.apHashtags || extractHashtags(combinedTokens);
const mentionedUsers = data.apMentions || await extractMentionedUsers(user, combinedTokens); emojis = data.apEmojis || extractEmojis(combinedTokens);
mentionedUsers = data.apMentions || await extractMentionedUsers(user, combinedTokens);
}
if (data.reply && !user._id.equals(data.reply.userId) && !mentionedUsers.some(u => u._id.equals(data.reply.userId))) { if (data.reply && !user._id.equals(data.reply.userId) && !mentionedUsers.some(u => u._id.equals(data.reply.userId))) {
mentionedUsers.push(await User.findOne({ _id: data.reply.userId })); mentionedUsers.push(await User.findOne({ _id: data.reply.userId }));