diff options
| author | Shadowghost <Ghost_of_Stone@web.de> | 2026-07-23 22:54:26 +0200 |
|---|---|---|
| committer | Shadowghost <Ghost_of_Stone@web.de> | 2026-07-23 22:54:26 +0200 |
| commit | 04e4505402b3f616fe9484f6bf0895ab68971176 (patch) | |
| tree | c278dd2b2c4c81d4f93d1847187c592874b5698b | |
| parent | f28fa563c9b6e6317e7fc7d54268e637a7ed09db (diff) | |
Fix AudioDB metadata fetching
3 files changed, 106 insertions, 44 deletions
diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index a438a94c40..39aebd46e8 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -1038,6 +1038,11 @@ namespace MediaBrowser.Providers.Manager target.OriginalTitle = source.OriginalTitle; } + if (replaceData || string.IsNullOrEmpty(target.HomePageUrl)) + { + target.HomePageUrl = source.HomePageUrl; + } + if (replaceData || string.IsNullOrEmpty(target.OriginalLanguage)) { target.OriginalLanguage = source.OriginalLanguage; diff --git a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistImageProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistImageProvider.cs index 88730f34d2..28cfc8f9a4 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistImageProvider.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistImageProvider.cs @@ -3,32 +3,24 @@ #pragma warning disable CS1591 using System.Collections.Generic; -using System.IO; using System.Net.Http; -using System.Text.Json; using System.Threading; using System.Threading.Tasks; -using Jellyfin.Extensions.Json; using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.IO; using MediaBrowser.Model.Providers; namespace MediaBrowser.Providers.Plugins.AudioDb { public class AudioDbArtistImageProvider : IRemoteImageProvider, IHasOrder { - private readonly IServerConfigurationManager _config; private readonly IHttpClientFactory _httpClientFactory; - private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options; - public AudioDbArtistImageProvider(IServerConfigurationManager config, IHttpClientFactory httpClientFactory) + public AudioDbArtistImageProvider(IHttpClientFactory httpClientFactory) { - _config = config; _httpClientFactory = httpClientFactory; } @@ -54,22 +46,14 @@ namespace MediaBrowser.Providers.Plugins.AudioDb /// <inheritdoc /> public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken) { - if (item.TryGetProviderId(MetadataProvider.MusicBrainzArtist, out var id)) - { - await AudioDbArtistProvider.Current.EnsureArtistInfo(id, cancellationToken).ConfigureAwait(false); - - var path = AudioDbArtistProvider.GetArtistInfoPath(_config.ApplicationPaths, id); + item.TryGetProviderId(MetadataProvider.MusicBrainzArtist, out var musicBrainzId); + item.TryGetProviderId(MetadataProvider.AudioDbArtist, out var audioDbId); - FileStream jsonStream = AsyncFile.OpenRead(path); - await using (jsonStream.ConfigureAwait(false)) - { - var obj = await JsonSerializer.DeserializeAsync<AudioDbArtistProvider.RootObject>(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false); + var artist = await AudioDbArtistProvider.Current.GetArtist(musicBrainzId, audioDbId, cancellationToken).ConfigureAwait(false); - if (obj is not null && obj.artists is not null && obj.artists.Count > 0) - { - return GetImages(obj.artists[0]); - } - } + if (artist is not null) + { + return GetImages(artist); } return []; diff --git a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs index 216e6eb7e5..3528099260 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs @@ -141,38 +141,92 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public async Task<MetadataResult<MusicArtist>> GetMetadata(ArtistInfo info, CancellationToken cancellationToken) { var result = new MetadataResult<MusicArtist>(); - var id = info.GetMusicBrainzArtistId(); - if (!string.IsNullOrWhiteSpace(id)) + var artist = await GetArtist( + info.GetMusicBrainzArtistId(), + info.GetProviderId(MetadataProvider.AudioDbArtist), + cancellationToken).ConfigureAwait(false); + + if (artist is not null) { - await EnsureArtistInfo(id, cancellationToken).ConfigureAwait(false); + result.Item = new MusicArtist(); + result.HasMetadata = true; + ProcessResult(result.Item, artist, info.MetadataLanguage); + } - var path = GetArtistInfoPath(_config.ApplicationPaths, id); + return result; + } - FileStream jsonStream = AsyncFile.OpenRead(path); - await using (jsonStream.ConfigureAwait(false)) - { - var obj = await JsonSerializer.DeserializeAsync<RootObject>(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false); + /// <summary> + /// Resolves the cached AudioDB artist, preferring the MusicBrainz id and falling back to the AudioDB id. + /// </summary> + /// <param name="musicBrainzId">The MusicBrainz artist id, if known.</param> + /// <param name="audioDbId">The TheAudioDB artist id, if known.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>The matching artist, or <c>null</c> if none could be resolved.</returns> + internal async Task<Artist> GetArtist(string musicBrainzId, string audioDbId, CancellationToken cancellationToken) + { + string path; + if (!string.IsNullOrWhiteSpace(musicBrainzId)) + { + await EnsureArtistInfo(musicBrainzId, cancellationToken).ConfigureAwait(false); + path = GetArtistInfoPath(_config.ApplicationPaths, musicBrainzId); + } + else if (!string.IsNullOrWhiteSpace(audioDbId)) + { + await EnsureArtistInfoByAudioDbId(audioDbId, cancellationToken).ConfigureAwait(false); + path = GetArtistInfoPath(_config.ApplicationPaths, audioDbId); + } + else + { + return null; + } - if (obj is not null && obj.artists is not null && obj.artists.Count > 0) - { - result.Item = new MusicArtist(); - result.HasMetadata = true; - ProcessResult(result.Item, obj.artists[0], info.MetadataLanguage); - } + FileStream jsonStream = AsyncFile.OpenRead(path); + await using (jsonStream.ConfigureAwait(false)) + { + var obj = await JsonSerializer.DeserializeAsync<RootObject>(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false); + + if (obj is not null && obj.artists is not null && obj.artists.Count > 0) + { + return obj.artists[0]; } } - return result; + return null; } private void ProcessResult(MusicArtist item, Artist result, string preferredLanguage) { - // item.HomePageUrl = result.strWebsite; + if (!string.IsNullOrWhiteSpace(result.strWebsite)) + { + item.HomePageUrl = result.strWebsite; + } - if (!string.IsNullOrEmpty(result.strGenre)) + var genres = new List<string>(); + if (!string.IsNullOrWhiteSpace(result.strGenre)) { - item.Genres = new[] { result.strGenre }; + genres.Add(result.strGenre); + } + + if (!string.IsNullOrWhiteSpace(result.strSubGenre)) + { + genres.Add(result.strSubGenre); + } + + if (genres.Count > 0) + { + item.Genres = genres.ToArray(); + } + + if (int.TryParse(result.intFormedYear, NumberStyles.Integer, CultureInfo.InvariantCulture, out var formedYear)) + { + item.ProductionYear = formedYear; + } + + if (!string.IsNullOrWhiteSpace(result.strCountry)) + { + item.ProductionLocations = new[] { result.strCountry }; } item.SetProviderId(MetadataProvider.AudioDbArtist, result.idArtist); @@ -232,13 +286,32 @@ namespace MediaBrowser.Providers.Plugins.AudioDb internal async Task DownloadArtistInfo(string musicBrainzId, CancellationToken cancellationToken) { - cancellationToken.ThrowIfCancellationRequested(); - var url = BaseUrl + "/artist-mb.php?i=" + musicBrainzId; + await DownloadArtistInfo(url, GetArtistInfoPath(_config.ApplicationPaths, musicBrainzId), cancellationToken).ConfigureAwait(false); + } + + internal async Task EnsureArtistInfoByAudioDbId(string audioDbId, CancellationToken cancellationToken) + { + var xmlPath = GetArtistInfoPath(_config.ApplicationPaths, audioDbId); + + var fileInfo = _fileSystem.GetFileSystemInfo(xmlPath); + + if (fileInfo.Exists + && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 2) + { + return; + } + + var url = BaseUrl + "/artist.php?i=" + audioDbId; + await DownloadArtistInfo(url, xmlPath, cancellationToken).ConfigureAwait(false); + } + + private async Task DownloadArtistInfo(string url, string path, CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken).ConfigureAwait(false); response.EnsureSuccessStatusCode(); - var path = GetArtistInfoPath(_config.ApplicationPaths, musicBrainzId); Directory.CreateDirectory(Path.GetDirectoryName(path)); var fileStreamOptions = AsyncFile.WriteOptions; |
