mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-03-25 11:36:35 +00:00
Merge pull request #811 from thogil/item_identity_providers_2
Item identity providers
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
73
MediaBrowser.Controller/Providers/ItemIdentifier.cs
Normal file
73
MediaBrowser.Controller/Providers/ItemIdentifier.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
43
MediaBrowser.Controller/Providers/ItemIdentities.cs
Normal file
43
MediaBrowser.Controller/Providers/ItemIdentities.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user