Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Initial support for TTS functionality #14716

Draft
wants to merge 20 commits into
base: develop
Choose a base branch
from
20 changes: 20 additions & 0 deletions locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,14 @@ export interface Locale extends ILocale {
* にゃにゃにゃ??
*/
"flagAsCatDescription": string;
/**
* 自動TTS機能が欲しい。
*/
"flagAsVI": string;
/**
* 自動TTS機能が必要な場合は有効にしてください。 権限のあるユーザーグループに所属している場合、特定の範囲で自動TTS機能を有効にします。
*/
"flagAsVIDescription": string;
/**
* タイムラインにノートへの返信を表示する
*/
Expand Down Expand Up @@ -6863,6 +6871,10 @@ export interface Locale extends ILocale {
* 翻訳機能の利用
*/
"canUseTranslator": string;
/**
* TTS機能の利用
*/
"canUseTTS": string;
/**
* アイコンデコレーションの最大取付個数
*/
Expand Down Expand Up @@ -6909,6 +6921,10 @@ export interface Locale extends ILocale {
* botユーザー
*/
"isBot": string;
/**
* TTSユーザー
*/
"isVI": string;
/**
* サスペンド済みユーザー
*/
Expand Down Expand Up @@ -7300,6 +7316,10 @@ export interface Locale extends ILocale {
* Misskeyを翻訳
*/
"translation": string;
/**
* Misskeyを変換
*/
"convert": string;
/**
* Misskeyに寄付
*/
Expand Down
5 changes: 5 additions & 0 deletions locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ flagAsBot: "Botとして設定"
flagAsBotDescription: "このアカウントがプログラムによって運用される場合は、このフラグをオンにします。オンにすると、反応の連鎖を防ぐためのフラグとして他の開発者に役立ったり、Misskeyのシステム上での扱いがBotに合ったものになります。"
flagAsCat: "にゃああああああああああああああ!!!!!!!!!!!!"
flagAsCatDescription: "にゃにゃにゃ??"
flagAsVI: "自動TTS機能が欲しい。"
flagAsVIDescription: "自動TTS機能が必要な場合は有効にしてください。 権限のあるユーザーグループに所属している場合、特定の範囲で自動TTS機能を有効にします。"
flagShowTimelineReplies: "タイムラインにノートへの返信を表示する"
flagShowTimelineRepliesDescription: "オンにすると、タイムラインにユーザーのノート以外にもそのユーザーの他のノートへの返信を表示します。"
autoAcceptFollowed: "フォロー中ユーザーからのフォロリクを自動承認"
Expand Down Expand Up @@ -1773,6 +1775,7 @@ _role:
canHideAds: "広告の非表示"
canSearchNotes: "ノート検索の利用"
canUseTranslator: "翻訳機能の利用"
canUseTTS: "TTS機能の利用"
avatarDecorationLimit: "アイコンデコレーションの最大取付個数"
canImportAntennas: "アンテナのインポートを許可"
canImportBlocking: "ブロックのインポートを許可"
Expand All @@ -1785,6 +1788,7 @@ _role:
isRemote: "リモートユーザー"
isCat: "猫ユーザー"
isBot: "botユーザー"
isVI: "TTSユーザー"
isSuspended: "サスペンド済みユーザー"
isLocked: "鍵アカウントユーザー"
isExplorable: "「アカウントを見つけやすくする」が有効なユーザー"
Expand Down Expand Up @@ -1903,6 +1907,7 @@ _aboutMisskey:
original: "オリジナル"
thisIsModifiedVersion: "{name}はオリジナルのMisskeyを改変したバージョンを使用しています。"
translation: "Misskeyを翻訳"
convert: "Misskeyを変換"
donate: "Misskeyに寄付"
morePatrons: "他にも多くの方が支援してくれています。ありがとうございます🥰"
patrons: "支援者"
Expand Down
19 changes: 19 additions & 0 deletions packages/backend/migration/1724683952000-tts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/

export class TTSIntegration1724683952000 {
constructor() {
this.name = 'TTSIntegration1724683952000';
}

async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" ADD "hfAuthKey" character varying(128)`);
}

async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "hfAuthKey"`);
}
}

45 changes: 45 additions & 0 deletions packages/backend/migration/1724683962000-tts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/

export class TTSIntegration1724683962000 {
constructor() {
this.name = 'TTSIntegration1724683962000';
}

async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "user" ADD "isVI" boolean NOT NULL DEFAULT false`);
await queryRunner.query(`COMMENT ON COLUMN "user"."isVI" IS 'Whether the User needs auto TTS.'`);
await queryRunner.query(`ALTER TABLE "meta" ADD "hfSpace" boolean NOT NULL DEFAULT false`);
await queryRunner.query(`ALTER TABLE "meta" ADD "hfSpaceName" character varying(128)`);
await queryRunner.query(`ALTER TABLE "meta" ADD "hfexampleAudioURL" character varying(128)`);
await queryRunner.query(`ALTER TABLE "meta" ADD "hfexampleText" character varying(128)`);
await queryRunner.query(`ALTER TABLE "meta" ADD "hfexampleLang" character varying(128)`);
await queryRunner.query(`ALTER TABLE "meta" ADD "hfslice" character varying(128) DEFAULT 'Slice once every 4 sentences'`);
await queryRunner.query(`ALTER TABLE "meta" ADD "hftopK" INTEGER DEFAULT 15`);
await queryRunner.query(`ALTER TABLE "meta" ADD "hftopP" INTEGER DEFAULT 100`);
await queryRunner.query(`ALTER TABLE "meta" ADD "hfTemperature" INTEGER DEFAULT 100`);
await queryRunner.query(`ALTER TABLE "meta" ADD "hfnrm" boolean NOT NULL DEFAULT false`);
await queryRunner.query(`ALTER TABLE "meta" ADD "hfSpeedRate" INTEGER DEFAULT 125`);
await queryRunner.query(`ALTER TABLE "meta" ADD "hfdas" boolean NOT NULL DEFAULT false`);
}

async down(queryRunner) {
await queryRunner.query(`COMMENT ON COLUMN "user"."isVI" IS NULL`);
await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "isVI"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "hfSpace"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "hfSpaceName"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "hfexampleAudioURL"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "hfexampleText"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "hfexampleLang"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "hfslice"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "hftopK"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "hftopP"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "hfTemperature"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "hfnrm"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "hfSpeedRate"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "hfdas"`);
}
}

3 changes: 2 additions & 1 deletion packages/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
"@fastify/multipart": "9.0.1",
"@fastify/static": "8.0.1",
"@fastify/view": "10.0.1",
"@gradio/client": "1.6.0-beta.3",
"@misskey-dev/sharp-read-bmp": "1.2.0",
"@misskey-dev/summaly": "5.1.0",
"@napi-rs/canvas": "0.1.56",
Expand Down Expand Up @@ -132,8 +133,8 @@
"json5": "2.2.3",
"jsonld": "8.3.2",
"jsrsasign": "11.1.0",
"meilisearch": "0.42.0",
"juice": "11.0.0",
"meilisearch": "0.42.0",
"mfm-js": "0.24.0",
"microformats-parser": "2.0.2",
"mime-types": "2.1.35",
Expand Down
7 changes: 7 additions & 0 deletions packages/backend/src/core/RoleService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export type RolePolicies = {
canManageAvatarDecorations: boolean;
canSearchNotes: boolean;
canUseTranslator: boolean;
canUseTTS: boolean;
canHideAds: boolean;
driveCapacityMb: number;
alwaysMarkNsfw: boolean;
Expand Down Expand Up @@ -78,6 +79,7 @@ export const DEFAULT_POLICIES: RolePolicies = {
canManageAvatarDecorations: false,
canSearchNotes: false,
canUseTranslator: true,
canUseTTS: true,
canHideAds: false,
driveCapacityMb: 100,
alwaysMarkNsfw: false,
Expand Down Expand Up @@ -254,6 +256,10 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
case 'isCat': {
return user.isCat;
}
// Auto TTS
case 'isVI': {
return user.isVI;
}
// 「ユーザを見つけやすくする」が有効なアカウント
case 'isExplorable': {
return user.isExplorable;
Expand Down Expand Up @@ -381,6 +387,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
canManageAvatarDecorations: calc('canManageAvatarDecorations', vs => vs.some(v => v === true)),
canSearchNotes: calc('canSearchNotes', vs => vs.some(v => v === true)),
canUseTranslator: calc('canUseTranslator', vs => vs.some(v => v === true)),
canUseTTS: calc('canUseTTS', vs => vs.some(v => v === true)),
canHideAds: calc('canHideAds', vs => vs.some(v => v === true)),
driveCapacityMb: calc('driveCapacityMb', vs => Math.max(...vs)),
alwaysMarkNsfw: calc('alwaysMarkNsfw', vs => vs.some(v => v === true)),
Expand Down
2 changes: 2 additions & 0 deletions packages/backend/src/core/WebhookTestService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ function generateDummyUser(override?: Partial<MiUser>): MiUser {
isLocked: false,
isBot: false,
isCat: true,
isVI: false,
isRoot: false,
isExplorable: true,
isHibernated: false,
Expand Down Expand Up @@ -197,6 +198,7 @@ function toPackedUserLite(user: MiUser, override?: Packed<'UserLite'>): Packed<'
})),
isBot: user.isBot,
isCat: user.isCat,
isVI: user.isVI,
emojis: user.emojis,
onlineStatus: 'active',
badgeRoles: [],
Expand Down
1 change: 1 addition & 0 deletions packages/backend/src/core/entities/MetaEntityService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export class MetaEntityService {
enableServiceWorker: instance.enableServiceWorker,

translatorAvailable: instance.deeplAuthKey != null,
ttsAvailable: instance.hfAuthKey != null,

serverRules: instance.serverRules,

Expand Down
1 change: 1 addition & 0 deletions packages/backend/src/core/entities/UserEntityService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ export class UserEntityService implements OnModuleInit {
}))) : [],
isBot: user.isBot,
isCat: user.isCat,
isVI: user.isVI,
instance: user.host ? this.federatedInstanceService.federatedInstanceCache.fetch(user.host).then(instance => instance ? {
name: instance.name,
softwareName: instance.softwareName,
Expand Down
72 changes: 72 additions & 0 deletions packages/backend/src/models/Meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,78 @@ export class MiMeta {
})
public deeplIsPro: boolean;

@Column('varchar', {
length: 1024,
nullable: true,
})
public hfAuthKey: string | null;

@Column('boolean', {
default: false,
})
public hfSpace: boolean;

@Column('varchar', {
length: 1024,
nullable: true,
})
public hfSpaceName: string | null;

@Column('varchar', {
length: 1024,
nullable: true,
})
public hfexampleAudioURL: string | null;

@Column('varchar', {
length: 1024,
nullable: true,
})
public hfexampleText: string | null;

@Column('varchar', {
length: 1024,
nullable: true,
})
public hfexampleLang: string | null;

@Column('varchar', {
length: 1024,
default: 'Slice once every 4 sentences',
nullable: true,
})
public hfslice: string | null;

@Column('integer', {
default: 15,
})
public hftopK: number;

@Column('integer', {
default: 100,
})
public hftopP: number;

@Column('integer', {
default: 100,
})
public hfTemperature: number;

@Column('boolean', {
default: false,
})
public hfnrm: boolean;

@Column('integer', {
default: 125,
})
public hfSpeedRate: number;

@Column('boolean', {
default: false,
})
public hfdas: boolean;

@Column('varchar', {
length: 1024,
nullable: true,
Expand Down
8 changes: 8 additions & 0 deletions packages/backend/src/models/Role.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ type CondFormulaValueIsCat = {
type: 'isCat';
};

/**
* Auto TTS
*/
type CondFormulaValueIsVI = {
type: 'isVI';
};

/**
* 「ユーザを見つけやすくする」が有効なアカウントの場合のみ成立とする
*/
Expand Down Expand Up @@ -164,6 +171,7 @@ export type RoleCondFormulaValue = { id: string } & (
CondFormulaValueIsLocked |
CondFormulaValueIsBot |
CondFormulaValueIsCat |
CondFormulaValueIsVI |
CondFormulaValueIsExplorable |
CondFormulaValueRoleAssignedTo |
CondFormulaValueCreatedLessThan |
Expand Down
6 changes: 6 additions & 0 deletions packages/backend/src/models/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,12 @@ export class MiUser {
})
public isCat: boolean;

@Column('boolean', {
default: false,
comment: 'Whether the User needs auto TTS.',
})
public isVI: boolean;

@Column('boolean', {
default: false,
comment: 'Whether the User is the root.',
Expand Down
4 changes: 4 additions & 0 deletions packages/backend/src/models/json-schema/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ export const packedMetaLiteSchema = {
type: 'boolean',
optional: false, nullable: false,
},
ttsAvailable: {
type: 'boolean',
optional: false, nullable: false,
},
mediaProxy: {
type: 'string',
optional: false, nullable: false,
Expand Down
6 changes: 5 additions & 1 deletion packages/backend/src/models/json-schema/role.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const packedRoleCondFormulaValueUserSettingBooleanSchema = {
type: {
type: 'string',
nullable: false, optional: false,
enum: ['isSuspended', 'isLocked', 'isBot', 'isCat', 'isExplorable'],
enum: ['isSuspended', 'isLocked', 'isBot', 'isCat', 'isVI', 'isExplorable'],
},
},
} as const;
Expand Down Expand Up @@ -216,6 +216,10 @@ export const packedRolePoliciesSchema = {
type: 'boolean',
optional: false, nullable: false,
},
canUseTTS: {
type: 'boolean',
optional: false, nullable: false,
},
canHideAds: {
type: 'boolean',
optional: false, nullable: false,
Expand Down
4 changes: 4 additions & 0 deletions packages/backend/src/models/json-schema/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ export const packedUserLiteSchema = {
type: 'boolean',
nullable: false, optional: true,
},
isVI: {
type: 'boolean',
nullable: false, optional: true,
},
instance: {
type: 'object',
nullable: false, optional: true,
Expand Down
Loading
Loading