diff --git a/.gitignore b/.gitignore index 088ba6b..1720240 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,11 @@ Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk + + +# Added by cargo +# +# already existing elements were commented out + +/target +#Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..e0af84a --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "ytd-rs" +version = "0.1.0" +authors = ["Nils Pukropp "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..ac9f607 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,9 @@ +pub mod ytd; + +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + assert_eq!(2 + 2, 4); + } +} diff --git a/src/ytd.rs b/src/ytd.rs new file mode 100644 index 0000000..ea4459d --- /dev/null +++ b/src/ytd.rs @@ -0,0 +1,81 @@ +//! Rust-Wrapper for youtube-dl + +use std::{ + fs::{canonicalize, create_dir_all}, + io::Error, + path::PathBuf, + process::ExitStatus, +}; +use std::{path::Path, process::Command}; + +pub struct YoutubeDL { + path: PathBuf, + link: String, + args: Vec<(String, Option)>, +} + +impl YoutubeDL { + pub fn new( + dl_path: &str, + args: Vec<(String, Option)>, + link: String, + ) -> Result { + // create path + let path = Path::new(dl_path); + + // check if it already exists + if !path.exists() { + // if not create + if let Err(why) = create_dir_all(&path) { + return Err(format!("Error: {:?}", why)); + } + } + + // return error if no directory + if !path.is_dir() { + return Err("Error: path is not a directory".to_string()); + } + + // absolute path + match canonicalize(dl_path) { + // return new youtube-dl job + Ok(path) => Ok(YoutubeDL { path, link, args }), + Err(why) => Err(format!("Error: {:?}", why)), + } + } + + pub fn download(&self) -> Result<&PathBuf, String> { + let result = self.spawn_youtube_dl(); + + if let Err(why) = result { + Err(format!("Error: {:?}", why)) + } else { + Ok(&self.path) + } + } + + fn spawn_youtube_dl(&self) -> Result { + let mut path = self.path.clone(); + path.push("%(title).90s.%(ext)s"); + let mut cmd = Command::new("youtube-dl"); + cmd.arg("--output") + .arg(format!("{}", path.display())) + .arg("--quiet") + .arg("--no-warnings"); + + for (opt, arg) in self.args.iter() { + match arg { + Some(arg) => cmd.arg(opt).arg(arg), + None => cmd.arg(opt), + }; + } + + cmd.arg(&self.link); + + let mut pr = match cmd.spawn() { + Err(why) => panic!("couldn't spawn youtube-dl: {:?}", why), + Ok(process) => process, + }; + pr.wait() + } +}