thumbnail creation as jobs

feat/vaults
Tomáš Mládek 2022-02-10 15:11:38 +01:00
parent 0dd5616e9c
commit 7c38406b16
No known key found for this signature in database
GPG Key ID: 65E225C8B3E2ED8A
2 changed files with 51 additions and 19 deletions

View File

@ -1,7 +1,9 @@
use crate::util::hash::Hash; use crate::util::hash::Hash;
use crate::util::jobs::{Job, JobContainer, State};
use crate::{database::UpEndDatabase, util::hash::b58_encode}; use crate::{database::UpEndDatabase, util::hash::b58_encode};
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use log::{debug, trace}; use log::{debug, trace};
use std::sync::RwLock;
use std::{ use std::{
collections::HashMap, collections::HashMap,
fs::File, fs::File,
@ -52,7 +54,12 @@ impl PreviewStore {
} }
} }
pub fn get<S>(&self, hash: Hash, mime_type: S) -> Result<Option<PathBuf>> pub fn get<S>(
&self,
hash: Hash,
mime_type: S,
job_container: Arc<RwLock<JobContainer>>,
) -> Result<Option<PathBuf>>
where where
S: Into<Option<String>>, S: Into<Option<String>>,
{ {
@ -67,8 +74,17 @@ impl PreviewStore {
let connection = self.db.connection()?; let connection = self.db.connection()?;
let files = connection.retrieve_file(&hash)?; let files = connection.retrieve_file(&hash)?;
if let Some(file) = files.get(0) { 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 = mime_type.into();
let mime_type: Option<String> = if mime_type.is_some() { let mime_type: Option<String> = if mime_type.is_some() {
mime_type mime_type
} else { } else {
@ -76,29 +92,43 @@ impl PreviewStore {
}; };
let preview = match mime_type { 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" => { 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" => { Some(tm) if tm.starts_with("audio") || tm == "application/x-riff" => {
Ok(AudioPath(&file.path).get_thumbnail()?) AudioPath(&file.path).get_thumbnail()
}
Some(tm) if tm.starts_with("image") => {
Ok(ImagePath(&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)), Some(unknown) => Err(anyhow!("No capability for {:?} thumbnails.", unknown)),
_ => Err(anyhow!("Unknown file type, or file doesn't exist.")), _ => 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 { let _ = job_container
std::fs::create_dir_all(&self.path)?; .write()
let mut file = File::create(&*thumbpath)?; .unwrap()
file.write_all(&data)?; .update_state(&job_id, State::Done);
Ok(Some(thumbpath.clone()))
} else { if let Some(data) = preview {
Ok(None) 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 { } else {
Err(anyhow!("Object not found, or is not a file.")) Err(anyhow!("Object not found, or is not a file."))

View File

@ -146,8 +146,10 @@ pub async fn get_thumbnail(
.map_err(ErrorInternalServerError)?; .map_err(ErrorInternalServerError)?;
if let Address::Hash(address_hash) = address { if let Address::Hash(address_hash) = address {
let preview_store = preview_store.clone(); let preview_store = preview_store.clone();
let preview_result = let preview_result = web::block(move || {
web::block(move || preview_store.get(address_hash, query.mime)).await?; preview_store.get(address_hash, query.mime, state.job_container.clone())
})
.await?;
if let Some(preview_path) = preview_result { if let Some(preview_path) = preview_result {
let mut file = NamedFile::open(&preview_path)?.disable_content_disposition(); let mut file = NamedFile::open(&preview_path)?.disable_content_disposition();