Enhance logging in RefreshShowEpisodesMetadataCommandHandler and TmdbMetadataProvider for image retrieval failures
Updated the RefreshShowEpisodesMetadataCommandHandler to include logging for scenarios where episode still images are not retrieved successfully. Introduced warning logs for missing still URLs and download failures, improving traceability. Additionally, modified the TmdbMetadataProvider to implement a fallback mechanism for episode still images, ensuring that appropriate imagery is displayed even when localized images are unavailable. Updated related tests to verify the correct behavior of these logging enhancements and fallback logic.
This commit is contained in:
@@ -110,7 +110,11 @@ public sealed class TmdbMetadataProvider(
|
||||
// оставляло бы шоу без постера, и это неотличимо от «постера нет вовсе».
|
||||
var posterPath =
|
||||
GetString(root, "poster_path")
|
||||
?? await NeutralPosterPathAsync(movie, externalId, cancellationToken);
|
||||
?? await NeutralImagePathAsync(
|
||||
$"{Segment(movie)}/{externalId}",
|
||||
"poster_path",
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
return new ShowMetadata(
|
||||
externalId,
|
||||
@@ -126,19 +130,20 @@ public sealed class TmdbMetadataProvider(
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Постер без привязки к языку: тот же запрос, но без <c>language</c>. Второе обращение к API
|
||||
/// делается только когда локализованного постера нет, — то есть редко.
|
||||
/// Картинка без привязки к языку: тот же адрес, но без <c>language</c>. TMDb отдаёт постеры
|
||||
/// и кадры под запрошенный язык, и у контента без локализованной картинки поле пустое — хотя
|
||||
/// язык-нейтральная у него есть. Второе обращение к API делается только в этом случае.
|
||||
/// </summary>
|
||||
private async Task<string?> NeutralPosterPathAsync(
|
||||
bool movie,
|
||||
string externalId,
|
||||
private async Task<string?> NeutralImagePathAsync(
|
||||
string path,
|
||||
string field,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var query = UsesBearer ? string.Empty : $"?api_key={Tmdb.ApiKey}";
|
||||
var url = $"{Tmdb.BaseUrl}/{Segment(movie)}/{externalId}{query}";
|
||||
var url = $"{Tmdb.BaseUrl}/{path}{query}";
|
||||
using var doc = await TryGetAsync(httpFactory, url, cancellationToken, BearerToken);
|
||||
return doc is null ? null : GetString(doc.RootElement, "poster_path");
|
||||
return doc is null ? null : GetString(doc.RootElement, field);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -274,15 +279,28 @@ public sealed class TmdbMetadataProvider(
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var url = $"{Tmdb.BaseUrl}/tv/{externalId}/season/{season}/episode/{episode}{BaseQuery}";
|
||||
using var doc = await TryGetAsync(httpFactory, url, cancellationToken, BearerToken);
|
||||
var path = $"tv/{externalId}/season/{season}/episode/{episode}";
|
||||
using var doc = await TryGetAsync(
|
||||
httpFactory,
|
||||
$"{Tmdb.BaseUrl}/{path}{BaseQuery}",
|
||||
cancellationToken,
|
||||
BearerToken
|
||||
);
|
||||
if (doc is null)
|
||||
return null;
|
||||
var root = doc.RootElement;
|
||||
|
||||
// Кадр серии — та же история, что и с постером шоу: под русский язык его обычно нет,
|
||||
// а язык-нейтральный есть. Добор идёт по серии, поэтому у сезона без локализованных
|
||||
// кадров запросов вдвое больше — «Обновить серии» жмут руками, это терпимо.
|
||||
var stillPath =
|
||||
GetString(root, "still_path")
|
||||
?? await NeutralImagePathAsync(path, "still_path", cancellationToken);
|
||||
|
||||
return new EpisodeMetadata(
|
||||
GetString(root, "name") ?? "—",
|
||||
GetString(root, "overview"),
|
||||
StillUrl(GetString(root, "still_path")),
|
||||
StillUrl(stillPath),
|
||||
DateFrom(GetString(root, "air_date"))
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user