Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Ia01590cdeed872cc8ebd16f6ca95f3cc6a6a6964
68 lines
1.9 KiB
Rust
68 lines
1.9 KiB
Rust
pub mod audio;
|
|
pub mod document;
|
|
pub mod image;
|
|
pub mod markdown;
|
|
pub mod video;
|
|
|
|
use std::{collections::HashMap, path::Path};
|
|
|
|
use crate::{error::Result, media_type::MediaType, model::BookMetadata};
|
|
|
|
#[derive(Debug, Clone, Default)]
|
|
pub struct ExtractedMetadata {
|
|
pub title: Option<String>,
|
|
pub artist: Option<String>,
|
|
pub album: Option<String>,
|
|
pub genre: Option<String>,
|
|
pub year: Option<i32>,
|
|
pub duration_secs: Option<f64>,
|
|
pub description: Option<String>,
|
|
pub extra: HashMap<String, String>,
|
|
pub book_metadata: Option<BookMetadata>,
|
|
|
|
// Photo-specific metadata
|
|
pub date_taken: Option<chrono::DateTime<chrono::Utc>>,
|
|
pub latitude: Option<f64>,
|
|
pub longitude: Option<f64>,
|
|
pub camera_make: Option<String>,
|
|
pub camera_model: Option<String>,
|
|
pub rating: Option<i32>,
|
|
}
|
|
|
|
pub trait MetadataExtractor: Send + Sync {
|
|
/// Extract metadata from a file at the given path.
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// Returns an error if the file cannot be read or parsed.
|
|
fn extract(&self, path: &Path) -> Result<ExtractedMetadata>;
|
|
fn supported_types(&self) -> Vec<MediaType>;
|
|
}
|
|
|
|
/// Extract metadata from a file using the appropriate extractor for the given
|
|
/// media type.
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// Returns an error if no extractor supports the media type, or if extraction
|
|
/// fails.
|
|
pub fn extract_metadata(
|
|
path: &Path,
|
|
media_type: &MediaType,
|
|
) -> Result<ExtractedMetadata> {
|
|
let extractors: Vec<Box<dyn MetadataExtractor>> = vec![
|
|
Box::new(audio::AudioExtractor),
|
|
Box::new(document::DocumentExtractor),
|
|
Box::new(video::VideoExtractor),
|
|
Box::new(markdown::MarkdownExtractor),
|
|
Box::new(image::ImageExtractor),
|
|
];
|
|
|
|
for extractor in &extractors {
|
|
if extractor.supported_types().contains(media_type) {
|
|
return extractor.extract(path);
|
|
}
|
|
}
|
|
|
|
Ok(ExtractedMetadata::default())
|
|
}
|