Fix re-showing prompt on password fail, impl logs
Also bump version to 0.2.6
This commit is contained in:
parent
c72e05c53d
commit
f98fc1e24f
7 changed files with 300 additions and 66 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1427,7 +1427,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mpd_info_screen"
|
name = "mpd_info_screen"
|
||||||
version = "0.2.5"
|
version = "0.2.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ggez",
|
"ggez",
|
||||||
"image",
|
"image",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "mpd_info_screen"
|
name = "mpd_info_screen"
|
||||||
version = "0.2.5"
|
version = "0.2.6"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
|
@ -9,7 +9,7 @@ counter, and the filename currently being played
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
mpd_info_screen 0.2.5
|
mpd_info_screen 0.2.6
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
mpd_info_screen [FLAGS] [OPTIONS] <host> [port]
|
mpd_info_screen [FLAGS] [OPTIONS] <host> [port]
|
||||||
|
|
|
@ -1,17 +1,63 @@
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
use structopt::clap::arg_enum;
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
arg_enum! {
|
||||||
pub fn log<T>(msg: T) -> ()
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
pub enum LogState {
|
||||||
|
ERROR,
|
||||||
|
WARNING,
|
||||||
|
DEBUG,
|
||||||
|
VERBOSE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn log<T>(msg: T, level: LogState, state: LogState)
|
||||||
where
|
where
|
||||||
T: Display,
|
T: Display,
|
||||||
{
|
{
|
||||||
println!("{}", msg);
|
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!();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(debug_assertions))]
|
pub fn log_error<T>(msg: T)
|
||||||
pub fn log<T>(msg: T) -> ()
|
|
||||||
where
|
where
|
||||||
T: Display,
|
T: Display,
|
||||||
{
|
{
|
||||||
// intentionally left blank, no logging in non-debug mode
|
println!("ERROR: {}", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn log_warning<T>(msg: T)
|
||||||
|
where
|
||||||
|
T: Display,
|
||||||
|
{
|
||||||
|
println!("WARNING: {}", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn log_debug<T>(msg: T)
|
||||||
|
where
|
||||||
|
T: Display,
|
||||||
|
{
|
||||||
|
println!("DEBUG: {}", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn log_verbose<T>(msg: T)
|
||||||
|
where
|
||||||
|
T: Display,
|
||||||
|
{
|
||||||
|
println!("VERBOSE: {}", msg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::debug_log::log;
|
use crate::debug_log::{self, log};
|
||||||
use crate::mpd_handler::{InfoFromShared, MPDHandler};
|
use crate::mpd_handler::{InfoFromShared, MPDHandler};
|
||||||
use crate::Opt;
|
use crate::Opt;
|
||||||
use ggez::event::{self, EventHandler};
|
use ggez::event::{self, EventHandler};
|
||||||
|
@ -51,6 +51,7 @@ pub struct MPDDisplay {
|
||||||
mpd_handler: Option<Arc<RwLock<MPDHandler>>>,
|
mpd_handler: Option<Arc<RwLock<MPDHandler>>>,
|
||||||
is_valid: bool,
|
is_valid: bool,
|
||||||
is_initialized: bool,
|
is_initialized: bool,
|
||||||
|
is_authenticated: bool,
|
||||||
notice_text: Text,
|
notice_text: Text,
|
||||||
poll_instant: Instant,
|
poll_instant: Instant,
|
||||||
shared: Option<InfoFromShared>,
|
shared: Option<InfoFromShared>,
|
||||||
|
@ -81,6 +82,7 @@ impl MPDDisplay {
|
||||||
mpd_handler: None,
|
mpd_handler: None,
|
||||||
is_valid: true,
|
is_valid: true,
|
||||||
is_initialized: false,
|
is_initialized: false,
|
||||||
|
is_authenticated: false,
|
||||||
notice_text: Text::new(""),
|
notice_text: Text::new(""),
|
||||||
poll_instant: Instant::now() - POLL_TIME,
|
poll_instant: Instant::now() - POLL_TIME,
|
||||||
shared: None,
|
shared: None,
|
||||||
|
@ -110,6 +112,7 @@ impl MPDDisplay {
|
||||||
self.opts.host,
|
self.opts.host,
|
||||||
self.opts.port,
|
self.opts.port,
|
||||||
self.opts.password.clone().map_or(String::new(), |s| s),
|
self.opts.password.clone().map_or(String::new(), |s| s),
|
||||||
|
self.opts.log_level,
|
||||||
)
|
)
|
||||||
.map_or_else(|_| None, |v| Some(v));
|
.map_or_else(|_| None, |v| Some(v));
|
||||||
if self.mpd_handler.is_some() {
|
if self.mpd_handler.is_some() {
|
||||||
|
@ -124,10 +127,18 @@ impl MPDDisplay {
|
||||||
thread::sleep(POLL_TIME);
|
thread::sleep(POLL_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log("Successfully initialized MPDHandler");
|
log(
|
||||||
|
"Successfully initialized MPDHandler",
|
||||||
|
debug_log::LogState::DEBUG,
|
||||||
|
self.opts.log_level,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
self.is_valid = false;
|
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,
|
&mut self.timer_y,
|
||||||
);
|
);
|
||||||
} else {
|
} 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 {
|
if !self.artist_text.contents().is_empty() && !self.opts.disable_show_artist {
|
||||||
|
@ -334,7 +349,11 @@ impl MPDDisplay {
|
||||||
&mut self.timer_y,
|
&mut self.timer_y,
|
||||||
);
|
);
|
||||||
} else {
|
} 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 {
|
if !self.title_text.contents().is_empty() && !self.opts.disable_show_title {
|
||||||
|
@ -349,7 +368,11 @@ impl MPDDisplay {
|
||||||
&mut self.timer_y,
|
&mut self.timer_y,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
log("title text is empty");
|
log(
|
||||||
|
"title text is empty",
|
||||||
|
debug_log::LogState::WARNING,
|
||||||
|
self.opts.log_level,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_transform(
|
set_transform(
|
||||||
|
@ -442,6 +465,42 @@ impl EventHandler for MPDDisplay {
|
||||||
} else {
|
} else {
|
||||||
self.init_mpd_handler();
|
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 {
|
if self.is_valid && self.is_initialized && self.poll_instant.elapsed() > POLL_TIME {
|
||||||
|
@ -453,7 +512,11 @@ impl EventHandler for MPDDisplay {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.swap(false, Ordering::Relaxed)
|
.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())
|
self.shared = MPDHandler::get_current_song_info(self.mpd_handler.clone().unwrap())
|
||||||
.map_or(None, |f| Some(f));
|
.map_or(None, |f| Some(f));
|
||||||
if let Some(shared) = &self.shared {
|
if let Some(shared) = &self.shared {
|
||||||
|
@ -491,12 +554,16 @@ impl EventHandler for MPDDisplay {
|
||||||
self.length = shared.length;
|
self.length = shared.length;
|
||||||
self.refresh_text_transforms(ctx)?;
|
self.refresh_text_transforms(ctx)?;
|
||||||
} else {
|
} 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() {
|
if self.album_art.is_none() {
|
||||||
let result = self.get_image_from_data(ctx);
|
let result = self.get_image_from_data(ctx);
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
log(e);
|
log(e, debug_log::LogState::DEBUG, self.opts.log_level);
|
||||||
self.album_art = None;
|
self.album_art = None;
|
||||||
self.album_art_draw_transform = None;
|
self.album_art_draw_transform = None;
|
||||||
} else {
|
} else {
|
||||||
|
@ -525,7 +592,6 @@ impl EventHandler for MPDDisplay {
|
||||||
graphics::clear(ctx, Color::BLACK);
|
graphics::clear(ctx, Color::BLACK);
|
||||||
|
|
||||||
if self.album_art.is_some() && self.album_art_draw_transform.is_some() {
|
if self.album_art.is_some() && self.album_art_draw_transform.is_some() {
|
||||||
log("Drawing album_art");
|
|
||||||
self.album_art.as_ref().unwrap().draw(
|
self.album_art.as_ref().unwrap().draw(
|
||||||
ctx,
|
ctx,
|
||||||
DrawParam {
|
DrawParam {
|
||||||
|
@ -619,7 +685,6 @@ impl EventHandler for MPDDisplay {
|
||||||
}
|
}
|
||||||
} else if keycode == event::KeyCode::Return {
|
} else if keycode == event::KeyCode::Return {
|
||||||
self.password_entered = true;
|
self.password_entered = true;
|
||||||
//log(format!("Entered \"{}\"", self.opts.password.as_ref().unwrap_or(&String::new())));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if keycode == event::KeyCode::H {
|
if keycode == event::KeyCode::H {
|
||||||
|
|
24
src/main.rs
24
src/main.rs
|
@ -14,7 +14,7 @@ use structopt::StructOpt;
|
||||||
|
|
||||||
use debug_log::log;
|
use debug_log::log;
|
||||||
|
|
||||||
#[derive(StructOpt, Debug)]
|
#[derive(StructOpt, Debug, Clone)]
|
||||||
#[structopt(name = "mpd_info_screen")]
|
#[structopt(name = "mpd_info_screen")]
|
||||||
pub struct Opt {
|
pub struct Opt {
|
||||||
host: Ipv4Addr,
|
host: Ipv4Addr,
|
||||||
|
@ -35,6 +35,14 @@ pub struct Opt {
|
||||||
help = "don't scale-fill the album art to the window"
|
help = "don't scale-fill the album art to the window"
|
||||||
)]
|
)]
|
||||||
do_not_fill_scale_album_art: bool,
|
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> {
|
fn main() -> Result<(), String> {
|
||||||
|
@ -53,7 +61,7 @@ fn main() -> Result<(), String> {
|
||||||
.build()
|
.build()
|
||||||
.expect("Failed to create ggez context");
|
.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();
|
let mut modifiers_state: ModifiersState = ModifiersState::default();
|
||||||
|
|
||||||
|
@ -113,7 +121,11 @@ fn main() -> Result<(), String> {
|
||||||
event::winit_event::WindowEvent::ReceivedCharacter(ch) => {
|
event::winit_event::WindowEvent::ReceivedCharacter(ch) => {
|
||||||
display.text_input_event(ctx, 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 => {
|
event::winit_event::Event::MainEventsCleared => {
|
||||||
ctx.timer_context.tick();
|
ctx.timer_context.tick();
|
||||||
|
@ -137,7 +149,11 @@ fn main() -> Result<(), String> {
|
||||||
thread::sleep(Duration::from_millis(90));
|
thread::sleep(Duration::from_millis(90));
|
||||||
ggez::timer::yield_now();
|
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,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::debug_log::log;
|
use crate::debug_log::{log, LogState};
|
||||||
use std::io::{self, Read, Write};
|
use std::io::{self, Read, Write};
|
||||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpStream};
|
use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpStream};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
@ -60,6 +60,7 @@ pub struct MPDHandler {
|
||||||
self_thread: Option<Arc<Mutex<thread::JoinHandle<Result<(), String>>>>>,
|
self_thread: Option<Arc<Mutex<thread::JoinHandle<Result<(), String>>>>>,
|
||||||
dirty_flag: Arc<AtomicBool>,
|
dirty_flag: Arc<AtomicBool>,
|
||||||
pub stop_flag: Arc<AtomicBool>,
|
pub stop_flag: Arc<AtomicBool>,
|
||||||
|
log_level: LogState,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_next_chars(
|
fn check_next_chars(
|
||||||
|
@ -218,7 +219,12 @@ fn read_line(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MPDHandler {
|
impl MPDHandler {
|
||||||
pub fn new(host: Ipv4Addr, port: u16, password: String) -> Result<Arc<RwLock<Self>>, String> {
|
pub fn new(
|
||||||
|
host: Ipv4Addr,
|
||||||
|
port: u16,
|
||||||
|
password: String,
|
||||||
|
log_level: LogState,
|
||||||
|
) -> Result<Arc<RwLock<Self>>, String> {
|
||||||
let stream = TcpStream::connect_timeout(
|
let stream = TcpStream::connect_timeout(
|
||||||
&SocketAddr::new(IpAddr::V4(host), port),
|
&SocketAddr::new(IpAddr::V4(host), port),
|
||||||
Duration::from_secs(5),
|
Duration::from_secs(5),
|
||||||
|
@ -254,6 +260,7 @@ impl MPDHandler {
|
||||||
self_thread: None,
|
self_thread: None,
|
||||||
dirty_flag: Arc::new(AtomicBool::new(true)),
|
dirty_flag: Arc::new(AtomicBool::new(true)),
|
||||||
stop_flag: Arc::new(AtomicBool::new(false)),
|
stop_flag: Arc::new(AtomicBool::new(false)),
|
||||||
|
log_level,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let s_clone = s.clone();
|
let s_clone = s.clone();
|
||||||
|
@ -326,7 +333,18 @@ impl MPDHandler {
|
||||||
&self.art_data
|
&self.art_data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_authenticated(h: Arc<RwLock<Self>>) -> Result<bool, ()> {
|
||||||
|
let read_handle = h.try_read().map_err(|_| ())?;
|
||||||
|
Ok(read_handle.is_authenticated)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn failed_to_authenticate(h: Arc<RwLock<Self>>) -> Result<bool, ()> {
|
||||||
|
let read_handle = h.try_read().map_err(|_| ())?;
|
||||||
|
Ok(!read_handle.can_authenticate)
|
||||||
|
}
|
||||||
|
|
||||||
fn handler_loop(h: Arc<RwLock<Self>>) -> Result<(), String> {
|
fn handler_loop(h: Arc<RwLock<Self>>) -> 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 buf: [u8; BUF_SIZE] = [0; BUF_SIZE];
|
||||||
let mut saved: Vec<u8> = Vec::new();
|
let mut saved: Vec<u8> = Vec::new();
|
||||||
let mut saved_str: String = String::new();
|
let mut saved_str: String = String::new();
|
||||||
|
@ -349,7 +367,11 @@ impl MPDHandler {
|
||||||
if let Ok(write_handle) = h.try_write() {
|
if let Ok(write_handle) = h.try_write() {
|
||||||
if write_handle.self_thread.is_none() {
|
if write_handle.self_thread.is_none() {
|
||||||
// main thread failed to store handle to this thread
|
// 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;
|
break 'main;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,9 +380,17 @@ impl MPDHandler {
|
||||||
if let Err(err_string) =
|
if let Err(err_string) =
|
||||||
Self::handler_read_block(h.clone(), &mut buf, &mut saved, &mut saved_str)
|
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()) {
|
} 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() {
|
if let Ok(read_handle) = h.try_read() {
|
||||||
|
@ -372,7 +402,11 @@ impl MPDHandler {
|
||||||
io::stdout().flush().unwrap();
|
io::stdout().flush().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
log("MPDHandler thread entering exit loop");
|
log(
|
||||||
|
"MPDHandler thread entering exit loop",
|
||||||
|
LogState::DEBUG,
|
||||||
|
log_level,
|
||||||
|
);
|
||||||
'exit: loop {
|
'exit: loop {
|
||||||
if let Ok(mut write_handle) = h.try_write() {
|
if let Ok(mut write_handle) = h.try_write() {
|
||||||
write_handle.self_thread = None;
|
write_handle.self_thread = None;
|
||||||
|
@ -417,22 +451,30 @@ impl MPDHandler {
|
||||||
buf_vec = buf_vec.split_off(count + 1);
|
buf_vec = buf_vec.split_off(count + 1);
|
||||||
write_handle.current_binary_size = 0;
|
write_handle.current_binary_size = 0;
|
||||||
write_handle.poll_state = PollState::None;
|
write_handle.poll_state = PollState::None;
|
||||||
log(format!(
|
log(
|
||||||
"Album art recv progress: {}/{}",
|
format!(
|
||||||
write_handle.art_data.len(),
|
"Album art recv progress: {}/{}",
|
||||||
write_handle.art_data_size
|
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 {
|
if write_handle.art_data.len() == write_handle.art_data_size {
|
||||||
write_handle.dirty_flag.store(true, Ordering::Relaxed);
|
write_handle.dirty_flag.store(true, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
write_handle.art_data.extend_from_slice(&buf_vec);
|
write_handle.art_data.extend_from_slice(&buf_vec);
|
||||||
write_handle.current_binary_size -= buf_vec.len();
|
write_handle.current_binary_size -= buf_vec.len();
|
||||||
log(format!(
|
log(
|
||||||
"Album art recv progress: {}/{}",
|
format!(
|
||||||
write_handle.art_data.len(),
|
"Album art recv progress: {}/{}",
|
||||||
write_handle.art_data_size
|
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 {
|
if write_handle.art_data.len() == write_handle.art_data_size {
|
||||||
write_handle.dirty_flag.store(true, Ordering::Relaxed);
|
write_handle.dirty_flag.store(true, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
@ -446,7 +488,11 @@ impl MPDHandler {
|
||||||
if write_handle.is_init {
|
if write_handle.is_init {
|
||||||
if line.starts_with("OK MPD ") {
|
if line.starts_with("OK MPD ") {
|
||||||
write_handle.is_init = false;
|
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;
|
write_handle.poll_state = PollState::None;
|
||||||
break 'handle_buf;
|
break 'handle_buf;
|
||||||
} else {
|
} else {
|
||||||
|
@ -455,24 +501,33 @@ impl MPDHandler {
|
||||||
} // write_handle.is_init
|
} // write_handle.is_init
|
||||||
|
|
||||||
if line.starts_with("OK") {
|
if line.starts_with("OK") {
|
||||||
log(format!(
|
log(
|
||||||
"Got OK when poll state is {:?}",
|
format!("Got OK when poll state is {:?}", write_handle.poll_state),
|
||||||
write_handle.poll_state
|
LogState::DEBUG,
|
||||||
));
|
write_handle.log_level,
|
||||||
|
);
|
||||||
match write_handle.poll_state {
|
match write_handle.poll_state {
|
||||||
PollState::Password => write_handle.is_authenticated = true,
|
PollState::Password => write_handle.is_authenticated = true,
|
||||||
PollState::ReadPicture => {
|
PollState::ReadPicture => {
|
||||||
if write_handle.art_data.is_empty() {
|
if write_handle.art_data.is_empty() {
|
||||||
write_handle.can_get_album_art = false;
|
write_handle.can_get_album_art = false;
|
||||||
write_handle.dirty_flag.store(true, Ordering::Relaxed);
|
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 => {
|
PollState::ReadPictureInDir => {
|
||||||
if write_handle.art_data.is_empty() {
|
if write_handle.art_data.is_empty() {
|
||||||
write_handle.can_get_album_art_in_dir = false;
|
write_handle.can_get_album_art_in_dir = false;
|
||||||
write_handle.dirty_flag.store(true, Ordering::Relaxed);
|
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;
|
write_handle.poll_state = PollState::None;
|
||||||
break 'handle_buf;
|
break 'handle_buf;
|
||||||
} else if line.starts_with("ACK") {
|
} else if line.starts_with("ACK") {
|
||||||
println!("ERROR: {}", line);
|
log(line, LogState::WARNING, write_handle.log_level);
|
||||||
match write_handle.poll_state {
|
match write_handle.poll_state {
|
||||||
PollState::Password => {
|
PollState::Password => {
|
||||||
write_handle.can_authenticate = false;
|
write_handle.can_authenticate = false;
|
||||||
|
@ -496,14 +551,22 @@ impl MPDHandler {
|
||||||
PollState::ReadPicture => {
|
PollState::ReadPicture => {
|
||||||
write_handle.can_get_album_art = false;
|
write_handle.can_get_album_art = false;
|
||||||
write_handle.dirty_flag.store(true, Ordering::Relaxed);
|
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
|
// Not setting error_text here since
|
||||||
// ReadPictureInDir is tried next
|
// ReadPictureInDir is tried next
|
||||||
}
|
}
|
||||||
PollState::ReadPictureInDir => {
|
PollState::ReadPictureInDir => {
|
||||||
write_handle.can_get_album_art_in_dir = false;
|
write_handle.can_get_album_art_in_dir = false;
|
||||||
write_handle.dirty_flag.store(true, Ordering::Relaxed);
|
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();
|
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.dirty_flag.store(true, Ordering::Relaxed);
|
||||||
write_handle.song_pos_get_time = Instant::now();
|
write_handle.song_pos_get_time = Instant::now();
|
||||||
} else {
|
} 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: ") {
|
} else if line.starts_with("duration: ") {
|
||||||
let parse_pos_result = f64::from_str(&line.split_off(10));
|
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.dirty_flag.store(true, Ordering::Relaxed);
|
||||||
write_handle.song_length_get_time = Instant::now();
|
write_handle.song_length_get_time = Instant::now();
|
||||||
} else {
|
} 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: ") {
|
} else if line.starts_with("size: ") {
|
||||||
let parse_artsize_result = usize::from_str(&line.split_off(6));
|
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.art_data_size = value;
|
||||||
write_handle.dirty_flag.store(true, Ordering::Relaxed);
|
write_handle.dirty_flag.store(true, Ordering::Relaxed);
|
||||||
} else {
|
} 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: ") {
|
} else if line.starts_with("binary: ") {
|
||||||
let parse_artbinarysize_result = usize::from_str(&line.split_off(8));
|
let parse_artbinarysize_result = usize::from_str(&line.split_off(8));
|
||||||
if let Ok(value) = parse_artbinarysize_result {
|
if let Ok(value) = parse_artbinarysize_result {
|
||||||
write_handle.current_binary_size = value;
|
write_handle.current_binary_size = value;
|
||||||
} else {
|
} 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: ") {
|
} else if line.starts_with("Title: ") {
|
||||||
write_handle.current_song_title = line.split_off(7);
|
write_handle.current_song_title = line.split_off(7);
|
||||||
|
@ -568,15 +647,23 @@ impl MPDHandler {
|
||||||
} else if line.starts_with("type: ") {
|
} else if line.starts_with("type: ") {
|
||||||
write_handle.art_data_type = line.split_off(6);
|
write_handle.art_data_type = line.split_off(6);
|
||||||
} else {
|
} 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 {
|
} else if let Err((msg, read_line_in_progress)) = read_line_result {
|
||||||
log(format!(
|
log(
|
||||||
"WARNING read_line: {}, saved size == {}, in_progress size == {}",
|
format!(
|
||||||
msg,
|
"read_line: {}, saved size == {}, in_progress size == {}",
|
||||||
saved.len(),
|
msg,
|
||||||
read_line_in_progress.len()
|
saved.len(),
|
||||||
));
|
read_line_in_progress.len()
|
||||||
|
),
|
||||||
|
LogState::WARNING,
|
||||||
|
write_handle.log_level,
|
||||||
|
);
|
||||||
*saved_str = read_line_in_progress;
|
*saved_str = read_line_in_progress;
|
||||||
break 'handle_buf;
|
break 'handle_buf;
|
||||||
} else {
|
} else {
|
||||||
|
@ -613,7 +700,11 @@ impl MPDHandler {
|
||||||
if write_result.is_ok() {
|
if write_result.is_ok() {
|
||||||
write_handle.poll_state = PollState::Password;
|
write_handle.poll_state = PollState::Password;
|
||||||
} else if let Err(e) = write_result {
|
} 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
|
} else if write_handle.can_get_status
|
||||||
&& (write_handle.song_title_get_time.elapsed() > POLL_DURATION
|
&& (write_handle.song_title_get_time.elapsed() > POLL_DURATION
|
||||||
|
@ -624,7 +715,11 @@ impl MPDHandler {
|
||||||
if write_result.is_ok() {
|
if write_result.is_ok() {
|
||||||
write_handle.poll_state = PollState::CurrentSong;
|
write_handle.poll_state = PollState::CurrentSong;
|
||||||
} else if let Err(e) = write_result {
|
} 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
|
} else if write_handle.can_get_status
|
||||||
&& (write_handle.song_length_get_time.elapsed() > POLL_DURATION
|
&& (write_handle.song_length_get_time.elapsed() > POLL_DURATION
|
||||||
|
@ -636,7 +731,11 @@ impl MPDHandler {
|
||||||
if write_result.is_ok() {
|
if write_result.is_ok() {
|
||||||
write_handle.poll_state = PollState::Status;
|
write_handle.poll_state = PollState::Status;
|
||||||
} else if let Err(e) = write_result {
|
} 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()
|
} else if (write_handle.art_data.is_empty()
|
||||||
|| write_handle.art_data.len() != write_handle.art_data_size)
|
|| write_handle.art_data.len() != write_handle.art_data_size)
|
||||||
|
@ -651,7 +750,11 @@ impl MPDHandler {
|
||||||
if write_result.is_ok() {
|
if write_result.is_ok() {
|
||||||
write_handle.poll_state = PollState::ReadPicture;
|
write_handle.poll_state = PollState::ReadPicture;
|
||||||
} else if let Err(e) = write_result {
|
} 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 {
|
} else if write_handle.can_get_album_art_in_dir {
|
||||||
let write_result = write_handle
|
let write_result = write_handle
|
||||||
|
@ -660,7 +763,11 @@ impl MPDHandler {
|
||||||
if write_result.is_ok() {
|
if write_result.is_ok() {
|
||||||
write_handle.poll_state = PollState::ReadPictureInDir;
|
write_handle.poll_state = PollState::ReadPictureInDir;
|
||||||
} else if let Err(e) = write_result {
|
} 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,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue