jan/src-tauri/src/core/system/commands.rs
2025-10-06 10:55:17 +07:00

121 lines
3.8 KiB
Rust

use std::fs;
use std::path::PathBuf;
use tauri::{AppHandle, Manager, Runtime, State};
use tauri_plugin_llamacpp::cleanup_llama_processes;
use crate::core::app::commands::{
default_data_folder_path, get_jan_data_folder_path, update_app_configuration,
};
use crate::core::app::models::AppConfiguration;
use crate::core::mcp::helpers::clean_up_mcp_servers;
use crate::core::state::AppState;
#[tauri::command]
pub fn factory_reset<R: Runtime>(app_handle: tauri::AppHandle<R>, state: State<'_, AppState>) {
// close window (not available on mobile platforms)
#[cfg(not(any(target_os = "ios", target_os = "android")))]
{
let windows = app_handle.webview_windows();
for (label, window) in windows.iter() {
window.close().unwrap_or_else(|_| {
log::warn!("Failed to close window: {label:?}");
});
}
}
let data_folder = get_jan_data_folder_path(app_handle.clone());
log::info!("Factory reset, removing data folder: {data_folder:?}");
tauri::async_runtime::block_on(async {
clean_up_mcp_servers(state.clone()).await;
let _ = cleanup_llama_processes(app_handle.clone()).await;
if data_folder.exists() {
if let Err(e) = fs::remove_dir_all(&data_folder) {
log::error!("Failed to remove data folder: {e}");
return;
}
}
// Recreate the data folder
let _ = fs::create_dir_all(&data_folder).map_err(|e| e.to_string());
// Reset the configuration
let mut default_config = AppConfiguration::default();
default_config.data_folder = default_data_folder_path(app_handle.clone());
let _ = update_app_configuration(app_handle.clone(), default_config);
app_handle.restart();
});
}
#[tauri::command]
pub fn relaunch<R: Runtime>(app: AppHandle<R>) {
app.restart()
}
#[tauri::command]
pub fn open_app_directory<R: Runtime>(app: AppHandle<R>) {
let app_path = app.path().app_data_dir().unwrap();
if cfg!(target_os = "windows") {
std::process::Command::new("explorer")
.arg(app_path)
.status()
.expect("Failed to open app directory");
} else if cfg!(target_os = "macos") {
std::process::Command::new("open")
.arg(app_path)
.status()
.expect("Failed to open app directory");
} else {
std::process::Command::new("xdg-open")
.arg(app_path)
.status()
.expect("Failed to open app directory");
}
}
#[tauri::command]
pub fn open_file_explorer(path: String) {
let path = PathBuf::from(path);
if cfg!(target_os = "windows") {
std::process::Command::new("explorer")
.arg(path)
.status()
.expect("Failed to open file explorer");
} else if cfg!(target_os = "macos") {
std::process::Command::new("open")
.arg(path)
.status()
.expect("Failed to open file explorer");
} else {
std::process::Command::new("xdg-open")
.arg(path)
.status()
.expect("Failed to open file explorer");
}
}
#[tauri::command]
pub async fn read_logs<R: Runtime>(app: AppHandle<R>) -> Result<String, String> {
let log_path = get_jan_data_folder_path(app).join("logs").join("app.log");
if log_path.exists() {
let content = fs::read_to_string(log_path).map_err(|e| e.to_string())?;
Ok(content)
} else {
Err("Log file not found".to_string())
}
}
// check if a system library is available
#[tauri::command]
pub fn is_library_available(library: &str) -> bool {
match unsafe { libloading::Library::new(library) } {
Ok(_) => true,
Err(e) => {
log::info!("Library {library} is not available: {e}");
false
}
}
}