Files
libertas/libertas_worker/src/plugins/xmp_writer.rs

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(),
})
}
}