2018-08-14 16:42:53 +00:00
|
|
|
use std::process::{Command, Output, Stdio};
|
|
|
|
use std::str::from_utf8;
|
|
|
|
|
2018-11-14 14:29:58 +00:00
|
|
|
use super::prelude::*;
|
2018-08-14 16:42:53 +00:00
|
|
|
|
|
|
|
const FIRST_LOAD_PREFIX: &str = "[download] Destination:";
|
|
|
|
const RELOAD_SUFFIX: &str = " has already been downloaded";
|
|
|
|
const PREFIX: &str = "[download] ";
|
|
|
|
|
|
|
|
fn convert_output(out: &Output) -> Result<Vec<String>, String> {
|
|
|
|
match from_utf8(out.stdout.as_slice()) {
|
|
|
|
Ok(string) => {
|
|
|
|
let lines = string.split("\n");
|
|
|
|
|
|
|
|
let mut files = Vec::new();
|
|
|
|
|
|
|
|
for line in lines {
|
|
|
|
if !line.is_empty() {
|
|
|
|
let mut line = line.to_string();
|
|
|
|
let line_len = line.len();
|
|
|
|
|
|
|
|
if line.starts_with(FIRST_LOAD_PREFIX) {
|
|
|
|
let file_name = line.split_off(FIRST_LOAD_PREFIX.len());
|
|
|
|
files.push(file_name.trim().to_string());
|
|
|
|
} else if line.ends_with(RELOAD_SUFFIX) {
|
|
|
|
line.split_off(line_len - RELOAD_SUFFIX.len());
|
|
|
|
let file_name = line.split_off(PREFIX.len());
|
|
|
|
files.push(file_name.trim().to_string());
|
|
|
|
}
|
|
|
|
}
|
2018-09-16 07:58:47 +00:00
|
|
|
}
|
2018-09-14 12:08:44 +00:00
|
|
|
|
|
|
|
let mut mp3s = Vec::new();
|
|
|
|
|
|
|
|
for file in files {
|
|
|
|
mp3s.push(str::replace(file.as_str(), ".webm", ".mp3").to_string());
|
2018-08-14 16:42:53 +00:00
|
|
|
}
|
|
|
|
|
2018-09-14 12:08:44 +00:00
|
|
|
Ok(mp3s)
|
2018-08-14 16:42:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Err(_) => Err("error converting output".to_string()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn youtube_dl(uri: &str) -> Result<Vec<Song>, String> {
|
2018-09-16 07:58:47 +00:00
|
|
|
let args = ["-f", "bestaudio/best", "-o", "%(title)s", uri];
|
2018-08-14 16:42:53 +00:00
|
|
|
|
|
|
|
let out = match Command::new("youtube-dl")
|
|
|
|
.args(&args)
|
|
|
|
.stdin(Stdio::null())
|
|
|
|
.output()
|
|
|
|
{
|
|
|
|
Ok(out) => out,
|
2018-11-25 18:30:53 +00:00
|
|
|
Err(why) => return Err(format!("youtube-dl error {:?}", why)),
|
2018-08-14 16:42:53 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
if !out.status.success() {
|
2018-11-25 18:30:53 +00:00
|
|
|
let stdout = match String::from_utf8(out.stdout) {
|
|
|
|
Ok(string) => string,
|
|
|
|
Err(_) => String::new(),
|
|
|
|
};
|
|
|
|
|
|
|
|
let stderr = match String::from_utf8(out.stderr) {
|
|
|
|
Ok(string) => string,
|
|
|
|
Err(_) => String::new(),
|
|
|
|
};
|
|
|
|
|
|
|
|
return Err(format!(
|
|
|
|
"Shell error\nstdout: {}\nstderr: {}",
|
|
|
|
stdout, stderr
|
|
|
|
));
|
2018-08-14 16:42:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let files = check_result!(convert_output(&out));
|
|
|
|
|
|
|
|
for file in &files {
|
|
|
|
println!("file: {}", file);
|
|
|
|
}
|
|
|
|
|
2018-11-14 15:43:53 +00:00
|
|
|
let mut songs = Vec::new();
|
2018-08-14 16:42:53 +00:00
|
|
|
|
|
|
|
for file in files {
|
2018-11-14 15:43:53 +00:00
|
|
|
songs.push(Song { name: file })
|
2018-08-14 16:42:53 +00:00
|
|
|
}
|
|
|
|
|
2018-11-14 15:43:53 +00:00
|
|
|
Ok(songs)
|
2018-08-14 16:42:53 +00:00
|
|
|
}
|