add player whitelist support, enhance readme

master
Ondřej Hruška 5 years ago
parent cf52a3668b
commit 99bad0012d
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 67
      README.md
  2. 6
      rapblock.example.json
  3. 18
      src/main.rs

@ -14,5 +14,68 @@ in the TrackChanged event metadata.
Customization
-------------
You can easily modify this to skip e.g. folk, country or any other genre. Just change the
`BAD_GENRES` list in `src/brainz.rs`.
The daemon loads its config from a JSON file, an example of which is provided as
`rapblock.example.json`. Copy this file (removing `.example`) and customize as desired.
Defaults will be loaded in absence of the config file.
Here is the structure explained (please note that JSON doesn't allow comments,
this is just for demonstration):
```
{
// Blacklist config
"blacklist": {
// Literal tags to reject
"tag": [],
// Tag sub-strings to reject (must be a whole word)
"tag_partial": ["hip-hop", "hip hop", "rap"],
// Artists to reject without even checking tags
"artist": ["Higher Brothers"]
},
// Whitelist config
"whitelist": {
// Tags to allow despite e.g. a substring match
"tag": [],
// Artists to allow unconditionally
"artist": []
},
// Logging - trace, debug, (info), warning, error
"logging": "info",
// Player names to allow (e.g. when we want to block only Spotify songs)
// This does not support multiple players playing at once - always only the first is
// handled.
"allowed_players": [
// spotify player name, as copied from the debug log
// -> Leave this list empty to allow all players!
"org.mpris.MediaPlayer2.spotify"
],
// Min MusicBrainz search score for artist look-up
"artist_min_score": 95,
// Max nr of artists to check per track (limits MusicBrainz request count)
"max_artists_per_track": 3,
// Interval in which the daemon probes DBUS for open MPRIS channels
"player_find_interval_ms": 2500,
// Delay after a skip or allow, e.g. to prevent infinite skip
// chain when someone starts a rap playlist and we block the 'rap' tag
"cooldown_ms": 500,
// Music Brainz API access timeout
"api_timeout_ms": 2000,
// Action to take when the daemon can't figure out if a song is good or not.
// Default is true; change to false if you REALLY hate rap, but it will
// also block good songs by less known artists.
"allow_by_default": true
}
```

@ -1,5 +1,4 @@
{
"logging": "info",
"blacklist": {
"tag": [],
"tag_partial": ["hip-hop", "hip hop", "rap"],
@ -9,9 +8,12 @@
"tag": [],
"artist": []
},
"logging": "info",
"allowed_players": [],
"artist_min_score": 95,
"max_artists_per_track": 3,
"player_find_interval_ms": 2500,
"cooldown_ms": 500,
"api_timeout_ms": 2000
"api_timeout_ms": 2000,
"allow_by_default": true
}

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

Loading…
Cancel
Save