From 90eca9e76a20d30f21b89aecea4f7d67cc20bd8e Mon Sep 17 00:00:00 2001 From: Thord Johansson Date: Tue, 18 Jun 2024 23:40:12 +0200 Subject: [PATCH] Enhance config handling and album art logic - Refactored variable names for clarity, changing `data` to `config_data` to better indicate its purpose related to configuration settings. - Significantly enhanced the album art determination logic to prioritize MusicBrainz data when configured, with a fallback to YouTube thumbnails if necessary. - Introduced `FindMusicBrainzRelease` method for searching MusicBrainz releases based on the release name, aiming for exact alphanumeric matches or the highest scoring match. - Added `EqualsAlphanumeric` utility method for accurate alphanumeric string comparisons, supporting the MusicBrainz release search functionality. --- Program.cs | 87 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 64 insertions(+), 23 deletions(-) diff --git a/Program.cs b/Program.cs index c353c01..7315613 100644 --- a/Program.cs +++ b/Program.cs @@ -44,9 +44,9 @@ public class LbzRpcService throw new ApplicationException("Configuration file not found. Please create a config.ini file with your tokens and user information."); } - IniData data = config.ReadFile("config.ini"); + IniData config_data = config.ReadFile("config.ini"); listenBrainz = new ListenBrainz(); - client = new DiscordRpcClient(data["general"]["discord_token"]); + client = new DiscordRpcClient(config_data["general"]["discord_token"]); void InitializeDiscordRpc() { @@ -84,8 +84,8 @@ public class LbzRpcService continue; } - var username = data["general"]["listenbrainz_username"]; - var ignoredPlayers = data["general"]["ignored_sources"].Split(",", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + var username = config_data["general"]["listenbrainz_username"]; + var ignoredPlayers = config_data["general"]["ignored_sources"].Split(",", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); var listen = listenBrainz.GetPlayingNow(username); if (listen != null) @@ -154,34 +154,45 @@ public class LbzRpcService buttons.Add(new Button() { Label = $"{username} on ListenBrainz", Url = $"https://listenbrainz.org/user/{username}" }); - if (listenData.AdditionalInfo?.OriginUrl?.ToString().Contains("youtube") == true - || listenData.AdditionalInfo?.OriginUrl?.ToString().Contains("youtu.be") == true) + string? newAlbumArt = null; + + if (config_data["general"]["prioritise_musicbrainz"] == "true" && listenData.AdditionalInfo?.ReleaseId != null) { - var youtubeId = GetYoutubeId(listenData.AdditionalInfo.OriginUrl); - albumArtUrl = "https://img.youtube.com/vi/" + youtubeId + "/0.jpg"; + newAlbumArt = "https://coverartarchive.org/release/" + listenData.AdditionalInfo?.ReleaseId + "/front-250.jpg"; } - else if (listenData.AdditionalInfo?.ReleaseId != null) + else if (config_data["general"]["prioritise_musicbrainz"] == "true" && listenData.Release != null) { - albumArtUrl = "https://coverartarchive.org/release/" + listenData.AdditionalInfo?.ReleaseId + "/front-250.jpg"; - } - else if (listenData.Release != null) - { - Console.WriteLine("Searching for release {0} on MusicBrainz", listenData.Release); - Query q = new("LBZ-DRPC", new Version(1, 0, 0)); - var release = q.FindReleases(listenData.Release, 1).Results?.FirstOrDefault(); - if (release != null && release?.Item?.CoverArtArchive != null) - { - albumArtUrl = "https://coverartarchive.org/release/" + release?.Item.Id + "/front-250.jpg"; - } + var release = FindMusicBrainzRelease(listenData.Release); + newAlbumArt = "https://coverartarchive.org/release/" + release?.Item.Id + "/front-250.jpg"; } - Console.WriteLine("Album art URL: " + albumArtUrl); + if (newAlbumArt == null) + { + if ((listenData.AdditionalInfo?.OriginUrl?.ToString().Contains("youtube") == true + || listenData.AdditionalInfo?.OriginUrl?.ToString().Contains("youtu.be") == true) + && GetYoutubeId(listenData.AdditionalInfo.OriginUrl) != null) + { + newAlbumArt = "https://img.youtube.com/vi/" + GetYoutubeId(listenData.AdditionalInfo.OriginUrl) + "/0.jpg"; + } + else if (listenData.AdditionalInfo?.ReleaseId != null) + { + newAlbumArt = "https://coverartarchive.org/release/" + listenData.AdditionalInfo?.ReleaseId + "/front-250.jpg"; + } + else if (listenData.Release != null) + { + var release = FindMusicBrainzRelease(listenData.Release); + newAlbumArt = "https://coverartarchive.org/release/" + release?.Item.Id + "/front-250.jpg"; + } + } + + Console.WriteLine("Album art URL: " + (newAlbumArt ?? "(none)")); + albumArtUrl = newAlbumArt ?? ""; } client.SetPresence(new RichPresence() { Details = $"{listenData.Name}", - State = (listenData.Release != null && listenData.Release != listenData.Name) ? $"{listenData.Artist} ({listenData.Release})" : listenData.Artist, + State = (listenData.Release != null && listenData.Release != listenData.Name) ? $"{listenData.Release} ({listenData.Artist})" : listenData.Artist, Buttons = buttons.ToArray(), Assets = new Assets() { @@ -204,7 +215,7 @@ public class LbzRpcService client.ClearPresence(); } - var interval = int.Parse(data["general"]["poll_interval"]); + var interval = int.Parse(config_data["general"]["poll_interval"]); while (interval > 0 && running) { Thread.Sleep(1000); @@ -213,6 +224,36 @@ public class LbzRpcService } } + private ISearchResult? FindMusicBrainzRelease(string release) + { + Console.WriteLine("Searching for release {0} on MusicBrainz", release); + Query q = new("LBZ-DRPC", new Version(1, 0, 0)); + var results = q.FindReleases(release, 5).Results; + + if (results != null && results.Any()) + { + // Find the result with the exact release title + var exactMatch = results.FirstOrDefault(r => EqualsAlphanumeric(r.Item.Title, release)); + if (exactMatch != null) + { + Console.WriteLine("Found match (alphanumeric): {0}", release); + return exactMatch; + } + + // If exact match not found, return the result with the highest score + var highestScore = results.OrderByDescending(r => r.Score).FirstOrDefault(); + Console.WriteLine("Found match (highest scoring): {0}", release); + return highestScore; + } + + return null; + } + + private bool EqualsAlphanumeric(string? a, string b) + { + return a?.Where(b => char.IsLetterOrDigit(b) || char.IsWhiteSpace(b)).SequenceEqual(b.Where(c => char.IsLetterOrDigit(c) || char.IsWhiteSpace(c))) == true; + } + private string? GetYoutubeId(Uri originUrl) { if (originUrl.ToString().Contains("youtu.be"))