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>, } #[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> } 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 { 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")); } } }