thumbnails -> previews

feat/vaults
Tomáš Mládek 2021-12-27 12:40:02 +01:00
parent d11d20f210
commit a43a9d6caf
No known key found for this signature in database
GPG Key ID: ED21612889E75EC5
6 changed files with 26 additions and 27 deletions

View File

@ -64,6 +64,6 @@ webbrowser = { version = "^0.5.5", optional = true }
nonempty = "0.6.0" nonempty = "0.6.0"
[features] [features]
default = ["desktop", "thumbnails"] default = ["desktop", "previews"]
desktop = ["webbrowser", "opener", "is_executable"] desktop = ["webbrowser", "opener", "is_executable"]
thumbnails = [] previews = []

View File

@ -16,7 +16,6 @@ use log::{info, warn};
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use crate::database::UpEndDatabase; use crate::database::UpEndDatabase;
use crate::thumbnails::ThumbnailStore;
mod addressing; mod addressing;
mod database; mod database;
@ -24,8 +23,8 @@ mod filesystem;
mod routes; mod routes;
mod util; mod util;
#[cfg(feature = "thumbnails")] #[cfg(feature = "previews")]
mod thumbnails; mod previews;
const VERSION: &str = env!("CARGO_PKG_VERSION"); const VERSION: &str = env!("CARGO_PKG_VERSION");
@ -100,14 +99,14 @@ fn main() -> Result<()> {
let upend = Arc::new(open_result.db); let upend = Arc::new(open_result.db);
#[cfg(feature = "thumbnails")] #[cfg(feature = "previews")]
let thumbnail_store = Some(Arc::new(ThumbnailStore::new( let preview_store = Some(Arc::new(crate::previews::PreviewStore::new(
upend.db_path.join("thumbnails"), upend.db_path.join("previews"),
upend.clone(), upend.clone(),
))); )));
#[cfg(not(feature = "thumbnails"))] #[cfg(not(feature = "previews"))]
let thumbnail_store = None; let preview_store = None;
let mut bind: SocketAddr = matches let mut bind: SocketAddr = matches
.value_of("BIND") .value_of("BIND")
@ -131,7 +130,7 @@ fn main() -> Result<()> {
}), }),
), ),
job_container: job_container.clone(), job_container: job_container.clone(),
thumbnail_store, preview_store,
}; };
// Start HTTP server // Start HTTP server

View File

@ -16,19 +16,19 @@ use self::video::VideoPath;
pub mod text; pub mod text;
pub mod video; pub mod video;
pub trait Thumbnailable { pub trait Previewable {
fn get_thumbnail(&self) -> Result<Vec<u8>>; fn get_thumbnail(&self) -> Result<Vec<u8>>;
} }
pub struct ThumbnailStore { pub struct PreviewStore {
path: PathBuf, path: PathBuf,
db: Arc<UpEndDatabase>, db: Arc<UpEndDatabase>,
locks: Mutex<HashMap<Hash, Arc<Mutex<PathBuf>>>>, locks: Mutex<HashMap<Hash, Arc<Mutex<PathBuf>>>>,
} }
impl ThumbnailStore { impl PreviewStore {
pub fn new<P: AsRef<Path>>(path: P, db: Arc<UpEndDatabase>) -> Self { pub fn new<P: AsRef<Path>>(path: P, db: Arc<UpEndDatabase>) -> Self {
ThumbnailStore { PreviewStore {
path: PathBuf::from(path.as_ref()), path: PathBuf::from(path.as_ref()),
db, db,
locks: Mutex::new(HashMap::new()), locks: Mutex::new(HashMap::new()),

View File

@ -1,11 +1,11 @@
use anyhow::Result; use anyhow::Result;
use std::{cmp::min, convert::TryInto, fs::File, io::Read, path::Path}; use std::{cmp::min, convert::TryInto, fs::File, io::Read, path::Path};
use super::Thumbnailable; use super::Previewable;
pub struct TextPath<'a>(pub &'a Path); pub struct TextPath<'a>(pub &'a Path);
impl<'a> Thumbnailable for TextPath<'a> { impl<'a> Previewable for TextPath<'a> {
fn get_thumbnail(&self) -> Result<Vec<u8>> { fn get_thumbnail(&self) -> Result<Vec<u8>> {
let mut f = File::open(self.0)?; let mut f = File::open(self.0)?;
let mut buffer = vec![0u8; min(1024, f.metadata()?.len().try_into()?)]; let mut buffer = vec![0u8; min(1024, f.metadata()?.len().try_into()?)];

View File

@ -5,11 +5,11 @@ use std::process::Command;
use anyhow::Result; use anyhow::Result;
use super::Thumbnailable; use super::Previewable;
pub struct VideoPath<'a>(pub &'a Path); pub struct VideoPath<'a>(pub &'a Path);
impl<'a> Thumbnailable for VideoPath<'a> { impl<'a> Previewable for VideoPath<'a> {
fn get_thumbnail(&self) -> Result<Vec<u8>> { fn get_thumbnail(&self) -> Result<Vec<u8>> {
let duration_cmd = Command::new("ffprobe") let duration_cmd = Command::new("ffprobe")
.args(["-v", "error"]) .args(["-v", "error"])

View File

@ -3,7 +3,7 @@ use crate::database::entry::{Entry, InEntry};
use crate::database::hierarchies::{list_roots, resolve_path, UHierPath}; use crate::database::hierarchies::{list_roots, resolve_path, UHierPath};
use crate::database::lang::Query; use crate::database::lang::Query;
use crate::database::UpEndDatabase; use crate::database::UpEndDatabase;
use crate::thumbnails::ThumbnailStore; use crate::previews::PreviewStore;
use crate::util::hash::{decode, encode}; use crate::util::hash::{decode, encode};
use crate::util::jobs::JobContainer; use crate::util::jobs::JobContainer;
use actix_files::NamedFile; use actix_files::NamedFile;
@ -29,7 +29,7 @@ pub struct State {
pub upend: Arc<UpEndDatabase>, pub upend: Arc<UpEndDatabase>,
pub vault_name: Option<String>, pub vault_name: Option<String>,
pub job_container: Arc<RwLock<JobContainer>>, pub job_container: Arc<RwLock<JobContainer>>,
pub thumbnail_store: Option<Arc<ThumbnailStore>>, pub preview_store: Option<Arc<PreviewStore>>,
} }
#[derive(Deserialize)] #[derive(Deserialize)]
@ -315,17 +315,17 @@ pub async fn get_thumbnail(
state: web::Data<State>, state: web::Data<State>,
hash: web::Path<String>, hash: web::Path<String>,
) -> Result<NamedFile, Error> { ) -> Result<NamedFile, Error> {
if let Some(thumbnail_store) = &state.thumbnail_store { if let Some(preview_store) = &state.preview_store {
let address = let address =
Address::decode(&decode(hash.into_inner()).map_err(ErrorInternalServerError)?) Address::decode(&decode(hash.into_inner()).map_err(ErrorInternalServerError)?)
.map_err(ErrorInternalServerError)?; .map_err(ErrorInternalServerError)?;
if let Address::Hash(hash) = address { if let Address::Hash(hash) = address {
let thumbnail_path = thumbnail_store let preview_path = preview_store
.get(hash) .get(hash)
.map_err(error::ErrorInternalServerError)?; .map_err(error::ErrorInternalServerError)?;
let mut file = NamedFile::open(&thumbnail_path)?.disable_content_disposition(); let mut file = NamedFile::open(&preview_path)?.disable_content_disposition();
if let Some(mime_type) = tree_magic_mini::from_filepath(&thumbnail_path) { if let Some(mime_type) = tree_magic_mini::from_filepath(&preview_path) {
if let Ok(mime) = mime_type.parse() { if let Ok(mime) = mime_type.parse() {
file = file.set_content_type(mime); file = file.set_content_type(mime);
} }
@ -333,10 +333,10 @@ pub async fn get_thumbnail(
Ok(file) Ok(file)
} else { } else {
Err(ErrorBadRequest( Err(ErrorBadRequest(
"Address does not refer to a thumbnailable object.", "Address does not refer to a previewable object.",
)) ))
} }
} else { } else {
Err(error::ErrorNotImplemented("Thumbnails not enabled.")) Err(error::ErrorNotImplemented("Previews not enabled."))
} }
} }