|
|
@ -18,8 +18,11 @@ use std::collections::HashMap; |
|
|
|
#[derive(Serialize, Deserialize, Debug)] |
|
|
|
#[derive(Serialize, Deserialize, Debug)] |
|
|
|
#[serde(default)] |
|
|
|
#[serde(default)] |
|
|
|
pub struct BlacklistConf { |
|
|
|
pub struct BlacklistConf { |
|
|
|
|
|
|
|
/// Literal tags to reject
|
|
|
|
pub tag: Vec<String>, |
|
|
|
pub tag: Vec<String>, |
|
|
|
|
|
|
|
/// Tag sub-strings to reject (must be a whole word)
|
|
|
|
pub tag_partial: Vec<String>, |
|
|
|
pub tag_partial: Vec<String>, |
|
|
|
|
|
|
|
/// Artists to reject
|
|
|
|
pub artist: Vec<String>, |
|
|
|
pub artist: Vec<String>, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -41,7 +44,9 @@ impl Default for BlacklistConf { |
|
|
|
#[derive(Serialize, Deserialize, Debug)] |
|
|
|
#[derive(Serialize, Deserialize, Debug)] |
|
|
|
#[serde(default)] |
|
|
|
#[serde(default)] |
|
|
|
pub struct WhiteList { |
|
|
|
pub struct WhiteList { |
|
|
|
|
|
|
|
/// Tags to allow despite e.g. a substring match
|
|
|
|
pub tag: Vec<String>, |
|
|
|
pub tag: Vec<String>, |
|
|
|
|
|
|
|
/// Artists to allow
|
|
|
|
pub artist: Vec<String>, |
|
|
|
pub artist: Vec<String>, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -59,6 +64,8 @@ impl Default for WhiteList { |
|
|
|
pub struct Config { |
|
|
|
pub struct Config { |
|
|
|
/// Logging - trace, debug, (info), warning, error
|
|
|
|
/// Logging - trace, debug, (info), warning, error
|
|
|
|
pub logging: String, |
|
|
|
pub logging: String, |
|
|
|
|
|
|
|
/// Players to handle (empty = all)
|
|
|
|
|
|
|
|
pub allowed_players: Vec<String>, |
|
|
|
/// Blacklists
|
|
|
|
/// Blacklists
|
|
|
|
pub blacklist: BlacklistConf, |
|
|
|
pub blacklist: BlacklistConf, |
|
|
|
/// Whitelist (overrides blacklist)
|
|
|
|
/// Whitelist (overrides blacklist)
|
|
|
@ -81,6 +88,7 @@ impl Default for Config { |
|
|
|
fn default() -> Self { |
|
|
|
fn default() -> Self { |
|
|
|
Self { |
|
|
|
Self { |
|
|
|
logging: "info".to_owned(), |
|
|
|
logging: "info".to_owned(), |
|
|
|
|
|
|
|
allowed_players: vec![], |
|
|
|
blacklist: BlacklistConf::default(), |
|
|
|
blacklist: BlacklistConf::default(), |
|
|
|
whitelist: WhiteList::default(), |
|
|
|
whitelist: WhiteList::default(), |
|
|
|
artist_min_score: 95, |
|
|
|
artist_min_score: 95, |
|
|
@ -137,12 +145,20 @@ fn main() -> Result<(), Error> { |
|
|
|
|
|
|
|
|
|
|
|
'main_loop: |
|
|
|
'main_loop: |
|
|
|
loop { |
|
|
|
loop { |
|
|
|
|
|
|
|
// XXX this picks the first player, which isn't always ideal - see mpris/src/find.rs
|
|
|
|
let player = PlayerFinder::new() |
|
|
|
let player = PlayerFinder::new() |
|
|
|
.expect("Could not connect to D-Bus") |
|
|
|
.expect("Could not connect to D-Bus") |
|
|
|
.find_active(); |
|
|
|
.find_active(); |
|
|
|
|
|
|
|
|
|
|
|
if let Ok(player) = player { |
|
|
|
if let Ok(player) = player { |
|
|
|
info!("Connected to player: {}{}", player.bus_name().to_string(), player.unique_name()); |
|
|
|
let player_name = player.bus_name().to_string(); |
|
|
|
|
|
|
|
if !config.allowed_players.is_empty() && !config.allowed_players.contains(&player_name) { |
|
|
|
|
|
|
|
debug!("Ignoring player {}", player_name); |
|
|
|
|
|
|
|
::std::thread::sleep(Duration::from_millis(config.player_find_interval_ms)); |
|
|
|
|
|
|
|
continue 'main_loop; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
info!("Connected to player: {}{}", player_name, player.unique_name()); |
|
|
|
|
|
|
|
|
|
|
|
let events = player.events(); |
|
|
|
let events = player.events(); |
|
|
|
if events.is_err() { |
|
|
|
if events.is_err() { |
|
|
|