67 lines
2.0 KiB
Rust
67 lines
2.0 KiB
Rust
use std::path::PathBuf;
|
|
|
|
use async_trait::async_trait;
|
|
use libertas_core::{
|
|
error::{CoreError, CoreResult},
|
|
models::Media,
|
|
plugins::{MediaProcessorPlugin, PluginContext, PluginData},
|
|
};
|
|
use tokio::fs;
|
|
use xmp_toolkit::{XmpMeta, XmpValue};
|
|
|
|
pub struct XmpWriterPlugin;
|
|
|
|
#[async_trait]
|
|
impl MediaProcessorPlugin for XmpWriterPlugin {
|
|
fn name(&self) -> &'static str {
|
|
"xmp_writer"
|
|
}
|
|
|
|
async fn process(&self, media: &Media, context: &PluginContext) -> CoreResult<PluginData> {
|
|
let fresh_media = context
|
|
.media_repo
|
|
.find_by_id(media.id)
|
|
.await?
|
|
.ok_or(CoreError::NotFound("Media".to_string(), media.id))?;
|
|
|
|
let file_path = PathBuf::from(&context.media_library_path).join(&fresh_media.storage_path);
|
|
let xmp_path = format!("{}.xmp", file_path.to_string_lossy());
|
|
|
|
let mut xmp = XmpMeta::new()
|
|
.map_err(|e| CoreError::Unknown(format!("Failed to create new XMP metadata: {}", e)))?;
|
|
|
|
xmp.set_property(
|
|
"http://purl.org/dc/elements/1.1/",
|
|
"description",
|
|
&fresh_media.original_filename.into(),
|
|
)
|
|
.map_err(|e| {
|
|
CoreError::Unknown(format!("Failed to set description property in XMP: {}", e))
|
|
})?;
|
|
|
|
if let Some(date_taken) = &fresh_media.date_taken {
|
|
let date_str = date_taken.to_rfc3339();
|
|
xmp.set_property(
|
|
"http://ns.adobe.com/exif/1.0/",
|
|
"DateTimeOriginal",
|
|
&XmpValue::from(date_str),
|
|
)
|
|
.map_err(|e| {
|
|
CoreError::Unknown(format!("Failed to set DateTimeOriginal in XMP: {}", e))
|
|
})?;
|
|
}
|
|
|
|
if let Some(_location) = &fresh_media.extracted_location {
|
|
// TODO: Set location properties in XMP
|
|
}
|
|
|
|
let xmp_str = xmp.to_string();
|
|
|
|
fs::write(&xmp_path, xmp_str).await?;
|
|
|
|
Ok(PluginData {
|
|
message: "XMP sidecar written successfully.".to_string(),
|
|
})
|
|
}
|
|
}
|