diff options
Diffstat (limited to 'MediaBrowser.Controller')
7 files changed, 210 insertions, 5 deletions
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index b7edbfc60..a2ff1b4fd 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -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> diff --git a/MediaBrowser.Controller/Entities/IHasMetadata.cs b/MediaBrowser.Controller/Entities/IHasMetadata.cs index 91f37135f..4e90fb155 100644 --- a/MediaBrowser.Controller/Entities/IHasMetadata.cs +++ b/MediaBrowser.Controller/Entities/IHasMetadata.cs @@ -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; } } } diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 7bc82f76d..addcaea8d 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -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" /> diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs index 94b19498a..883fa12b4 100644 --- a/MediaBrowser.Controller/Providers/IProviderManager.cs +++ b/MediaBrowser.Controller/Providers/IProviderManager.cs @@ -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; } }
\ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/ItemIdentifier.cs b/MediaBrowser.Controller/Providers/ItemIdentifier.cs new file mode 100644 index 000000000..13e4f137f --- /dev/null +++ b/MediaBrowser.Controller/Providers/ItemIdentifier.cs @@ -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; + } + } +}
\ No newline at end of file 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<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; } + } +}
\ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/ItemLookupInfo.cs b/MediaBrowser.Controller/Providers/ItemLookupInfo.cs index 65ee94556..20bc572b4 100644 --- a/MediaBrowser.Controller/Providers/ItemLookupInfo.cs +++ b/MediaBrowser.Controller/Providers/ItemLookupInfo.cs @@ -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; } } } |
