Compare commits
28 commits
Author | SHA1 | Date | |
---|---|---|---|
Stephen Seo | d90c86c894 | ||
Stephen Seo | f42fadd403 | ||
Stephen Seo | f2f58047a5 | ||
Stephen Seo | d457098f2a | ||
Stephen Seo | d0beff5a98 | ||
Stephen Seo | 7a860e323a | ||
Stephen Seo | ef234f0ec0 | ||
Stephen Seo | 391949cde6 | ||
Stephen Seo | f66880f13d | ||
Stephen Seo | 83bb20c246 | ||
Stephen Seo | dd868969cc | ||
Stephen Seo | 1dc28d7b07 | ||
Stephen Seo | f7ffa62e02 | ||
Stephen Seo | bcea959381 | ||
Stephen Seo | aa6fb750e7 | ||
Stephen Seo | a1706913e6 | ||
Stephen Seo | e28d20a5da | ||
Stephen Seo | 4653399fe9 | ||
Stephen Seo | e0be69df81 | ||
Stephen Seo | 8643542b7a | ||
Stephen Seo | e9e57c9dff | ||
Stephen Seo | d1590bee0a | ||
Stephen Seo | 56f6784892 | ||
Stephen Seo | a223d8b530 | ||
Stephen Seo | fad82f6448 | ||
Stephen Seo | 934aa1a610 | ||
Stephen Seo | 6d400cd7c7 | ||
Stephen Seo | c902f0fcf3 |
2436
Cargo.lock
generated
2436
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
10
Cargo.toml
10
Cargo.toml
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "mpd_info_screen"
|
||||
version = "0.4.0"
|
||||
version = "0.4.9"
|
||||
edition = "2021"
|
||||
description = "Displays info on currently playing music from an MPD daemon"
|
||||
license = "MIT"
|
||||
|
@ -10,14 +10,14 @@ resolver = "2"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
structopt = "0.3"
|
||||
clap = { version = "4.4", features = ["derive"] }
|
||||
image = "0.24"
|
||||
ggez = "0.8.1"
|
||||
ggez = "0.9.3"
|
||||
freetype = { version = "0.7", optional = true }
|
||||
wgpu = "0.14"
|
||||
wgpu = "0.16"
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = { version = "0.53", optional = true }
|
||||
bindgen = { version = "0.69", optional = true }
|
||||
|
||||
[features]
|
||||
unicode_support = ["dep:freetype", "dep:bindgen"]
|
||||
|
|
57
README.md
57
README.md
|
@ -12,6 +12,11 @@ A Rust program that displays info about the currently running MPD server.
|
|||
The window shows albumart (may be embedded in the audio file, or is a "cover.jpg" in the same directory as the song file), a "time-remaining"
|
||||
counter, and the filename currently being played
|
||||
|
||||
## Known Bugs ❗❗
|
||||
|
||||
Currently there are no known bugs. Please report any bugs you find to the
|
||||
[issue tracker](https://github.com/Stephen-Seo/mpd_info_screen/issues).
|
||||
|
||||
## Unicode Support
|
||||
|
||||
By default, unicode characters will not display properly. Build the project with
|
||||
|
@ -30,29 +35,39 @@ or through crates.io:
|
|||
# Usage
|
||||
|
||||
|
||||
mpd_info_screen 0.3.7
|
||||
Displays info on currently playing music from an MPD daemon
|
||||
|
||||
USAGE:
|
||||
mpd_info_screen [FLAGS] [OPTIONS] <host> [port]
|
||||
Usage: mpd_info_screen [OPTIONS] <HOST> [PORT]
|
||||
|
||||
FLAGS:
|
||||
--disable-show-album disable album display
|
||||
--disable-show-artist disable artist display
|
||||
--disable-show-filename disable filename display
|
||||
--disable-show-title disable title display
|
||||
--no-scale-fill don't scale-fill the album art to the window
|
||||
--pprompt input password via prompt
|
||||
-h, --help Prints help information
|
||||
-V, --version Prints version information
|
||||
Arguments:
|
||||
<HOST>
|
||||
[PORT] [default: 6600]
|
||||
|
||||
OPTIONS:
|
||||
-l, --log-level <log-level> [default: Error] [possible values: Error, Warning, Debug, Verbose]
|
||||
-p <password>
|
||||
-t, --text-bg-opacity <text-bg-opacity> sets the opacity of the text background (0-255) [default: 190]
|
||||
Options:
|
||||
-p <PASSWORD>
|
||||
|
||||
ARGS:
|
||||
<host>
|
||||
<port> [default: 6600]
|
||||
--disable-show-title
|
||||
disable title display
|
||||
--disable-show-artist
|
||||
disable artist display
|
||||
--disable-show-album
|
||||
disable album display
|
||||
--disable-show-filename
|
||||
disable filename display
|
||||
--pprompt
|
||||
input password via prompt
|
||||
--pfile <PASSWORD_FILE>
|
||||
read password from file
|
||||
--no-scale-fill
|
||||
don't scale-fill the album art to the window
|
||||
-l, --log-level <LOG_LEVEL>
|
||||
[default: error] [possible values: error, warning, debug, verbose]
|
||||
-t, --text-bg-opacity <TEXT_BG_OPACITY>
|
||||
sets the opacity of the text background (0-255) [default: 190]
|
||||
-h, --help
|
||||
Print help
|
||||
-V, --version
|
||||
Print version
|
||||
|
||||
|
||||
Note that presing the Escape key when the window is focused closes the program.
|
||||
|
@ -81,8 +96,8 @@ MIT license.
|
|||
Uses dependency [image](https://crates.io/crates/image) which is licensed under
|
||||
MIT license.
|
||||
|
||||
Uses dependency [structopt](https://crates.io/crates/structopt) which is
|
||||
licensed under Apache-2.0 or MIT licenses.
|
||||
Uses dependency [clap](https://crates.io/crates/clap) which is licensed under
|
||||
Apache-2.0 or MIT licenses.
|
||||
|
||||
## Unicode Support Dependencies
|
||||
|
||||
|
|
2
build.rs
2
build.rs
|
@ -14,7 +14,7 @@ fn main() {
|
|||
|
||||
let bindings = bindgen::Builder::default()
|
||||
.header("src/bindgen_wrapper.h")
|
||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
|
||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
|
||||
.generate()
|
||||
.expect("Unable to generate bindings");
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use std::fmt::Display;
|
||||
use structopt::clap::arg_enum;
|
||||
use clap::ValueEnum;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum LogState {
|
||||
|
@ -9,14 +9,12 @@ pub enum LogState {
|
|||
Verbose,
|
||||
}
|
||||
|
||||
arg_enum! {
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum LogLevel {
|
||||
Error,
|
||||
Warning,
|
||||
Debug,
|
||||
Verbose,
|
||||
}
|
||||
#[derive(ValueEnum, Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum LogLevel {
|
||||
Error,
|
||||
Warning,
|
||||
Debug,
|
||||
Verbose,
|
||||
}
|
||||
|
||||
pub fn log<T>(msg: T, state: LogState, level: LogLevel)
|
||||
|
@ -46,26 +44,26 @@ pub fn log_error<T>(msg: T)
|
|||
where
|
||||
T: Display,
|
||||
{
|
||||
println!("Error: {}", msg);
|
||||
println!("Error: {msg}");
|
||||
}
|
||||
|
||||
pub fn log_warning<T>(msg: T)
|
||||
where
|
||||
T: Display,
|
||||
{
|
||||
println!("Warning: {}", msg);
|
||||
println!("Warning: {msg}");
|
||||
}
|
||||
|
||||
pub fn log_debug<T>(msg: T)
|
||||
where
|
||||
T: Display,
|
||||
{
|
||||
println!("Debug: {}", msg);
|
||||
println!("Debug: {msg}");
|
||||
}
|
||||
|
||||
pub fn log_verbose<T>(msg: T)
|
||||
where
|
||||
T: Display,
|
||||
{
|
||||
println!("Verbose: {}", msg);
|
||||
println!("Verbose: {msg}");
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ fn string_to_text(
|
|||
}
|
||||
} else {
|
||||
log(
|
||||
format!("Failed to find font for {}", c),
|
||||
format!("Failed to find font for {c}"),
|
||||
debug_log::LogState::Error,
|
||||
debug_log::LogLevel::Error,
|
||||
);
|
||||
|
@ -213,11 +213,17 @@ pub struct MPDDisplay {
|
|||
album_string_cache: String,
|
||||
album_transform: Transform,
|
||||
timer_text: Text,
|
||||
timer_text_len: usize,
|
||||
timer_transform: Transform,
|
||||
timer_x: f32,
|
||||
timer_y: f32,
|
||||
timer: f64,
|
||||
length: f64,
|
||||
cached_filename_y: f32,
|
||||
cached_album_y: f32,
|
||||
cached_artist_y: f32,
|
||||
cached_title_y: f32,
|
||||
cached_timer_y: f32,
|
||||
text_bg_mesh: Option<Mesh>,
|
||||
hide_text: bool,
|
||||
tried_album_art_in_dir: bool,
|
||||
|
@ -234,7 +240,7 @@ impl MPDDisplay {
|
|||
is_initialized: false,
|
||||
is_authenticated: false,
|
||||
notice_text: Text::default(),
|
||||
poll_instant: Instant::now() - POLL_TIME,
|
||||
poll_instant: Instant::now().checked_sub(POLL_TIME).unwrap(),
|
||||
shared: None,
|
||||
password_entered: false,
|
||||
dirty_flag: None,
|
||||
|
@ -247,11 +253,17 @@ impl MPDDisplay {
|
|||
title_text: Text::default(),
|
||||
title_transform: Transform::default(),
|
||||
timer_text: Text::new("0"),
|
||||
timer_text_len: 0,
|
||||
timer_transform: Transform::default(),
|
||||
timer_x: INIT_FONT_SIZE_X,
|
||||
timer_y: INIT_FONT_SIZE_Y,
|
||||
timer: 0.0,
|
||||
length: 0.0,
|
||||
cached_filename_y: 0.0f32,
|
||||
cached_album_y: 0.0f32,
|
||||
cached_artist_y: 0.0f32,
|
||||
cached_title_y: 0.0f32,
|
||||
cached_timer_y: 0.0f32,
|
||||
text_bg_mesh: None,
|
||||
hide_text: false,
|
||||
tried_album_art_in_dir: false,
|
||||
|
@ -411,13 +423,10 @@ impl MPDDisplay {
|
|||
let reader = ImageReader::new(Cursor::new(image_ref));
|
||||
let guessed_reader = reader
|
||||
.with_guessed_format()
|
||||
.map_err(|e| format!("Error: Failed to guess format of album art image: {}", e));
|
||||
.map_err(|e| format!("Error: Failed to guess format of album art image: {e}"));
|
||||
if let Ok(reader) = guessed_reader {
|
||||
reader.decode().map_err(|e| {
|
||||
format!(
|
||||
"Error: Failed to decode album art image (guessed format): {}",
|
||||
e
|
||||
)
|
||||
format!("Error: Failed to decode album art image (guessed format): {e}")
|
||||
})
|
||||
} else {
|
||||
// Convert Ok(_) to Ok(DynamicImage) which will never be used
|
||||
|
@ -427,7 +436,7 @@ impl MPDDisplay {
|
|||
} else {
|
||||
ImageReader::with_format(Cursor::new(image_ref), image_format)
|
||||
.decode()
|
||||
.map_err(|e| format!("Error: Failed to decode album art image: {}", e))
|
||||
.map_err(|e| format!("Error: Failed to decode album art image: {e}"))
|
||||
};
|
||||
if img_result.is_err() && !self.tried_album_art_in_dir {
|
||||
return try_second_art_fetch_method(
|
||||
|
@ -462,12 +471,6 @@ impl MPDDisplay {
|
|||
|
||||
let mut offset_y: f32 = drawable_size.1;
|
||||
|
||||
let mut filename_y: f32 = 0.0;
|
||||
let mut album_y: f32 = 0.0;
|
||||
let mut artist_y: f32 = 0.0;
|
||||
let mut title_y: f32 = 0.0;
|
||||
let mut timer_y: f32 = 0.0;
|
||||
|
||||
let set_transform = |text: &mut Text,
|
||||
transform: &mut Transform,
|
||||
offset_y: &mut f32,
|
||||
|
@ -554,7 +557,7 @@ impl MPDDisplay {
|
|||
&mut self.filename_text,
|
||||
&mut self.filename_transform,
|
||||
&mut offset_y,
|
||||
&mut filename_y,
|
||||
&mut self.cached_filename_y,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
|
@ -574,7 +577,7 @@ impl MPDDisplay {
|
|||
&mut self.album_text,
|
||||
&mut self.album_transform,
|
||||
&mut offset_y,
|
||||
&mut album_y,
|
||||
&mut self.cached_album_y,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
|
@ -588,7 +591,7 @@ impl MPDDisplay {
|
|||
&mut self.artist_text,
|
||||
&mut self.artist_transform,
|
||||
&mut offset_y,
|
||||
&mut artist_y,
|
||||
&mut self.cached_artist_y,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
|
@ -608,7 +611,7 @@ impl MPDDisplay {
|
|||
&mut self.title_text,
|
||||
&mut self.title_transform,
|
||||
&mut offset_y,
|
||||
&mut title_y,
|
||||
&mut self.cached_title_y,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
|
@ -627,7 +630,7 @@ impl MPDDisplay {
|
|||
&mut self.timer_text,
|
||||
&mut self.timer_transform,
|
||||
&mut offset_y,
|
||||
&mut timer_y,
|
||||
&mut self.cached_timer_y,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
|
@ -635,6 +638,12 @@ impl MPDDisplay {
|
|||
&mut self.timer_y,
|
||||
);
|
||||
|
||||
self.update_bg_mesh(ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update_bg_mesh(&mut self, ctx: &mut Context) -> GameResult<()> {
|
||||
let filename_dimensions = self
|
||||
.filename_text
|
||||
.dimensions(ctx)
|
||||
|
@ -662,7 +671,7 @@ impl MPDDisplay {
|
|||
DrawMode::fill(),
|
||||
Rect {
|
||||
x: TEXT_X_OFFSET,
|
||||
y: filename_y,
|
||||
y: self.cached_filename_y,
|
||||
w: filename_dimensions.w,
|
||||
h: filename_dimensions.h,
|
||||
},
|
||||
|
@ -674,7 +683,7 @@ impl MPDDisplay {
|
|||
DrawMode::fill(),
|
||||
Rect {
|
||||
x: TEXT_X_OFFSET,
|
||||
y: album_y,
|
||||
y: self.cached_album_y,
|
||||
w: album_dimensions.w,
|
||||
h: album_dimensions.h,
|
||||
},
|
||||
|
@ -686,7 +695,7 @@ impl MPDDisplay {
|
|||
DrawMode::fill(),
|
||||
Rect {
|
||||
x: TEXT_X_OFFSET,
|
||||
y: artist_y,
|
||||
y: self.cached_artist_y,
|
||||
w: artist_dimensions.w,
|
||||
h: artist_dimensions.h,
|
||||
},
|
||||
|
@ -698,7 +707,7 @@ impl MPDDisplay {
|
|||
DrawMode::fill(),
|
||||
Rect {
|
||||
x: TEXT_X_OFFSET,
|
||||
y: title_y,
|
||||
y: self.cached_title_y,
|
||||
w: title_dimensions.w,
|
||||
h: title_dimensions.h,
|
||||
},
|
||||
|
@ -712,7 +721,7 @@ impl MPDDisplay {
|
|||
DrawMode::fill(),
|
||||
Rect {
|
||||
x: TEXT_X_OFFSET,
|
||||
y: timer_y,
|
||||
y: self.cached_timer_y,
|
||||
w: timer_dimensions.w,
|
||||
h: timer_dimensions.h,
|
||||
},
|
||||
|
@ -732,8 +741,7 @@ impl EventHandler for MPDDisplay {
|
|||
if !self.is_valid {
|
||||
if let Err(mpd_handler_error) = &self.mpd_handler {
|
||||
return Err(GameError::EventLoopError(format!(
|
||||
"Failed to initialize MPDHandler: {}",
|
||||
mpd_handler_error
|
||||
"Failed to initialize MPDHandler: {mpd_handler_error}"
|
||||
)));
|
||||
} else {
|
||||
return Err(GameError::EventLoopError(
|
||||
|
@ -922,11 +930,16 @@ impl EventHandler for MPDDisplay {
|
|||
let delta = ctx.time.delta();
|
||||
self.timer += delta.as_secs_f64();
|
||||
let timer_diff = seconds_to_time(self.length - self.timer);
|
||||
let timer_diff_len = timer_diff.len();
|
||||
self.timer_text = Text::new(timer_diff);
|
||||
self.timer_text.set_scale(PxScale {
|
||||
x: self.timer_x,
|
||||
y: self.timer_y,
|
||||
});
|
||||
if timer_diff_len != self.timer_text_len {
|
||||
self.timer_text_len = timer_diff_len;
|
||||
self.update_bg_mesh(ctx)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
59
src/main.rs
59
src/main.rs
|
@ -9,46 +9,48 @@ use ggez::event::winit_event::{ElementState, KeyboardInput, ModifiersState};
|
|||
use ggez::event::{self, ControlFlow, EventHandler};
|
||||
use ggez::input::keyboard::{self, KeyInput};
|
||||
use ggez::{ContextBuilder, GameError};
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::path::PathBuf;
|
||||
use std::thread;
|
||||
use std::time::{Duration, Instant};
|
||||
use structopt::StructOpt;
|
||||
use clap::Parser;
|
||||
|
||||
use debug_log::log;
|
||||
|
||||
#[derive(StructOpt, Debug, Clone)]
|
||||
#[structopt(name = "mpd_info_screen")]
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
pub struct Opt {
|
||||
host: Ipv4Addr,
|
||||
#[structopt(default_value = "6600")]
|
||||
#[arg(default_value = "6600")]
|
||||
port: u16,
|
||||
#[structopt(short = "p")]
|
||||
#[arg(short = 'p')]
|
||||
password: Option<String>,
|
||||
#[structopt(long = "disable-show-title", help = "disable title display")]
|
||||
#[arg(long = "disable-show-title", help = "disable title display")]
|
||||
disable_show_title: bool,
|
||||
#[structopt(long = "disable-show-artist", help = "disable artist display")]
|
||||
#[arg(long = "disable-show-artist", help = "disable artist display")]
|
||||
disable_show_artist: bool,
|
||||
#[structopt(long = "disable-show-album", help = "disable album display")]
|
||||
#[arg(long = "disable-show-album", help = "disable album display")]
|
||||
disable_show_album: bool,
|
||||
#[structopt(long = "disable-show-filename", help = "disable filename display")]
|
||||
#[arg(long = "disable-show-filename", help = "disable filename display")]
|
||||
disable_show_filename: bool,
|
||||
#[structopt(long = "pprompt", help = "input password via prompt")]
|
||||
#[arg(long = "pprompt", help = "input password via prompt")]
|
||||
enable_prompt_password: bool,
|
||||
#[structopt(
|
||||
#[arg(long = "pfile", help = "read password from file")]
|
||||
password_file: Option<PathBuf>,
|
||||
#[arg(
|
||||
long = "no-scale-fill",
|
||||
help = "don't scale-fill the album art to the window"
|
||||
)]
|
||||
do_not_fill_scale_album_art: bool,
|
||||
#[structopt(
|
||||
short = "l",
|
||||
#[arg(
|
||||
short = 'l',
|
||||
long = "log-level",
|
||||
possible_values = &debug_log::LogLevel::variants(),
|
||||
default_value = "Error",
|
||||
case_insensitive = true,
|
||||
default_value = "error",
|
||||
)]
|
||||
log_level: debug_log::LogLevel,
|
||||
#[structopt(
|
||||
#[arg(
|
||||
short,
|
||||
long,
|
||||
help = "sets the opacity of the text background (0-255)",
|
||||
|
@ -58,9 +60,26 @@ pub struct Opt {
|
|||
}
|
||||
|
||||
fn main() -> Result<(), String> {
|
||||
let opt = Opt::from_args();
|
||||
let mut opt = Opt::parse();
|
||||
println!("Got host addr == {}, port == {}", opt.host, opt.port);
|
||||
|
||||
// Read password from file if exists, error otherwise.
|
||||
if let Some(psswd_file_path) = opt.password_file.as_ref() {
|
||||
let mut file = File::open(psswd_file_path).expect("pfile/password_file should exist");
|
||||
let mut content: String = String::new();
|
||||
|
||||
file.read_to_string(&mut content)
|
||||
.expect("Should be able to read from pfile/password_file");
|
||||
|
||||
if content.ends_with("\r\n") {
|
||||
content.truncate(content.len() - 2);
|
||||
} else if content.ends_with('\n') {
|
||||
content.truncate(content.len() - 1);
|
||||
}
|
||||
|
||||
opt.password = Some(content);
|
||||
}
|
||||
|
||||
let (mut ctx, event_loop) = ContextBuilder::new("mpd_info_screen", "Stephen Seo")
|
||||
.window_setup(WindowSetup {
|
||||
title: "mpd info screen".into(),
|
||||
|
@ -131,7 +150,7 @@ fn main() -> Result<(), String> {
|
|||
display.text_input_event(ctx, ch).ok();
|
||||
}
|
||||
x => log(
|
||||
format!("Other window event fired: {:?}", x),
|
||||
format!("Other window event fired: {x:?}"),
|
||||
debug_log::LogState::Verbose,
|
||||
opt.log_level,
|
||||
),
|
||||
|
@ -162,7 +181,7 @@ fn main() -> Result<(), String> {
|
|||
ggez::timer::yield_now();
|
||||
}
|
||||
x => log(
|
||||
format!("Device event fired: {:?}", x),
|
||||
format!("Device event fired: {x:?}"),
|
||||
debug_log::LogState::Verbose,
|
||||
opt.log_level,
|
||||
),
|
||||
|
|
|
@ -250,6 +250,8 @@ impl MPDHandler {
|
|||
)
|
||||
.map_err(|_| String::from("Failed to get TCP connection (is MPD running?)"))?;
|
||||
|
||||
let password_is_empty = password.is_empty();
|
||||
|
||||
let s = MPDHandler {
|
||||
state: Arc::new(RwLock::new(MPDHandlerState {
|
||||
art_data: Vec::new(),
|
||||
|
@ -266,7 +268,7 @@ impl MPDHandler {
|
|||
password,
|
||||
error_text: String::new(),
|
||||
can_authenticate: true,
|
||||
is_authenticated: false,
|
||||
is_authenticated: password_is_empty,
|
||||
can_get_album_art: true,
|
||||
can_get_album_art_in_dir: true,
|
||||
can_get_status: true,
|
||||
|
@ -274,9 +276,9 @@ impl MPDHandler {
|
|||
did_check_overtime: false,
|
||||
force_get_status: false,
|
||||
force_get_current_song: false,
|
||||
song_title_get_time: Instant::now() - Duration::from_secs(10),
|
||||
song_pos_get_time: Instant::now() - Duration::from_secs(10),
|
||||
song_length_get_time: Instant::now() - Duration::from_secs(10),
|
||||
song_title_get_time: Instant::now().checked_sub(Duration::from_secs(10)).unwrap(),
|
||||
song_pos_get_time: Instant::now().checked_sub(Duration::from_secs(10)).unwrap(),
|
||||
song_length_get_time: Instant::now().checked_sub(Duration::from_secs(10)).unwrap(),
|
||||
self_thread: None,
|
||||
dirty_flag: Arc::new(AtomicBool::new(true)),
|
||||
stop_flag: Arc::new(AtomicBool::new(false)),
|
||||
|
@ -426,13 +428,13 @@ impl MPDHandler {
|
|||
|
||||
if let Err(err_string) = self.handler_read_block(&mut buf, &mut saved, &mut saved_str) {
|
||||
log(
|
||||
format!("read_block error: {}", err_string),
|
||||
format!("read_block error: {err_string}"),
|
||||
LogState::Warning,
|
||||
log_level,
|
||||
);
|
||||
} else if let Err(err_string) = self.handler_write_block() {
|
||||
log(
|
||||
format!("write_block error: {}", err_string),
|
||||
format!("write_block error: {err_string}"),
|
||||
LogState::Warning,
|
||||
log_level,
|
||||
);
|
||||
|
@ -477,7 +479,7 @@ impl MPDHandler {
|
|||
let read_result = write_handle.stream.read(buf);
|
||||
if let Err(io_err) = read_result {
|
||||
if io_err.kind() != io::ErrorKind::WouldBlock {
|
||||
return Err(format!("TCP stream error: {}", io_err));
|
||||
return Err(format!("TCP stream error: {io_err}"));
|
||||
} else {
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -649,9 +651,9 @@ impl MPDHandler {
|
|||
MPDPlayState::Paused
|
||||
};
|
||||
write_handle.error_text.clear();
|
||||
write!(&mut write_handle.error_text, "MPD has {:?}", got_mpd_state).ok();
|
||||
write!(&mut write_handle.error_text, "MPD has {got_mpd_state:?}").ok();
|
||||
log(
|
||||
format!("MPD is {:?}", got_mpd_state),
|
||||
format!("MPD is {got_mpd_state:?}"),
|
||||
LogState::Warning,
|
||||
write_handle.log_level,
|
||||
);
|
||||
|
@ -736,7 +738,7 @@ impl MPDHandler {
|
|||
write_handle.art_data_type = line.split_off(6);
|
||||
} else {
|
||||
log(
|
||||
format!("Got unrecognized/ignored line: {}", line),
|
||||
format!("Got unrecognized/ignored line: {line}"),
|
||||
LogState::Warning,
|
||||
write_handle.log_level,
|
||||
);
|
||||
|
@ -799,12 +801,12 @@ impl MPDHandler {
|
|||
let p = write_handle.password.clone();
|
||||
let write_result = write_handle
|
||||
.stream
|
||||
.write(format!("password {}\n", p).as_bytes());
|
||||
.write(format!("password {p}\n").as_bytes());
|
||||
if write_result.is_ok() {
|
||||
write_handle.poll_state = PollState::Password;
|
||||
} else if let Err(e) = write_result {
|
||||
log(
|
||||
format!("Failed to send password for authentication: {}", e),
|
||||
format!("Failed to send password for authentication: {e}"),
|
||||
LogState::Error,
|
||||
write_handle.log_level,
|
||||
);
|
||||
|
@ -820,7 +822,7 @@ impl MPDHandler {
|
|||
write_handle.poll_state = PollState::CurrentSong;
|
||||
} else if let Err(e) = write_result {
|
||||
log(
|
||||
format!("Failed to request song info over stream: {}", e),
|
||||
format!("Failed to request song info over stream: {e}"),
|
||||
LogState::Error,
|
||||
write_handle.log_level,
|
||||
);
|
||||
|
@ -836,7 +838,7 @@ impl MPDHandler {
|
|||
write_handle.poll_state = PollState::Status;
|
||||
} else if let Err(e) = write_result {
|
||||
log(
|
||||
format!("Failed to request status over stream: {}", e),
|
||||
format!("Failed to request status over stream: {e}"),
|
||||
LogState::Error,
|
||||
write_handle.log_level,
|
||||
);
|
||||
|
@ -848,14 +850,14 @@ impl MPDHandler {
|
|||
let title = write_handle.current_song_filename.clone();
|
||||
let art_data_length = write_handle.art_data.len();
|
||||
if write_handle.can_get_album_art {
|
||||
let write_result = write_handle.stream.write(
|
||||
format!("readpicture \"{}\" {}\n", title, art_data_length).as_bytes(),
|
||||
);
|
||||
let write_result = write_handle
|
||||
.stream
|
||||
.write(format!("readpicture \"{title}\" {art_data_length}\n").as_bytes());
|
||||
if write_result.is_ok() {
|
||||
write_handle.poll_state = PollState::ReadPicture;
|
||||
} else if let Err(e) = write_result {
|
||||
log(
|
||||
format!("Failed to request album art: {}", e),
|
||||
format!("Failed to request album art: {e}"),
|
||||
LogState::Error,
|
||||
write_handle.log_level,
|
||||
);
|
||||
|
@ -863,12 +865,12 @@ impl MPDHandler {
|
|||
} else if write_handle.can_get_album_art_in_dir {
|
||||
let write_result = write_handle
|
||||
.stream
|
||||
.write(format!("albumart \"{}\" {}\n", title, art_data_length).as_bytes());
|
||||
.write(format!("albumart \"{title}\" {art_data_length}\n").as_bytes());
|
||||
if write_result.is_ok() {
|
||||
write_handle.poll_state = PollState::ReadPictureInDir;
|
||||
} else if let Err(e) = write_result {
|
||||
log(
|
||||
format!("Failed to request album art in dir: {}", e),
|
||||
format!("Failed to request album art in dir: {e}"),
|
||||
LogState::Error,
|
||||
write_handle.log_level,
|
||||
);
|
||||
|
|
|
@ -67,8 +67,7 @@ mod ffi {
|
|||
return Err(String::from("Failed to FcFontMatch (FcResult is not FcResultMatch; result_pattern is not null)"));
|
||||
} else {
|
||||
return Err(format!(
|
||||
"Failed to FcFontMatch (FcResult is not FcResultMatch; {:?})",
|
||||
result
|
||||
"Failed to FcFontMatch (FcResult is not FcResultMatch; {result:?})"
|
||||
));
|
||||
}
|
||||
} else if result_pattern.is_null() {
|
||||
|
|
Loading…
Reference in a new issue