add support for getting genre from mpris (experimental)
This commit is contained in:
Generated
+1
@@ -956,6 +956,7 @@ dependencies = [
|
||||
name = "rapblock"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"dbus 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"inotify 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
||||
@@ -17,3 +17,4 @@ log = "0.4"
|
||||
env_logger = "0.6"
|
||||
regex = "1.1.0"
|
||||
inotify = "0.7.0"
|
||||
dbus = "0.6.4"
|
||||
|
||||
+33
-30
@@ -30,6 +30,38 @@ struct MBArtist {
|
||||
|
||||
const VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
/// Check genre; returns true if it's OK
|
||||
pub fn check_genre(config: &crate::Config, genre: &String) -> bool {
|
||||
if config.whitelist.tag.contains(genre) {
|
||||
info!("+ Whitelisted tag \"{}\"", genre);
|
||||
return true;
|
||||
}
|
||||
|
||||
if config.blacklist.tag.contains(genre) {
|
||||
info!("- Blacklisted tag \"{}\"", genre);
|
||||
return false;
|
||||
} else {
|
||||
for substr in config.blacklist.tag_partial.iter() {
|
||||
let re = Regex::new(&format!(r"\b{}\b", regex::escape(substr)));
|
||||
|
||||
let matches = match re {
|
||||
Ok(re) => re.is_match(genre),
|
||||
Err(_) => genre.contains(substr),
|
||||
};
|
||||
|
||||
if matches {
|
||||
info!(
|
||||
"- Blacklisted tag \"{}\" - due to substring \"{}\"",
|
||||
genre, substr
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn check_artist(config: &crate::Config, artist: &str) -> Result<bool, Error> {
|
||||
let query = utf8_percent_encode(&format!("\"{}\"", artist), DEFAULT_ENCODE_SET).to_string();
|
||||
let url = format!(
|
||||
@@ -89,36 +121,7 @@ pub fn check_artist(config: &crate::Config, artist: &str) -> Result<bool, Error>
|
||||
|
||||
info!("Artist #{} - \"{}\" has tags: {:?}", an + 1, a.name, as_vec);
|
||||
'tags: for tag in as_vec {
|
||||
if config.whitelist.tag.contains(tag) {
|
||||
info!("+ Whitelisted tag \"{}\"", tag);
|
||||
continue 'tags;
|
||||
}
|
||||
|
||||
let mut blacklisted = false;
|
||||
if config.blacklist.tag.contains(&tag) {
|
||||
info!("- Blacklisted tag \"{}\"", tag);
|
||||
blacklisted = true;
|
||||
} else {
|
||||
'blacklist: for t in config.blacklist.tag_partial.iter() {
|
||||
let re = Regex::new(&format!(r"\b{}\b", regex::escape(t)));
|
||||
|
||||
let matches = match re {
|
||||
Ok(re) => re.is_match(tag),
|
||||
Err(_) => tag.contains(t),
|
||||
};
|
||||
|
||||
if matches {
|
||||
info!(
|
||||
"- Blacklisted tag \"{}\" - due to substring \"{}\"",
|
||||
tag, t
|
||||
);
|
||||
blacklisted = true;
|
||||
break 'blacklist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if blacklisted {
|
||||
if !check_genre(config, tag) {
|
||||
confidence = true;
|
||||
passed = false;
|
||||
break 'artists;
|
||||
|
||||
+95
-57
@@ -11,6 +11,8 @@ use std::time::Duration;
|
||||
use mpris::Event;
|
||||
use std::collections::HashSet;
|
||||
use failure::Error;
|
||||
use dbus::arg::Variant;
|
||||
use dbus::arg::RefArg;
|
||||
|
||||
mod brainz;
|
||||
mod config_file;
|
||||
@@ -167,6 +169,9 @@ fn main() -> Result<(), Error> {
|
||||
break 'event_loop;
|
||||
}
|
||||
Event::TrackChanged(mut metadata) => {
|
||||
::std::thread::sleep(Duration::from_millis(250));
|
||||
metadata = player.get_metadata().unwrap_or(metadata);
|
||||
|
||||
let mut title = metadata.title().unwrap_or("");
|
||||
info!("--- new track : {} ---", title);
|
||||
|
||||
@@ -185,71 +190,104 @@ fn main() -> Result<(), Error> {
|
||||
}
|
||||
}
|
||||
|
||||
let mut artists = HashSet::new();
|
||||
|
||||
if let Some(aa) = metadata.artists() {
|
||||
for a in aa {
|
||||
artists.insert(a);
|
||||
}
|
||||
}
|
||||
if let Some(aa) = metadata.album_artists() {
|
||||
for a in aa {
|
||||
artists.insert(a);
|
||||
}
|
||||
}
|
||||
|
||||
let mut skip = false;
|
||||
let mut skip = !config.allow_by_default;
|
||||
let mut confidence = false;
|
||||
'artists_loop: for (an, a) in artists
|
||||
.iter()
|
||||
.take(config.max_artists_per_track as usize)
|
||||
.enumerate()
|
||||
{
|
||||
info!("Checking artist #{}: {}", an + 1, a);
|
||||
if let Some(resolution) = artist_cache.get(a.as_str()) {
|
||||
confidence = true;
|
||||
if !resolution {
|
||||
info!("~ result cached: BAD");
|
||||
skip = true;
|
||||
break 'artists_loop;
|
||||
}
|
||||
info!("~ result cached: GOOD");
|
||||
continue 'artists_loop;
|
||||
}
|
||||
|
||||
if config.whitelist.artist.contains(a) {
|
||||
info!("+ Whitelisted artist!");
|
||||
// there may be other co-artists that spoil the song -> don't break yet
|
||||
artist_cache.insert(a.to_string(), true);
|
||||
confidence = true;
|
||||
continue 'artists_loop;
|
||||
}
|
||||
debug!("MPRIS meta: {:#?}", metadata);
|
||||
|
||||
if config.blacklist.artist.contains(a) {
|
||||
info!("- Blacklisted artist!");
|
||||
skip = true;
|
||||
artist_cache.insert(a.to_string(), false);
|
||||
confidence = true;
|
||||
break 'artists_loop;
|
||||
}
|
||||
|
||||
let verdict = brainz::check_artist(&config, &a);
|
||||
match verdict {
|
||||
Ok(allow) => {
|
||||
// try to get genre from the 'rest' map in the metadata struct
|
||||
#[allow(deprecated)] // 2.0.0 will provide some nicer API, hopefully
|
||||
let rest = metadata.rest();
|
||||
let meta_genre : Option<&Variant<Box<RefArg>>> = rest.get("xesam:genre");
|
||||
match meta_genre {
|
||||
Some(variant) => {
|
||||
let b : &RefArg = variant.0.as_ref();
|
||||
if let Some(s) = b.as_str() {
|
||||
info!("Using genre from MPRIS metadata: {}", s);
|
||||
skip = !brainz::check_genre(&config, &s.to_string().to_lowercase());
|
||||
confidence = true;
|
||||
artist_cache.insert(a.to_string(), allow);
|
||||
if allow {
|
||||
info!("Artist passed");
|
||||
} else {
|
||||
} else if let Some(list) = b.as_iter() {
|
||||
debug!("MPRIS contains array of genres");
|
||||
for item in list {
|
||||
if let Some(s) = item.as_str() {
|
||||
info!("Using genre from MPRIS metadata: {}", s);
|
||||
skip = !brainz::check_genre(&config, &s.to_string().to_lowercase());
|
||||
confidence = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
debug!("No MPRIS genre");
|
||||
}
|
||||
};
|
||||
|
||||
if !confidence {
|
||||
let mut artists = HashSet::new();
|
||||
|
||||
if let Some(aa) = metadata.artists() {
|
||||
for a in aa {
|
||||
artists.insert(a);
|
||||
}
|
||||
}
|
||||
if let Some(aa) = metadata.album_artists() {
|
||||
for a in aa {
|
||||
artists.insert(a);
|
||||
}
|
||||
}
|
||||
|
||||
let artists_e = artists
|
||||
.iter()
|
||||
.take(config.max_artists_per_track as usize)
|
||||
.enumerate();
|
||||
|
||||
'artists_loop: for (an, a) in artists_e {
|
||||
info!("Checking artist #{}: {}", an + 1, a);
|
||||
if let Some(resolution) = artist_cache.get(*a) {
|
||||
confidence = true;
|
||||
if !resolution {
|
||||
info!("~ result cached: BAD");
|
||||
skip = true;
|
||||
break 'artists_loop;
|
||||
}
|
||||
info!("~ result cached: GOOD");
|
||||
continue 'artists_loop;
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("Something went wrong: {}", e);
|
||||
// probably no tags, or not found - use the default action
|
||||
artist_cache
|
||||
.insert(a.to_string(), config.allow_by_default);
|
||||
|
||||
if config.whitelist.artist.contains(a) {
|
||||
info!("+ Whitelisted artist!");
|
||||
// there may be other co-artists that spoil the song -> don't break yet
|
||||
artist_cache.insert(a.to_string(), true);
|
||||
confidence = true;
|
||||
continue 'artists_loop;
|
||||
}
|
||||
|
||||
if config.blacklist.artist.contains(a) {
|
||||
info!("- Blacklisted artist!");
|
||||
skip = true;
|
||||
artist_cache.insert(a.to_string(), false);
|
||||
confidence = true;
|
||||
break 'artists_loop;
|
||||
}
|
||||
|
||||
let verdict = brainz::check_artist(&config, &a);
|
||||
match verdict {
|
||||
Ok(allow) => {
|
||||
confidence = true;
|
||||
artist_cache.insert(a.to_string(), allow);
|
||||
if allow {
|
||||
info!("Artist passed");
|
||||
} else {
|
||||
skip = true;
|
||||
break 'artists_loop;
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("Something went wrong: {}", e);
|
||||
// probably no tags, or not found - use the default action
|
||||
artist_cache
|
||||
.insert(a.to_string(), config.allow_by_default);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user