use std::path::Path; use serde::{Deserialize, Serialize}; use crate::{error::Result, jobs::ExportFormat, storage::DynStorageBackend}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ExportResult { pub items_exported: usize, pub output_path: String, } /// Export library data to the specified format. pub async fn export_library( storage: &DynStorageBackend, format: &ExportFormat, destination: &Path, ) -> Result { let pagination = crate::model::Pagination { offset: 0, limit: u64::MAX, sort: None, }; let items = storage.list_media(&pagination).await?; let count = items.len(); match format { ExportFormat::Json => { let json = serde_json::to_string_pretty(&items).map_err(|e| { crate::error::PinakesError::Config(format!("json serialize: {e}")) })?; std::fs::write(destination, json)?; }, ExportFormat::Csv => { let mut csv = String::new(); csv.push_str( "id,path,file_name,media_type,content_hash,file_size,title,artist,\ album,genre,year,duration_secs,description,created_at,updated_at\n", ); for item in &items { csv.push_str(&format!( "{},{},{},{:?},{},{},{},{},{},{},{},{},{},{},{}\n", item.id, item.path.display(), item.file_name, item.media_type, item.content_hash, item.file_size, item.title.as_deref().unwrap_or(""), item.artist.as_deref().unwrap_or(""), item.album.as_deref().unwrap_or(""), item.genre.as_deref().unwrap_or(""), item.year.map(|y| y.to_string()).unwrap_or_default(), item .duration_secs .map(|d| d.to_string()) .unwrap_or_default(), item.description.as_deref().unwrap_or(""), item.created_at, item.updated_at, )); } std::fs::write(destination, csv)?; }, } Ok(ExportResult { items_exported: count, output_path: destination.to_string_lossy().to_string(), }) }