aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Jaremko2018-11-19 10:36:42 -0500
committerNathan Jaremko2018-11-19 10:36:42 -0500
commit118b36cbf32024f16ab7db4f1ad0b1a29b7592f5 (patch)
treef4d4b40f20ec10ec3526bdf239a1995e6830ac36
parent714e8ded029907c1d8639121a3d171344808a5d5 (diff)
downloadpodcast-118b36cbf32024f16ab7db4f1ad0b1a29b7592f5.tar.bz2
Upgrade to rust 2018
-rw-r--r--CHANGELOG6
-rw-r--r--Cargo.toml14
-rw-r--r--src/actions.rs86
-rw-r--r--src/main.rs34
-rw-r--r--src/structs.rs38
-rw-r--r--src/utils.rs47
6 files changed, 132 insertions, 93 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 3fc8939..cc6daef 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,9 @@
+0.6.0
+- Update to rust 2018 edition
+
+0.5.11
+- Code cleanup
+
0.5.10
- Fix update check functionality
diff --git a/Cargo.toml b/Cargo.toml
index cb9cebe..8ccf3e3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,7 @@
[package]
name = "podcast"
-version = "0.5.10"
+edition = "2018"
+version = "0.6.0"
authors = ["Nathan Jaremko <njaremko@gmail.com>"]
description = "A command line podcast manager"
license = "GPL-3.0"
@@ -19,13 +20,14 @@ name = "podcast"
[dependencies]
chrono = { version = "0.4", features = ["serde"] }
-clap = "2.31"
-error-chain = "0.11"
-lazy_static = "1.0"
+clap = "2.32"
+dirs = "1.0"
+error-chain = "0.12"
+lazy_static = "1.2"
rayon = "1.0"
regex = "1.0"
-reqwest = "0.8"
-rss = {version = "1.5", features = ["from_url"] }
+reqwest = "0.9"
+rss = {version = "1.6", features = ["from_url"] }
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
diff --git a/src/actions.rs b/src/actions.rs
index 6a8951d..0775aec 100644
--- a/src/actions.rs
+++ b/src/actions.rs
@@ -1,12 +1,12 @@
-use structs::*;
-use utils::*;
+use super::structs::*;
+use super::utils::*;
use std::collections::HashSet;
use std::fs::{self, DirBuilder, File};
use std::io::{self, BufReader, Read, Write};
use std::process::Command;
-use errors::*;
+use crate::errors::*;
use rayon::prelude::*;
use regex::Regex;
use reqwest;
@@ -34,12 +34,14 @@ pub fn list_episodes(search: &str) -> Result<()> {
let podcast = Podcast::from(channel);
let episodes = podcast.episodes();
for (num, ep) in episodes.iter().enumerate() {
- write!(
+ writeln!(
&mut handle,
- "({}) {}\n",
+ "({}) {}",
episodes.len() - num,
- ep.title().chain_err(|| "unable to retrieve episode title")?
- ).chain_err(|| "unable to write to stdout")?
+ ep.title()
+ .chain_err(|| "unable to retrieve episode title")?
+ )
+ .chain_err(|| "unable to write to stdout")?
}
return Ok(());
}
@@ -79,18 +81,19 @@ pub fn update_subscription(sub: &mut Subscription) -> Result<()> {
let mut titles = HashSet::new();
for entry in fs::read_dir(&path).chain_err(|| UNABLE_TO_READ_DIRECTORY)? {
let unwrapped_entry = &entry.chain_err(|| UNABLE_TO_READ_ENTRY)?;
- titles.insert(trim_extension(&unwrapped_entry
- .file_name()
- .into_string()
- .unwrap()));
+ titles.insert(trim_extension(
+ &unwrapped_entry.file_name().into_string().unwrap(),
+ ));
}
let mut resp = reqwest::get(&sub.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)?;
- let podcast = Podcast::from(Channel::read_from(BufReader::new(&content[..]))
- .chain_err(|| UNABLE_TO_CREATE_CHANNEL_FROM_RESPONSE)?);
+ let podcast = Podcast::from(
+ Channel::read_from(BufReader::new(&content[..]))
+ .chain_err(|| UNABLE_TO_CREATE_CHANNEL_FROM_RESPONSE)?,
+ );
path = get_podcast_dir()?;
path.push(".rss");
@@ -126,7 +129,7 @@ pub fn list_subscriptions(state: &State) -> Result<()> {
let stdout = io::stdout();
let mut handle = stdout.lock();
for podcast in &state.subscriptions() {
- write!(&mut handle, "{}\n", &podcast.title).chain_err(|| "unable to write to stdout")?;
+ writeln!(&mut handle, "{}", &podcast.title).chain_err(|| "unable to write to stdout")?;
}
Ok(())
}
@@ -201,27 +204,35 @@ pub fn play_latest(state: &State, p_search: &str) -> Result<()> {
file.read_to_end(&mut content)
.chain_err(|| "unable to read file to end")?;
- let podcast: Podcast = Podcast::from(Channel::read_from(content.as_slice())
- .chain_err(|| UNABLE_TO_CREATE_CHANNEL_FROM_FILE)?);
+ let podcast: Podcast = Podcast::from(
+ Channel::read_from(content.as_slice())
+ .chain_err(|| UNABLE_TO_CREATE_CHANNEL_FROM_FILE)?,
+ );
let episodes = podcast.episodes();
let episode = episodes[0].clone();
- filename = String::from(episode
+ filename = episode
.title()
- .chain_err(|| "unable to retrieve episode name")?);
- filename.push_str(episode
- .extension()
- .chain_err(|| "unable to retrieve episode extension")?);
+ .chain_err(|| "unable to retrieve episode name")?;
+ filename.push_str(
+ episode
+ .extension()
+ .chain_err(|| "unable to retrieve episode extension")?,
+ );
path = get_podcast_dir()?;
path.push(podcast.title());
path.push(filename);
if path.exists() {
- launch_player(path.to_str()
- .chain_err(|| "unable to convert path to &str")?)?;
+ launch_player(
+ path.to_str()
+ .chain_err(|| "unable to convert path to &str")?,
+ )?;
} else {
- launch_player(episode
- .url()
- .chain_err(|| "unable to retrieve episode url")?)?;
+ launch_player(
+ episode
+ .url()
+ .chain_err(|| "unable to retrieve episode url")?,
+ )?;
}
return Ok(());
}
@@ -256,7 +267,7 @@ pub fn play_episode(state: &State, p_search: &str, ep_num_string: &str) -> Resul
let episodes = podcast.episodes();
let episode = episodes[episodes.len() - ep_num].clone();
- filename = String::from(episode.title().unwrap());
+ filename = episode.title().unwrap();
filename.push_str(episode.extension().unwrap());
path = get_podcast_dir()?;
path.push(podcast.title());
@@ -264,9 +275,11 @@ pub fn play_episode(state: &State, p_search: &str, ep_num_string: &str) -> Resul
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")?)?;
+ launch_player(
+ episode
+ .url()
+ .chain_err(|| "unable to retrieve episode url")?,
+ )?;
}
return Ok(());
}
@@ -276,14 +289,15 @@ pub fn play_episode(state: &State, p_search: &str, ep_num_string: &str) -> Resul
pub fn check_for_update(version: &str) -> Result<()> {
println!("Checking for updates...");
- let resp: String = reqwest::get(
- "https://raw.githubusercontent.com/njaremko/podcast/master/Cargo.toml",
- ).chain_err(|| UNABLE_TO_GET_HTTP_RESPONSE)?
- .text()
- .chain_err(|| "unable to convert response to text")?;
+ let resp: String =
+ reqwest::get("https://raw.githubusercontent.com/njaremko/podcast/master/Cargo.toml")
+ .chain_err(|| UNABLE_TO_GET_HTTP_RESPONSE)?
+ .text()
+ .chain_err(|| "unable to convert response to text")?;
//println!("{}", resp);
- let config = resp.parse::<toml::Value>()
+ let config = resp
+ .parse::<toml::Value>()
.chain_err(|| "unable to parse toml")?;
let latest = config["package"]["version"]
.as_str()
diff --git a/src/main.rs b/src/main.rs
index 2e07e08..c3ad6c3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,7 +1,9 @@
+#![feature(nll)]
#![recursion_limit = "1024"]
extern crate chrono;
extern crate clap;
+extern crate dirs;
#[macro_use]
extern crate error_chain;
#[macro_use]
@@ -16,22 +18,22 @@ extern crate serde_json;
extern crate toml;
extern crate yaml_rust;
-mod actions;
-mod structs;
-mod utils;
-mod errors {
+pub mod actions;
+pub mod structs;
+pub mod utils;
+pub mod errors {
// Create the Error, ErrorKind, ResultExt, and Result types
error_chain!{}
}
-use actions::*;
-use errors::*;
-use structs::*;
-use utils::*;
+use self::actions::*;
+use self::errors::*;
+use self::structs::*;
+use self::utils::*;
use clap::{App, Arg, SubCommand};
-const VERSION: &str = "0.5.10";
+const VERSION: &str = "0.6.0";
fn main() -> Result<()> {
create_directories().chain_err(|| "unable to create directories")?;
@@ -138,18 +140,20 @@ fn main() -> Result<()> {
.value_of("PODCAST")
.chain_err(|| "unable to find subcommand match")?;
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("ls") | Some("list") => {
let list_matches = matches
.subcommand_matches("ls")
- .or(matches.subcommand_matches("list"))
+ .or_else(|| matches.subcommand_matches("list"))
.chain_err(|| "unable to find subcommand matches")?;
match list_matches.value_of("PODCAST") {
Some(regex) => list_episodes(regex)?,
diff --git a/src/structs.rs b/src/structs.rs
index e585677..a0d9bd7 100644
--- a/src/structs.rs
+++ b/src/structs.rs
@@ -1,6 +1,6 @@
-use actions::*;
-use errors::*;
-use utils::*;
+use super::actions::*;
+use super::utils::*;
+use crate::errors::*;
use std::collections::BTreeSet;
use std::fs::{self, DirBuilder, File};
@@ -105,7 +105,8 @@ impl State {
// Check if a day has passed (86400 seconds) since last launch
if Utc::now()
.signed_duration_since(state.last_run_time)
- .num_seconds() > 86400
+ .num_seconds()
+ > 86400
{
update_rss(&mut state);
check_for_update(&state.version)?;
@@ -186,9 +187,9 @@ impl Podcast {
#[allow(dead_code)]
pub fn from_url(url: &str) -> Result<Podcast> {
- Ok(
- Podcast::from(Channel::from_url(url).chain_err(|| UNABLE_TO_CREATE_CHANNEL_FROM_RESPONSE)?),
- )
+ Ok(Podcast::from(
+ Channel::from_url(url).chain_err(|| UNABLE_TO_CREATE_CHANNEL_FROM_RESPONSE)?,
+ ))
}
pub fn from_title(title: &str) -> Result<Podcast> {
@@ -198,8 +199,10 @@ impl Podcast {
path.push(filename);
let file = File::open(&path).chain_err(|| UNABLE_TO_OPEN_FILE)?;
- Ok(Podcast::from(Channel::read_from(BufReader::new(file))
- .chain_err(|| UNABLE_TO_CREATE_CHANNEL_FROM_FILE)?))
+ Ok(Podcast::from(
+ Channel::read_from(BufReader::new(file))
+ .chain_err(|| UNABLE_TO_CREATE_CHANNEL_FROM_FILE)?,
+ ))
}
pub fn delete(title: &str) -> Result<()> {
@@ -284,7 +287,11 @@ impl Podcast {
impl Episode {
pub fn title(&self) -> Option<String> {
- Some(FILENAME_ESCAPE.replace_all(self.0.title()?, "_").to_string())
+ Some(
+ FILENAME_ESCAPE
+ .replace_all(self.0.title()?, "_")
+ .to_string(),
+ )
}
pub fn url(&self) -> Option<&str> {
@@ -313,9 +320,11 @@ impl Episode {
if let Some(url) = self.url() {
if let Some(title) = self.title() {
- let mut filename = String::from(title);
- filename.push_str(self.extension()
- .chain_err(|| "unable to retrieve extension")?);
+ let mut filename = title;
+ filename.push_str(
+ self.extension()
+ .chain_err(|| "unable to retrieve extension")?,
+ );
path.push(filename);
if !path.exists() {
println!("Downloading: {}", path.to_str().unwrap());
@@ -324,7 +333,8 @@ impl Episode {
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)?;
+ file.write_all(&content)
+ .chain_err(|| UNABLE_TO_WRITE_FILE)?;
} else {
println!(
"File already exists: {}",
diff --git a/src/utils.rs b/src/utils.rs
index 4648903..657ff5b 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -4,27 +4,27 @@ use std::fs::{self, DirBuilder, File};
use std::io::{BufReader, Read, Write};
use std::path::PathBuf;
-use errors::*;
+use crate::errors::*;
+use dirs;
use reqwest;
use rss::Channel;
-pub const UNABLE_TO_PARSE_REGEX: &'static str = "unable to parse regex";
-pub const UNABLE_TO_OPEN_FILE: &'static str = "unable to open file";
-pub const UNABLE_TO_CREATE_FILE: &'static str = "unable to create file";
-pub const UNABLE_TO_WRITE_FILE: &'static str = "unable to write file";
-pub const UNABLE_TO_READ_FILE_TO_STRING: &'static str = "unable to read file to string";
-pub const UNABLE_TO_READ_DIRECTORY: &'static str = "unable to read directory";
-pub const UNABLE_TO_READ_ENTRY: &'static str = "unable to read entry";
-pub const UNABLE_TO_CREATE_DIRECTORY: &'static str = "unable to create directory";
-pub const UNABLE_TO_READ_RESPONSE_TO_END: &'static str = "unable to read response to end";
-pub const UNABLE_TO_GET_HTTP_RESPONSE: &'static str = "unable to get http response";
-pub const UNABLE_TO_CONVERT_TO_STR: &'static str = "unable to convert to &str";
-pub const UNABLE_TO_REMOVE_FILE: &'static str = "unable to remove file";
-pub const UNABLE_TO_CREATE_CHANNEL_FROM_RESPONSE: &'static str =
+pub const UNABLE_TO_PARSE_REGEX: &str = "unable to parse regex";
+pub const UNABLE_TO_OPEN_FILE: &str = "unable to open file";
+pub const UNABLE_TO_CREATE_FILE: &str = "unable to create file";
+pub const UNABLE_TO_WRITE_FILE: &str = "unable to write file";
+pub const UNABLE_TO_READ_FILE_TO_STRING: &str = "unable to read file to string";
+pub const UNABLE_TO_READ_DIRECTORY: &str = "unable to read directory";
+pub const UNABLE_TO_READ_ENTRY: &str = "unable to read entry";
+pub const UNABLE_TO_CREATE_DIRECTORY: &str = "unable to create directory";
+pub const UNABLE_TO_READ_RESPONSE_TO_END: &str = "unable to read response to end";
+pub const UNABLE_TO_GET_HTTP_RESPONSE: &str = "unable to get http response";
+pub const UNABLE_TO_CONVERT_TO_STR: &str = "unable to convert to &str";
+pub const UNABLE_TO_REMOVE_FILE: &str = "unable to remove file";
+pub const UNABLE_TO_CREATE_CHANNEL_FROM_RESPONSE: &str =
"unable to create channel from http response";
-pub const UNABLE_TO_CREATE_CHANNEL_FROM_FILE: &'static str =
- "unable to create channel from xml file";
-pub const UNABLE_TO_RETRIEVE_PODCAST_BY_TITLE: &'static str = "unable to retrieve podcast by title";
+pub const UNABLE_TO_CREATE_CHANNEL_FROM_FILE: &str = "unable to create channel from xml file";
+pub const UNABLE_TO_RETRIEVE_PODCAST_BY_TITLE: &str = "unable to retrieve podcast by title";
pub fn trim_extension(filename: &str) -> Option<String> {
let name = String::from(filename);
let index = name.rfind('.')?;
@@ -52,7 +52,7 @@ pub fn get_podcast_dir() -> Result<PathBuf> {
match env::var_os("PODCAST") {
Some(val) => Ok(PathBuf::from(val)),
None => {
- let mut path = env::home_dir().chain_err(|| "Couldn't find your home directory")?;
+ let mut path = dirs::home_dir().chain_err(|| "Couldn't find your home directory")?;
path.push("Podcasts");
Ok(path)
}
@@ -135,20 +135,23 @@ pub fn parse_download_episodes(e_search: &str) -> Result<Vec<usize>> {
for elem in comma_separated {
let temp = String::from(elem);
if temp.contains('-') {
- let range: Vec<usize> = elem.split('-')
+ let range: Vec<usize> = elem
+ .split('-')
.map(|i| i.parse::<usize>().chain_err(|| "unable to parse number"))
.collect::<Result<Vec<usize>>>()
.chain_err(|| "unable to collect ranges")?;
ranges.push((range[0], range[1]));
} else {
- elements.push(elem.parse::<usize>()
- .chain_err(|| "unable to parse number")?);
+ elements.push(
+ elem.parse::<usize>()
+ .chain_err(|| "unable to parse number")?,
+ );
}
}
for range in ranges {
// Add 1 to upper range to include given episode in the download
- for num in range.0..range.1 + 1 {
+ for num in range.0..=range.1 {
elements.push(num);
}
}