using System; using System.Collections.Generic; using System.Globalization; using System.Runtime.CompilerServices; using System.Threading; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using Microsoft.Extensions.Logging; namespace MediaBrowser.Providers.Plugins.Tmdb.TV; /// /// TMDb-based similar items provider for TV series. /// public class TmdbSeriesSimilarProvider : IRemoteSimilarItemsProvider { private readonly TmdbClientManager _tmdbClientManager; private readonly ILogger _logger; /// /// Initializes a new instance of the class. /// /// The TMDb client manager. /// The logger. public TmdbSeriesSimilarProvider(TmdbClientManager tmdbClientManager, ILogger logger) { _tmdbClientManager = tmdbClientManager; _logger = logger; } /// public string Name => TmdbUtils.ProviderName; /// public MetadataPluginType Type => MetadataPluginType.SimilarityProvider; /// public TimeSpan? CacheDuration { get { var days = Plugin.Instance?.Configuration.SimilarItemsCacheDays ?? 0; return days > 0 ? TimeSpan.FromDays(days) : null; } } /// public async IAsyncEnumerable GetSimilarItemsAsync( Series item, SimilarItemsQuery query, [EnumeratorCancellation] CancellationToken cancellationToken) { if (!item.TryGetProviderId(MetadataProvider.Tmdb, out var tmdbIdStr) || !int.TryParse(tmdbIdStr, CultureInfo.InvariantCulture, out var tmdbId)) { yield break; } var providerName = MetadataProvider.Tmdb.ToString(); var page = 1; var totalPages = 1; while (page <= totalPages && !cancellationToken.IsCancellationRequested) { IReadOnlyList pageResults; try { (pageResults, totalPages) = await _tmdbClientManager .GetSeriesSimilarPageAsync(tmdbId, page, TmdbUtils.GetImageLanguagesParam(string.Empty), cancellationToken) .ConfigureAwait(false); } catch (Exception ex) { _logger.LogWarning(ex, "Failed to get similar TV shows from TMDb for {TmdbId} page {Page}", tmdbId, page); yield break; } if (pageResults.Count == 0) { yield break; } foreach (var similar in pageResults) { yield return new SimilarItemReference { ProviderName = providerName, ProviderId = similar.Id.ToString(CultureInfo.InvariantCulture) }; } page++; } } }