From 39748ea0c38c5bfbdadf6cd2772fae636337c470 Mon Sep 17 00:00:00 2001 From: Chocolate Pie <106949016+chocolate-pie@users.noreply.github.com> Date: Sat, 6 May 2023 08:17:55 +0900 Subject: feat: アンテナのエクスポート・インポート (#10754) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: アンテナのエクスポートに対応 (misskey-dev/misskey#10690) * feat: アンテナのインポートに対応 (misskey-dev/misskey#10690) * fix: タイポを修正 * feat: ユーザーリストをサポート * fix: バグを直した * fix: バグを直した * fix: 適当に決めた変数名を変更 * fix * fix: 変数の変更、リファクタリング --- packages/backend/src/server/api/EndpointsModule.ts | 8 +++ packages/backend/src/server/api/endpoints.ts | 4 ++ .../src/server/api/endpoints/i/export-antennas.ts | 30 ++++++++ .../src/server/api/endpoints/i/import-antennas.ts | 81 ++++++++++++++++++++++ 4 files changed, 123 insertions(+) create mode 100644 packages/backend/src/server/api/endpoints/i/export-antennas.ts create mode 100644 packages/backend/src/server/api/endpoints/i/import-antennas.ts (limited to 'packages/backend/src/server/api') diff --git a/packages/backend/src/server/api/EndpointsModule.ts b/packages/backend/src/server/api/EndpointsModule.ts index 6dc1313e59..ee1aae5b6c 100644 --- a/packages/backend/src/server/api/EndpointsModule.ts +++ b/packages/backend/src/server/api/EndpointsModule.ts @@ -194,6 +194,7 @@ import * as ep___i_exportMute from './endpoints/i/export-mute.js'; import * as ep___i_exportNotes from './endpoints/i/export-notes.js'; import * as ep___i_exportFavorites from './endpoints/i/export-favorites.js'; import * as ep___i_exportUserLists from './endpoints/i/export-user-lists.js'; +import * as ep___i_exportAntennas from './endpoints/i/export-antennas.js'; import * as ep___i_favorites from './endpoints/i/favorites.js'; import * as ep___i_gallery_likes from './endpoints/i/gallery/likes.js'; import * as ep___i_gallery_posts from './endpoints/i/gallery/posts.js'; @@ -202,6 +203,7 @@ import * as ep___i_importBlocking from './endpoints/i/import-blocking.js'; import * as ep___i_importFollowing from './endpoints/i/import-following.js'; import * as ep___i_importMuting from './endpoints/i/import-muting.js'; import * as ep___i_importUserLists from './endpoints/i/import-user-lists.js'; +import * as ep___i_importAntennas from './endpoints/i/import-antennas.js'; import * as ep___i_notifications from './endpoints/i/notifications.js'; import * as ep___i_pageLikes from './endpoints/i/page-likes.js'; import * as ep___i_pages from './endpoints/i/pages.js'; @@ -530,6 +532,7 @@ const $i_exportMute: Provider = { provide: 'ep:i/export-mute', useClass: ep___i_ const $i_exportNotes: Provider = { provide: 'ep:i/export-notes', useClass: ep___i_exportNotes.default }; const $i_exportFavorites: Provider = { provide: 'ep:i/export-favorites', useClass: ep___i_exportFavorites.default }; const $i_exportUserLists: Provider = { provide: 'ep:i/export-user-lists', useClass: ep___i_exportUserLists.default }; +const $i_exportAntennas: Provider = { provide: 'ep:i/export-antennas', useClass: ep___i_exportAntennas.default }; const $i_favorites: Provider = { provide: 'ep:i/favorites', useClass: ep___i_favorites.default }; const $i_gallery_likes: Provider = { provide: 'ep:i/gallery/likes', useClass: ep___i_gallery_likes.default }; const $i_gallery_posts: Provider = { provide: 'ep:i/gallery/posts', useClass: ep___i_gallery_posts.default }; @@ -538,6 +541,7 @@ const $i_importBlocking: Provider = { provide: 'ep:i/import-blocking', useClass: const $i_importFollowing: Provider = { provide: 'ep:i/import-following', useClass: ep___i_importFollowing.default }; const $i_importMuting: Provider = { provide: 'ep:i/import-muting', useClass: ep___i_importMuting.default }; const $i_importUserLists: Provider = { provide: 'ep:i/import-user-lists', useClass: ep___i_importUserLists.default }; +const $i_importAntennas: Provider = { provide: 'ep:i/import-antennas', useClass: ep___i_importAntennas.default }; const $i_notifications: Provider = { provide: 'ep:i/notifications', useClass: ep___i_notifications.default }; const $i_pageLikes: Provider = { provide: 'ep:i/page-likes', useClass: ep___i_pageLikes.default }; const $i_pages: Provider = { provide: 'ep:i/pages', useClass: ep___i_pages.default }; @@ -870,6 +874,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $i_exportNotes, $i_exportFavorites, $i_exportUserLists, + $i_exportAntennas, $i_favorites, $i_gallery_likes, $i_gallery_posts, @@ -878,6 +883,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $i_importFollowing, $i_importMuting, $i_importUserLists, + $i_importAntennas, $i_notifications, $i_pageLikes, $i_pages, @@ -1204,6 +1210,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $i_exportNotes, $i_exportFavorites, $i_exportUserLists, + $i_exportAntennas, $i_favorites, $i_gallery_likes, $i_gallery_posts, @@ -1212,6 +1219,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $i_importFollowing, $i_importMuting, $i_importUserLists, + $i_importAntennas, $i_notifications, $i_pageLikes, $i_pages, diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts index acd7f7ec3e..09bd7cbff4 100644 --- a/packages/backend/src/server/api/endpoints.ts +++ b/packages/backend/src/server/api/endpoints.ts @@ -194,6 +194,7 @@ import * as ep___i_exportMute from './endpoints/i/export-mute.js'; import * as ep___i_exportNotes from './endpoints/i/export-notes.js'; import * as ep___i_exportFavorites from './endpoints/i/export-favorites.js'; import * as ep___i_exportUserLists from './endpoints/i/export-user-lists.js'; +import * as ep___i_exportAntennas from './endpoints/i/export-antennas.js'; import * as ep___i_favorites from './endpoints/i/favorites.js'; import * as ep___i_gallery_likes from './endpoints/i/gallery/likes.js'; import * as ep___i_gallery_posts from './endpoints/i/gallery/posts.js'; @@ -202,6 +203,7 @@ import * as ep___i_importBlocking from './endpoints/i/import-blocking.js'; import * as ep___i_importFollowing from './endpoints/i/import-following.js'; import * as ep___i_importMuting from './endpoints/i/import-muting.js'; import * as ep___i_importUserLists from './endpoints/i/import-user-lists.js'; +import * as ep___i_importAntennas from './endpoints/i/import-antennas.js'; import * as ep___i_notifications from './endpoints/i/notifications.js'; import * as ep___i_pageLikes from './endpoints/i/page-likes.js'; import * as ep___i_pages from './endpoints/i/pages.js'; @@ -528,6 +530,7 @@ const eps = [ ['i/export-notes', ep___i_exportNotes], ['i/export-favorites', ep___i_exportFavorites], ['i/export-user-lists', ep___i_exportUserLists], + ['i/export-antennas', ep___i_exportAntennas], ['i/favorites', ep___i_favorites], ['i/gallery/likes', ep___i_gallery_likes], ['i/gallery/posts', ep___i_gallery_posts], @@ -536,6 +539,7 @@ const eps = [ ['i/import-following', ep___i_importFollowing], ['i/import-muting', ep___i_importMuting], ['i/import-user-lists', ep___i_importUserLists], + ['i/import-antennas', ep___i_importAntennas], ['i/notifications', ep___i_notifications], ['i/page-likes', ep___i_pageLikes], ['i/pages', ep___i_pages], diff --git a/packages/backend/src/server/api/endpoints/i/export-antennas.ts b/packages/backend/src/server/api/endpoints/i/export-antennas.ts new file mode 100644 index 0000000000..4182c1b247 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/i/export-antennas.ts @@ -0,0 +1,30 @@ +import { Injectable } from '@nestjs/common'; +import ms from 'ms'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { QueueService } from '@/core/QueueService.js'; + +export const meta = { + secure: true, + requireCredential: true, + limit: { + duration: ms('1hour'), + max: 1, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: {}, + required: [], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor ( + private queueService: QueueService, + ) { + super(meta, paramDef, async (ps, me) => { + this.queueService.createExportAntennasJob(me); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/i/import-antennas.ts b/packages/backend/src/server/api/endpoints/i/import-antennas.ts new file mode 100644 index 0000000000..676648bde8 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/i/import-antennas.ts @@ -0,0 +1,81 @@ +import { Inject, Injectable } from '@nestjs/common'; +import ms from 'ms'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { QueueService } from '@/core/QueueService.js'; +import type { AntennasRepository, DriveFilesRepository, UsersRepository, Antenna as _Antenna } from '@/models/index.js'; +import { DI } from '@/di-symbols.js'; +import { ApiError } from '../../error.js'; +import { RoleService } from '@/core/RoleService.js'; +import { DownloadService } from '@/core/DownloadService.js'; + +export const meta = { + secure: true, + requireCredential: true, + prohibitMoved: true, + + limit: { + duration: ms('1hour'), + max: 1, + }, + errors: { + noSuchFile: { + message: 'No such file.', + code: 'NO_SUCH_FILE', + id: '3b71d086-c3fa-431c-b01d-ded65a777172', + }, + noSuchUser: { + message: 'No such user.', + code: 'NO_SUCH_USER', + id: 'e842c379-8ac7-4cf7-b07a-4d4de7e4671c', + }, + emptyFile: { + message: 'That file is empty.', + code: 'EMPTY_FILE', + id: '7f60115d-8d93-4b0f-bd0e-3815dcbb389f', + }, + tooManyAntennas: { + message: 'You cannot create antenna any more.', + code: 'TOO_MANY_ANTENNAS', + id: '600917d4-a4cb-4cc5-8ba8-7ac8ea3c7779', + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + fileId: { type: 'string', format: 'misskey:id' }, + }, + required: ['fileId'], +} as const; + +@Injectable() // eslint-disable-next-line import/no-default-export +export default class extends Endpoint { + constructor ( + @Inject(DI.driveFilesRepository) + private driveFilesRepository: DriveFilesRepository, + @Inject(DI.antennasRepository) + private antennasRepository: AntennasRepository, + @Inject(DI.usersRepository) + private usersRepository: UsersRepository, + private roleService: RoleService, + private queueService: QueueService, + private downloadService: DownloadService + ) { + super(meta, paramDef, async (ps, me) => { + const users = await this.usersRepository.findOneBy({ id: me.id }); + if (users === null) throw new ApiError(meta.errors.noSuchUser); + const file = await this.driveFilesRepository.findOneBy({ id: ps.fileId }); + if (file === null) throw new ApiError(meta.errors.noSuchFile); + if (file.size === 0) throw new ApiError(meta.errors.emptyFile); + const antennas: (_Antenna & { userListAcct: string[] | null })[] = JSON.parse(await this.downloadService.downloadTextFile(file.url)); + const currentAntennasCount = await this.antennasRepository.countBy({ userId: me.id }); + if (currentAntennasCount + antennas.length > (await this.roleService.getUserPolicies(me.id)).antennaLimit) { + throw new ApiError(meta.errors.tooManyAntennas); + } + this.queueService.createImportAntennasJob(me, antennas); + }); + } +} + +export type Antenna = (_Antenna & { userListAcct: string[] | null })[]; -- cgit v1.2.3-freya