From 8917221b422cdb0030dce1ba3c3319fdd31da8dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Ml=C3=A1dek?= Date: Wed, 17 Jan 2024 20:31:20 +0100 Subject: [PATCH] feat(cli): add ID3 image extraction --- cli/src/extractors/audio.rs | 26 ++++++++++++++++++++++++-- cli/src/routes.rs | 2 +- db/src/stores/fs/mod.rs | 4 ++-- db/src/stores/mod.rs | 2 +- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/cli/src/extractors/audio.rs b/cli/src/extractors/audio.rs index 9f10654..f07d6cb 100644 --- a/cli/src/extractors/audio.rs +++ b/cli/src/extractors/audio.rs @@ -1,3 +1,4 @@ +use std::io::Write; use std::sync::Arc; use super::Extractor; @@ -8,10 +9,11 @@ use upend_base::{ constants::{ATTR_IN, ATTR_KEY, ATTR_LABEL, ATTR_OF}, entry::{Entry, EntryValue, InvariantEntry}, }; +use upend_db::stores::Blob; use upend_db::{ jobs::{JobContainer, JobState}, stores::{fs::FILE_MIME_KEY, UpStore}, - UpEndConnection, + BlobMode, UpEndConnection, }; lazy_static! { @@ -33,7 +35,7 @@ impl Extractor for ID3Extractor { fn get( &self, address: &Address, - _connection: &UpEndConnection, + connection: &UpEndConnection, store: Arc>, mut job_container: JobContainer, ) -> Result> { @@ -83,6 +85,26 @@ impl Extractor for ID3Extractor { }) .collect(); + for (idx, picture) in tags.pictures().enumerate() { + let tmp_dir = tempfile::tempdir()?; + let tmp_path = tmp_dir.path().join(format!("img-{}", idx)); + let mut file = std::fs::File::create(&tmp_path)?; + file.write_all(&*picture.data)?; + let hash = store.store( + connection, + Blob::from_filepath(&tmp_path), + None, + Some(BlobMode::StoreOnly), + )?; + result.push(Entry { + entity: address.clone(), + attribute: "ID3_PICTURE".to_string(), + value: EntryValue::Address(Address::Hash(hash)), + provenance: "SYSTEM EXTRACTOR".to_string(), + timestamp: chrono::Utc::now().naive_utc(), + }); + } + if !result.is_empty() { result.extend( result diff --git a/cli/src/routes.rs b/cli/src/routes.rs index 0af29ec..fd613d4 100644 --- a/cli/src/routes.rs +++ b/cli/src/routes.rs @@ -559,7 +559,7 @@ pub async fn put_blob( let options = connection.get_vault_options()?; _store .store( - connection, + &connection, Blob::from_filepath(file.path()), _filename, options.blob_mode, diff --git a/db/src/stores/fs/mod.rs b/db/src/stores/fs/mod.rs index cba0a90..e7409ab 100644 --- a/db/src/stores/fs/mod.rs +++ b/db/src/stores/fs/mod.rs @@ -645,7 +645,7 @@ impl UpStore for FsStore { fn store( &self, - connection: UpEndConnection, + connection: &UpEndConnection, blob: Blob, name_hint: Option, blob_mode: Option, @@ -694,7 +694,7 @@ impl UpStore for FsStore { .flatten(); self.insert_file_with_metadata( - &connection, + connection, &final_path, upath, hash.clone(), diff --git a/db/src/stores/mod.rs b/db/src/stores/mod.rs index 7e9cc1c..39d2893 100644 --- a/db/src/stores/mod.rs +++ b/db/src/stores/mod.rs @@ -57,7 +57,7 @@ pub trait UpStore { fn retrieve_all(&self) -> Result>; fn store( &self, - connection: UpEndConnection, + connection: &UpEndConnection, blob: Blob, name_hint: Option, blob_mode: Option,