You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
jellyfin/MediaBrowser.Controller/Providers/ItemIdentifier.cs

73 lines
2.6 KiB

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;
}
}
}