1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
use crate::download;
use crate::errors::*;
use crate::structs::*;
use crate::utils;
use std::collections::HashSet;
use std::fs::{self, File};
use std::io::{self, BufReader, BufWriter, Write};
use clap::App;
use clap::Shell;
use rayon::prelude::*;
use regex::Regex;
use reqwest;
use rss::Channel;
use std::path::PathBuf;
use toml;
pub fn list_episodes(search: &str) -> Result<()> {
let re = Regex::new(&format!("(?i){}", &search))?;
let path = utils::get_xml_dir()?;
utils::create_dir_if_not_exist(&path)?;
for entry in fs::read_dir(&path)? {
let entry = entry?;
if re.is_match(&entry.file_name().into_string().unwrap()) {
let file = File::open(&entry.path())?;
let channel = Channel::read_from(BufReader::new(file))?;
let podcast = Podcast::from(channel);
let episodes = podcast.episodes();
let stdout = io::stdout();
let mut handle = stdout.lock();
episodes
.iter()
.filter(|ep| ep.title().is_some())
.enumerate()
.for_each(|(num, ep)| {
writeln!(
&mut handle,
"({}) {}",
episodes.len() - num,
ep.title().unwrap()
)
.ok();
});
return Ok(());
}
}
Ok(())
}
pub fn update_subscription(sub: &mut Subscription) -> Result<()> {
println!("Updating {}", sub.title);
let mut path: PathBuf = utils::get_podcast_dir()?;
path.push(&sub.title);
utils::create_dir_if_not_exist(&path)?;
let mut titles = HashSet::new();
for entry in fs::read_dir(&path)? {
let unwrapped_entry = &entry?;
titles.insert(utils::trim_extension(
&unwrapped_entry.file_name().into_string().unwrap(),
));
}
let resp = reqwest::get(&sub.url)?;
let podcast = Podcast::from(Channel::read_from(BufReader::new(resp))?);
let mut podcast_rss_path = utils::get_xml_dir()?;
let title = utils::append_extension(podcast.title(), "xml");
podcast_rss_path.push(title);
let file = File::create(&podcast_rss_path)?;
(*podcast).write_to(BufWriter::new(file))?;
if sub.num_episodes < podcast.episodes().len() {
podcast.episodes()[..podcast.episodes().len() - sub.num_episodes]
.par_iter()
.map(|ep| download::download(podcast.title(), ep))
.flat_map(std::result::Result::err)
.for_each(|err| eprintln!("Error: {}", err));
}
sub.num_episodes = podcast.episodes().len();
Ok(())
}
pub fn update_rss(state: &mut State) {
println!("Checking for new episodes...");
let _result: Vec<Result<()>> = state
.subscriptions_mut()
.par_iter_mut()
.map(|sub: &mut Subscription| update_subscription(sub))
.collect();
println!("Done.");
}
pub fn list_subscriptions(state: &State) -> Result<()> {
let stdout = io::stdout();
let mut handle = stdout.lock();
for subscription in state.subscriptions() {
writeln!(&mut handle, "{}", subscription.title())?;
}
Ok(())
}
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")?
.text()?;
let config = resp.parse::<toml::Value>()?;
let latest = config["package"]["version"]
.as_str()
.unwrap_or_else(|| panic!("Cargo.toml didn't have a version {:?}", config));
if version != latest {
println!("New version available: {} -> {}", version, latest);
}
Ok(())
}
pub fn remove_podcast(state: &mut State, p_search: &str) -> Result<()> {
if p_search == "*" {
state.subscriptions = vec![];
return utils::delete_all();
}
let re_pod = Regex::new(&format!("(?i){}", &p_search))?;
for subscription in 0..state.subscriptions.len() {
let title = state.subscriptions[subscription].title.clone();
if re_pod.is_match(&title) {
state.subscriptions.remove(subscription);
utils::delete(&title)?;
}
}
Ok(())
}
pub fn print_completion(app: &mut App, arg: &str) {
let command_name = "podcast";
match arg {
"zsh" => {
app.gen_completions_to(command_name, Shell::Zsh, &mut io::stdout());
}
"bash" => {
app.gen_completions_to(command_name, Shell::Bash, &mut io::stdout());
}
"powershell" => {
app.gen_completions_to(command_name, Shell::PowerShell, &mut io::stdout());
}
"fish" => {
app.gen_completions_to(command_name, Shell::Fish, &mut io::stdout());
}
"elvish" => {
app.gen_completions_to(command_name, Shell::Elvish, &mut io::stdout());
}
other => {
println!("Completions are not available for {}", other);
}
}
}
|