aboutsummaryrefslogtreecommitdiffstats
path: root/src/playback.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/playback.rs')
-rw-r--r--src/playback.rs183
1 files changed, 183 insertions, 0 deletions
diff --git a/src/playback.rs b/src/playback.rs
new file mode 100644
index 0000000..05196dd
--- /dev/null
+++ b/src/playback.rs
@@ -0,0 +1,183 @@
+use crate::errors::*;
+use crate::structs::*;
+use crate::utils::*;
+
+use std::fs::{DirBuilder, File};
+use std::io::{self, BufReader, Read, Write};
+use std::process::Command;
+
+use regex::Regex;
+use rss::Channel;
+use std::path::PathBuf;
+
+fn launch_player(url: &str) -> Result<()> {
+ if launch_mpv(url).is_err() {
+ return launch_vlc(url);
+ }
+ Ok(())
+}
+
+fn launch_mpv(url: &str) -> Result<()> {
+ if let Err(err) = Command::new("mpv")
+ .args(&["--audio-display=no", "--ytdl=no", url])
+ .status()
+ {
+ let stderr = io::stderr();
+ let mut handle = stderr.lock();
+ match err.kind() {
+ io::ErrorKind::NotFound => {
+ writeln!(&mut handle, "Couldn't open mpv\nTrying vlc...").ok()
+ }
+ _ => writeln!(&mut handle, "Error: {}", err).ok(),
+ };
+ }
+ Ok(())
+}
+
+fn launch_vlc(url: &str) -> Result<()> {
+ if let Err(err) = Command::new("vlc").args(&["-I ncurses", url]).status() {
+ let stderr = io::stderr();
+ let mut handle = stderr.lock();
+ match err.kind() {
+ io::ErrorKind::NotFound => writeln!(&mut handle, "Couldn't open vlc...aborting").ok(),
+ _ => writeln!(&mut handle, "Error: {}", err).ok(),
+ };
+ }
+ Ok(())
+}
+
+pub fn play_latest(state: &State, p_search: &str) -> Result<()> {
+ let re_pod: Regex = Regex::new(&format!("(?i){}", &p_search))?;
+ let mut path: PathBuf = get_xml_dir()?;
+ DirBuilder::new().recursive(true).create(&path)?;
+ for subscription in &state.subscriptions {
+ if re_pod.is_match(&subscription.title) {
+ let mut filename: String = subscription.title.clone();
+ filename.push_str(".xml");
+ path.push(filename);
+
+ let file: File = File::open(&path)?;
+ let podcast: Podcast = Podcast::from(Channel::read_from(BufReader::new(file))?);
+ let episodes = podcast.episodes();
+ let episode = episodes[0].clone();
+
+ filename = episode.title().unwrap();
+ filename.push_str(&episode.extension().unwrap());
+ path = get_podcast_dir()?;
+ path.push(podcast.title());
+ path.push(filename);
+ if path.exists() {
+ launch_player(path.to_str().unwrap())?;
+ } else {
+ launch_player(episode.url().unwrap())?;
+ }
+ return Ok(());
+ }
+ }
+ Ok(())
+}
+
+pub fn play_episode_by_num(state: &State, p_search: &str, ep_num_string: &str) -> Result<()> {
+ let re_pod: Regex = Regex::new(&format!("(?i){}", &p_search))?;
+ if let Ok(ep_num) = ep_num_string.parse::<usize>() {
+ let mut path: PathBuf = get_xml_dir()?;
+ let stderr = io::stderr();
+ let mut handle = stderr.lock();
+ if let Err(err) = DirBuilder::new().recursive(true).create(&path) {
+ writeln!(
+ &mut handle,
+ "Couldn't create directory: {}\nReason: {}",
+ path.to_str().unwrap(),
+ err
+ )
+ .ok();
+ return Ok(());
+ }
+ for subscription in &state.subscriptions {
+ if re_pod.is_match(&subscription.title) {
+ let mut filename: String = subscription.title.clone();
+ filename.push_str(".xml");
+ path.push(filename);
+
+ let file: File = File::open(&path).unwrap();
+ let podcast = Podcast::from(Channel::read_from(BufReader::new(file)).unwrap());
+ let episodes = podcast.episodes();
+ let episode = episodes[episodes.len() - ep_num].clone();
+
+ filename = episode.title().unwrap();
+ filename.push_str(&episode.extension().unwrap());
+ path = get_podcast_dir()?;
+ path.push(podcast.title());
+ path.push(filename);
+ if path.exists() {
+ launch_player(path.to_str().unwrap())?;
+ } else {
+ launch_player(episode.url().unwrap())?;
+ }
+ return Ok(());
+ }
+ }
+ } else {
+ {
+ let stdout = io::stdout();
+ let mut handle = stdout.lock();
+ writeln!(&mut handle, "Failed to parse episode index number...").ok();
+ writeln!(&mut handle, "Attempting to find episode by name...").ok();
+ }
+ play_episode_by_name(state, p_search, ep_num_string)?;
+ }
+ Ok(())
+}
+
+pub fn play_episode_by_name(state: &State, p_search: &str, ep_string: &str) -> Result<()> {
+ let re_pod: Regex = Regex::new(&format!("(?i){}", &p_search))?;
+ let mut path: PathBuf = get_xml_dir()?;
+ if let Err(err) = DirBuilder::new().recursive(true).create(&path) {
+ let stderr = io::stderr();
+ let mut handle = stderr.lock();
+ writeln!(
+ &mut handle,
+ "Couldn't create directory: {:?}\nReason: {}",
+ path, err
+ )
+ .ok();
+ return Ok(());
+ }
+ for subscription in &state.subscriptions {
+ if re_pod.is_match(&subscription.title) {
+ let mut filename: String = subscription.title.clone();
+ filename.push_str(".xml");
+ path.push(filename);
+
+ let mut file: File = File::open(&path).unwrap();
+ let mut content: Vec<u8> = Vec::new();
+ file.read_to_end(&mut content).unwrap();
+
+ let podcast = Podcast::from(Channel::read_from(content.as_slice()).unwrap());
+ let episodes = podcast.episodes();
+ let filtered_episodes: Vec<&Episode> = episodes
+ .iter()
+ .filter(|ep| {
+ ep.title()
+ .unwrap_or_else(|| "".to_string())
+ .to_lowercase()
+ .contains(&ep_string.to_lowercase())
+ })
+ .collect();
+ if let Some(episode) = filtered_episodes.first() {
+ filename = episode.title().unwrap();
+ filename.push_str(&episode.extension().unwrap());
+ path = get_podcast_dir()?;
+ path.push(podcast.title());
+ path.push(filename);
+ if path.exists() {
+ launch_player(path.to_str().unwrap())?;
+ } else {
+ launch_player(episode.url().unwrap())?;
+ }
+ }
+ return Ok(());
+ }
+ }
+ Ok(())
+}