GlobalFetch 리팩토링, Elevenlabs 다국어모델 정보 body에 삽입, DeepLX 로직구현(미작동) (#328)
# PR Checklist - [x] Did you check if it works normally in all models? *ignore this when it dosen't uses models* - [ ] Did you check if it works normally in all of web, local and node hosted versions? if it dosen't, did you blocked it in those versions? - [ ] Did you added a type def? # Description 1. DeepLX 를 번역 옵션에 넣고 URL, Token을 넣을 수 있게 하였습니다. 2. DeepLX 를 호출하는 로직을 넣었는데, DeepLX의 Body 중 Text는 완전한 텍스트로만 이루어져야 해서 번역 실행시 에러가 발생하는 중입니다. (DeepLX에 globalFetech로 호출은 정상적으로 가는중, body의 text타입만 해결하면 작동,) 3. TTS -> 일레븐랩스 호출시 body에 model을 다국어모델로 지정하였습니다. (정상작동) 4. globalFetch 함수를 리팩토링 하였습니다. DeepLX 쪽만 해결방법을 찾으면 좋을 것 같은데 로직이 제가 생각한 것과 달라서 파악하는데 시간이 오래걸리고 있습니다. DeepLX 부분 저도 더 로직 분석해볼 예정이지만, Body 부분에서 특수문자 제거 및 본문 텍스트만 파싱해서 번역 후 재조립하는 게 구현 가능하시다면 해당 부분만 업데이트 해주시면 좋을 것 같습니다.
This commit is contained in:
@@ -391,6 +391,8 @@ export const languageChinese = {
|
||||
"translatorType": "翻译类型",
|
||||
"deeplKey": "deepl API密钥",
|
||||
"deeplFreeKey": "deepl 免费 API密钥",
|
||||
"deeplXUrl": "deepLX URL",
|
||||
"deeplXToken": "deepLX Token",
|
||||
"exportPersona": "导出角色",
|
||||
"importPersona": "导入角色",
|
||||
"export": "导出",
|
||||
|
||||
@@ -421,6 +421,8 @@ export const languageGerman = {
|
||||
translatorType: "Übersetzer-Typ",
|
||||
deeplKey: "DeepL API-Schlüssel",
|
||||
deeplFreeKey: "DeepL Gratis API-Schlüssel",
|
||||
deeplXUrl: "deepLX URL",
|
||||
deeplXToken: "deepLX Token",
|
||||
exportPersona: "Profil exportieren",
|
||||
importPersona: "Profil importieren",
|
||||
export: "Exportieren",
|
||||
|
||||
@@ -456,6 +456,8 @@ export const languageEnglish = {
|
||||
translatorType: "Translator Type",
|
||||
deeplKey: "deepL API Key",
|
||||
deeplFreeKey: "deepL Free API Key",
|
||||
deeplXUrl: "deepLX URL",
|
||||
deeplXToken: "deepLX Token",
|
||||
exportPersona: "Export Persona",
|
||||
importPersona: "Import Persona",
|
||||
export: "Export",
|
||||
|
||||
@@ -394,6 +394,8 @@ export const languageKorean = {
|
||||
translatorType: "번역기 타입",
|
||||
deeplKey: "deepL API 키",
|
||||
deeplFreeKey: "deepL 무료 API 키",
|
||||
deeplXUrl: "deepLX URL",
|
||||
deeplXToken: "deepLX Token",
|
||||
exportPersona: "페르소나 엑스포트",
|
||||
importPersona: "페르소나 임포트",
|
||||
export: "엑스포트",
|
||||
|
||||
@@ -392,6 +392,8 @@ export const LanguageVietnamese = {
|
||||
"translatorType": "Loại dịch giả",
|
||||
"deeplKey": "Khóa API deepL",
|
||||
"deeplFreeKey": "Khóa API miễn phí deepL",
|
||||
"deeplXUrl": "deepLX URL",
|
||||
"deeplXToken": "deepLX Token",
|
||||
"exportPersona": "Xuất khẩu nhân vật",
|
||||
"importPersona": "Nhập khẩu nhân vật",
|
||||
"export": "Xuất khẩu",
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
<OptionInput value="google" >Google</OptionInput>
|
||||
<OptionInput value="deepl" >DeepL</OptionInput>
|
||||
<OptionInput value="llm" >Ax. Model</OptionInput>
|
||||
<OptionInput value="deeplX" >DeepL X</OptionInput>
|
||||
</SelectInput>
|
||||
|
||||
{#if $DataBase.translatorType === 'deepl'}
|
||||
@@ -71,6 +72,14 @@
|
||||
<Check bind:check={$DataBase.deeplOptions.freeApi} name={language.deeplFreeKey}/>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if $DataBase.translatorType === 'deeplX'}
|
||||
<span class="text-textcolor mt-4">{language.deeplXUrl}</span>
|
||||
<TextInput bind:value={$DataBase.deeplXOptions.url} />
|
||||
|
||||
<span class="text-textcolor mt-4">{language.deeplXToken}</span>
|
||||
<TextInput bind:value={$DataBase.deeplXOptions.token} />
|
||||
{/if}
|
||||
|
||||
{#if $DataBase.translatorType === 'llm'}
|
||||
<span class="text-textcolor mt-4">{language.translationPrompt}</span>
|
||||
|
||||
@@ -56,7 +56,8 @@ export async function sayTTS(character:character,text:string) {
|
||||
const audioContext = new AudioContext();
|
||||
const da = await fetch(`https://api.elevenlabs.io/v1/text-to-speech/${character.ttsSpeech}`, {
|
||||
body: JSON.stringify({
|
||||
text: text
|
||||
text: text,
|
||||
model_id: "eleven_multilingual_v2"
|
||||
}),
|
||||
method: "POST",
|
||||
headers: {
|
||||
|
||||
@@ -332,6 +332,10 @@ export function setDatabase(data:Database){
|
||||
key:'',
|
||||
freeApi: false
|
||||
}
|
||||
data.deeplXOptions ??= {
|
||||
url:'',
|
||||
token:''
|
||||
}
|
||||
data.NAIadventure ??= false
|
||||
data.NAIappendName ??= true
|
||||
data.NAIsettings.cfg_scale ??= 1
|
||||
@@ -555,13 +559,17 @@ export interface Database{
|
||||
mancerHeader:string
|
||||
emotionProcesser:'submodel'|'embedding',
|
||||
showMenuChatList?:boolean,
|
||||
translatorType:'google'|'deepl'|'none'|'llm',
|
||||
translatorType:'google'|'deepl'|'none'|'llm'|'deeplX',
|
||||
NAIadventure?:boolean,
|
||||
NAIappendName?:boolean,
|
||||
deeplOptions:{
|
||||
key:string,
|
||||
freeApi:boolean
|
||||
}
|
||||
deeplXOptions:{
|
||||
url:string,
|
||||
token:string
|
||||
}
|
||||
localStopStrings?:string[]
|
||||
autofillRequestUrl:boolean
|
||||
customProxyRequestModel:string
|
||||
|
||||
@@ -488,335 +488,211 @@ export async function loadData() {
|
||||
}
|
||||
}
|
||||
|
||||
const knownHostes = ["localhost","127.0.0.1"]
|
||||
export async function getFetchData(id:string) {
|
||||
for(const log of fetchLog){
|
||||
if(log.chatId === id){
|
||||
return log
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
const knownHostes = ["localhost","127.0.0.1","0.0.0.0"]
|
||||
|
||||
interface GlobalFetchArgs {
|
||||
plainFetchForce?: boolean;
|
||||
body?: any;
|
||||
headers?: { [key: string]: string };
|
||||
rawResponse?: boolean;
|
||||
method?: 'POST' | 'GET';
|
||||
abortSignal?: AbortSignal;
|
||||
useRisuToken?: boolean;
|
||||
chatId?: string;
|
||||
}
|
||||
|
||||
interface GlobalFetchResult {
|
||||
ok: boolean;
|
||||
data: any;
|
||||
headers: { [key: string]: string };
|
||||
}
|
||||
|
||||
export function addFetchLog(arg:{
|
||||
body:any,
|
||||
headers?:{[key:string]:string},
|
||||
response:any,
|
||||
success:boolean,
|
||||
url:string,
|
||||
resType?:string,
|
||||
chatId?:string
|
||||
body:any,
|
||||
headers?:{[key:string]:string},
|
||||
response:any,
|
||||
success:boolean,
|
||||
url:string,
|
||||
resType?:string,
|
||||
chatId?:string
|
||||
}){
|
||||
fetchLog.unshift({
|
||||
body: typeof(arg.body) === 'string' ? arg.body : JSON.stringify(arg.body, null, 2),
|
||||
header: JSON.stringify(arg.headers ?? {}, null, 2),
|
||||
response: typeof(arg.response) === 'string' ? arg.response : JSON.stringify(arg.response, null, 2),
|
||||
responseType: arg.resType ?? 'json',
|
||||
success: arg.success,
|
||||
date: (new Date()).toLocaleTimeString(),
|
||||
url: arg.url,
|
||||
chatId: arg.chatId
|
||||
})
|
||||
return fetchLog.length - 1
|
||||
fetchLog.unshift({
|
||||
body: typeof(arg.body) === 'string' ? arg.body : JSON.stringify(arg.body, null, 2),
|
||||
header: JSON.stringify(arg.headers ?? {}, null, 2),
|
||||
response: typeof(arg.response) === 'string' ? arg.response : JSON.stringify(arg.response, null, 2),
|
||||
responseType: arg.resType ?? 'json',
|
||||
success: arg.success,
|
||||
date: (new Date()).toLocaleTimeString(),
|
||||
url: arg.url,
|
||||
chatId: arg.chatId
|
||||
})
|
||||
return fetchLog.length - 1
|
||||
}
|
||||
|
||||
export async function getFetchData(id:string) {
|
||||
for(const log of fetchLog){
|
||||
if(log.chatId === id){
|
||||
return log
|
||||
}
|
||||
|
||||
|
||||
export async function globalFetch(url: string, arg: GlobalFetchArgs = {}): Promise<GlobalFetchResult> {
|
||||
try {
|
||||
const db = get(DataBase)
|
||||
const method = arg.method ?? "POST"
|
||||
db.requestmet = "normal"
|
||||
|
||||
if (arg.abortSignal?.aborted) { return { ok: false, data: 'aborted', headers: {} }}
|
||||
|
||||
const urlHost = new URL(url).hostname
|
||||
const forcePlainFetch = (knownHostes.includes(urlHost) && !isTauri) || db.usePlainFetch || arg.plainFetchForce
|
||||
|
||||
if (knownHostes.includes(urlHost) && !isTauri && !isNodeServer)
|
||||
return { ok: false, headers: {}, data: 'You are trying local request on web version. This is not allowed due to browser security policy. Use the desktop version instead, or use a tunneling service like ngrok and set the CORS to allow all.' }
|
||||
|
||||
// Simplify the globalFetch function: Detach built-in functions
|
||||
if (forcePlainFetch) {
|
||||
return await fetchWithPlainFetch(url, arg);
|
||||
}
|
||||
if (isTauri) {
|
||||
return await fetchWithTauri(url, arg);
|
||||
}
|
||||
if (Capacitor.isNativePlatform()) {
|
||||
return await fetchWithCapacitor(url, arg);
|
||||
}
|
||||
return await fetchWithProxy(url, arg);
|
||||
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return { ok: false, data: `${error}`, headers: {} };
|
||||
}
|
||||
}
|
||||
|
||||
// Decoupled globalFetch built-in function
|
||||
function addFetchLogInGlobalFetch(response:any, success:boolean, url:string, arg:GlobalFetchArgs){
|
||||
try{
|
||||
fetchLog.unshift({
|
||||
body: JSON.stringify(arg.body, null, 2),
|
||||
header: JSON.stringify(arg.headers ?? {}, null, 2),
|
||||
response: JSON.stringify(response, null, 2),
|
||||
success: success,
|
||||
date: (new Date()).toLocaleTimeString(),
|
||||
url: url,
|
||||
chatId: arg.chatId
|
||||
})
|
||||
}
|
||||
catch{
|
||||
fetchLog.unshift({
|
||||
body: JSON.stringify(arg.body, null, 2),
|
||||
header: JSON.stringify(arg.headers ?? {}, null, 2),
|
||||
response: `${response}`,
|
||||
success: success,
|
||||
date: (new Date()).toLocaleTimeString(),
|
||||
url: url,
|
||||
chatId: arg.chatId
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Decoupled globalFetch built-in function
|
||||
async function fetchWithPlainFetch(url: string, arg: GlobalFetchArgs): Promise<GlobalFetchResult> {
|
||||
try {
|
||||
const headers = { 'Content-Type': 'application/json', ...arg.headers };
|
||||
const response = await fetch(new URL(url), { body: JSON.stringify(arg.body), headers, method: arg.method, signal: arg.abortSignal });
|
||||
const data = arg.rawResponse ? new Uint8Array(await response.arrayBuffer()) : await response.json();
|
||||
const ok = response.ok && response.status >= 200 && response.status < 300;
|
||||
addFetchLogInGlobalFetch(data, ok, url, arg);
|
||||
return { ok, data, headers: Object.fromEntries(response.headers) };
|
||||
} catch (error) {
|
||||
return { ok: false, data: `${error}`, headers: {} };
|
||||
}
|
||||
}
|
||||
|
||||
// Decoupled globalFetch built-in function
|
||||
async function fetchWithTauri(url: string, arg: GlobalFetchArgs): Promise<GlobalFetchResult> {
|
||||
const body = !arg.body ? null : arg.body instanceof URLSearchParams ? Body.text(arg.body.toString()) : Body.json(arg.body);
|
||||
const headers = arg.headers ?? {};
|
||||
const fetchPromise = TauriFetch(url, {
|
||||
body,
|
||||
method: arg.method,
|
||||
headers,
|
||||
timeout: { secs: get(DataBase).timeOut, nanos: 0 },
|
||||
responseType: arg.rawResponse ? ResponseType.Binary : ResponseType.JSON,
|
||||
});
|
||||
|
||||
let abortFn = () => {};
|
||||
const abortPromise = new Promise<"aborted">((res, rej) => {
|
||||
abortFn = () => res("aborted");
|
||||
arg.abortSignal?.addEventListener('abort', abortFn);
|
||||
});
|
||||
|
||||
const result = await Promise.any([fetchPromise, abortPromise]);
|
||||
arg.abortSignal?.removeEventListener('abort', abortFn);
|
||||
|
||||
if (result === 'aborted') {
|
||||
return { ok: false, data: 'aborted', headers: {} };
|
||||
}
|
||||
|
||||
const data = arg.rawResponse ? new Uint8Array(result.data as number[]) : result.data;
|
||||
addFetchLogInGlobalFetch(data, result.ok, url, arg);
|
||||
return { ok: result.ok, data, headers: result.headers };
|
||||
}
|
||||
|
||||
// Decoupled globalFetch built-in function
|
||||
async function fetchWithCapacitor(url: string, arg: GlobalFetchArgs): Promise<GlobalFetchResult> {
|
||||
const { body, headers = {}, rawResponse } = arg;
|
||||
headers["Content-Type"] = body instanceof URLSearchParams ? "application/x-www-form-urlencoded" : "application/json";
|
||||
|
||||
const res = await CapacitorHttp.request({ url, method: arg.method, headers, data: body, responseType: rawResponse ? "arraybuffer" : "json" });
|
||||
|
||||
addFetchLogInGlobalFetch(rawResponse ? "Uint8Array Response" : res.data, true, url, arg);
|
||||
|
||||
return {
|
||||
ok: true,
|
||||
data: rawResponse ? new Uint8Array(res.data as ArrayBuffer) : res.data,
|
||||
headers: res.headers,
|
||||
};
|
||||
}
|
||||
|
||||
// Decoupled globalFetch built-in function
|
||||
async function fetchWithProxy(url: string, arg: GlobalFetchArgs): Promise<GlobalFetchResult> {
|
||||
try {
|
||||
const furl = !isTauri && !isNodeServer ? `${hubURL}/proxy2` : `/proxy2`;
|
||||
const headers = {
|
||||
"risu-header": encodeURIComponent(JSON.stringify(arg.headers)),
|
||||
"risu-url": encodeURIComponent(url),
|
||||
"Content-Type": arg.body instanceof URLSearchParams ? "application/x-www-form-urlencoded" : "application/json",
|
||||
...(arg.useRisuToken && { "x-risu-tk": "use" }),
|
||||
};
|
||||
|
||||
const body = arg.body instanceof URLSearchParams ? arg.body.toString() : JSON.stringify(arg.body);
|
||||
|
||||
const response = await fetch(furl, { body, headers, method: arg.method, signal: arg.abortSignal });
|
||||
const isSuccess = response.ok && response.status >= 200 && response.status < 300;
|
||||
|
||||
if (arg.rawResponse) {
|
||||
const data = new Uint8Array(await response.arrayBuffer());
|
||||
addFetchLogInGlobalFetch("Uint8Array Response", isSuccess, url, arg);
|
||||
return { ok: isSuccess, data, headers: Object.fromEntries(response.headers) };
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export async function globalFetch(url:string, arg:{
|
||||
plainFetchForce?:boolean,
|
||||
body?:any,
|
||||
headers?:{[key:string]:string},
|
||||
rawResponse?:boolean,
|
||||
method?:"POST"|"GET",
|
||||
abortSignal?:AbortSignal,
|
||||
useRisuToken?:boolean,
|
||||
chatId?:string
|
||||
} = {}): Promise<{
|
||||
ok: boolean;
|
||||
data: any;
|
||||
headers:{[key:string]:string},
|
||||
}> {
|
||||
const text = await response.text();
|
||||
try {
|
||||
const db = get(DataBase)
|
||||
const method = arg.method ?? "POST"
|
||||
db.requestmet = "normal"
|
||||
|
||||
if(arg.abortSignal && arg.abortSignal.aborted){
|
||||
return {
|
||||
ok: false,
|
||||
data: 'aborted',
|
||||
headers: {}
|
||||
}
|
||||
}
|
||||
|
||||
function addFetchLog(response:any, success:boolean){
|
||||
try{
|
||||
fetchLog.unshift({
|
||||
body: JSON.stringify(arg.body, null, 2),
|
||||
header: JSON.stringify(arg.headers ?? {}, null, 2),
|
||||
response: JSON.stringify(response, null, 2),
|
||||
success: success,
|
||||
date: (new Date()).toLocaleTimeString(),
|
||||
url: url,
|
||||
chatId: arg.chatId
|
||||
})
|
||||
}
|
||||
catch{
|
||||
fetchLog.unshift({
|
||||
body: JSON.stringify(arg.body, null, 2),
|
||||
header: JSON.stringify(arg.headers ?? {}, null, 2),
|
||||
response: `${response}`,
|
||||
success: success,
|
||||
date: (new Date()).toLocaleTimeString(),
|
||||
url: url,
|
||||
chatId: arg.chatId
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const urlHost = (new URL(url)).hostname
|
||||
let forcePlainFetch = (knownHostes.includes(urlHost) && (!isTauri)) || db.usePlainFetch || arg.plainFetchForce
|
||||
//check if the url is a local url like localhost
|
||||
if(urlHost.includes("localhost") || urlHost.includes("172.0.0.1") || urlHost.includes("0.0.0.0")){
|
||||
if((!isTauri) && (!isNodeServer)){
|
||||
return {
|
||||
ok: false,
|
||||
data: 'You are trying local request on web version. this is not allowed dude to browser security policy. use the desktop version instead, or use tunneling service like ngrok and set the cors to allow all.',
|
||||
headers: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(forcePlainFetch){
|
||||
try {
|
||||
let headers = arg.headers ?? {}
|
||||
if(!headers["Content-Type"]){
|
||||
headers["Content-Type"] = `application/json`
|
||||
}
|
||||
const furl = new URL(url)
|
||||
|
||||
const da = await fetch(furl, {
|
||||
body: JSON.stringify(arg.body),
|
||||
headers: arg.headers,
|
||||
method: method,
|
||||
signal: arg.abortSignal
|
||||
})
|
||||
|
||||
if(arg.rawResponse){
|
||||
addFetchLog("Uint8Array Response", da.ok && da.status >= 200 && da.status < 300)
|
||||
return {
|
||||
ok: da.ok && da.status >= 200 && da.status < 300,
|
||||
data: new Uint8Array(await da.arrayBuffer()),
|
||||
headers: Object.fromEntries(da.headers)
|
||||
}
|
||||
}
|
||||
else{
|
||||
const dat = await da.json()
|
||||
addFetchLog(dat, da.ok && da.status >= 200 && da.status < 300)
|
||||
return {
|
||||
ok: da.ok && da.status >= 200 && da.status < 300,
|
||||
data: dat,
|
||||
headers: Object.fromEntries(da.headers)
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
return {
|
||||
ok: false,
|
||||
data: `${error}`,
|
||||
headers: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(isTauri){
|
||||
const body = (!arg.body) ? null :
|
||||
(arg.body instanceof URLSearchParams) ? (Body.text(arg.body.toString())) : (Body.json(arg.body))
|
||||
const headers = arg.headers ?? {}
|
||||
const fetchPromise = TauriFetch(url, {
|
||||
body: body,
|
||||
method: method,
|
||||
headers: headers,
|
||||
timeout: {
|
||||
secs: db.timeOut,
|
||||
nanos: 0
|
||||
},
|
||||
responseType: arg.rawResponse ? ResponseType.Binary : ResponseType.JSON,
|
||||
|
||||
})
|
||||
|
||||
//abort the promise when abort signal is triggered
|
||||
let abortFn:() => void = () => {}
|
||||
|
||||
const abortPromise = (new Promise<"aborted">((res,rej) => {
|
||||
abortFn = () => {
|
||||
res("aborted")
|
||||
}
|
||||
if(arg.abortSignal){
|
||||
arg.abortSignal?.addEventListener('abort', abortFn)
|
||||
}
|
||||
}))
|
||||
|
||||
const result = await Promise.any([fetchPromise,abortPromise])
|
||||
|
||||
if(arg.abortSignal){
|
||||
arg.abortSignal.removeEventListener('abort', abortFn)
|
||||
}
|
||||
|
||||
if(result === 'aborted'){
|
||||
return {
|
||||
ok: false,
|
||||
data: 'aborted',
|
||||
headers: {}
|
||||
}
|
||||
}
|
||||
|
||||
if(arg.rawResponse){
|
||||
addFetchLog("Uint8Array Response", result.ok)
|
||||
return {
|
||||
ok: result.ok,
|
||||
data: new Uint8Array(result.data as number[]),
|
||||
headers: result.headers
|
||||
}
|
||||
}
|
||||
else{
|
||||
addFetchLog(result.data, result.ok)
|
||||
return {
|
||||
ok: result.ok,
|
||||
data: result.data,
|
||||
headers: result.headers
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Capacitor.isNativePlatform()){
|
||||
const body = arg.body
|
||||
const headers = arg.headers ?? {}
|
||||
if(arg.body instanceof URLSearchParams){
|
||||
if(!headers["Content-Type"]){
|
||||
headers["Content-Type"] = `application/x-www-form-urlencoded`
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(!headers["Content-Type"]){
|
||||
headers["Content-Type"] = `application/json`
|
||||
}
|
||||
}
|
||||
const res = await CapacitorHttp.request({
|
||||
url: url,
|
||||
method: method,
|
||||
headers: headers,
|
||||
data: body,
|
||||
responseType: arg.rawResponse ? 'arraybuffer' : 'json'
|
||||
})
|
||||
|
||||
if(arg.rawResponse){
|
||||
addFetchLog("Uint8Array Response", true)
|
||||
return {
|
||||
ok: true,
|
||||
data: new Uint8Array(res.data as ArrayBuffer),
|
||||
headers: res.headers
|
||||
}
|
||||
}
|
||||
addFetchLog(res.data, true)
|
||||
return {
|
||||
ok: true,
|
||||
data: res.data,
|
||||
headers: res.headers
|
||||
}
|
||||
}
|
||||
else{
|
||||
try {
|
||||
let body:any
|
||||
if(arg.body instanceof URLSearchParams){
|
||||
const argBody = arg.body as URLSearchParams
|
||||
body = argBody.toString()
|
||||
let headers = arg.headers ?? {}
|
||||
if(!headers["Content-Type"]){
|
||||
headers["Content-Type"] = `application/x-www-form-urlencoded`
|
||||
}
|
||||
}
|
||||
else{
|
||||
body = JSON.stringify(arg.body)
|
||||
let headers = arg.headers ?? {}
|
||||
if(!headers["Content-Type"]){
|
||||
headers["Content-Type"] = `application/json`
|
||||
}
|
||||
}
|
||||
if(arg.rawResponse){
|
||||
const furl = ((!isTauri) && (!isNodeServer)) ? `${hubURL}/proxy2` : `/proxy2`
|
||||
|
||||
let headers = {
|
||||
"risu-header": encodeURIComponent(JSON.stringify(arg.headers)),
|
||||
"risu-url": encodeURIComponent(url),
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
if(arg.useRisuToken){
|
||||
headers["x-risu-tk"] = "use"
|
||||
}
|
||||
|
||||
const da = await fetch(furl, {
|
||||
body: body,
|
||||
headers: headers,
|
||||
method: method,
|
||||
signal: arg.abortSignal
|
||||
})
|
||||
|
||||
addFetchLog("Uint8Array Response", da.ok && da.status >= 200 && da.status < 300)
|
||||
return {
|
||||
ok: da.ok && da.status >= 200 && da.status < 300,
|
||||
data: new Uint8Array(await da.arrayBuffer()),
|
||||
headers: Object.fromEntries(da.headers)
|
||||
}
|
||||
}
|
||||
else{
|
||||
const furl = ((!isTauri) && (!isNodeServer)) ? `${hubURL}/proxy2` : `/proxy2`
|
||||
|
||||
let headers = {
|
||||
"risu-header": encodeURIComponent(JSON.stringify(arg.headers)),
|
||||
"risu-url": encodeURIComponent(url),
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
if(arg.useRisuToken){
|
||||
headers["x-risu-tk"] = "use"
|
||||
}
|
||||
const da = await fetch(furl, {
|
||||
body: body,
|
||||
headers: headers,
|
||||
method: method
|
||||
})
|
||||
const daText = await da.text()
|
||||
try {
|
||||
const dat = JSON.parse(daText)
|
||||
addFetchLog(dat, da.ok && da.status >= 200 && da.status < 300)
|
||||
return {
|
||||
ok: da.ok && da.status >= 200 && da.status < 300,
|
||||
data: dat,
|
||||
headers: Object.fromEntries(da.headers)
|
||||
}
|
||||
} catch (error) {
|
||||
addFetchLog(daText, false)
|
||||
let errorMsg = (daText.startsWith('<!DOCTYPE')) ? ("Responded HTML. is your url, api key and password correct?") : (daText)
|
||||
return {
|
||||
ok:false,
|
||||
data: errorMsg,
|
||||
headers: Object.fromEntries(da.headers)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
ok:false,
|
||||
data: `${error}`,
|
||||
headers: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
const data = JSON.parse(text);
|
||||
addFetchLogInGlobalFetch(data, isSuccess, url, arg);
|
||||
return { ok: isSuccess, data, headers: Object.fromEntries(response.headers) };
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
return {
|
||||
ok:false,
|
||||
data: `${error}`,
|
||||
headers: {}
|
||||
}
|
||||
const errorMsg = text.startsWith('<!DOCTYPE') ? "Responded HTML. Is your URL, API key, and password correct?" : text;
|
||||
addFetchLogInGlobalFetch(text, false, url, arg);
|
||||
return { ok: false, data: errorMsg, headers: Object.fromEntries(response.headers) };
|
||||
}
|
||||
} catch (error) {
|
||||
return { ok: false, data: `${error}`, headers: {} };
|
||||
}
|
||||
}
|
||||
|
||||
async function registerSw() {
|
||||
|
||||
@@ -127,6 +127,27 @@ async function translateMain(text:string, arg:{from:string, to:string, host:stri
|
||||
return f.data.translations[0].text
|
||||
|
||||
}
|
||||
if(db.translatorType === 'deeplX'){
|
||||
// URL이 DeeplX 프로그램 실행시키면 CMD에서는 0.0.0.0:1188라고 뜨는데 https://0.0.0.0:1188/translate 로 호출 보내야함
|
||||
// 유저가 https://0.0.0.0:1188/translate라고 입력하게 할지, 아니면 0.0.0.0:1188만 입력하면 /translate를 자동으로 붙여줄지 결정필요
|
||||
let url = db.deeplXOptions.url;
|
||||
let headers = { "Content-Type": "application/json" }
|
||||
|
||||
const body = {text: text, target_lang: arg.to.toLocaleUpperCase(), source_lang: arg.from.toLocaleUpperCase()}
|
||||
|
||||
|
||||
if(db.deeplXOptions.token.trim() !== '') { headers["Authorization"] = "Bearer " + db.deeplXOptions.token}
|
||||
|
||||
console.log(body)
|
||||
const f = await globalFetch(url, { method: "POST", headers: headers, body: body })
|
||||
|
||||
if(!f.ok){ return 'ERR::DeepLX API Error' + (await f.data) }
|
||||
|
||||
const jsonResponse = JSON.stringify(f.data.data)
|
||||
return jsonResponse
|
||||
}
|
||||
|
||||
|
||||
const url = `https://${arg.host}/translate_a/single?client=gtx&dt=t&sl=${arg.from}&tl=${arg.to}&q=` + encodeURIComponent(text)
|
||||
|
||||
|
||||
@@ -171,7 +192,7 @@ async function jaTrans(text:string) {
|
||||
|
||||
export function isExpTranslator(){
|
||||
const db = get(DataBase)
|
||||
return db.translatorType === 'llm' || db.translatorType === 'deepl'
|
||||
return db.translatorType === 'llm' || db.translatorType === 'deepl' || db.translatorType === 'deeplX'
|
||||
}
|
||||
|
||||
export async function translateHTML(html: string, reverse:boolean, charArg:simpleCharacterArgument|string = ''): Promise<string> {
|
||||
|
||||
Reference in New Issue
Block a user