diff options
| -rw-r--r-- | Cargo.toml | 4 | ||||
| -rw-r--r-- | src/actions.rs | 104 | ||||
| -rw-r--r-- | src/main.rs | 47 |
3 files changed, 147 insertions, 8 deletions
@@ -1,7 +1,7 @@ [package] name = "podcast" edition = "2018" -version = "0.6.1" +version = "0.7.0" authors = ["Nathan Jaremko <njaremko@gmail.com>"] description = "A command line podcast manager" license = "GPL-3.0" @@ -25,7 +25,7 @@ dirs = "1.0" error-chain = "0.12" lazy_static = "1.2" rayon = "1.0" -regex = "1.0" +regex = "1.1" reqwest = "0.9" rss = {version = "1.6", features = ["from_url"] } serde = "1.0" diff --git a/src/actions.rs b/src/actions.rs index 0775aec..58cda4f 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -151,7 +151,7 @@ pub fn download_range(state: &State, p_search: &str, e_search: &str) -> Result<( Ok(()) } -pub fn download_episode(state: &State, p_search: &str, e_search: &str) -> Result<()> { +pub fn download_episode_by_num(state: &State, p_search: &str, e_search: &str) -> Result<()> { let re_pod = Regex::new(&format!("(?i){}", &p_search)).chain_err(|| UNABLE_TO_PARSE_REGEX)?; let ep_num = e_search .parse::<usize>() @@ -170,6 +170,52 @@ pub fn download_episode(state: &State, p_search: &str, e_search: &str) -> Result Ok(()) } +pub fn download_episode_by_name( + state: &State, + p_search: &str, + e_search: &str, + download_all: bool, +) -> Result<()> { + let re_pod = Regex::new(&format!("(?i){}", &p_search)).chain_err(|| UNABLE_TO_PARSE_REGEX)?; + + for subscription in &state.subscriptions { + if re_pod.is_match(&subscription.title) { + let podcast = Podcast::from_title(&subscription.title) + .chain_err(|| UNABLE_TO_RETRIEVE_PODCAST_BY_TITLE)?; + let episodes = podcast.episodes(); + if download_all { + episodes + .iter() + .filter(|ep| { + ep.title() + .unwrap_or_else(|| "".to_string()) + .contains(e_search) + }) + .for_each(|ep| { + ep.download(podcast.title()).unwrap_or_else(|_| { + println!("Error downloading episode: {}", podcast.title()) + }); + }) + } else { + let filtered_episodes: Vec<&Episode> = episodes + .iter() + .filter(|ep| { + ep.title() + .unwrap_or_else(|| "".to_string()) + .contains(e_search) + }) + .collect(); + + if let Some(ep) = filtered_episodes.first() { + ep.download(podcast.title()) + .chain_err(|| "unable to download episode")?; + } + } + } + } + Ok(()) +} + pub fn download_all(state: &State, p_search: &str) -> Result<()> { let re_pod = Regex::new(&format!("(?i){}", &p_search)).chain_err(|| UNABLE_TO_PARSE_REGEX)?; @@ -240,7 +286,7 @@ pub fn play_latest(state: &State, p_search: &str) -> Result<()> { Ok(()) } -pub fn play_episode(state: &State, p_search: &str, ep_num_string: &str) -> Result<()> { +pub fn play_episode_by_num(state: &State, p_search: &str, ep_num_string: &str) -> Result<()> { let re_pod: Regex = Regex::new(&format!("(?i){}", &p_search)).chain_err(|| UNABLE_TO_PARSE_REGEX)?; let ep_num: usize = ep_num_string.parse::<usize>().unwrap(); @@ -287,6 +333,60 @@ pub fn play_episode(state: &State, p_search: &str, ep_num_string: &str) -> Resul Ok(()) } +pub fn play_episode_by_name(state: &State, p_search: &str, ep_string: &str) -> Result<()> { + let re_pod: Regex = + Regex::new(&format!("(?i){}", &p_search)).chain_err(|| UNABLE_TO_PARSE_REGEX)?; + let mut path: PathBuf = get_xml_dir()?; + if let Err(err) = DirBuilder::new().recursive(true).create(&path) { + eprintln!( + "Couldn't create directory: {}\nReason: {}", + path.to_str().unwrap(), + err + ); + return Ok(()); + } + for subscription in &state.subscriptions { + if re_pod.is_match(&subscription.title) { + let mut filename: String = subscription.title.clone(); + filename.push_str(".xml"); + path.push(filename); + + let mut file: File = File::open(&path).unwrap(); + let mut content: Vec<u8> = Vec::new(); + file.read_to_end(&mut content).unwrap(); + + let podcast = Podcast::from(Channel::read_from(content.as_slice()).unwrap()); + let episodes = podcast.episodes(); + let filtered_episodes: Vec<&Episode> = episodes + .iter() + .filter(|ep| { + ep.title() + .unwrap_or_else(|| "".to_string()) + .contains(ep_string) + }) + .collect(); + if let Some(episode) = filtered_episodes.first() { + filename = episode.title().unwrap(); + filename.push_str(episode.extension().unwrap()); + path = get_podcast_dir()?; + path.push(podcast.title()); + path.push(filename); + if path.exists() { + launch_player(path.to_str().chain_err(|| UNABLE_TO_CONVERT_TO_STR)?)?; + } else { + launch_player( + episode + .url() + .chain_err(|| "unable to retrieve episode url")?, + )?; + } + } + return Ok(()); + } + } + Ok(()) +} + pub fn check_for_update(version: &str) -> Result<()> { println!("Checking for updates..."); let resp: String = diff --git a/src/main.rs b/src/main.rs index 3c03ab0..4eba999 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,7 +22,7 @@ pub mod structs; pub mod utils; pub mod errors { // Create the Error, ErrorKind, ResultExt, and Result types - error_chain!{} + error_chain! {} } use self::actions::*; @@ -51,7 +51,26 @@ fn main() -> Result<()> { .required(true) .index(1), ) - .arg(Arg::with_name("EPISODE").help("Episode index").index(2)), + .arg( + Arg::with_name("EPISODE") + .required(false) + .help("Episode index") + .index(2), + ) + .arg( + Arg::with_name("name") + .short("e") + .long("episode") + .help("Download using episode name instead of number") + .required(false), + ) + .arg( + Arg::with_name("all") + .short("a") + .long("all") + .help("Download all matching episodes") + .required(false), + ), ) .subcommand( SubCommand::with_name("ls") @@ -85,6 +104,13 @@ fn main() -> Result<()> { .help("Episode index") .required(false) .index(2), + ) + .arg( + Arg::with_name("name") + .short("e") + .long("episode") + .help("Play using episode name instead of number") + .required(false), ), ) .subcommand( @@ -142,8 +168,15 @@ fn main() -> Result<()> { Some(ep) => { if String::from(ep).contains(|c| c == '-' || c == ',') { download_range(&state, podcast, ep)? + } else if download_matches.occurrences_of("name") > 0 { + download_episode_by_name( + &state, + podcast, + ep, + download_matches.occurrences_of("all") > 0, + )? } else { - download_episode(&state, podcast, ep)? + download_episode_by_num(&state, podcast, ep)? } } None => download_all(&state, podcast)?, @@ -167,7 +200,13 @@ fn main() -> Result<()> { .value_of("PODCAST") .chain_err(|| "unable to find subcommand match")?; match play_matches.value_of("EPISODE") { - Some(episode) => play_episode(&state, podcast, episode)?, + Some(episode) => { + if play_matches.occurrences_of("name") > 0 { + play_episode_by_name(&state, podcast, episode)? + } else { + play_episode_by_num(&state, podcast, episode)? + } + } None => play_latest(&state, podcast)?, } } |
