fix: previews are cached re: mimetype as well

feat/type-attributes
Tomáš Mládek 2022-09-18 12:54:09 +02:00
parent 0bb4639859
commit b04a00c660
2 changed files with 31 additions and 20 deletions

View File

@ -26,11 +26,13 @@ pub mod video;
pub trait Previewable {
fn get_thumbnail(&self) -> Result<Option<Vec<u8>>>;
}
type HashWithOptions = (Hash, String);
pub struct PreviewStore {
path: PathBuf,
store: Arc<Box<dyn UpStore + Send + Sync>>,
locks: Mutex<HashMap<Hash, Arc<Mutex<PathBuf>>>>,
locks: Mutex<HashMap<HashWithOptions, Arc<Mutex<PathBuf>>>>,
}
#[cfg(feature = "previews")]
@ -43,29 +45,39 @@ impl PreviewStore {
}
}
fn get_path(&self, hash: &Hash) -> Arc<Mutex<PathBuf>> {
fn get_path(&self, hash: &Hash, options: &HashMap<String, String>) -> Arc<Mutex<PathBuf>> {
let mut locks = self.locks.lock().unwrap();
if let Some(path) = locks.get(hash) {
let options_concat = options
.iter()
.map(|(k, v)| format!("{k}{v}"))
.collect::<String>();
if let Some(path) = locks.get(&(hash.clone(), options_concat.clone())) {
path.clone()
} else {
let thumbpath = self.path.join(b58_encode(hash));
let thumbpath = self.path.join(format!(
"{}{}",
b58_encode(hash),
if options_concat.is_empty() {
String::from("")
} else {
format!("_{options_concat}")
}
));
let path = Arc::new(Mutex::new(thumbpath));
locks.insert(hash.clone(), path.clone());
locks.insert((hash.clone(), options_concat), path.clone());
path
}
}
pub fn get<S>(
pub fn get(
&self,
hash: Hash,
mime_type: S,
options: HashMap<String, String>,
mut job_container: JobContainer,
) -> Result<Option<PathBuf>>
where
S: Into<Option<String>>,
{
) -> Result<Option<PathBuf>> {
debug!("Preview for {hash:?} requested...");
let path_mutex = self.get_path(&hash);
let path_mutex = self.get_path(&hash, &options);
let thumbpath = path_mutex.lock().unwrap();
if thumbpath.exists() {
trace!("Preview for {hash:?} already exists, returning {thumbpath:?}");
@ -80,7 +92,7 @@ impl PreviewStore {
&format!("Creating preview for {:?}", file_path.file_name().unwrap()),
)?;
let mime_type = mime_type.into();
let mime_type = options.get("mime").map(|x| x.to_owned());
let mime_type: Option<String> = if mime_type.is_some() {
mime_type

View File

@ -207,16 +207,11 @@ pub async fn get_raw(
}
}
#[derive(Deserialize)]
pub struct ThumbRequest {
mime: Option<String>,
}
#[get("/api/thumb/{hash}")]
pub async fn get_thumbnail(
state: web::Data<State>,
hash: web::Path<String>,
web::Query(query): web::Query<ThumbRequest>,
web::Query(query): web::Query<HashMap<String, String>>,
) -> Result<Either<NamedFile, HttpResponse>, Error> {
#[cfg(feature = "previews")]
if let Some(preview_store) = &state.preview_store {
@ -228,7 +223,11 @@ pub async fn get_thumbnail(
let (tx, rx) = oneshot::channel();
let _job_container = state.job_container.clone();
state.preview_pool.as_ref().unwrap().spawn(move || {
let result = preview_store.get(address_hash, query.mime, _job_container);
let result = preview_store.get(
address_hash,
query,
_job_container,
);
tx.send(result).unwrap();
});