From 42c233c74efe94b30192fc0b50b2ec15bd43bf36 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Thu, 7 Feb 2019 22:42:02 +0100 Subject: [PATCH] Add much needed exception handling and logging --- .../TV/TheTVDB/TvDbClientManager.cs | 23 ++++--- .../TV/TheTVDB/TvdbEpisodeImageProvider.cs | 24 +++++-- .../TV/TheTVDB/TvdbEpisodeProvider.cs | 65 +++++++++++-------- .../TV/TheTVDB/TvdbSeasonImageProvider.cs | 4 +- .../TV/TheTVDB/TvdbSeriesImageProvider.cs | 25 +++++-- .../TV/TheTVDB/TvdbSeriesProvider.cs | 44 +++++++++---- 6 files changed, 122 insertions(+), 63 deletions(-) diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvDbClientManager.cs b/MediaBrowser.Providers/TV/TheTVDB/TvDbClientManager.cs index 7af9863232..e789d2ded7 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvDbClientManager.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvDbClientManager.cs @@ -3,7 +3,6 @@ using System.Threading; using System.Threading.Tasks; using MediaBrowser.Controller.Library; using Microsoft.Extensions.Caching.Memory; -using Microsoft.Extensions.Internal; using TvDbSharper; using TvDbSharper.Dto; @@ -75,43 +74,47 @@ namespace MediaBrowser.Providers.TV public Task> GetSeriesByNameAsync(string name, CancellationToken cancellationToken) { - return TryGetValue(name,() => TvDbClient.Search.SearchSeriesByNameAsync(name, cancellationToken)); + return TryGetValue("series" + name,() => TvDbClient.Search.SearchSeriesByNameAsync(name, cancellationToken)); } public Task> GetSeriesByIdAsync(int tvdbId, CancellationToken cancellationToken) { - return TryGetValue(tvdbId,() => TvDbClient.Series.GetAsync(tvdbId, cancellationToken)); + return TryGetValue("series" + tvdbId,() => TvDbClient.Series.GetAsync(tvdbId, cancellationToken)); } - public Task> GetEpisodesAsync(int tvdbId, CancellationToken cancellationToken) + public Task> GetEpisodesAsync(int episodeTvdbId, CancellationToken cancellationToken) { - return TryGetValue(tvdbId,() => TvDbClient.Episodes.GetAsync(tvdbId, cancellationToken)); + return TryGetValue("episode" + episodeTvdbId,() => TvDbClient.Episodes.GetAsync(episodeTvdbId, cancellationToken)); } public Task> GetSeriesByImdbIdAsync(string imdbId, CancellationToken cancellationToken) { - return TryGetValue(imdbId,() => TvDbClient.Search.SearchSeriesByImdbIdAsync(imdbId, cancellationToken)); + return TryGetValue("series" + imdbId,() => TvDbClient.Search.SearchSeriesByImdbIdAsync(imdbId, cancellationToken)); } public Task> GetSeriesByZap2ItIdAsync(string zap2ItId, CancellationToken cancellationToken) { - return TryGetValue(zap2ItId,() => TvDbClient.Search.SearchSeriesByImdbIdAsync(zap2ItId, cancellationToken)); + return TryGetValue("series" + zap2ItId,() => TvDbClient.Search.SearchSeriesByImdbIdAsync(zap2ItId, cancellationToken)); } public Task> GetActorsAsync(int tvdbId, CancellationToken cancellationToken) { - return TryGetValue(tvdbId,() => TvDbClient.Series.GetActorsAsync(tvdbId, cancellationToken)); + return TryGetValue("actors" + tvdbId,() => TvDbClient.Series.GetActorsAsync(tvdbId, cancellationToken)); } public Task> GetImagesAsync(int tvdbId, ImagesQuery imageQuery, CancellationToken cancellationToken) { - return TryGetValue(tvdbId,() => TvDbClient.Series.GetImagesAsync(tvdbId, imageQuery, cancellationToken)); + return TryGetValue("images" + tvdbId,() => TvDbClient.Series.GetImagesAsync(tvdbId, imageQuery, cancellationToken)); + } + + public Task> GetLanguagesAsync(CancellationToken cancellationToken) + { + return TryGetValue("languages",() => TvDbClient.Languages.GetAllAsync(cancellationToken)); } private async Task TryGetValue(object key, Func> resultFactory) { if (_cache.TryGetValue(key, out T cachedValue)) { - Console.WriteLine("Cache hit!!!"); return cachedValue; } diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeImageProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeImageProvider.cs index 3f5d415afe..caa0a5aba2 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeImageProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeImageProvider.cs @@ -11,6 +11,7 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Providers; +using Microsoft.Extensions.Logging; using TvDbSharper; using TvDbSharper.Dto; @@ -19,11 +20,13 @@ namespace MediaBrowser.Providers.TV.TheTVDB public class TvdbEpisodeImageProvider : IRemoteImageProvider { private readonly IHttpClient _httpClient; + private readonly ILogger _logger; private readonly TvDbClientManager _tvDbClientManager; - public TvdbEpisodeImageProvider(IHttpClient httpClient) + public TvdbEpisodeImageProvider(IHttpClient httpClient, ILogger logger) { _httpClient = httpClient; + _logger = logger; _tvDbClientManager = TvDbClientManager.Instance; } @@ -51,13 +54,22 @@ namespace MediaBrowser.Providers.TV.TheTVDB if (series != null && TvdbSeriesProvider.IsValidSeries(series.ProviderIds)) { var tvdbId = episode.GetProviderId(MetadataProviders.Tvdb); - // Process images - var episodeResult = await _tvDbClientManager.GetEpisodesAsync(Convert.ToInt32(tvdbId), cancellationToken); - var image = GetImageInfo(episodeResult.Data); - if (image != null) + // Process images + try { - imageResult.Add(image); + var episodeResult = + await _tvDbClientManager.GetEpisodesAsync(Convert.ToInt32(tvdbId), cancellationToken); + + var image = GetImageInfo(episodeResult.Data); + if (image != null) + { + imageResult.Add(image); + } + } + catch (TvDbServerException e) + { + _logger.LogError(e, "Failed to retrieve episode images for {TvDbId}", tvdbId); } } diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs index c4891a66a0..68125d50a8 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs @@ -9,6 +9,7 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Providers; using Microsoft.Extensions.Logging; +using TvDbSharper; using TvDbSharper.Dto; namespace MediaBrowser.Providers.TV @@ -37,7 +38,7 @@ namespace MediaBrowser.Providers.TV var list = new List(); // The search query must either provide an episode number or date - // TODO premieredate functionality is ded + // TODO premieredate functionality is ded, could grab all episodes and search for it if (!searchInfo.IndexNumber.HasValue || !searchInfo.PremiereDate.HasValue) { return list; @@ -45,25 +46,32 @@ namespace MediaBrowser.Providers.TV if (TvdbSeriesProvider.IsValidSeries(searchInfo.SeriesProviderIds)) { - var episodeResult = - await _tvDbClientManager.GetEpisodesAsync((int)searchInfo.IndexNumber, cancellationToken); - var metadataResult = MapEpisodeToResult(searchInfo, episodeResult.Data); - - if (metadataResult.HasMetadata) + try { - var item = metadataResult.Item; + var episodeResult = + await _tvDbClientManager.GetEpisodesAsync((int)searchInfo.IndexNumber, cancellationToken); + var metadataResult = MapEpisodeToResult(searchInfo, episodeResult.Data); - list.Add(new RemoteSearchResult + if (metadataResult.HasMetadata) { - IndexNumber = item.IndexNumber, - Name = item.Name, - ParentIndexNumber = item.ParentIndexNumber, - PremiereDate = item.PremiereDate, - ProductionYear = item.ProductionYear, - ProviderIds = item.ProviderIds, - SearchProviderName = Name, - IndexNumberEnd = item.IndexNumberEnd - }); + var item = metadataResult.Item; + + list.Add(new RemoteSearchResult + { + IndexNumber = item.IndexNumber, + Name = item.Name, + ParentIndexNumber = item.ParentIndexNumber, + PremiereDate = item.PremiereDate, + ProductionYear = item.ProductionYear, + ProviderIds = item.ProviderIds, + SearchProviderName = Name, + IndexNumberEnd = item.IndexNumberEnd + }); + } + } + catch (TvDbServerException e) + { + _logger.LogError(e, "Failed to retrieve episode with id {TvDbId}", searchInfo.IndexNumber); } } @@ -82,10 +90,19 @@ namespace MediaBrowser.Providers.TV if (TvdbSeriesProvider.IsValidSeries(searchInfo.SeriesProviderIds) && (searchInfo.IndexNumber.HasValue || searchInfo.PremiereDate.HasValue)) { - var episodeResult = await _tvDbClientManager.GetEpisodesAsync(Convert.ToInt32(searchInfo.GetProviderId(MetadataProviders.Tvdb)), - cancellationToken); + var tvdbId = searchInfo.GetProviderId(MetadataProviders.Tvdb); + try + { + var episodeResult = await _tvDbClientManager.GetEpisodesAsync( + Convert.ToInt32(tvdbId), + cancellationToken); - result = MapEpisodeToResult(searchInfo, episodeResult.Data); + result = MapEpisodeToResult(searchInfo, episodeResult.Data); + } + catch (TvDbServerException e) + { + _logger.LogError(e, "Failed to retrieve episode with id {TvDbId}", tvdbId); + } } else { @@ -178,14 +195,8 @@ namespace MediaBrowser.Providers.TV Type = PersonType.Writer }); } - // TODO result.ResultLanguage = episode. - - // TODO wtf is additional part info? -// foreach (var node in xmlNodes.Skip(1)) -// { -// FetchAdditionalPartInfo(result, node, cancellationToken); -// } + result.ResultLanguage = episode.Language.EpisodeName; return result; } diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs index 7040779b4d..42c7bc5c38 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs @@ -93,7 +93,7 @@ namespace MediaBrowser.Providers.TV.TheTVDB private static IEnumerable GetImages(Image[] images, string preferredLanguage) { var list = new List(); - + var languages = TvDbClientManager.Instance.GetLanguagesAsync(CancellationToken.None).Result.Data; foreach (Image image in images) { var imageInfo = new RemoteImageInfo @@ -103,7 +103,7 @@ namespace MediaBrowser.Providers.TV.TheTVDB VoteCount = image.RatingsInfo.Count, Url = TVUtils.BannerUrl + image.FileName, ProviderName = ProviderName, - // TODO Language = image.LanguageId, + Language = languages.FirstOrDefault(l => l.Id == image.LanguageId)?.Abbreviation, ThumbnailUrl = TVUtils.BannerUrl + image.Thumbnail }; diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesImageProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesImageProvider.cs index 03c5502dcd..b9caf0b3a9 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesImageProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesImageProvider.cs @@ -10,6 +10,7 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Providers; +using Microsoft.Extensions.Logging; using TvDbSharper; using TvDbSharper.Dto; using RatingType = MediaBrowser.Model.Dto.RatingType; @@ -20,12 +21,13 @@ namespace MediaBrowser.Providers.TV.TheTVDB public class TvdbSeriesImageProvider : IRemoteImageProvider, IHasOrder { private readonly IHttpClient _httpClient; - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); + private readonly ILogger _logger; private readonly TvDbClientManager _tvDbClientManager; - public TvdbSeriesImageProvider(IHttpClient httpClient) + public TvdbSeriesImageProvider(IHttpClient httpClient, ILogger logger) { _httpClient = httpClient; + _logger = logger; _tvDbClientManager = TvDbClientManager.Instance; } @@ -59,17 +61,25 @@ namespace MediaBrowser.Providers.TV.TheTVDB _tvDbClientManager.TvDbClient.AcceptedLanguage = language; var remoteImages = new List(); var keyTypes = new[] {KeyType.Poster, KeyType.Series, KeyType.Fanart}; - // TODO error handling + var tvdbId = Convert.ToInt32(item.GetProviderId(MetadataProviders.Tvdb)); foreach (KeyType keyType in keyTypes) { var imageQuery = new ImagesQuery { KeyType = keyType }; - var imageResults = - await _tvDbClientManager.GetImagesAsync(Convert.ToInt32(item.GetProviderId(MetadataProviders.Tvdb)), imageQuery, cancellationToken); + try + { + var imageResults = + await _tvDbClientManager.GetImagesAsync(tvdbId, imageQuery, cancellationToken); - remoteImages.AddRange(GetImages(imageResults.Data, language)); + remoteImages.AddRange(GetImages(imageResults.Data, language)); + } + catch (TvDbServerException e) + { + _logger.LogError(e, "Failed to retrieve images of type {KeyType} for series {TvDbId}", keyType, + tvdbId); + } } return remoteImages; } @@ -77,6 +87,7 @@ namespace MediaBrowser.Providers.TV.TheTVDB private IEnumerable GetImages(Image[] images, string preferredLanguage) { var list = new List(); + var languages = TvDbClientManager.Instance.GetLanguagesAsync(CancellationToken.None).Result.Data; foreach (Image image in images) { @@ -87,7 +98,7 @@ namespace MediaBrowser.Providers.TV.TheTVDB VoteCount = image.RatingsInfo.Count, Url = TVUtils.BannerUrl + image.FileName, ProviderName = Name, - // TODO Language = image.LanguageId, + Language = languages.FirstOrDefault(l => l.Id == image.LanguageId)?.Abbreviation, ThumbnailUrl = TVUtils.BannerUrl + image.Thumbnail }; diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs index b431d5c7f6..9940cf7e42 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs @@ -123,33 +123,55 @@ namespace MediaBrowser.Providers.TV.TheTVDB tvdbId = await GetSeriesByRemoteId(zap2It, MetadataProviders.Zap2It.ToString(), metadataLanguage, cancellationToken); } - var seriesResult = await _tvDbClientManager.GetSeriesByIdAsync(Convert.ToInt32(tvdbId), cancellationToken); - - MapSeriesToResult(result, seriesResult.Data); + try + { + var seriesResult = + await _tvDbClientManager.GetSeriesByIdAsync(Convert.ToInt32(tvdbId), cancellationToken); + MapSeriesToResult(result, seriesResult.Data); + } + catch (TvDbServerException e) + { + _logger.LogError(e, "Failed to retrieve series with id {TvdbId}", tvdbId); + return; + } cancellationToken.ThrowIfCancellationRequested(); result.ResetPeople(); - var actorsResult = await _tvDbClientManager.GetActorsAsync(Convert.ToInt32(tvdbId), cancellationToken); - MapActorsToResult(result, actorsResult.Data); + try + { + var actorsResult = await _tvDbClientManager.GetActorsAsync(Convert.ToInt32(tvdbId), cancellationToken); + MapActorsToResult(result, actorsResult.Data); + } + catch (TvDbServerException e) + { + _logger.LogError(e, "Failed to retrieve actors for series {TvdbId}", tvdbId); + } } private async Task GetSeriesByRemoteId(string id, string idType, string language, CancellationToken cancellationToken) { _tvDbClientManager.TvDbClient.AcceptedLanguage = NormalizeLanguage(language); - TvDbResponse result; + TvDbResponse result = null; - if (string.Equals(idType, MetadataProviders.Zap2It.ToString(), StringComparison.OrdinalIgnoreCase)) + try { - result = await _tvDbClientManager.GetSeriesByZap2ItIdAsync(id, cancellationToken); + if (string.Equals(idType, MetadataProviders.Zap2It.ToString(), StringComparison.OrdinalIgnoreCase)) + { + result = await _tvDbClientManager.GetSeriesByZap2ItIdAsync(id, cancellationToken); + } + else + { + result = await _tvDbClientManager.GetSeriesByImdbIdAsync(id, cancellationToken); + } } - else + catch (TvDbServerException e) { - result = await _tvDbClientManager.GetSeriesByImdbIdAsync(id, cancellationToken); + _logger.LogError(e, "Failed to retrieve series with remote id {RemoteId}", id); } - return result.Data.First().Id.ToString(); + return result?.Data.First().Id.ToString(); } internal static bool IsValidSeries(Dictionary seriesProviderIds)