aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Providers/Plugins
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Providers/Plugins')
-rw-r--r--MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs75
-rw-r--r--MediaBrowser.Providers/Plugins/TheTvdb/TvdbClientManager.cs3
-rw-r--r--MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeProvider.cs3
-rw-r--r--MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesProvider.cs30
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeImageProvider.cs14
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs32
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonImageProvider.cs13
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesImageProvider.cs19
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs34
9 files changed, 123 insertions, 100 deletions
diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs
index abfa1c6e7..31f0123dc 100644
--- a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs
+++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs
@@ -46,6 +46,7 @@ namespace MediaBrowser.Providers.Music
private readonly string _musicBrainzBaseUrl;
+ private SemaphoreSlim _apiRequestLock = new SemaphoreSlim(1, 1);
private Stopwatch _stopWatchMusicBrainz = new Stopwatch();
public MusicBrainzAlbumProvider(
@@ -742,48 +743,58 @@ namespace MediaBrowser.Providers.Music
/// </summary>
internal async Task<HttpResponseMessage> GetMusicBrainzResponse(string url, CancellationToken cancellationToken)
{
- using var options = new HttpRequestMessage(HttpMethod.Get, _musicBrainzBaseUrl.TrimEnd('/') + url);
+ await _apiRequestLock.WaitAsync(cancellationToken).ConfigureAwait(false);
- // MusicBrainz request a contact email address is supplied, as comment, in user agent field:
- // https://musicbrainz.org/doc/XML_Web_Service/Rate_Limiting#User-Agent
- options.Headers.UserAgent.ParseAdd(string.Format(
- CultureInfo.InvariantCulture,
- "{0} ( {1} )",
- _appHost.ApplicationUserAgent,
- _appHost.ApplicationUserAgentAddress));
-
- HttpResponseMessage response;
- var attempts = 0u;
-
- do
+ try
{
- attempts++;
+ HttpResponseMessage response;
+ var attempts = 0u;
+ var requestUrl = _musicBrainzBaseUrl.TrimEnd('/') + url;
- if (_stopWatchMusicBrainz.ElapsedMilliseconds < _musicBrainzQueryIntervalMs)
+ do
{
- // MusicBrainz is extremely adamant about limiting to one request per second
- var delayMs = _musicBrainzQueryIntervalMs - _stopWatchMusicBrainz.ElapsedMilliseconds;
- await Task.Delay((int)delayMs, cancellationToken).ConfigureAwait(false);
- }
+ attempts++;
- // Write time since last request to debug log as evidence we're meeting rate limit
- // requirement, before resetting stopwatch back to zero.
- _logger.LogDebug("GetMusicBrainzResponse: Time since previous request: {0} ms", _stopWatchMusicBrainz.ElapsedMilliseconds);
- _stopWatchMusicBrainz.Restart();
+ if (_stopWatchMusicBrainz.ElapsedMilliseconds < _musicBrainzQueryIntervalMs)
+ {
+ // MusicBrainz is extremely adamant about limiting to one request per second.
+ var delayMs = _musicBrainzQueryIntervalMs - _stopWatchMusicBrainz.ElapsedMilliseconds;
+ await Task.Delay((int)delayMs, cancellationToken).ConfigureAwait(false);
+ }
- response = await _httpClientFactory.CreateClient(NamedClient.Default).SendAsync(options).ConfigureAwait(false);
+ // Write time since last request to debug log as evidence we're meeting rate limit
+ // requirement, before resetting stopwatch back to zero.
+ _logger.LogDebug("GetMusicBrainzResponse: Time since previous request: {0} ms", _stopWatchMusicBrainz.ElapsedMilliseconds);
+ _stopWatchMusicBrainz.Restart();
- // We retry a finite number of times, and only whilst MB is indicating 503 (throttling)
- }
- while (attempts < MusicBrainzQueryAttempts && response.StatusCode == HttpStatusCode.ServiceUnavailable);
+ using var request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
+
+ // MusicBrainz request a contact email address is supplied, as comment, in user agent field:
+ // https://musicbrainz.org/doc/XML_Web_Service/Rate_Limiting#User-Agent .
+ request.Headers.UserAgent.ParseAdd(string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} ( {1} )",
+ _appHost.ApplicationUserAgent,
+ _appHost.ApplicationUserAgentAddress));
- // Log error if unable to query MB database due to throttling
- if (attempts == MusicBrainzQueryAttempts && response.StatusCode == HttpStatusCode.ServiceUnavailable)
+ response = await _httpClientFactory.CreateClient(NamedClient.Default).SendAsync(request).ConfigureAwait(false);
+
+ // We retry a finite number of times, and only whilst MB is indicating 503 (throttling).
+ }
+ while (attempts < MusicBrainzQueryAttempts && response.StatusCode == HttpStatusCode.ServiceUnavailable);
+
+ // Log error if unable to query MB database due to throttling.
+ if (attempts == MusicBrainzQueryAttempts && response.StatusCode == HttpStatusCode.ServiceUnavailable)
+ {
+ _logger.LogError("GetMusicBrainzResponse: 503 Service Unavailable (throttled) response received {0} times whilst requesting {1}", attempts, requestUrl);
+ }
+
+ return response;
+ }
+ finally
{
- _logger.LogError("GetMusicBrainzResponse: 503 Service Unavailable (throttled) response received {0} times whilst requesting {1}", attempts, options.RequestUri);
+ _apiRequestLock.Release();
}
-
- return response;
}
/// <inheritdoc />
diff --git a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbClientManager.cs b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbClientManager.cs
index 5e9a4a225..ce0dab701 100644
--- a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbClientManager.cs
+++ b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbClientManager.cs
@@ -150,7 +150,8 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
string language,
CancellationToken cancellationToken)
{
- searchInfo.SeriesProviderIds.TryGetValue(nameof(MetadataProvider.Tvdb),
+ searchInfo.SeriesProviderIds.TryGetValue(
+ nameof(MetadataProvider.Tvdb),
out var seriesTvdbId);
var episodeQuery = new EpisodeQuery();
diff --git a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeProvider.cs
index 5fa8a3e1c..fd72ea4a8 100644
--- a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeProvider.cs
+++ b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeProvider.cs
@@ -106,7 +106,8 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
.ConfigureAwait(false);
if (string.IsNullOrEmpty(episodeTvdbId))
{
- _logger.LogError("Episode {SeasonNumber}x{EpisodeNumber} not found for series {SeriesTvdbId}",
+ _logger.LogError(
+ "Episode {SeasonNumber}x{EpisodeNumber} not found for series {SeriesTvdbId}",
searchInfo.ParentIndexNumber, searchInfo.IndexNumber, seriesTvdbId);
return result;
}
diff --git a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesProvider.cs b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesProvider.cs
index ca9b1d738..b34e52235 100644
--- a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesProvider.cs
+++ b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesProvider.cs
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Text;
@@ -123,7 +124,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
await _tvdbClientManager
.GetSeriesByIdAsync(Convert.ToInt32(tvdbId), metadataLanguage, cancellationToken)
.ConfigureAwait(false);
- MapSeriesToResult(result, seriesResult.Data, metadataLanguage);
+ await MapSeriesToResult(result, seriesResult.Data, metadataLanguage).ConfigureAwait(false);
}
catch (TvDbServerException e)
{
@@ -297,7 +298,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
return name.Trim();
}
- private void MapSeriesToResult(MetadataResult<Series> result, TvDbSharper.Dto.Series tvdbSeries, string metadataLanguage)
+ private async Task MapSeriesToResult(MetadataResult<Series> result, TvDbSharper.Dto.Series tvdbSeries, string metadataLanguage)
{
Series series = result.Item;
series.SetProviderId(MetadataProvider.Tvdb, tvdbSeries.Id.ToString());
@@ -340,20 +341,21 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
{
try
{
- var episodeSummary = _tvdbClientManager
- .GetSeriesEpisodeSummaryAsync(tvdbSeries.Id, metadataLanguage, CancellationToken.None).Result.Data;
- var maxSeasonNumber = episodeSummary.AiredSeasons.Select(s => Convert.ToInt32(s)).Max();
- var episodeQuery = new EpisodeQuery
+ var episodeSummary = await _tvdbClientManager.GetSeriesEpisodeSummaryAsync(tvdbSeries.Id, metadataLanguage, CancellationToken.None).ConfigureAwait(false);
+
+ if (episodeSummary.Data.AiredSeasons.Length != 0)
{
- AiredSeason = maxSeasonNumber
- };
- var episodesPage =
- _tvdbClientManager.GetEpisodesPageAsync(tvdbSeries.Id, episodeQuery, metadataLanguage, CancellationToken.None).Result.Data;
- result.Item.EndDate = episodesPage.Select(e =>
+ var maxSeasonNumber = episodeSummary.Data.AiredSeasons.Max(s => Convert.ToInt32(s, CultureInfo.InvariantCulture));
+ var episodeQuery = new EpisodeQuery
{
- DateTime.TryParse(e.FirstAired, out var firstAired);
- return firstAired;
- }).Max();
+ AiredSeason = maxSeasonNumber
+ };
+ var episodesPage = await _tvdbClientManager.GetEpisodesPageAsync(tvdbSeries.Id, episodeQuery, metadataLanguage, CancellationToken.None).ConfigureAwait(false);
+
+ result.Item.EndDate = episodesPage.Data
+ .Select(e => DateTime.TryParse(e.FirstAired, out var firstAired) ? firstAired : (DateTime?)null)
+ .Max();
+ }
}
catch (TvDbServerException e)
{
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeImageProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeImageProvider.cs
index fe9e483c6..3b7a0b254 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeImageProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeImageProvider.cs
@@ -67,17 +67,17 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
.GetEpisodeAsync(seriesTmdbId, seasonNumber.Value, episodeNumber.Value, language, TmdbUtils.GetImageLanguagesParam(language), cancellationToken)
.ConfigureAwait(false);
- if (episodeResult?.Images?.Stills == null)
+ var stills = episodeResult?.Images?.Stills;
+ if (stills == null)
{
return Enumerable.Empty<RemoteImageInfo>();
}
- var remoteImages = new List<RemoteImageInfo>();
-
- for (var i = 0; i < episodeResult.Images.Stills.Count; i++)
+ var remoteImages = new RemoteImageInfo[stills.Count];
+ for (var i = 0; i < stills.Count; i++)
{
- var image = episodeResult.Images.Stills[i];
- remoteImages.Add(new RemoteImageInfo
+ var image = stills[i];
+ remoteImages[i] = new RemoteImageInfo
{
Url = _tmdbClientManager.GetStillUrl(image.FilePath),
CommunityRating = image.VoteAverage,
@@ -88,7 +88,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
ProviderName = Name,
Type = ImageType.Primary,
RatingType = RatingType.Score
- });
+ };
}
return remoteImages.OrderByLanguageDescending(language);
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs
index 55f1ba7dc..93998a110 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs
@@ -40,30 +40,29 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
return Enumerable.Empty<RemoteSearchResult>();
}
- var metadataResult = await GetMetadata(searchInfo, cancellationToken);
+ var metadataResult = await GetMetadata(searchInfo, cancellationToken).ConfigureAwait(false);
if (!metadataResult.HasMetadata)
{
return Enumerable.Empty<RemoteSearchResult>();
}
- var list = new List<RemoteSearchResult>();
-
var item = metadataResult.Item;
- list.Add(new RemoteSearchResult
+ return new[]
{
- IndexNumber = item.IndexNumber,
- Name = item.Name,
- ParentIndexNumber = item.ParentIndexNumber,
- PremiereDate = item.PremiereDate,
- ProductionYear = item.ProductionYear,
- ProviderIds = item.ProviderIds,
- SearchProviderName = Name,
- IndexNumberEnd = item.IndexNumberEnd
- });
-
- return list;
+ 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
+ }
+ };
}
public async Task<MetadataResult<Episode>> GetMetadata(EpisodeInfo info, CancellationToken cancellationToken)
@@ -137,8 +136,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
{
if (TmdbUtils.IsTrailerType(video))
{
- var videoUrl = string.Format(CultureInfo.InvariantCulture, "http://www.youtube.com/watch?v={0}", video.Key);
- item.AddTrailerUrl(videoUrl);
+ item.AddTrailerUrl("https://www.youtube.com/watch?v=" + video.Key);
}
}
}
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonImageProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonImageProvider.cs
index 0feaa5732..f4ed480ae 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonImageProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonImageProvider.cs
@@ -56,16 +56,17 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
.GetSeasonAsync(seriesTmdbId, season.IndexNumber.Value, language, TmdbUtils.GetImageLanguagesParam(language), cancellationToken)
.ConfigureAwait(false);
- if (seasonResult?.Images?.Posters == null)
+ var posters = seasonResult?.Images?.Posters;
+ if (posters == null)
{
return Enumerable.Empty<RemoteImageInfo>();
}
- var remoteImages = new List<RemoteImageInfo>();
- for (var i = 0; i < seasonResult.Images.Posters.Count; i++)
+ var remoteImages = new RemoteImageInfo[posters.Count];
+ for (var i = 0; i < posters.Count; i++)
{
- var image = seasonResult.Images.Posters[i];
- remoteImages.Add(new RemoteImageInfo
+ var image = posters[i];
+ remoteImages[i] = new RemoteImageInfo
{
Url = _tmdbClientManager.GetPosterUrl(image.FilePath),
CommunityRating = image.VoteAverage,
@@ -76,7 +77,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
ProviderName = Name,
Type = ImageType.Primary,
RatingType = RatingType.Score
- });
+ };
}
return remoteImages.OrderByLanguageDescending(language);
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesImageProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesImageProvider.cs
index 2fdec0196..d0c6b8b88 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesImageProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesImageProvider.cs
@@ -68,12 +68,15 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
return Enumerable.Empty<RemoteImageInfo>();
}
- var remoteImages = new List<RemoteImageInfo>();
+ var posters = series.Images.Posters;
+ var backdrops = series.Images.Backdrops;
- for (var i = 0; i < series.Images.Posters.Count; i++)
+ var remoteImages = new RemoteImageInfo[posters.Count + backdrops.Count];
+
+ for (var i = 0; i < posters.Count; i++)
{
- var poster = series.Images.Posters[i];
- remoteImages.Add(new RemoteImageInfo
+ var poster = posters[i];
+ remoteImages[i] = new RemoteImageInfo
{
Url = _tmdbClientManager.GetPosterUrl(poster.FilePath),
CommunityRating = poster.VoteAverage,
@@ -84,13 +87,13 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
ProviderName = Name,
Type = ImageType.Primary,
RatingType = RatingType.Score
- });
+ };
}
- for (var i = 0; i < series.Images.Backdrops.Count; i++)
+ for (var i = 0; i < backdrops.Count; i++)
{
var backdrop = series.Images.Backdrops[i];
- remoteImages.Add(new RemoteImageInfo
+ remoteImages[posters.Count + i] = new RemoteImageInfo
{
Url = _tmdbClientManager.GetBackdropUrl(backdrop.FilePath),
CommunityRating = backdrop.VoteAverage,
@@ -100,7 +103,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
ProviderName = Name,
Type = ImageType.Backdrop,
RatingType = RatingType.Score
- });
+ };
}
return remoteImages.OrderByLanguageDescending(language);
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs
index 7944dfe27..942c85b90 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs
@@ -66,14 +66,15 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
.FindByExternalIdAsync(imdbId, FindExternalSource.Imdb, searchInfo.MetadataLanguage, cancellationToken)
.ConfigureAwait(false);
- if (findResult?.TvResults != null)
+ var tvResults = findResult?.TvResults;
+ if (tvResults != null)
{
- var imdbIdResults = new List<RemoteSearchResult>();
- for (var i = 0; i < findResult.TvResults.Count; i++)
+ var imdbIdResults = new RemoteSearchResult[tvResults.Count];
+ for (var i = 0; i < tvResults.Count; i++)
{
- var remoteResult = MapSearchTvToRemoteSearchResult(findResult.TvResults[i]);
+ var remoteResult = MapSearchTvToRemoteSearchResult(tvResults[i]);
remoteResult.SetProviderId(MetadataProvider.Imdb, imdbId);
- imdbIdResults.Add(remoteResult);
+ imdbIdResults[i] = remoteResult;
}
return imdbIdResults;
@@ -88,14 +89,15 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
.FindByExternalIdAsync(tvdbId, FindExternalSource.TvDb, searchInfo.MetadataLanguage, cancellationToken)
.ConfigureAwait(false);
- if (findResult?.TvResults != null)
+ var tvResults = findResult?.TvResults;
+ if (tvResults != null)
{
- var tvIdResults = new List<RemoteSearchResult>();
- for (var i = 0; i < findResult.TvResults.Count; i++)
+ var tvIdResults = new RemoteSearchResult[tvResults.Count];
+ for (var i = 0; i < tvResults.Count; i++)
{
- var remoteResult = MapSearchTvToRemoteSearchResult(findResult.TvResults[i]);
+ var remoteResult = MapSearchTvToRemoteSearchResult(tvResults[i]);
remoteResult.SetProviderId(MetadataProvider.Tvdb, tvdbId);
- tvIdResults.Add(remoteResult);
+ tvIdResults[i] = remoteResult;
}
return tvIdResults;
@@ -105,10 +107,10 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
var tvSearchResults = await _tmdbClientManager.SearchSeriesAsync(searchInfo.Name, searchInfo.MetadataLanguage, cancellationToken)
.ConfigureAwait(false);
- var remoteResults = new List<RemoteSearchResult>();
+ var remoteResults = new RemoteSearchResult[tvSearchResults.Count];
for (var i = 0; i < tvSearchResults.Count; i++)
{
- remoteResults.Add(MapSearchTvToRemoteSearchResult(tvSearchResults[i]));
+ remoteResults[i] = MapSearchTvToRemoteSearchResult(tvSearchResults[i]);
}
return remoteResults;
@@ -236,7 +238,11 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
private Series MapTvShowToSeries(TvShow seriesResult, string preferredCountryCode)
{
- var series = new Series {Name = seriesResult.Name, OriginalTitle = seriesResult.OriginalName};
+ var series = new Series
+ {
+ Name = seriesResult.Name,
+ OriginalTitle = seriesResult.OriginalName
+ };
series.SetProviderId(MetadataProvider.Tmdb, seriesResult.Id.ToString(CultureInfo.InvariantCulture));
@@ -322,7 +328,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
{
if (TmdbUtils.IsTrailerType(video))
{
- series.AddTrailerUrl($"http://www.youtube.com/watch?v={video.Key}");
+ series.AddTrailerUrl("https://www.youtube.com/watch?v=" + video.Key);
}
}
}