< Summary - Jellyfin

Information
Class: MediaBrowser.Providers.Plugins.AudioDb.AudioDbArtistProvider
Assembly: MediaBrowser.Providers
File(s): /srv/git/jellyfin/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs
Line coverage
14%
Covered lines: 6
Uncovered lines: 35
Coverable lines: 41
Total lines: 290
Line coverage: 14.6%
Branch coverage
0%
Covered branches: 0
Total branches: 24
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_Name()100%210%
get_Order()100%210%
GetSearchResults(...)100%210%
ProcessResult(...)0%420200%
EnsureArtistInfo(...)0%2040%
GetArtistDataPath(...)100%210%
GetArtistDataPath(...)100%210%
GetArtistInfoPath(...)100%210%
GetImageResponse(...)100%210%

File(s)

/srv/git/jellyfin/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs

#LineLine coverage
 1#nullable disable
 2
 3#pragma warning disable CA1034, CS1591, CA1002, SA1028, SA1300
 4
 5using System;
 6using System.Collections.Generic;
 7using System.IO;
 8using System.Linq;
 9using System.Net.Http;
 10using System.Text.Json;
 11using System.Threading;
 12using System.Threading.Tasks;
 13using Jellyfin.Extensions.Json;
 14using MediaBrowser.Common.Configuration;
 15using MediaBrowser.Common.Extensions;
 16using MediaBrowser.Common.Net;
 17using MediaBrowser.Controller.Configuration;
 18using MediaBrowser.Controller.Entities.Audio;
 19using MediaBrowser.Controller.Providers;
 20using MediaBrowser.Model.Entities;
 21using MediaBrowser.Model.IO;
 22using MediaBrowser.Model.Providers;
 23using MediaBrowser.Providers.Music;
 24
 25namespace MediaBrowser.Providers.Plugins.AudioDb
 26{
 27    public class AudioDbArtistProvider : IRemoteMetadataProvider<MusicArtist, ArtistInfo>, IHasOrder
 28    {
 29        private const string ApiKey = "195003";
 30        public const string BaseUrl = "https://www.theaudiodb.com/api/v1/json/" + ApiKey;
 31
 32        private readonly IServerConfigurationManager _config;
 33        private readonly IFileSystem _fileSystem;
 34        private readonly IHttpClientFactory _httpClientFactory;
 2235        private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options;
 36
 37        public AudioDbArtistProvider(IServerConfigurationManager config, IFileSystem fileSystem, IHttpClientFactory http
 38        {
 2239            _config = config;
 2240            _fileSystem = fileSystem;
 2241            _httpClientFactory = httpClientFactory;
 2242            Current = this;
 2243        }
 44
 45        public static AudioDbArtistProvider Current { get; private set; }
 46
 47        /// <inheritdoc />
 048        public string Name => "TheAudioDB";
 49
 50        /// <inheritdoc />
 51        // After musicbrainz
 052        public int Order => 1;
 53
 54        /// <inheritdoc />
 55        public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(ArtistInfo searchInfo, CancellationToken cancellat
 056            => Task.FromResult(Enumerable.Empty<RemoteSearchResult>());
 57
 58        /// <inheritdoc />
 59        public async Task<MetadataResult<MusicArtist>> GetMetadata(ArtistInfo info, CancellationToken cancellationToken)
 60        {
 61            var result = new MetadataResult<MusicArtist>();
 62            var id = info.GetMusicBrainzArtistId();
 63
 64            if (!string.IsNullOrWhiteSpace(id))
 65            {
 66                await EnsureArtistInfo(id, cancellationToken).ConfigureAwait(false);
 67
 68                var path = GetArtistInfoPath(_config.ApplicationPaths, id);
 69
 70                FileStream jsonStream = AsyncFile.OpenRead(path);
 71                await using (jsonStream.ConfigureAwait(false))
 72                {
 73                    var obj = await JsonSerializer.DeserializeAsync<RootObject>(jsonStream, _jsonOptions, cancellationTo
 74
 75                    if (obj is not null && obj.artists is not null && obj.artists.Count > 0)
 76                    {
 77                        result.Item = new MusicArtist();
 78                        result.HasMetadata = true;
 79                        ProcessResult(result.Item, obj.artists[0], info.MetadataLanguage);
 80                    }
 81                }
 82            }
 83
 84            return result;
 85        }
 86
 87        private void ProcessResult(MusicArtist item, Artist result, string preferredLanguage)
 88        {
 89            // item.HomePageUrl = result.strWebsite;
 90
 091            if (!string.IsNullOrEmpty(result.strGenre))
 92            {
 093                item.Genres = new[] { result.strGenre };
 94            }
 95
 096            item.SetProviderId(MetadataProvider.AudioDbArtist, result.idArtist);
 097            item.SetProviderId(MetadataProvider.MusicBrainzArtist, result.strMusicBrainzID);
 98
 099            string overview = null;
 100
 0101            if (string.Equals(preferredLanguage, "de", StringComparison.OrdinalIgnoreCase))
 102            {
 0103                overview = result.strBiographyDE;
 104            }
 0105            else if (string.Equals(preferredLanguage, "fr", StringComparison.OrdinalIgnoreCase))
 106            {
 0107                overview = result.strBiographyFR;
 108            }
 0109            else if (string.Equals(preferredLanguage, "nl", StringComparison.OrdinalIgnoreCase))
 110            {
 0111                overview = result.strBiographyNL;
 112            }
 0113            else if (string.Equals(preferredLanguage, "ru", StringComparison.OrdinalIgnoreCase))
 114            {
 0115                overview = result.strBiographyRU;
 116            }
 0117            else if (string.Equals(preferredLanguage, "it", StringComparison.OrdinalIgnoreCase))
 118            {
 0119                overview = result.strBiographyIT;
 120            }
 0121            else if ((preferredLanguage ?? string.Empty).StartsWith("pt", StringComparison.OrdinalIgnoreCase))
 122            {
 0123                overview = result.strBiographyPT;
 124            }
 125
 0126            if (string.IsNullOrWhiteSpace(overview))
 127            {
 0128                overview = result.strBiographyEN;
 129            }
 130
 0131            item.Overview = (overview ?? string.Empty).StripHtml();
 0132        }
 133
 134        internal Task EnsureArtistInfo(string musicBrainzId, CancellationToken cancellationToken)
 135        {
 0136            var xmlPath = GetArtistInfoPath(_config.ApplicationPaths, musicBrainzId);
 137
 0138            var fileInfo = _fileSystem.GetFileSystemInfo(xmlPath);
 139
 0140            if (fileInfo.Exists
 0141                && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 2)
 142            {
 0143                return Task.CompletedTask;
 144            }
 145
 0146            return DownloadArtistInfo(musicBrainzId, cancellationToken);
 147        }
 148
 149        internal async Task DownloadArtistInfo(string musicBrainzId, CancellationToken cancellationToken)
 150        {
 151            cancellationToken.ThrowIfCancellationRequested();
 152
 153            var url = BaseUrl + "/artist-mb.php?i=" + musicBrainzId;
 154
 155            using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationTo
 156            response.EnsureSuccessStatusCode();
 157            var path = GetArtistInfoPath(_config.ApplicationPaths, musicBrainzId);
 158            Directory.CreateDirectory(Path.GetDirectoryName(path));
 159
 160            var fileStreamOptions = AsyncFile.WriteOptions;
 161            fileStreamOptions.Mode = FileMode.Create;
 162            var xmlFileStream = new FileStream(path, fileStreamOptions);
 163            await using (xmlFileStream.ConfigureAwait(false))
 164            {
 165                await response.Content.CopyToAsync(xmlFileStream, cancellationToken).ConfigureAwait(false);
 166            }
 167        }
 168
 169        /// <summary>
 170        /// Gets the artist data path.
 171        /// </summary>
 172        /// <param name="appPaths">The application paths.</param>
 173        /// <param name="musicBrainzArtistId">The music brainz artist identifier.</param>
 174        /// <returns>System.String.</returns>
 175        private static string GetArtistDataPath(IApplicationPaths appPaths, string musicBrainzArtistId)
 0176            => Path.Combine(GetArtistDataPath(appPaths), musicBrainzArtistId);
 177
 178        /// <summary>
 179        /// Gets the artist data path.
 180        /// </summary>
 181        /// <param name="appPaths">The application paths.</param>
 182        /// <returns>System.String.</returns>
 183        private static string GetArtistDataPath(IApplicationPaths appPaths)
 0184            => Path.Combine(appPaths.CachePath, "audiodb-artist");
 185
 186        internal static string GetArtistInfoPath(IApplicationPaths appPaths, string musicBrainzArtistId)
 187        {
 0188            var dataPath = GetArtistDataPath(appPaths, musicBrainzArtistId);
 189
 0190            return Path.Combine(dataPath, "artist.json");
 191        }
 192
 193        /// <inheritdoc />
 194        public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
 195        {
 0196            throw new NotImplementedException();
 197        }
 198
 199        public class Artist
 200        {
 201            public string idArtist { get; set; }
 202
 203            public string strArtist { get; set; }
 204
 205            public string strArtistAlternate { get; set; }
 206
 207            public object idLabel { get; set; }
 208
 209            public string intFormedYear { get; set; }
 210
 211            public string intBornYear { get; set; }
 212
 213            public object intDiedYear { get; set; }
 214
 215            public object strDisbanded { get; set; }
 216
 217            public string strGenre { get; set; }
 218
 219            public string strSubGenre { get; set; }
 220
 221            public string strWebsite { get; set; }
 222
 223            public string strFacebook { get; set; }
 224
 225            public string strTwitter { get; set; }
 226
 227            public string strBiographyEN { get; set; }
 228
 229            public string strBiographyDE { get; set; }
 230
 231            public string strBiographyFR { get; set; }
 232
 233            public string strBiographyCN { get; set; }
 234
 235            public string strBiographyIT { get; set; }
 236
 237            public string strBiographyJP { get; set; }
 238
 239            public string strBiographyRU { get; set; }
 240
 241            public string strBiographyES { get; set; }
 242
 243            public string strBiographyPT { get; set; }
 244
 245            public string strBiographySE { get; set; }
 246
 247            public string strBiographyNL { get; set; }
 248
 249            public string strBiographyHU { get; set; }
 250
 251            public string strBiographyNO { get; set; }
 252
 253            public string strBiographyIL { get; set; }
 254
 255            public string strBiographyPL { get; set; }
 256
 257            public string strGender { get; set; }
 258
 259            public string intMembers { get; set; }
 260
 261            public string strCountry { get; set; }
 262
 263            public string strCountryCode { get; set; }
 264
 265            public string strArtistThumb { get; set; }
 266
 267            public string strArtistLogo { get; set; }
 268
 269            public string strArtistFanart { get; set; }
 270
 271            public string strArtistFanart2 { get; set; }
 272
 273            public string strArtistFanart3 { get; set; }
 274
 275            public string strArtistBanner { get; set; }
 276
 277            public string strMusicBrainzID { get; set; }
 278
 279            public object strLastFMChart { get; set; }
 280
 281            public string strLocked { get; set; }
 282        }
 283
 284#pragma warning disable CA2227
 285        public class RootObject
 286        {
 287            public List<Artist> artists { get; set; }
 288        }
 289    }
 290}