From 2c3bd78fc1a03450d792733820dddf0d8da92368 Mon Sep 17 00:00:00 2001 From: ByteDream Date: Tue, 27 Dec 2022 20:37:45 +0100 Subject: [PATCH 1/3] Leave special files untouched from renaming --- crunchy-cli-core/src/utils/os.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crunchy-cli-core/src/utils/os.rs b/crunchy-cli-core/src/utils/os.rs index 01d0f89..e3320fb 100644 --- a/crunchy-cli-core/src/utils/os.rs +++ b/crunchy-cli-core/src/utils/os.rs @@ -37,6 +37,12 @@ pub fn tempfile>(suffix: S) -> io::Result { /// Check if the given path exists and rename it until the new (renamed) file does not exist. pub fn free_file(mut path: PathBuf) -> PathBuf { + // if path is not a file and not a dir it's probably a pipe on linux which reguarly is intended + // and thus does not need to be renamed. what it is on windows ¯\_(ツ)_/¯ + if !path.is_file() && !path.is_dir() { + return path; + } + let mut i = 0; while path.exists() { i += 1; From c37e2495e1e66d9ee7a5d17d3570dcb5f081e137 Mon Sep 17 00:00:00 2001 From: ByteDream Date: Tue, 27 Dec 2022 20:49:53 +0100 Subject: [PATCH 2/3] Create output parent directory if it doesn't exists (#91) --- crunchy-cli-core/src/cli/archive.rs | 7 +++++++ crunchy-cli-core/src/cli/download.rs | 13 +++++++++++++ 2 files changed, 20 insertions(+) diff --git a/crunchy-cli-core/src/cli/archive.rs b/crunchy-cli-core/src/cli/archive.rs index b5244f7..70240cf 100644 --- a/crunchy-cli-core/src/cli/archive.rs +++ b/crunchy-cli-core/src/cli/archive.rs @@ -647,6 +647,13 @@ fn generate_mkv( debug!("ffmpeg {}", command_args.join(" ")); + // create parent directory if it does not exist + if let Some(parent) = target.parent() { + if !parent.exists() { + std::fs::create_dir_all(parent)? + } + } + let ffmpeg = Command::new("ffmpeg") .stdout(Stdio::null()) .stderr(Stdio::piped()) diff --git a/crunchy-cli-core/src/cli/download.rs b/crunchy-cli-core/src/cli/download.rs index d8a4ada..99da758 100644 --- a/crunchy-cli-core/src/cli/download.rs +++ b/crunchy-cli-core/src/cli/download.rs @@ -240,6 +240,12 @@ impl Execute for Download { let mut stdout = std::io::stdout().lock(); download_segments(&ctx, &mut stdout, None, format.stream).await?; } else { + // create parent directory if it does not exist + if let Some(parent) = path.parent() { + if !parent.exists() { + std::fs::create_dir_all(parent)? + } + } let mut file = File::options().create(true).write(true).open(&path)?; download_segments(&ctx, &mut file, None, format.stream).await? } @@ -259,6 +265,13 @@ async fn download_ffmpeg( let (input_presets, output_presets) = FFmpegPreset::ffmpeg_presets(download.ffmpeg_preset.clone())?; + // create parent directory if it does not exist + if let Some(parent) = target.parent() { + if !parent.exists() { + std::fs::create_dir_all(parent)? + } + } + let mut ffmpeg = Command::new("ffmpeg") .stdin(Stdio::piped()) .stdout(Stdio::null()) From 14f42833cb5257e0f9ef10f4b243c0ec51cbf28e Mon Sep 17 00:00:00 2001 From: ByteDream Date: Tue, 27 Dec 2022 22:59:35 +0100 Subject: [PATCH 3/3] Fix output to special file (pipes etc.) --- crunchy-cli-core/src/cli/archive.rs | 9 +++++++-- crunchy-cli-core/src/cli/download.rs | 27 ++++++++++++++++++++++----- crunchy-cli-core/src/utils/os.rs | 13 +++++++++---- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/crunchy-cli-core/src/cli/archive.rs b/crunchy-cli-core/src/cli/archive.rs index 70240cf..e3d5520 100644 --- a/crunchy-cli-core/src/cli/archive.rs +++ b/crunchy-cli-core/src/cli/archive.rs @@ -3,7 +3,7 @@ use crate::cli::utils::{download_segments, find_resolution, FFmpegPreset}; use crate::utils::context::Context; use crate::utils::format::{format_string, Format}; use crate::utils::log::progress; -use crate::utils::os::{free_file, has_ffmpeg, tempfile}; +use crate::utils::os::{free_file, has_ffmpeg, is_special_file, tempfile}; use crate::utils::parse::{parse_url, UrlFilter}; use crate::utils::sort::{sort_formats_after_seasons, sort_seasons_after_number}; use crate::Execute; @@ -133,6 +133,7 @@ impl Execute for Archive { .unwrap_or_default() .to_string_lossy() != "mkv" + && !is_special_file(PathBuf::from(&self.output)) { bail!("File extension is not '.mkv'. Currently only matroska / '.mkv' files are supported") } @@ -251,7 +252,11 @@ impl Execute for Archive { info!( "Downloading {} to '{}'", primary.title, - path.to_str().unwrap() + if is_special_file(&path) { + path.to_str().unwrap() + } else { + path.file_name().unwrap().to_str().unwrap() + } ); tab_info!( "Episode: S{:02}E{:02}", diff --git a/crunchy-cli-core/src/cli/download.rs b/crunchy-cli-core/src/cli/download.rs index 99da758..0411a5e 100644 --- a/crunchy-cli-core/src/cli/download.rs +++ b/crunchy-cli-core/src/cli/download.rs @@ -3,7 +3,7 @@ use crate::cli::utils::{download_segments, find_resolution, FFmpegPreset}; use crate::utils::context::Context; use crate::utils::format::{format_string, Format}; use crate::utils::log::progress; -use crate::utils::os::{free_file, has_ffmpeg}; +use crate::utils::os::{free_file, has_ffmpeg, is_special_file}; use crate::utils::parse::{parse_url, UrlFilter}; use crate::utils::sort::{sort_formats_after_seasons, sort_seasons_after_number}; use crate::Execute; @@ -219,7 +219,11 @@ impl Execute for Download { info!( "Downloading {} to '{}'", format.title, - path.file_name().unwrap().to_str().unwrap() + if is_special_file(&path) { + path.to_str().unwrap() + } else { + path.file_name().unwrap().to_str().unwrap() + } ); tab_info!("Episode: S{:02}E{:02}", format.season_number, format.number); tab_info!("Audio: {}", format.audio); @@ -232,9 +236,9 @@ impl Execute for Download { tab_info!("Resolution: {}", format.stream.resolution); tab_info!("FPS: {:.2}", format.stream.fps); - if path.extension().unwrap_or_default().to_string_lossy() != "ts" - || !self.ffmpeg_preset.is_empty() - { + let extension = path.extension().unwrap_or_default().to_string_lossy(); + + if (!extension.is_empty() && extension != "ts") || !self.ffmpeg_preset.is_empty() { download_ffmpeg(&ctx, &self, format.stream, path.as_path()).await?; } else if path.to_str().unwrap() == "-" { let mut stdout = std::io::stdout().lock(); @@ -279,6 +283,19 @@ async fn download_ffmpeg( .arg("-y") .args(input_presets) .args(["-f", "mpegts", "-i", "pipe:"]) + .args( + if target + .extension() + .unwrap_or_default() + .to_string_lossy() + .is_empty() + { + vec!["-f", "mpegts"] + } else { + vec![] + } + .as_slice(), + ) .args(output_presets) .arg(target.to_str().unwrap()) .spawn()?; diff --git a/crunchy-cli-core/src/utils/os.rs b/crunchy-cli-core/src/utils/os.rs index e3320fb..d2d4c3c 100644 --- a/crunchy-cli-core/src/utils/os.rs +++ b/crunchy-cli-core/src/utils/os.rs @@ -1,6 +1,6 @@ use log::debug; use std::io::ErrorKind; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use std::{env, io}; use tempfile::{Builder, NamedTempFile}; @@ -37,9 +37,8 @@ pub fn tempfile>(suffix: S) -> io::Result { /// Check if the given path exists and rename it until the new (renamed) file does not exist. pub fn free_file(mut path: PathBuf) -> PathBuf { - // if path is not a file and not a dir it's probably a pipe on linux which reguarly is intended - // and thus does not need to be renamed. what it is on windows ¯\_(ツ)_/¯ - if !path.is_file() && !path.is_dir() { + // if it's a special file does not rename it + if is_special_file(&path) { return path; } @@ -58,3 +57,9 @@ pub fn free_file(mut path: PathBuf) -> PathBuf { } path } + +/// Check if the given path is a special file. On Linux this is probably a pipe and on Windows +/// ¯\_(ツ)_/¯ +pub fn is_special_file>(path: P) -> bool { + path.as_ref().exists() && !path.as_ref().is_file() && !path.as_ref().is_dir() +}