Merge pull request #92 from crunchy-labs/fix/non-existing-parent-directory

Fix non existing parent directory
This commit is contained in:
ByteDream 2022-12-28 01:10:43 +01:00 committed by GitHub
commit 9e0edda7c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 8 deletions

View file

@ -3,7 +3,7 @@ use crate::cli::utils::{download_segments, find_resolution, FFmpegPreset};
use crate::utils::context::Context; use crate::utils::context::Context;
use crate::utils::format::{format_string, Format}; use crate::utils::format::{format_string, Format};
use crate::utils::log::progress; 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::parse::{parse_url, UrlFilter};
use crate::utils::sort::{sort_formats_after_seasons, sort_seasons_after_number}; use crate::utils::sort::{sort_formats_after_seasons, sort_seasons_after_number};
use crate::Execute; use crate::Execute;
@ -133,6 +133,7 @@ impl Execute for Archive {
.unwrap_or_default() .unwrap_or_default()
.to_string_lossy() .to_string_lossy()
!= "mkv" != "mkv"
&& !is_special_file(PathBuf::from(&self.output))
{ {
bail!("File extension is not '.mkv'. Currently only matroska / '.mkv' files are supported") bail!("File extension is not '.mkv'. Currently only matroska / '.mkv' files are supported")
} }
@ -251,7 +252,11 @@ impl Execute for Archive {
info!( info!(
"Downloading {} to '{}'", "Downloading {} to '{}'",
primary.title, 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!( tab_info!(
"Episode: S{:02}E{:02}", "Episode: S{:02}E{:02}",
@ -647,6 +652,13 @@ fn generate_mkv(
debug!("ffmpeg {}", command_args.join(" ")); 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") let ffmpeg = Command::new("ffmpeg")
.stdout(Stdio::null()) .stdout(Stdio::null())
.stderr(Stdio::piped()) .stderr(Stdio::piped())

View file

@ -3,7 +3,7 @@ use crate::cli::utils::{download_segments, find_resolution, FFmpegPreset};
use crate::utils::context::Context; use crate::utils::context::Context;
use crate::utils::format::{format_string, Format}; use crate::utils::format::{format_string, Format};
use crate::utils::log::progress; 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::parse::{parse_url, UrlFilter};
use crate::utils::sort::{sort_formats_after_seasons, sort_seasons_after_number}; use crate::utils::sort::{sort_formats_after_seasons, sort_seasons_after_number};
use crate::Execute; use crate::Execute;
@ -219,7 +219,11 @@ impl Execute for Download {
info!( info!(
"Downloading {} to '{}'", "Downloading {} to '{}'",
format.title, 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!("Episode: S{:02}E{:02}", format.season_number, format.number);
tab_info!("Audio: {}", format.audio); tab_info!("Audio: {}", format.audio);
@ -232,14 +236,20 @@ impl Execute for Download {
tab_info!("Resolution: {}", format.stream.resolution); tab_info!("Resolution: {}", format.stream.resolution);
tab_info!("FPS: {:.2}", format.stream.fps); tab_info!("FPS: {:.2}", format.stream.fps);
if path.extension().unwrap_or_default().to_string_lossy() != "ts" let extension = path.extension().unwrap_or_default().to_string_lossy();
|| !self.ffmpeg_preset.is_empty()
{ if (!extension.is_empty() && extension != "ts") || !self.ffmpeg_preset.is_empty() {
download_ffmpeg(&ctx, &self, format.stream, path.as_path()).await?; download_ffmpeg(&ctx, &self, format.stream, path.as_path()).await?;
} else if path.to_str().unwrap() == "-" { } else if path.to_str().unwrap() == "-" {
let mut stdout = std::io::stdout().lock(); let mut stdout = std::io::stdout().lock();
download_segments(&ctx, &mut stdout, None, format.stream).await?; download_segments(&ctx, &mut stdout, None, format.stream).await?;
} else { } 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)?; let mut file = File::options().create(true).write(true).open(&path)?;
download_segments(&ctx, &mut file, None, format.stream).await? download_segments(&ctx, &mut file, None, format.stream).await?
} }
@ -259,6 +269,13 @@ async fn download_ffmpeg(
let (input_presets, output_presets) = let (input_presets, output_presets) =
FFmpegPreset::ffmpeg_presets(download.ffmpeg_preset.clone())?; 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") let mut ffmpeg = Command::new("ffmpeg")
.stdin(Stdio::piped()) .stdin(Stdio::piped())
.stdout(Stdio::null()) .stdout(Stdio::null())
@ -266,6 +283,19 @@ async fn download_ffmpeg(
.arg("-y") .arg("-y")
.args(input_presets) .args(input_presets)
.args(["-f", "mpegts", "-i", "pipe:"]) .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) .args(output_presets)
.arg(target.to_str().unwrap()) .arg(target.to_str().unwrap())
.spawn()?; .spawn()?;

View file

@ -1,6 +1,6 @@
use log::debug; use log::debug;
use std::io::ErrorKind; use std::io::ErrorKind;
use std::path::PathBuf; use std::path::{Path, PathBuf};
use std::process::{Command, Stdio}; use std::process::{Command, Stdio};
use std::{env, io}; use std::{env, io};
use tempfile::{Builder, NamedTempFile}; use tempfile::{Builder, NamedTempFile};
@ -37,6 +37,11 @@ pub fn tempfile<S: AsRef<str>>(suffix: S) -> io::Result<NamedTempFile> {
/// Check if the given path exists and rename it until the new (renamed) file does not exist. /// 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 { pub fn free_file(mut path: PathBuf) -> PathBuf {
// if it's a special file does not rename it
if is_special_file(&path) {
return path;
}
let mut i = 0; let mut i = 0;
while path.exists() { while path.exists() {
i += 1; i += 1;
@ -52,3 +57,9 @@ pub fn free_file(mut path: PathBuf) -> PathBuf {
} }
path 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<P: AsRef<Path>>(path: P) -> bool {
path.as_ref().exists() && !path.as_ref().is_file() && !path.as_ref().is_dir()
}