aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Controller')
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs4
-rw-r--r--MediaBrowser.Controller/Entities/IHasMetadata.cs6
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj2
-rw-r--r--MediaBrowser.Controller/Providers/IProviderManager.cs11
-rw-r--r--MediaBrowser.Controller/Providers/ItemIdentifier.cs73
-rw-r--r--MediaBrowser.Controller/Providers/ItemIdentities.cs43
-rw-r--r--MediaBrowser.Controller/Providers/ItemLookupInfo.cs76
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; }
}
}