feat: add cache IPC commands for analysis caching

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-22 14:41:37 -04:00
parent 1773ae81e6
commit b7fb7929f0
3 changed files with 162 additions and 1 deletions

View File

@@ -0,0 +1,153 @@
use crate::models::{ThumbnailSpritesheet, WaveformTiers};
use crate::services::cache_manager::{self, CacheManifest, CacheStats};
use serde::Serialize;
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CachedAnalysis {
pub waveform_tiers: Option<WaveformTiers>,
pub keyframe_positions: Vec<f64>,
pub thumbnail_spritesheets: Vec<ThumbnailSpritesheet>,
pub caption_file_path: Option<String>,
}
#[tauri::command]
pub async fn load_cached_analysis(url: String) -> Option<CachedAnalysis> {
let url_clone = url.clone();
let manifest = tokio::task::spawn_blocking(move || cache_manager::load_manifest(&url_clone))
.await
.ok()
.flatten()?;
let cache_dir = cache_manager::cache_dir_for_url(&url);
// Resolve relative paths in thumbnail spritesheets to absolute paths
let spritesheets: Vec<ThumbnailSpritesheet> = manifest
.thumbnail_spritesheets
.into_iter()
.map(|mut sheet| {
let abs_path = cache_dir.join(&sheet.file_path);
sheet.file_path = abs_path.to_string_lossy().to_string();
sheet
})
.collect();
// Verify thumbnail files actually exist on disk
let thumbs_valid = if spritesheets.is_empty() {
false
} else {
let first_dir = std::path::Path::new(&spritesheets[0].file_path);
first_dir.is_dir()
};
// Resolve caption path to absolute
let caption_path = manifest
.caption_file_path
.map(|rel| cache_dir.join(&rel).to_string_lossy().to_string())
.filter(|p| std::path::Path::new(p).is_file());
Some(CachedAnalysis {
waveform_tiers: manifest.waveform_tiers,
keyframe_positions: manifest.keyframe_positions,
thumbnail_spritesheets: if thumbs_valid {
spritesheets
} else {
vec![]
},
caption_file_path: caption_path,
})
}
#[tauri::command]
pub async fn save_analysis_to_cache(
url: String,
title: String,
duration: f64,
fps: f64,
waveform_tiers: Option<WaveformTiers>,
keyframe_positions: Vec<f64>,
thumbnail_spritesheets: Vec<ThumbnailSpritesheet>,
caption_file_path: Option<String>,
) -> Result<(), String> {
let cache_dir = cache_manager::cache_dir_for_url(&url);
// Convert absolute spritesheet paths to relative
let relative_sheets: Vec<ThumbnailSpritesheet> = thumbnail_spritesheets
.into_iter()
.map(|mut sheet| {
if let Ok(rel) = std::path::Path::new(&sheet.file_path).strip_prefix(&cache_dir) {
sheet.file_path = rel.to_string_lossy().to_string();
}
sheet
})
.collect();
// Convert absolute caption path to relative
let relative_caption = caption_file_path.and_then(|abs| {
std::path::Path::new(&abs)
.strip_prefix(&cache_dir)
.ok()
.map(|rel| rel.to_string_lossy().to_string())
});
let now = format!(
"{}",
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_secs()
);
let manifest = CacheManifest {
version: 1,
source_url: url.clone(),
title,
duration,
fps,
created_at: now.clone(),
last_accessed_at: now,
waveform_tiers,
keyframe_positions,
thumbnail_spritesheets: relative_sheets,
caption_file_path: relative_caption,
};
tokio::task::spawn_blocking(move || cache_manager::save_manifest(&url, &manifest))
.await
.map_err(|e| format!("Task failed: {e}"))?
}
#[tauri::command]
pub async fn clear_video_cache(url: String) -> Result<(), String> {
tokio::task::spawn_blocking(move || cache_manager::clear_cache_entry(&url))
.await
.map_err(|e| format!("Task failed: {e}"))?
}
#[tauri::command]
pub async fn clear_all_cache() -> Result<(), String> {
tokio::task::spawn_blocking(cache_manager::clear_all_cache)
.await
.map_err(|e| format!("Task failed: {e}"))?
}
#[tauri::command]
pub async fn get_cache_stats() -> Result<CacheStats, String> {
tokio::task::spawn_blocking(cache_manager::get_cache_stats)
.await
.map_err(|e| format!("Task failed: {e}"))?
}
#[tauri::command]
pub fn get_thumbnail_cache_dir(url: String) -> String {
let dir = cache_manager::thumbnail_cache_dir(&url);
std::fs::create_dir_all(&dir).ok();
dir.to_string_lossy().to_string()
}
#[tauri::command]
pub fn get_caption_cache_dir(url: String) -> String {
let dir = cache_manager::caption_cache_dir(&url);
std::fs::create_dir_all(&dir).ok();
dir.to_string_lossy().to_string()
}

View File

@@ -1,3 +1,4 @@
pub mod cache;
pub mod dependencies;
pub mod export;
pub mod media_analysis;