This commit is contained in:
MomentQYC 2024-08-30 14:26:28 +08:00
parent 44f62160cb
commit a481f00cab
24 changed files with 406 additions and 4 deletions

View file

@ -301,6 +301,7 @@ import * as ep___notes_threadMuting_create from './endpoints/notes/thread-muting
import * as ep___notes_threadMuting_delete from './endpoints/notes/thread-muting/delete.js';
import * as ep___notes_timeline from './endpoints/notes/timeline.js';
import * as ep___notes_translate from './endpoints/notes/translate.js';
import * as ep___notes_tts from './endpoints/notes/tts.js';
import * as ep___notes_unrenote from './endpoints/notes/unrenote.js';
import * as ep___notes_userListTimeline from './endpoints/notes/user-list-timeline.js';
import * as ep___notifications_create from './endpoints/notifications/create.js';
@ -684,6 +685,7 @@ const $notes_threadMuting_create: Provider = { provide: 'ep:notes/thread-muting/
const $notes_threadMuting_delete: Provider = { provide: 'ep:notes/thread-muting/delete', useClass: ep___notes_threadMuting_delete.default };
const $notes_timeline: Provider = { provide: 'ep:notes/timeline', useClass: ep___notes_timeline.default };
const $notes_translate: Provider = { provide: 'ep:notes/translate', useClass: ep___notes_translate.default };
const $notes_tts: Provider = { provide: 'ep:notes/tts', useClass: ep___notes_tts.default };
const $notes_unrenote: Provider = { provide: 'ep:notes/unrenote', useClass: ep___notes_unrenote.default };
const $notes_userListTimeline: Provider = { provide: 'ep:notes/user-list-timeline', useClass: ep___notes_userListTimeline.default };
const $notifications_create: Provider = { provide: 'ep:notifications/create', useClass: ep___notifications_create.default };
@ -1071,6 +1073,7 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__
$notes_threadMuting_delete,
$notes_timeline,
$notes_translate,
$notes_tts,
$notes_unrenote,
$notes_userListTimeline,
$notifications_create,
@ -1452,6 +1455,7 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__
$notes_threadMuting_delete,
$notes_timeline,
$notes_translate,
$notes_tts,
$notes_unrenote,
$notes_userListTimeline,
$notifications_create,

View file

@ -307,6 +307,7 @@ import * as ep___notes_threadMuting_create from './endpoints/notes/thread-muting
import * as ep___notes_threadMuting_delete from './endpoints/notes/thread-muting/delete.js';
import * as ep___notes_timeline from './endpoints/notes/timeline.js';
import * as ep___notes_translate from './endpoints/notes/translate.js';
import * as ep___notes_tts from './endpoints/notes/tts.js';
import * as ep___notes_unrenote from './endpoints/notes/unrenote.js';
import * as ep___notes_userListTimeline from './endpoints/notes/user-list-timeline.js';
import * as ep___notifications_create from './endpoints/notifications/create.js';
@ -688,6 +689,7 @@ const eps = [
['notes/thread-muting/delete', ep___notes_threadMuting_delete],
['notes/timeline', ep___notes_timeline],
['notes/translate', ep___notes_translate],
['notes/tts', ep___notes_tts],
['notes/unrenote', ep___notes_unrenote],
['notes/user-list-timeline', ep___notes_userListTimeline],
['notifications/create', ep___notifications_create],

View file

@ -118,6 +118,10 @@ export const meta = {
type: 'boolean',
optional: false, nullable: false,
},
ttsAvailable: {
type: 'boolean',
optional: false, nullable: false,
},
silencedHosts: {
type: 'array',
optional: true,
@ -556,6 +560,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
enableEmail: instance.enableEmail,
enableServiceWorker: instance.enableServiceWorker,
translatorAvailable: instance.deeplAuthKey != null,
ttsAvailable: instance.hfAuthKey != null,
cacheRemoteFiles: instance.cacheRemoteFiles,
cacheRemoteSensitiveFiles: instance.cacheRemoteSensitiveFiles,
pinnedUsers: instance.pinnedUsers,

View file

@ -92,6 +92,7 @@ export const paramDef = {
},
deeplAuthKey: { type: 'string', nullable: true },
deeplIsPro: { type: 'boolean' },
hfAuthKey: { type: 'string', nullable: true },
enableEmail: { type: 'boolean' },
email: { type: 'string', nullable: true },
smtpSecure: { type: 'boolean' },
@ -506,6 +507,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
set.deeplIsPro = ps.deeplIsPro;
}
if (ps.hfAuthKey !== undefined) {
if (ps.hfAuthKey === '') {
set.hfAuthKey = null;
} else {
set.hfAuthKey = ps.hfAuthKey;
}
}
if (ps.enableIpLogging !== undefined) {
set.enableIpLogging = ps.enableIpLogging;
}

View file

@ -0,0 +1,109 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { MetaService } from '@/core/MetaService.js';
import { HttpRequestService } from '@/core/HttpRequestService.js';
import { GetterService } from '@/server/api/GetterService.js';
import { RoleService } from '@/core/RoleService.js';
import { ApiError } from '../../error.js';
export const meta = {
tags: ['notes'],
requireCredential: true,
kind: 'read:account',
res: {
type: 'string',
optional: true, nullable: false,
contentMediaType: 'audio/flac',
},
errors: {
unavailable: {
message: 'Convert of notes unavailable.',
code: 'UNAVAILABLE',
id: '97a0826c-6393-11ef-a650-67972d710975',
},
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: 'bea9b03f-36e0-49c5-a4db-627a029f8971',
},
cannotConvertInvisibleNote: {
message: 'Cannot convert invisible note.',
code: 'CANNOT_CONVERT_INVISIBLE_NOTE',
id: 'f57caae0-6394-11ef-8e2a-d706932c1030',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
noteId: { type: 'string', format: 'misskey:id' },
},
required: ['noteId'],
} as const;
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
constructor(
private noteEntityService: NoteEntityService,
private getterService: GetterService,
private metaService: MetaService,
private httpRequestService: HttpRequestService,
private roleService: RoleService,
) {
super(meta, paramDef, async (ps, me) => {
const policies = await this.roleService.getUserPolicies(me.id);
if (!policies.canUseTTS) {
throw new ApiError(meta.errors.unavailable);
}
const note = await this.getterService.getNote(ps.noteId).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
throw err;
});
if (!(await this.noteEntityService.isVisibleForMe(note, me.id))) {
throw new ApiError(meta.errors.cannotConvertInvisibleNote);
}
if (note.text == null) {
return;
}
const instance = await this.metaService.fetch();
if (instance.hfAuthKey == null) {
throw new ApiError(meta.errors.unavailable);
}
const endpoint = 'https://api-inference.huggingface.co/models/suno/bark';
const res = await this.httpRequestService.send(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + instance.hfAuthKey,
},
body: JSON.stringify({
inputs: note.text,
}),
timeout: 60000,
});
if (res.headers.get('content-type') === 'audio/flac') {
return res.body;
} else {
throw new ApiError(meta.errors.unavailable);
}
});
}
}