polishing
This commit is contained in:
141
src-tauri/src/models.rs
Normal file
141
src-tauri/src/models.rs
Normal file
@ -0,0 +1,141 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct ModelInfo {
|
||||
pub name: String,
|
||||
pub path: String,
|
||||
pub size_bytes: u64,
|
||||
pub kind: String,
|
||||
}
|
||||
|
||||
fn huggingface_cache_dir() -> PathBuf {
|
||||
// Follows huggingface_hub default cache location
|
||||
if let Ok(custom) = std::env::var("HF_HOME") {
|
||||
return PathBuf::from(custom).join("hub");
|
||||
}
|
||||
if let Ok(custom) = std::env::var("XDG_CACHE_HOME") {
|
||||
return PathBuf::from(custom).join("huggingface").join("hub");
|
||||
}
|
||||
dirs::home_dir()
|
||||
.unwrap_or_default()
|
||||
.join(".cache")
|
||||
.join("huggingface")
|
||||
.join("hub")
|
||||
}
|
||||
|
||||
fn scan_whisper_models() -> Vec<ModelInfo> {
|
||||
let cache_dir = huggingface_cache_dir();
|
||||
if !cache_dir.exists() {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
let mut models = vec![];
|
||||
let pattern = "models--Systran--faster-whisper-";
|
||||
let Ok(entries) = std::fs::read_dir(&cache_dir) else {
|
||||
return vec![];
|
||||
};
|
||||
|
||||
for entry in entries.flatten() {
|
||||
let name = entry.file_name();
|
||||
let name_str = name.to_string_lossy();
|
||||
if !name_str.starts_with(pattern) {
|
||||
continue;
|
||||
}
|
||||
let model_name = name_str
|
||||
.strip_prefix(pattern)
|
||||
.unwrap_or(&name_str)
|
||||
.to_string();
|
||||
|
||||
// The actual model files are in snapshots/ subdirectory
|
||||
let snapshots_dir = entry.path().join("snapshots");
|
||||
let mut total_size = 0u64;
|
||||
if let Ok(snap_entries) = std::fs::read_dir(&snapshots_dir) {
|
||||
for snap in snap_entries.flatten() {
|
||||
total_size += dir_size(&snap.path());
|
||||
}
|
||||
}
|
||||
|
||||
// If no snapshots dir, try blobs/
|
||||
if total_size == 0 {
|
||||
let blobs_dir = entry.path().join("blobs");
|
||||
if blobs_dir.exists() {
|
||||
total_size = dir_size(&blobs_dir);
|
||||
}
|
||||
}
|
||||
|
||||
models.push(ModelInfo {
|
||||
name: model_name,
|
||||
path: entry.path().to_string_lossy().to_string(),
|
||||
size_bytes: total_size,
|
||||
kind: "whisper".to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
models
|
||||
}
|
||||
|
||||
fn scan_llm_models(app_data_dir: &PathBuf) -> Vec<ModelInfo> {
|
||||
let models_dir = app_data_dir.join("models");
|
||||
if !models_dir.exists() {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
let mut models = vec![];
|
||||
let Ok(entries) = std::fs::read_dir(&models_dir) else {
|
||||
return vec![];
|
||||
};
|
||||
|
||||
for entry in entries.flatten() {
|
||||
let path = entry.path();
|
||||
if path.extension().map(|e| e == "gguf").unwrap_or(false) {
|
||||
let meta = std::fs::metadata(&path).ok();
|
||||
models.push(ModelInfo {
|
||||
name: entry.file_name().to_string_lossy().to_string(),
|
||||
path: path.to_string_lossy().to_string(),
|
||||
size_bytes: meta.map(|m| m.len()).unwrap_or(0),
|
||||
kind: "llm".to_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
models
|
||||
}
|
||||
|
||||
fn dir_size(path: &std::path::Path) -> u64 {
|
||||
let mut total = 0u64;
|
||||
if let Ok(entries) = std::fs::read_dir(path) {
|
||||
for entry in entries.flatten() {
|
||||
let path = entry.path();
|
||||
if path.is_dir() {
|
||||
total += dir_size(&path);
|
||||
} else if let Ok(meta) = std::fs::metadata(&path) {
|
||||
total += meta.len();
|
||||
}
|
||||
}
|
||||
}
|
||||
total
|
||||
}
|
||||
|
||||
pub fn list_models(app_data_dir: &PathBuf) -> Vec<ModelInfo> {
|
||||
let mut models = scan_whisper_models();
|
||||
models.extend(scan_llm_models(app_data_dir));
|
||||
models
|
||||
}
|
||||
|
||||
pub fn delete_model(path: &str) -> Result<(), String> {
|
||||
let path = std::path::Path::new(path);
|
||||
if !path.exists() {
|
||||
return Err("Model path not found".to_string());
|
||||
}
|
||||
|
||||
if path.is_dir() {
|
||||
std::fs::remove_dir_all(path)
|
||||
.map_err(|e| format!("Failed to delete model: {e}"))?;
|
||||
} else {
|
||||
std::fs::remove_file(path)
|
||||
.map_err(|e| format!("Failed to delete model: {e}"))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user