Merge pull request #811 from thogil/item_identity_providers_2

Item identity providers
This commit is contained in:
Luke
2014-06-12 16:14:01 -04:00
16 changed files with 381 additions and 52 deletions

View File

@@ -32,6 +32,7 @@ namespace MediaBrowser.Controller.Entities
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
LockedFields = new List<MetadataFields>();
ImageInfos = new List<ItemImageInfo>();
Identities = new List<IItemIdentity>();
}
/// <summary>
@@ -244,6 +245,9 @@ namespace MediaBrowser.Controller.Entities
public bool IsUnidentified { get; set; }
[IgnoreDataMember]
public List<IItemIdentity> Identities { get; set; }
/// <summary>
/// Gets or sets the locked fields.
/// </summary>

View File

@@ -1,4 +1,5 @@
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
@@ -55,5 +56,10 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
/// <value><c>true</c> if this instance is unidentified; otherwise, <c>false</c>.</value>
bool IsUnidentified { get; set; }
/// <summary>
/// Gets the item identities.
/// </summary>
List<IItemIdentity> Identities { get; set; }
}
}

View File

@@ -225,6 +225,8 @@
<Compile Include="Security\IEncryptionManager.cs" />
<Compile Include="Subtitles\ISubtitleManager.cs" />
<Compile Include="Subtitles\ISubtitleProvider.cs" />
<Compile Include="Providers\ItemIdentifier.cs" />
<Compile Include="Providers\ItemIdentities.cs" />
<Compile Include="Providers\ItemLookupInfo.cs" />
<Compile Include="Providers\MetadataRefreshOptions.cs" />
<Compile Include="Providers\NameParser.cs" />

View File

@@ -54,11 +54,13 @@ namespace MediaBrowser.Controller.Providers
/// </summary>
/// <param name="imageProviders">The image providers.</param>
/// <param name="metadataServices">The metadata services.</param>
/// <param name="identityProviders">The identity providers.</param>
/// <param name="identityConverters">The identity converters.</param>
/// <param name="metadataProviders">The metadata providers.</param>
/// <param name="savers">The savers.</param>
/// <param name="imageSavers">The image savers.</param>
/// <param name="externalIds">The external ids.</param>
void AddParts(IEnumerable<IImageProvider> imageProviders, IEnumerable<IMetadataService> metadataServices, IEnumerable<IMetadataProvider> metadataProviders,
void AddParts(IEnumerable<IImageProvider> imageProviders, IEnumerable<IMetadataService> metadataServices, IEnumerable<IItemIdentityProvider> identityProviders, IEnumerable<IItemIdentityConverter> identityConverters, IEnumerable<IMetadataProvider> metadataProviders,
IEnumerable<IMetadataSaver> savers,
IEnumerable<IImageSaver> imageSavers,
IEnumerable<IExternalId> externalIds);
@@ -136,5 +138,12 @@ namespace MediaBrowser.Controller.Providers
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{HttpResponseInfo}.</returns>
Task<HttpResponseInfo> GetSearchImage(string providerName, string url, CancellationToken cancellationToken);
IEnumerable<IItemIdentityProvider<TLookupInfo, TIdentity>> GetItemIdentityProviders<TLookupInfo, TIdentity>()
where TLookupInfo : ItemLookupInfo
where TIdentity : IItemIdentity;
IEnumerable<IItemIdentityConverter<TIdentity>> GetItemIdentityConverters<TIdentity>()
where TIdentity : IItemIdentity;
}
}

View File

@@ -0,0 +1,73 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Providers
{
public class ItemIdentifier<TLookupInfo, TIdentity>
where TLookupInfo : ItemLookupInfo
where TIdentity : IItemIdentity
{
public async Task<IEnumerable<TIdentity>> FindIdentities(TLookupInfo item, IProviderManager providerManager, CancellationToken cancellationToken)
{
var providers = providerManager.GetItemIdentityProviders<TLookupInfo, TIdentity>();
var converters = providerManager.GetItemIdentityConverters<TIdentity>();
var identities = new List<IdentityPair>();
foreach (var provider in providers)
{
var result = new IdentityPair
{
Identity = await provider.FindIdentity(item),
Order = provider.Order
};
if (!Equals(result.Identity, default(TIdentity)))
{
identities.Add(result);
}
}
var convertersAvailable = new List<IItemIdentityConverter<TIdentity>>(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
};
if (!Equals(result.Identity, default(TIdentity)))
{
identities.Add(result);
convertersAvailable.RemoveAt(i);
changesMade = true;
}
}
}
} while (changesMade);
return identities.OrderBy(id => id.Order).Select(id => id.Identity);
}
private class IdentityPair
{
public TIdentity Identity;
public int Order;
}
}
}

View File

@@ -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<out TIdentity>
where TIdentity : IItemIdentity
{
IEnumerable<TIdentity> Identities { get; }
Task FindIdentities(IProviderManager providerManager, CancellationToken cancellationToken);
}
public interface IItemIdentityProvider : IHasOrder { }
public interface IItemIdentityProvider<in TLookupInfo, TIdentity> : IItemIdentityProvider
where TLookupInfo : ItemLookupInfo
where TIdentity : IItemIdentity
{
Task<TIdentity> FindIdentity(TLookupInfo info);
}
public interface IItemIdentityConverter : IHasOrder { }
public interface IItemIdentityConverter<TIdentity> : IItemIdentityConverter
where TIdentity : IItemIdentity
{
Task<TIdentity> Convert(TIdentity identity);
string SourceType { get; }
string ResultType { get; }
}
}

View File

@@ -1,4 +1,7 @@
using MediaBrowser.Model.Entities;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
@@ -96,8 +99,10 @@ namespace MediaBrowser.Controller.Providers
public string Path { get; set; }
}
public class EpisodeInfo : ItemLookupInfo
public class EpisodeInfo : ItemLookupInfo, IHasIdentities<EpisodeIdentity>
{
private List<EpisodeIdentity> _identities = new List<EpisodeIdentity>();
public Dictionary<string, string> SeriesProviderIds { get; set; }
public int? IndexNumberEnd { get; set; }
@@ -107,6 +112,27 @@ namespace MediaBrowser.Controller.Providers
{
SeriesProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}
public IEnumerable<EpisodeIdentity> Identities
{
get { return _identities; }
}
public async Task FindIdentities(IProviderManager providerManager, CancellationToken cancellationToken)
{
var identifier = new ItemIdentifier<EpisodeInfo, EpisodeIdentity>();
_identities = (await identifier.FindIdentities(this, providerManager, cancellationToken)).ToList();
}
}
public class EpisodeIdentity : IItemIdentity
{
public string Type { get; set; }
public string SeriesId { get; set; }
public int? SeasonIndex { get; set; }
public int IndexNumber { get; set; }
public int? IndexNumberEnd { get; set; }
}
public class SongInfo : ItemLookupInfo
@@ -116,9 +142,29 @@ namespace MediaBrowser.Controller.Providers
public List<string> Artists { get; set; }
}
public class SeriesInfo : ItemLookupInfo
public class SeriesInfo : ItemLookupInfo, IHasIdentities<SeriesIdentity>
{
private List<SeriesIdentity> _identities = new List<SeriesIdentity>();
public int? AnimeSeriesIndex { get; set; }
public IEnumerable<SeriesIdentity> Identities
{
get { return _identities; }
}
public async Task FindIdentities(IProviderManager providerManager, CancellationToken cancellationToken)
{
var identifier = new ItemIdentifier<SeriesInfo, SeriesIdentity>();
_identities = (await identifier.FindIdentities(this, providerManager, cancellationToken)).ToList();
}
}
public class SeriesIdentity : IItemIdentity
{
public string Type { get; set; }
public string Id { get; set; }
}
public class PersonLookupInfo : ItemLookupInfo
@@ -151,8 +197,10 @@ namespace MediaBrowser.Controller.Providers
public string SeriesName { get; set; }
}
public class SeasonInfo : ItemLookupInfo
public class SeasonInfo : ItemLookupInfo, IHasIdentities<SeasonIdentity>
{
private List<SeasonIdentity> _identities = new List<SeasonIdentity>();
public Dictionary<string, string> SeriesProviderIds { get; set; }
public int? AnimeSeriesIndex { get; set; }
@@ -160,5 +208,25 @@ namespace MediaBrowser.Controller.Providers
{
SeriesProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}
public IEnumerable<SeasonIdentity> Identities
{
get { return _identities; }
}
public async Task FindIdentities(IProviderManager providerManager, CancellationToken cancellationToken)
{
var identifier = new ItemIdentifier<SeasonInfo, SeasonIdentity>();
_identities = (await identifier.FindIdentities(this, providerManager, cancellationToken)).ToList();
}
}
public class SeasonIdentity : IItemIdentity
{
public string Type { get; set; }
public string SeriesId { get; set; }
public int SeasonIndex { get; set; }
}
}