diff options
| author | Nathan Jaremko | 2019-02-24 18:57:46 -0500 |
|---|---|---|
| committer | Nathan Jaremko | 2019-02-24 18:57:46 -0500 |
| commit | ec5f7a63028303f0f0aab78dbebd61afba68b184 (patch) | |
| tree | fd48b58047e3abdb2b49c2de3128696371ad6754 | |
| parent | b238a6606fb4ea0df4c69b4f15874a65f22263b4 (diff) | |
| download | podcast-ec5f7a63028303f0f0aab78dbebd61afba68b184.tar.bz2 | |
Add completion generation
| -rw-r--r-- | CHANGELOG | 3 | ||||
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | src/actions.rs | 109 | ||||
| -rw-r--r-- | src/main.rs | 7 | ||||
| -rw-r--r-- | src/match_handler.rs | 18 | ||||
| -rw-r--r-- | src/parser.rs | 5 | ||||
| -rw-r--r-- | src/structs.rs | 7 | ||||
| -rw-r--r-- | src/utils.rs | 20 |
8 files changed, 73 insertions, 98 deletions
@@ -1,3 +1,6 @@ +0.8.2 +- Add completion generation for all major shells + 0.8.1 - Fix parser to actually see "sub" subcommand @@ -32,4 +32,4 @@ serde = "1.0" serde_derive = "1.0" serde_json = "1.0" serde_yaml = "0.8" -toml = "0.4" +toml = "0.4"
\ No newline at end of file diff --git a/src/actions.rs b/src/actions.rs index 0ecb083..cb4a157 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -7,6 +7,8 @@ use std::io::{self, BufReader, Read, Write}; use std::process::Command; use crate::errors::*; +use clap::App; +use clap::Shell; use rayon::prelude::*; use regex::Regex; use reqwest; @@ -54,11 +56,10 @@ pub fn download_rss(config: &Config, url: &str) -> Result<()> { println!("Downloading episode(s)..."); let channel = download_rss_feed(url)?; let mut download_limit = config.auto_download_limit as usize; - if 0 < download_limit { + if 0 < download_limit { let podcast = Podcast::from(channel); let episodes = podcast.episodes(); - if episodes.len() < download_limit - { + if episodes.len() < download_limit { download_limit = episodes.len() } episodes[..download_limit].par_iter().for_each(|ep| { @@ -187,36 +188,32 @@ pub fn download(podcast_name: &str, episode: &Episode) -> Result<()> { create_dir_if_not_exist(&path)?; if let Some(url) = episode.url() { - if let Some(title) = episode.title() { - let mut filename = title; - filename.push_str( - episode.extension() - .chain_err(|| "unable to retrieve extension")?, - ); - path.push(filename); - if !path.exists() { - { - let mut handle = stdout.lock(); - writeln!(&mut handle, "Downloading: {:?}", &path).ok(); - } - let mut file = File::create(&path).chain_err(|| UNABLE_TO_CREATE_FILE)?; - let mut resp = reqwest::get(url).chain_err(|| UNABLE_TO_GET_HTTP_RESPONSE)?; - let mut content: Vec<u8> = Vec::new(); - resp.read_to_end(&mut content) - .chain_err(|| UNABLE_TO_READ_RESPONSE_TO_END)?; - file.write_all(&content) - .chain_err(|| UNABLE_TO_WRITE_FILE)?; - } else { + if let Some(title) = episode.title() { + let mut filename = title; + filename.push_str( + episode + .extension() + .chain_err(|| "unable to retrieve extension")?, + ); + path.push(filename); + if !path.exists() { + { let mut handle = stdout.lock(); - writeln!( - &mut handle, - "File already exists: {:?}", - &path - ) - .ok(); + writeln!(&mut handle, "Downloading: {:?}", &path).ok(); } + let mut file = File::create(&path).chain_err(|| UNABLE_TO_CREATE_FILE)?; + let mut resp = reqwest::get(url).chain_err(|| UNABLE_TO_GET_HTTP_RESPONSE)?; + let mut content: Vec<u8> = Vec::new(); + resp.read_to_end(&mut content) + .chain_err(|| UNABLE_TO_READ_RESPONSE_TO_END)?; + file.write_all(&content) + .chain_err(|| UNABLE_TO_WRITE_FILE)?; + } else { + let mut handle = stdout.lock(); + writeln!(&mut handle, "File already exists: {:?}", &path).ok(); } } + } Ok(()) } @@ -256,8 +253,7 @@ pub fn download_episode_by_name( .collect(); if let Some(ep) = filtered_episodes.first() { - download(podcast.title(), ep) - .chain_err(|| "unable to download episode")?; + download(podcast.title(), ep).chain_err(|| "unable to download episode")?; } } } @@ -519,50 +515,13 @@ pub fn remove_podcast(state: &mut State, p_search: &str) -> Result<()> { Ok(()) } -pub fn print_completion(arg: &str) { - let zsh = r#"#compdef podcast -#autoload - -# Copyright (C) 2019: -# Nathan Jaremko <njaremko@gmail.com> -# All Rights Reserved. -# This file is licensed under the GPLv2+. Please see COPYING for more information. - -_podcast() { - local ret=1 - _arguments -C \ - '1: :_podcast_cmds' \ - && ret=0 -} - -_podcast_cmds () { - local subcommands; - subcommands=( - "download:Download episodes of podcast" - "help:Prints this message or the help of the given subcommand(s)" - "ls:List podcasts or episodes of a podcast" - "play:Play episodes of a podcast" - "refresh:Refreshes subscribed podcasts" - "rm:Unsubscribe from a podcast" - "completion:Shell Completions" - "search:Searches for podcasts" - "subscribe:Subscribe to a podcast RSS feed" - "update:check for updates" - ) - _describe -t commands 'podcast' subcommands - _arguments : \ - "--version[Output version information]" \ - "--help[Output help message]" -} - -_podcast"#; - - //let bash = ""; - //let sh = ""; +pub fn print_completion(app: &mut App, arg: &str) { match arg { - "zsh" => println!("{}", zsh), - //"bash" => println!("{}", bash), - //"sh" => println!("{}", sh), - _ => println!("Only options avaliable are: zsh"), + "zsh" => app.gen_completions_to("podcast", Shell::Zsh, &mut io::stdout()), + "bash" => app.gen_completions_to("podcast", Shell::Bash, &mut io::stdout()), + "powershell" => app.gen_completions_to("podcast", Shell::PowerShell, &mut io::stdout()), + "fish" => app.gen_completions_to("podcast", Shell::Fish, &mut io::stdout()), + "elvish" => app.gen_completions_to("podcast", Shell::Elvish, &mut io::stdout()), + other => eprintln!("Completions are not available for {}", other), } } diff --git a/src/main.rs b/src/main.rs index 8be9e82..9d5b4d5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,14 +30,15 @@ pub mod errors { use self::errors::*; use self::structs::*; -const VERSION: &str = "0.8.1"; +const VERSION: &str = "0.8.2"; fn main() -> Result<()> { utils::create_directories().chain_err(|| "unable to create directories")?; migration_handler::migrate_old_subscriptions()?; let mut state = State::new(VERSION).chain_err(|| "unable to load state")?; let config = Config::new()?; - let matches = parser::get_matches(&VERSION); - match_handler::handle_matches(&VERSION, &mut state, &config, &matches)?; + let mut app = parser::get_app(&VERSION); + let matches = app.clone().get_matches(); + match_handler::handle_matches(&VERSION, &mut state, &config, &mut app, &matches)?; state.save().chain_err(|| "unable to save state") } diff --git a/src/match_handler.rs b/src/match_handler.rs index 599e8f1..428f99c 100644 --- a/src/match_handler.rs +++ b/src/match_handler.rs @@ -1,4 +1,7 @@ -use clap::ArgMatches; +use clap::{App, ArgMatches}; + +use std::env; +use std::path::Path; use crate::actions::*; use crate::errors::*; @@ -8,6 +11,7 @@ pub fn handle_matches( version: &str, state: &mut State, config: &Config, + app: &mut App, matches: &ArgMatches, ) -> Result<()> { match matches.subcommand_name() { @@ -92,8 +96,16 @@ pub fn handle_matches( .subcommand_matches("completion") .chain_err(|| "unable to find subcommand matches")?; match matches.value_of("SHELL") { - Some(shell) => print_completion(shell), - None => print_completion(""), + Some(shell) => print_completion(app, shell), + None => { + let shell_path_env = env::var("SHELL"); + if let Ok(p) = shell_path_env { + let shell_path = Path::new(&p); + if let Some(shell) = shell_path.file_name() { + print_completion(app, shell.to_str().chain_err(|| format!("Unable to convert {:?} to string", shell))?) + } + } + } } } Some("refresh") => update_rss(state), diff --git a/src/parser.rs b/src/parser.rs index ce5ca93..6802ceb 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,6 +1,6 @@ -use clap::{App, Arg, ArgMatches, SubCommand}; +use clap::{App, Arg, SubCommand}; -pub fn get_matches<'a>(version: &str) -> ArgMatches<'a> { +pub fn get_app<'a, 'b>(version: &'a str) -> App<'a, 'b> { App::new("podcast") .version(version) .author("Nathan J. <njaremko@gmail.com>") @@ -133,5 +133,4 @@ pub fn get_matches<'a>(version: &str) -> ArgMatches<'a> { .index(1), ), ) - .get_matches() } diff --git a/src/structs.rs b/src/structs.rs index d6bad40..1c3ceaf 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -103,9 +103,10 @@ impl State { }; state.version = String::from(version); // Check if a day has passed (86400 seconds) since last launch - if 86400 < Utc::now() - .signed_duration_since(state.last_run_time) - .num_seconds() + if 86400 + < Utc::now() + .signed_duration_since(state.last_run_time) + .num_seconds() { update_rss(&mut state); check_for_update(&state.version)?; diff --git a/src/utils.rs b/src/utils.rs index 5c3b2db..e1b2ccb 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -66,7 +66,7 @@ pub fn create_dir_if_not_exist(path: &PathBuf) -> Result<()> { .recursive(true) .create(&path) .chain_err(|| UNABLE_TO_CREATE_DIRECTORY)?; - Ok(()) + Ok(()) } pub fn create_directories() -> Result<()> { @@ -76,16 +76,16 @@ pub fn create_directories() -> Result<()> { } pub fn delete(title: &str) -> Result<()> { - let mut path = get_xml_dir()?; - let mut filename = String::from(title); - filename.push_str(".xml"); - path.push(filename); - fs::remove_file(path).chain_err(|| UNABLE_TO_REMOVE_FILE) - } + let mut path = get_xml_dir()?; + let mut filename = String::from(title); + filename.push_str(".xml"); + path.push(filename); + fs::remove_file(path).chain_err(|| UNABLE_TO_REMOVE_FILE) +} - pub fn delete_all() -> Result<()> { - fs::remove_dir_all(get_xml_dir()?).chain_err(|| UNABLE_TO_READ_DIRECTORY) - } +pub fn delete_all() -> Result<()> { + fs::remove_dir_all(get_xml_dir()?).chain_err(|| UNABLE_TO_READ_DIRECTORY) +} pub fn already_downloaded(dir: &str) -> Result<HashSet<String>> { let mut result = HashSet::new(); |
