Add Python installation and setup functionality
This commit is contained in:
174
src-tauri/Cargo.lock
generated
174
src-tauri/Cargo.lock
generated
@@ -17,6 +17,17 @@ version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aes"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cipher",
|
||||
"cpufeatures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.2"
|
||||
@@ -119,6 +130,12 @@ version = "0.21.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9"
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.5.3"
|
||||
@@ -220,6 +237,27 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bzip2"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8"
|
||||
dependencies = [
|
||||
"bzip2-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bzip2-sys"
|
||||
version = "0.1.11+1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cairo-rs"
|
||||
version = "0.15.12"
|
||||
@@ -260,6 +298,7 @@ version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"libc",
|
||||
]
|
||||
|
||||
@@ -318,6 +357,16 @@ dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cipher"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"inout",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cocoa"
|
||||
version = "0.24.1"
|
||||
@@ -364,6 +413,12 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.4.0"
|
||||
@@ -584,6 +639,7 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1211,6 +1267,15 @@ version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "hmac"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
|
||||
dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "html5ever"
|
||||
version = "0.25.2"
|
||||
@@ -1425,6 +1490,15 @@ dependencies = [
|
||||
"cfb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inout"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
@@ -1495,6 +1569,15 @@ version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.66"
|
||||
@@ -2012,12 +2095,35 @@ dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "password-hash"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
"rand_core 0.6.4",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pathdiff"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
|
||||
|
||||
[[package]]
|
||||
name = "pbkdf2"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"hmac",
|
||||
"password-hash",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
@@ -2520,9 +2626,11 @@ dependencies = [
|
||||
"darling",
|
||||
"reqwest",
|
||||
"serde_json",
|
||||
"tar",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tiktoken-rs",
|
||||
"zip",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2783,6 +2891,17 @@ dependencies = [
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.8"
|
||||
@@ -2925,6 +3044,12 @@ version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
@@ -4384,3 +4509,52 @@ checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"byteorder",
|
||||
"bzip2",
|
||||
"constant_time_eq",
|
||||
"crc32fast",
|
||||
"crossbeam-utils",
|
||||
"flate2",
|
||||
"hmac",
|
||||
"pbkdf2",
|
||||
"sha1",
|
||||
"time",
|
||||
"zstd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd"
|
||||
version = "0.11.2+zstd.1.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4"
|
||||
dependencies = [
|
||||
"zstd-safe",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd-safe"
|
||||
version = "5.0.2+zstd.1.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"zstd-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd-sys"
|
||||
version = "2.0.9+zstd.1.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
@@ -19,6 +19,8 @@ tiktoken-rs = "0.4.0"
|
||||
base64 = "0.21.0"
|
||||
reqwest = { version = "0.11.16", features = ["json"] }
|
||||
darling = "0.20.3"
|
||||
zip = "0.6.6"
|
||||
tar = "0.4.40"
|
||||
|
||||
[features]
|
||||
# this feature is used for production builds or when `devPath` points to the filesystem
|
||||
|
||||
@@ -10,6 +10,7 @@ fn greet(name: &str) -> String {
|
||||
use serde_json::Value;
|
||||
use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
use std::io::Write;
|
||||
use std::{time::Duration, path::Path};
|
||||
use serde_json::json;
|
||||
use std::collections::HashMap;
|
||||
@@ -122,6 +123,109 @@ fn check_auth(fpath: String, auth: String) -> bool{
|
||||
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn install_python(path:String) -> bool{
|
||||
//get python embeddable depending on os
|
||||
let os = std::env::consts::OS;
|
||||
let url;
|
||||
let py_path = Path::new(&path).join("python");
|
||||
if !py_path.exists() {
|
||||
std::fs::create_dir_all(&py_path).unwrap();
|
||||
}
|
||||
let zip_path: std::path::PathBuf = Path::new(&path).join("python.zip");
|
||||
|
||||
println!("Path: {}", path);
|
||||
if os == "windows" {
|
||||
url = "https://www.python.org/ftp/python/3.11.7/python-3.11.7-embed-amd64.zip".to_string()
|
||||
}
|
||||
else{
|
||||
println!("OS not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
//download python embeddable
|
||||
let mut resp = reqwest::get(&url).await.unwrap();
|
||||
let mut out = std::fs::File::create(&zip_path).unwrap();
|
||||
let mut content = Vec::new();
|
||||
while let Some(chunk) = resp.chunk().await.unwrap() {
|
||||
content.extend_from_slice(&chunk);
|
||||
}
|
||||
out.write_all(&content).unwrap();
|
||||
|
||||
//extract python embeddable
|
||||
|
||||
use zip::ZipArchive;
|
||||
|
||||
if os == "windows" {
|
||||
let mut zipf = ZipArchive::new(std::fs::File::open(&zip_path).unwrap()).unwrap();
|
||||
zipf.extract(&py_path).unwrap();
|
||||
}
|
||||
else if os == "linux" {
|
||||
let mut tarf = tar::Archive::new(std::fs::File::open(&zip_path).unwrap());
|
||||
tarf.unpack(&py_path).unwrap();
|
||||
}
|
||||
else if os == "macos" {
|
||||
let mut zipf = zip::ZipArchive::new(std::fs::File::open(&zip_path).unwrap()).unwrap();
|
||||
zipf.extract(&py_path).unwrap();
|
||||
}
|
||||
else{
|
||||
println!("OS not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
let py_exec_path = py_path.join("python.exe");
|
||||
|
||||
//check python is installed
|
||||
let mut py = Command::new(py_exec_path);
|
||||
let output = py.arg("--version").output();
|
||||
match output {
|
||||
Ok(o) => {
|
||||
let res = String::from_utf8(o.stdout).unwrap();
|
||||
if !res.starts_with("Python ") {
|
||||
return false
|
||||
}
|
||||
println!("{}", res);
|
||||
return true
|
||||
},
|
||||
Err(e) => {
|
||||
println!("{}", e);
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn install_pip(path:String) -> bool{
|
||||
let py_path = Path::new(&path).join("python");
|
||||
let py_exec_path = py_path.join("python.exe");
|
||||
let get_pip_url = "https://bootstrap.pypa.io/get-pip.py";
|
||||
let mut resp = reqwest::get(get_pip_url).await.unwrap();
|
||||
let get_pip_path = Path::new(&path).join("get-pip.py");
|
||||
let mut out = std::fs::File::create(&get_pip_path).unwrap();
|
||||
let mut content = Vec::new();
|
||||
while let Some(chunk) = resp.chunk().await.unwrap() {
|
||||
content.extend_from_slice(&chunk);
|
||||
}
|
||||
out.write_all(&content).unwrap();
|
||||
|
||||
let mut py = Command::new(py_exec_path);
|
||||
let output = py.arg(get_pip_path).output();
|
||||
match output {
|
||||
Ok(o) => {
|
||||
let res = String::from_utf8(o.stdout).unwrap();
|
||||
println!("{}", res);
|
||||
if !res.starts_with("Python ") {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
Err(e) => {
|
||||
println!("{}", e);
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use std::process::Command;
|
||||
|
||||
#[tauri::command]
|
||||
@@ -161,6 +265,20 @@ fn check_requirements_local() -> String{
|
||||
return "success".to_string()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn post_py_install(path:String){
|
||||
let py_path = Path::new(&path).join("python");
|
||||
let py_pth_path = py_path.join("python311._pth");
|
||||
//uncomment python libs
|
||||
let mut py_pth = std::fs::read_to_string(&py_pth_path).unwrap();
|
||||
py_pth = py_pth.replace("#import site", "import site");
|
||||
std::fs::write(&py_pth_path, py_pth).unwrap();
|
||||
|
||||
//create "completed" file
|
||||
let completed_path = py_path.join("completed.txt");
|
||||
std::fs::write(&completed_path, "python311").unwrap();
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn run_server_local(){
|
||||
let app_base_path = tauri::api::path::data_dir().unwrap().join("co.aiclient.risu");
|
||||
@@ -226,7 +344,10 @@ fn main() {
|
||||
native_request,
|
||||
check_auth,
|
||||
check_requirements_local,
|
||||
run_server_local
|
||||
run_server_local,
|
||||
install_python,
|
||||
install_pip,
|
||||
post_py_install
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import SelectInput from "src/lib/UI/GUI/SelectInput.svelte";
|
||||
import OptionInput from "src/lib/UI/GUI/OptionInput.svelte";
|
||||
import Help from "src/lib/Others/Help.svelte";
|
||||
import { installPython } from "src/ts/process/models/local";
|
||||
|
||||
</script>
|
||||
<h2 class="text-2xl font-bold mt-2">{language.advancedSettings}</h2>
|
||||
@@ -123,3 +124,12 @@
|
||||
class="drop-shadow-lg p-3 border-borderc border-solid mt-6 flex justify-center items-center ml-2 mr-2 border-1 hover:bg-selected text-sm">
|
||||
{language.ShowLog}
|
||||
</button>
|
||||
{#if $DataBase.tpo}
|
||||
<button
|
||||
on:click={async () => {
|
||||
installPython()
|
||||
}}
|
||||
class="drop-shadow-lg p-3 border-borderc border-solid mt-6 flex justify-center items-center ml-2 mr-2 border-1 hover:bg-selected text-sm">
|
||||
Test Python
|
||||
</button>
|
||||
{/if}
|
||||
@@ -152,4 +152,29 @@ export async function runLocalModel(prompt:string){
|
||||
})
|
||||
|
||||
console.log(gen)
|
||||
}
|
||||
|
||||
export async function installPython(){
|
||||
const appDir = await path.appDataDir()
|
||||
const completedPath = await path.join(appDir, 'python', 'completed.txt')
|
||||
if(await exists(completedPath)){
|
||||
alertMd("Python is already installed")
|
||||
return
|
||||
}
|
||||
|
||||
alertWait("Installing Python")
|
||||
await invoke("install_python", {
|
||||
path: appDir
|
||||
})
|
||||
alertWait("Installing Pip")
|
||||
await invoke("install_pip", {
|
||||
path: appDir
|
||||
})
|
||||
alertWait("Rewriting requirements")
|
||||
await invoke('post_py_install', {
|
||||
path: appDir
|
||||
})
|
||||
alertClear()
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user