diff --git a/src/previews/mod.rs b/src/previews/mod.rs index 7cca24b..7789c5a 100644 --- a/src/previews/mod.rs +++ b/src/previews/mod.rs @@ -1,7 +1,9 @@ use crate::util::hash::Hash; +use crate::util::jobs::{Job, JobContainer, State}; use crate::{database::UpEndDatabase, util::hash::b58_encode}; use anyhow::{anyhow, Result}; use log::{debug, trace}; +use std::sync::RwLock; use std::{ collections::HashMap, fs::File, @@ -52,7 +54,12 @@ impl PreviewStore { } } - pub fn get(&self, hash: Hash, mime_type: S) -> Result> + pub fn get( + &self, + hash: Hash, + mime_type: S, + job_container: Arc>, + ) -> Result> where S: Into>, { @@ -67,8 +74,17 @@ impl PreviewStore { let connection = self.db.connection()?; let files = connection.retrieve_file(&hash)?; if let Some(file) = files.get(0) { + let job_id = job_container + .write() + .unwrap() + .add_job(Job::new( + None, + &format!("Creating preview for {:?}", file.path.file_name().unwrap()), + )) + .unwrap(); + let mime_type = mime_type.into(); - + let mime_type: Option = if mime_type.is_some() { mime_type } else { @@ -76,29 +92,43 @@ impl PreviewStore { }; let preview = match mime_type { - Some(tm) if tm.starts_with("text") => Ok(TextPath(&file.path).get_thumbnail()?), + Some(tm) if tm.starts_with("text") => TextPath(&file.path).get_thumbnail(), Some(tm) if tm.starts_with("video") || tm == "application/x-matroska" => { - Ok(VideoPath(&file.path).get_thumbnail()?) + VideoPath(&file.path).get_thumbnail() } Some(tm) if tm.starts_with("audio") || tm == "application/x-riff" => { - Ok(AudioPath(&file.path).get_thumbnail()?) - } - Some(tm) if tm.starts_with("image") => { - Ok(ImagePath(&file.path).get_thumbnail()?) + AudioPath(&file.path).get_thumbnail() } + Some(tm) if tm.starts_with("image") => ImagePath(&file.path).get_thumbnail(), Some(unknown) => Err(anyhow!("No capability for {:?} thumbnails.", unknown)), _ => Err(anyhow!("Unknown file type, or file doesn't exist.")), - }?; + }; - trace!("Got preview for {hash:?}."); + match preview { + Ok(preview) => { + trace!("Got preview for {hash:?}."); - if let Some(data) = preview { - std::fs::create_dir_all(&self.path)?; - let mut file = File::create(&*thumbpath)?; - file.write_all(&data)?; - Ok(Some(thumbpath.clone())) - } else { - Ok(None) + let _ = job_container + .write() + .unwrap() + .update_state(&job_id, State::Done); + + if let Some(data) = preview { + std::fs::create_dir_all(&self.path)?; + let mut file = File::create(&*thumbpath)?; + file.write_all(&data)?; + Ok(Some(thumbpath.clone())) + } else { + Ok(None) + } + } + Err(err) => { + let _ = job_container + .write() + .unwrap() + .update_state(&job_id, State::Failed); + Err(err) + } } } else { Err(anyhow!("Object not found, or is not a file.")) diff --git a/src/routes.rs b/src/routes.rs index a1d2b2d..d64a182 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -146,8 +146,10 @@ pub async fn get_thumbnail( .map_err(ErrorInternalServerError)?; if let Address::Hash(address_hash) = address { let preview_store = preview_store.clone(); - let preview_result = - web::block(move || preview_store.get(address_hash, query.mime)).await?; + let preview_result = web::block(move || { + preview_store.get(address_hash, query.mime, state.job_container.clone()) + }) + .await?; if let Some(preview_path) = preview_result { let mut file = NamedFile::open(&preview_path)?.disable_content_disposition();