diff --git a/core/src/external/mod.rs b/core/src/external/mod.rs index 7ff19ab0..5312e70c 100644 --- a/core/src/external/mod.rs +++ b/core/src/external/mod.rs @@ -5,6 +5,7 @@ mod file; mod fzf; mod jq; mod lsar; +mod pdftoppm; mod rg; mod unar; mod zoxide; @@ -16,6 +17,7 @@ pub use file::*; pub use fzf::*; pub use jq::*; pub use lsar::*; +pub use pdftoppm::*; pub use rg::*; pub use unar::*; pub use zoxide::*; diff --git a/core/src/external/pdftoppm.rs b/core/src/external/pdftoppm.rs new file mode 100644 index 00000000..ba92a415 --- /dev/null +++ b/core/src/external/pdftoppm.rs @@ -0,0 +1,22 @@ +use std::path::Path; + +use anyhow::{bail, Result}; +use tokio::process::Command; + +pub async fn pdftoppm(path: &Path, dest: &Path) -> Result<()> { + let output = Command::new("pdftoppm") + .args(["-png", "-singlefile"]) + .arg(path) + .arg(dest) + .kill_on_drop(true) + .output() + .await?; + + if !output.status.success() { + bail!( + "failed to get pdf: {}", + String::from_utf8_lossy(&output.stderr) + ); + } + Ok(()) +} diff --git a/core/src/manager/preview.rs b/core/src/manager/preview.rs index fe2faeb5..4fff95de 100644 --- a/core/src/manager/preview.rs +++ b/core/src/manager/preview.rs @@ -63,6 +63,7 @@ impl Preview { MimeKind::JSON => Self::json(&path).await.map(PreviewData::Text), MimeKind::Text => Self::highlight(&path).await.map(PreviewData::Text), MimeKind::Image => Self::image(&path).await, + MimeKind::Pdf => Self::pdf(&path).await, MimeKind::Video => Self::video(&path).await, MimeKind::Archive => Self::archive(&path).await.map(PreviewData::Text), MimeKind::Others => Err(anyhow!("Unsupported mimetype: {mime}")), @@ -117,6 +118,19 @@ impl Preview { Self::image(&cache).await } + pub async fn pdf(path: &Path) -> Result { + let cache = Image::cache(path); + if fs::metadata(&cache).await.is_err() { + external::pdftoppm(path, &cache).await?; + } + + let mut dest = cache.into_os_string(); + dest.push(".png"); + + let dest = Path::new(&dest); + Self::image(dest).await + } + pub async fn json(path: &Path) -> Result { Ok( external::jq(path) diff --git a/shared/src/mime.rs b/shared/src/mime.rs index 1b212dd9..33a13b2f 100644 --- a/shared/src/mime.rs +++ b/shared/src/mime.rs @@ -7,6 +7,7 @@ pub enum MimeKind { Text, Image, Video, + Pdf, Archive, Others, } @@ -27,6 +28,7 @@ impl MimeKind { "message" => true, "model" => true, "multipart" => true, + "pdf" => true, "text" => true, "video" => true, _ => false, @@ -39,6 +41,8 @@ impl MimeKind { Self::Dir } else if s == "application/json" { Self::JSON + } else if s == "application/pdf" { + Self::Pdf } else if s.starts_with("text/") || s.ends_with("/xml") { Self::Text } else if s.starts_with("image/") {