using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Providers.Music { public class ArtistInfoFromSongProvider : BaseMetadataProvider { public ArtistInfoFromSongProvider(ILogManager logManager, IServerConfigurationManager configurationManager) : base(logManager, configurationManager) { } public override bool Supports(BaseItem item) { return item is MusicArtist; } protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo) { var artist = (MusicArtist)item; if (!artist.IsAccessedByName) { // If song metadata has changed if (GetComparisonData(artist) != providerInfo.FileStamp) { return true; } } return base.NeedsRefreshInternal(item, providerInfo); } /// <summary> /// Gets the data. /// </summary> /// <param name="artist">The artist.</param> /// <returns>Guid.</returns> private Guid GetComparisonData(MusicArtist artist) { var songs = artist.RecursiveChildren.OfType<Audio>().ToList(); return GetComparisonData(songs); } private Guid GetComparisonData(IEnumerable<Audio> songs) { var genres = songs.SelectMany(i => i.Genres) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); return string.Join(string.Empty, genres.OrderBy(i => i).ToArray()).GetMD5(); } public override Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) { var artist = (MusicArtist)item; if (!artist.IsAccessedByName) { var songs = artist.RecursiveChildren.OfType<Audio>().ToList(); if (!item.LockedFields.Contains(MetadataFields.Genres)) { artist.Genres = songs.SelectMany(i => i.Genres) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); } providerInfo.FileStamp = GetComparisonData(songs); } SetLastRefreshed(item, DateTime.UtcNow, providerInfo); return TrueTaskResult; } public override MetadataProviderPriority Priority { get { return MetadataProviderPriority.Second; } } } }