diff --git a/deno.json b/deno.json index 410a752..8729335 100644 --- a/deno.json +++ b/deno.json @@ -1,8 +1,8 @@ { "tasks": { - "watch": "deno run --watch --allow-net --allow-env --allow-read --allow-write main.ts", - "start": "deno run --allow-net --allow-env --allow-read --allow-write main.ts", - "compile": "deno compile --allow-net --allow-env --allow-read --allow-write -o coeiroink-v2-bridge main.ts" + "watch": "deno run --watch --allow-net --allow-run --allow-env --allow-read --allow-write main.ts", + "start": "deno run --allow-net --allow-run --allow-env --allow-read --allow-write main.ts", + "compile": "deno compile --allow-net --allow-run --allow-env --allow-read --allow-write -o coeiroink-v2-bridge main.ts" }, "lock": false } diff --git a/main.ts b/main.ts index a322a19..a648038 100644 --- a/main.ts +++ b/main.ts @@ -1,8 +1,9 @@ -import { Hono, honoLogger, ky, parse, serve } from "./deps.ts"; +import { dirname, Hono, honoLogger, ky, parse, serve } from "./deps.ts"; import dictProvider from "./providers/dict.ts"; import infoProvider from "./providers/info.ts"; import noopProvider from "./providers/noop.ts"; import synthesisProvider from "./providers/synthesis.ts"; +import { saveStore, store } from "./store.ts"; const args = parse(Deno.args, { string: ["host", "port", "originalUrl"], @@ -16,6 +17,56 @@ const baseClient = ky.create({ prefixUrl: args.originalUrl, }); +if (store.enginePath != undefined) { + if (await baseClient.get("").catch(() => null)) { + console.log("The server is already running, not starting the engine."); + } else if (Deno.stat(store.enginePath).catch(() => null) == undefined) { + console.log( + `The engine path ${store.enginePath} does not exist, not starting the engine.`, + ); + store.enginePath = undefined; + } else { + console.log(`Starting the engine at ${store.enginePath}...`); + new Deno.Command( + store.enginePath, + { + stdout: "inherit", + stderr: "inherit", + }, + ).spawn(); + } +} else { + console.log("No engine path, not starting the engine."); +} + +while (true) { + try { + await baseClient.get(""); + break; + } catch { + console.log("Waiting for the server to be ready..."); + await new Promise((resolve) => setTimeout(resolve, 1000)); + } +} + +const speakers: { + speakerUuid: string; +}[] = await baseClient.get("v1/speakers").json(); +const path: { + speakerFolderPath: string; +} = await baseClient.get("v1/speaker_folder_path", { + searchParams: { + speakerUuid: speakers[0].speakerUuid, + }, +}).json(); +const speakerFolderPath = path.speakerFolderPath; +const enginePath = dirname(dirname(speakerFolderPath)) + "/engine/engine.exe"; + +console.log(`Engine path: ${enginePath}`); + +store.enginePath = enginePath; +await saveStore(); + const app = new Hono(); app.use("*", honoLogger()); diff --git a/providers/info.ts b/providers/info.ts index 3cfc8ee..fb59aaa 100644 --- a/providers/info.ts +++ b/providers/info.ts @@ -1,5 +1,5 @@ import { dirname, toBase64 } from "../deps.ts"; -import { getIdFromSpeaker, getOrAppendSpeaker } from "../speakerMap.ts"; +import { getIdFromSpeaker, getOrAppendSpeaker } from "../store.ts"; import { Provider } from "./index.ts"; let speakers: { diff --git a/providers/synthesis.ts b/providers/synthesis.ts index 01bf25f..365b0cc 100644 --- a/providers/synthesis.ts +++ b/providers/synthesis.ts @@ -1,5 +1,5 @@ import { Provider } from "./index.ts"; -import { getSpeakerFromId } from "../speakerMap.ts"; +import { getSpeakerFromId } from "../store.ts"; import { AsyncLock, wanakana } from "../deps.ts"; type Prosody = { diff --git a/speakerMap.ts b/speakerMap.ts deleted file mode 100644 index 44daf05..0000000 --- a/speakerMap.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { homeDir } from "./deps.ts"; - -const filePath = homeDir + "/.coeiroink-v2-bridge-map.json" -export const speakerMap: [number, [string, number]][] = JSON.parse( - await Deno.readTextFile(filePath).catch(() => "[]") -); - -export const getSpeakerFromId = (id: number) => { - return speakerMap.find(([id_, _]) => id_ === id)?.[1]; -}; - -export const getIdFromSpeaker = (speakerUuid: string, styleId: number) => { - return speakerMap.find( - ([_, [speakerUuid_, styleId_]]) => - speakerUuid_ === speakerUuid && styleId_ === styleId - )?.[0]; -}; - -export const getOrAppendSpeaker = async ( - speakerUuid: string, - styleId: number -) => { - const speakerId = getIdFromSpeaker(speakerUuid, styleId); - if (speakerId !== undefined) { - return speakerId; - } - const speakerCount = speakerMap.length; - speakerMap.push([speakerCount, [speakerUuid, styleId]]); - await Deno.writeTextFile(filePath, JSON.stringify(speakerMap)); - return speakerCount; -}; diff --git a/store.ts b/store.ts new file mode 100644 index 0000000..5aa9ddf --- /dev/null +++ b/store.ts @@ -0,0 +1,49 @@ +import { homeDir } from "./deps.ts"; + +type SpeakerMap = [number, [string, number]][]; +type Store = { + speakerMap: SpeakerMap; + enginePath: string | undefined; +}; + +const filePath = homeDir + "/.coeiroink-v2.json"; +export let store: Store = { speakerMap: [], enginePath: undefined }; +const oldFilePath = homeDir + "/.coeiroink-v2-bridge-map.json"; +if (await Deno.stat(oldFilePath).catch(() => null)) { + console.log("Migrating old speaker map..."); + store.speakerMap.push(...JSON.parse(await Deno.readTextFile(oldFilePath))); + await Deno.remove(oldFilePath); +} +if (await Deno.stat(filePath).catch(() => null)) { + console.log("Loading store..."); + store = JSON.parse(await Deno.readTextFile(filePath)); +} + +export const getSpeakerFromId = (id: number) => { + return store.speakerMap.find(([id_, _]) => id_ === id)?.[1]; +}; + +export const getIdFromSpeaker = (speakerUuid: string, styleId: number) => { + return store.speakerMap.find( + ([_, [speakerUuid_, styleId_]]) => + speakerUuid_ === speakerUuid && styleId_ === styleId, + )?.[0]; +}; + +export const getOrAppendSpeaker = async ( + speakerUuid: string, + styleId: number, +) => { + const speakerId = getIdFromSpeaker(speakerUuid, styleId); + if (speakerId !== undefined) { + return speakerId; + } + const speakerCount = store.speakerMap.length; + store.speakerMap.push([speakerCount, [speakerUuid, styleId]]); + await saveStore(); + return speakerCount; +}; + +export const saveStore = async () => { + await Deno.writeTextFile(filePath, JSON.stringify(store)); +};