parent
e5c060eecf
commit
c6e3ec07d1
7 changed files with 103 additions and 14 deletions
18
packages/backend/migration/1706232992000-deeplx.js
Normal file
18
packages/backend/migration/1706232992000-deeplx.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and other misskey contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
export class Deeplx1706232992000 {
|
||||||
|
name = 'Deeplx1706232992000';
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "deeplFreeMode" boolean NOT NULL DEFAULT false`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "deeplFreeInstance" character varying(1024)`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "deeplFreeMode"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "deeplFreeInstance"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -353,6 +353,17 @@ export class MiMeta {
|
||||||
})
|
})
|
||||||
public deeplIsPro: boolean;
|
public deeplIsPro: boolean;
|
||||||
|
|
||||||
|
@Column('boolean', {
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
public deeplFreeMode: boolean;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 1024,
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
public deeplFreeInstance: string | null;
|
||||||
|
|
||||||
@Column('varchar', {
|
@Column('varchar', {
|
||||||
length: 1024,
|
length: 1024,
|
||||||
nullable: true,
|
nullable: true,
|
||||||
|
|
|
@ -395,6 +395,14 @@ export const meta = {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
|
deeplFreeMode: {
|
||||||
|
type: 'boolean',
|
||||||
|
optional: false, nullable: false,
|
||||||
|
},
|
||||||
|
deeplFreeInstance: {
|
||||||
|
type: 'string',
|
||||||
|
optional: false, nullable: true,
|
||||||
|
},
|
||||||
defaultDarkTheme: {
|
defaultDarkTheme: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: false, nullable: true,
|
optional: false, nullable: true,
|
||||||
|
@ -576,6 +584,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
objectStorageS3ForcePathStyle: instance.objectStorageS3ForcePathStyle,
|
objectStorageS3ForcePathStyle: instance.objectStorageS3ForcePathStyle,
|
||||||
deeplAuthKey: instance.deeplAuthKey,
|
deeplAuthKey: instance.deeplAuthKey,
|
||||||
deeplIsPro: instance.deeplIsPro,
|
deeplIsPro: instance.deeplIsPro,
|
||||||
|
deeplFreeMode: instance.deeplFreeMode,
|
||||||
|
deeplFreeInstance: instance.deeplFreeInstance,
|
||||||
enableIpLogging: instance.enableIpLogging,
|
enableIpLogging: instance.enableIpLogging,
|
||||||
enableActiveEmailValidation: instance.enableActiveEmailValidation,
|
enableActiveEmailValidation: instance.enableActiveEmailValidation,
|
||||||
enableVerifymailApi: instance.enableVerifymailApi,
|
enableVerifymailApi: instance.enableVerifymailApi,
|
||||||
|
|
|
@ -91,6 +91,8 @@ export const paramDef = {
|
||||||
summalyProxy: { type: 'string', nullable: true },
|
summalyProxy: { type: 'string', nullable: true },
|
||||||
deeplAuthKey: { type: 'string', nullable: true },
|
deeplAuthKey: { type: 'string', nullable: true },
|
||||||
deeplIsPro: { type: 'boolean' },
|
deeplIsPro: { type: 'boolean' },
|
||||||
|
deeplFreeMode: { type: 'boolean' },
|
||||||
|
deeplFreeInstance: { type: 'string', nullable: true },
|
||||||
enableEmail: { type: 'boolean' },
|
enableEmail: { type: 'boolean' },
|
||||||
email: { type: 'string', nullable: true },
|
email: { type: 'string', nullable: true },
|
||||||
smtpSecure: { type: 'boolean' },
|
smtpSecure: { type: 'boolean' },
|
||||||
|
@ -479,6 +481,18 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
set.deeplIsPro = ps.deeplIsPro;
|
set.deeplIsPro = ps.deeplIsPro;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ps.deeplFreeMode !== undefined) {
|
||||||
|
set.deeplFreeMode = ps.deeplFreeMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ps.deeplFreeInstance !== undefined) {
|
||||||
|
if (ps.deeplFreeInstance === '') {
|
||||||
|
set.deeplFreeInstance = null;
|
||||||
|
} else {
|
||||||
|
set.deeplFreeInstance = ps.deeplFreeInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ps.enableIpLogging !== undefined) {
|
if (ps.enableIpLogging !== undefined) {
|
||||||
set.enableIpLogging = ps.enableIpLogging;
|
set.enableIpLogging = ps.enableIpLogging;
|
||||||
}
|
}
|
||||||
|
|
|
@ -411,7 +411,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
enableEmail: instance.enableEmail,
|
enableEmail: instance.enableEmail,
|
||||||
enableServiceWorker: instance.enableServiceWorker,
|
enableServiceWorker: instance.enableServiceWorker,
|
||||||
|
|
||||||
translatorAvailable: instance.deeplAuthKey != null,
|
translatorAvailable: instance.deeplAuthKey != null || instance.deeplFreeMode && instance.deeplFreeInstance,
|
||||||
|
|
||||||
serverRules: instance.serverRules,
|
serverRules: instance.serverRules,
|
||||||
|
|
||||||
|
|
|
@ -81,19 +81,23 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
|
|
||||||
const instance = await this.metaService.fetch();
|
const instance = await this.metaService.fetch();
|
||||||
|
|
||||||
if (instance.deeplAuthKey == null) {
|
if (instance.deeplAuthKey == null && !instance.deeplFreeMode) {
|
||||||
return 204; // TODO: 良い感じのエラー返す
|
return 204; // TODO: 良い感じのエラー返す
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (instance.deeplFreeMode && !instance.deeplFreeInstance) {
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
let targetLang = ps.targetLang;
|
let targetLang = ps.targetLang;
|
||||||
if (targetLang.includes('-')) targetLang = targetLang.split('-')[0];
|
if (targetLang.includes('-')) targetLang = targetLang.split('-')[0];
|
||||||
|
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
params.append('auth_key', instance.deeplAuthKey);
|
if (instance.deeplAuthKey) params.append('auth_key', instance.deeplAuthKey);
|
||||||
params.append('text', note.text);
|
params.append('text', note.text);
|
||||||
params.append('target_lang', targetLang);
|
params.append('target_lang', targetLang);
|
||||||
|
|
||||||
const endpoint = instance.deeplIsPro ? 'https://api.deepl.com/v2/translate' : 'https://api-free.deepl.com/v2/translate';
|
const endpoint = instance.deeplFreeMode && instance.deeplFreeInstance ? `https://${instance.deeplFreeInstance}` : instance.deeplIsPro ? 'https://api.deepl.com/v2/translate' : 'https://api-free.deepl.com/v2/translate';
|
||||||
|
|
||||||
const res = await this.httpRequestService.send(endpoint, {
|
const res = await this.httpRequestService.send(endpoint, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
@ -103,7 +107,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
},
|
},
|
||||||
body: params.toString(),
|
body: params.toString(),
|
||||||
});
|
});
|
||||||
|
if (instance.deeplAuthKey) {
|
||||||
const json = (await res.json()) as {
|
const json = (await res.json()) as {
|
||||||
translations: {
|
translations: {
|
||||||
detected_source_language: string;
|
detected_source_language: string;
|
||||||
|
@ -115,6 +119,25 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
sourceLang: json.translations[0].detected_source_language,
|
sourceLang: json.translations[0].detected_source_language,
|
||||||
text: json.translations[0].text,
|
text: json.translations[0].text,
|
||||||
};
|
};
|
||||||
|
} else {
|
||||||
|
const json = (await res.json()) as {
|
||||||
|
code: number,
|
||||||
|
message: string,
|
||||||
|
data: string,
|
||||||
|
source_lang: string,
|
||||||
|
target_lang: string,
|
||||||
|
alternatives: string[],
|
||||||
|
};
|
||||||
|
|
||||||
|
const languageNames = new Intl.DisplayNames(['en'], {
|
||||||
|
type: 'language',
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
sourceLang: languageNames.of(json.source_lang),
|
||||||
|
text: json.data,
|
||||||
|
};
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,13 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkSwitch v-model="deeplIsPro">
|
<MkSwitch v-model="deeplIsPro">
|
||||||
<template #label>Pro account</template>
|
<template #label>Pro account</template>
|
||||||
</MkSwitch>
|
</MkSwitch>
|
||||||
|
<MkSwitch v-model="deeplFreeMode">
|
||||||
|
<template #label>Use DeepLX-JS (No Auth Key)</template>
|
||||||
|
</MkSwitch>
|
||||||
|
<MkInput v-if="deeplFreeMode" v-model="deeplFreeInstance" :placeholder="'example.com/translate'">
|
||||||
|
<template #prefix>https://</template>
|
||||||
|
<template #label>DeepLX-JS URL</template>
|
||||||
|
</MkInput>
|
||||||
</div>
|
</div>
|
||||||
</FormSection>
|
</FormSection>
|
||||||
</FormSuspense>
|
</FormSuspense>
|
||||||
|
@ -49,17 +56,23 @@ import { definePageMetadata } from '@/scripts/page-metadata.js';
|
||||||
|
|
||||||
const deeplAuthKey = ref<string>('');
|
const deeplAuthKey = ref<string>('');
|
||||||
const deeplIsPro = ref<boolean>(false);
|
const deeplIsPro = ref<boolean>(false);
|
||||||
|
const deeplFreeMode = ref<boolean>(false);
|
||||||
|
const deeplFreeInstance = ref<string>('');
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
const meta = await misskeyApi('admin/meta');
|
const meta = await misskeyApi('admin/meta');
|
||||||
deeplAuthKey.value = meta.deeplAuthKey;
|
deeplAuthKey.value = meta.deeplAuthKey;
|
||||||
deeplIsPro.value = meta.deeplIsPro;
|
deeplIsPro.value = meta.deeplIsPro;
|
||||||
|
deeplFreeMode.value = meta.deeplFreeMode;
|
||||||
|
deeplFreeInstance.value = meta.deeplFreeInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
function save() {
|
function save() {
|
||||||
os.apiWithDialog('admin/update-meta', {
|
os.apiWithDialog('admin/update-meta', {
|
||||||
deeplAuthKey: deeplAuthKey.value,
|
deeplAuthKey: deeplAuthKey.value,
|
||||||
deeplIsPro: deeplIsPro.value,
|
deeplIsPro: deeplIsPro.value,
|
||||||
|
deeplFreeMode: deeplFreeMode.value,
|
||||||
|
deeplFreeInstance: deeplFreeInstance.value,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
fetchInstance();
|
fetchInstance();
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue