fix: previews are cached re: mimetype as well
parent
0bb4639859
commit
b04a00c660
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue