diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 6a7557e3a..6d09fe163 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -194,6 +194,7 @@
+
diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs
index 94b19498a..242a16ee9 100644
--- a/MediaBrowser.Controller/Providers/IProviderManager.cs
+++ b/MediaBrowser.Controller/Providers/IProviderManager.cs
@@ -54,11 +54,13 @@ namespace MediaBrowser.Controller.Providers
///
/// The image providers.
/// The metadata services.
+ /// The identity providers.
+ /// The identity converters.
/// The metadata providers.
/// The savers.
/// The image savers.
/// The external ids.
- void AddParts(IEnumerable imageProviders, IEnumerable metadataServices, IEnumerable metadataProviders,
+ void AddParts(IEnumerable imageProviders, IEnumerable metadataServices, IEnumerable identityProviders, IEnumerable identityConverters, IEnumerable metadataProviders,
IEnumerable savers,
IEnumerable imageSavers,
IEnumerable externalIds);
diff --git a/MediaBrowser.Controller/Providers/ItemIdentities.cs b/MediaBrowser.Controller/Providers/ItemIdentities.cs
new file mode 100644
index 000000000..93d468af0
--- /dev/null
+++ b/MediaBrowser.Controller/Providers/ItemIdentities.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Controller.Providers
+{
+ public interface IItemIdentity
+ {
+ string Type { get; }
+ }
+
+ public interface IHasIdentities
+ where TIdentity : IItemIdentity
+ {
+ IEnumerable Identities { get; }
+
+ Task FindIdentities(IProviderManager providerManager, CancellationToken cancellationToken);
+ }
+
+ public interface IItemIdentityProvider : IHasOrder { }
+
+ public interface IItemIdentityProvider : IItemIdentityProvider
+ where TLookupInfo : ItemLookupInfo
+ where TIdentity : IItemIdentity
+ {
+ Task FindIdentity(TLookupInfo info);
+ }
+
+ public interface IItemIdentityConverter : IHasOrder { }
+
+ public interface IItemIdentityConverter : IItemIdentityConverter
+ where TIdentity : IItemIdentity
+ {
+ Task Convert(TIdentity identity);
+
+ string SourceType { get; }
+
+ string ResultType { get; }
+ }
+}
\ No newline at end of file
diff --git a/MediaBrowser.Providers/Manager/ItemIdentifier.cs b/MediaBrowser.Providers/Manager/ItemIdentifier.cs
new file mode 100644
index 000000000..0bf983b69
--- /dev/null
+++ b/MediaBrowser.Providers/Manager/ItemIdentifier.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Controller.Providers;
+
+namespace MediaBrowser.Providers.Manager
+{
+ public class ItemIdentifier
+ where TLookupInfo : ItemLookupInfo
+ where TIdentity : IItemIdentity
+ {
+ public async Task> FindIdentities(TLookupInfo item, ProviderManager providerManager, CancellationToken cancellationToken)
+ {
+ var providers = providerManager.GetItemIdentityProviders();
+ var converters = providerManager.GetItemIdentityConverters();
+
+ var identities = new List();
+
+ foreach (var provider in providers)
+ {
+ var result = new IdentityPair
+ {
+ Identity = await provider.FindIdentity(item),
+ Order = provider.Order
+ };
+
+ identities.Add(result);
+ }
+
+ var convertersAvailable = new List>(converters);
+ bool changesMade;
+
+ do
+ {
+ changesMade = false;
+
+ for (int i = convertersAvailable.Count - 1; i >= 0; i--)
+ {
+ var converter = convertersAvailable[i];
+ var input = identities.FirstOrDefault(id => id.Identity.Type == converter.SourceType);
+ var existing = identities.Where(id => id.Identity.Type == converter.ResultType);
+
+ if (input != null && !existing.Any(id => id.Order >= converter.Order))
+ {
+ var result = new IdentityPair
+ {
+ Identity = await converter.Convert(input.Identity).ConfigureAwait(false),
+ Order = converter.Order
+ };
+
+ identities.Add(result);
+ convertersAvailable.RemoveAt(i);
+ changesMade = true;
+ }
+ }
+ } while (changesMade);
+
+ return identities.Select(id => id.Identity);
+ }
+
+ private class IdentityPair
+ {
+ public TIdentity Identity;
+ public int Order;
+ }
+ }
+}
\ No newline at end of file
diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs
index b2e23682b..c0ef7e144 100644
--- a/MediaBrowser.Providers/Manager/MetadataService.cs
+++ b/MediaBrowser.Providers/Manager/MetadataService.cs
@@ -389,7 +389,7 @@ namespace MediaBrowser.Providers.Manager
private async Task ExecuteRemoteProviders(TItemType item, TItemType temp, IEnumerable> providers, RefreshResult refreshResult, CancellationToken cancellationToken)
{
- TIdType id = null;
+ TIdType id = await CreateInitialLookupInfo(item, cancellationToken).ConfigureAwait(false);
var unidentifiedCount = 0;
var identifiedCount = 0;
@@ -399,11 +399,7 @@ namespace MediaBrowser.Providers.Manager
var providerName = provider.GetType().Name;
Logger.Debug("Running {0} for {1}", providerName, item.Path ?? item.Name);
- if (id == null)
- {
- id = item.GetLookupInfo();
- }
- else
+ if (id != null)
{
MergeNewData(temp, id);
}
@@ -448,6 +444,19 @@ namespace MediaBrowser.Providers.Manager
}
}
+ private async Task CreateInitialLookupInfo(TItemType item, CancellationToken cancellationToken)
+ {
+ var info = item.GetLookupInfo();
+
+ var hasIdentity = info as IHasIdentities;
+ if (hasIdentity != null)
+ {
+ await hasIdentity.FindIdentities(ProviderManager, cancellationToken).ConfigureAwait(false);
+ }
+
+ return info;
+ }
+
private void MergeNewData(TItemType source, TIdType lookupInfo)
{
// Copy new provider id's that may have been obtained
diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs
index 414d7f064..4630da83f 100644
--- a/MediaBrowser.Providers/Manager/ProviderManager.cs
+++ b/MediaBrowser.Providers/Manager/ProviderManager.cs
@@ -53,6 +53,8 @@ namespace MediaBrowser.Providers.Manager
private readonly IFileSystem _fileSystem;
private IMetadataService[] _metadataServices = { };
+ private IItemIdentityProvider[] _identityProviders = { };
+ private IItemIdentityConverter[] _identityConverters = { };
private IMetadataProvider[] _metadataProviders = { };
private IEnumerable _savers;
private IImageSaver[] _imageSavers;
@@ -81,17 +83,22 @@ namespace MediaBrowser.Providers.Manager
///
/// The image providers.
/// The metadata services.
+ /// The identity providers.
+ /// The identity converters.
/// The metadata providers.
/// The metadata savers.
/// The image savers.
/// The external ids.
- public void AddParts(IEnumerable imageProviders, IEnumerable metadataServices, IEnumerable metadataProviders, IEnumerable metadataSavers,
- IEnumerable imageSavers,
- IEnumerable externalIds)
+ public void AddParts(IEnumerable imageProviders, IEnumerable metadataServices,
+ IEnumerable identityProviders, IEnumerable identityConverters,
+ IEnumerable metadataProviders, IEnumerable metadataSavers,
+ IEnumerable imageSavers, IEnumerable externalIds)
{
ImageProviders = imageProviders.ToArray();
_metadataServices = metadataServices.OrderBy(i => i.Order).ToArray();
+ _identityProviders = identityProviders.ToArray();
+ _identityConverters = identityConverters.ToArray();
_metadataProviders = metadataProviders.ToArray();
_savers = metadataSavers.ToArray();
_imageSavers = imageSavers.ToArray();
@@ -257,6 +264,19 @@ namespace MediaBrowser.Providers.Manager
.ThenBy(GetDefaultOrder);
}
+ public IEnumerable> GetItemIdentityProviders()
+ where TLookupInfo : ItemLookupInfo
+ where TIdentity : IItemIdentity
+ {
+ return _identityProviders.OfType>();
+ }
+
+ public IEnumerable> GetItemIdentityConverters()
+ where TIdentity : IItemIdentity
+ {
+ return _identityConverters.OfType>();
+ }
+
private IEnumerable GetRemoteImageProviders(IHasImages item, bool includeDisabled)
{
var options = GetMetadataOptions(item);
diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
index 43402123c..0549da557 100644
--- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj
+++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
@@ -95,6 +95,7 @@
+
diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs
index 9de319851..e6306f934 100644
--- a/MediaBrowser.ServerApplication/ApplicationHost.cs
+++ b/MediaBrowser.ServerApplication/ApplicationHost.cs
@@ -708,10 +708,14 @@ namespace MediaBrowser.ServerApplication
GetExports(),
GetExports());
- ProviderManager.AddParts(GetExports(), GetExports(), GetExports(),
- GetExports(),
- GetExports(),
- GetExports());
+ ProviderManager.AddParts(GetExports(),
+ GetExports(),
+ GetExports(),
+ GetExports(),
+ GetExports(),
+ GetExports(),
+ GetExports(),
+ GetExports());
SeriesOrderManager.AddParts(GetExports());