private async Task GeniusSearch(Song s, List <Song> geniusTemp) { callsMade++; Log(Type.Info, "Starting geniusSearch"); string results = await HttpRequests.GetRequest(GeniusSearchUrl + s.Artist + " - " + s.Title, GeniusAuthHeader); if (results == null) { results = await HttpRequests.GetRequest(GeniusSearchUrl + s.Artist + " - " + s.Title, GeniusAuthHeader); } JObject parsed = JObject.Parse(results); IList <JToken> parsedList = parsed["response"]["hits"].Children().ToList(); foreach (JToken result in parsedList) { string resultTitle = (string)result["result"]["title"]; string resultArtist = (string)result["result"]["primary_artist"]["name"]; if ((Text.Distance(resultTitle, s.Title) <= maxDistance && Text.Distance(resultArtist, s.Artist) <= maxDistance) || resultTitle.Contains(s.Title) && resultArtist.Contains(s.Artist)) { string path = Path.Combine(ApplicationPath, savedLyricsLocation, (string)result["result"]["primary_artist"]["name"] + savedSeparator + (string)result["result"]["title"] + ".txt"); if (!File.Exists(path)) { Log(Type.Info, "Song found! Adding to geniusTemp"); Song song = new Song() { Title = (string)result["result"]["title"], Artist = (string)result["result"]["primary_artist"]["name"], Cover = (string)result["result"]["song_art_image_thumbnail_url"], Header = (string)result["result"]["header_image_url"], ApiPath = (string)result["result"]["api_path"], Path = (string)result["result"]["path"] }; geniusTemp.Add(song); break; } else { Log(Type.Info, "Song found but already downloaded"); break; } } } completedTasks++; Log(Type.Event, "completedTasks = " + completedTasks); }
public static async Task <List <SongBundle> > GetSearchResults(string query) { string results = await HttpRequests.GetRequest(GeniusSearchUrl + Uri.EscapeUriString(query), GeniusAuthHeader); JObject parsed = JObject.Parse(results); IList <JToken> parsedList = parsed["response"]?["hits"]?.Children().ToList(); List <SongBundle> resultsList = new List <SongBundle>(); if (parsedList != null && parsedList.Count != 0) { foreach (JToken result in parsedList) { Song song = new Song { Id = (int)result["result"]?["id"], Title = (string)result["result"]?["title"], Artist = (string)result["result"]?["primary_artist"]?["name"], Cover = (string)result["result"]?["song_art_image_thumbnail_url"], Header = (string)result["result"]?["header_image_url"], ApiPath = (string)result["result"]?["api_path"], Path = (string)result["result"]?["path"] }; RomanizedSong rSong = new RomanizedSong(); if (Prefs.GetBoolean("romanize_search", false)) { rSong = await JapaneseTools.RomanizeSong(song, false); } resultsList.Add(new SongBundle(song, rSong)); } return(resultsList); } resultsList = new List <SongBundle>(); return(resultsList); }
private async Task GetDetails(string apiPath) { callsMade++; Log(Type.Info, "Starting getDetails operation"); string results = await HttpRequests.GetRequest(GeniusApiUrl + apiPath, GeniusAuthHeader); if (results == null) { Log(Type.Processing, "Returned null, calling API again..."); results = await HttpRequests.GetRequest(GeniusApiUrl + apiPath, GeniusAuthHeader); } JObject parsed = JObject.Parse(results); Song song = new Song() { Title = (string)parsed["response"]["song"]["title"], Artist = (string)parsed["response"]["song"]["primary_artist"]["name"], Album = (string)parsed.SelectToken("response.song.album.name"), Header = (string)parsed["response"]["song"]["header_image_url"], Cover = (string)parsed["response"]["song"]["song_art_image_url"], ApiPath = (string)parsed["response"]["song"]["api_path"], Path = (string)parsed["response"]["song"]["path"] }; Log(Type.Processing, "Created new Song variable"); if (parsed["response"]["song"]["featured_artists"].HasValues) { Log(Type.Info, "Track has featured artists"); IList <JToken> parsedList = parsed["response"]["song"]["featured_artists"].Children().ToList(); song.FeaturedArtist = "feat. "; foreach (JToken artist in parsedList) { if (song.FeaturedArtist == "feat. ") { song.FeaturedArtist += artist["name"].ToString(); } else { song.FeaturedArtist += ", " + artist["name"]; } } } else { Log(Type.Info, "Track does not have featured artists"); song.FeaturedArtist = ""; } string downloadedLyrics; HtmlWeb web = new HtmlWeb(); Log(Type.Processing, "Trying to load page"); HtmlDocument doc = await web.LoadFromWebAsync("https://genius.com" + song.Path); Log(Type.Info, "Loaded Genius page"); HtmlNode lyricsBody = doc.DocumentNode.SelectSingleNode("//div[@class='lyrics']"); downloadedLyrics = Regex.Replace(lyricsBody.InnerText, @"^\s*", ""); downloadedLyrics = Regex.Replace(downloadedLyrics, @"[\s]+$", ""); song.Lyrics = downloadedLyrics; await SaveSongLyrics(song); Log(Type.Info, "Finished saving!"); completedTasks++; Log(Type.Info, "Completed getDetails task for " + song.ApiPath); }
public static async Task <SongBundle> GetSongDetails(SongBundle song) { Log(Logging.Type.Info, "Starting GetSongDetails operation"); string results = await HttpRequests.GetRequest(GeniusApiUrl + song.Normal.ApiPath, GeniusAuthHeader); JObject parsed = JObject.Parse(results); parsed = (JObject)parsed["response"]?["song"]; //Change root to song Song fromJson = new Song { Title = (string)parsed?.SelectToken("title") ?? "", Artist = (string)parsed?.SelectToken("primary_artist.name") ?? "", Album = (string)parsed?.SelectToken("album.name") ?? "", Header = (string)parsed?.SelectToken("header_image_url") ?? "", Cover = (string)parsed?.SelectToken("song_art_image_url") ?? "", ApiPath = (string)parsed?.SelectToken("api_path") ?? "", Path = (string)parsed?.SelectToken("path") ?? "" }; song.Normal = fromJson; if (parsed != null && parsed["featured_artists"].HasValues) { IList <JToken> parsedList = parsed["featured_artists"].Children().ToList(); song.Normal.FeaturedArtist = "feat. "; foreach (JToken artist in parsedList) { if (song.Normal.FeaturedArtist == "feat. ") { song.Normal.FeaturedArtist += artist["name"]?.ToString(); } else { song.Normal.FeaturedArtist += ", " + artist["name"]; } } Log(Logging.Type.Processing, "Added featured artists to song"); } else { song.Normal.FeaturedArtist = ""; } //Execute all Japanese transliteration tasks at once if (Prefs.GetBoolean("auto_romanize_details", true) && song.Normal.Title.ContainsJapanese() || song.Normal.Artist.ContainsJapanese() || song.Normal.Album.ContainsJapanese()) { Task <string> awaitTitle = song.Normal.Title.StripJapanese(); Task <string> awaitArtist = song.Normal.Artist.StripJapanese(); Task <string> awaitAlbum = song.Normal.Album.StripJapanese(); await Task.WhenAll(awaitTitle, awaitArtist, awaitAlbum); RomanizedSong romanized = new RomanizedSong(); // This snippet is the same in GetAndShowLyrics song.Romanized ??= romanized; romanized.Title = await awaitTitle; romanized.Artist = await awaitArtist; romanized.Album = await awaitAlbum; romanized.Id = song.Normal.Id; song.Romanized = romanized; song.Normal.Romanized = true; Log(Logging.Type.Event, "Romanized song info with ID " + song.Normal.Id); Analytics.TrackEvent("Romanized song info", new Dictionary <string, string> { { "SongID", song.Normal.Id.ToString() } }); } else { song.Romanized = null; } return(song); }
private async Task GetAndCompareResults(Song ntfSong) { //set previous song variable now so that it won't be called again in a short period of time previousSong = ntfSong; Log(Type.Info, "Starting async GetSearchResults operation"); // strip song for things that interfere search. making a separate // Song object makes sure that one search is as broad as possible, so // a song with (Remix) on the title would still appear if we searched // without (Remix) tag Song stripped = StripSongForSearch(ntfSong); string results = await HttpRequests.GetRequest(GeniusSearchUrl + stripped.Artist + " - " + stripped.Title, GeniusAuthHeader); //search on genius JObject parsed = JObject.Parse(results); IList <JToken> parsedList = parsed["response"]?["hits"]?.Children().ToList(); if (parsedList != null) { Log(Type.Info, $"Parsed results into list with size {parsedList.Count}"); List <Song> likenessRanking = new List <Song>(); Song mostLikely; //calculate likeness and add to list, which will be sorted by ascending likeness if (parsedList.Count == 0) { mostLikely = new Song(); Log(Type.Info, "No search results!"); } else if (parsedList.Count == 1) { Log(Type.Info, "Search returned 1 result"); mostLikely = new Song() { Id = (int)parsedList[0]["result"]?["id"], Title = (string)parsedList[0]["result"]?["title"], Artist = (string)parsedList[0]["result"]?["primary_artist"]?["name"], Cover = (string)parsedList[0]["result"]?["song_art_image_thumbnail_url"], Header = (string)parsedList[0]["result"]?["header_image_url"], ApiPath = (string)parsedList[0]["result"]?["api_path"], Path = (string)parsedList[0]["result"]?["path"] }; mostLikely.Likeness = await CalculateLikeness(mostLikely, ntfSong, 0); //index is 0 since this is the only result } else { foreach (JToken result in parsedList) { Song resultSong = new Song() { Id = (int)result["result"]?["id"], Title = (string)result["result"]?["title"], Artist = (string)result["result"]?["primary_artist"]?["name"], Cover = (string)result["result"]?["song_art_image_thumbnail_url"], Header = (string)result["result"]?["header_image_url"], ApiPath = (string)result["result"]?["api_path"], Path = (string)result["result"]?["path"] }; Log(Type.Processing, $"Evaluating song {resultSong.Title} by {resultSong.Artist}"); int index = parsedList.IndexOf(result); resultSong.Likeness = await CalculateLikeness(resultSong, ntfSong, index); likenessRanking.Add(resultSong); } likenessRanking = likenessRanking.OrderBy(o => o.Likeness).ToList(); mostLikely = likenessRanking.First(); } //separated this to keep this method shorter HandleChosenSong(mostLikely); } }