74 lines
2.2 KiB
Rust
74 lines
2.2 KiB
Rust
use crate::util::hash::Hash;
|
|
use crate::{database::UpEndDatabase, util::hash::encode};
|
|
use anyhow::{anyhow, Result};
|
|
use std::{
|
|
collections::HashMap,
|
|
fs::File,
|
|
io::Write,
|
|
path::{Path, PathBuf},
|
|
sync::{Arc, Mutex},
|
|
};
|
|
|
|
use self::text::TextPath;
|
|
|
|
pub mod text;
|
|
|
|
pub trait Thumbnailable {
|
|
fn get_thumbnail(&self) -> Result<Vec<u8>>;
|
|
}
|
|
pub struct ThumbnailStore {
|
|
path: PathBuf,
|
|
db: Arc<UpEndDatabase>,
|
|
|
|
locks: Mutex<HashMap<Hash, Arc<Mutex<PathBuf>>>>,
|
|
}
|
|
|
|
impl ThumbnailStore {
|
|
pub fn new<P: AsRef<Path>>(path: P, db: Arc<UpEndDatabase>) -> Self {
|
|
ThumbnailStore {
|
|
path: PathBuf::from(path.as_ref()),
|
|
db,
|
|
locks: Mutex::new(HashMap::new()),
|
|
}
|
|
}
|
|
|
|
fn get_path(&self, hash: &Hash) -> Arc<Mutex<PathBuf>> {
|
|
let mut locks = self.locks.lock().unwrap();
|
|
if let Some(path) = locks.get(hash) {
|
|
path.clone()
|
|
} else {
|
|
let thumbpath = self.path.join(encode(hash));
|
|
let path = Arc::new(Mutex::new(thumbpath));
|
|
locks.insert(hash.clone(), path.clone());
|
|
path
|
|
}
|
|
}
|
|
|
|
pub fn get(&self, hash: Hash) -> Result<PathBuf> {
|
|
let path_mutex = self.get_path(&hash);
|
|
let thumbpath = path_mutex.lock().unwrap();
|
|
if thumbpath.exists() {
|
|
Ok(thumbpath.clone())
|
|
} else {
|
|
let connection = self.db.connection()?;
|
|
let files = connection.retrieve_file(hash)?;
|
|
if let Some(file) = files.get(0) {
|
|
|
|
let data = match tree_magic_mini::from_filepath(&file.path) {
|
|
Some(tm) if tm.starts_with("text") => Ok(TextPath(&file.path).get_thumbnail()?),
|
|
Some(unknown) => Err(anyhow!("No capability for {:?} thumbnails.", unknown)),
|
|
_ => Err(anyhow!("Unknown file type, or file doesn't exist."))
|
|
}?;
|
|
|
|
std::fs::create_dir_all(&self.path)?;
|
|
let mut file = File::create(&*thumbpath)?;
|
|
file.write_all(&data)?;
|
|
|
|
Ok(thumbpath.clone())
|
|
} else {
|
|
Err(anyhow!("Object not found, or is not a file."))
|
|
}
|
|
}
|
|
}
|
|
}
|