diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/config.rs | 8 | ||||
-rw-r--r-- | src/fail.rs | 3 | ||||
-rw-r--r-- | src/files.rs | 6 | ||||
-rw-r--r-- | src/imgview.rs | 22 | ||||
-rw-r--r-- | src/main.rs | 3 | ||||
-rw-r--r-- | src/mediaview.rs | 60 | ||||
-rw-r--r-- | src/preview.rs | 24 | ||||
-rw-r--r-- | src/widget.rs | 13 |
8 files changed, 97 insertions, 42 deletions
diff --git a/src/config.rs b/src/config.rs index 24bc995..e969f1a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -77,6 +77,7 @@ pub struct Config { pub icons: bool, pub media_autoplay: bool, pub media_mute: bool, + pub media_previewer: String } @@ -95,7 +96,8 @@ impl Config { cd_cmd: "find -type d | fzf".to_string(), icons: false, media_autoplay: false, - media_mute: false + media_mute: false, + media_previewer: "hunter-media".to_string() } } @@ -128,6 +130,10 @@ impl Config { Ok(("media_autoplay", "off")) => { config.media_autoplay = false; }, Ok(("media_mute", "on")) => { config.media_mute = true; }, Ok(("media_mute", "off")) => { config.media_mute = false; }, + Ok(("media_previewer", cmd)) => { + let cmd = cmd.to_string(); + config.select_cmd = cmd; + } _ => { HError::config_error::<Config>(line.to_string()).log(); } } config diff --git a/src/fail.rs b/src/fail.rs index 0102fa0..b3351ba 100644 --- a/src/fail.rs +++ b/src/fail.rs @@ -10,6 +10,7 @@ use std::path::PathBuf; use std::sync::{Arc, Mutex}; use crate::foldview::LogEntry; +use crate::mediaview::MediaError; pub type HResult<T> = Result<T, HError>; @@ -101,6 +102,8 @@ pub enum HError { UTF8ParseError(std::str::Utf8Error), #[fail(display = "Failed to parse integer!")] ParseIntError(std::num::ParseIntError), + #[fail(display = "{}", _0)] + Media(MediaError) } impl HError { diff --git a/src/files.rs b/src/files.rs index 44f5470..a4bbbcc 100644 --- a/src/files.rs +++ b/src/files.rs @@ -424,9 +424,9 @@ impl Files { file.path = new_path.into(); file.reload_meta()?; }, - DebouncedEvent::Error(err, path) => { - dbg!(err); - dbg!(path); + DebouncedEvent::Error(err, _path) => { + // Never seen this happen. Should reload affected dirs + HError::log::<()>(&format!("{}", err))?; }, _ => {}, } diff --git a/src/imgview.rs b/src/imgview.rs index d84fc03..93e1832 100644 --- a/src/imgview.rs +++ b/src/imgview.rs @@ -4,6 +4,8 @@ use crate::fail::HResult; use std::path::{Path, PathBuf}; +use crate::mediaview::MediaError; + impl std::cmp::PartialEq for ImgView { fn eq(&self, other: &Self) -> bool { self.core == other.core && @@ -31,18 +33,34 @@ impl ImgView { pub fn encode_file(&mut self) -> HResult<()> { let (xsize, ysize) = self.core.coordinates.size_u(); + let (xpos, ypos) = self.core.coordinates.position_u(); let file = &self.file; + let media_previewer = self.core.config().media_previewer; - let output = std::process::Command::new("preview-gen") + let output = std::process::Command::new(&media_previewer) .arg(format!("{}", (xsize))) .arg(format!("{}", (ysize+1))) + .arg(format!("{}", xpos)) + .arg(format!("{}", ypos)) .arg("image") .arg(format!("true")) .arg(format!("true")) .arg(file.to_string_lossy().to_string()) - .output()? + .output() + .map_err(|e| { + let msg = format!("Couldn't run {}{}{}! Error: {:?}", + crate::term::color_red(), + media_previewer, + crate::term::normal_color(), + &e.kind()); + + self.core.show_status(&msg).ok(); + + MediaError::NoPreviewer(msg) + })? .stdout; + let output = std::str::from_utf8(&output)?; let output = output.lines() .map(|l| l.to_string()) diff --git a/src/main.rs b/src/main.rs index bc949fe..57d2dbd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -59,10 +59,7 @@ mod icon; mod quick_actions; mod trait_ext; mod config_installer; - -#[cfg(feature = "img")] mod imgview; -#[cfg(feature = "video")] mod mediaview; diff --git a/src/mediaview.rs b/src/mediaview.rs index f502591..2f9153c 100644 --- a/src/mediaview.rs +++ b/src/mediaview.rs @@ -1,5 +1,6 @@ use lazy_static; use termion::event::Key; +use failure::{self, Fail}; use crate::widget::{Widget, WidgetCore}; use crate::coordinates::Coordinates; @@ -14,6 +15,18 @@ use std::sync::{Arc, Mutex, RwLock, use std::io::{BufRead, BufReader, Write}; use std::process::Child; +#[derive(Fail, Debug, Clone)] +pub enum MediaError { + #[fail(display = "{}", _0)] + NoPreviewer(String) +} + +impl From<MediaError> for HError { + fn from(e: MediaError) -> HError { + HError::Media(e) + } +} + impl std::cmp::PartialEq for MediaView { fn eq(&self, other: &Self) -> bool { self.core == other.core @@ -61,8 +74,23 @@ impl MediaType { impl MediaView { pub fn new_from_file(core: WidgetCore, file: &Path, - media_type: MediaType) -> MediaView { + media_type: MediaType) -> HResult<MediaView> { + // Check if previewer is present, or bail out to show message + let media_previewer = core.config().media_previewer; + if crate::minibuffer::find_bins(&media_previewer).is_err() { + let msg = format!("Couldn't find previewer: {}{}{}!", + crate::term::color_red(), + media_previewer, + crate::term::normal_color()); + + + core.show_status(&msg).log(); + + return Err(MediaError::NoPreviewer(msg))?; + } + let (xsize, ysize) = core.coordinates.size_u(); + let (xpos, ypos) = core.coordinates.position_u(); let (tx_cmd, rx_cmd) = channel(); let imgview = ImgView { @@ -71,6 +99,7 @@ impl MediaView { file: file.to_path_buf() }; + // Stuff that gets moved into the closure let imgview = Arc::new(Mutex::new(imgview)); let thread_imgview = imgview.clone(); @@ -82,7 +111,8 @@ impl MediaView { let process = Arc::new(Mutex::new(None)); let cprocess = process.clone(); let ctype = media_type.clone(); - + let ccore = core.clone(); + let media_previewer = core.config().media_previewer; let run_preview = Box::new(move | auto, mute, @@ -93,18 +123,32 @@ impl MediaView { return Ok(()); } - let mut previewer = std::process::Command::new("preview-gen") + + let mut previewer = std::process::Command::new(&media_previewer) .arg(format!("{}", (xsize))) // Leave space for position/seek bar .arg(format!("{}", (ysize-1))) + .arg(format!("{}", xpos)) + .arg(format!("{}", ypos)) .arg(format!("{}", ctype.to_str())) .arg(format!("{}", auto)) .arg(format!("{}", mute)) .arg(&path) .stdin(std::process::Stdio::piped()) .stdout(std::process::Stdio::piped()) - .stderr(std::process::Stdio::inherit()) - .spawn()?; + .stderr(std::process::Stdio::piped()) + .spawn() + .map_err(|e| { + let msg = format!("Couldn't run {}{}{}! Error: {:?}", + crate::term::color_red(), + media_previewer, + crate::term::normal_color(), + &e.kind()); + + ccore.show_status(&msg).log(); + + MediaError::NoPreviewer(msg) + })?; let mut stdout = BufReader::new(previewer.stdout.take()?); let mut stdin = previewer.stdin.take()?; @@ -174,7 +218,7 @@ impl MediaView { }); - MediaView { + Ok(MediaView { core: core.clone(), imgview: imgview, file: file.to_path_buf(), @@ -186,7 +230,7 @@ impl MediaView { stale: stale, process: process, preview_runner: Some(run_preview) - } + }) } pub fn start_video(&mut self) -> HResult<()> { @@ -308,7 +352,7 @@ impl MediaView { // Since GStreamer sucks, just create a new instace let mut view = MediaView::new_from_file(self.core.clone(), &self.file.clone(), - self.media_type.clone()); + self.media_type.clone())?; // Insert buffer to prevent flicker let buffer = self.imgview.lock()?.buffer.clone(); diff --git a/src/preview.rs b/src/preview.rs index 3d7a022..ac5ee60 100644 --- a/src/preview.rs +++ b/src/preview.rs @@ -12,10 +12,7 @@ use crate::widget::{Widget, WidgetCore}; use crate::coordinates::Coordinates; use crate::fail::{HResult, HError, ErrorLog}; use crate::dirty::Dirtyable; - -#[cfg(feature = "img")] use crate::imgview::ImgView; -#[cfg(feature = "video")] use crate::mediaview::MediaView; @@ -201,9 +198,7 @@ impl PartialEq for Previewer { enum PreviewWidget { FileList(ListView<Files>), TextView(TextView), - #[cfg(feature = "img")] ImgView(ImgView), - #[cfg(feature = "video")] MediaView(MediaView) } @@ -370,26 +365,23 @@ impl Previewer { let is_gif = mime.subtype() == "gif"; match mime_type { - #[cfg(feature = "video")] _ if mime_type == "video" || is_gif => { let media_type = crate::mediaview::MediaType::Video; let mediaview = MediaView::new_from_file(core.clone(), &file.path, - media_type); + media_type)?; return Ok(PreviewWidget::MediaView(mediaview)); } - #[cfg(feature = "img")] "image" => { let imgview = ImgView::new_from_file(core.clone(), &file.path())?; return Ok(PreviewWidget::ImgView(imgview)); } - #[cfg(feature = "video")] "audio" => { let media_type = crate::mediaview::MediaType::Audio; let mediaview = MediaView::new_from_file(core.clone(), &file.path, - media_type); + media_type)?; return Ok(PreviewWidget::MediaView(mediaview)); } "text" if mime.subtype() == "plain" => { @@ -578,9 +570,7 @@ impl Widget for PreviewWidget { match self { PreviewWidget::FileList(widget) => widget.get_core(), PreviewWidget::TextView(widget) => widget.get_core(), - #[cfg(feature = "img")] PreviewWidget::ImgView(widget) => widget.get_core(), - #[cfg(feature = "video")] PreviewWidget::MediaView(widget) => widget.get_core() } } @@ -588,9 +578,7 @@ impl Widget for PreviewWidget { match self { PreviewWidget::FileList(widget) => widget.get_core_mut(), PreviewWidget::TextView(widget) => widget.get_core_mut(), - #[cfg(feature = "img")] PreviewWidget::ImgView(widget) => widget.get_core_mut(), - #[cfg(feature = "video")] PreviewWidget::MediaView(widget) => widget.get_core_mut() } } @@ -598,9 +586,7 @@ impl Widget for PreviewWidget { match self { PreviewWidget::FileList(widget) => widget.set_coordinates(coordinates), PreviewWidget::TextView(widget) => widget.set_coordinates(coordinates), - #[cfg(feature = "img")] PreviewWidget::ImgView(widget) => widget.set_coordinates(coordinates), - #[cfg(feature = "video")] PreviewWidget::MediaView(widget) => widget.set_coordinates(coordinates), } } @@ -608,9 +594,7 @@ impl Widget for PreviewWidget { match self { PreviewWidget::FileList(widget) => widget.refresh(), PreviewWidget::TextView(widget) => widget.refresh(), - #[cfg(feature = "img")] PreviewWidget::ImgView(widget) => widget.refresh(), - #[cfg(feature = "video")] PreviewWidget::MediaView(widget) => widget.refresh() } } @@ -618,9 +602,7 @@ impl Widget for PreviewWidget { match self { PreviewWidget::FileList(widget) => widget.get_drawlist(), PreviewWidget::TextView(widget) => widget.get_drawlist(), - #[cfg(feature = "img")] PreviewWidget::ImgView(widget) => widget.get_drawlist(), - #[cfg(feature = "video")] PreviewWidget::MediaView(widget) => widget.get_drawlist() } } @@ -629,9 +611,7 @@ impl Widget for PreviewWidget { match self { PreviewWidget::FileList(widget) => widget.on_key(key), PreviewWidget::TextView(widget) => widget.on_key(key), - #[cfg(feature = "img")] PreviewWidget::ImgView(widget) => widget.on_key(key), - #[cfg(feature = "video")] PreviewWidget::MediaView(widget) => widget.on_key(key) } } diff --git a/src/widget.rs b/src/widget.rs index 6cb19eb..8e2019d 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -192,9 +192,16 @@ impl WidgetCore { } pub fn config(&self) -> Config { - self.config.read().unwrap().get() - .map(|config| config.clone()) - .unwrap_or(Config::new()) + self.get_conf() + .unwrap_or_else(|_| Config::new()) + } + + fn get_conf(&self) -> HResult<Config> { + let conf = self.config + .read()? + .get()? + .clone(); + Ok(conf) } } |