send/receive user hashtags via AP (#4064)

This commit is contained in:
MeiMei 2019-01-31 20:42:45 +09:00 committed by syuilo
parent d140548784
commit a6e7bbc306
6 changed files with 29 additions and 14 deletions

View file

@ -48,6 +48,7 @@ type IUserBase = {
lang?: string; lang?: string;
pinnedNoteIds: mongo.ObjectID[]; pinnedNoteIds: mongo.ObjectID[];
emojis?: string[]; emojis?: string[];
tags?: string[];
/** /**
* *

View file

@ -11,7 +11,7 @@ import { resolveImage } from './image';
import { IRemoteUser, IUser } from '../../../models/user'; import { IRemoteUser, IUser } from '../../../models/user';
import { fromHtml } from '../../../mfm/fromHtml'; import { fromHtml } from '../../../mfm/fromHtml';
import Emoji, { IEmoji } from '../../../models/emoji'; import Emoji, { IEmoji } from '../../../models/emoji';
import { ITag } from './tag'; import { ITag, extractHashtags } from './tag';
import { toUnicode } from 'punycode'; import { toUnicode } from 'punycode';
import { unique, concat, difference } from '../../../prelude/array'; import { unique, concat, difference } from '../../../prelude/array';
import { extractPollFromQuestion } from './question'; import { extractPollFromQuestion } from './question';
@ -239,14 +239,3 @@ 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

@ -17,7 +17,7 @@ import registerInstance from '../../../services/register-instance';
import Instance from '../../../models/instance'; import Instance from '../../../models/instance';
import getDriveFileUrl from '../../../misc/get-drive-file-url'; import getDriveFileUrl from '../../../misc/get-drive-file-url';
import { IEmoji } from '../../../models/emoji'; import { IEmoji } from '../../../models/emoji';
import { ITag } from './tag'; import { ITag, extractHashtags } from './tag';
import Following from '../../../models/following'; import Following from '../../../models/following';
import { IIdentifier } from './identifier'; import { IIdentifier } from './identifier';
@ -140,6 +140,8 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<IU
const { fields, services } = analyzeAttachments(person.attachment); const { fields, services } = analyzeAttachments(person.attachment);
const tags = extractHashtags(person.tag);
const isBot = object.type == 'Service'; const isBot = object.type == 'Service';
// Create user // Create user
@ -171,6 +173,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<IU
url: person.url, url: person.url,
fields, fields,
...services, ...services,
tags,
isBot, isBot,
isCat: (person as any).isCat === true isCat: (person as any).isCat === true
}) as IRemoteUser; }) as IRemoteUser;
@ -334,6 +337,8 @@ export async function updatePerson(uri: string, resolver?: Resolver, hint?: obje
const { fields, services } = analyzeAttachments(person.attachment); const { fields, services } = analyzeAttachments(person.attachment);
const tags = extractHashtags(person.tag);
const updates = { const updates = {
lastFetchedAt: new Date(), lastFetchedAt: new Date(),
inbox: person.inbox, inbox: person.inbox,
@ -349,6 +354,7 @@ export async function updatePerson(uri: string, resolver?: Resolver, hint?: obje
endpoints: person.endpoints, endpoints: person.endpoints,
fields, fields,
...services, ...services,
tags,
isBot: object.type == 'Service', isBot: object.type == 'Service',
isCat: (person as any).isCat === true, isCat: (person as any).isCat === true,
isLocked: person.manuallyApprovesFollowers, isLocked: person.manuallyApprovesFollowers,

View file

@ -13,3 +13,14 @@ export type ITag = {
icon?: IIcon; icon?: IIcon;
identifier?: IIdentifier; identifier?: IIdentifier;
}; };
export 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

@ -8,6 +8,7 @@ import DriveFile from '../../../models/drive-file';
import { getEmojis } from './note'; import { getEmojis } from './note';
import renderEmoji from './emoji'; import renderEmoji from './emoji';
import { IIdentifier } from '../models/identifier'; import { IIdentifier } from '../models/identifier';
import renderHashtag from './hashtag';
export default async (user: ILocalUser) => { export default async (user: ILocalUser) => {
const id = `${config.url}/users/${user._id}`; const id = `${config.url}/users/${user._id}`;
@ -67,8 +68,11 @@ export default async (user: ILocalUser) => {
const emojis = await getEmojis(user.emojis); const emojis = await getEmojis(user.emojis);
const apemojis = emojis.map(emoji => renderEmoji(emoji)); const apemojis = emojis.map(emoji => renderEmoji(emoji));
const hashtagTags = (user.tags || []).map(tag => renderHashtag(tag));
const tag = [ const tag = [
...apemojis, ...apemojis,
...hashtagTags,
]; ];
return { return {

View file

@ -8,6 +8,7 @@ import define from '../../define';
import getDriveFileUrl from '../../../../misc/get-drive-file-url'; import getDriveFileUrl from '../../../../misc/get-drive-file-url';
import { parse, parsePlain } from '../../../../mfm/parse'; import { parse, parsePlain } from '../../../../mfm/parse';
import extractEmojis from '../../../../misc/extract-emojis'; import extractEmojis from '../../../../misc/extract-emojis';
import extractHashtags from '../../../../misc/extract-hashtags';
const langmap = require('langmap'); const langmap = require('langmap');
export const meta = { export const meta = {
@ -201,9 +202,10 @@ export default define(meta, (ps, user, app) => new Promise(async (res, rej) => {
} }
} }
//#region emojis //#region emojis/tags
if (updates.name != null || updates.description != null) { if (updates.name != null || updates.description != null) {
let emojis = [] as string[]; let emojis = [] as string[];
let tags = [] as string[];
if (updates.name != null) { if (updates.name != null) {
const tokens = parsePlain(updates.name); const tokens = parsePlain(updates.name);
@ -213,9 +215,11 @@ export default define(meta, (ps, user, app) => new Promise(async (res, rej) => {
if (updates.description != null) { if (updates.description != null) {
const tokens = parse(updates.description); const tokens = parse(updates.description);
emojis = emojis.concat(extractEmojis(tokens)); emojis = emojis.concat(extractEmojis(tokens));
tags = extractHashtags(tokens);
} }
updates.emojis = emojis; updates.emojis = emojis;
updates.tags = tags;
} }
//#endregion //#endregion