forked from misskey-dev/misskey
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
wip:emoji/add-requestとemoji/update-requestをadmin配下から出す。(#47)
- Loading branch information
1 parent
21c3d24
commit fe06eb7
Showing
3 changed files
with
262 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
141 changes: 141 additions & 0 deletions
141
packages/backend/src/server/api/endpoints/emoji/add-request.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
/* | ||
* SPDX-FileCopyrightText: Type4ny-project | ||
* SPDX-License-Identifier: AGPL-3.0-only | ||
*/ | ||
|
||
import { Inject, Injectable } from '@nestjs/common'; | ||
import { Endpoint } from '@/server/api/endpoint-base.js'; | ||
import type { DriveFilesRepository } from '@/models/_.js'; | ||
import { DI } from '@/di-symbols.js'; | ||
import { CustomEmojiService } from '@/core/CustomEmojiService.js'; | ||
import { ModerationLogService } from '@/core/ModerationLogService.js'; | ||
import { MetaService } from '@/core/MetaService.js'; | ||
import { DriveService } from '@/core/DriveService.js'; | ||
import { ApiError } from '../../error.js'; | ||
|
||
export const meta = { | ||
|
||
requireCredential: true, | ||
requireRolePolicy: 'canRequestCustomEmojis', | ||
kind: 'write:admin:emoji', | ||
|
||
errors: { | ||
noSuchFile: { | ||
message: 'No such file.', | ||
code: 'NO_SUCH_FILE', | ||
id: 'fc46b5a4-6b92-4c33-ac66-b806659bb5cf', | ||
}, | ||
duplicateName: { | ||
message: 'Duplicate name.', | ||
code: 'DUPLICATE_NAME', | ||
id: 'f7a3462c-4e6e-4069-8421-b9bd4f4c3975', | ||
}, | ||
}, | ||
} as const; | ||
|
||
export const paramDef = { | ||
type: 'object', | ||
properties: { | ||
name: { type: 'string', pattern: '^[a-zA-Z0-9_]+$' }, | ||
category: { | ||
type: 'string', | ||
nullable: true, | ||
description: 'Use `null` to reset the category.', | ||
}, | ||
aliases: { type: 'array', items: { | ||
type: 'string', | ||
} }, | ||
license: { type: 'string', nullable: true }, | ||
isSensitive: { type: 'boolean', nullable: true }, | ||
localOnly: { type: 'boolean', nullable: true }, | ||
fileId: { type: 'string', format: 'misskey:id' }, | ||
isNotifyIsHome: { type: 'boolean', nullable: true }, | ||
}, | ||
required: ['name', 'fileId'], | ||
} as const; | ||
|
||
// TODO: ロジックをサービスに切り出す | ||
|
||
@Injectable() | ||
// eslint-disable-next-line import/no-default-export | ||
export default class extends Endpoint<typeof meta, typeof paramDef> { | ||
constructor( | ||
@Inject(DI.driveFilesRepository) | ||
private driveFilesRepository: DriveFilesRepository, | ||
private metaService: MetaService, | ||
private customEmojiService: CustomEmojiService, | ||
private driveService: DriveService, | ||
private moderationLogService: ModerationLogService, | ||
) { | ||
super(meta, paramDef, async (ps, me) => { | ||
const isDuplicate = await this.customEmojiService.checkDuplicate(ps.name); | ||
const isRequestDuplicate = await this.customEmojiService.checkRequestDuplicate(ps.name); | ||
|
||
if (isDuplicate || isRequestDuplicate) throw new ApiError(meta.errors.duplicateName); | ||
let driveFile; | ||
const tmp = await this.driveFilesRepository.findOneBy({ id: ps.fileId }); | ||
if (tmp == null) throw new ApiError(meta.errors.noSuchFile); | ||
|
||
try { | ||
driveFile = await this.driveService.uploadFromUrl({ url: tmp.url, user: null, force: true }); | ||
} catch (e) { | ||
throw new ApiError(); | ||
} | ||
if (driveFile == null) throw new ApiError(meta.errors.noSuchFile); | ||
const { ApiBase, EmojiBotToken, requestEmojiAllOk } = (await this.metaService.fetch()); | ||
let emoji; | ||
if (requestEmojiAllOk) { | ||
emoji = await this.customEmojiService.add({ | ||
driveFile, | ||
name: ps.name, | ||
category: ps.category ?? null, | ||
aliases: ps.aliases ?? [], | ||
license: ps.license ?? null, | ||
host: null, | ||
isSensitive: ps.isSensitive ?? false, | ||
localOnly: ps.localOnly ?? false, | ||
roleIdsThatCanBeUsedThisEmojiAsReaction: [], | ||
}, undefined, me); | ||
} else { | ||
emoji = await this.customEmojiService.request({ | ||
driveFile, | ||
name: ps.name, | ||
category: ps.category ?? null, | ||
aliases: ps.aliases ?? [], | ||
license: ps.license ?? null, | ||
isSensitive: ps.isSensitive ?? false, | ||
localOnly: ps.localOnly ?? false, | ||
}, me); | ||
} | ||
|
||
await this.moderationLogService.log(me, 'addCustomEmoji', { | ||
emojiId: emoji.id, | ||
emoji: emoji, | ||
}); | ||
|
||
if (EmojiBotToken) { | ||
const data_Miss = { | ||
'i': EmojiBotToken, | ||
'visibility': ps.isNotifyIsHome ? 'home' : 'public', | ||
'text': | ||
'絵文字名 : :' + ps.name + ':\n' + | ||
'カテゴリ : ' + ps.category + '\n' + | ||
'ライセンス : ' + ps.license + '\n' + | ||
'タグ : ' + ps.aliases + '\n' + | ||
'追加したユーザー : ' + '@' + me.username + '\n', | ||
}; | ||
await fetch(ApiBase + '/notes/create', { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify( data_Miss), | ||
}); | ||
} | ||
|
||
return { | ||
id: emoji.id, | ||
}; | ||
}); | ||
} | ||
} |
117 changes: 117 additions & 0 deletions
117
packages/backend/src/server/api/endpoints/emoji/update-request.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/* | ||
* SPDX-FileCopyrightText: syuilo and other misskey contributors | ||
* SPDX-License-Identifier: AGPL-3.0-only | ||
*/ | ||
|
||
import { Inject, Injectable } from '@nestjs/common'; | ||
import { Endpoint } from '@/server/api/endpoint-base.js'; | ||
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; | ||
import { CustomEmojiService } from '@/core/CustomEmojiService.js'; | ||
import type { DriveFilesRepository } from '@/models/_.js'; | ||
import { DI } from '@/di-symbols.js'; | ||
import { ApiError } from '../../error.js'; | ||
|
||
export const meta = { | ||
|
||
requireCredential: true, | ||
requireRolePolicy: 'canManageCustomEmojis', | ||
kind: 'write:admin:emoji', | ||
|
||
errors: { | ||
noSuchEmoji: { | ||
message: 'No such emoji.', | ||
code: 'NO_SUCH_EMOJI', | ||
id: '684dec9d-a8c2-4364-9aa8-456c49cb1dc8', | ||
}, | ||
noSuchFile: { | ||
message: 'No such file.', | ||
code: 'NO_SUCH_FILE', | ||
id: '14fb9fd9-0731-4e2f-aeb9-f09e4740333d', | ||
}, | ||
sameNameEmojiExists: { | ||
message: 'Emoji that have same name already exists.', | ||
code: 'SAME_NAME_EMOJI_EXISTS', | ||
id: '7180fe9d-1ee3-bff9-647d-fe9896d2ffb8', | ||
}, | ||
}, | ||
} as const; | ||
|
||
export const paramDef = { | ||
type: 'object', | ||
properties: { | ||
id: { type: 'string', format: 'misskey:id' }, | ||
name: { type: 'string', pattern: '^[a-zA-Z0-9_]+$' }, | ||
fileId: { type: 'string', format: 'misskey:id' }, | ||
category: { | ||
type: 'string', | ||
nullable: true, | ||
description: 'Use `null` to reset the category.', | ||
}, | ||
aliases: { type: 'array', items: { | ||
type: 'string', | ||
} }, | ||
license: { type: 'string', nullable: true }, | ||
isSensitive: { type: 'boolean' }, | ||
localOnly: { type: 'boolean' }, | ||
roleIdsThatCanBeUsedThisEmojiAsReaction: { type: 'array', items: { | ||
type: 'string', | ||
} }, | ||
Request: { type: 'boolean' }, | ||
}, | ||
required: ['id', 'name', 'aliases'], | ||
} as const; | ||
|
||
@Injectable() | ||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export | ||
constructor( | ||
@Inject(DI.driveFilesRepository) | ||
private driveFilesRepository: DriveFilesRepository, | ||
|
||
private customEmojiService: CustomEmojiService, | ||
private driveFileEntityService: DriveFileEntityService, | ||
) { | ||
super(meta, paramDef, async (ps, me) => { | ||
let driveFile; | ||
const isRequest = !!ps.Request; | ||
if (ps.fileId) { | ||
driveFile = await this.driveFilesRepository.findOneBy({ id: ps.fileId }); | ||
if (driveFile == null) throw new ApiError(meta.errors.noSuchFile); | ||
} | ||
|
||
const emoji = await this.customEmojiService.getEmojiRequestById(ps.id); | ||
if (emoji != null) { | ||
if (ps.name !== emoji.name) { | ||
const isDuplicate = await this.customEmojiService.checkRequestDuplicate(ps.name); | ||
if (isDuplicate) throw new ApiError(meta.errors.sameNameEmojiExists); | ||
} | ||
} else { | ||
throw new ApiError(meta.errors.noSuchEmoji); | ||
} | ||
if (!isRequest) { | ||
const file = await this.driveFileEntityService.getFromUrl(emoji.originalUrl); | ||
if (file === null) throw new ApiError(meta.errors.noSuchFile); | ||
await this.customEmojiService.add({ | ||
driveFile: file, | ||
name: ps.name, | ||
category: ps.category ?? null, | ||
aliases: ps.aliases ?? [], | ||
host: null, | ||
license: ps.license ?? null, | ||
isSensitive: ps.isSensitive ?? false, | ||
localOnly: ps.localOnly ?? false, | ||
roleIdsThatCanBeUsedThisEmojiAsReaction: [], | ||
}, me); | ||
await this.customEmojiService.deleteRequest(ps.id); | ||
} else { | ||
await this.customEmojiService.updateRequest(ps.id, { | ||
name: ps.name, | ||
category: ps.category ?? null, | ||
aliases: ps.aliases ?? [], | ||
license: ps.license ?? null, | ||
isSensitive: ps.isSensitive ?? false, | ||
localOnly: ps.localOnly ?? false, | ||
}, me); | ||
} | ||
}); | ||
} | ||
} |