aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2013-05-02 18:32:15 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2013-05-02 18:32:15 -0400
commit19a95edf58eb7f412008c75cb8c020512d1cb846 (patch)
treeaff32932a8d530f88dd03d0a124f157d2e5080de
parent9105b065e74555778e221dec50a7dcc3f4b465db (diff)
fixes #222 - Music providers not downloading art.
-rw-r--r--MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs1
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicArtist.cs1
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs14
-rw-r--r--MediaBrowser.Controller/Providers/BaseProviderInfo.cs5
-rw-r--r--MediaBrowser.Controller/Providers/FanartBaseProvider.cs9
-rw-r--r--MediaBrowser.Controller/Providers/ImagesByNameProvider.cs7
-rw-r--r--MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs2
-rw-r--r--MediaBrowser.Controller/Providers/Movies/RottenTomatoesMovieProvider.cs17
-rw-r--r--MediaBrowser.Controller/Providers/Movies/TmdbPersonProvider.cs2
-rw-r--r--MediaBrowser.Controller/Providers/Music/FanArtAlbumProvider.cs119
-rw-r--r--MediaBrowser.Controller/Providers/Music/FanArtArtistProvider.cs16
-rw-r--r--MediaBrowser.Controller/Providers/Music/LastfmAlbumProvider.cs53
-rw-r--r--MediaBrowser.Server.Implementations/Providers/ProviderManager.cs7
13 files changed, 221 insertions, 32 deletions
diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
index c707209ea..dd02bdc09 100644
--- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
+++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
@@ -97,7 +97,6 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
};
client = new HttpClient(handler);
- client.DefaultRequestHeaders.Add("Accept", "application/json,image/*");
client.Timeout = TimeSpan.FromSeconds(30);
_httpClients.TryAdd(host, client);
}
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
index 1f1d5e083..b2fc04873 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
@@ -6,6 +6,5 @@ namespace MediaBrowser.Controller.Entities.Audio
/// </summary>
public class MusicArtist : Folder
{
-
}
}
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 89aedadee..10fd3e79e 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -35,6 +35,8 @@ namespace MediaBrowser.Controller.Entities
ScreenshotImagePaths = new List<string>();
BackdropImagePaths = new List<string>();
ProductionLocations = new List<string>();
+ Images = new Dictionary<ImageType, string>();
+ ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}
/// <summary>
@@ -977,10 +979,10 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
public virtual void ClearMetaValues()
{
- Images = null;
+ Images.Clear();
ForcedSortName = null;
PremiereDate = null;
- BackdropImagePaths = null;
+ BackdropImagePaths.Clear();
OfficialRating = null;
CustomRating = null;
Overview = null;
@@ -992,7 +994,7 @@ namespace MediaBrowser.Controller.Entities
RunTimeTicks = null;
AspectRatio = null;
ProductionYear = null;
- ProviderIds = null;
+ ProviderIds.Clear();
DisplayMediaType = GetType().Name;
ResolveArgs = null;
}
@@ -1465,12 +1467,6 @@ namespace MediaBrowser.Controller.Entities
}
else
{
- // Ensure it exists
- if (Images == null)
- {
- Images = new Dictionary<ImageType, string>();
- }
-
Images[typeKey] = path;
}
}
diff --git a/MediaBrowser.Controller/Providers/BaseProviderInfo.cs b/MediaBrowser.Controller/Providers/BaseProviderInfo.cs
index 6262392fd..72fddfd93 100644
--- a/MediaBrowser.Controller/Providers/BaseProviderInfo.cs
+++ b/MediaBrowser.Controller/Providers/BaseProviderInfo.cs
@@ -28,10 +28,9 @@ namespace MediaBrowser.Controller.Providers
/// <value>The provider version.</value>
public string ProviderVersion { get; set; }
/// <summary>
- /// Gets or sets the custom data.
+ /// Contains a has of data that can be used to determine if the provider should refresh again
/// </summary>
- /// <value>The custom data.</value>
- public string CustomData { get; set; }
+ public Guid Data { get; set; }
}
/// <summary>
diff --git a/MediaBrowser.Controller/Providers/FanartBaseProvider.cs b/MediaBrowser.Controller/Providers/FanartBaseProvider.cs
index de749d7cc..617cd3256 100644
--- a/MediaBrowser.Controller/Providers/FanartBaseProvider.cs
+++ b/MediaBrowser.Controller/Providers/FanartBaseProvider.cs
@@ -1,9 +1,8 @@
-using System.Threading;
-using MediaBrowser.Controller.Configuration;
-using System.Collections.Generic;
-using MediaBrowser.Controller.Entities;
-using System;
+using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Logging;
+using System;
+using System.Collections.Generic;
+using System.Threading;
namespace MediaBrowser.Controller.Providers
{
diff --git a/MediaBrowser.Controller/Providers/ImagesByNameProvider.cs b/MediaBrowser.Controller/Providers/ImagesByNameProvider.cs
index 1df52f061..15e0ecfa8 100644
--- a/MediaBrowser.Controller/Providers/ImagesByNameProvider.cs
+++ b/MediaBrowser.Controller/Providers/ImagesByNameProvider.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.Logging;
@@ -52,7 +53,7 @@ namespace MediaBrowser.Controller.Providers
protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
{
// Force a refresh if the IBN path changed
- if (!string.Equals(providerInfo.CustomData, ConfigurationManager.ApplicationPaths.ItemsByNamePath, StringComparison.OrdinalIgnoreCase))
+ if (providerInfo.Data != ConfigurationManager.ApplicationPaths.ItemsByNamePath.GetMD5())
{
return true;
}
@@ -120,7 +121,7 @@ namespace MediaBrowser.Controller.Providers
if (item.ProviderData.TryGetValue(Id, out data))
{
- data.CustomData = ConfigurationManager.ApplicationPaths.ItemsByNamePath;
+ data.Data = ConfigurationManager.ApplicationPaths.ItemsByNamePath.GetMD5();
}
return result;
diff --git a/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs
index d750c335a..c5041e54b 100644
--- a/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs
+++ b/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs
@@ -253,7 +253,7 @@ namespace MediaBrowser.Controller.Providers.Movies
new Regex(@"(?<name>.*)") // last resort matches the whole string as the name
};
- public const string LOCAL_META_FILE_NAME = "mbmovie.js";
+ public const string LOCAL_META_FILE_NAME = "mbmovie.json";
public const string ALT_META_FILE_NAME = "movie.xml";
protected string ItemType = "movie";
diff --git a/MediaBrowser.Controller/Providers/Movies/RottenTomatoesMovieProvider.cs b/MediaBrowser.Controller/Providers/Movies/RottenTomatoesMovieProvider.cs
index edb6db14d..ee2869e10 100644
--- a/MediaBrowser.Controller/Providers/Movies/RottenTomatoesMovieProvider.cs
+++ b/MediaBrowser.Controller/Providers/Movies/RottenTomatoesMovieProvider.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Common.Net;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
@@ -114,7 +115,7 @@ namespace MediaBrowser.Controller.Providers.Movies
}
// Refresh if imdb id has changed
- if (!string.Equals(item.GetProviderId(MetadataProviders.Imdb), providerInfo.CustomData))
+ if (providerInfo.Data != GetComparisonData(item.GetProviderId(MetadataProviders.Imdb)))
{
return true;
}
@@ -144,7 +145,7 @@ namespace MediaBrowser.Controller.Providers.Movies
if (item.ProviderData.TryGetValue(Id, out data))
{
- data.CustomData = item.GetProviderId(MetadataProviders.Imdb);
+ data.Data = GetComparisonData(item.GetProviderId(MetadataProviders.Imdb));
}
SetLastRefreshed(item, DateTime.UtcNow);
@@ -153,6 +154,16 @@ namespace MediaBrowser.Controller.Providers.Movies
}
/// <summary>
+ /// Gets the comparison data.
+ /// </summary>
+ /// <param name="imdbId">The imdb id.</param>
+ /// <returns>Guid.</returns>
+ private Guid GetComparisonData(string imdbId)
+ {
+ return string.IsNullOrEmpty(imdbId) ? Guid.Empty : imdbId.GetMD5();
+ }
+
+ /// <summary>
/// Gets the priority.
/// </summary>
/// <value>The priority.</value>
diff --git a/MediaBrowser.Controller/Providers/Movies/TmdbPersonProvider.cs b/MediaBrowser.Controller/Providers/Movies/TmdbPersonProvider.cs
index affd4757a..ac0bf9911 100644
--- a/MediaBrowser.Controller/Providers/Movies/TmdbPersonProvider.cs
+++ b/MediaBrowser.Controller/Providers/Movies/TmdbPersonProvider.cs
@@ -24,7 +24,7 @@ namespace MediaBrowser.Controller.Providers.Movies
/// <summary>
/// The meta file name
/// </summary>
- protected const string MetaFileName = "mbperson.js";
+ protected const string MetaFileName = "mbperson.json";
protected readonly IProviderManager ProviderManager;
diff --git a/MediaBrowser.Controller/Providers/Music/FanArtAlbumProvider.cs b/MediaBrowser.Controller/Providers/Music/FanArtAlbumProvider.cs
index 33ea8b9a9..15188bc69 100644
--- a/MediaBrowser.Controller/Providers/Music/FanArtAlbumProvider.cs
+++ b/MediaBrowser.Controller/Providers/Music/FanArtAlbumProvider.cs
@@ -7,18 +7,41 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Net;
using System;
using System.IO;
+using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
namespace MediaBrowser.Controller.Providers.Music
{
+ /// <summary>
+ /// Class FanArtAlbumProvider
+ /// </summary>
public class FanArtAlbumProvider : FanartBaseProvider
{
+ /// <summary>
+ /// The _provider manager
+ /// </summary>
private readonly IProviderManager _providerManager;
+ /// <summary>
+ /// The _music brainz resource pool
+ /// </summary>
+ private readonly SemaphoreSlim _musicBrainzResourcePool = new SemaphoreSlim(1, 1);
+
+ /// <summary>
+ /// Gets the HTTP client.
+ /// </summary>
+ /// <value>The HTTP client.</value>
protected IHttpClient HttpClient { get; private set; }
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FanArtAlbumProvider"/> class.
+ /// </summary>
+ /// <param name="httpClient">The HTTP client.</param>
+ /// <param name="logManager">The log manager.</param>
+ /// <param name="configurationManager">The configuration manager.</param>
+ /// <param name="providerManager">The provider manager.</param>
public FanArtAlbumProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager)
: base(logManager, configurationManager)
{
@@ -26,11 +49,20 @@ namespace MediaBrowser.Controller.Providers.Music
HttpClient = httpClient;
}
+ /// <summary>
+ /// Supportses the specified item.
+ /// </summary>
+ /// <param name="item">The item.</param>
+ /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
public override bool Supports(BaseItem item)
{
return item is MusicAlbum;
}
+ /// <summary>
+ /// Gets a value indicating whether [refresh on version change].
+ /// </summary>
+ /// <value><c>true</c> if [refresh on version change]; otherwise, <c>false</c>.</value>
protected override bool RefreshOnVersionChange
{
get
@@ -39,11 +71,15 @@ namespace MediaBrowser.Controller.Providers.Music
}
}
+ /// <summary>
+ /// Gets the provider version.
+ /// </summary>
+ /// <value>The provider version.</value>
protected override string ProviderVersion
{
get
{
- return "20130501.5";
+ return "11";
}
}
@@ -69,11 +105,27 @@ namespace MediaBrowser.Controller.Providers.Music
return base.NeedsRefreshInternal(item, providerInfo);
}
+ /// <summary>
+ /// Fetches metadata and returns true or false indicating if any work that requires persistence was done
+ /// </summary>
+ /// <param name="item">The item.</param>
+ /// <param name="force">if set to <c>true</c> [force].</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>Task{System.Boolean}.</returns>
public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
- var url = string.Format("http://api.fanart.tv/webservice/album/{0}/{1}/xml/all/1/1", APIKey, item.GetProviderId(MetadataProviders.Musicbrainz));
+ var releaseGroupId = await GetReleaseGroupId(item.GetProviderId(MetadataProviders.Musicbrainz), cancellationToken).ConfigureAwait(false);
+
+ if (string.IsNullOrEmpty(releaseGroupId))
+ {
+ SetLastRefreshed(item, DateTime.UtcNow);
+
+ return true;
+ }
+
+ var url = string.Format("http://api.fanart.tv/webservice/album/{0}/{1}/xml/all/1/1", APIKey, releaseGroupId);
var doc = new XmlDocument();
@@ -143,5 +195,68 @@ namespace MediaBrowser.Controller.Providers.Music
return true;
}
+
+ /// <summary>
+ /// The _last music brainz request
+ /// </summary>
+ private DateTime _lastMusicBrainzRequest = DateTime.MinValue;
+
+ /// <summary>
+ /// Gets the release group id.
+ /// </summary>
+ /// <param name="releaseEntryId">The release entry id.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>Task{System.String}.</returns>
+ private async Task<string> GetReleaseGroupId(string releaseEntryId, CancellationToken cancellationToken)
+ {
+ await _musicBrainzResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
+
+ try
+ {
+ var diff = 1000 - (DateTime.Now - _lastMusicBrainzRequest).TotalMilliseconds;
+
+ // MusicBrainz is extremely adamant about limiting to one request per second
+
+ if (diff > 0)
+ {
+ await Task.Delay(Convert.ToInt32(diff), cancellationToken).ConfigureAwait(false);
+ }
+
+ _lastMusicBrainzRequest = DateTime.Now;
+
+ return await GetReleaseGroupIdInternal(releaseEntryId, cancellationToken).ConfigureAwait(false);
+ }
+ finally
+ {
+ _musicBrainzResourcePool.Release();
+ }
+ }
+
+ /// <summary>
+ /// Gets the release group id internal.
+ /// </summary>
+ /// <param name="releaseEntryId">The release entry id.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>Task{System.String}.</returns>
+ private async Task<string> GetReleaseGroupIdInternal(string releaseEntryId, CancellationToken cancellationToken)
+ {
+ var url = string.Format("http://www.musicbrainz.org/ws/2/release-group/?query=reid:{0}", releaseEntryId);
+
+ var doc = new XmlDocument();
+
+ using (var xml = await HttpClient.Get(url, cancellationToken).ConfigureAwait(false))
+ {
+ using (var oReader = new StreamReader(xml, Encoding.UTF8))
+ {
+ doc.Load(oReader);
+ }
+ }
+
+ var ns = new XmlNamespaceManager(doc.NameTable);
+ ns.AddNamespace("mb", "http://musicbrainz.org/ns/mmd-2.0#");
+ var node = doc.SelectSingleNode("//mb:release-group-list/mb:release-group/@id", ns);
+
+ return node != null ? node.Value : null;
+ }
}
}
diff --git a/MediaBrowser.Controller/Providers/Music/FanArtArtistProvider.cs b/MediaBrowser.Controller/Providers/Music/FanArtArtistProvider.cs
index 86c7a22f4..320acb701 100644
--- a/MediaBrowser.Controller/Providers/Music/FanArtArtistProvider.cs
+++ b/MediaBrowser.Controller/Providers/Music/FanArtArtistProvider.cs
@@ -58,6 +58,22 @@ namespace MediaBrowser.Controller.Providers.Music
get { return ConfigurationManager.Configuration.SaveLocalMeta; }
}
+ protected override bool RefreshOnVersionChange
+ {
+ get
+ {
+ return true;
+ }
+ }
+
+ protected override string ProviderVersion
+ {
+ get
+ {
+ return "1";
+ }
+ }
+
/// <summary>
/// Needses the refresh internal.
/// </summary>
diff --git a/MediaBrowser.Controller/Providers/Music/LastfmAlbumProvider.cs b/MediaBrowser.Controller/Providers/Music/LastfmAlbumProvider.cs
index a3fad6e8a..0cdd9b19b 100644
--- a/MediaBrowser.Controller/Providers/Music/LastfmAlbumProvider.cs
+++ b/MediaBrowser.Controller/Providers/Music/LastfmAlbumProvider.cs
@@ -1,7 +1,9 @@
-using MediaBrowser.Common.Net;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
using MoreLinq;
@@ -32,6 +34,24 @@ namespace MediaBrowser.Controller.Providers.Music
return BlankId;
}
+ /// <summary>
+ /// Needses the refresh internal.
+ /// </summary>
+ /// <param name="item">The item.</param>
+ /// <param name="providerInfo">The provider info.</param>
+ /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
+ protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
+ {
+ // If song metadata has changed and we don't have an mbid, refresh
+ if (string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.Musicbrainz)) &&
+ GetComparisonData(item as MusicAlbum) != providerInfo.Data)
+ {
+ return true;
+ }
+
+ return base.NeedsRefreshInternal(item, providerInfo);
+ }
+
protected override async Task FetchLastfmData(BaseItem item, string id, CancellationToken cancellationToken)
{
var result = await GetAlbumResult(item, cancellationToken).ConfigureAwait(false);
@@ -51,6 +71,13 @@ namespace MediaBrowser.Controller.Providers.Music
}
}
+
+ BaseProviderInfo data;
+
+ if (item.ProviderData.TryGetValue(Id, out data))
+ {
+ data.Data = GetComparisonData(item as MusicAlbum);
+ }
}
private async Task<LastfmGetAlbumResult> GetAlbumResult(BaseItem item, CancellationToken cancellationToken)
@@ -102,5 +129,29 @@ namespace MediaBrowser.Controller.Providers.Music
return true;
}
}
+
+ /// <summary>
+ /// Gets the data.
+ /// </summary>
+ /// <param name="album">The album.</param>
+ /// <returns>Guid.</returns>
+ private Guid GetComparisonData(MusicAlbum album)
+ {
+ var songs = album.RecursiveChildren.OfType<Audio>().ToList();
+
+ var albumArtists = songs.Select(i => i.AlbumArtist)
+ .Where(i => !string.IsNullOrEmpty(i))
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .ToList();
+
+ var albumNames = songs.Select(i => i.AlbumArtist)
+ .Where(i => !string.IsNullOrEmpty(i))
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .ToList();
+
+ albumArtists.AddRange(albumNames);
+
+ return string.Join(string.Empty, albumArtists.OrderBy(i => i).ToArray()).GetMD5();
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs
index 979679916..fe93cd377 100644
--- a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs
+++ b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs
@@ -129,10 +129,13 @@ namespace MediaBrowser.Server.Implementations.Providers
var providersChanged = false;
item.ProviderData.TryGetValue(_supportedProvidersKey, out supportedProvidersInfo);
+
+ var supportedProvidersHash = supportedProvidersValue.GetMD5();
+
if (supportedProvidersInfo != null)
{
// Force refresh if the supported providers have changed
- providersChanged = force = force || !string.Equals(supportedProvidersInfo.CustomData, supportedProvidersValue);
+ providersChanged = force = force || supportedProvidersHash != supportedProvidersInfo.Data;
// If providers have changed, clear provider info and update the supported providers hash
if (providersChanged)
@@ -144,7 +147,7 @@ namespace MediaBrowser.Server.Implementations.Providers
if (providersChanged)
{
- supportedProvidersInfo.CustomData = supportedProvidersValue;
+ supportedProvidersInfo.Data = supportedProvidersHash;
}
if (force) item.ClearMetaValues();