diff options
| author | Nathan | 2017-07-22 16:39:24 -0400 | 
|---|---|---|
| committer | Nathan | 2017-07-22 16:39:24 -0400 | 
| commit | 81324bf762067b1ed257e506c2ce88421387afd8 (patch) | |
| tree | d8e4c02971df8a799b3bc615991d9969ac9cfd6e /src | |
| parent | c2a8ea951ad98baa7f1776cba6edf7127860cbb3 (diff) | |
| download | podcast-81324bf762067b1ed257e506c2ce88421387afd8.tar.bz2 | |
Release 0.2.0 - Now with async IO and download episode ranges
Diffstat (limited to 'src')
| -rw-r--r-- | src/actions.rs | 48 | ||||
| -rw-r--r-- | src/main.rs | 23 | ||||
| -rw-r--r-- | src/structs.rs | 13 | ||||
| -rw-r--r-- | src/utils.rs | 2 | 
4 files changed, 63 insertions, 23 deletions
| diff --git a/src/actions.rs b/src/actions.rs index d81aa8c..b87b2f1 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -4,6 +4,7 @@ use rss::Channel;  use std::fs::{DirBuilder, File};  use std::io::{self, Read, Write};  use std::process::Command; +use rayon::prelude::*;  use structs::*;  use utils::*; @@ -26,8 +27,7 @@ pub fn list_episodes(state: &State, search: &str) {  }  pub fn update_rss(state: &State) { -    let subs = state.subscriptions(); -    for sub in subs { +    state.subscriptions().par_iter().for_each(|ref sub| {          let mut path = get_podcast_dir();          path.push(".rss");          DirBuilder::new().recursive(true).create(&path).unwrap(); @@ -40,7 +40,7 @@ pub fn update_rss(state: &State) {          let mut content: Vec<u8> = Vec::new();          resp.read_to_end(&mut content).unwrap();          file.write_all(&content).unwrap(); -    } +    });  }  pub fn list_subscriptions(state: &State) { @@ -49,6 +49,28 @@ pub fn list_subscriptions(state: &State) {      }  } +pub fn download_range(state: &State, p_search: &str, e_search: &str) { +    let re_pod = Regex::new(p_search).unwrap(); +    let input = String::from(e_search); +    let range: Vec<usize> = input +        .split('-') +        .map(|i| i.parse::<usize>().unwrap()) +        .collect(); + +    for subscription in state.subscriptions() { +        if re_pod.is_match(&subscription.name) { +            let podcast = Podcast::from_url(&subscription.url).unwrap(); +            let episodes = podcast.episodes(); + +            &episodes[episodes.len() - range[1]..episodes.len() - range[0]] +                .par_iter() +                .for_each(|ref ep| if let Err(err) = ep.download(podcast.title()) { +                    println!("{}", err); +                }); +        } +    } +} +  pub fn download_episode(state: &State, p_search: &str, e_search: &str) {      let re_pod = Regex::new(p_search).unwrap();      let ep_num = e_search.parse::<usize>().unwrap(); @@ -80,7 +102,14 @@ pub fn play_episode(state: &State, p_search: &str, ep_num_string: &str) {      let ep_num = ep_num_string.parse::<usize>().unwrap();      let mut path = get_podcast_dir();      path.push(".rss"); -    DirBuilder::new().recursive(true).create(&path).unwrap(); +    if let Err(err) = DirBuilder::new().recursive(true).create(&path) { +        eprintln!( +            "Couldn't create directory: {}\nReason: {}", +            path.to_str().unwrap(), +            err +        ); +        return; +    }      for subscription in state.subscriptions() {          if re_pod.is_match(&subscription.name) {              let mut filename = String::from(subscription.name); @@ -110,19 +139,22 @@ pub fn play_episode(state: &State, p_search: &str, ep_num_string: &str) {      }  } -fn launch_player(url: &str)  { +fn launch_player(url: &str) {      if let Err(_) = launch_mpv(&url) {          launch_vlc(url)      }  }  fn launch_mpv(url: &str) -> Result<(), io::Error> { -    if let Err(err) = Command::new("mpv").args(&["--audio-display=no", "--ytdl=no", url]).status() { +    if let Err(err) = Command::new("mpv") +        .args(&["--audio-display=no", "--ytdl=no", url]) +        .status() +    {          match err.kind() {              io::ErrorKind::NotFound => {                  eprintln!("Couldn't open mpv\nTrying vlc...");                  return Err(err); -            }, +            }              _ => eprintln!("Error: {}", err),          }      } @@ -134,7 +166,7 @@ fn launch_vlc(url: &str) {          match err.kind() {              io::ErrorKind::NotFound => {                  eprintln!("vlc not found in PATH\nAborting..."); -            }, +            }              _ => eprintln!("Error: {}", err),          }      } diff --git a/src/main.rs b/src/main.rs index 0eab682..c408745 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@  extern crate clap; +extern crate rayon;  extern crate regex;  extern crate reqwest;  extern crate rss; @@ -61,11 +62,9 @@ fn main() {          .subcommand(              SubCommand::with_name("search")                  .about("searches for podcasts") -                .arg( -                    Arg::with_name("debug") -                        .short("d") -                        .help("print debug information verbosely"), -                ), +                .arg(Arg::with_name("debug").short("d").help( +                    "print debug information verbosely", +                )),          )          .subcommand(              SubCommand::with_name("subscribe") @@ -77,9 +76,9 @@ fn main() {                          .index(1),                  ),          ) -        .subcommand( -            SubCommand::with_name("update").about("update subscribed podcasts"), -        ) +        .subcommand(SubCommand::with_name("update").about( +            "update subscribed podcasts", +        ))          .get_matches();      match matches.subcommand_name() { @@ -87,7 +86,13 @@ fn main() {              let download_matches = matches.subcommand_matches("download").unwrap();              let podcast = download_matches.value_of("PODCAST").unwrap();              match download_matches.value_of("EPISODE") { -                Some(ep) => download_episode(&state, podcast, ep), +                Some(ep) => { +                    if String::from(ep).contains("-") { +                        download_range(&state, podcast, ep) +                    } else { +                        download_episode(&state, podcast, ep) +                    } +                }                  None => download_all(&state, podcast),              }          } diff --git a/src/structs.rs b/src/structs.rs index a94c96e..7087077 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -1,4 +1,5 @@  use actions::*; +use rayon::prelude::*;  use reqwest;  use rss::{self, Channel, Item};  use serde_json; @@ -113,15 +114,17 @@ impl Podcast {          let downloaded = already_downloaded(self.title()); -        for ep in self.episodes() { -            if let Some(ep_title) = ep.title() { +        self.episodes().par_iter().for_each( +            |ref i| if let Some(ep_title) = +                i.title() +            {                  if !downloaded.contains(ep_title) { -                    if let Err(err) = ep.download(self.title()) { +                    if let Err(err) = i.download(self.title()) {                          println!("{}", err);                      }                  } -            } -        } +            }, +        );      }  } diff --git a/src/utils.rs b/src/utils.rs index e602932..b2c590a 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -28,7 +28,7 @@ pub fn already_downloaded(dir: &str) -> BTreeSet<String> {  }  pub fn get_podcast_dir() -> PathBuf { -   match env::var_os("PODCAST") { +    match env::var_os("PODCAST") {          Some(val) => PathBuf::from(val),          None => {              let mut path = env::home_dir().unwrap(); | 
