big overhaul
This commit is contained in:
parent
3be9b6ccea
commit
ecfbe8f147
24
src/main.rs
24
src/main.rs
|
|
@ -8,18 +8,24 @@ use structs::{config::Config, data::Data};
|
||||||
use crate::update_players::update_players;
|
use crate::update_players::update_players;
|
||||||
use crate::update_message::update_message;
|
use crate::update_message::update_message;
|
||||||
use crate::print_text::print_text;
|
use crate::print_text::print_text;
|
||||||
|
use crate::print_players::print_players;
|
||||||
|
|
||||||
mod update_players;
|
mod update_players;
|
||||||
mod update_message;
|
mod update_message;
|
||||||
mod print_text;
|
mod print_text;
|
||||||
mod structs;
|
mod structs;
|
||||||
|
mod print_players;
|
||||||
|
|
||||||
fn handle_signal(data: &Data, pf: &PlayerFinder) {
|
fn handle_signal(data: &Data) {
|
||||||
if data.current_player.is_some() {
|
if let Some(p) = &data.current_player {
|
||||||
if let Ok(p) = pf.find_by_name(data.current_player.as_ref().unwrap()) {
|
|
||||||
let _ = p.checked_play_pause();
|
let _ = p.checked_play_pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn default_loop(pf: &PlayerFinder, cfg: &Config, data: &mut Data) {
|
||||||
|
update_players(pf, cfg, data);
|
||||||
|
update_message(cfg, data);
|
||||||
|
print_text(cfg, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
@ -44,11 +50,13 @@ fn main() {
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
thread::sleep(cfg.update_delay);
|
thread::sleep(cfg.update_delay);
|
||||||
update_players(&pf, &cfg, &mut data);
|
match cli.debug {
|
||||||
update_message(&pf, &cfg, &mut data);
|
true => print_players(&pf),
|
||||||
print_text(&cfg, &mut data);
|
false => default_loop(&pf, &cfg, &mut data),
|
||||||
|
}
|
||||||
|
|
||||||
if term.load(Ordering::Relaxed) {
|
if term.load(Ordering::Relaxed) {
|
||||||
handle_signal(&data, &pf);
|
handle_signal(&data);
|
||||||
term.swap(false, Ordering::Relaxed);
|
term.swap(false, Ordering::Relaxed);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
use mpris::PlayerFinder;
|
||||||
|
|
||||||
|
|
||||||
|
pub fn print_players(pf: &PlayerFinder) {
|
||||||
|
match pf.find_all() {
|
||||||
|
Ok(players) => {
|
||||||
|
if players.is_empty() {
|
||||||
|
println!("No players found!");
|
||||||
|
} else {
|
||||||
|
for player in players {
|
||||||
|
println!("{}", player.identity());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => println!("{}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,4 +8,9 @@ pub struct Cli {
|
||||||
/// The name of the config file to use.
|
/// The name of the config file to use.
|
||||||
#[arg(short = 'c', long = "config", default_value = "default")]
|
#[arg(short = 'c', long = "config", default_value = "default")]
|
||||||
pub config_file: String,
|
pub config_file: String,
|
||||||
|
/// Enable debug mod.
|
||||||
|
///
|
||||||
|
/// This mode prints all active players to stdout, to allow one to find the appropriate player names to use in the config files.
|
||||||
|
#[arg(short = 'd', long = "debug")]
|
||||||
|
pub debug: bool,
|
||||||
}
|
}
|
||||||
|
|
@ -86,7 +86,7 @@ impl Config {
|
||||||
|
|
||||||
pub fn find_player_priorities_idx(&self, name: &str) -> i32 {
|
pub fn find_player_priorities_idx(&self, name: &str) -> i32 {
|
||||||
match self.player_priorities.iter()
|
match self.player_priorities.iter()
|
||||||
.position(|x| x.to_ascii_lowercase().eq(&name.to_ascii_lowercase())) {
|
.position(|x| x.eq(&name)) {
|
||||||
Some(idx) => idx as i32,
|
Some(idx) => idx as i32,
|
||||||
None => i32::MAX,
|
None => i32::MAX,
|
||||||
}
|
}
|
||||||
|
|
@ -97,6 +97,8 @@ fn ms(str: &str) -> String {
|
||||||
str.to_string()
|
str.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: changed some functions to use case-sensitive matching instead, breaking this
|
||||||
|
// and also all my existing config files. Whoops
|
||||||
fn default_player_prefixes() -> HashMap<String, char> {
|
fn default_player_prefixes() -> HashMap<String, char> {
|
||||||
let mut out: HashMap<String, char> = HashMap::new();
|
let mut out: HashMap<String, char> = HashMap::new();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use mpris::Player;
|
||||||
|
|
||||||
pub struct Data {
|
pub struct Data {
|
||||||
pub current_player: Option<String>,
|
pub current_player: Option<Player>,
|
||||||
pub display_text: HashMap<String, String>,
|
pub display_text: HashMap<String, String>,
|
||||||
pub display_prefix: char,
|
pub display_prefix: char,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,7 @@
|
||||||
use log::{debug, trace};
|
use mpris::{MetadataValue};
|
||||||
use mpris::{PlayerFinder, MetadataValue};
|
|
||||||
|
|
||||||
use crate::structs::{config::{Rating, Config}, data::Data};
|
use crate::structs::{config::{Rating, Config}, data::Data};
|
||||||
|
|
||||||
|
|
||||||
fn update_prefix(cfg: &Config, data: &mut Data) {
|
|
||||||
if data.current_player.is_some() {
|
|
||||||
let c = cfg.player_prefixes.get(&data.current_player.as_ref().unwrap().to_ascii_lowercase());
|
|
||||||
if let Some(char) = c {
|
|
||||||
data.display_prefix = char.clone();
|
|
||||||
trace!("updated prefix to {}", data.display_prefix);
|
|
||||||
} else {
|
|
||||||
data.display_prefix = cfg.player_prefixes.get("default").unwrap_or(&'>').clone();
|
|
||||||
trace!("set prefix to default ({})", data.display_prefix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn value_to_string(v: &MetadataValue, sep: char) -> String {
|
fn value_to_string(v: &MetadataValue, sep: char) -> String {
|
||||||
match v {
|
match v {
|
||||||
MetadataValue::String(v) => v.to_string(),
|
MetadataValue::String(v) => v.to_string(),
|
||||||
|
|
@ -72,36 +57,22 @@ fn rating_to_string(r: Option<&MetadataValue>, map: &Rating) -> Option<String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_message(pf: &PlayerFinder, cfg: &Config, data: &mut Data) {
|
pub fn update_message(cfg: &Config, data: &mut Data) {
|
||||||
if data.current_player.is_some() {
|
if let Some(player) = &data.current_player {
|
||||||
update_prefix(cfg, data);
|
if let Ok(meta) = player.get_metadata() {
|
||||||
let name = &data.current_player.as_ref().unwrap();
|
|
||||||
if let Ok(player) = pf.find_by_name(name) {
|
|
||||||
debug!("found player!");
|
|
||||||
if let Ok(m) = player.get_metadata() {
|
|
||||||
debug!("got metadata!");
|
|
||||||
for field in &cfg.metadata_fields {
|
for field in &cfg.metadata_fields {
|
||||||
if field.field.eq("xesam:userRating") || field.field.eq("xesam:autoRating") {
|
|
||||||
let key = field.field.clone();
|
let key = field.field.clone();
|
||||||
let string = rating_to_string(m.get(&key), &cfg.rating_icons);
|
if field.field.eq("xesam:userRating") {
|
||||||
if let Some(str) = string {
|
if let Some(rating_string) = rating_to_string(meta.get(&key), &cfg.rating_icons) {
|
||||||
data.display_text.insert(key, str);
|
data.display_text.insert(key, rating_string);
|
||||||
} else {
|
} else {
|
||||||
data.display_text.remove(&key);
|
data.display_text.remove(&key);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let key = field.field.clone();
|
match meta.get(&key) {
|
||||||
match m.get(&key) {
|
Some(value) => data.display_text.insert(key, value_to_string(value, cfg.array_separator)),
|
||||||
Some(value) => {
|
None => data.display_text.insert(key, format!("No {}", field.field.clone().trim_start_matches("xesam:"))),
|
||||||
debug!("inserting {}: '{}'", key, value_to_string(value, cfg.array_separator));
|
};
|
||||||
data.display_text.insert(key, value_to_string(value, cfg.array_separator));
|
|
||||||
},
|
|
||||||
None => {
|
|
||||||
debug!("field {} is empty!", key);
|
|
||||||
data.display_text.insert(key, format!("No {}", field.field.clone().trim_start_matches("xesam:")));
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,17 @@
|
||||||
use mpris::PlayerFinder;
|
use log::trace;
|
||||||
|
use mpris::{PlayerFinder, Metadata, Player};
|
||||||
use crate::structs::{data::Data, config::Config};
|
use crate::structs::{data::Data, config::Config};
|
||||||
|
|
||||||
|
fn update_prefix(cfg: &Config, data: &mut char, name: &str) {
|
||||||
|
if let Some(char) = cfg.player_prefixes.get(name) {
|
||||||
|
*data = char.clone();
|
||||||
|
trace!("updated prefix to {}", data);
|
||||||
|
} else {
|
||||||
|
*data = cfg.player_prefixes.get("default").unwrap_or(&'>').clone();
|
||||||
|
trace!("set prefix to default ({})", data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn update_players(
|
pub fn update_players(
|
||||||
pf: &PlayerFinder,
|
pf: &PlayerFinder,
|
||||||
cfg: &Config,
|
cfg: &Config,
|
||||||
|
|
@ -10,31 +21,30 @@ pub fn update_players(
|
||||||
if players.is_empty() {
|
if players.is_empty() {
|
||||||
data.current_player = None;
|
data.current_player = None;
|
||||||
} else {
|
} else {
|
||||||
let mut active: Vec<(i32, String)> = Vec::new();
|
let mut active: Vec<(i32, Player)> = Vec::new();
|
||||||
for player in players {
|
for player in players {
|
||||||
if let Ok(mpris::PlaybackStatus::Playing) = player.get_playback_status() {
|
if let Ok(mpris::PlaybackStatus::Playing) = player.get_playback_status() {
|
||||||
let name = player.identity();
|
let idx = cfg.find_player_priorities_idx(player.identity());
|
||||||
let idx = cfg.find_player_priorities_idx(name);
|
active.push((idx, player));
|
||||||
active.push((idx, name.to_owned()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !active.is_empty() {
|
if !active.is_empty() {
|
||||||
data.current_player = Some(get_lowest(&active));
|
let cur = get_lowest(&mut active);
|
||||||
|
update_prefix(cfg, &mut data.display_prefix, cur.identity());
|
||||||
|
data.current_player = Some(cur);
|
||||||
} else {
|
} else {
|
||||||
data.current_player = None;
|
data.current_player = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_lowest(v: &Vec<(i32, String)>) -> String {
|
fn get_lowest(v: &mut Vec<(i32, Player)>) -> Player {
|
||||||
let mut out = String::new();
|
let mut lowest_index = i32::MAX; //FIXME: use options here instead, also fixes a bug
|
||||||
let mut lowest_index = i32::MAX;
|
for (v_id, _) in v.into_iter() {
|
||||||
for (v_id, v_str) in v.iter() {
|
if v_id < &mut lowest_index {
|
||||||
if v_id < &lowest_index {
|
|
||||||
out = v_str.to_owned();
|
|
||||||
lowest_index = *v_id;
|
lowest_index = *v_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out
|
v.swap_remove(lowest_index as usize).1
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue