Add Python installation and setup functionality

This commit is contained in:
kwaroran
2024-01-12 12:02:06 +09:00
parent 11ae0266d9
commit b4b461288d
5 changed files with 333 additions and 1 deletions

View File

@@ -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");