aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Jaremko2017-11-23 13:18:21 -0500
committerNathan Jaremko2017-11-23 13:18:21 -0500
commit3313491352b1f0b2a62ae12328bd99ac3b727a66 (patch)
tree7ba58d3d2a61006416713073be06136d31e9ec91
parente2533f49d984cb2af7e5c48a8e8bb5695de0f0c7 (diff)
downloadpodcast-3313491352b1f0b2a62ae12328bd99ac3b727a66.tar.bz2
implement zsh completions and start adding some features
-rw-r--r--Cargo.toml2
-rw-r--r--completions/zsh-podcast35
-rw-r--r--src/actions.rs42
-rw-r--r--src/main.rs63
-rw-r--r--src/structs.rs44
5 files changed, 108 insertions, 78 deletions
diff --git a/Cargo.toml b/Cargo.toml
index f7d2d97..6c7f173 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "podcast"
-version = "0.3.1"
+version = "0.4.0"
authors = ["njaremko <njaremko@gmail.com>"]
description = "A command line podcast player"
license = "GPL-3.0"
diff --git a/completions/zsh-podcast b/completions/zsh-podcast
new file mode 100644
index 0000000..a39e7f6
--- /dev/null
+++ b/completions/zsh-podcast
@@ -0,0 +1,35 @@
+#compdef podcast
+#autoload
+
+# Copyright (C) 2017:
+# 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:Delete podcast"
+ "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
diff --git a/src/actions.rs b/src/actions.rs
index 3428f79..7d554b5 100644
--- a/src/actions.rs
+++ b/src/actions.rs
@@ -10,7 +10,7 @@ use structs::*;
use utils::*;
pub fn list_episodes(search: &str) {
- let re = Regex::new(search).unwrap();
+ let re = Regex::new(&format!("(?i){}", &search)).expect("Failed to parse regex");
let mut path = get_podcast_dir();
path.push(".rss");
DirBuilder::new().recursive(true).create(&path).unwrap();
@@ -58,7 +58,7 @@ pub fn download_rss(url: &str, config: &Config) {
pub fn update_rss(state: &mut State) {
println!("Checking for new episodes...");
- &state.subs.par_iter_mut().for_each(|mut sub| {
+ &state.subs.par_iter_mut().for_each(|sub| {
let mut path = get_podcast_dir();
path.push(&sub.title);
DirBuilder::new().recursive(true).create(&path).unwrap();
@@ -85,8 +85,10 @@ pub fn update_rss(state: &mut State) {
if podcast.episodes().len() > sub.num_episodes {
&podcast.episodes()[..podcast.episodes().len() - sub.num_episodes]
.par_iter()
- .for_each(|ref ep| if let Err(err) = ep.download(podcast.title()) {
- eprintln!("Error downloading {}: {}", podcast.title(), err);
+ .for_each(|ref ep| {
+ if let Err(err) = ep.download(podcast.title()) {
+ eprintln!("Error downloading {}: {}", podcast.title(), err);
+ }
});
}
sub.num_episodes = podcast.episodes().len();
@@ -100,21 +102,19 @@ 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 re_pod = Regex::new(&format!("(?i){}", &p_search)).expect("Failed to parse regex");;
for subscription in &state.subs {
if re_pod.is_match(&subscription.title) {
match Podcast::from_title(&subscription.title) {
- Ok(podcast) => {
- match parse_download_episodes(e_search) {
- Ok(episodes_to_download) => {
- if let Err(err) = podcast.download_specific(episodes_to_download) {
- eprintln!("Error: {}", err);
- }
+ Ok(podcast) => match parse_download_episodes(e_search) {
+ Ok(episodes_to_download) => {
+ if let Err(err) = podcast.download_specific(episodes_to_download) {
+ eprintln!("Error: {}", err);
}
- Err(err) => eprintln!("Error: {}", err),
}
- }
+ Err(err) => eprintln!("Error: {}", err),
+ },
Err(err) => eprintln!("Error: {}", err),
}
}
@@ -141,16 +141,14 @@ pub fn download_episode(state: &State, p_search: &str, e_search: &str) {
}
pub fn download_all(state: &State, p_search: &str) {
- let re_pod = Regex::new(p_search).unwrap();
+ let re_pod = Regex::new(&format!("(?i){}", &p_search)).expect("Failed to parse regex");
for subscription in &state.subs {
if re_pod.is_match(&subscription.title) {
match Podcast::from_title(&subscription.title) {
- Ok(podcast) => {
- if let Err(err) = podcast.download() {
- eprintln!("{}", err);
- }
- }
+ Ok(podcast) => if let Err(err) = podcast.download() {
+ eprintln!("{}", err);
+ },
Err(err) => eprintln!("Error: {}", err),
}
}
@@ -158,7 +156,7 @@ pub fn download_all(state: &State, p_search: &str) {
}
pub fn play_episode(state: &State, p_search: &str, ep_num_string: &str) {
- let re_pod = Regex::new(p_search).unwrap();
+ let re_pod = Regex::new(&format!("(?i){}", &p_search)).expect("Failed to parse regex");
let ep_num = ep_num_string.parse::<usize>().unwrap();
let mut path = get_xml_dir();
if let Err(err) = DirBuilder::new().recursive(true).create(&path) {
@@ -198,6 +196,10 @@ pub fn play_episode(state: &State, p_search: &str, ep_num_string: &str) {
}
}
+pub fn check_for_update(state: &mut State) {
+ println!("Checking for updates...");
+}
+
fn launch_player(url: &str) {
if let Err(_) = launch_mpv(&url) {
launch_vlc(&url)
diff --git a/src/main.rs b/src/main.rs
index 37da2eb..82961dc 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -4,7 +4,6 @@ extern crate rayon;
extern crate regex;
extern crate reqwest;
extern crate rss;
-extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
@@ -15,7 +14,7 @@ mod structs;
mod utils;
use actions::*;
-use clap::{Arg, App, SubCommand};
+use clap::{App, Arg, SubCommand};
use structs::*;
use utils::*;
@@ -33,9 +32,9 @@ fn main() {
};
let config = Config::new();
let matches = App::new("podcast")
- .version("1.0")
+ .version("0.4")
.author("Nathan J. <njaremko@gmail.com>")
- .about("Does awesome things")
+ .about("A command line podcast manager")
.subcommand(
SubCommand::with_name("download")
.about("download episodes of podcast")
@@ -48,7 +47,7 @@ fn main() {
.arg(Arg::with_name("EPISODE").help("Episode index").index(2)),
)
.subcommand(
- SubCommand::with_name("list")
+ SubCommand::with_name("ls")
.about("list episodes of podcast")
.arg(
Arg::with_name("PODCAST")
@@ -75,9 +74,11 @@ 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")
@@ -89,9 +90,10 @@ fn main() {
.index(1),
),
)
- .subcommand(SubCommand::with_name("update").about(
- "update subscribed podcasts",
- ))
+ .subcommand(SubCommand::with_name("refresh").about("refresh subscribed podcasts"))
+ .subcommand(SubCommand::with_name("update").about("check for updates"))
+ .subcommand(SubCommand::with_name("rm").about("delete podcast"))
+ .subcommand(SubCommand::with_name("completions").about("install shell completions"))
.get_matches();
match matches.subcommand_name() {
@@ -99,18 +101,16 @@ 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) => {
- if String::from(ep).contains(|c| c == '-' || c == ',') {
- download_range(&state, podcast, ep)
- } else {
- download_episode(&state, podcast, ep)
- }
- }
+ Some(ep) => if String::from(ep).contains(|c| c == '-' || c == ',') {
+ download_range(&state, podcast, ep)
+ } else {
+ download_episode(&state, podcast, ep)
+ },
None => download_all(&state, podcast),
}
}
- Some("list") => {
- let list_matches = matches.subcommand_matches("list").unwrap();
+ Some("ls") => {
+ let list_matches = matches.subcommand_matches("ls").unwrap();
match list_matches.value_of("PODCAST") {
Some(regex) => list_episodes(regex),
None => list_subscriptions(&state),
@@ -122,18 +122,19 @@ fn main() {
let episode = play_matches.value_of("EPISODE").unwrap();
play_episode(&state, podcast, episode);
}
- Some("subscribe") => {
- state.subscribe(
- matches
- .subcommand_matches("subscribe")
- .unwrap()
- .value_of("URL")
- .unwrap(),
- &config,
- )
- }
+ Some("subscribe") => state.subscribe(
+ matches
+ .subcommand_matches("subscribe")
+ .unwrap()
+ .value_of("URL")
+ .unwrap(),
+ &config,
+ ),
Some("search") => (),
- Some("update") => update_rss(&mut state),
+ Some("rm") => (),
+ Some("completions") => (),
+ Some("refresh") => update_rss(&mut state),
+ Some("update") => check_for_update(&mut state),
_ => (),
}
if let Err(err) = state.save() {
diff --git a/src/structs.rs b/src/structs.rs
index a7e82ee..b33da2e 100644
--- a/src/structs.rs
+++ b/src/structs.rs
@@ -177,12 +177,10 @@ impl Podcast {
path.push(filename);
match File::open(&path) {
- Ok(file) => {
- match Channel::read_from(BufReader::new(file)) {
- Ok(podcast) => return Ok(Podcast::from(podcast)),
- Err(err) => return Err(format!("Error: {}", err)),
- }
- }
+ Ok(file) => match Channel::read_from(BufReader::new(file)) {
+ Ok(podcast) => return Ok(Podcast::from(podcast)),
+ Err(err) => return Err(format!("Error: {}", err)),
+ },
Err(err) => return Err(format!("Error: {}", err)),
}
}
@@ -203,17 +201,15 @@ impl Podcast {
let downloaded = already_downloaded(self.title())?;
- self.episodes().par_iter().for_each(
- |ref i| if let Some(ep_title) =
- i.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) = i.download(self.title()) {
println!("{}", err);
}
}
- },
- );
+ }
+ });
Ok(())
}
@@ -224,17 +220,15 @@ impl Podcast {
let downloaded = already_downloaded(self.title())?;
let episodes = self.episodes();
- episode_numbers.par_iter().for_each(
- |ep_num| if let Some(ep_title) =
- episodes[episodes.len() - ep_num].title()
- {
+ episode_numbers.par_iter().for_each(|ep_num| {
+ if let Some(ep_title) = episodes[episodes.len() - ep_num].title() {
if !downloaded.contains(ep_title) {
if let Err(err) = episodes[episodes.len() - ep_num].download(self.title()) {
println!("{}", err);
}
}
- },
- );
+ }
+ });
Ok(())
}
}
@@ -253,14 +247,12 @@ impl Episode {
pub fn extension(&self) -> Option<&str> {
match self.0.enclosure() {
- Some(enclosure) => {
- match enclosure.mime_type() {
- "audio/mpeg" => Some(".mp3"),
- "audio/mp4" => Some(".m4a"),
- "audio/ogg" => Some(".ogg"),
- _ => find_extension(self.url().unwrap()),
- }
- }
+ Some(enclosure) => match enclosure.mime_type() {
+ "audio/mpeg" => Some(".mp3"),
+ "audio/mp4" => Some(".m4a"),
+ "audio/ogg" => Some(".ogg"),
+ _ => find_extension(self.url().unwrap()),
+ },
None => None,
}
}