diff --git a/MediaBrowser.Controller/Entities/Audio/Artist.cs b/MediaBrowser.Controller/Entities/Audio/Artist.cs
index 7730c90d3b..274356b30f 100644
--- a/MediaBrowser.Controller/Entities/Audio/Artist.cs
+++ b/MediaBrowser.Controller/Entities/Audio/Artist.cs
@@ -6,6 +6,8 @@ namespace MediaBrowser.Controller.Entities.Audio
///
public class Artist : BaseItem, IItemByName
{
+ public string LastFmImageUrl { get; set; }
+
///
/// Gets the user data key.
///
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
index b2fc04873f..e2bad64d4f 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
@@ -6,5 +6,6 @@ namespace MediaBrowser.Controller.Entities.Audio
///
public class MusicArtist : Folder
{
+ public string LastFmImageUrl { get; set; }
}
}
diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
index 9d07394944..c49424f65e 100644
--- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj
+++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
@@ -77,6 +77,7 @@
+
diff --git a/MediaBrowser.Providers/Music/ArtistsPostScanTask.cs b/MediaBrowser.Providers/Music/ArtistsPostScanTask.cs
index 58da610a67..f67d616813 100644
--- a/MediaBrowser.Providers/Music/ArtistsPostScanTask.cs
+++ b/MediaBrowser.Providers/Music/ArtistsPostScanTask.cs
@@ -63,28 +63,17 @@ namespace MediaBrowser.Providers.Music
backdrops.InsertRange(0, artist.BackdropImagePaths);
artist.BackdropImagePaths = backdrops.Distinct(StringComparer.OrdinalIgnoreCase)
.ToList();
-
- if (!artist.LockedFields.Contains(MetadataFields.Genres))
- {
- // Merge genres
- var genres = musicArtist.Genres.ToList();
- genres.InsertRange(0, artist.Genres);
- artist.Genres = genres.Distinct(StringComparer.OrdinalIgnoreCase)
- .ToList();
- }
}
- else
+
+ if (!artist.LockedFields.Contains(MetadataFields.Genres))
{
- if (!artist.LockedFields.Contains(MetadataFields.Genres))
- {
- // Avoid implicitly captured closure
- var artist1 = artist;
+ // Avoid implicitly captured closure
+ var artist1 = artist;
- artist.Genres = allSongs.Where(i => i.HasArtist(artist1.Name))
- .SelectMany(i => i.Genres)
- .Distinct(StringComparer.OrdinalIgnoreCase)
- .ToList();
- }
+ artist.Genres = allSongs.Where(i => i.HasArtist(artist1.Name))
+ .SelectMany(i => i.Genres)
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .ToList();
}
numComplete++;
diff --git a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs
index 2593b9838f..9960ebc916 100644
--- a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs
+++ b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs
@@ -115,6 +115,14 @@ namespace MediaBrowser.Providers.Music
}
}
+ public override MetadataProviderPriority Priority
+ {
+ get
+ {
+ return MetadataProviderPriority.Fourth;
+ }
+ }
+
///
/// Needses the refresh internal.
///
diff --git a/MediaBrowser.Providers/Music/LastFmArtistImageProvider.cs b/MediaBrowser.Providers/Music/LastFmArtistImageProvider.cs
new file mode 100644
index 0000000000..b5fb160c3f
--- /dev/null
+++ b/MediaBrowser.Providers/Music/LastFmArtistImageProvider.cs
@@ -0,0 +1,120 @@
+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.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Providers.Music
+{
+ ///
+ /// Class LastFmArtistImageProvider
+ ///
+ public class LastFmArtistImageProvider : BaseMetadataProvider
+ {
+ ///
+ /// The _provider manager
+ ///
+ private readonly IProviderManager _providerManager;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The log manager.
+ /// The configuration manager.
+ /// The provider manager.
+ public LastFmArtistImageProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager) :
+ base(logManager, configurationManager)
+ {
+ _providerManager = providerManager;
+ }
+
+ ///
+ /// Supportses the specified item.
+ ///
+ /// The item.
+ /// true if XXXX, false otherwise
+ public override bool Supports(BaseItem item)
+ {
+ return item is Artist || item is MusicArtist;
+ }
+
+ ///
+ /// Needses the refresh internal.
+ ///
+ /// The item.
+ /// The provider info.
+ /// true if XXXX, false otherwise
+ protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
+ {
+ if (item.HasImage(ImageType.Primary))
+ {
+ return false;
+ }
+
+ if (string.IsNullOrWhiteSpace(GetImageUrl(item)))
+ {
+ return false;
+ }
+
+ return base.NeedsRefreshInternal(item, providerInfo);
+ }
+
+ ///
+ /// Fetches metadata and returns true or false indicating if any work that requires persistence was done
+ ///
+ /// The item.
+ /// if set to true [force].
+ /// The cancellation token.
+ /// Task{System.Boolean}.
+ public override async Task FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken)
+ {
+ var url = GetImageUrl(item);
+
+ if (!string.IsNullOrWhiteSpace(url))
+ {
+ await _providerManager.SaveImage(item, url, LastfmBaseProvider.LastfmResourcePool, ImageType.Primary, null, cancellationToken)
+ .ConfigureAwait(false);
+ }
+
+ SetLastRefreshed(item, DateTime.UtcNow);
+ return true;
+ }
+
+ ///
+ /// Gets the priority.
+ ///
+ /// The priority.
+ public override MetadataProviderPriority Priority
+ {
+ get { return MetadataProviderPriority.Fifth; }
+ }
+
+ ///
+ /// Gets the image URL.
+ ///
+ /// The item.
+ /// System.String.
+ private string GetImageUrl(BaseItem item)
+ {
+ var musicArtist = item as MusicArtist;
+
+ if (musicArtist != null)
+ {
+ return musicArtist.LastFmImageUrl;
+ }
+
+ var artistByName = item as Artist;
+
+ if (artistByName != null)
+ {
+ return artistByName.LastFmImageUrl;
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/MediaBrowser.Providers/Music/LastfmAlbumProvider.cs b/MediaBrowser.Providers/Music/LastfmAlbumProvider.cs
index 50a5ac8ed2..275b3c0aff 100644
--- a/MediaBrowser.Providers/Music/LastfmAlbumProvider.cs
+++ b/MediaBrowser.Providers/Music/LastfmAlbumProvider.cs
@@ -67,7 +67,7 @@ namespace MediaBrowser.Providers.Music
return base.NeedsRefreshInternal(item, providerInfo);
}
- protected override async Task FetchLastfmData(BaseItem item, string id, CancellationToken cancellationToken)
+ protected override async Task FetchLastfmData(BaseItem item, string id, bool force, CancellationToken cancellationToken)
{
var album = (MusicAlbum)item;
@@ -165,9 +165,9 @@ namespace MediaBrowser.Providers.Music
}
}
- protected override Task FetchData(BaseItem item, CancellationToken cancellationToken)
+ protected override Task FetchData(BaseItem item, bool force, CancellationToken cancellationToken)
{
- return FetchLastfmData(item, string.Empty, cancellationToken);
+ return FetchLastfmData(item, string.Empty, force, cancellationToken);
}
public override bool Supports(BaseItem item)
diff --git a/MediaBrowser.Providers/Music/LastfmArtistByNameProvider.cs b/MediaBrowser.Providers/Music/LastfmArtistByNameProvider.cs
index d3bc28d3c4..5bc9debd3a 100644
--- a/MediaBrowser.Providers/Music/LastfmArtistByNameProvider.cs
+++ b/MediaBrowser.Providers/Music/LastfmArtistByNameProvider.cs
@@ -72,20 +72,20 @@ namespace MediaBrowser.Providers.Music
/// The music brainz id.
/// The cancellation token.
/// Task.
- protected override async Task FetchLastfmData(BaseItem item, string musicBrainzId, CancellationToken cancellationToken)
+ protected override async Task FetchLastfmData(BaseItem item, string musicBrainzId, bool force, CancellationToken cancellationToken)
{
var artist = (Artist)item;
// See if we can avoid an http request by finding the matching MusicArtist entity
var musicArtist = FindMusicArtist(artist, LibraryManager);
- if (musicArtist != null)
+ if (musicArtist != null && !force)
{
LastfmHelper.ProcessArtistData(musicArtist, artist);
}
else
{
- await base.FetchLastfmData(item, musicBrainzId, cancellationToken).ConfigureAwait(false);
+ await base.FetchLastfmData(item, musicBrainzId, force, cancellationToken).ConfigureAwait(false);
}
}
diff --git a/MediaBrowser.Providers/Music/LastfmArtistProvider.cs b/MediaBrowser.Providers/Music/LastfmArtistProvider.cs
index bbd2325b43..a65cecb887 100644
--- a/MediaBrowser.Providers/Music/LastfmArtistProvider.cs
+++ b/MediaBrowser.Providers/Music/LastfmArtistProvider.cs
@@ -200,7 +200,7 @@ namespace MediaBrowser.Providers.Music
/// The music brainz id.
/// The cancellation token.
/// Task.
- protected override async Task FetchLastfmData(BaseItem item, string musicBrainzId, CancellationToken cancellationToken)
+ protected override async Task FetchLastfmData(BaseItem item, string musicBrainzId, bool force, CancellationToken cancellationToken)
{
// Get artist info with provided id
var url = RootUrl + string.Format("method=artist.getInfo&mbid={0}&api_key={1}&format=json", UrlEncode(musicBrainzId), ApiKey);
@@ -216,7 +216,15 @@ namespace MediaBrowser.Providers.Music
}).ConfigureAwait(false))
{
- result = JsonSerializer.DeserializeFromStream(json);
+ using (var reader = new StreamReader(json))
+ {
+ var jsonText = await reader.ReadToEndAsync().ConfigureAwait(false);
+
+ // Fix their bad json
+ jsonText = jsonText.Replace("\"#text\"", "\"url\"");
+
+ result = JsonSerializer.DeserializeFromString(jsonText);
+ }
}
if (result != null && result.artist != null)
diff --git a/MediaBrowser.Providers/Music/LastfmBaseProvider.cs b/MediaBrowser.Providers/Music/LastfmBaseProvider.cs
index d5580bb4d0..36099509dd 100644
--- a/MediaBrowser.Providers/Music/LastfmBaseProvider.cs
+++ b/MediaBrowser.Providers/Music/LastfmBaseProvider.cs
@@ -18,7 +18,7 @@ namespace MediaBrowser.Providers.Music
///
public abstract class LastfmBaseProvider : BaseMetadataProvider
{
- protected static readonly SemaphoreSlim LastfmResourcePool = new SemaphoreSlim(4, 4);
+ internal static readonly SemaphoreSlim LastfmResourcePool = new SemaphoreSlim(4, 4);
///
/// Initializes a new instance of the class.
@@ -100,7 +100,7 @@ namespace MediaBrowser.Providers.Music
/// The item.
///
/// Task.
- protected virtual async Task FetchData(BaseItem item, CancellationToken cancellationToken)
+ protected virtual async Task FetchData(BaseItem item, bool force, CancellationToken cancellationToken)
{
var id = item.GetProviderId(MetadataProviders.Musicbrainz) ?? await FindId(item, cancellationToken).ConfigureAwait(false);
if (!string.IsNullOrWhiteSpace(id))
@@ -111,18 +111,18 @@ namespace MediaBrowser.Providers.Music
item.SetProviderId(MetadataProviders.Musicbrainz, id);
- await FetchLastfmData(item, id, cancellationToken).ConfigureAwait(false);
+ await FetchLastfmData(item, id, force, cancellationToken).ConfigureAwait(false);
}
else
{
Logger.Info("LastfmProvider could not find " + item.Name + ". Check name on Last.fm.");
}
-
+
}
protected abstract Task FindId(BaseItem item, CancellationToken cancellationToken);
- protected abstract Task FetchLastfmData(BaseItem item, string id, CancellationToken cancellationToken);
+ protected abstract Task FetchLastfmData(BaseItem item, string id, bool force, CancellationToken cancellationToken);
///
/// Encodes an URL.
@@ -145,7 +145,7 @@ namespace MediaBrowser.Providers.Music
{
cancellationToken.ThrowIfCancellationRequested();
- await FetchData(item, cancellationToken).ConfigureAwait(false);
+ await FetchData(item, force, cancellationToken).ConfigureAwait(false);
SetLastRefreshed(item, DateTime.UtcNow);
return true;
}
@@ -187,6 +187,12 @@ namespace MediaBrowser.Providers.Music
public List formationlist { get; set; }
}
+ public class LastFmImage
+ {
+ public string url { get; set; }
+ public string size { get; set; }
+ }
+
public class LastfmArtist
{
public string name { get; set; }
@@ -198,6 +204,7 @@ namespace MediaBrowser.Providers.Music
public List similar { get; set; }
public LastfmTags tags { get; set; }
public LastFmBio bio { get; set; }
+ public List image { get; set; }
}
diff --git a/MediaBrowser.Providers/Music/LastfmHelper.cs b/MediaBrowser.Providers/Music/LastfmHelper.cs
index 56f18d7e6a..a955ecbd57 100644
--- a/MediaBrowser.Providers/Music/LastfmHelper.cs
+++ b/MediaBrowser.Providers/Music/LastfmHelper.cs
@@ -31,6 +31,40 @@ namespace MediaBrowser.Providers.Music
{
AddTags(artist, data.tags);
}
+
+ var musicArtist = artist as MusicArtist;
+
+ if (musicArtist != null)
+ {
+ musicArtist.LastFmImageUrl = GetImageUrl(data);
+ }
+
+ var artistByName = artist as Artist;
+
+ if (artistByName != null)
+ {
+ artistByName.LastFmImageUrl = GetImageUrl(data);
+ }
+ }
+
+ private static string GetImageUrl(LastfmArtist data)
+ {
+ if (data.image == null)
+ {
+ return null;
+ }
+
+ var img = data.image.FirstOrDefault(i => string.Equals(i.size, "extralarge", StringComparison.OrdinalIgnoreCase)) ??
+ data.image.FirstOrDefault(i => string.Equals(i.size, "large", StringComparison.OrdinalIgnoreCase)) ??
+ data.image.FirstOrDefault(i => string.Equals(i.size, "medium", StringComparison.OrdinalIgnoreCase)) ??
+ data.image.FirstOrDefault();
+
+ if (img != null)
+ {
+ return img.url;
+ }
+
+ return null;
}
public static void ProcessArtistData(MusicArtist source, Artist target)