| use std::fs; |
| use std::path::PathBuf; |
| use tauri::{AppHandle, Manager}; |
|
|
| pub fn app_file_path(app: &AppHandle, name: &str) -> Result<PathBuf, String> { |
| let dir = app.path().app_data_dir().map_err(|e| e.to_string())?.join("musealpha"); |
| fs::create_dir_all(&dir).map_err(|e| e.to_string())?; |
| Ok(dir.join(name)) |
| } |
|
|
| pub fn save_json<T: serde::Serialize>(app: &AppHandle, name: &str, value: &T) -> Result<(), String> { |
| let path = app_file_path(app, name)?; |
| let json = serde_json::to_string_pretty(value).map_err(|e| e.to_string())?; |
| fs::write(path, json).map_err(|e| e.to_string()) |
| } |
|
|
| pub fn load_json<T: serde::de::DeserializeOwned + Default>(app: &AppHandle, name: &str) -> Result<T, String> { |
| let path = app_file_path(app, name)?; |
| if !path.exists() { |
| return Ok(T::default()); |
| } |
| let json = fs::read_to_string(path).map_err(|e| e.to_string())?; |
| serde_json::from_str(&json).map_err(|e| e.to_string()) |
| } |
|
|
| |
| #[derive(serde::Serialize)] |
| pub struct StorageInfo { |
| pub data_path: String, |
| pub total_size_bytes: u64, |
| pub file_count: usize, |
| pub project_count: usize, |
| pub library_count: usize, |
| pub library_size_bytes: u64, |
| pub projects_size_bytes: u64, |
| } |
|
|
| #[tauri::command] |
| pub fn storage_info(app: AppHandle) -> Result<StorageInfo, String> { |
| let dir = app.path().app_data_dir().map_err(|e| e.to_string())?.join("musealpha"); |
| let data_path = dir.to_string_lossy().to_string(); |
|
|
| if !dir.exists() { |
| return Ok(StorageInfo { data_path, total_size_bytes: 0, file_count: 0, project_count: 0, library_count: 0, library_size_bytes: 0, projects_size_bytes: 0 }); |
| } |
|
|
| let mut total_size: u64 = 0; |
| let mut file_count: usize = 0; |
| let mut projects_size: u64 = 0; |
| let mut project_count: usize = 0; |
| let mut library_size: u64 = 0; |
|
|
| if let Ok(entries) = fs::read_dir(&dir) { |
| for entry in entries.flatten() { |
| if let Ok(meta) = entry.metadata() { |
| if meta.is_file() { |
| let size = meta.len(); |
| total_size += size; |
| file_count += 1; |
| let name = entry.file_name().to_string_lossy().to_string(); |
| if name.starts_with("project_") && name.ends_with(".json") { |
| projects_size += size; |
| project_count += 1; |
| } |
| if name == "library.json" { |
| library_size = size; |
| } |
| } |
| } |
| } |
| } |
|
|
| |
| let library_count = load_json::<Vec<serde_json::Value>>(&app, "library.json").map(|v| v.len()).unwrap_or(0); |
|
|
| Ok(StorageInfo { data_path, total_size_bytes: total_size, file_count, project_count, library_count, library_size_bytes: library_size, projects_size_bytes: projects_size }) |
| } |
|
|
| |
| #[tauri::command] |
| pub fn storage_clear_library(app: AppHandle) -> Result<(), String> { |
| let path = app_file_path(&app, "library.json")?; |
| if path.exists() { fs::write(&path, "[]").map_err(|e| e.to_string())?; } |
| |
| let state = app.state::<crate::library::LibraryState>(); |
| let mut items = state.items.lock().map_err(|_| "lock")?; |
| items.clear(); |
| Ok(()) |
| } |
|
|
| |
| #[tauri::command] |
| pub fn storage_clear_projects(app: AppHandle) -> Result<(), String> { |
| let dir = app.path().app_data_dir().map_err(|e| e.to_string())?.join("musealpha"); |
| if let Ok(entries) = fs::read_dir(&dir) { |
| for entry in entries.flatten() { |
| let name = entry.file_name().to_string_lossy().to_string(); |
| if name.starts_with("project_") && name.ends_with(".json") { |
| let _ = fs::remove_file(entry.path()); |
| } |
| } |
| } |
| |
| save_json(&app, "projects_index.json", &serde_json::json!({"projects": [], "active_id": null}))?; |
| Ok(()) |
| } |
|
|
| |
| #[tauri::command] |
| pub fn storage_reveal_folder(app: AppHandle) -> Result<(), String> { |
| let dir = app.path().app_data_dir().map_err(|e| e.to_string())?.join("musealpha"); |
| fs::create_dir_all(&dir).map_err(|e| e.to_string())?; |
| opener::open(dir.to_string_lossy().as_ref()).map_err(|e| format!("Could not open folder: {e}")) |
| } |
|
|