Adding Clearlogo support for TMDB

This commit is contained in:
Nick Wallace 2026-03-17 14:47:12 -05:00
parent 89110c2cc8
commit 5d53b101d8
5 changed files with 130 additions and 1 deletions

View file

@ -203,7 +203,11 @@ private void DownloadCover(Movie movie, MediaCover cover)
{
var fileName = GetCoverPath(movie.Id, cover.CoverType);
_logger.Info("Downloading {0} for {1} {2}", cover.CoverType, movie, cover.RemoteUrl);
if (cover.CoverType == MediaCoverTypes.Clearlogo)
{
_logger.Debug("Downloading Clearlogo for {0} {1}", movie, cover.RemoteUrl);
}
_httpClient.DownloadFile(cover.RemoteUrl, fileName);
}

View file

@ -14,6 +14,7 @@
using NzbDrone.Core.Languages;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.MetadataSource.SkyHook.Resource;
using NzbDrone.Core.MetadataSource.TMDb;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Movies.AlternativeTitles;
using NzbDrone.Core.Movies.Collections;
@ -33,6 +34,7 @@ public class SkyHookProxy : IProvideMovieInfo, ISearchForNewMovie
private readonly IMovieService _movieService;
private readonly IMovieMetadataService _movieMetadataService;
private readonly IMovieTranslationService _movieTranslationService;
private readonly ITmdbImagesProxy _tmdbImagesProxy;
public SkyHookProxy(IHttpClient httpClient,
IRadarrCloudRequestBuilder requestBuilder,
@ -40,6 +42,7 @@ public SkyHookProxy(IHttpClient httpClient,
IMovieService movieService,
IMovieMetadataService movieMetadataService,
IMovieTranslationService movieTranslationService,
ITmdbImagesProxy tmdbImagesProxy,
Logger logger)
{
_httpClient = httpClient;
@ -48,6 +51,7 @@ public SkyHookProxy(IHttpClient httpClient,
_movieService = movieService;
_movieMetadataService = movieMetadataService;
_movieTranslationService = movieTranslationService;
_tmdbImagesProxy = tmdbImagesProxy;
_logger = logger;
}
@ -276,6 +280,15 @@ public MovieMetadata MapMovie(MovieResource resource)
movie.Keywords = resource.Keywords ?? new List<string>();
movie.Images = resource.Images.Select(MapImage).ToList();
if (!movie.Images.Any(i => i.CoverType == MediaCoverTypes.Clearlogo))
{
var logo = _tmdbImagesProxy.GetMovieLogo(resource.TmdbId);
if (logo != null)
{
movie.Images.Add(logo);
}
}
movie.Recommendations = resource.Recommendations?.Select(r => r.TmdbId).ToList() ?? new List<int>();
// Workaround due to metadata change until cache cleans up

View file

@ -0,0 +1,7 @@
namespace NzbDrone.Core.MetadataSource.TMDb
{
public interface ITmdbImagesProxy
{
NzbDrone.Core.MediaCover.MediaCover GetMovieLogo(int tmdbId);
}
}

View file

@ -0,0 +1,80 @@
using System;
using System.Linq;
using NLog;
using NzbDrone.Common.Cloud;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http;
using NzbDrone.Core.MediaCover;
namespace NzbDrone.Core.MetadataSource.TMDb
{
public class TmdbImagesProxy : ITmdbImagesProxy
{
private const string TmdbImageBaseUrl = "https://image.tmdb.org/t/p/original";
private readonly IHttpClient _httpClient;
private readonly IRadarrCloudRequestBuilder _requestBuilder;
private readonly Logger _logger;
public TmdbImagesProxy(IHttpClient httpClient, IRadarrCloudRequestBuilder requestBuilder, Logger logger)
{
_httpClient = httpClient;
_requestBuilder = requestBuilder;
_logger = logger;
}
public MediaCover.MediaCover GetMovieLogo(int tmdbId)
{
try
{
var request = _requestBuilder.TMDB.Create()
.SetSegment("api", "3")
.SetSegment("route", "movie")
.SetSegment("id", tmdbId.ToString())
.SetSegment("secondaryRoute", "/images")
.AddQueryParam("include_image_language", "en,null")
.Accept(HttpAccept.Json)
.Build();
request.AllowAutoRedirect = true;
request.SuppressHttpError = true;
var response = _httpClient.Get<TmdbMovieImagesResource>(request);
if (response.HasHttpError)
{
return null;
}
if (response.Resource == null || response.Resource.Logos == null || response.Resource.Logos.Length == 0)
{
return null;
}
var logo = response.Resource.Logos
.OrderByDescending(l => l.Iso6391 == "en" || l.Iso6391 == null ? 1 : 0)
.ThenByDescending(l => l.VoteAverage)
.ThenByDescending(l => l.VoteCount)
.FirstOrDefault();
if (logo == null || logo.FilePath.IsNullOrWhiteSpace())
{
return null;
}
var filePath = logo.FilePath;
if (filePath.EndsWith(".svg", StringComparison.OrdinalIgnoreCase))
{
filePath = string.Concat(filePath.AsSpan(0, filePath.Length - 4), ".png");
}
var url = TmdbImageBaseUrl + filePath;
return new MediaCover.MediaCover(MediaCoverTypes.Clearlogo, url);
}
catch (Exception)
{
return null;
}
}
}
}

View file

@ -0,0 +1,25 @@
using Newtonsoft.Json;
namespace NzbDrone.Core.MetadataSource.TMDb
{
public class TmdbMovieImagesResource
{
public int Id { get; set; }
public TmdbLogoResource[] Logos { get; set; }
}
public class TmdbLogoResource
{
[JsonProperty("file_path")]
public string FilePath { get; set; }
[JsonProperty("vote_average")]
public double VoteAverage { get; set; }
[JsonProperty("vote_count")]
public int VoteCount { get; set; }
[JsonProperty("iso_639_1")]
public string Iso6391 { get; set; }
}
}