#[macro_use] extern crate serde_derive; #[macro_use] extern crate lazy_static; #[macro_use] extern crate log; mod brainz; use mpris::{PlayerFinder,Event}; use failure::Error; use std::time::Duration; const DELAY_FIND_PLAYER : Duration = Duration::from_millis(1000); fn main() -> Result<(), Error> { let env = env_logger::Env::default().default_filter_or("info"); env_logger::Builder::from_env(env).init(); 'main_loop: loop { let player = PlayerFinder::new() .expect("Could not connect to D-Bus") .find_active(); if let Ok(player) = player { info!("Connected to player: {}{}", player.bus_name().to_string(), player.unique_name()); let events = player.events(); if events.is_err() { error!("Could not start event stream!"); // add a delay so we don't run too hot here ::std::thread::sleep(DELAY_FIND_PLAYER); continue 'main_loop; } 'event_loop: for event in events.unwrap() { match event { Ok(event) => { debug!("MPRIS event: {:#?}", event); match &event { Event::PlayerShutDown => { info!("Player shut down"); break 'event_loop; }, Event::TrackChanged(metadata) => { let title = metadata.title().unwrap_or(""); info!("--- new track : {} ---", title); debug!("{:#?}", event); if title.is_empty() { warn!("!!! Spotify is giving us garbage - empty metadata struct !!!"); // wait for next event continue 'event_loop; } 'artists_loop: for ar in metadata.artists().into_iter().chain(metadata.artists()) { for a in ar { info!("Checking artist: {}", a); let verdict = brainz::artist_sucks(&a); match verdict { Ok(verdict) => { if verdict { if player.can_go_next().unwrap_or(false) { info!(">>>>>> SKIP >>>>>>"); if player.next().is_err() { break 'artists_loop; } } else { info!("<><><> STOP <><><>"); if player.pause().is_err() { break 'artists_loop; } } // we add a delay here to prevent going insane on rap playlists ::std::thread::sleep(Duration::from_millis(1000)); } else { info!("Good artist, let it play"); } }, Err(e) => { error!("Something went wrong: {}", e); info!("Letting to play"); } } } } }, _ => { debug!("Event not handled."); } } }, Err(err) => { error!("D-Bus error: {}. Aborting.", err); break 'event_loop; } } } info!("Event stream ended - player likely shut down"); } else { debug!("No player found, waiting..."); } ::std::thread::sleep(DELAY_FIND_PLAYER); } }