Browse Source

Move some functionality to functions

main v0.2.0
Georg Hopp 11 months ago
parent
commit
3124fbc202
Signed by: ghopp GPG Key ID: 4C5D226768784538
  1. 72
      src/main.rs
  2. 82
      src/process.rs

72
src/main.rs

@ -1,12 +1,10 @@
mod download_error;
mod client;
mod process;
use std::{
env::{current_dir, set_current_dir},
ffi::OsStr,
io::ErrorKind,
path::{Path, PathBuf},
process::Command,
path::PathBuf,
time::Duration
};
@ -14,12 +12,12 @@ use anyhow::anyhow;
use clap::Parser;
use env_logger::Env;
use http::Uri;
use shellwords::escape;
use tokio::{fs::{create_dir, remove_dir_all}, task::JoinSet};
use which::which;
use tokio::task::JoinSet;
use log::{log, Level};
use process::{enter_download_dir, ffmpeg, remove_download_dir};
#[allow(dead_code)]
#[derive(Debug)]
@ -65,20 +63,6 @@ async fn main() -> anyhow::Result<()> {
return Err(anyhow!("Only filenames with .mp4 extension are allowed"));
}
let basename = name.file_stem()
. ok_or(anyhow!("No valid filename given"))?;
if let Err(error) = create_dir(basename).await {
if ErrorKind::AlreadyExists == error.kind() {
if ! Path::new(basename).is_dir() {
return Err(anyhow!("Unable to create directory at {:?}", basename));
}
} else {
return Err(anyhow!("Unable to create directory at {:?}", basename));
}
}
set_current_dir(basename)?;
let concurrency = args.concurrency.unwrap_or(10);
let timeout = args.timeout.unwrap_or(10);
let timeout = Duration::from_secs(timeout);
@ -87,6 +71,10 @@ async fn main() -> anyhow::Result<()> {
let m3u8_path_and_query = m3u8_uri.path_and_query()
. ok_or(anyhow!("Problem path and query in m3u8 uri"))?;
log!(Level::Info, "Create and chdir into temporary download dir...");
let basename = enter_download_dir(&name).await?;
log!(Level::Info, "Creating an HTTP client with Tower layers...");
let mut state = client::State::new(&m3u8_uri, concurrency, timeout)?;
@ -127,45 +115,15 @@ async fn main() -> anyhow::Result<()> {
}
}
let outfile = current_dir()?;
let outfile = outfile.parent().ok_or(anyhow!("Can't get output dir"))?;
let mut outfile = outfile.canonicalize()?;
outfile.push(name);
let outfile = outfile.as_os_str();
let ffmpeg = which("ffmpeg")?;
let ffmpeg = ffmpeg.as_path().as_os_str();
let index = Path::new(m3u8_uri.path()).file_name()
. ok_or(anyhow!("unable to get index filename from url"))?;
let index = Path::new(index).canonicalize()?;
let index = index.as_os_str();
log!(Level::Debug, "ffmpeg: {:?}", ffmpeg);
log!(Level::Debug, "index: {:?}", index);
log!(Level::Debug, "outfile: {:?}", outfile);
log!( Level::Info
, "execute: {} -allowed_extensions ALL -i {} -c copy {}"
, escape(ffmpeg.try_into()?)
, escape(index.try_into()?)
, escape(outfile.try_into()?) );
let mut child = Command::new(ffmpeg)
. arg("-allowed_extensions")
. arg("ALL")
. arg("-i")
. arg(index)
. arg("-c")
. arg("copy")
. arg(outfile)
. spawn()?;
let status = child.wait()?;
log!(Level::Info, "Call ffmpeg to join ts files to single mp4...");
let status = ffmpeg(&name, &m3u8_uri).await?;
log!(Level::Info, "ffmpeg status: {}", status);
set_current_dir("..")?;
remove_dir_all(basename).await?;
log!(Level::Info, "Leave and remove temporary download dir...");
remove_download_dir(&basename).await?;
Ok(())
}

82
src/process.rs

@ -0,0 +1,82 @@
use std::{
env::{current_dir,
set_current_dir},
ffi::OsString,
io::ErrorKind,
path::Path,
process::{Command, ExitStatus}
};
use anyhow::anyhow;
use http::Uri;
use shellwords::escape;
use tokio::fs::{create_dir, remove_dir_all};
use which::which;
use log::{log, Level};
pub(super) async fn enter_download_dir(name: &dyn AsRef<Path>) -> anyhow::Result<OsString> {
let basename = name.as_ref().file_stem()
. ok_or(anyhow!("No valid filename given"))?;
if let Err(error) = create_dir(basename).await {
if ErrorKind::AlreadyExists == error.kind() {
if ! Path::new(basename).is_dir() {
return Err(anyhow!("Unable to create directory at {:?}", basename));
}
} else {
return Err(anyhow!("Unable to create directory at {:?}", basename));
}
}
set_current_dir(basename)?;
Ok(basename.into())
}
pub(super) async fn remove_download_dir(name: &dyn AsRef<Path>) -> anyhow::Result<()> {
let name = name.as_ref().parent()
. ok_or(anyhow!("Failed to get parent of download dir"))?;
set_current_dir(name)?;
remove_dir_all(name).await?;
Ok(())
}
pub(super) async fn ffmpeg(name: &dyn AsRef<Path>, uri: &Uri) -> anyhow::Result<ExitStatus> {
let outfile = current_dir()?;
let outfile = outfile.parent().ok_or(anyhow!("Can't get output dir"))?;
let mut outfile = outfile.canonicalize()?;
outfile.push(name);
let outfile = outfile.as_os_str();
let which = which("ffmpeg");
let ffmpeg = which?;
let ffmpeg = ffmpeg.as_os_str();
let index = Path::new(uri.path()).file_name()
. ok_or(anyhow!("unable to get index filename from url"))?;
let index = Path::new(index).canonicalize()?;
let index = index.as_os_str();
log!(Level::Debug, "ffmpeg: {:?}", ffmpeg);
log!(Level::Debug, "index: {:?}", index);
log!(Level::Debug, "outfile: {:?}", outfile);
log!( Level::Debug
, "execute: {} -allowed_extensions ALL -i {} -c copy {}"
, escape(ffmpeg.try_into()?)
, escape(index.try_into()?)
, escape(outfile.try_into()?) );
let mut child = Command::new(ffmpeg)
. arg("-allowed_extensions")
. arg("ALL")
. arg("-i")
. arg(index)
. arg("-c")
. arg("copy")
. arg(outfile)
. spawn()?;
Ok(child.wait()?)
}
Loading…
Cancel
Save