Fixed: Posters not always showing when searching for new shows

pull/3523/head
Taloth Saldono 5 years ago
parent d8446c2d5a
commit 10dc884fa8

@ -0,0 +1,66 @@
using NzbDrone.Common.Cache;
using NzbDrone.Common.Http;
using NzbDrone.Core.Configuration;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NzbDrone.Core.MediaCover
{
public interface IMediaCoverProxy
{
string RegisterUrl(string url);
string GetUrl(string hash);
byte[] GetImage(string hash);
}
public class MediaCoverProxy : IMediaCoverProxy
{
private readonly IHttpClient _httpClient;
private readonly IConfigFileProvider _configFileProvider;
private readonly ICached<string> _cache;
public MediaCoverProxy(IHttpClient httpClient, IConfigFileProvider configFileProvider, ICacheManager cacheManager)
{
_httpClient = httpClient;
_configFileProvider = configFileProvider;
_cache = cacheManager.GetCache<string>(GetType());
}
public string RegisterUrl(string url)
{
var hash = url.SHA256Hash();
_cache.Set(hash, url, TimeSpan.FromHours(24));
_cache.ClearExpired();
var fileName = Path.GetFileName(url);
return _configFileProvider.UrlBase + @"/MediaCoverProxy/" + hash + "/" + fileName;
}
public string GetUrl(string hash)
{
var result = _cache.Find(hash);
if (result == null)
{
throw new KeyNotFoundException("Url no longer in cache");
}
return result;
}
public byte[] GetImage(string hash)
{
var url = GetUrl(hash);
var request = new HttpRequest(url);
return _httpClient.Get(request).ResponseData;
}
}
}

@ -26,6 +26,7 @@ namespace NzbDrone.Core.MediaCover
IHandleAsync<SeriesDeletedEvent>, IHandleAsync<SeriesDeletedEvent>,
IMapCoversToLocal IMapCoversToLocal
{ {
private readonly IMediaCoverProxy _mediaCoverProxy;
private readonly IImageResizer _resizer; private readonly IImageResizer _resizer;
private readonly IHttpClient _httpClient; private readonly IHttpClient _httpClient;
private readonly IDiskProvider _diskProvider; private readonly IDiskProvider _diskProvider;
@ -40,7 +41,8 @@ namespace NzbDrone.Core.MediaCover
// So limit the number of concurrent resizing tasks // So limit the number of concurrent resizing tasks
private static SemaphoreSlim _semaphore = new SemaphoreSlim((int)Math.Ceiling(Environment.ProcessorCount / 2.0)); private static SemaphoreSlim _semaphore = new SemaphoreSlim((int)Math.Ceiling(Environment.ProcessorCount / 2.0));
public MediaCoverService(IImageResizer resizer, public MediaCoverService(IMediaCoverProxy mediaCoverProxy,
IImageResizer resizer,
IHttpClient httpClient, IHttpClient httpClient,
IDiskProvider diskProvider, IDiskProvider diskProvider,
IAppFolderInfo appFolderInfo, IAppFolderInfo appFolderInfo,
@ -49,6 +51,7 @@ namespace NzbDrone.Core.MediaCover
IEventAggregator eventAggregator, IEventAggregator eventAggregator,
Logger logger) Logger logger)
{ {
_mediaCoverProxy = mediaCoverProxy;
_resizer = resizer; _resizer = resizer;
_httpClient = httpClient; _httpClient = httpClient;
_diskProvider = diskProvider; _diskProvider = diskProvider;
@ -69,16 +72,27 @@ namespace NzbDrone.Core.MediaCover
public void ConvertToLocalUrls(int seriesId, IEnumerable<MediaCover> covers) public void ConvertToLocalUrls(int seriesId, IEnumerable<MediaCover> covers)
{ {
foreach (var mediaCover in covers) if (seriesId == 0)
{ {
var filePath = GetCoverPath(seriesId, mediaCover.CoverType); // Series isn't in Sonarr yet, map via a proxy to circument referrer issues
foreach (var mediaCover in covers)
{
mediaCover.Url = _mediaCoverProxy.RegisterUrl(mediaCover.Url);
}
}
else
{
foreach (var mediaCover in covers)
{
var filePath = GetCoverPath(seriesId, mediaCover.CoverType);
mediaCover.Url = _configFileProvider.UrlBase + @"/MediaCover/" + seriesId + "/" + mediaCover.CoverType.ToString().ToLower() + ".jpg"; mediaCover.Url = _configFileProvider.UrlBase + @"/MediaCover/" + seriesId + "/" + mediaCover.CoverType.ToString().ToLower() + ".jpg";
if (_diskProvider.FileExists(filePath)) if (_diskProvider.FileExists(filePath))
{ {
var lastWrite = _diskProvider.FileGetLastWrite(filePath); var lastWrite = _diskProvider.FileGetLastWrite(filePath);
mediaCover.Url += "?lastWrite=" + lastWrite.Ticks; mediaCover.Url += "?lastWrite=" + lastWrite.Ticks;
}
} }
} }
} }

@ -100,7 +100,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
var httpResponse = _httpClient.Get<List<ShowResource>>(httpRequest); var httpResponse = _httpClient.Get<List<ShowResource>>(httpRequest);
return httpResponse.Resource.SelectList(MapSearhResult); return httpResponse.Resource.SelectList(MapSearchResult);
} }
catch (HttpException) catch (HttpException)
{ {
@ -113,7 +113,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
} }
} }
private Series MapSearhResult(ShowResource show) private Series MapSearchResult(ShowResource show)
{ {
var series = _seriesService.FindByTvdbId(show.TvdbId); var series = _seriesService.FindByTvdbId(show.TvdbId);

@ -13,12 +13,14 @@ namespace Sonarr.Api.V3.Series
{ {
private readonly ISearchForNewSeries _searchProxy; private readonly ISearchForNewSeries _searchProxy;
private readonly IBuildFileNames _fileNameBuilder; private readonly IBuildFileNames _fileNameBuilder;
private readonly IMapCoversToLocal _coverMapper;
public SeriesLookupModule(ISearchForNewSeries searchProxy, IBuildFileNames fileNameBuilder) public SeriesLookupModule(ISearchForNewSeries searchProxy, IBuildFileNames fileNameBuilder, IMapCoversToLocal coverMapper)
: base("/series/lookup") : base("/series/lookup")
{ {
_searchProxy = searchProxy; _searchProxy = searchProxy;
_fileNameBuilder = fileNameBuilder; _fileNameBuilder = fileNameBuilder;
_coverMapper = coverMapper;
Get("/", x => Search()); Get("/", x => Search());
} }
@ -33,6 +35,9 @@ namespace Sonarr.Api.V3.Series
foreach (var currentSeries in series) foreach (var currentSeries in series)
{ {
var resource = currentSeries.ToResource(); var resource = currentSeries.ToResource();
_coverMapper.ConvertToLocalUrls(resource.Id, resource.Images);
var poster = currentSeries.Images.FirstOrDefault(c => c.CoverType == MediaCoverTypes.Poster); var poster = currentSeries.Images.FirstOrDefault(c => c.CoverType == MediaCoverTypes.Poster);
if (poster != null) if (poster != null)

@ -43,7 +43,7 @@ namespace Sonarr.Http.Frontend.Mappers
public override bool CanHandle(string resourceUrl) public override bool CanHandle(string resourceUrl)
{ {
return resourceUrl.StartsWith("/MediaCover", StringComparison.InvariantCultureIgnoreCase); return resourceUrl.StartsWith("/MediaCover/", StringComparison.InvariantCultureIgnoreCase);
} }
} }
} }

@ -0,0 +1,48 @@
using System;
using System.IO;
using System.Text.RegularExpressions;
using Nancy;
using Nancy.Responses;
using NzbDrone.Core.MediaCover;
namespace Sonarr.Http.Frontend.Mappers
{
public class MediaCoverProxyMapper : IMapHttpRequestsToDisk
{
private readonly Regex _regex = new Regex(@"/MediaCoverProxy/(?<hash>\w+)/(?<filename>(.+)\.(jpg|png|gif))");
private readonly IMediaCoverProxy _mediaCoverProxy;
public MediaCoverProxyMapper(IMediaCoverProxy mediaCoverProxy)
{
_mediaCoverProxy = mediaCoverProxy;
}
public string Map(string resourceUrl)
{
return null;
}
public bool CanHandle(string resourceUrl)
{
return resourceUrl.StartsWith("/MediaCoverProxy/", StringComparison.InvariantCultureIgnoreCase);
}
public Response GetResponse(string resourceUrl)
{
var match = _regex.Match(resourceUrl);
if (!match.Success)
{
return new NotFoundResponse();
}
var hash = match.Groups["hash"].Value;
var filename = match.Groups["filename"].Value;
var imageData = _mediaCoverProxy.GetImage(hash);
return new StreamResponse(() => new MemoryStream(imageData), MimeTypes.GetMimeType(filename));
}
}
}
Loading…
Cancel
Save