From: Stephen Seo Date: Mon, 20 Dec 2021 08:41:03 +0000 (+0900) Subject: Fix re-showing prompt on password fail, impl logs X-Git-Tag: 0.2.6 X-Git-Url: https://git.seodisparate.com/stephenseo/LD54_Box_Survival?a=commitdiff_plain;h=f98fc1e24f2084794b9d9a15c4b790677ed59e91;p=mpd_info_screen Fix re-showing prompt on password fail, impl logs Also bump version to 0.2.6 --- diff --git a/Cargo.lock b/Cargo.lock index ea77f73..bc12bfc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1427,7 +1427,7 @@ dependencies = [ [[package]] name = "mpd_info_screen" -version = "0.2.5" +version = "0.2.6" dependencies = [ "ggez", "image", diff --git a/Cargo.toml b/Cargo.toml index 5b10826..6835af6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mpd_info_screen" -version = "0.2.5" +version = "0.2.6" edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/README.md b/README.md index 9d2a0c1..77c4218 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ counter, and the filename currently being played # Usage - mpd_info_screen 0.2.5 + mpd_info_screen 0.2.6 USAGE: mpd_info_screen [FLAGS] [OPTIONS] [port] diff --git a/src/debug_log.rs b/src/debug_log.rs index cfb04ab..90b7200 100644 --- a/src/debug_log.rs +++ b/src/debug_log.rs @@ -1,17 +1,63 @@ use std::fmt::Display; +use structopt::clap::arg_enum; -#[cfg(debug_assertions)] -pub fn log(msg: T) -> () +arg_enum! { + #[derive(Copy, Clone, Debug, PartialEq)] + pub enum LogState { + ERROR, + WARNING, + DEBUG, + VERBOSE, + } +} + +pub fn log(msg: T, level: LogState, state: LogState) +where + T: Display, +{ + if level == LogState::ERROR { + log_error(msg); + } else if level == LogState::WARNING { + if state != LogState::ERROR { + log_warning(msg); + } + } else if level == LogState::DEBUG { + if state == LogState::DEBUG || state == LogState::VERBOSE { + log_debug(msg); + } + } else if level == LogState::VERBOSE { + if state == LogState::VERBOSE { + log_verbose(msg); + } + } else { + unreachable!(); + } +} + +pub fn log_error(msg: T) +where + T: Display, +{ + println!("ERROR: {}", msg); +} + +pub fn log_warning(msg: T) +where + T: Display, +{ + println!("WARNING: {}", msg); +} + +pub fn log_debug(msg: T) where T: Display, { - println!("{}", msg); + println!("DEBUG: {}", msg); } -#[cfg(not(debug_assertions))] -pub fn log(msg: T) -> () +pub fn log_verbose(msg: T) where T: Display, { - // intentionally left blank, no logging in non-debug mode + println!("VERBOSE: {}", msg); } diff --git a/src/display.rs b/src/display.rs index d59d01f..dbfce80 100644 --- a/src/display.rs +++ b/src/display.rs @@ -1,4 +1,4 @@ -use crate::debug_log::log; +use crate::debug_log::{self, log}; use crate::mpd_handler::{InfoFromShared, MPDHandler}; use crate::Opt; use ggez::event::{self, EventHandler}; @@ -51,6 +51,7 @@ pub struct MPDDisplay { mpd_handler: Option>>, is_valid: bool, is_initialized: bool, + is_authenticated: bool, notice_text: Text, poll_instant: Instant, shared: Option, @@ -81,6 +82,7 @@ impl MPDDisplay { mpd_handler: None, is_valid: true, is_initialized: false, + is_authenticated: false, notice_text: Text::new(""), poll_instant: Instant::now() - POLL_TIME, shared: None, @@ -110,6 +112,7 @@ impl MPDDisplay { self.opts.host, self.opts.port, self.opts.password.clone().map_or(String::new(), |s| s), + self.opts.log_level, ) .map_or_else(|_| None, |v| Some(v)); if self.mpd_handler.is_some() { @@ -124,10 +127,18 @@ impl MPDDisplay { thread::sleep(POLL_TIME); } } - log("Successfully initialized MPDHandler"); + log( + "Successfully initialized MPDHandler", + debug_log::LogState::DEBUG, + self.opts.log_level, + ); } else { self.is_valid = false; - log("Failed to initialize MPDHandler"); + log( + "Failed to initialize MPDHandler", + debug_log::LogState::DEBUG, + self.opts.log_level, + ); } } @@ -319,7 +330,11 @@ impl MPDDisplay { &mut self.timer_y, ); } else { - log("filename text is empty"); + log( + "filename text is empty", + debug_log::LogState::WARNING, + self.opts.log_level, + ); } if !self.artist_text.contents().is_empty() && !self.opts.disable_show_artist { @@ -334,7 +349,11 @@ impl MPDDisplay { &mut self.timer_y, ); } else { - log("artist text is empty"); + log( + "artist text is empty", + debug_log::LogState::WARNING, + self.opts.log_level, + ); } if !self.title_text.contents().is_empty() && !self.opts.disable_show_title { @@ -349,7 +368,11 @@ impl MPDDisplay { &mut self.timer_y, ); } else { - log("title text is empty"); + log( + "title text is empty", + debug_log::LogState::WARNING, + self.opts.log_level, + ); } set_transform( @@ -442,6 +465,42 @@ impl EventHandler for MPDDisplay { } else { self.init_mpd_handler(); } + } else if self.password_entered { + 'check_state: loop { + let result = MPDHandler::is_authenticated(self.mpd_handler.clone().unwrap()); + if let Ok(true) = result { + self.is_authenticated = true; + break; + } else if let Err(()) = result { + continue; + } else { + loop { + let check_fail_result = + MPDHandler::failed_to_authenticate(self.mpd_handler.clone().unwrap()); + if let Ok(true) = check_fail_result { + { + let mpd_handler = self.mpd_handler.clone().unwrap(); + loop { + let write_handle_result = mpd_handler.try_write(); + if let Ok(write_handle) = write_handle_result { + write_handle.stop_flag.store(true, Ordering::Relaxed); + break; + } + } + } + self.notice_text = Text::new(TextFragment::new("password: ")); + self.opts.password = Some(String::new()); + self.password_entered = false; + self.is_initialized = false; + break 'check_state; + } else if let Err(()) = check_fail_result { + continue; + } else { + break 'check_state; + } + } + } + } } if self.is_valid && self.is_initialized && self.poll_instant.elapsed() > POLL_TIME { @@ -453,7 +512,11 @@ impl EventHandler for MPDDisplay { .unwrap() .swap(false, Ordering::Relaxed) { - log("dirty_flag cleared, acquiring shared data..."); + log( + "dirty_flag cleared, acquiring shared data...", + debug_log::LogState::DEBUG, + self.opts.log_level, + ); self.shared = MPDHandler::get_current_song_info(self.mpd_handler.clone().unwrap()) .map_or(None, |f| Some(f)); if let Some(shared) = &self.shared { @@ -491,12 +554,16 @@ impl EventHandler for MPDDisplay { self.length = shared.length; self.refresh_text_transforms(ctx)?; } else { - log("Failed to acquire read lock for getting shared data"); + log( + "Failed to acquire read lock for getting shared data", + debug_log::LogState::DEBUG, + self.opts.log_level, + ); } if self.album_art.is_none() { let result = self.get_image_from_data(ctx); if let Err(e) = result { - log(e); + log(e, debug_log::LogState::DEBUG, self.opts.log_level); self.album_art = None; self.album_art_draw_transform = None; } else { @@ -525,7 +592,6 @@ impl EventHandler for MPDDisplay { graphics::clear(ctx, Color::BLACK); if self.album_art.is_some() && self.album_art_draw_transform.is_some() { - log("Drawing album_art"); self.album_art.as_ref().unwrap().draw( ctx, DrawParam { @@ -619,7 +685,6 @@ impl EventHandler for MPDDisplay { } } else if keycode == event::KeyCode::Return { self.password_entered = true; - //log(format!("Entered \"{}\"", self.opts.password.as_ref().unwrap_or(&String::new()))); } } else { if keycode == event::KeyCode::H { diff --git a/src/main.rs b/src/main.rs index 6c8239e..dac8219 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,7 @@ use structopt::StructOpt; use debug_log::log; -#[derive(StructOpt, Debug)] +#[derive(StructOpt, Debug, Clone)] #[structopt(name = "mpd_info_screen")] pub struct Opt { host: Ipv4Addr, @@ -35,6 +35,14 @@ pub struct Opt { help = "don't scale-fill the album art to the window" )] do_not_fill_scale_album_art: bool, + #[structopt( + short = "l", + long = "log-level", + possible_values = &debug_log::LogState::variants(), + default_value = "ERROR", + case_insensitive = true, + )] + log_level: debug_log::LogState, } fn main() -> Result<(), String> { @@ -53,7 +61,7 @@ fn main() -> Result<(), String> { .build() .expect("Failed to create ggez context"); - let mut display = display::MPDDisplay::new(&mut ctx, opt); + let mut display = display::MPDDisplay::new(&mut ctx, opt.clone()); let mut modifiers_state: ModifiersState = ModifiersState::default(); @@ -113,7 +121,11 @@ fn main() -> Result<(), String> { event::winit_event::WindowEvent::ReceivedCharacter(ch) => { display.text_input_event(ctx, ch); } - x => log(format!("Other window event fired: {:?}", x)), + x => log( + format!("Other window event fired: {:?}", x), + debug_log::LogState::VERBOSE, + opt.log_level, + ), }, event::winit_event::Event::MainEventsCleared => { ctx.timer_context.tick(); @@ -137,7 +149,11 @@ fn main() -> Result<(), String> { thread::sleep(Duration::from_millis(90)); ggez::timer::yield_now(); } - x => log(format!("Device event fired: {:?}", x)), + x => log( + format!("Device event fired: {:?}", x), + debug_log::LogState::VERBOSE, + opt.log_level, + ), } }); } diff --git a/src/mpd_handler.rs b/src/mpd_handler.rs index 2b72412..4a12931 100644 --- a/src/mpd_handler.rs +++ b/src/mpd_handler.rs @@ -1,4 +1,4 @@ -use crate::debug_log::log; +use crate::debug_log::{log, LogState}; use std::io::{self, Read, Write}; use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpStream}; use std::str::FromStr; @@ -60,6 +60,7 @@ pub struct MPDHandler { self_thread: Option>>>>, dirty_flag: Arc, pub stop_flag: Arc, + log_level: LogState, } fn check_next_chars( @@ -218,7 +219,12 @@ fn read_line( } impl MPDHandler { - pub fn new(host: Ipv4Addr, port: u16, password: String) -> Result>, String> { + pub fn new( + host: Ipv4Addr, + port: u16, + password: String, + log_level: LogState, + ) -> Result>, String> { let stream = TcpStream::connect_timeout( &SocketAddr::new(IpAddr::V4(host), port), Duration::from_secs(5), @@ -254,6 +260,7 @@ impl MPDHandler { self_thread: None, dirty_flag: Arc::new(AtomicBool::new(true)), stop_flag: Arc::new(AtomicBool::new(false)), + log_level, })); let s_clone = s.clone(); @@ -326,7 +333,18 @@ impl MPDHandler { &self.art_data } + pub fn is_authenticated(h: Arc>) -> Result { + let read_handle = h.try_read().map_err(|_| ())?; + Ok(read_handle.is_authenticated) + } + + pub fn failed_to_authenticate(h: Arc>) -> Result { + let read_handle = h.try_read().map_err(|_| ())?; + Ok(!read_handle.can_authenticate) + } + fn handler_loop(h: Arc>) -> Result<(), String> { + let log_level = h.read().expect("Failed to get log_level").log_level; let mut buf: [u8; BUF_SIZE] = [0; BUF_SIZE]; let mut saved: Vec = Vec::new(); let mut saved_str: String = String::new(); @@ -349,7 +367,11 @@ impl MPDHandler { if let Ok(write_handle) = h.try_write() { if write_handle.self_thread.is_none() { // main thread failed to store handle to this thread - println!("MPDHandle thread stopping due to failed handle storage"); + log( + "MPDHandle thread stopping due to failed handle storage", + LogState::ERROR, + write_handle.log_level, + ); break 'main; } } @@ -358,9 +380,17 @@ impl MPDHandler { if let Err(err_string) = Self::handler_read_block(h.clone(), &mut buf, &mut saved, &mut saved_str) { - println!("WARNING: read_block error: {}", err_string); + log( + format!("read_block error: {}", err_string), + LogState::WARNING, + log_level, + ); } else if let Err(err_string) = Self::handler_write_block(h.clone()) { - println!("WARNING: write_block error: {}", err_string); + log( + format!("write_block error: {}", err_string), + LogState::WARNING, + log_level, + ); } if let Ok(read_handle) = h.try_read() { @@ -372,7 +402,11 @@ impl MPDHandler { io::stdout().flush().unwrap(); } - log("MPDHandler thread entering exit loop"); + log( + "MPDHandler thread entering exit loop", + LogState::DEBUG, + log_level, + ); 'exit: loop { if let Ok(mut write_handle) = h.try_write() { write_handle.self_thread = None; @@ -417,22 +451,30 @@ impl MPDHandler { buf_vec = buf_vec.split_off(count + 1); write_handle.current_binary_size = 0; write_handle.poll_state = PollState::None; - log(format!( - "Album art recv progress: {}/{}", - write_handle.art_data.len(), - write_handle.art_data_size - )); + log( + format!( + "Album art recv progress: {}/{}", + write_handle.art_data.len(), + write_handle.art_data_size + ), + LogState::DEBUG, + write_handle.log_level, + ); if write_handle.art_data.len() == write_handle.art_data_size { write_handle.dirty_flag.store(true, Ordering::Relaxed); } } else { write_handle.art_data.extend_from_slice(&buf_vec); write_handle.current_binary_size -= buf_vec.len(); - log(format!( - "Album art recv progress: {}/{}", - write_handle.art_data.len(), - write_handle.art_data_size - )); + log( + format!( + "Album art recv progress: {}/{}", + write_handle.art_data.len(), + write_handle.art_data_size + ), + LogState::DEBUG, + write_handle.log_level, + ); if write_handle.art_data.len() == write_handle.art_data_size { write_handle.dirty_flag.store(true, Ordering::Relaxed); } @@ -446,7 +488,11 @@ impl MPDHandler { if write_handle.is_init { if line.starts_with("OK MPD ") { write_handle.is_init = false; - println!("Got initial \"OK\" from MPD"); + log( + "Got initial \"OK\" from MPD", + LogState::DEBUG, + write_handle.log_level, + ); write_handle.poll_state = PollState::None; break 'handle_buf; } else { @@ -455,24 +501,33 @@ impl MPDHandler { } // write_handle.is_init if line.starts_with("OK") { - log(format!( - "Got OK when poll state is {:?}", - write_handle.poll_state - )); + log( + format!("Got OK when poll state is {:?}", write_handle.poll_state), + LogState::DEBUG, + write_handle.log_level, + ); match write_handle.poll_state { PollState::Password => write_handle.is_authenticated = true, PollState::ReadPicture => { if write_handle.art_data.is_empty() { write_handle.can_get_album_art = false; write_handle.dirty_flag.store(true, Ordering::Relaxed); - println!("No embedded album art"); + log( + "No embedded album art", + LogState::WARNING, + write_handle.log_level, + ); } } PollState::ReadPictureInDir => { if write_handle.art_data.is_empty() { write_handle.can_get_album_art_in_dir = false; write_handle.dirty_flag.store(true, Ordering::Relaxed); - println!("No album art in dir"); + log( + "No album art in dir", + LogState::WARNING, + write_handle.log_level, + ); } } _ => (), @@ -480,7 +535,7 @@ impl MPDHandler { write_handle.poll_state = PollState::None; break 'handle_buf; } else if line.starts_with("ACK") { - println!("ERROR: {}", line); + log(line, LogState::WARNING, write_handle.log_level); match write_handle.poll_state { PollState::Password => { write_handle.can_authenticate = false; @@ -496,14 +551,22 @@ impl MPDHandler { PollState::ReadPicture => { write_handle.can_get_album_art = false; write_handle.dirty_flag.store(true, Ordering::Relaxed); - println!("Failed to get readpicture"); + log( + "Failed to get readpicture", + LogState::WARNING, + write_handle.log_level, + ); // Not setting error_text here since // ReadPictureInDir is tried next } PollState::ReadPictureInDir => { write_handle.can_get_album_art_in_dir = false; write_handle.dirty_flag.store(true, Ordering::Relaxed); - println!("Failed to get albumart"); + log( + "Failed to get albumart", + LogState::WARNING, + write_handle.log_level, + ); write_handle.error_text = "Failed to get album art from MPD".into(); } _ => (), @@ -535,7 +598,11 @@ impl MPDHandler { write_handle.dirty_flag.store(true, Ordering::Relaxed); write_handle.song_pos_get_time = Instant::now(); } else { - println!("WARNING: Failed to parse current song position"); + log( + "Failed to parse current song position", + LogState::WARNING, + write_handle.log_level, + ); } } else if line.starts_with("duration: ") { let parse_pos_result = f64::from_str(&line.split_off(10)); @@ -544,7 +611,11 @@ impl MPDHandler { write_handle.dirty_flag.store(true, Ordering::Relaxed); write_handle.song_length_get_time = Instant::now(); } else { - println!("WARNING: Failed to parse current song duration"); + log( + "Failed to parse current song duration", + LogState::WARNING, + write_handle.log_level, + ); } } else if line.starts_with("size: ") { let parse_artsize_result = usize::from_str(&line.split_off(6)); @@ -552,14 +623,22 @@ impl MPDHandler { write_handle.art_data_size = value; write_handle.dirty_flag.store(true, Ordering::Relaxed); } else { - println!("WARNING: Failed to parse album art byte size"); + log( + "Failed to parse album art byte size", + LogState::WARNING, + write_handle.log_level, + ); } } else if line.starts_with("binary: ") { let parse_artbinarysize_result = usize::from_str(&line.split_off(8)); if let Ok(value) = parse_artbinarysize_result { write_handle.current_binary_size = value; } else { - println!("WARNING: Failed to parse album art chunk byte size"); + log( + "Failed to parse album art chunk byte size", + LogState::WARNING, + write_handle.log_level, + ); } } else if line.starts_with("Title: ") { write_handle.current_song_title = line.split_off(7); @@ -568,15 +647,23 @@ impl MPDHandler { } else if line.starts_with("type: ") { write_handle.art_data_type = line.split_off(6); } else { - log(format!("WARNING: Got unrecognized/ignored line: {}", line)); + log( + format!("Got unrecognized/ignored line: {}", line), + LogState::WARNING, + write_handle.log_level, + ); } } else if let Err((msg, read_line_in_progress)) = read_line_result { - log(format!( - "WARNING read_line: {}, saved size == {}, in_progress size == {}", - msg, - saved.len(), - read_line_in_progress.len() - )); + log( + format!( + "read_line: {}, saved size == {}, in_progress size == {}", + msg, + saved.len(), + read_line_in_progress.len() + ), + LogState::WARNING, + write_handle.log_level, + ); *saved_str = read_line_in_progress; break 'handle_buf; } else { @@ -613,7 +700,11 @@ impl MPDHandler { if write_result.is_ok() { write_handle.poll_state = PollState::Password; } else if let Err(e) = write_result { - println!("ERROR: Failed to send password for authentication: {}", e); + log( + format!("Failed to send password for authentication: {}", e), + LogState::ERROR, + write_handle.log_level, + ); } } else if write_handle.can_get_status && (write_handle.song_title_get_time.elapsed() > POLL_DURATION @@ -624,7 +715,11 @@ impl MPDHandler { if write_result.is_ok() { write_handle.poll_state = PollState::CurrentSong; } else if let Err(e) = write_result { - println!("ERROR: Failed to request song info over stream: {}", e); + log( + format!("Failed to request song info over stream: {}", e), + LogState::ERROR, + write_handle.log_level, + ); } } else if write_handle.can_get_status && (write_handle.song_length_get_time.elapsed() > POLL_DURATION @@ -636,7 +731,11 @@ impl MPDHandler { if write_result.is_ok() { write_handle.poll_state = PollState::Status; } else if let Err(e) = write_result { - println!("ERROR: Failed to request status over stream: {}", e); + log( + format!("Failed to request status over stream: {}", e), + LogState::ERROR, + write_handle.log_level, + ); } } else if (write_handle.art_data.is_empty() || write_handle.art_data.len() != write_handle.art_data_size) @@ -651,7 +750,11 @@ impl MPDHandler { if write_result.is_ok() { write_handle.poll_state = PollState::ReadPicture; } else if let Err(e) = write_result { - println!("ERROR: Failed to request album art: {}", e); + log( + format!("Failed to request album art: {}", e), + LogState::ERROR, + write_handle.log_level, + ); } } else if write_handle.can_get_album_art_in_dir { let write_result = write_handle @@ -660,7 +763,11 @@ impl MPDHandler { if write_result.is_ok() { write_handle.poll_state = PollState::ReadPictureInDir; } else if let Err(e) = write_result { - println!("ERROR: Failed to request album art in dir: {}", e); + log( + format!("Failed to request album art in dir: {}", e), + LogState::ERROR, + write_handle.log_level, + ); } } }