From 556b34d0005dce04d6a798334fd37ba284cef3fd Mon Sep 17 00:00:00 2001 From: Thomas Gillen Date: Sat, 19 Sep 2015 22:25:19 +0100 Subject: [PATCH] Re-designed item identity providers --- MediaBrowser.Controller/Entities/BaseItem.cs | 6 +- .../Entities/IHasMetadata.cs | 7 +- .../MediaBrowser.Controller.csproj | 5 - .../Providers/EpisodeIdentity.cs | 12 -- .../Providers/EpisodeInfo.cs | 18 +-- .../Providers/IHasIdentities.cs | 14 --- .../Providers/IItemIdentity.cs | 7 -- .../Providers/IItemIdentityConverter.cs | 2 +- .../Providers/IItemIdentityProvider.cs | 2 +- .../Providers/IProviderManager.cs | 12 +- .../Providers/ItemIdentifier.cs | 63 ++-------- .../Providers/ItemIdentities.cs | 15 +-- .../Providers/SeasonIdentity.cs | 11 -- .../Providers/SeasonInfo.cs | 18 +-- .../Providers/SeriesIdentity.cs | 9 -- .../Providers/SeriesInfo.cs | 20 +-- .../Manager/MetadataService.cs | 36 +----- .../Manager/ProviderManager.cs | 11 +- .../TV/TvdbEpisodeProvider.cs | 117 ++++++++++++++---- .../TV/TvdbSeasonIdentityProvider.cs | 46 +++++-- .../TV/TvdbSeasonImageProvider.cs | 25 ++-- .../TV/TvdbSeriesProvider.cs | 39 ++---- 22 files changed, 188 insertions(+), 307 deletions(-) delete mode 100644 MediaBrowser.Controller/Providers/EpisodeIdentity.cs delete mode 100644 MediaBrowser.Controller/Providers/IHasIdentities.cs delete mode 100644 MediaBrowser.Controller/Providers/IItemIdentity.cs delete mode 100644 MediaBrowser.Controller/Providers/SeasonIdentity.cs delete mode 100644 MediaBrowser.Controller/Providers/SeriesIdentity.cs diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 25e742e7c..d413bda9b 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -38,7 +38,6 @@ namespace MediaBrowser.Controller.Entities ProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase); LockedFields = new List(); ImageInfos = new List(); - Identities = new List(); } /// @@ -336,10 +335,7 @@ namespace MediaBrowser.Controller.Entities public bool IsLocked { get; set; } public bool IsUnidentified { get; set; } - - [IgnoreDataMember] - public List Identities { get; set; } - + /// /// Gets or sets the locked fields. /// diff --git a/MediaBrowser.Controller/Entities/IHasMetadata.cs b/MediaBrowser.Controller/Entities/IHasMetadata.cs index 158bcb6d1..9d54541f1 100644 --- a/MediaBrowser.Controller/Entities/IHasMetadata.cs +++ b/MediaBrowser.Controller/Entities/IHasMetadata.cs @@ -49,12 +49,7 @@ namespace MediaBrowser.Controller.Entities /// /// true if this instance is unidentified; otherwise, false. bool IsUnidentified { get; set; } - - /// - /// Gets the item identities. - /// - List Identities { get; set; } - + /// /// Afters the metadata refresh. /// diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index ea6e98ea6..a3e00359f 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -268,7 +268,6 @@ - @@ -282,14 +281,12 @@ - - @@ -314,9 +311,7 @@ - - diff --git a/MediaBrowser.Controller/Providers/EpisodeIdentity.cs b/MediaBrowser.Controller/Providers/EpisodeIdentity.cs deleted file mode 100644 index 53f469e95..000000000 --- a/MediaBrowser.Controller/Providers/EpisodeIdentity.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace MediaBrowser.Controller.Providers -{ - 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; } - } -} \ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/EpisodeInfo.cs b/MediaBrowser.Controller/Providers/EpisodeInfo.cs index 88a7cbab7..28abd636a 100644 --- a/MediaBrowser.Controller/Providers/EpisodeInfo.cs +++ b/MediaBrowser.Controller/Providers/EpisodeInfo.cs @@ -1,15 +1,10 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; namespace MediaBrowser.Controller.Providers { - public class EpisodeInfo : ItemLookupInfo, IHasIdentities + public class EpisodeInfo : ItemLookupInfo { - private List _identities = new List(); - public Dictionary SeriesProviderIds { get; set; } public int? IndexNumberEnd { get; set; } @@ -19,16 +14,5 @@ namespace MediaBrowser.Controller.Providers { SeriesProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase); } - - public IEnumerable Identities - { - get { return _identities; } - } - - public async Task FindIdentities(IProviderManager providerManager, CancellationToken cancellationToken) - { - var identifier = new ItemIdentifier(); - _identities = (await identifier.FindIdentities(this, providerManager, cancellationToken)).ToList(); - } } } \ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/IHasIdentities.cs b/MediaBrowser.Controller/Providers/IHasIdentities.cs deleted file mode 100644 index 36f940dd3..000000000 --- a/MediaBrowser.Controller/Providers/IHasIdentities.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.Providers -{ - public interface IHasIdentities - where TIdentity : IItemIdentity - { - IEnumerable Identities { get; } - - Task FindIdentities(IProviderManager providerManager, CancellationToken cancellationToken); - } -} \ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/IItemIdentity.cs b/MediaBrowser.Controller/Providers/IItemIdentity.cs deleted file mode 100644 index cab189c84..000000000 --- a/MediaBrowser.Controller/Providers/IItemIdentity.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace MediaBrowser.Controller.Providers -{ - public interface IItemIdentity - { - string Type { get; } - } -} \ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/IItemIdentityConverter.cs b/MediaBrowser.Controller/Providers/IItemIdentityConverter.cs index 30e96b9e5..bfdd1dbf3 100644 --- a/MediaBrowser.Controller/Providers/IItemIdentityConverter.cs +++ b/MediaBrowser.Controller/Providers/IItemIdentityConverter.cs @@ -1,4 +1,4 @@ namespace MediaBrowser.Controller.Providers { - public interface IItemIdentityConverter : IHasOrder { } + public interface IItemIdentityConverter { } } \ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/IItemIdentityProvider.cs b/MediaBrowser.Controller/Providers/IItemIdentityProvider.cs index 9d437c208..6b403bb55 100644 --- a/MediaBrowser.Controller/Providers/IItemIdentityProvider.cs +++ b/MediaBrowser.Controller/Providers/IItemIdentityProvider.cs @@ -1,4 +1,4 @@ namespace MediaBrowser.Controller.Providers { - public interface IItemIdentityProvider : IHasOrder { } + public interface IItemIdentityProvider { } } \ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs index d6fc39c5f..57e4ff320 100644 --- a/MediaBrowser.Controller/Providers/IProviderManager.cs +++ b/MediaBrowser.Controller/Providers/IProviderManager.cs @@ -195,18 +195,16 @@ namespace MediaBrowser.Controller.Providers /// Gets the item identity providers. /// /// The type of the t lookup information. - /// The type of the t identity. /// IEnumerable<IItemIdentityProvider<TLookupInfo, TIdentity>>. - IEnumerable> GetItemIdentityProviders() - where TLookupInfo : ItemLookupInfo - where TIdentity : IItemIdentity; + IEnumerable> GetItemIdentityProviders() + where TLookupInfo : ItemLookupInfo; /// /// Gets the item identity converters. /// - /// The type of the t identity. + /// The type of the t lookup information. /// IEnumerable<IItemIdentityConverter<TIdentity>>. - IEnumerable> GetItemIdentityConverters() - where TIdentity : IItemIdentity; + IEnumerable> GetItemIdentityConverters() + where TLookupInfo : ItemLookupInfo; } } \ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/ItemIdentifier.cs b/MediaBrowser.Controller/Providers/ItemIdentifier.cs index 13e4f137f..bbc6dd76c 100644 --- a/MediaBrowser.Controller/Providers/ItemIdentifier.cs +++ b/MediaBrowser.Controller/Providers/ItemIdentifier.cs @@ -1,73 +1,36 @@ -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Controller.Providers { - public class ItemIdentifier + public static class ItemIdentifier where TLookupInfo : ItemLookupInfo - where TIdentity : IItemIdentity { - public async Task> FindIdentities(TLookupInfo item, IProviderManager providerManager, CancellationToken cancellationToken) + public static async Task FindIdentities(TLookupInfo item, IProviderManager providerManager, CancellationToken cancellationToken) { - var providers = providerManager.GetItemIdentityProviders(); - var converters = providerManager.GetItemIdentityConverters(); - - var identities = new List(); - + var providers = providerManager.GetItemIdentityProviders(); + var converters = providerManager.GetItemIdentityConverters().ToList(); + 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); - } + await provider.Identify(item); } - var convertersAvailable = new List>(converters); - bool changesMade; + bool changesMade = true; - do + while (changesMade) { changesMade = false; - for (int i = convertersAvailable.Count - 1; i >= 0; i--) + foreach (var converter in converters) { - 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)) + if (await converter.Convert(item)) { - 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; - } + 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 index 939fd3b8f..48316d0f4 100644 --- a/MediaBrowser.Controller/Providers/ItemIdentities.cs +++ b/MediaBrowser.Controller/Providers/ItemIdentities.cs @@ -2,20 +2,15 @@ namespace MediaBrowser.Controller.Providers { - public interface IItemIdentityProvider : IItemIdentityProvider + public interface IItemIdentityProvider : IItemIdentityProvider where TLookupInfo : ItemLookupInfo - where TIdentity : IItemIdentity { - Task FindIdentity(TLookupInfo info); + Task Identify(TLookupInfo info); } - public interface IItemIdentityConverter : IItemIdentityConverter - where TIdentity : IItemIdentity + public interface IItemIdentityConverter : IItemIdentityConverter + where TLookupInfo : ItemLookupInfo { - Task Convert(TIdentity identity); - - string SourceType { get; } - - string ResultType { get; } + Task Convert(TLookupInfo info); } } \ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/SeasonIdentity.cs b/MediaBrowser.Controller/Providers/SeasonIdentity.cs deleted file mode 100644 index 1e6b9b65a..000000000 --- a/MediaBrowser.Controller/Providers/SeasonIdentity.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace MediaBrowser.Controller.Providers -{ - public class SeasonIdentity : IItemIdentity - { - public string Type { get; set; } - - public string SeriesId { get; set; } - - public int SeasonIndex { get; set; } - } -} \ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/SeasonInfo.cs b/MediaBrowser.Controller/Providers/SeasonInfo.cs index 17bcd3f77..2c785d7d7 100644 --- a/MediaBrowser.Controller/Providers/SeasonInfo.cs +++ b/MediaBrowser.Controller/Providers/SeasonInfo.cs @@ -1,15 +1,10 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; namespace MediaBrowser.Controller.Providers { - public class SeasonInfo : ItemLookupInfo, IHasIdentities + public class SeasonInfo : ItemLookupInfo { - private List _identities = new List(); - public Dictionary SeriesProviderIds { get; set; } public int? AnimeSeriesIndex { get; set; } @@ -17,16 +12,5 @@ namespace MediaBrowser.Controller.Providers { SeriesProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase); } - - public IEnumerable Identities - { - get { return _identities; } - } - - public async Task FindIdentities(IProviderManager providerManager, CancellationToken cancellationToken) - { - var identifier = new ItemIdentifier(); - _identities = (await identifier.FindIdentities(this, providerManager, cancellationToken)).ToList(); - } } } \ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/SeriesIdentity.cs b/MediaBrowser.Controller/Providers/SeriesIdentity.cs deleted file mode 100644 index 326d34027..000000000 --- a/MediaBrowser.Controller/Providers/SeriesIdentity.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace MediaBrowser.Controller.Providers -{ - public class SeriesIdentity : IItemIdentity - { - public string Type { get; set; } - - public string Id { get; set; } - } -} \ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/SeriesInfo.cs b/MediaBrowser.Controller/Providers/SeriesInfo.cs index fc1119cd2..387865de2 100644 --- a/MediaBrowser.Controller/Providers/SeriesInfo.cs +++ b/MediaBrowser.Controller/Providers/SeriesInfo.cs @@ -1,25 +1,7 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - namespace MediaBrowser.Controller.Providers { - public class SeriesInfo : ItemLookupInfo, IHasIdentities + public class SeriesInfo : ItemLookupInfo { - private List _identities = new List(); - public int? AnimeSeriesIndex { get; set; } - - public IEnumerable Identities - { - get { return _identities; } - } - - public async Task FindIdentities(IProviderManager providerManager, CancellationToken cancellationToken) - { - var identifier = new ItemIdentifier(); - _identities = (await identifier.FindIdentities(this, providerManager, cancellationToken)).ToList(); - } } } \ No newline at end of file diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 8a60ea78f..71cfea209 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -141,7 +141,8 @@ namespace MediaBrowser.Providers.Manager if (providers.Count > 0) { - var id = await CreateInitialLookupInfo(itemOfType, cancellationToken).ConfigureAwait(false); + var id = itemOfType.GetLookupInfo(); + await ItemIdentifier.FindIdentities(id, ProviderManager, cancellationToken); var result = await RefreshWithProviders(metadataResult, id, refreshOptions, providers, itemImageProvider, cancellationToken).ConfigureAwait(false); @@ -155,8 +156,6 @@ namespace MediaBrowser.Providers.Manager { refreshResult.SetDateLastMetadataRefresh(null); } - - MergeIdentities(itemOfType, id); } } @@ -223,16 +222,7 @@ namespace MediaBrowser.Providers.Manager item.AfterMetadataRefresh(); return _cachedTask; } - - private void MergeIdentities(TItemType item, TIdType id) - { - var hasIdentity = id as IHasIdentities; - if (hasIdentity != null) - { - item.Identities = hasIdentity.Identities.ToList(); - } - } - + private readonly Task _cachedResult = Task.FromResult(ItemUpdateType.None); /// /// Befores the save. @@ -623,26 +613,6 @@ namespace MediaBrowser.Providers.Manager } } - private async Task CreateInitialLookupInfo(TItemType item, CancellationToken cancellationToken) - { - var info = item.GetLookupInfo(); - - var hasIdentity = info as IHasIdentities; - if (hasIdentity != null) - { - try - { - await hasIdentity.FindIdentities(ProviderManager, cancellationToken).ConfigureAwait(false); - } - catch (Exception ex) - { - Logger.ErrorException("Error in identity providers", ex); - } - } - - return info; - } - private void MergeNewData(TItemType source, TIdType lookupInfo) { // Copy new provider id's that may have been obtained diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 80264d848..16d5a8de4 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -298,17 +298,16 @@ namespace MediaBrowser.Providers.Manager .ThenBy(GetDefaultOrder); } - public IEnumerable> GetItemIdentityProviders() + public IEnumerable> GetItemIdentityProviders() where TLookupInfo : ItemLookupInfo - where TIdentity : IItemIdentity { - return _identityProviders.OfType>(); + return _identityProviders.OfType>(); } - public IEnumerable> GetItemIdentityConverters() - where TIdentity : IItemIdentity + public IEnumerable> GetItemIdentityConverters() + where TLookupInfo : ItemLookupInfo { - return _identityConverters.OfType>(); + return _identityConverters.OfType>(); } private IEnumerable GetRemoteImageProviders(IHasImages item, bool includeDisabled) diff --git a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs index 1702a5044..0fda7edae 100644 --- a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs @@ -24,8 +24,11 @@ namespace MediaBrowser.Providers.TV /// /// Class RemoteEpisodeProvider /// - class TvdbEpisodeProvider : IRemoteMetadataProvider, IItemIdentityProvider, IHasChangeMonitor + class TvdbEpisodeProvider : IRemoteMetadataProvider, IItemIdentityProvider, IHasChangeMonitor { + private const string FullIdFormat = "{0}:{1}:{2}"; // seriesId:seasonIndex:episodeNumbers + private static readonly string FullIdKey = MetadataProviders.Tvdb + "-Full"; + internal static TvdbEpisodeProvider Current; private readonly IFileSystem _fileSystem; private readonly IServerConfigurationManager _config; @@ -45,18 +48,24 @@ namespace MediaBrowser.Providers.TV { var list = new List(); - var identity = searchInfo.Identities.FirstOrDefault(id => id.Type == MetadataProviders.Tvdb.ToString()) ?? await FindIdentity(searchInfo).ConfigureAwait(false); + var identity = ParseIdentity(searchInfo.GetProviderId(FullIdKey)); + + if (identity == null) + { + await Identify(searchInfo).ConfigureAwait(false); + identity = ParseIdentity(searchInfo.GetProviderId(FullIdKey)); + } if (identity != null) { - await TvdbSeriesProvider.Current.EnsureSeriesInfo(identity.SeriesId, searchInfo.MetadataLanguage, + await TvdbSeriesProvider.Current.EnsureSeriesInfo(identity.Value.SeriesId, searchInfo.MetadataLanguage, cancellationToken).ConfigureAwait(false); - var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, identity.SeriesId); + var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, identity.Value.SeriesId); try { - var metadataResult = FetchEpisodeData(searchInfo, identity, seriesDataPath, searchInfo.SeriesProviderIds, cancellationToken); + var metadataResult = FetchEpisodeData(searchInfo, identity.Value, seriesDataPath, searchInfo.SeriesProviderIds, cancellationToken); if (metadataResult.HasMetadata) { @@ -95,17 +104,23 @@ namespace MediaBrowser.Providers.TV public async Task> GetMetadata(EpisodeInfo searchInfo, CancellationToken cancellationToken) { - var identity = searchInfo.Identities.FirstOrDefault(id => id.Type == MetadataProviders.Tvdb.ToString()) ?? await FindIdentity(searchInfo).ConfigureAwait(false); + var identity = ParseIdentity(searchInfo.GetProviderId(FullIdKey)); + + if (identity == null) + { + await Identify(searchInfo).ConfigureAwait(false); + identity = ParseIdentity(searchInfo.GetProviderId(FullIdKey)); + } var result = new MetadataResult(); if (identity != null) { - var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, identity.SeriesId); + var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, identity.Value.SeriesId); try { - result = FetchEpisodeData(searchInfo, identity, seriesDataPath, searchInfo.SeriesProviderIds, cancellationToken); + result = FetchEpisodeData(searchInfo, identity.Value, seriesDataPath, searchInfo.SeriesProviderIds, cancellationToken); } catch (FileNotFoundException) { @@ -231,9 +246,9 @@ namespace MediaBrowser.Providers.TV /// The series provider ids. /// The cancellation token. /// Task{System.Boolean}. - private MetadataResult FetchEpisodeData(EpisodeInfo id, EpisodeIdentity identity, string seriesDataPath, Dictionary seriesProviderIds, CancellationToken cancellationToken) + private MetadataResult FetchEpisodeData(EpisodeInfo id, Identity identity, string seriesDataPath, Dictionary seriesProviderIds, CancellationToken cancellationToken) { - var episodeNumber = identity.IndexNumber; + var episodeNumber = identity.EpisodeNumber; var seasonOffset = TvdbSeriesProvider.GetSeriesOffset(seriesProviderIds) ?? 0; var seasonNumber = identity.SeasonIndex + seasonOffset; @@ -278,7 +293,7 @@ namespace MediaBrowser.Providers.TV usingAbsoluteData = true; } - var end = identity.IndexNumberEnd ?? episodeNumber; + var end = identity.EpisodeNumberEnd ?? episodeNumber; episodeNumber++; while (episodeNumber <= end) @@ -753,28 +768,86 @@ namespace MediaBrowser.Providers.TV }); } - public Task FindIdentity(EpisodeInfo info) + public Task Identify(EpisodeInfo info) { + if (info.ProviderIds.ContainsKey(FullIdKey)) + { + return Task.FromResult(null); + } + string seriesTvdbId; info.SeriesProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(), out seriesTvdbId); if (string.IsNullOrEmpty(seriesTvdbId) || info.IndexNumber == null) { - return Task.FromResult(null); + return Task.FromResult(null); } - - var id = new EpisodeIdentity - { - Type = MetadataProviders.Tvdb.ToString(), - SeriesId = seriesTvdbId, - SeasonIndex = info.ParentIndexNumber, - IndexNumber = info.IndexNumber.Value, - IndexNumberEnd = info.IndexNumberEnd - }; + + var number = info.IndexNumber.Value.ToString(); + if (info.IndexNumberEnd != null) + number += "-" + info.IndexNumberEnd; + + var id = string.Format( + FullIdFormat, + seriesTvdbId, + info.ParentIndexNumber.HasValue ? info.ParentIndexNumber.Value.ToString() : "A", + number); + + info.SetProviderId(FullIdKey, FullIdFormat); return Task.FromResult(id); } + private Identity? ParseIdentity(string id) + { + if (string.IsNullOrEmpty(id)) + return null; + + try + { + var parts = id.Split(':'); + var series = parts[0]; + var season = parts[1] != "A" ? (int?) int.Parse(parts[1]) : null; + + int index; + int? indexEnd; + + if (parts[2].Contains("-")) + { + var split = parts[2].IndexOf("-", StringComparison.OrdinalIgnoreCase); + index = int.Parse(parts[2].Substring(0, split)); + indexEnd = int.Parse(parts[2].Substring(split + 1)); + } + else + { + index = int.Parse(parts[2]); + indexEnd = null; + } + + return new Identity(series, season, index, indexEnd); + } + catch + { + return null; + } + } + public int Order { get { return 0; } } + + private struct Identity + { + public string SeriesId { get; private set; } + public int? SeasonIndex { get; private set; } + public int EpisodeNumber { get; private set; } + public int? EpisodeNumberEnd { get; private set; } + + public Identity(string seriesId, int? seasonIndex, int episodeNumber, int? episodeNumberEnd) + { + SeriesId = seriesId; + SeasonIndex = seasonIndex; + EpisodeNumber = episodeNumber; + EpisodeNumberEnd = episodeNumberEnd; + } + } } } diff --git a/MediaBrowser.Providers/TV/TvdbSeasonIdentityProvider.cs b/MediaBrowser.Providers/TV/TvdbSeasonIdentityProvider.cs index 5876c9998..3f95c18b9 100644 --- a/MediaBrowser.Providers/TV/TvdbSeasonIdentityProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeasonIdentityProvider.cs @@ -4,26 +4,50 @@ using MediaBrowser.Model.Entities; namespace MediaBrowser.Providers.TV { - public class TvdbSeasonIdentityProvider : IItemIdentityProvider + public class TvdbSeasonIdentityProvider : IItemIdentityProvider { - public Task FindIdentity(SeasonInfo info) + public static readonly string FullIdKey = MetadataProviders.Tvdb + "-Full"; + + public Task Identify(SeasonInfo info) { string tvdbSeriesId; if (!info.SeriesProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(), out tvdbSeriesId) || string.IsNullOrEmpty(tvdbSeriesId) || info.IndexNumber == null) { - return Task.FromResult(null); + return Task.FromResult(null); } - var result = new SeasonIdentity + if (string.IsNullOrEmpty(info.GetProviderId(FullIdKey))) { - Type = MetadataProviders.Tvdb.ToString(), - SeriesId = tvdbSeriesId, - SeasonIndex = info.IndexNumber.Value - }; - - return Task.FromResult(result); + var id = string.Format("{0}:{1}", tvdbSeriesId, info.IndexNumber.Value); + info.SetProviderId(FullIdKey, id); + } + + return Task.FromResult(null); } - public int Order { get { return 0; } } + public static TvdbSeasonIdentity? ParseIdentity(string id) + { + try + { + var parts = id.Split(':'); + return new TvdbSeasonIdentity(parts[0], int.Parse(parts[1])); + } + catch + { + return null; + } + } + } + + public struct TvdbSeasonIdentity + { + public string SeriesId { get; private set; } + public int Index { get; private set; } + + public TvdbSeasonIdentity(string seriesId, int index) + { + SeriesId = seriesId; + Index = index; + } } } \ No newline at end of file diff --git a/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs b/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs index 4dbf05d53..7f6224e5b 100644 --- a/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs @@ -65,26 +65,23 @@ namespace MediaBrowser.Providers.TV var season = (Season)item; var series = season.Series; - var seriesId = series != null ? series.GetProviderId(MetadataProviders.Tvdb) : null; - - if (!string.IsNullOrEmpty(seriesId) && season.IndexNumber.HasValue) + var identity = TvdbSeasonIdentityProvider.ParseIdentity(season.GetProviderId(TvdbSeasonIdentityProvider.FullIdKey)); + if (identity == null && series != null && season.IndexNumber.HasValue) { - await TvdbSeriesProvider.Current.EnsureSeriesInfo(seriesId, series.GetPreferredMetadataLanguage(), cancellationToken).ConfigureAwait(false); + identity = new TvdbSeasonIdentity(series.GetProviderId(MetadataProviders.Tvdb), season.IndexNumber.Value); + } + + if (identity != null && series != null) + { + var id = identity.Value; + await TvdbSeriesProvider.Current.EnsureSeriesInfo(id.SeriesId, series.GetPreferredMetadataLanguage(), cancellationToken).ConfigureAwait(false); // Process images - var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, seriesId); + var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, id.SeriesId); var path = Path.Combine(seriesDataPath, "banners.xml"); - var identity = season.Identities.OfType() - .FirstOrDefault(id => id.Type == MetadataProviders.Tvdb.ToString()); - - var seasonNumber = season.IndexNumber.Value; - - if (identity != null) - { - seasonNumber = AdjustForSeriesOffset(series, identity.SeasonIndex); - } + var seasonNumber = AdjustForSeriesOffset(series, id.Index); try { diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs index 56e9dbd03..827e8bc53 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs @@ -25,7 +25,7 @@ using System.Xml; namespace MediaBrowser.Providers.TV { - public class TvdbSeriesProvider : IRemoteMetadataProvider, IItemIdentityProvider, IHasOrder + public class TvdbSeriesProvider : IRemoteMetadataProvider, IItemIdentityProvider, IHasOrder { private const string TvdbSeriesOffset = "TvdbSeriesOffset"; private const string TvdbSeriesOffsetFormat = "{0}-{1}"; @@ -94,24 +94,10 @@ namespace MediaBrowser.Providers.TV if (string.IsNullOrWhiteSpace(seriesId)) { - seriesId = itemId.Identities - .Where(id => id.Type == MetadataProviders.Tvdb.ToString()) - .Select(id => id.Id) - .FirstOrDefault(); - - if (string.IsNullOrWhiteSpace(seriesId)) - { - var srch = await GetSearchResults(itemId, cancellationToken).ConfigureAwait(false); - - var entry = srch.FirstOrDefault(); - - if (entry != null) - { - seriesId = entry.GetProviderId(MetadataProviders.Tvdb); - } - } + await Identify(itemId).ConfigureAwait(false); + seriesId = itemId.GetProviderId(MetadataProviders.Tvdb); } - + cancellationToken.ThrowIfCancellationRequested(); if (!string.IsNullOrWhiteSpace(seriesId)) @@ -1239,27 +1225,20 @@ namespace MediaBrowser.Providers.TV get { return "TheTVDB"; } } - public async Task FindIdentity(SeriesInfo info) + public async Task Identify(SeriesInfo info) { - string tvdbId; - if (!info.ProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(), out tvdbId)) + if (string.IsNullOrEmpty(info.GetProviderId(MetadataProviders.Tvdb))) { - var srch = await GetSearchResults(info, CancellationToken.None).ConfigureAwait(false); + var srch = await FindSeries(info.Name, info.MetadataLanguage, CancellationToken.None).ConfigureAwait(false); var entry = srch.FirstOrDefault(); if (entry != null) { - tvdbId = entry.GetProviderId(MetadataProviders.Tvdb); + var id = entry.GetProviderId(MetadataProviders.Tvdb); + info.SetProviderId(MetadataProviders.Tvdb, id); } } - - if (!string.IsNullOrWhiteSpace(tvdbId)) - { - return new SeriesIdentity { Type = MetadataProviders.Tvdb.ToString(), Id = tvdbId }; - } - - return null; } public int Order