This commit is contained in:
sxyazi 2023-08-26 06:38:58 +08:00
parent c4f76bd778
commit a7e8567e81
No known key found for this signature in database
10 changed files with 55 additions and 43 deletions

View file

@ -1,4 +1,4 @@
use std::{env, fs, path::{Path, PathBuf}, time::{self, SystemTime}};
use std::{env, fs, path::{Path, PathBuf}, process, time::{self, SystemTime}};
use clap::{command, Parser};
use md5::{Digest, Md5};
@ -30,6 +30,10 @@ struct Args {
/// Write the selected files on open emitted by the chooser mode
#[arg(long)]
chooser_file: Option<PathBuf>,
/// Clear the cache directory
#[arg(long, action)]
clear_cache: bool,
}
impl Default for Boot {
@ -58,6 +62,12 @@ impl Default for Boot {
fs::create_dir_all(&boot.state_dir).unwrap();
}
if args.clear_cache {
println!("Clearing cache directory: {:?}", boot.cache_dir);
fs::remove_dir_all(&boot.cache_dir).unwrap();
process::exit(0);
}
boot
}
}

View file

@ -1,13 +1,13 @@
use std::path::Path;
use config::PREVIEW;
use shared::PagedError;
use shared::PeekError;
use tokio::process::Command;
pub async fn ffmpegthumbnailer(src: &Path, dest: &Path, skip: usize) -> Result<(), PagedError> {
pub async fn ffmpegthumbnailer(src: &Path, dest: &Path, skip: usize) -> Result<(), PeekError> {
let percentage = 5 + skip;
if percentage >= 100 {
return Err(PagedError::Exceed(94));
if percentage > 95 {
return Err(PeekError::Exceed(95 - 5));
}
let output = Command::new("ffmpegthumbnailer")

View file

@ -2,10 +2,10 @@ use std::{path::Path, process::Stdio};
use anyhow::Result;
use config::PREVIEW;
use shared::PagedError;
use shared::PeekError;
use tokio::{io::{AsyncBufReadExt, BufReader}, process::Command};
pub async fn jq(path: &Path, skip: usize, limit: usize) -> Result<String, PagedError> {
pub async fn jq(path: &Path, skip: usize, limit: usize) -> Result<String, PeekError> {
let mut child = Command::new("jq")
.args(["-C", "--indent", &PREVIEW.tab_size.to_string(), "."])
.arg(path)
@ -30,7 +30,7 @@ pub async fn jq(path: &Path, skip: usize, limit: usize) -> Result<String, PagedE
}
if skip > 0 && i < skip + limit {
Err(PagedError::Exceed(i.saturating_sub(limit)))
Err(PeekError::Exceed(i.saturating_sub(limit)))
} else {
Ok(lines)
}

View file

@ -3,7 +3,7 @@ use std::path::Path;
use anyhow::anyhow;
use serde::Deserialize;
use serde_json::Value;
use shared::PagedError;
use shared::PeekError;
use tokio::process::Command;
#[derive(Debug)]
@ -31,7 +31,7 @@ pub struct LsarFile {
}
#[allow(clippy::manual_map)]
pub async fn lsar(path: &Path, skip: usize, limit: usize) -> Result<Vec<LsarFile>, PagedError> {
pub async fn lsar(path: &Path, skip: usize, limit: usize) -> Result<Vec<LsarFile>, PeekError> {
let output =
Command::new("lsar").args(["-j", "-jss"]).arg(path).kill_on_drop(true).output().await?;
@ -74,7 +74,7 @@ pub async fn lsar(path: &Path, skip: usize, limit: usize) -> Result<Vec<LsarFile
}
if skip > 0 && files.len() < limit {
Err(PagedError::Exceed(i.saturating_sub(limit)))
Err(PeekError::Exceed(i.saturating_sub(limit)))
} else {
Ok(files)
}

View file

@ -2,10 +2,10 @@ use std::path::Path;
use adaptor::Image;
use regex::Regex;
use shared::PagedError;
use shared::PeekError;
use tokio::process::Command;
pub async fn pdftoppm(src: &Path, dest: impl AsRef<Path>, skip: usize) -> Result<(), PagedError> {
pub async fn pdftoppm(src: &Path, dest: impl AsRef<Path>, skip: usize) -> Result<(), PeekError> {
let output = Command::new("pdftoppm")
.args(["-singlefile", "-jpeg", "-jpegopt", "quality=75", "-f"])
.arg((skip + 1).to_string())
@ -22,7 +22,7 @@ pub async fn pdftoppm(src: &Path, dest: impl AsRef<Path>, skip: usize) -> Result
.map(|cap| cap[1].parse().unwrap())
.unwrap_or(0);
return if pages > 0 { Err(PagedError::Exceed(pages - 1)) } else { Err(s.to_string().into()) };
return if pages > 0 { Err(PeekError::Exceed(pages - 1)) } else { Err(s.to_string().into()) };
}
Ok(Image::precache_anyway(output.stdout.into(), dest).await?)

View file

@ -2,7 +2,7 @@ use std::{mem, path::{Path, PathBuf}, sync::atomic::Ordering};
use adaptor::Adaptor;
use config::MANAGER;
use shared::{MimeKind, PagedError};
use shared::{MimeKind, PeekError};
use tokio::task::JoinHandle;
use super::{provider::INCR, Provider};
@ -51,7 +51,6 @@ impl Preview {
self.handle.take().map(|h| h.abort());
INCR.fetch_add(1, Ordering::Relaxed);
Adaptor::image_hide(MANAGER.layout.preview_rect()).ok();
self.skip = skip;
self.handle = Some(tokio::spawn(async move {
@ -59,7 +58,7 @@ impl Preview {
Ok(result) => {
emit!(Preview(path, mime, result));
}
Err(PagedError::Exceed(max)) => {
Err(PeekError::Exceed(max)) => {
emit!(Peek(path, max));
}
_ => {}

View file

@ -3,7 +3,7 @@ use std::{io::BufRead, path::Path, sync::atomic::{AtomicUsize, Ordering}};
use adaptor::Adaptor;
use anyhow::anyhow;
use config::{BOOT, MANAGER, PREVIEW};
use shared::{MimeKind, PagedError};
use shared::{MimeKind, PeekError};
use syntect::{easy::HighlightFile, util::as_24_bit_terminal_escaped};
use tokio::fs;
@ -19,7 +19,7 @@ impl Provider {
kind: MimeKind,
path: &Path,
skip: usize,
) -> Result<PreviewData, PagedError> {
) -> Result<PreviewData, PeekError> {
match kind {
MimeKind::Empty => Ok(PreviewData::None),
MimeKind::Archive => Provider::archive(path, skip).await.map(PreviewData::Text),
@ -47,7 +47,7 @@ impl Provider {
}
}
pub(super) async fn folder(path: &Path) -> Result<PreviewData, PagedError> {
pub(super) async fn folder(path: &Path) -> Result<PreviewData, PeekError> {
emit!(Files(match Files::read_dir(path).await {
Ok(items) => FilesOp::Read(path.to_path_buf(), items),
Err(_) => FilesOp::IOErr(path.to_path_buf()),
@ -56,12 +56,12 @@ impl Provider {
Ok(PreviewData::Folder)
}
pub(super) async fn image(path: &Path) -> Result<PreviewData, PagedError> {
pub(super) async fn image(path: &Path) -> Result<PreviewData, PeekError> {
Adaptor::image_show(path, MANAGER.layout.preview_rect()).await?;
Ok(PreviewData::Image)
}
pub(super) async fn video(path: &Path, skip: usize) -> Result<PreviewData, PagedError> {
pub(super) async fn video(path: &Path, skip: usize) -> Result<PreviewData, PeekError> {
let cache = BOOT.cache(path, skip);
if fs::metadata(&cache).await.is_err() {
external::ffmpegthumbnailer(path, &cache, skip).await?;
@ -70,7 +70,7 @@ impl Provider {
Self::image(&cache).await
}
pub(super) async fn pdf(path: &Path, skip: usize) -> Result<PreviewData, PagedError> {
pub(super) async fn pdf(path: &Path, skip: usize) -> Result<PreviewData, PeekError> {
let cache = BOOT.cache(path, skip);
if fs::metadata(&cache).await.is_err() {
external::pdftoppm(path, &cache, skip).await?;
@ -79,11 +79,11 @@ impl Provider {
Self::image(&cache).await
}
pub(super) async fn json(path: &Path, skip: usize) -> Result<String, PagedError> {
pub(super) async fn json(path: &Path, skip: usize) -> Result<String, PeekError> {
external::jq(path, skip, MANAGER.layout.preview_height()).await
}
pub(super) async fn archive(path: &Path, skip: usize) -> Result<String, PagedError> {
pub(super) async fn archive(path: &Path, skip: usize) -> Result<String, PeekError> {
Ok(
external::lsar(path, skip, MANAGER.layout.preview_height())
.await?
@ -94,13 +94,13 @@ impl Provider {
)
}
pub(super) async fn highlight(path: &Path, skip: usize) -> Result<String, PagedError> {
pub(super) async fn highlight(path: &Path, skip: usize) -> Result<String, PeekError> {
let tick = INCR.load(Ordering::Relaxed);
let path = path.to_path_buf();
let spaces = " ".repeat(PREVIEW.tab_size as usize);
let (syntaxes, theme) = highlighter();
tokio::task::spawn_blocking(move || -> Result<String, PagedError> {
tokio::task::spawn_blocking(move || -> Result<String, PeekError> {
let mut h = HighlightFile::new(path, syntaxes, theme)?;
let mut line = String::new();
let mut buf = String::new();
@ -109,25 +109,25 @@ impl Provider {
let limit = MANAGER.layout.preview_height();
while h.reader.read_line(&mut line)? > 0 {
if tick != INCR.load(Ordering::Relaxed) {
return Err("Preview cancelled".into());
return Err("Highlighting cancelled".into());
}
i += 1;
if i > skip + limit {
break;
} else if i <= skip {
line.clear();
continue;
}
line = line.replace('\t', &spaces);
let regions = h.highlight_lines.highlight_line(&line, syntaxes).map_err(|e| anyhow!(e))?;
buf.push_str(&as_24_bit_terminal_escaped(&regions, false));
if i > skip {
buf.push_str(&as_24_bit_terminal_escaped(&regions, false));
}
line.clear();
}
if skip > 0 && i < skip + limit {
return Err(PagedError::Exceed(i.saturating_sub(limit)));
return Err(PeekError::Exceed(i.saturating_sub(limit)));
}
buf.push_str("\x1b[0m");

View file

@ -90,8 +90,8 @@ impl Tab {
};
let path = self.preview.lock.as_ref().unwrap().0.clone();
if let Some(dir) = self.history(&path) {
let max = dir.files.len().saturating_sub(MANAGER.layout.preview_height());
if let Some(folder) = self.history(&path) {
let max = folder.files.len().saturating_sub(MANAGER.layout.preview_height());
if new > max {
emit!(Peek(path, max));
return false;

3
shared/src/errors/mod.rs Normal file
View file

@ -0,0 +1,3 @@
mod peek;
pub use peek::*;

View file

@ -1,12 +1,12 @@
use std::{error::Error, fmt::{self, Display}};
#[derive(Debug)]
pub enum PagedError {
pub enum PeekError {
Exceed(usize),
Unexpected(String),
}
impl Display for PagedError {
impl Display for PeekError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Exceed(lines) => write!(f, "Exceed: {lines}"),
@ -15,20 +15,20 @@ impl Display for PagedError {
}
}
impl Error for PagedError {}
impl Error for PeekError {}
impl From<String> for PagedError {
impl From<String> for PeekError {
fn from(error: String) -> Self { Self::Unexpected(error) }
}
impl From<&str> for PagedError {
impl From<&str> for PeekError {
fn from(error: &str) -> Self { Self::from(error.to_owned()) }
}
impl From<anyhow::Error> for PagedError {
impl From<anyhow::Error> for PeekError {
fn from(error: anyhow::Error) -> Self { Self::from(error.to_string()) }
}
impl From<std::io::Error> for PagedError {
impl From<std::io::Error> for PeekError {
fn from(error: std::io::Error) -> Self { Self::from(error.to_string()) }
}
impl From<tokio::task::JoinError> for PagedError {
impl From<tokio::task::JoinError> for PeekError {
fn from(error: tokio::task::JoinError) -> Self { Self::from(error.to_string()) }
}