diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
index 485afcaef..1526cf46a 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
@@ -1,5 +1,4 @@
using MediaBrowser.Model.Entities;
-using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
@@ -54,26 +53,6 @@ namespace MediaBrowser.Controller.Entities.Audio
get { return Parent as MusicArtist ?? UnknwonArtist; }
}
- ///
- /// Override to point to first child (song)
- ///
- /// The genres.
- public override List Genres
- {
- get
- {
- return Children
- .OfType()
- .SelectMany(i => i.Genres)
- .Distinct(StringComparer.OrdinalIgnoreCase)
- .ToList();
- }
- set
- {
- base.Genres = value;
- }
- }
-
///
/// Gets or sets the images.
///
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
index bf11403e5..b2fc04873 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Linq;
-using System.Collections.Generic;
-
+
namespace MediaBrowser.Controller.Entities.Audio
{
///
@@ -9,20 +6,5 @@ namespace MediaBrowser.Controller.Entities.Audio
///
public class MusicArtist : Folder
{
- public override List Genres
- {
- get
- {
- return Children
- .OfType()
- .SelectMany(i => i.Genres)
- .Distinct(StringComparer.OrdinalIgnoreCase)
- .ToList();
- }
- set
- {
- base.Genres = value;
- }
- }
}
}
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index d8dec4645..8aef52875 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -543,7 +543,7 @@ namespace MediaBrowser.Controller.Entities
/// Gets or sets the genres.
///
/// The genres.
- public virtual List Genres { get; set; }
+ public List Genres { get; set; }
///
/// Gets or sets the home page URL.
diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
index ce924df06..ad517cefd 100644
--- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj
+++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
@@ -67,6 +67,7 @@
+
diff --git a/MediaBrowser.Providers/Music/ArtistInfoFromSongProvider.cs b/MediaBrowser.Providers/Music/ArtistInfoFromSongProvider.cs
new file mode 100644
index 000000000..b5a3b92f9
--- /dev/null
+++ b/MediaBrowser.Providers/Music/ArtistInfoFromSongProvider.cs
@@ -0,0 +1,90 @@
+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)
+ {
+ // If song metadata has changed
+ if (GetComparisonData((MusicArtist)item) != providerInfo.FileStamp)
+ {
+ return true;
+ }
+
+ return base.NeedsRefreshInternal(item, providerInfo);
+ }
+ ///
+ /// Gets the data.
+ ///
+ /// The artist.
+ /// Guid.
+ private Guid GetComparisonData(MusicArtist artist)
+ {
+ var songs = artist.RecursiveChildren.OfType().ToList();
+
+ return GetComparisonData(songs);
+ }
+
+ private Guid GetComparisonData(List 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 FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken)
+ {
+ var artist = (MusicArtist)item;
+
+ BaseProviderInfo data;
+ if (!item.ProviderData.TryGetValue(Id, out data))
+ {
+ data = new BaseProviderInfo();
+ item.ProviderData[Id] = data;
+ }
+
+ var songs = artist.RecursiveChildren.OfType().ToList();
+
+ if (!item.LockedFields.Contains(MetadataFields.Genres))
+ {
+ artist.Genres = songs.SelectMany(i => i.Genres)
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .ToList();
+ }
+
+ data.FileStamp = GetComparisonData(songs);
+
+ SetLastRefreshed(item, DateTime.UtcNow);
+ return TrueTaskResult;
+ }
+
+ public override MetadataProviderPriority Priority
+ {
+ get { return MetadataProviderPriority.Second; }
+ }
+ }
+}
diff --git a/MediaBrowser.Providers/Music/LastfmArtistProvider.cs b/MediaBrowser.Providers/Music/LastfmArtistProvider.cs
index b01fa1256..526034d5a 100644
--- a/MediaBrowser.Providers/Music/LastfmArtistProvider.cs
+++ b/MediaBrowser.Providers/Music/LastfmArtistProvider.cs
@@ -54,6 +54,15 @@ namespace MediaBrowser.Providers.Music
return base.NeedsRefreshInternal(item, providerInfo);
}
+ ///
+ /// Gets the priority.
+ ///
+ /// The priority.
+ public override MetadataProviderPriority Priority
+ {
+ get { return MetadataProviderPriority.Third; }
+ }
+
private bool HasAltMeta(BaseItem item)
{
return item.LocationType == LocationType.FileSystem && item.ResolveArgs.ContainsMetaFileByName("artist.xml");
diff --git a/MediaBrowser.Providers/Music/LastfmBaseProvider.cs b/MediaBrowser.Providers/Music/LastfmBaseProvider.cs
index 765911383..d5580bb4d 100644
--- a/MediaBrowser.Providers/Music/LastfmBaseProvider.cs
+++ b/MediaBrowser.Providers/Music/LastfmBaseProvider.cs
@@ -79,15 +79,6 @@ namespace MediaBrowser.Providers.Music
}
}
- ///
- /// Gets the priority.
- ///
- /// The priority.
- public override MetadataProviderPriority Priority
- {
- get { return MetadataProviderPriority.Second; }
- }
-
///
/// Gets a value indicating whether [requires internet].
///