fetch essentials from url
This commit is contained in:
@@ -4,12 +4,26 @@ use std::fs;
|
||||
use std::process::{Command, Stdio};
|
||||
use std::os::windows::process::CommandExt;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::path::PathBuf;
|
||||
use tokio::sync::mpsc;
|
||||
use tauri::{AppHandle, Manager, State, Emitter};
|
||||
use serde::Serialize;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use winget::{Software, list_all_software, list_updates, ensure_winget_dependencies};
|
||||
use regex::Regex;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct AppSettings {
|
||||
pub repo_url: String,
|
||||
}
|
||||
|
||||
impl Default for AppSettings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
repo_url: "https://karlblue.github.io/winget-repo".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct AppState {
|
||||
install_tx: mpsc::Sender<String>,
|
||||
}
|
||||
@@ -34,46 +48,94 @@ pub fn emit_log(handle: &AppHandle, id: &str, command: &str, output: &str, statu
|
||||
});
|
||||
}
|
||||
|
||||
fn get_settings_path(app: &AppHandle) -> PathBuf {
|
||||
let app_data_dir = app.path().app_data_dir().unwrap_or_default();
|
||||
if !app_data_dir.exists() {
|
||||
let _ = fs::create_dir_all(&app_data_dir);
|
||||
}
|
||||
app_data_dir.join("settings.json")
|
||||
}
|
||||
|
||||
fn get_essentials_path(app: &AppHandle) -> PathBuf {
|
||||
let app_data_dir = app.path().app_data_dir().unwrap_or_default();
|
||||
if !app_data_dir.exists() {
|
||||
let _ = fs::create_dir_all(&app_data_dir);
|
||||
}
|
||||
app_data_dir.join("setup-essentials.json")
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn get_settings(app: AppHandle) -> AppSettings {
|
||||
let path = get_settings_path(&app);
|
||||
if !path.exists() {
|
||||
let default_settings = AppSettings::default();
|
||||
let _ = fs::write(&path, serde_json::to_string_pretty(&default_settings).unwrap());
|
||||
return default_settings;
|
||||
}
|
||||
let content = fs::read_to_string(path).unwrap_or_default();
|
||||
serde_json::from_str(&content).unwrap_or_default()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn save_settings(app: AppHandle, settings: AppSettings) -> Result<(), String> {
|
||||
let path = get_settings_path(&app);
|
||||
let content = serde_json::to_string_pretty(&settings).map_err(|e| e.to_string())?;
|
||||
fs::write(path, content).map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn sync_essentials(app: AppHandle) -> Result<bool, String> {
|
||||
let settings = get_settings(app.clone());
|
||||
let url = format!("{}/setup-essentials.json", settings.repo_url.trim_end_matches('/'));
|
||||
|
||||
emit_log(&app, "sync-essentials", "Syncing Essentials", &format!("Downloading from {}...", url), "info");
|
||||
|
||||
let client = reqwest::Client::builder()
|
||||
.timeout(std::time::Duration::from_secs(10))
|
||||
.build()
|
||||
.map_err(|e| e.to_string())?;
|
||||
|
||||
match client.get(&url).send().await {
|
||||
Ok(response) => {
|
||||
if response.status().is_success() {
|
||||
let content = response.text().await.map_err(|e| e.to_string())?;
|
||||
// 验证 JSON 格式
|
||||
let validation: Result<Vec<Software>, _> = serde_json::from_str(&content);
|
||||
if validation.is_ok() {
|
||||
let path = get_essentials_path(&app);
|
||||
fs::write(path, content).map_err(|e| e.to_string())?;
|
||||
emit_log(&app, "sync-essentials", "Result", "Essentials list updated successfully.", "success");
|
||||
Ok(true)
|
||||
} else {
|
||||
emit_log(&app, "sync-essentials", "Error", "Invalid JSON format from repository.", "error");
|
||||
Err("Invalid JSON format".to_string())
|
||||
}
|
||||
} else {
|
||||
let err_msg = format!("HTTP Error: {}", response.status());
|
||||
emit_log(&app, "sync-essentials", "Error", &err_msg, "error");
|
||||
Err(err_msg)
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
emit_log(&app, "sync-essentials", "Skipped", &format!("Network issue: {}. Using local cache.", e), "info");
|
||||
Ok(false) // 静默失败,返回 false 表示未更新但可继续
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn initialize_app(app: AppHandle) -> Result<bool, String> {
|
||||
let app_clone = app.clone();
|
||||
tokio::task::spawn_blocking(move || {
|
||||
ensure_winget_dependencies(&app).map(|_| true)
|
||||
ensure_winget_dependencies(&app_clone).map(|_| true)
|
||||
}).await.unwrap_or(Err("Initialization Task Panicked".to_string()))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn get_essentials(app: AppHandle) -> Vec<Software> {
|
||||
let app_data_dir = app.path().app_data_dir().unwrap_or_default();
|
||||
if !app_data_dir.exists() {
|
||||
let _ = fs::create_dir_all(&app_data_dir);
|
||||
}
|
||||
|
||||
let file_path = app_data_dir.join("setup-essentials.json");
|
||||
let file_path = get_essentials_path(&app);
|
||||
if !file_path.exists() {
|
||||
let default_essentials = vec![
|
||||
Software {
|
||||
id: "Microsoft.PowerToys".to_string(),
|
||||
name: "PowerToys".to_string(),
|
||||
description: Some("Microsoft PowerToys 是一组实用程序,供高级用户调整和简化其 Windows 10 和 11 体验。".to_string()),
|
||||
version: None,
|
||||
available_version: None,
|
||||
icon_url: Some("https://raw.githubusercontent.com/microsoft/PowerToys/master/doc/images/logo.png".to_string()),
|
||||
status: "idle".to_string(),
|
||||
progress: 0.0,
|
||||
},
|
||||
Software {
|
||||
id: "Google.Chrome".to_string(),
|
||||
name: "Google Chrome".to_string(),
|
||||
description: Some("Google Chrome 是一款快速、安全且免费的浏览器。".to_string()),
|
||||
version: None,
|
||||
available_version: None,
|
||||
icon_url: Some("https://www.google.com/chrome/static/images/chrome-logo.svg".to_string()),
|
||||
status: "idle".to_string(),
|
||||
progress: 0.0,
|
||||
}
|
||||
];
|
||||
let _ = fs::write(&file_path, serde_json::to_string_pretty(&default_essentials).unwrap());
|
||||
return default_essentials;
|
||||
return vec![];
|
||||
}
|
||||
|
||||
let content = fs::read_to_string(file_path).unwrap_or_else(|_| "[]".to_string());
|
||||
@@ -210,6 +272,9 @@ pub fn run() {
|
||||
})
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
initialize_app,
|
||||
get_settings,
|
||||
save_settings,
|
||||
sync_essentials,
|
||||
get_essentials,
|
||||
get_all_software,
|
||||
get_updates,
|
||||
|
||||
Reference in New Issue
Block a user