diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 23a7de4d426..366057f38aa 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -101,8 +101,8 @@ - - + + diff --git a/src/NzbDrone.Api.Test/Radarr.Api.Test.csproj b/src/NzbDrone.Api.Test/Radarr.Api.Test.csproj index ede6b5975c7..e78ea891ec4 100644 --- a/src/NzbDrone.Api.Test/Radarr.Api.Test.csproj +++ b/src/NzbDrone.Api.Test/Radarr.Api.Test.csproj @@ -12,7 +12,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/NzbDrone.Automation.Test/Radarr.Automation.Test.csproj b/src/NzbDrone.Automation.Test/Radarr.Automation.Test.csproj index 023342c7128..155c9084620 100644 --- a/src/NzbDrone.Automation.Test/Radarr.Automation.Test.csproj +++ b/src/NzbDrone.Automation.Test/Radarr.Automation.Test.csproj @@ -3,14 +3,14 @@ net10.0 - - + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/NzbDrone.Common.Test/Http/HttpClientFixture.cs b/src/NzbDrone.Common.Test/Http/HttpClientFixture.cs index e2fc4cd00c8..6395fd94268 100644 --- a/src/NzbDrone.Common.Test/Http/HttpClientFixture.cs +++ b/src/NzbDrone.Common.Test/Http/HttpClientFixture.cs @@ -796,8 +796,8 @@ public async Task should_parse_malformed_cloudflare_cookie(string culture) Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(culture); try { - // the date is bad in the below - should be 13-Jul-2026 - var malformedCookie = @"__cfduid=d29e686a9d65800021c66faca0a29b4261436890790; expires=Mon, 13-Jul-26 16:19:50 GMT; path=/; HttpOnly"; + // the date is bad in the below - should be 16-Jul-2046 + var malformedCookie = @"__cfduid=d29e686a9d65800021c66faca0a29b4261436890790; expires=Mon, 16-Jul-46 16:19:50 GMT; path=/; HttpOnly"; var requestSet = new HttpRequestBuilder($"https://{_httpBinHost}/response-headers") .AddQueryParam("Set-Cookie", malformedCookie) .Build(); @@ -805,7 +805,7 @@ public async Task should_parse_malformed_cloudflare_cookie(string culture) requestSet.AllowAutoRedirect = false; requestSet.StoreResponseCookie = true; - var responseSet = await Subject.GetAsync(requestSet); + await Subject.GetAsync(requestSet); var request = new HttpRequest($"https://{_httpBinHost}/get"); diff --git a/src/NzbDrone.Common.Test/Radarr.Common.Test.csproj b/src/NzbDrone.Common.Test/Radarr.Common.Test.csproj index fd5c35a501a..483d5ee8ee3 100644 --- a/src/NzbDrone.Common.Test/Radarr.Common.Test.csproj +++ b/src/NzbDrone.Common.Test/Radarr.Common.Test.csproj @@ -8,7 +8,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs b/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs index 2847789197e..929e1bf67a6 100644 --- a/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs +++ b/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs @@ -53,11 +53,9 @@ public ManagedHttpDispatcher(IHttpProxySettingsProvider proxySettingsProvider, public async Task GetResponseAsync(HttpRequest request, CookieContainer cookies) { - var requestMessage = new HttpRequestMessage(request.Method, (Uri)request.Url) - { - Version = HttpVersion.Version20, - VersionPolicy = HttpVersionPolicy.RequestVersionOrLower - }; + using var requestMessage = new HttpRequestMessage(request.Method, (Uri)request.Url); + requestMessage.Version = HttpVersion.Version20; + requestMessage.VersionPolicy = HttpVersionPolicy.RequestVersionOrLower; requestMessage.Headers.UserAgent.ParseAdd(_userAgentBuilder.GetUserAgent(request.UseSimplifiedUserAgent)); requestMessage.Headers.ConnectionClose = !request.ConnectionKeepAlive; @@ -113,31 +111,30 @@ public async Task GetResponseAsync(HttpRequest request, CookieCont try { using var responseMessage = await httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, cts.Token); - { - byte[] data = null; - try + byte[] data = null; + + try + { + if (request.ResponseStream != null && responseMessage.StatusCode == HttpStatusCode.OK) { - if (request.ResponseStream != null && responseMessage.StatusCode == HttpStatusCode.OK) - { - await responseMessage.Content.CopyToAsync(request.ResponseStream, null, cts.Token); - } - else - { - data = await responseMessage.Content.ReadAsByteArrayAsync(cts.Token); - } + await responseMessage.Content.CopyToAsync(request.ResponseStream, null, cts.Token); } - catch (Exception ex) + else { - throw new WebException("Failed to read complete http response", ex, WebExceptionStatus.ReceiveFailure, null); + data = await responseMessage.Content.ReadAsByteArrayAsync(cts.Token); } + } + catch (Exception ex) + { + throw new WebException("Failed to read complete http response", ex, WebExceptionStatus.ReceiveFailure, null); + } - var headers = responseMessage.Headers.ToNameValueCollection(); + var headers = responseMessage.Headers.ToNameValueCollection(); - headers.Add(responseMessage.Content.Headers.ToNameValueCollection()); + headers.Add(responseMessage.Content.Headers.ToNameValueCollection()); - return new HttpResponse(request, new HttpHeader(headers), data, responseMessage.StatusCode, responseMessage.Version); - } + return new HttpResponse(request, new HttpHeader(headers), data, responseMessage.StatusCode, responseMessage.Version); } catch (OperationCanceledException ex) when (cts.IsCancellationRequested) { diff --git a/src/NzbDrone.Common/Http/HttpResponse.cs b/src/NzbDrone.Common/Http/HttpResponse.cs index 8a8266c662f..db2c6a06aef 100644 --- a/src/NzbDrone.Common/Http/HttpResponse.cs +++ b/src/NzbDrone.Common/Http/HttpResponse.cs @@ -101,12 +101,14 @@ public override string ToString() public class HttpResponse : HttpResponse where T : new() { + private readonly Lazy _resource; + public HttpResponse(HttpResponse response) : base(response.Request, response.Headers, response.ResponseData, response.StatusCode, response.Version) { - Resource = Json.Deserialize(response.Content); + _resource = new Lazy(() => Json.Deserialize(response.Content)); } - public T Resource { get; private set; } + public T Resource => _resource.Value; } } diff --git a/src/NzbDrone.Common/Radarr.Common.csproj b/src/NzbDrone.Common/Radarr.Common.csproj index 6bc1cfa8379..9c091bf80a1 100644 --- a/src/NzbDrone.Common/Radarr.Common.csproj +++ b/src/NzbDrone.Common/Radarr.Common.csproj @@ -5,17 +5,17 @@ - - + + - + - + diff --git a/src/NzbDrone.Core.Test/MediaCoverTests/MediaCoverServiceFixture.cs b/src/NzbDrone.Core.Test/MediaCoverTests/MediaCoverServiceFixture.cs index 120fd5ab7c0..d951c08b84a 100644 --- a/src/NzbDrone.Core.Test/MediaCoverTests/MediaCoverServiceFixture.cs +++ b/src/NzbDrone.Core.Test/MediaCoverTests/MediaCoverServiceFixture.cs @@ -26,37 +26,29 @@ public void Setup() _movie = Builder.CreateNew() .With(v => v.Id = 2) - .With(v => v.MovieMetadata.Value.Images = new List { new MediaCover.MediaCover(MediaCoverTypes.Poster, "") }) + .With(v => v.MovieMetadata.Value.Images = new List { new(MediaCoverTypes.Poster, "") }) .Build(); - - Mocker.GetMock().Setup(m => m.GetMovie(It.Is(id => id == _movie.Id))).Returns(_movie); } [Test] public void should_convert_cover_urls_to_local() { var covers = new List - { - new MediaCover.MediaCover { CoverType = MediaCoverTypes.Banner } - }; - - Mocker.GetMock().Setup(c => c.FileGetLastWrite(It.IsAny())) - .Returns(new DateTime(1234)); - - Mocker.GetMock().Setup(c => c.FileExists(It.IsAny())) - .Returns(true); + { + new() { CoverType = MediaCoverTypes.Banner, RemoteUrl = "https://artworks.examples.com/banners/1.jpg" } + }; Subject.ConvertToLocalUrls(12, covers); - covers.Single().Url.Should().Be("/MediaCover/12/banner.jpg?lastWrite=1234"); + covers.Single().Url.Should().Be("/MediaCover/12/banner.jpg?h=a6210a45e2b93963ad9e"); } [Test] - public void should_convert_media_urls_to_local_without_time_if_file_doesnt_exist() + public void should_convert_media_urls_to_local_without_hash_if_remote_url_is_empty() { var covers = new List { - new MediaCover.MediaCover { CoverType = MediaCoverTypes.Banner } + new() { CoverType = MediaCoverTypes.Banner } }; Subject.ConvertToLocalUrls(12, covers); diff --git a/src/NzbDrone.Core.Test/Radarr.Core.Test.csproj b/src/NzbDrone.Core.Test/Radarr.Core.Test.csproj index 6f858c1430a..3b5fe0279ba 100644 --- a/src/NzbDrone.Core.Test/Radarr.Core.Test.csproj +++ b/src/NzbDrone.Core.Test/Radarr.Core.Test.csproj @@ -24,7 +24,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/NzbDrone.Core/CustomFormats/Specifications/IndexerFlagSpecification.cs b/src/NzbDrone.Core/CustomFormats/Specifications/IndexerFlagSpecification.cs index 56d8926b5ed..7132ba4d788 100644 --- a/src/NzbDrone.Core/CustomFormats/Specifications/IndexerFlagSpecification.cs +++ b/src/NzbDrone.Core/CustomFormats/Specifications/IndexerFlagSpecification.cs @@ -11,11 +11,11 @@ public class IndexerFlagSpecificationValidator : AbstractValidator c.Value).NotEmpty(); - RuleFor(c => c.Value).Custom((qualityValue, context) => + RuleFor(c => c.Value).Custom((flag, context) => { - if (!Enum.IsDefined(typeof(IndexerFlags), qualityValue)) + if (!Enum.IsDefined(typeof(IndexerFlags), flag)) { - context.AddFailure($"Invalid indexer flag condition value: {qualityValue}"); + context.AddFailure($"Invalid indexer flag condition value: {flag}"); } }); } diff --git a/src/NzbDrone.Core/CustomFormats/Specifications/QualityModifierSpecification.cs b/src/NzbDrone.Core/CustomFormats/Specifications/QualityModifierSpecification.cs index d5a1cf7872a..6268f55a9b9 100644 --- a/src/NzbDrone.Core/CustomFormats/Specifications/QualityModifierSpecification.cs +++ b/src/NzbDrone.Core/CustomFormats/Specifications/QualityModifierSpecification.cs @@ -10,12 +10,11 @@ public class QualityModifierSpecificationValidator : AbstractValidator c.Value).NotEmpty(); - RuleFor(c => c.Value).Custom((qualityValue, context) => + RuleFor(c => c.Value).Custom((value, context) => { - if (!Enum.IsDefined(typeof(Modifier), qualityValue)) + if (!Enum.IsDefined(typeof(Modifier), value)) { - context.AddFailure(string.Format("Invalid quality modifier condition value: {0}", qualityValue)); + context.AddFailure($"Invalid quality modifier condition value: {value}"); } }); } @@ -23,7 +22,7 @@ public QualityModifierSpecificationValidator() public class QualityModifierSpecification : CustomFormatSpecificationBase { - private static readonly QualityModifierSpecificationValidator Validator = new QualityModifierSpecificationValidator(); + private static readonly QualityModifierSpecificationValidator Validator = new(); public override int Order => 7; public override string ImplementationName => "Quality Modifier"; diff --git a/src/NzbDrone.Core/CustomFormats/Specifications/ResolutionSpecification.cs b/src/NzbDrone.Core/CustomFormats/Specifications/ResolutionSpecification.cs index a7866d0a026..1cd93efa085 100644 --- a/src/NzbDrone.Core/CustomFormats/Specifications/ResolutionSpecification.cs +++ b/src/NzbDrone.Core/CustomFormats/Specifications/ResolutionSpecification.cs @@ -1,3 +1,4 @@ +using System; using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.Parser; @@ -9,13 +10,19 @@ public class ResolutionSpecificationValidator : AbstractValidator c.Value).NotEmpty(); + RuleFor(c => c.Value).Custom((value, context) => + { + if (!Enum.IsDefined(typeof(Resolution), value)) + { + context.AddFailure($"Invalid resolution condition value: {value}"); + } + }); } } public class ResolutionSpecification : CustomFormatSpecificationBase { - private static readonly ResolutionSpecificationValidator Validator = new ResolutionSpecificationValidator(); + private static readonly ResolutionSpecificationValidator Validator = new(); public override int Order => 6; public override string ImplementationName => "Resolution"; diff --git a/src/NzbDrone.Core/CustomFormats/Specifications/SourceSpecification.cs b/src/NzbDrone.Core/CustomFormats/Specifications/SourceSpecification.cs index b5d3566996d..7bd8bbe9604 100644 --- a/src/NzbDrone.Core/CustomFormats/Specifications/SourceSpecification.cs +++ b/src/NzbDrone.Core/CustomFormats/Specifications/SourceSpecification.cs @@ -1,3 +1,4 @@ +using System; using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.Qualities; @@ -9,13 +10,19 @@ public class SourceSpecificationValidator : AbstractValidator c.Value).NotEmpty(); + RuleFor(c => c.Value).Custom((value, context) => + { + if (!Enum.IsDefined(typeof(QualitySource), value)) + { + context.AddFailure($"Invalid source condition value: {value}"); + } + }); } } public class SourceSpecification : CustomFormatSpecificationBase { - private static readonly SourceSpecificationValidator Validator = new SourceSpecificationValidator(); + private static readonly SourceSpecificationValidator Validator = new(); public override int Order => 5; public override string ImplementationName => "Source"; diff --git a/src/NzbDrone.Core/Datastore/BasicRepository.cs b/src/NzbDrone.Core/Datastore/BasicRepository.cs index 618999992a6..cb5dca20a3a 100644 --- a/src/NzbDrone.Core/Datastore/BasicRepository.cs +++ b/src/NzbDrone.Core/Datastore/BasicRepository.cs @@ -266,8 +266,10 @@ public void UpdateMany(IList models) } using (var conn = _database.OpenConnection()) + using (var tran = conn.BeginTransaction(IsolationLevel.ReadCommitted)) { - UpdateFields(conn, null, models, _properties); + UpdateFields(conn, tran, models, _properties); + tran.Commit(); } } @@ -371,8 +373,10 @@ public void SetFields(IList models, params Expression x.GetMemberName()).ToList(); using (var conn = _database.OpenConnection()) + using (var tran = conn.BeginTransaction(IsolationLevel.ReadCommitted)) { - UpdateFields(conn, null, models, propertiesToUpdate); + UpdateFields(conn, tran, models, propertiesToUpdate); + tran.Commit(); } foreach (var model in models) diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs index 5fc5152f159..248bd89dba4 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs @@ -104,7 +104,7 @@ public UpgradeableRejectReason IsUpgradable(QualityProfile qualityProfile, Quali if (newFormatScore < currentFormatScore + qualityProfile.MinUpgradeFormatScore) { - _logger.Debug("New item's custom formats [{0}] ({1}) do not meet minimum custom format score increment of {3} required for upgrade, skipping. Existing: [{4}] ({5}).", + _logger.Debug("New item's custom formats [{0}] ({1}) do not meet minimum custom format score increment of {2} required for upgrade, skipping. Existing: [{3}] ({4}).", newCustomFormats.ConcatToString(), newFormatScore, qualityProfile.MinUpgradeFormatScore, diff --git a/src/NzbDrone.Core/MediaCover/MediaCoverService.cs b/src/NzbDrone.Core/MediaCover/MediaCoverService.cs index 8a2a32a39c1..40f43abac71 100644 --- a/src/NzbDrone.Core/MediaCover/MediaCoverService.cs +++ b/src/NzbDrone.Core/MediaCover/MediaCoverService.cs @@ -1,11 +1,9 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Net; using System.Threading; using NLog; -using NzbDrone.Common; using NzbDrone.Common.Disk; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.Extensions; @@ -19,9 +17,7 @@ namespace NzbDrone.Core.MediaCover { public interface IMapCoversToLocal { - Dictionary GetCoverFileInfos(); - void ConvertToLocalUrls(int movieId, IEnumerable covers, Dictionary fileInfos = null); - void ConvertToLocalUrls(IEnumerable>> items, Dictionary coverFileInfos); + void ConvertToLocalUrls(int movieId, IEnumerable covers); string GetCoverPath(int movieId, MediaCoverTypes coverType, int? height = null); } @@ -43,7 +39,7 @@ public class MediaCoverService : // ImageSharp is slow on ARM (no hardware acceleration on mono yet) // So limit the number of concurrent resizing tasks - private static SemaphoreSlim _semaphore = new SemaphoreSlim((int)Math.Ceiling(Environment.ProcessorCount / 2.0)); + private static readonly SemaphoreSlim Semaphore = new((int)Math.Ceiling(Environment.ProcessorCount / 2.0)); public MediaCoverService(IMediaCoverProxy mediaCoverProxy, IImageResizer resizer, @@ -69,28 +65,16 @@ public MediaCoverService(IMediaCoverProxy mediaCoverProxy, public string GetCoverPath(int movieId, MediaCoverTypes coverType, int? height = null) { - var heightSuffix = height.HasValue ? "-" + height.ToString() : ""; + var heightSuffix = height.HasValue ? $"-{height}" : ""; - return Path.Combine(GetMovieCoverPath(movieId), coverType.ToString().ToLower() + heightSuffix + GetExtension(coverType)); + return Path.Combine(GetMovieCoverPath(movieId), coverType.ToString().ToLowerInvariant() + heightSuffix + GetExtension(coverType)); } - public Dictionary GetCoverFileInfos() - { - if (!_diskProvider.FolderExists(_coverRootFolder)) - { - return new Dictionary(); - } - - return _diskProvider - .GetFileInfos(_coverRootFolder, true) - .ToDictionary(x => x.FullName, PathEqualityComparer.Instance); - } - - public void ConvertToLocalUrls(int movieId, IEnumerable covers, Dictionary fileInfos = null) + public void ConvertToLocalUrls(int movieId, IEnumerable covers) { if (movieId == 0) { - // Movie isn't in Radarr yet, map via a proxy to circument referrer issues + // Movie isn't in Radarr yet, map via a proxy to circumvent referrer issues foreach (var mediaCover in covers) { mediaCover.Url = _mediaCoverProxy.RegisterUrl(mediaCover.RemoteUrl); @@ -105,37 +89,16 @@ public void ConvertToLocalUrls(int movieId, IEnumerable covers, Dict continue; } - var filePath = GetCoverPath(movieId, mediaCover.CoverType); - - mediaCover.Url = _configFileProvider.UrlBase + @"/MediaCover/" + movieId + "/" + mediaCover.CoverType.ToString().ToLower() + GetExtension(mediaCover.CoverType); - - DateTime? lastWrite = null; - - if (fileInfos != null && fileInfos.TryGetValue(filePath, out var file)) - { - lastWrite = file.LastWriteTimeUtc; - } - else if (_diskProvider.FileExists(filePath)) - { - lastWrite = _diskProvider.FileGetLastWrite(filePath); - } + mediaCover.Url = _configFileProvider.UrlBase + @"/MediaCover/" + movieId + "/" + mediaCover.CoverType.ToString().ToLowerInvariant() + GetExtension(mediaCover.CoverType); - if (lastWrite.HasValue) + if (mediaCover.RemoteUrl.IsNotNullOrWhiteSpace()) { - mediaCover.Url += "?lastWrite=" + lastWrite.Value.Ticks; + mediaCover.Url += "?h=" + mediaCover.RemoteUrl.SHA256Hash()[..20]; } } } } - public void ConvertToLocalUrls(IEnumerable>> items, Dictionary coverFileInfos) - { - foreach (var movie in items) - { - ConvertToLocalUrls(movie.Item1, movie.Item2, coverFileInfos); - } - } - private string GetMovieCoverPath(int movieId) { return Path.Combine(_coverRootFolder, movieId.ToString()); @@ -184,7 +147,7 @@ private bool EnsureCovers(Movie movie) try { - _semaphore.Wait(); + Semaphore.Wait(); foreach (var tuple in toResize) { @@ -193,7 +156,7 @@ private bool EnsureCovers(Movie movie) } finally { - _semaphore.Release(); + Semaphore.Release(); } return updated; @@ -252,7 +215,7 @@ private void EnsureResizedCovers(Movie movie, MediaCover cover, bool forceResize } } - private string GetExtension(MediaCoverTypes coverType) + private static string GetExtension(MediaCoverTypes coverType) { return coverType switch { diff --git a/src/NzbDrone.Core/MediaFiles/ScriptImportDecider.cs b/src/NzbDrone.Core/MediaFiles/ScriptImportDecider.cs index 56888ffb09d..08f66bd1fe3 100644 --- a/src/NzbDrone.Core/MediaFiles/ScriptImportDecider.cs +++ b/src/NzbDrone.Core/MediaFiles/ScriptImportDecider.cs @@ -139,7 +139,7 @@ public ScriptImportDecision TryImport(string sourcePath, string destinationFileP environmentVariables.Add("Radarr_Movie_ImdbId", movie.MovieMetadata.Value.ImdbId ?? string.Empty); environmentVariables.Add("Radarr_Movie_OriginalLanguage", IsoLanguages.Get(movie.MovieMetadata.Value.OriginalLanguage).ThreeLetterCode); environmentVariables.Add("Radarr_Movie_Genres", string.Join("|", movie.MovieMetadata.Value.Genres)); - environmentVariables.Add("Radarr_Movie_Tags", string.Join("|", movie.Tags.Select(t => _tagRepository.Get(t).Label))); + environmentVariables.Add("Radarr_Movie_Tags", string.Join("|", _tagRepository.GetTags(movie.Tags).Select(t => t.Label))); environmentVariables.Add("Radarr_Movie_In_Cinemas_Date", movie.MovieMetadata.Value.InCinemas.ToString() ?? string.Empty); environmentVariables.Add("Radarr_Movie_Physical_Release_Date", movie.MovieMetadata.Value.PhysicalRelease.ToString() ?? string.Empty); diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs index 6afb7326980..76bfce6dc23 100644 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs +++ b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs @@ -516,17 +516,12 @@ public List SearchForNewMovie(string title) var searchTerm = parserTitle.Replace("_", "+").Replace(" ", "+").Replace(".", "+"); - var firstChar = searchTerm.First(); - var request = _radarrMetadata.Create() .SetSegment("route", "search") .AddQueryParam("q", searchTerm) .AddQueryParam("year", yearTerm) .Build(); - request.AllowAutoRedirect = true; - request.SuppressHttpError = true; - var httpResponse = _httpClient.Get>(request); return httpResponse.Resource.SelectList(MapSearchResult); @@ -651,7 +646,7 @@ private static Ratings MapRatings(RatingResource ratings) { mappedRatings.Tmdb = new RatingChild { - Type = (RatingType)Enum.Parse(typeof(RatingType), ratings.Tmdb.Type), + Type = (RatingType)Enum.Parse(typeof(RatingType), ratings.Tmdb.Type, true), Value = ratings.Tmdb.Value, Votes = ratings.Tmdb.Count }; @@ -661,7 +656,7 @@ private static Ratings MapRatings(RatingResource ratings) { mappedRatings.Imdb = new RatingChild { - Type = (RatingType)Enum.Parse(typeof(RatingType), ratings.Imdb.Type), + Type = (RatingType)Enum.Parse(typeof(RatingType), ratings.Imdb.Type, true), Value = ratings.Imdb.Value, Votes = ratings.Imdb.Count }; @@ -671,7 +666,7 @@ private static Ratings MapRatings(RatingResource ratings) { mappedRatings.Metacritic = new RatingChild { - Type = (RatingType)Enum.Parse(typeof(RatingType), ratings.Metacritic.Type), + Type = (RatingType)Enum.Parse(typeof(RatingType), ratings.Metacritic.Type, true), Value = ratings.Metacritic.Value, Votes = ratings.Metacritic.Count }; @@ -681,7 +676,7 @@ private static Ratings MapRatings(RatingResource ratings) { mappedRatings.RottenTomatoes = new RatingChild { - Type = (RatingType)Enum.Parse(typeof(RatingType), ratings.RottenTomatoes.Type), + Type = (RatingType)Enum.Parse(typeof(RatingType), ratings.RottenTomatoes.Type, true), Value = ratings.RottenTomatoes.Value, Votes = ratings.RottenTomatoes.Count }; @@ -691,7 +686,7 @@ private static Ratings MapRatings(RatingResource ratings) { mappedRatings.Trakt = new RatingChild { - Type = (RatingType)Enum.Parse(typeof(RatingType), ratings.Trakt.Type), + Type = (RatingType)Enum.Parse(typeof(RatingType), ratings.Trakt.Type, true), Value = ratings.Trakt.Value, Votes = ratings.Trakt.Count }; diff --git a/src/NzbDrone.Core/Radarr.Core.csproj b/src/NzbDrone.Core/Radarr.Core.csproj index 392c3a3b5af..7fd51a0b203 100644 --- a/src/NzbDrone.Core/Radarr.Core.csproj +++ b/src/NzbDrone.Core/Radarr.Core.csproj @@ -7,12 +7,12 @@ - - + + - - + + diff --git a/src/NzbDrone.Host.Test/Radarr.Host.Test.csproj b/src/NzbDrone.Host.Test/Radarr.Host.Test.csproj index 8ba6cadba8f..1dcd878b498 100644 --- a/src/NzbDrone.Host.Test/Radarr.Host.Test.csproj +++ b/src/NzbDrone.Host.Test/Radarr.Host.Test.csproj @@ -7,7 +7,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/NzbDrone.Integration.Test/Radarr.Integration.Test.csproj b/src/NzbDrone.Integration.Test/Radarr.Integration.Test.csproj index 7bd9b9c3e79..f5e7d35c44b 100644 --- a/src/NzbDrone.Integration.Test/Radarr.Integration.Test.csproj +++ b/src/NzbDrone.Integration.Test/Radarr.Integration.Test.csproj @@ -4,14 +4,14 @@ Library - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/NzbDrone.Libraries.Test/Radarr.Libraries.Test.csproj b/src/NzbDrone.Libraries.Test/Radarr.Libraries.Test.csproj index 0277bd08227..f836c4b3753 100644 --- a/src/NzbDrone.Libraries.Test/Radarr.Libraries.Test.csproj +++ b/src/NzbDrone.Libraries.Test/Radarr.Libraries.Test.csproj @@ -6,7 +6,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/NzbDrone.Mono.Test/Radarr.Mono.Test.csproj b/src/NzbDrone.Mono.Test/Radarr.Mono.Test.csproj index 6c695c02220..9b6ecb4870c 100644 --- a/src/NzbDrone.Mono.Test/Radarr.Mono.Test.csproj +++ b/src/NzbDrone.Mono.Test/Radarr.Mono.Test.csproj @@ -20,7 +20,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/NzbDrone.Update.Test/Radarr.Update.Test.csproj b/src/NzbDrone.Update.Test/Radarr.Update.Test.csproj index f93e85645c7..c0f7caa29be 100644 --- a/src/NzbDrone.Update.Test/Radarr.Update.Test.csproj +++ b/src/NzbDrone.Update.Test/Radarr.Update.Test.csproj @@ -7,7 +7,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/NzbDrone.Windows.Test/Radarr.Windows.Test.csproj b/src/NzbDrone.Windows.Test/Radarr.Windows.Test.csproj index 2a72e9f546f..748164c6900 100644 --- a/src/NzbDrone.Windows.Test/Radarr.Windows.Test.csproj +++ b/src/NzbDrone.Windows.Test/Radarr.Windows.Test.csproj @@ -8,7 +8,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Radarr.Api.V3/Movies/MovieController.cs b/src/Radarr.Api.V3/Movies/MovieController.cs index 42d85925478..d92f75dc3c0 100644 --- a/src/Radarr.Api.V3/Movies/MovieController.cs +++ b/src/Radarr.Api.V3/Movies/MovieController.cs @@ -1,6 +1,4 @@ -using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Threading.Tasks; using FluentValidation; @@ -156,9 +154,7 @@ public List AllMovie(int? tmdbId, bool excludeLocalCovers = false if (!excludeLocalCovers) { - var coverFileInfos = _coverMapper.GetCoverFileInfos(); - - MapCoversToLocal(moviesResources, coverFileInfos); + MapCoversToLocal(moviesResources.ToArray()); } LinkMovieStatistics(moviesResources, sdict); @@ -283,14 +279,12 @@ public void DeleteMovie(int id, bool deleteFiles = false, bool addImportExclusio _moviesService.DeleteMovie(id, deleteFiles, addImportExclusion); } - private void MapCoversToLocal(MovieResource movie) - { - _coverMapper.ConvertToLocalUrls(movie.Id, movie.Images); - } - - private void MapCoversToLocal(IEnumerable movies, Dictionary coverFileInfos) + private void MapCoversToLocal(params MovieResource[] movies) { - _coverMapper.ConvertToLocalUrls(movies.Select(x => Tuple.Create(x.Id, x.Images.AsEnumerable())), coverFileInfos); + foreach (var movieResource in movies) + { + _coverMapper.ConvertToLocalUrls(movieResource.Id, movieResource.Images); + } } private void FetchAndLinkMovieStatistics(MovieResource resource) diff --git a/src/Radarr.Api.V3/Radarr.Api.V3.csproj b/src/Radarr.Api.V3/Radarr.Api.V3.csproj index 6a702ef0a82..28fbe0b9b22 100644 --- a/src/Radarr.Api.V3/Radarr.Api.V3.csproj +++ b/src/Radarr.Api.V3/Radarr.Api.V3.csproj @@ -3,7 +3,7 @@ net10.0 - +