diff options
author | RaindropsSys <raindrops@equestria.dev> | 2024-06-29 20:59:16 +0200 |
---|---|---|
committer | RaindropsSys <raindrops@equestria.dev> | 2024-06-29 20:59:16 +0200 |
commit | 914bcbb474f6f186c212b2da0d9d864b5e75d8e4 (patch) | |
tree | b77a3e341f87e7a9c4ad9e1f9d4928f5b2495329 /src/PrisbeamAI.ts | |
parent | 1c94bd658c2469f9ca9f465db82e71b6f7d2bfe8 (diff) | |
download | faunerie-914bcbb474f6f186c212b2da0d9d864b5e75d8e4.tar.gz faunerie-914bcbb474f6f186c212b2da0d9d864b5e75d8e4.tar.bz2 faunerie-914bcbb474f6f186c212b2da0d9d864b5e75d8e4.zip |
Rename to Faunerie
Diffstat (limited to 'src/PrisbeamAI.ts')
-rwxr-xr-x | src/PrisbeamAI.ts | 224 |
1 files changed, 0 insertions, 224 deletions
diff --git a/src/PrisbeamAI.ts b/src/PrisbeamAI.ts deleted file mode 100755 index a9fc4d4..0000000 --- a/src/PrisbeamAI.ts +++ /dev/null @@ -1,224 +0,0 @@ -import {PrisbeamApp} from "./PrisbeamApp"; -import {ChildProcess} from "node:child_process"; -import {PrisbeamImageType} from "libprisbeam"; -import * as fs from "node:fs"; -import * as cp from "node:child_process"; - -export class PrisbeamAI { - instance: PrisbeamApp; - aiProcess: ChildProcess; - aiStarting: boolean; - - constructor(instance: PrisbeamApp) { - this.instance = instance; - } - - get aiRunning() { - return (!!this.aiProcess && this.aiProcess.exitCode === null) || this.aiStarting; - } - - findPythonExecutable() { - try { - if (process.platform !== "darwin") throw new Error("Not running on macOS"); - cp.execFileSync("/usr/local/bin/python3.11", ["--version"], {cwd: __dirname + "/../ai"}).toString().trim(); - return "/usr/local/bin/python3.11"; - } catch (e) { - try { - cp.execFileSync("py", ["--version"], {cwd: __dirname + "/../ai"}).toString().trim(); - return "py"; - } catch (e) { - try { - cp.execFileSync("python3.11", ["--version"], {cwd: __dirname + "/../ai"}).toString().trim(); - return "python3.11"; - } catch (e) { - try { - cp.execFileSync("python3", ["--version"], {cwd: __dirname + "/../ai"}).toString().trim(); - return "python3"; - } catch (e) { - cp.execFileSync("python", ["--version"], {cwd: __dirname + "/../ai"}).toString().trim(); - return "python"; - } - } - } - } - } - - getPythonVersion() { - return cp.execFileSync(this.findPythonExecutable(), ["--version"], {cwd: __dirname + "/../ai"}).toString().trim(); - } - - updateDependencies() { - return new Promise<void>((res) => { - this.aiProcess = cp.execFile(this.findPythonExecutable(), ["-m", "pip", "install", "-U", "torch", "ultralytics", "Pillow", "requests", "pandas", "opencv-python", "flask", "gitpython", "setuptools>=65.5.1"], {cwd: __dirname + "/../ai"}); - - this.aiProcess.stdout.on('data', (d) => { - console.debug(d.toString()); - }); - - this.aiProcess.stderr.on('data', (d) => { - console.debug(d.toString()); - }); - - this.aiProcess.on('exit', () => { - res(); - }); - }); - } - - triggerEngineStart() { - this.aiProcess = cp.execFile(this.findPythonExecutable(), ["server.py"], {cwd: __dirname + "/../ai"}); - - this.aiProcess.stdout.on('data', (d) => { - console.debug(d.toString()); - }); - - this.aiProcess.stderr.on('data', (d) => { - console.debug(d.toString()); - }); - - this.aiProcess.on('exit', () => { - this.aiProcess = null; - }); - } - - waitForEngine() { - return new Promise<void>((res) => { - let aiInterval = setInterval(async () => { - try { - if ("data" in (await (await fetch("http://127.0.0.1:25091/status")).json())) { - clearInterval(aiInterval); - this.aiStarting = false; - res(); - } - } catch (e) { - } - }, 1000); - }) - } - - validatePythonVersion() { - let pyVersion: string = this.getPythonVersion(); - - if (!pyVersion) { - console.log("Unable to find a Python executable"); - throw new Error("Python not found"); - } else if (!pyVersion.startsWith("Python 3.11.") && pyVersion !== "Python 3.11") { - console.log("Invalid Python version: " + pyVersion); - throw new Error("Python not found"); - } - } - - async startAI() { - if (this.aiRunning) return; - - this.aiStarting = true; - this.validatePythonVersion(); - await this.updateDependencies(); - this.triggerEngineStart(); - await this.waitForEngine(); - } - - async getClasses() { - let _dataStore = this.instance.dataStore; - let protectedDecode = (b: Buffer) => { - return require('zlib').inflateRawSync(b); - } - - await this.startAI(); - let url = _dataStore.database.frontend.getImageFile(_dataStore.currentImage, PrisbeamImageType.ViewURL); - let data: any; - - if (url.startsWith("blob:") || url.startsWith("pbip:")) { - fs.writeFileSync(_dataStore.appData + "/.temp", protectedDecode(fs.readFileSync(_dataStore.database.frontend.getImageFile(_dataStore.currentImage, PrisbeamImageType.ViewFile)))); - url = "file://" + (_dataStore.appData + "/.temp").replaceAll("\\", "/"); - } - - if (_dataStore.currentImage.tags.includes("safe")) { - data = await (await fetch("http://127.0.0.1:25091/safe?url=" + encodeURIComponent(url.replace("file://", "")))).json(); - } else { - data = await (await fetch("http://127.0.0.1:25091/explicit?url=" + encodeURIComponent(url.replace("file://", "")))).json(); - } - - if (fs.existsSync(_dataStore.appData + "/.temp")) fs.unlinkSync(_dataStore.appData + "/.temp"); - return data; - } - - unload() { - if (this.instance.dataStore.appData && fs.existsSync(this.instance.dataStore.appData + "/.temp")) fs.unlinkSync(this.instance.dataStore.appData + "/.temp"); - - if (this.aiProcess) { - console.log("Engine did not stop before quitting, forcefully killing it"); - this.aiProcess.kill("SIGKILL"); - } - } - - makeClassesHTML(c: any) { - let _dataStore = this.instance.dataStore; - - window.onresize = () => { - document.getElementById("preview-zones").style.top = document.getElementById("preview-content-inner").offsetTop + "px"; - document.getElementById("preview-zones").style.left = document.getElementById("preview-content-inner").offsetLeft + "px"; - document.getElementById("preview-zones").style.width = document.getElementById("preview-content-inner").clientWidth + "px"; - document.getElementById("preview-zones").style.height = document.getElementById("preview-content-inner").clientHeight + "px"; - } - - window.onresize(null); - _dataStore.currentImageClasses = c.data || []; - - let properClasses = _dataStore.currentImageClasses.filter(i => i.confidence > 0.5).map(i => { - return { - name: i.name, - top: (i.ymin / _dataStore.currentImage.height) * 100, - left: (i.xmin / _dataStore.currentImage.width) * 100, - width: ((i.xmax - i.xmin) / _dataStore.currentImage.width) * 100, - height: ((i.ymax - i.ymin) / _dataStore.currentImage.height) * 100 - } - }); - document.getElementById("preview-zones").innerHTML = properClasses.map((i, j) => ` - <div onmouseenter="instance.display.highlightZone(${j}, true);" onmouseleave="instance.display.highlightZone(${j}, false);" class="preview-zone" id="preview-zone-${j}" style="opacity: 0; transition: opacity 100ms; border-radius: 1%; background-color: rgba(255, 255, 255, .25); border: 1px solid rgba(255, 255, 255, .5); width: ${i.width}%; height: ${i.height}%; top: ${i.top}%; left: ${i.left}%; position: absolute;"></div> - `).join(""); - - this.displayClassesList(properClasses); - } - - displayClassesList(properClasses: any) { - if (properClasses.length === 0) { - document.getElementById("preview-parts-loader").style.display = "none"; - document.getElementById("preview-parts-none").style.display = ""; - document.getElementById("preview-parts-unsupported").style.display = "none"; - document.getElementById("preview-parts-list").style.display = "none"; - } else { - document.getElementById("preview-parts-loader").style.display = "none"; - document.getElementById("preview-parts-none").style.display = "none"; - document.getElementById("preview-parts-unsupported").style.display = "none"; - document.getElementById("preview-parts-list").style.display = ""; - document.getElementById("preview-parts-list").innerHTML = properClasses.map((i, j) => ` - <a onmouseenter="instance.display.highlightZone(${j}, true);" onmouseleave="instance.display.highlightZone(${j}, false);" id="preview-tag-zone-${j}" class='preview-tag preview-tag-zone' href='#'>${i.name}</a> - `).join(""); - } - } - - displayClasses(id: string) { - let _dataStore = this.instance.dataStore; - - if (_dataStore.currentImage.mime_type.startsWith("image/")) { - if (_dataStore.currentImage.tags.includes("screencap") || !_dataStore.currentImage.tags.includes("safe")) { - this.instance.ai.getClasses().then((c: any) => { - if (_dataStore.currentImage.id === parseInt(id)) { - this.makeClassesHTML(c); - } - }); - } else { - document.getElementById("preview-parts-loader").style.display = "none"; - document.getElementById("preview-parts-none").style.display = ""; - document.getElementById("preview-parts-unsupported").style.display = "none"; - document.getElementById("preview-parts-list").style.display = "none"; - } - } else { - document.getElementById("preview-parts-loader").style.display = "none"; - document.getElementById("preview-parts-none").style.display = "none"; - document.getElementById("preview-parts-unsupported").style.display = ""; - document.getElementById("preview-parts-list").style.display = "none"; - } - } -} |