aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml4
-rw-r--r--src/actions.rs104
-rw-r--r--src/main.rs47
3 files changed, 147 insertions, 8 deletions
diff --git a/Cargo.toml b/Cargo.toml
index c023235..14385ec 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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)?,
}
}