mirror of
https://github.com/open-webui/desktop
synced 2025-06-26 18:15:59 +00:00
refac
This commit is contained in:
parent
4e99cf651e
commit
9f09e26247
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "open-webui",
|
||||
"productName": "Open WebUI",
|
||||
"version": "1.0.0",
|
||||
"version": "0.0.1",
|
||||
"description": "Open WebUI",
|
||||
"main": ".vite/build/main.js",
|
||||
"scripts": {
|
||||
|
||||
@ -13,11 +13,11 @@
|
||||
version: 1
|
||||
metadata:
|
||||
content_hash:
|
||||
linux-64: 70e93bda3c8489b7c9a77267cf5f53637ac0986f8eb5e3c2a61b62c711ba28cc
|
||||
linux-aarch64: ae6dd314eb6a45f1d31ad96cc52c06a1d7d4cd3bb9c37d49dd8faf2873366511
|
||||
osx-64: d93fb8129cd157fb75eec5b95210a21f4277ab47e8c95f314d8cd36e820f1eaf
|
||||
osx-arm64: 94bf97b6d0946324018d90ea0bb7203470a35c64ab1af0cb97b167670423fe12
|
||||
win-64: 4a82a67e4012619c266c561d9ed123a9cb5b321bf0e216ed4446d36b38a1aa9a
|
||||
linux-64: 32a65ee01f9bc14f0e200fcab21a7570646cd57905095aee6fdd821d282af160
|
||||
linux-aarch64: 8211b35201c1b6b1be1e81f062a3cf49ba5ab3e243c4e36dfc7a427022ccf3da
|
||||
osx-64: 2f9c668aa6e91bbe0f5972c8b491d399c6b9669268226e1d03ea4cf032e091d3
|
||||
osx-arm64: df6864f98ad09f0d80fe854d9d9f09b54d38f64c3e7129f498f4be5abc8f30d8
|
||||
win-64: 5109005b8bf33c4cb71d88488196a65b165f25e00a1363d1b7a5676dab11f366
|
||||
channels:
|
||||
- url: conda-forge
|
||||
used_env_vars: []
|
||||
@ -207,6 +207,30 @@ package:
|
||||
sha256: 80ec7e8f006196808fac5bd4b3773a652847f97bbf08044cd87731424ac64f8b
|
||||
category: main
|
||||
optional: false
|
||||
- name: libcxx
|
||||
version: 19.1.6
|
||||
manager: conda
|
||||
platform: osx-64
|
||||
dependencies:
|
||||
__osx: '>=10.13'
|
||||
url: https://conda.anaconda.org/conda-forge/osx-64/libcxx-19.1.6-hf95d169_1.conda
|
||||
hash:
|
||||
md5: 1bad6c181a0799298aad42fc5a7e98b7
|
||||
sha256: c40661648c34c08e21b69e0eec021ccaf090ffff070d2a9cbcb1519e1b310568
|
||||
category: main
|
||||
optional: false
|
||||
- name: libcxx
|
||||
version: 19.1.6
|
||||
manager: conda
|
||||
platform: osx-arm64
|
||||
dependencies:
|
||||
__osx: '>=11.0'
|
||||
url: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-19.1.6-ha82da77_1.conda
|
||||
hash:
|
||||
md5: ce5252d8db110cdb4ae4173d0a63c7c5
|
||||
sha256: 2b2443404503cd862385fd2f2a2c73f9624686fd1e5a45050b4034cfc06904ec
|
||||
category: main
|
||||
optional: false
|
||||
- name: libexpat
|
||||
version: 2.6.4
|
||||
manager: conda
|
||||
@ -555,6 +579,30 @@ package:
|
||||
sha256: ecfc0182c3b2e63c870581be1fa0e4dbdfec70d2011cb4f5bde416ece26c41df
|
||||
category: main
|
||||
optional: false
|
||||
- name: libstdcxx
|
||||
version: 14.2.0
|
||||
manager: conda
|
||||
platform: linux-64
|
||||
dependencies:
|
||||
libgcc: 14.2.0
|
||||
url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-14.2.0-hc0a3c3a_1.conda
|
||||
hash:
|
||||
md5: 234a5554c53625688d51062645337328
|
||||
sha256: 4661af0eb9bdcbb5fb33e5d0023b001ad4be828fccdcc56500059d56f9869462
|
||||
category: main
|
||||
optional: false
|
||||
- name: libstdcxx
|
||||
version: 14.2.0
|
||||
manager: conda
|
||||
platform: linux-aarch64
|
||||
dependencies:
|
||||
libgcc: 14.2.0
|
||||
url: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-14.2.0-h3f4de04_1.conda
|
||||
hash:
|
||||
md5: 37f489acd39e22b623d2d1e5ac6d195c
|
||||
sha256: 519556d2c93f1b487091ce046d62e762286177f4a670ec10e16005177d0bcab3
|
||||
category: main
|
||||
optional: false
|
||||
- name: libuuid
|
||||
version: 2.38.1
|
||||
manager: conda
|
||||
@ -783,6 +831,76 @@ package:
|
||||
sha256: 519a06eaab7c878fbebb8cab98ea4a4465eafb1e9ed8c6ce67226068a80a92f0
|
||||
category: main
|
||||
optional: false
|
||||
- name: pip
|
||||
version: 24.3.1
|
||||
manager: conda
|
||||
platform: linux-64
|
||||
dependencies:
|
||||
python: '>=3.9,<3.13.0a0'
|
||||
setuptools: ''
|
||||
wheel: ''
|
||||
url: https://conda.anaconda.org/conda-forge/noarch/pip-24.3.1-pyh8b19718_2.conda
|
||||
hash:
|
||||
md5: 04e691b9fadd93a8a9fad87a81d4fd8f
|
||||
sha256: da8c8888de10c1e4234ebcaa1550ac2b4b5408ac20f093fe641e4bc8c9c9f3eb
|
||||
category: main
|
||||
optional: false
|
||||
- name: pip
|
||||
version: 24.3.1
|
||||
manager: conda
|
||||
platform: linux-aarch64
|
||||
dependencies:
|
||||
setuptools: ''
|
||||
wheel: ''
|
||||
python: '>=3.9,<3.13.0a0'
|
||||
url: https://conda.anaconda.org/conda-forge/noarch/pip-24.3.1-pyh8b19718_2.conda
|
||||
hash:
|
||||
md5: 04e691b9fadd93a8a9fad87a81d4fd8f
|
||||
sha256: da8c8888de10c1e4234ebcaa1550ac2b4b5408ac20f093fe641e4bc8c9c9f3eb
|
||||
category: main
|
||||
optional: false
|
||||
- name: pip
|
||||
version: 24.3.1
|
||||
manager: conda
|
||||
platform: osx-64
|
||||
dependencies:
|
||||
setuptools: ''
|
||||
wheel: ''
|
||||
python: '>=3.9,<3.13.0a0'
|
||||
url: https://conda.anaconda.org/conda-forge/noarch/pip-24.3.1-pyh8b19718_2.conda
|
||||
hash:
|
||||
md5: 04e691b9fadd93a8a9fad87a81d4fd8f
|
||||
sha256: da8c8888de10c1e4234ebcaa1550ac2b4b5408ac20f093fe641e4bc8c9c9f3eb
|
||||
category: main
|
||||
optional: false
|
||||
- name: pip
|
||||
version: 24.3.1
|
||||
manager: conda
|
||||
platform: osx-arm64
|
||||
dependencies:
|
||||
setuptools: ''
|
||||
wheel: ''
|
||||
python: '>=3.9,<3.13.0a0'
|
||||
url: https://conda.anaconda.org/conda-forge/noarch/pip-24.3.1-pyh8b19718_2.conda
|
||||
hash:
|
||||
md5: 04e691b9fadd93a8a9fad87a81d4fd8f
|
||||
sha256: da8c8888de10c1e4234ebcaa1550ac2b4b5408ac20f093fe641e4bc8c9c9f3eb
|
||||
category: main
|
||||
optional: false
|
||||
- name: pip
|
||||
version: 24.3.1
|
||||
manager: conda
|
||||
platform: win-64
|
||||
dependencies:
|
||||
setuptools: ''
|
||||
wheel: ''
|
||||
python: '>=3.9,<3.13.0a0'
|
||||
url: https://conda.anaconda.org/conda-forge/noarch/pip-24.3.1-pyh8b19718_2.conda
|
||||
hash:
|
||||
md5: 04e691b9fadd93a8a9fad87a81d4fd8f
|
||||
sha256: da8c8888de10c1e4234ebcaa1550ac2b4b5408ac20f093fe641e4bc8c9c9f3eb
|
||||
category: main
|
||||
optional: false
|
||||
- name: python
|
||||
version: 3.11.11
|
||||
manager: conda
|
||||
@ -957,6 +1075,66 @@ package:
|
||||
sha256: a1dfa679ac3f6007362386576a704ad2d0d7a02e98f5d0b115f207a2da63e884
|
||||
category: main
|
||||
optional: false
|
||||
- name: setuptools
|
||||
version: 75.8.0
|
||||
manager: conda
|
||||
platform: linux-64
|
||||
dependencies:
|
||||
python: '>=3.9'
|
||||
url: https://conda.anaconda.org/conda-forge/noarch/setuptools-75.8.0-pyhff2d567_0.conda
|
||||
hash:
|
||||
md5: 8f28e299c11afdd79e0ec1e279dcdc52
|
||||
sha256: e0778e4f276e9a81b51c56f51ec22a27b4d8fc955abc0be77ad09ca9bea06bb9
|
||||
category: main
|
||||
optional: false
|
||||
- name: setuptools
|
||||
version: 75.8.0
|
||||
manager: conda
|
||||
platform: linux-aarch64
|
||||
dependencies:
|
||||
python: '>=3.9'
|
||||
url: https://conda.anaconda.org/conda-forge/noarch/setuptools-75.8.0-pyhff2d567_0.conda
|
||||
hash:
|
||||
md5: 8f28e299c11afdd79e0ec1e279dcdc52
|
||||
sha256: e0778e4f276e9a81b51c56f51ec22a27b4d8fc955abc0be77ad09ca9bea06bb9
|
||||
category: main
|
||||
optional: false
|
||||
- name: setuptools
|
||||
version: 75.8.0
|
||||
manager: conda
|
||||
platform: osx-64
|
||||
dependencies:
|
||||
python: '>=3.9'
|
||||
url: https://conda.anaconda.org/conda-forge/noarch/setuptools-75.8.0-pyhff2d567_0.conda
|
||||
hash:
|
||||
md5: 8f28e299c11afdd79e0ec1e279dcdc52
|
||||
sha256: e0778e4f276e9a81b51c56f51ec22a27b4d8fc955abc0be77ad09ca9bea06bb9
|
||||
category: main
|
||||
optional: false
|
||||
- name: setuptools
|
||||
version: 75.8.0
|
||||
manager: conda
|
||||
platform: osx-arm64
|
||||
dependencies:
|
||||
python: '>=3.9'
|
||||
url: https://conda.anaconda.org/conda-forge/noarch/setuptools-75.8.0-pyhff2d567_0.conda
|
||||
hash:
|
||||
md5: 8f28e299c11afdd79e0ec1e279dcdc52
|
||||
sha256: e0778e4f276e9a81b51c56f51ec22a27b4d8fc955abc0be77ad09ca9bea06bb9
|
||||
category: main
|
||||
optional: false
|
||||
- name: setuptools
|
||||
version: 75.8.0
|
||||
manager: conda
|
||||
platform: win-64
|
||||
dependencies:
|
||||
python: '>=3.9'
|
||||
url: https://conda.anaconda.org/conda-forge/noarch/setuptools-75.8.0-pyhff2d567_0.conda
|
||||
hash:
|
||||
md5: 8f28e299c11afdd79e0ec1e279dcdc52
|
||||
sha256: e0778e4f276e9a81b51c56f51ec22a27b4d8fc955abc0be77ad09ca9bea06bb9
|
||||
category: main
|
||||
optional: false
|
||||
- name: tk
|
||||
version: 8.6.13
|
||||
manager: conda
|
||||
@ -1087,6 +1265,73 @@ package:
|
||||
sha256: db8dead3dd30fb1a032737554ce91e2819b43496a0db09927edf01c32b577450
|
||||
category: main
|
||||
optional: false
|
||||
- name: uv
|
||||
version: 0.5.17
|
||||
manager: conda
|
||||
platform: linux-64
|
||||
dependencies:
|
||||
__glibc: '>=2.17,<3.0.a0'
|
||||
libgcc: '>=13'
|
||||
libstdcxx: '>=13'
|
||||
url: https://conda.anaconda.org/conda-forge/linux-64/uv-0.5.17-h0f3a69f_0.conda
|
||||
hash:
|
||||
md5: d5d97fb9313f4ff7ae3d7e5c98794b5b
|
||||
sha256: 6c42b2eedd779b671f7cb7e74665a0dcf6a12404d546e2095a4aac5d76820cd2
|
||||
category: main
|
||||
optional: false
|
||||
- name: uv
|
||||
version: 0.5.17
|
||||
manager: conda
|
||||
platform: linux-aarch64
|
||||
dependencies:
|
||||
libgcc: '>=13'
|
||||
libstdcxx: '>=13'
|
||||
url: https://conda.anaconda.org/conda-forge/linux-aarch64/uv-0.5.17-h2016286_0.conda
|
||||
hash:
|
||||
md5: c4a46d144ce557015ffcc82c5153ca5b
|
||||
sha256: 2708d296ad6f7928ea089d428c3c40190ecafc27ed6124f9979904e61f3adfd1
|
||||
category: main
|
||||
optional: false
|
||||
- name: uv
|
||||
version: 0.5.17
|
||||
manager: conda
|
||||
platform: osx-64
|
||||
dependencies:
|
||||
__osx: '>=10.13'
|
||||
libcxx: '>=18'
|
||||
url: https://conda.anaconda.org/conda-forge/osx-64/uv-0.5.17-h8de1528_0.conda
|
||||
hash:
|
||||
md5: 8fecdbea72fffbc52150943fdfe730a9
|
||||
sha256: 86a0684c14e3d9ed54314c8a0d748c3d8378808137439ed8f6d7bfbd0a44520d
|
||||
category: main
|
||||
optional: false
|
||||
- name: uv
|
||||
version: 0.5.17
|
||||
manager: conda
|
||||
platform: osx-arm64
|
||||
dependencies:
|
||||
__osx: '>=11.0'
|
||||
libcxx: '>=18'
|
||||
url: https://conda.anaconda.org/conda-forge/osx-arm64/uv-0.5.17-h668ec48_0.conda
|
||||
hash:
|
||||
md5: e6aee4ba25b32e27eadf9a60315faa06
|
||||
sha256: 27fb3cf5daa5cdbf9d16629d702290e342399b8217bb44031fe531200f9f9eeb
|
||||
category: main
|
||||
optional: false
|
||||
- name: uv
|
||||
version: 0.5.16
|
||||
manager: conda
|
||||
platform: win-64
|
||||
dependencies:
|
||||
ucrt: '>=10.0.20348.0'
|
||||
vc: '>=14.2,<15'
|
||||
vc14_runtime: '>=14.29.30139'
|
||||
url: https://conda.anaconda.org/conda-forge/win-64/uv-0.5.16-ha08ef0e_0.conda
|
||||
hash:
|
||||
md5: 810e5ec595b71a697921245347b5c52b
|
||||
sha256: e07951504d15fb299385ac20879007abf13f764e5a96b8abb9dff5275387f042
|
||||
category: main
|
||||
optional: false
|
||||
- name: vc
|
||||
version: '14.3'
|
||||
manager: conda
|
||||
@ -1123,3 +1368,63 @@ package:
|
||||
sha256: 568ce8151eaae256f1cef752fc78651ad7a86ff05153cc7a4740b52ae6536118
|
||||
category: main
|
||||
optional: false
|
||||
- name: wheel
|
||||
version: 0.45.1
|
||||
manager: conda
|
||||
platform: linux-64
|
||||
dependencies:
|
||||
python: '>=3.9'
|
||||
url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda
|
||||
hash:
|
||||
md5: 75cb7132eb58d97896e173ef12ac9986
|
||||
sha256: 1b34021e815ff89a4d902d879c3bd2040bc1bd6169b32e9427497fa05c55f1ce
|
||||
category: main
|
||||
optional: false
|
||||
- name: wheel
|
||||
version: 0.45.1
|
||||
manager: conda
|
||||
platform: linux-aarch64
|
||||
dependencies:
|
||||
python: '>=3.9'
|
||||
url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda
|
||||
hash:
|
||||
md5: 75cb7132eb58d97896e173ef12ac9986
|
||||
sha256: 1b34021e815ff89a4d902d879c3bd2040bc1bd6169b32e9427497fa05c55f1ce
|
||||
category: main
|
||||
optional: false
|
||||
- name: wheel
|
||||
version: 0.45.1
|
||||
manager: conda
|
||||
platform: osx-64
|
||||
dependencies:
|
||||
python: '>=3.9'
|
||||
url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda
|
||||
hash:
|
||||
md5: 75cb7132eb58d97896e173ef12ac9986
|
||||
sha256: 1b34021e815ff89a4d902d879c3bd2040bc1bd6169b32e9427497fa05c55f1ce
|
||||
category: main
|
||||
optional: false
|
||||
- name: wheel
|
||||
version: 0.45.1
|
||||
manager: conda
|
||||
platform: osx-arm64
|
||||
dependencies:
|
||||
python: '>=3.9'
|
||||
url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda
|
||||
hash:
|
||||
md5: 75cb7132eb58d97896e173ef12ac9986
|
||||
sha256: 1b34021e815ff89a4d902d879c3bd2040bc1bd6169b32e9427497fa05c55f1ce
|
||||
category: main
|
||||
optional: false
|
||||
- name: wheel
|
||||
version: 0.45.1
|
||||
manager: conda
|
||||
platform: win-64
|
||||
dependencies:
|
||||
python: '>=3.9'
|
||||
url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda
|
||||
hash:
|
||||
md5: 75cb7132eb58d97896e173ef12ac9986
|
||||
sha256: 1b34021e815ff89a4d902d879c3bd2040bc1bd6169b32e9427497fa05c55f1ce
|
||||
category: main
|
||||
optional: false
|
||||
|
||||
@ -3,6 +3,8 @@ channels:
|
||||
- conda-forge
|
||||
dependencies:
|
||||
- python=3.11
|
||||
- pip
|
||||
- uv
|
||||
platforms:
|
||||
- linux-64
|
||||
- linux-aarch64 # aka arm64, use for Docker on Apple Silicon
|
||||
|
||||
18
src/main.ts
18
src/main.ts
@ -10,6 +10,8 @@ import {
|
||||
import path from "path";
|
||||
import started from "electron-squirrel-startup";
|
||||
|
||||
import { installPackage } from "./utils";
|
||||
|
||||
// Restrict app to a single instance
|
||||
const gotTheLock = app.requestSingleInstanceLock();
|
||||
if (!gotTheLock) {
|
||||
@ -68,6 +70,10 @@ if (!gotTheLock) {
|
||||
);
|
||||
}
|
||||
|
||||
if (!app.isPackaged) {
|
||||
mainWindow.webContents.openDevTools();
|
||||
}
|
||||
|
||||
// Create a system tray icon
|
||||
const image = nativeImage.createFromPath(
|
||||
path.join(__dirname, "assets/tray.png")
|
||||
@ -102,7 +108,12 @@ if (!gotTheLock) {
|
||||
});
|
||||
};
|
||||
|
||||
ipcMain.on("load-webui", (event, arg) => {
|
||||
ipcMain.handle("install-package", async (event) => {
|
||||
console.log("Installing package...");
|
||||
installPackage();
|
||||
});
|
||||
|
||||
ipcMain.handle("load-webui", async (event, arg) => {
|
||||
console.log(arg); // prints "ping"
|
||||
mainWindow.loadURL("http://localhost:8080");
|
||||
|
||||
@ -118,9 +129,14 @@ if (!gotTheLock) {
|
||||
});
|
||||
});
|
||||
|
||||
app.on("before-quit", () => {
|
||||
app.isQuiting = true; // Ensure quit flag is set
|
||||
});
|
||||
|
||||
// Quit when all windows are closed, except on macOS
|
||||
app.on("window-all-closed", () => {
|
||||
if (process.platform !== "darwin") {
|
||||
app.isQuitting = true;
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
@ -15,12 +15,16 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||
});
|
||||
|
||||
contextBridge.exposeInMainWorld("electronAPI", {
|
||||
sendPing: () => {
|
||||
sendPing: async () => {
|
||||
console.log("Sending PING to main process...");
|
||||
ipcRenderer.send("send-ping"); // Send the ping back to the main process
|
||||
await ipcRenderer.invoke("send-ping"); // Send the ping back to the main process
|
||||
},
|
||||
|
||||
loadWebUI: (arg) => {
|
||||
ipcRenderer.send("load-webui", arg);
|
||||
installPackage: async () => {
|
||||
await ipcRenderer.invoke("install-package");
|
||||
},
|
||||
|
||||
loadWebUI: async (arg) => {
|
||||
await ipcRenderer.invoke("load-webui", arg);
|
||||
},
|
||||
});
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
onclick={() => {
|
||||
console.log("clicked");
|
||||
if (window?.electronAPI) {
|
||||
window.electronAPI.loadWebUI();
|
||||
window.electronAPI.installPackage();
|
||||
}
|
||||
}}>Install Open WebUI</button
|
||||
>
|
||||
|
||||
0
src/utils/build.ts
Normal file
0
src/utils/build.ts
Normal file
@ -7,6 +7,8 @@ import {
|
||||
ExecFileOptions,
|
||||
execFileSync,
|
||||
execSync,
|
||||
spawn,
|
||||
ChildProcess,
|
||||
} from "child_process";
|
||||
|
||||
import * as tar from "tar";
|
||||
@ -22,9 +24,6 @@ import { app } from "electron";
|
||||
|
||||
export function getAppPath(): string {
|
||||
let appDir = app.getAppPath();
|
||||
if (!app.isPackaged) {
|
||||
appDir = path.dirname(appDir);
|
||||
}
|
||||
return appDir;
|
||||
}
|
||||
|
||||
@ -57,7 +56,7 @@ export function getBundledPythonTarPath(): string {
|
||||
return path.join(appPath, "resources", "python.tar.gz");
|
||||
}
|
||||
|
||||
export function getBundledPythonInstallPath(): string {
|
||||
export function getBundledPythonInstallationPath(): string {
|
||||
const installDir = path.join(app.getPath("userData"), "python");
|
||||
|
||||
if (!fs.existsSync(installDir)) {
|
||||
@ -85,7 +84,7 @@ export function getPythonPath(envPath: string, isConda?: boolean) {
|
||||
}
|
||||
|
||||
export function getBundledPythonPath() {
|
||||
return getPythonPath(getBundledPythonInstallPath());
|
||||
return getPythonPath(getBundledPythonInstallationPath());
|
||||
}
|
||||
|
||||
export function isBundledPythonInstalled() {
|
||||
@ -128,37 +127,210 @@ export function createAdHocSignCommand(envPath: string): string {
|
||||
)} && cd -`;
|
||||
}
|
||||
|
||||
export async function installBundledPython(installPath?: string) {
|
||||
const platform = process.platform;
|
||||
const isWin = platform === "win32";
|
||||
installPath = installPath || getBundledPythonInstallPath();
|
||||
export async function installOpenWebUI(installationPath: string) {
|
||||
console.log(installationPath);
|
||||
let unpackCommand =
|
||||
process.platform === "win32"
|
||||
? `${installationPath}\\Scripts\\activate.bat && pip install open-webui -U`
|
||||
: `source "${installationPath}/bin/activate" && pip install open-webui -U`;
|
||||
|
||||
// only unsign when installing from bundled installer
|
||||
// if (platform === "darwin") {
|
||||
// unpackCommand = `${createAdHocSignCommand(installationPath)}\n${unpackCommand}`;
|
||||
// }
|
||||
|
||||
console.log(unpackCommand);
|
||||
|
||||
const commandProcess = exec(unpackCommand, {
|
||||
shell: process.platform === "win32" ? "cmd.exe" : "/bin/bash",
|
||||
});
|
||||
|
||||
// once the environment is activated, print the python version
|
||||
commandProcess.stdout?.on("data", (data) => {
|
||||
console.log(data);
|
||||
});
|
||||
|
||||
commandProcess.stderr?.on("data", (data) => {
|
||||
console.error(data);
|
||||
});
|
||||
|
||||
commandProcess.on("exit", (code) => {
|
||||
console.log(`Child exited with code ${code}`);
|
||||
});
|
||||
}
|
||||
|
||||
export async function installBundledPython(installationPath?: string) {
|
||||
installationPath = installationPath || getBundledPythonInstallationPath();
|
||||
|
||||
const pythonTarPath = getBundledPythonTarPath();
|
||||
|
||||
console.log(installationPath, pythonTarPath);
|
||||
if (!fs.existsSync(pythonTarPath)) {
|
||||
log.error("Python tarball not found");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
fs.mkdirSync(installPath, { recursive: true });
|
||||
fs.mkdirSync(installationPath, { recursive: true });
|
||||
await tar.x({
|
||||
cwd: installPath,
|
||||
cwd: installationPath,
|
||||
file: pythonTarPath,
|
||||
});
|
||||
} catch (error) {
|
||||
log.error(error);
|
||||
}
|
||||
|
||||
let unpackCommand = isWin
|
||||
? `${installPath}\\Scripts\\activate.bat && conda-unpack`
|
||||
: `source "${installPath}/bin/activate" && conda-unpack`;
|
||||
// Get the path to the installed Python binary
|
||||
const bundledPythonPath = getBundledPythonPath();
|
||||
|
||||
// only unsign when installing from bundled installer
|
||||
if (platform === "darwin") {
|
||||
unpackCommand = `${createAdHocSignCommand(installPath)}\n${unpackCommand}`;
|
||||
if (!fs.existsSync(bundledPythonPath)) {
|
||||
log.error("Python binary not found in install path");
|
||||
return;
|
||||
}
|
||||
|
||||
const commandProcess = exec(unpackCommand, {
|
||||
shell: isWin ? "cmd.exe" : "/bin/bash",
|
||||
});
|
||||
try {
|
||||
// Execute the Python binary to print the version
|
||||
const pythonVersion = execFileSync(bundledPythonPath, ["--version"], {
|
||||
encoding: "utf-8",
|
||||
});
|
||||
console.log("Installed Python Version:", pythonVersion.trim());
|
||||
} catch (error) {
|
||||
log.error("Failed to execute Python binary", error);
|
||||
}
|
||||
}
|
||||
|
||||
export async function installPackage(installationPath?: string) {
|
||||
installationPath = installationPath || getBundledPythonInstallationPath();
|
||||
|
||||
if (!isBundledPythonInstalled()) {
|
||||
try {
|
||||
await installBundledPython(installationPath);
|
||||
} catch (error) {
|
||||
log.error("Failed to install bundled Python", error);
|
||||
return Promise.reject("Failed to install bundled Python");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await installOpenWebUI(installationPath);
|
||||
} catch (error) {
|
||||
log.error("Failed to install open-webui", error);
|
||||
return Promise.reject("Failed to install open-webui");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that Python is installed and the `open-webui` package is present
|
||||
* within the specified virtual environment.
|
||||
*
|
||||
* @param installationPath - The path to the virtual environment installation
|
||||
* @returns Promise<void> - Resolves if all prerequisites are valid; rejects otherwise
|
||||
*/
|
||||
export async function validateInstallation(
|
||||
installationPath: string
|
||||
): Promise<void> {
|
||||
const pythonPath = getPythonPath(installationPath);
|
||||
|
||||
// Check if Python binary exists
|
||||
if (!fs.existsSync(pythonPath)) {
|
||||
return Promise.reject(
|
||||
`Python binary not found in environment: ${pythonPath}`
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
// Check if `open-webui` is installed
|
||||
const checkCommand =
|
||||
process.platform === "win32"
|
||||
? `${installationPath}\\Scripts\\activate.bat && pip show open-webui`
|
||||
: `source "${installationPath}/bin/activate" && pip show open-webui`;
|
||||
|
||||
execSync(checkCommand, { stdio: "ignore", shell: true });
|
||||
} catch (error) {
|
||||
return Promise.reject(
|
||||
`The 'open-webui' package is not installed in the virtual environment at ${installationPath}. Install it first.`
|
||||
);
|
||||
}
|
||||
|
||||
// All validation passed
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// Map to track running processes by installation path
|
||||
const activeProcesses: Map<string, ChildProcess> = new Map();
|
||||
|
||||
/**
|
||||
* Starts the Open-WebUI server.
|
||||
*
|
||||
* @param installationPath - The path to the virtual environment installation
|
||||
* @param port - The port on which the server will run
|
||||
*/
|
||||
export async function startOpenWebUIServer(
|
||||
installationPath: string,
|
||||
port: number
|
||||
): Promise<void> {
|
||||
try {
|
||||
await validateInstallation(installationPath);
|
||||
} catch (validationError) {
|
||||
console.error(validationError);
|
||||
return Promise.reject(validationError); // Abort if validation fails
|
||||
}
|
||||
|
||||
// Construct the command based on the platform
|
||||
let startCommand =
|
||||
process.platform === "win32"
|
||||
? `${installationPath}\\Scripts\\activate.bat && open-webui serve`
|
||||
: `source "${installationPath}/bin/activate" && open-webui serve`;
|
||||
|
||||
if (port) {
|
||||
startCommand += ` --port ${port}`;
|
||||
}
|
||||
|
||||
// Spawn the process
|
||||
console.log("Starting Open-WebUI server...");
|
||||
const childProcess = spawn(startCommand, [], { shell: true });
|
||||
|
||||
// Log process output
|
||||
childProcess.stdout?.on("data", (data) => {
|
||||
console.log(`[Open-WebUI]: ${data.toString().trim()}`);
|
||||
});
|
||||
|
||||
childProcess.stderr?.on("data", (data) => {
|
||||
console.error(`[Open-WebUI Error]: ${data.toString().trim()}`);
|
||||
});
|
||||
|
||||
childProcess.on("exit", (exitCode) => {
|
||||
console.log(`Open-WebUI server exited with code ${exitCode}`);
|
||||
});
|
||||
|
||||
// Keep track of the process for later termination
|
||||
activeProcesses.set(installationPath, childProcess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the running Open-WebUI server.
|
||||
*
|
||||
* @param installationPath - The path to the virtual environment installation
|
||||
*/
|
||||
export async function stopOpenWebUIServer(
|
||||
installationPath: string
|
||||
): Promise<void> {
|
||||
const processToStop = activeProcesses.get(installationPath);
|
||||
|
||||
if (!processToStop) {
|
||||
console.error(
|
||||
"No active server found for the specified installation path."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Stopping Open-WebUI server...");
|
||||
|
||||
// Terminate the process
|
||||
processToStop.kill();
|
||||
|
||||
// Remove from the active processes map
|
||||
activeProcesses.delete(installationPath);
|
||||
|
||||
console.log("Open-WebUI server stopped successfully.");
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user