You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
2.6 KiB
87 lines
2.6 KiB
5 years ago
|
use percent_encoding::{utf8_percent_encode, DEFAULT_ENCODE_SET};
|
||
|
use failure::Error;
|
||
|
use std::io::Read;
|
||
|
use std::time::Duration;
|
||
|
|
||
|
#[derive(Serialize, Deserialize, Debug)]
|
||
|
struct MBArtistQueryResult {
|
||
|
created : String,
|
||
|
count: i32,
|
||
|
offset: i32,
|
||
|
artists: Option<Vec<MBArtist>>,
|
||
|
}
|
||
|
|
||
|
#[derive(Serialize, Deserialize, Debug)]
|
||
|
struct Tag {
|
||
|
count: i32, // negative doesn't make sense, but it sometimes occurs
|
||
|
name: String,
|
||
|
}
|
||
|
|
||
|
#[derive(Serialize, Deserialize, Debug)]
|
||
|
struct MBArtist {
|
||
|
id: String,
|
||
|
score: i32,
|
||
|
name: String,
|
||
|
#[serde(rename="sort-name")]
|
||
|
sort_name: String,
|
||
|
tags: Option<Vec<Tag>>
|
||
|
}
|
||
|
|
||
|
lazy_static! {
|
||
|
static ref BAD_GENRES : Vec<&'static str> = vec![
|
||
|
"hip hop", "hip-hop", "hiphop", "rnb", "rap", "rapper",
|
||
|
"hardcore hip hop", "new york hip hop", "east coast hip hop",
|
||
|
"pop rap"
|
||
|
];
|
||
|
}
|
||
|
|
||
|
pub fn artist_sucks(artist : &str) -> Result<bool, Error> {
|
||
|
let query = utf8_percent_encode(&format!("\"{}\"", artist), DEFAULT_ENCODE_SET).to_string();
|
||
|
let url = format!("https://musicbrainz.org/ws/2/artist?query={}&fmt=json&inc=tags", query);
|
||
|
|
||
|
info!("Querying MusicBrainz for artist \"{}\", query URL: {}", artist, url);
|
||
|
|
||
|
let mut resp = String::new();
|
||
|
|
||
|
reqwest::Client::builder()
|
||
|
.timeout(Duration::from_millis(2000))
|
||
|
.build()?
|
||
|
.get(&url)
|
||
|
.header(reqwest::header::USER_AGENT, "Bad Spotify Song Skipper/0.0.1 ( ondra@ondrovo.com )")
|
||
|
.header(reqwest::header::ACCEPT, "text/json")
|
||
|
.send()?
|
||
|
.read_to_string(&mut resp)?;
|
||
|
|
||
|
debug!("Resp: {}", resp);
|
||
|
|
||
|
let result : MBArtistQueryResult = serde_json::from_str(&resp)?;
|
||
|
|
||
|
info!("Response OK");
|
||
|
debug!("{:#?}", result);
|
||
|
|
||
|
if result.count == 0 {
|
||
|
// not found, let's hope it's OK
|
||
|
warn!("No results!");
|
||
|
return Err(failure::err_msg("Artist not found"));
|
||
|
} else {
|
||
|
info!("Got {} results", result.count);
|
||
|
let artists = result.artists.as_ref().unwrap();
|
||
|
if artists[0].tags.is_some() {
|
||
|
let tags = artists[0].tags.as_ref().unwrap();
|
||
|
let as_vec : Vec<&String> = tags.iter().map(|t| &t.name).collect();
|
||
|
debug!("First artist has tags: {:?}", tags);
|
||
|
for tag in as_vec {
|
||
|
if BAD_GENRES.contains(&tag.as_str()) {
|
||
|
info!("Found a bad tag: {}", tag);
|
||
|
return Ok(true);
|
||
|
}
|
||
|
}
|
||
|
info!("All tags OK");
|
||
|
return Ok(false);
|
||
|
} else {
|
||
|
warn!("No tags, can't determine genre");
|
||
|
return Err(failure::err_msg("Artist found, but has no tags"));
|
||
|
}
|
||
|
}
|
||
|
}
|