From 4e9ae8e8d5c862ac7a72f56d7bc0b7dab9c81044 Mon Sep 17 00:00:00 2001 From: syuilo Date: Fri, 6 Apr 2018 19:35:23 +0900 Subject: [PATCH] Split code --- src/remote/activitypub/act/create.ts | 108 ------------------ src/remote/activitypub/act/create/image.ts | 19 +++ src/remote/activitypub/act/create/index.ts | 45 ++++++++ src/remote/activitypub/act/create/note.ts | 60 ++++++++++ .../act/{delete.ts => delete/index.ts} | 14 +-- src/remote/activitypub/act/delete/note.ts | 11 ++ 6 files changed, 137 insertions(+), 120 deletions(-) delete mode 100644 src/remote/activitypub/act/create.ts create mode 100644 src/remote/activitypub/act/create/image.ts create mode 100644 src/remote/activitypub/act/create/index.ts create mode 100644 src/remote/activitypub/act/create/note.ts rename src/remote/activitypub/act/{delete.ts => delete/index.ts} (50%) create mode 100644 src/remote/activitypub/act/delete/note.ts diff --git a/src/remote/activitypub/act/create.ts b/src/remote/activitypub/act/create.ts deleted file mode 100644 index d1eeacbc3..000000000 --- a/src/remote/activitypub/act/create.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { JSDOM } from 'jsdom'; -import * as debug from 'debug'; - -import Resolver from '../resolver'; -import Post from '../../../models/post'; -import uploadFromUrl from '../../../services/drive/upload-from-url'; -import createPost from '../../../services/post/create'; -import { IRemoteUser, isRemoteUser } from '../../../models/user'; -import resolvePerson from '../resolve-person'; - -const log = debug('misskey:activitypub'); - -export default async (actor: IRemoteUser, activity): Promise => { - if ('actor' in activity && actor.account.uri !== activity.actor) { - throw new Error('invalid actor'); - } - - const uri = activity.id || activity; - - log(`Create: ${uri}`); - - // TODO: 同じURIをもつものが既に登録されていないかチェック - - const resolver = new Resolver(); - - let object; - - try { - object = await resolver.resolve(activity.object); - } catch (e) { - log(`Resolution failed: ${e}`); - throw e; - } - - switch (object.type) { - case 'Image': - createImage(resolver, actor, object); - break; - - case 'Note': - createNote(resolver, actor, object); - break; - - default: - console.warn(`Unknown type: ${object.type}`); - break; - } -}; - -async function createImage(resolver: Resolver, actor: IRemoteUser, image) { - if ('attributedTo' in image && actor.account.uri !== image.attributedTo) { - log(`invalid image: ${JSON.stringify(image, null, 2)}`); - throw new Error('invalid image'); - } - - log(`Creating the Image: ${image.id}`); - - return await uploadFromUrl(image.url, actor); -} - -async function createNote(resolver: Resolver, actor: IRemoteUser, note) { - if ( - ('attributedTo' in note && actor.account.uri !== note.attributedTo) || - typeof note.id !== 'string' - ) { - log(`invalid note: ${JSON.stringify(note, null, 2)}`); - throw new Error('invalid note'); - } - - log(`Creating the Note: ${note.id}`); - - const media = []; - if ('attachment' in note && note.attachment != null) { - // TODO: attachmentは必ずしもImageではない - // TODO: ループの中でawaitはすべきでない - note.attachment.forEach(async media => { - const created = await createImage(resolver, note.actor, media); - media.push(created); - }); - } - - let reply = null; - if ('inReplyTo' in note && note.inReplyTo != null) { - const inReplyToPost = await Post.findOne({ uri: note.inReplyTo.id || note.inReplyTo }); - if (inReplyToPost) { - reply = inReplyToPost; - } else { - const inReplyTo = await resolver.resolve(note.inReplyTo) as any; - const actor = await resolvePerson(inReplyTo.attributedTo); - if (isRemoteUser(actor)) { - reply = await createNote(resolver, actor, inReplyTo); - } - } - } - - const { window } = new JSDOM(note.content); - - return await createPost(actor, { - createdAt: new Date(note.published), - media, - reply, - repost: undefined, - text: window.document.body.textContent, - viaMobile: false, - geo: undefined, - uri: note.id - }); -} diff --git a/src/remote/activitypub/act/create/image.ts b/src/remote/activitypub/act/create/image.ts new file mode 100644 index 000000000..cd9e7b4e0 --- /dev/null +++ b/src/remote/activitypub/act/create/image.ts @@ -0,0 +1,19 @@ +import * as debug from 'debug'; + +import Resolver from '../../resolver'; +import uploadFromUrl from '../../../../services/drive/upload-from-url'; +import { IRemoteUser } from '../../../../models/user'; +import { IDriveFile } from '../../../../models/drive-file'; + +const log = debug('misskey:activitypub'); + +export default async function(resolver: Resolver, actor: IRemoteUser, image): Promise { + if ('attributedTo' in image && actor.account.uri !== image.attributedTo) { + log(`invalid image: ${JSON.stringify(image, null, 2)}`); + throw new Error('invalid image'); + } + + log(`Creating the Image: ${image.id}`); + + return await uploadFromUrl(image.url, actor); +} diff --git a/src/remote/activitypub/act/create/index.ts b/src/remote/activitypub/act/create/index.ts new file mode 100644 index 000000000..d210aa4c5 --- /dev/null +++ b/src/remote/activitypub/act/create/index.ts @@ -0,0 +1,45 @@ +import * as debug from 'debug'; + +import Resolver from '../../resolver'; +import { IRemoteUser } from '../../../../models/user'; +import createNote from './note'; +import createImage from './image'; + +const log = debug('misskey:activitypub'); + +export default async (actor: IRemoteUser, activity): Promise => { + if ('actor' in activity && actor.account.uri !== activity.actor) { + throw new Error('invalid actor'); + } + + const uri = activity.id || activity; + + log(`Create: ${uri}`); + + // TODO: 同じURIをもつものが既に登録されていないかチェック + + const resolver = new Resolver(); + + let object; + + try { + object = await resolver.resolve(activity.object); + } catch (e) { + log(`Resolution failed: ${e}`); + throw e; + } + + switch (object.type) { + case 'Image': + createImage(resolver, actor, object); + break; + + case 'Note': + createNote(resolver, actor, object); + break; + + default: + console.warn(`Unknown type: ${object.type}`); + break; + } +}; diff --git a/src/remote/activitypub/act/create/note.ts b/src/remote/activitypub/act/create/note.ts new file mode 100644 index 000000000..2ccd503ae --- /dev/null +++ b/src/remote/activitypub/act/create/note.ts @@ -0,0 +1,60 @@ +import { JSDOM } from 'jsdom'; +import * as debug from 'debug'; + +import Resolver from '../../resolver'; +import Post, { IPost } from '../../../../models/post'; +import createPost from '../../../../services/post/create'; +import { IRemoteUser, isRemoteUser } from '../../../../models/user'; +import resolvePerson from '../../resolve-person'; +import createImage from './image'; + +const log = debug('misskey:activitypub'); + +export default async function createNote(resolver: Resolver, actor: IRemoteUser, note): Promise { + if ( + ('attributedTo' in note && actor.account.uri !== note.attributedTo) || + typeof note.id !== 'string' + ) { + log(`invalid note: ${JSON.stringify(note, null, 2)}`); + throw new Error('invalid note'); + } + + log(`Creating the Note: ${note.id}`); + + const media = []; + if ('attachment' in note && note.attachment != null) { + // TODO: attachmentは必ずしもImageではない + // TODO: ループの中でawaitはすべきでない + note.attachment.forEach(async media => { + const created = await createImage(resolver, note.actor, media); + media.push(created); + }); + } + + let reply = null; + if ('inReplyTo' in note && note.inReplyTo != null) { + const inReplyToPost = await Post.findOne({ uri: note.inReplyTo.id || note.inReplyTo }); + if (inReplyToPost) { + reply = inReplyToPost; + } else { + const inReplyTo = await resolver.resolve(note.inReplyTo) as any; + const actor = await resolvePerson(inReplyTo.attributedTo); + if (isRemoteUser(actor)) { + reply = await createNote(resolver, actor, inReplyTo); + } + } + } + + const { window } = new JSDOM(note.content); + + return await createPost(actor, { + createdAt: new Date(note.published), + media, + reply, + repost: undefined, + text: window.document.body.textContent, + viaMobile: false, + geo: undefined, + uri: note.id + }); +} diff --git a/src/remote/activitypub/act/delete.ts b/src/remote/activitypub/act/delete/index.ts similarity index 50% rename from src/remote/activitypub/act/delete.ts rename to src/remote/activitypub/act/delete/index.ts index 334ca47ed..764814bac 100644 --- a/src/remote/activitypub/act/delete.ts +++ b/src/remote/activitypub/act/delete/index.ts @@ -1,6 +1,5 @@ -import Resolver from '../resolver'; -import Post from '../../../models/post'; -import { createDb } from '../../../queue'; +import Resolver from '../../resolver'; +import deleteNote from './note'; export default async (actor, activity): Promise => { if ('actor' in activity && actor.account.uri !== activity.actor) { @@ -16,13 +15,4 @@ export default async (actor, activity): Promise => { deleteNote(object); break; } - - async function deleteNote(note) { - const post = await Post.findOneAndDelete({ uri: note.id }); - - createDb({ - type: 'deletePostDependents', - id: post._id - }).delay(65536).save(); - } }; diff --git a/src/remote/activitypub/act/delete/note.ts b/src/remote/activitypub/act/delete/note.ts new file mode 100644 index 000000000..3b821f87c --- /dev/null +++ b/src/remote/activitypub/act/delete/note.ts @@ -0,0 +1,11 @@ +import Post from '../../../../models/post'; +import { createDb } from '../../../../queue'; + +export default async function(note) { + const post = await Post.findOneAndDelete({ uri: note.id }); + + createDb({ + type: 'deletePostDependents', + id: post._id + }).delay(65536).save(); +}