feat: TMDB Discover source + retry yt-dlp once before fallback (v1.0.0.17)
All checks were successful
Publish Release / release (push) Successful in 14s
All checks were successful
Publish Release / release (push) Successful in 14s
The fixed TV lists are mostly long-running shows whose first_air_date is outside ReleaseDateRangeMonths, and paging stops at the first page with no in-range title, so only ~7 TV candidates were found (5 then dropped by language). Add a "discover" source per media type that asks /discover for recent titles in AllowedLanguages, sorted by popularity (1600+ TV results for en|fr today). TV Discover defaults on, movie Discover off. yt-dlp failures were mostly passing HTTP 403s from back-to-back requests; the built-in fallback is sometimes only offered 360p. Retry yt-dlp once after 15s before falling back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -84,6 +84,7 @@ namespace Jellyfin.Plugin.CinemaTrailers4Jellyfins.Services
|
||||
if (config.SourceUpcoming) sources.Add("upcoming");
|
||||
if (config.SourcePopular) sources.Add("popular");
|
||||
if (config.SourceTopRated) sources.Add("top_rated");
|
||||
if (config.SourceDiscover) sources.Add(DiscoverSource);
|
||||
|
||||
return GetCandidatesAsync("movie", sources, config, ct);
|
||||
}
|
||||
@@ -101,6 +102,7 @@ namespace Jellyfin.Plugin.CinemaTrailers4Jellyfins.Services
|
||||
if (config.SourceTvOnTheAir) sources.Add("on_the_air");
|
||||
if (config.SourceTvPopular) sources.Add("popular");
|
||||
if (config.SourceTvTopRated) sources.Add("top_rated");
|
||||
if (config.SourceTvDiscover) sources.Add(DiscoverSource);
|
||||
|
||||
return GetCandidatesAsync("tv", sources, config, ct);
|
||||
}
|
||||
@@ -120,7 +122,10 @@ namespace Jellyfin.Plugin.CinemaTrailers4Jellyfins.Services
|
||||
|
||||
foreach (var endpoint in sourceEndpoints)
|
||||
{
|
||||
var items = await FetchSourcePagesAsync(mediaType, endpoint, config.TmdbApiKey, releasedAfter, config.MaxPagesPerSource, ct)
|
||||
var path = endpoint == DiscoverSource
|
||||
? DiscoverPath(mediaType, releasedAfter, config.AllowedLanguages)
|
||||
: $"{mediaType}/{endpoint}";
|
||||
var items = await FetchSourcePagesAsync(mediaType, path, config.TmdbApiKey, releasedAfter, config.MaxPagesPerSource, ct)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
foreach (var item in items)
|
||||
@@ -133,9 +138,31 @@ namespace Jellyfin.Plugin.CinemaTrailers4Jellyfins.Services
|
||||
return results;
|
||||
}
|
||||
|
||||
private const string DiscoverSource = "discover";
|
||||
|
||||
// /discover asks TMDB directly for recent titles in the allowed languages, sorted by
|
||||
// popularity, unlike the fixed lists, which are mostly older titles the date range drops.
|
||||
private static string DiscoverPath(string mediaType, DateTime? releasedAfter, string allowedLanguages)
|
||||
{
|
||||
var query = new List<string> { "sort_by=popularity.desc" };
|
||||
if (releasedAfter.HasValue)
|
||||
{
|
||||
var dateParam = mediaType == "movie" ? "primary_release_date.gte" : "first_air_date.gte";
|
||||
query.Add($"{dateParam}={releasedAfter.Value:yyyy-MM-dd}");
|
||||
}
|
||||
|
||||
var languages = (allowedLanguages ?? string.Empty)
|
||||
.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
if (languages.Length > 0)
|
||||
query.Add("with_original_language=" + Uri.EscapeDataString(string.Join("|", languages)));
|
||||
|
||||
return $"discover/{mediaType}?" + string.Join("&", query);
|
||||
}
|
||||
|
||||
// path is relative to the API root, e.g. "tv/popular" or "discover/tv?sort_by=...".
|
||||
private async Task<List<TmdbMediaResult>> FetchSourcePagesAsync(
|
||||
string mediaType,
|
||||
string endpoint,
|
||||
string path,
|
||||
string apiKey,
|
||||
DateTime? releasedAfter,
|
||||
int maxPages,
|
||||
@@ -153,7 +180,7 @@ namespace Jellyfin.Plugin.CinemaTrailers4Jellyfins.Services
|
||||
|
||||
try
|
||||
{
|
||||
var url = $"{BaseUrl}/{mediaType}/{endpoint}?language=en-US&page={page}";
|
||||
var url = $"{BaseUrl}/{path}{(path.Contains('?') ? '&' : '?')}language=en-US&page={page}";
|
||||
using var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
ApplyAuth(request, apiKey);
|
||||
using var response = await _httpClient.SendAsync(request, ct).ConfigureAwait(false);
|
||||
@@ -190,7 +217,7 @@ namespace Jellyfin.Plugin.CinemaTrailers4Jellyfins.Services
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "|CinemaTrailers4Jellyfins| Failed to fetch TMDB source '{MediaType}/{Endpoint}' page {Page}", mediaType, endpoint, page);
|
||||
_logger.LogError(ex, "|CinemaTrailers4Jellyfins| Failed to fetch TMDB source '{Path}' page {Page}", path, page);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user