From 9e1d4fe6fc8dc55122400e1e035d1b483f43bf30 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 16 Sep 2023 14:58:33 +0300 Subject: [PATCH] Async skyhook, movie lookup and media cover proxy --- .../FetchAndParseImportListServiceFixture.cs | 3 +- .../CoverExistsSpecificationFixture.cs | 23 ++++++++----- .../MediaCoverServiceFixture.cs | 11 ++++--- .../SkyHook/SkyHookProxyFixture.cs | 6 ++-- .../SkyHook/SkyHookProxySearchFixture.cs | 9 ++--- .../MovieTests/AddMovieFixture.cs | 15 +++++---- .../MovieTests/RefreshMovieServiceFixture.cs | 3 +- .../FetchAndParseImportListService.cs | 2 +- .../ImportLists/ImportListSyncService.cs | 17 +++++----- .../CoverAlreadyExistsSpecification.cs | 12 ++++--- .../MediaCover/MediaCoverService.cs | 15 +++++---- .../MetadataSource/IProvideMovieInfo.cs | 5 +-- .../MetadataSource/ISearchForNewMovie.cs | 5 +-- .../MetadataSource/SkyHook/SkyHookProxy.cs | 33 +++++++++++-------- src/NzbDrone.Core/Movies/AddMovieService.cs | 18 +++++----- .../Movies/RefreshCollectionService.cs | 9 ++--- .../Movies/RefreshMovieService.cs | 9 ++--- .../ImportLists/ImportListMoviesController.cs | 9 +++-- src/Radarr.Api.V3/Movies/MovieController.cs | 4 +-- .../Movies/MovieImportController.cs | 8 +++-- .../Movies/MovieLookupController.cs | 19 +++++++---- 21 files changed, 139 insertions(+), 96 deletions(-) diff --git a/src/NzbDrone.Core.Test/ImportListTests/FetchAndParseImportListServiceFixture.cs b/src/NzbDrone.Core.Test/ImportListTests/FetchAndParseImportListServiceFixture.cs index e89ed32d7..82e49c3d6 100644 --- a/src/NzbDrone.Core.Test/ImportListTests/FetchAndParseImportListServiceFixture.cs +++ b/src/NzbDrone.Core.Test/ImportListTests/FetchAndParseImportListServiceFixture.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FizzWare.NBuilder; using FluentAssertions; using Moq; @@ -39,7 +40,7 @@ namespace NzbDrone.Core.Test.ImportListTests Mocker.GetMock() .Setup(v => v.MapMovieToTmdbMovie(It.IsAny())) - .Returns(m => new MovieMetadata { TmdbId = m.TmdbId }); + .Returns(m => Task.FromResult(new MovieMetadata { TmdbId = m.TmdbId })); } private void GivenList(int id, bool enabled, bool enabledAuto, ImportListFetchResult fetchResult) diff --git a/src/NzbDrone.Core.Test/MediaCoverTests/CoverExistsSpecificationFixture.cs b/src/NzbDrone.Core.Test/MediaCoverTests/CoverExistsSpecificationFixture.cs index ff34a9efe..7e3743e9d 100644 --- a/src/NzbDrone.Core.Test/MediaCoverTests/CoverExistsSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/MediaCoverTests/CoverExistsSpecificationFixture.cs @@ -1,4 +1,5 @@ using System.Net; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -19,7 +20,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests { _httpResponse = new HttpResponse(null, new HttpHeader(), "", HttpStatusCode.OK); Mocker.GetMock().Setup(c => c.GetFileSize(It.IsAny())).Returns(100); - Mocker.GetMock().Setup(c => c.Head(It.IsAny())).Returns(_httpResponse); + Mocker.GetMock().Setup(c => c.HeadAsync(It.IsAny())).Returns(Task.FromResult(_httpResponse)); } private void GivenFileExistsOnDisk() @@ -34,33 +35,37 @@ namespace NzbDrone.Core.Test.MediaCoverTests } [Test] - public void should_return_false_if_file_not_exists() + public async Task should_return_false_if_file_not_exists() { - Subject.AlreadyExists("http://url", "c:\\file.exe").Should().BeFalse(); + var result = await Subject.AlreadyExists("http://url", "c:\\file.exe"); + result.Should().BeFalse(); } [Test] - public void should_return_false_if_file_exists_but_diffrent_size() + public async Task should_return_false_if_file_exists_but_diffrent_size() { GivenExistingFileSize(100); _httpResponse.Headers.ContentLength = 200; - Subject.AlreadyExists("http://url", "c:\\file.exe").Should().BeFalse(); + var result = await Subject.AlreadyExists("http://url", "c:\\file.exe"); + result.Should().BeFalse(); } [Test] - public void should_return_true_if_file_exists_and_same_size_and_not_corrupt() + public async Task should_return_true_if_file_exists_and_same_size_and_not_corrupt() { GivenExistingFileSize(100); _httpResponse.Headers.ContentLength = 100; - Subject.AlreadyExists("http://url", "c:\\file.exe").Should().BeTrue(); + var result = await Subject.AlreadyExists("http://url", "c:\\file.exe"); + result.Should().BeTrue(); } [Test] - public void should_return_true_if_there_is_no_size_header_and_file_exist() + public async Task should_return_true_if_there_is_no_size_header_and_file_exist() { GivenExistingFileSize(100); - Subject.AlreadyExists("http://url", "c:\\file.exe").Should().BeFalse(); + var result = await Subject.AlreadyExists("http://url", "c:\\file.exe"); + result.Should().BeFalse(); } } } diff --git a/src/NzbDrone.Core.Test/MediaCoverTests/MediaCoverServiceFixture.cs b/src/NzbDrone.Core.Test/MediaCoverTests/MediaCoverServiceFixture.cs index ba11c4355..0b209f527 100644 --- a/src/NzbDrone.Core.Test/MediaCoverTests/MediaCoverServiceFixture.cs +++ b/src/NzbDrone.Core.Test/MediaCoverTests/MediaCoverServiceFixture.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading.Tasks; using FizzWare.NBuilder; using FluentAssertions; using Moq; @@ -78,7 +79,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests { Mocker.GetMock() .Setup(v => v.AlreadyExists(It.IsAny(), It.IsAny())) - .Returns(false); + .Returns(Task.FromResult(false)); Mocker.GetMock() .Setup(v => v.FileExists(It.IsAny())) @@ -95,7 +96,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests { Mocker.GetMock() .Setup(v => v.AlreadyExists(It.IsAny(), It.IsAny())) - .Returns(true); + .Returns(Task.FromResult(true)); Mocker.GetMock() .Setup(v => v.FileExists(It.IsAny())) @@ -112,7 +113,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests { Mocker.GetMock() .Setup(v => v.AlreadyExists(It.IsAny(), It.IsAny())) - .Returns(true); + .Returns(Task.FromResult(true)); Mocker.GetMock() .Setup(v => v.FileExists(It.IsAny())) @@ -133,7 +134,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests { Mocker.GetMock() .Setup(v => v.AlreadyExists(It.IsAny(), It.IsAny())) - .Returns(true); + .Returns(Task.FromResult(true)); Mocker.GetMock() .Setup(v => v.FileExists(It.IsAny())) @@ -154,7 +155,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests { Mocker.GetMock() .Setup(v => v.AlreadyExists(It.IsAny(), It.IsAny())) - .Returns(true); + .Returns(Task.FromResult(true)); Mocker.GetMock() .Setup(v => v.FileExists(It.IsAny())) diff --git a/src/NzbDrone.Core.Test/MetadataSource/SkyHook/SkyHookProxyFixture.cs b/src/NzbDrone.Core.Test/MetadataSource/SkyHook/SkyHookProxyFixture.cs index b8e790a5b..443297551 100644 --- a/src/NzbDrone.Core.Test/MetadataSource/SkyHook/SkyHookProxyFixture.cs +++ b/src/NzbDrone.Core.Test/MetadataSource/SkyHook/SkyHookProxyFixture.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using FluentAssertions; using NUnit.Framework; using NzbDrone.Core.MetadataSource.SkyHook; @@ -20,9 +21,10 @@ namespace NzbDrone.Core.Test.MetadataSource.SkyHook [TestCase(11, "Star Wars")] [TestCase(2, "Ariel")] [TestCase(70981, "Prometheus")] - public void should_be_able_to_get_movie_detail(int tmdbId, string title) + public async Task should_be_able_to_get_movie_detail(int tmdbId, string title) { - var details = Subject.GetMovieInfo(tmdbId).Item1; + var movieInfo = await Subject.GetMovieInfo(tmdbId); + var details = movieInfo.Item1; ValidateMovie(details); diff --git a/src/NzbDrone.Core.Test/MetadataSource/SkyHook/SkyHookProxySearchFixture.cs b/src/NzbDrone.Core.Test/MetadataSource/SkyHook/SkyHookProxySearchFixture.cs index 4ae0b066d..69dfdab7a 100644 --- a/src/NzbDrone.Core.Test/MetadataSource/SkyHook/SkyHookProxySearchFixture.cs +++ b/src/NzbDrone.Core.Test/MetadataSource/SkyHook/SkyHookProxySearchFixture.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using FluentAssertions; using NUnit.Framework; using NzbDrone.Core.MetadataSource.SkyHook; @@ -23,9 +24,9 @@ namespace NzbDrone.Core.Test.MetadataSource.SkyHook // [TestCase("The Man from U.N.C.L.E.", "The Man from U.N.C.L.E.")] [TestCase("imdb:tt2527336", "Star Wars: The Last Jedi")] [TestCase("imdb:tt2798920", "Annihilation")] - public void successful_search(string title, string expected) + public async Task successful_search(string title, string expected) { - var result = Subject.SearchForNewMovie(title); + var result = await Subject.SearchForNewMovie(title); result.Should().NotBeEmpty(); @@ -41,9 +42,9 @@ namespace NzbDrone.Core.Test.MetadataSource.SkyHook [TestCase("tmdbid:1")] [TestCase("adjalkwdjkalwdjklawjdlKAJD;EF")] [TestCase("imdb: tt9805708")] - public void no_search_result(string term) + public async Task no_search_result(string term) { - var result = Subject.SearchForNewMovie(term); + var result = await Subject.SearchForNewMovie(term); result.Should().BeEmpty(); ExceptionVerification.IgnoreWarns(); diff --git a/src/NzbDrone.Core.Test/MovieTests/AddMovieFixture.cs b/src/NzbDrone.Core.Test/MovieTests/AddMovieFixture.cs index a97d6196b..9a2aeba20 100644 --- a/src/NzbDrone.Core.Test/MovieTests/AddMovieFixture.cs +++ b/src/NzbDrone.Core.Test/MovieTests/AddMovieFixture.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Threading.Tasks; using FizzWare.NBuilder; using FluentAssertions; using FluentValidation; @@ -36,7 +37,7 @@ namespace NzbDrone.Core.Test.MovieTests { Mocker.GetMock() .Setup(s => s.GetMovieInfo(tmdbId)) - .Returns(new Tuple>(_fakeMovie, new List())); + .Returns(Task.FromResult(new Tuple>(_fakeMovie, new List()))); } private void GivenValidPath() @@ -51,7 +52,7 @@ namespace NzbDrone.Core.Test.MovieTests } [Test] - public void should_be_able_to_add_a_movie_without_passing_in_title() + public async Task should_be_able_to_add_a_movie_without_passing_in_title() { var newMovie = new Movie { @@ -62,13 +63,13 @@ namespace NzbDrone.Core.Test.MovieTests GivenValidMovie(newMovie.TmdbId); GivenValidPath(); - var series = Subject.AddMovie(newMovie); + var series = await Subject.AddMovie(newMovie); series.Title.Should().Be(_fakeMovie.Title); } [Test] - public void should_have_proper_path() + public async Task should_have_proper_path() { var newMovie = new Movie { @@ -79,7 +80,7 @@ namespace NzbDrone.Core.Test.MovieTests GivenValidMovie(newMovie.TmdbId); GivenValidPath(); - var series = Subject.AddMovie(newMovie); + var series = await Subject.AddMovie(newMovie); series.Path.Should().Be(Path.Combine(newMovie.RootFolderPath, _fakeMovie.Title)); } @@ -102,7 +103,7 @@ namespace NzbDrone.Core.Test.MovieTests new ValidationFailure("Path", "Test validation failure") })); - Assert.Throws(() => Subject.AddMovie(newMovie)); + Assert.ThrowsAsync(async () => await Subject.AddMovie(newMovie)); } [Test] @@ -125,7 +126,7 @@ namespace NzbDrone.Core.Test.MovieTests new ValidationFailure("Path", "Test validation failure") })); - Assert.Throws(() => Subject.AddMovie(newMovie)); + Assert.ThrowsAsync(async () => await Subject.AddMovie(newMovie)); ExceptionVerification.ExpectedErrors(1); } diff --git a/src/NzbDrone.Core.Test/MovieTests/RefreshMovieServiceFixture.cs b/src/NzbDrone.Core.Test/MovieTests/RefreshMovieServiceFixture.cs index 33cb41ac4..bf901dec2 100644 --- a/src/NzbDrone.Core.Test/MovieTests/RefreshMovieServiceFixture.cs +++ b/src/NzbDrone.Core.Test/MovieTests/RefreshMovieServiceFixture.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using FizzWare.NBuilder; using Moq; using NUnit.Framework; @@ -67,7 +68,7 @@ namespace NzbDrone.Core.Test.MovieTests { Mocker.GetMock() .Setup(s => s.GetMovieInfo(_movie.TmdbId)) - .Returns(new Tuple>(movie, new List())); + .Returns(Task.FromResult(new Tuple>(movie, new List()))); } [Test] diff --git a/src/NzbDrone.Core/ImportLists/FetchAndParseImportListService.cs b/src/NzbDrone.Core/ImportLists/FetchAndParseImportListService.cs index d47aeb71f..0e950ad30 100644 --- a/src/NzbDrone.Core/ImportLists/FetchAndParseImportListService.cs +++ b/src/NzbDrone.Core/ImportLists/FetchAndParseImportListService.cs @@ -190,7 +190,7 @@ namespace NzbDrone.Core.ImportLists private List MapMovieReports(IEnumerable reports) { - var mappedMovies = reports.Select(m => _movieSearch.MapMovieToTmdbMovie(new MovieMetadata { Title = m.Title, TmdbId = m.TmdbId, ImdbId = m.ImdbId, Year = m.Year })) + var mappedMovies = reports.Select(m => _movieSearch.MapMovieToTmdbMovie(new MovieMetadata { Title = m.Title, TmdbId = m.TmdbId, ImdbId = m.ImdbId, Year = m.Year }).GetAwaiter().GetResult()) .Where(x => x != null) .DistinctBy(x => x.TmdbId) .ToList(); diff --git a/src/NzbDrone.Core/ImportLists/ImportListSyncService.cs b/src/NzbDrone.Core/ImportLists/ImportListSyncService.cs index f73d0b7dd..ce5a1db4d 100644 --- a/src/NzbDrone.Core/ImportLists/ImportListSyncService.cs +++ b/src/NzbDrone.Core/ImportLists/ImportListSyncService.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using NLog; using NzbDrone.Common.Extensions; using NzbDrone.Common.Instrumentation.Extensions; @@ -41,7 +42,7 @@ namespace NzbDrone.Core.ImportLists _configService = configService; } - private void SyncAll() + private async Task SyncAll() { if (_importListFactory.Enabled().Empty()) { @@ -62,16 +63,16 @@ namespace NzbDrone.Core.ImportLists CleanLibrary(); } - ProcessListItems(listItemsResult); + await ProcessListItems(listItemsResult); } - private void SyncList(ImportListDefinition definition) + private async Task SyncList(ImportListDefinition definition) { _logger.ProgressInfo("Starting Import List Refresh for List {0}", definition.Name); var listItemsResult = _listFetcherAndParser.FetchSingleList(definition); - ProcessListItems(listItemsResult); + await ProcessListItems(listItemsResult); } private void ProcessMovieReport(ImportListDefinition importList, ImportListMovie report, List listExclusions, List dbMovies, List moviesToAdd) @@ -123,7 +124,7 @@ namespace NzbDrone.Core.ImportLists } } - private void ProcessListItems(ImportListFetchResult listFetchResult) + private async Task ProcessListItems(ImportListFetchResult listFetchResult) { listFetchResult.Movies = listFetchResult.Movies.DistinctBy(x => { @@ -164,7 +165,7 @@ namespace NzbDrone.Core.ImportLists if (moviesToAdd.Any()) { _logger.ProgressInfo("Adding {0} movies from your auto enabled lists to library", moviesToAdd.Count); - _addMovieService.AddMovies(moviesToAdd, true); + await _addMovieService.AddMovies(moviesToAdd, true); } } @@ -172,11 +173,11 @@ namespace NzbDrone.Core.ImportLists { if (message.DefinitionId.HasValue) { - SyncList(_importListFactory.Get(message.DefinitionId.Value)); + SyncList(_importListFactory.Get(message.DefinitionId.Value)).GetAwaiter().GetResult(); } else { - SyncAll(); + SyncAll().GetAwaiter().GetResult(); } } diff --git a/src/NzbDrone.Core/MediaCover/CoverAlreadyExistsSpecification.cs b/src/NzbDrone.Core/MediaCover/CoverAlreadyExistsSpecification.cs index d6c303d88..33f6813e2 100644 --- a/src/NzbDrone.Core/MediaCover/CoverAlreadyExistsSpecification.cs +++ b/src/NzbDrone.Core/MediaCover/CoverAlreadyExistsSpecification.cs @@ -1,4 +1,5 @@ -using NLog; +using System.Threading.Tasks; +using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.Http; @@ -6,7 +7,7 @@ namespace NzbDrone.Core.MediaCover { public interface ICoverExistsSpecification { - bool AlreadyExists(string url, string path); + Task AlreadyExists(string url, string path); } public class CoverAlreadyExistsSpecification : ICoverExistsSpecification @@ -22,16 +23,17 @@ namespace NzbDrone.Core.MediaCover _logger = logger; } - public bool AlreadyExists(string url, string path) + public async Task AlreadyExists(string url, string path) { if (!_diskProvider.FileExists(path)) { return false; } - var headers = _httpClient.Head(new HttpRequest(url)).Headers; + var response = await _httpClient.HeadAsync(new HttpRequest(url)); var fileSize = _diskProvider.GetFileSize(path); - return fileSize == headers.ContentLength; + + return fileSize == response.Headers.ContentLength; } } } diff --git a/src/NzbDrone.Core/MediaCover/MediaCoverService.cs b/src/NzbDrone.Core/MediaCover/MediaCoverService.cs index c0b692ce3..aabfbdff2 100644 --- a/src/NzbDrone.Core/MediaCover/MediaCoverService.cs +++ b/src/NzbDrone.Core/MediaCover/MediaCoverService.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Net; using System.Threading; +using System.Threading.Tasks; using NLog; using NzbDrone.Common; using NzbDrone.Common.Disk; @@ -143,7 +144,7 @@ namespace NzbDrone.Core.MediaCover return Path.Combine(_coverRootFolder, movieId.ToString()); } - private bool EnsureCovers(Movie movie) + private async Task EnsureCovers(Movie movie) { var updated = false; var toResize = new List>(); @@ -160,11 +161,11 @@ namespace NzbDrone.Core.MediaCover try { - alreadyExists = _coverExistsSpecification.AlreadyExists(cover.RemoteUrl, fileName); + alreadyExists = await _coverExistsSpecification.AlreadyExists(cover.RemoteUrl, fileName); if (!alreadyExists) { - DownloadCover(movie, cover); + await DownloadCover(movie, cover); updated = true; } } @@ -186,7 +187,7 @@ namespace NzbDrone.Core.MediaCover try { - _semaphore.Wait(); + await _semaphore.WaitAsync(); foreach (var tuple in toResize) { @@ -201,12 +202,12 @@ namespace NzbDrone.Core.MediaCover return updated; } - private void DownloadCover(Movie movie, MediaCover cover) + private async Task DownloadCover(Movie movie, MediaCover cover) { var fileName = GetCoverPath(movie.Id, cover.CoverType); _logger.Info("Downloading {0} for {1} {2}", cover.CoverType, movie, cover.RemoteUrl); - _httpClient.DownloadFile(cover.RemoteUrl, fileName); + await _httpClient.DownloadFileAsync(cover.RemoteUrl, fileName); } private void EnsureResizedCovers(Movie movie, MediaCover cover, bool forceResize) @@ -265,7 +266,7 @@ namespace NzbDrone.Core.MediaCover public void HandleAsync(MovieUpdatedEvent message) { - var updated = EnsureCovers(message.Movie); + var updated = EnsureCovers(message.Movie).GetAwaiter().GetResult(); _eventAggregator.PublishEvent(new MediaCoversUpdatedEvent(message.Movie, updated)); } diff --git a/src/NzbDrone.Core/MetadataSource/IProvideMovieInfo.cs b/src/NzbDrone.Core/MetadataSource/IProvideMovieInfo.cs index b2323f7b6..93cef167d 100644 --- a/src/NzbDrone.Core/MetadataSource/IProvideMovieInfo.cs +++ b/src/NzbDrone.Core/MetadataSource/IProvideMovieInfo.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using NzbDrone.Core.Movies; using NzbDrone.Core.Movies.Collections; using NzbDrone.Core.Movies.Credits; @@ -8,8 +9,8 @@ namespace NzbDrone.Core.MetadataSource { public interface IProvideMovieInfo { - MovieMetadata GetMovieByImdbId(string imdbId); - Tuple> GetMovieInfo(int tmdbId); + Task GetMovieByImdbId(string imdbId); + Task>> GetMovieInfo(int tmdbId); MovieCollection GetCollectionInfo(int tmdbId); List GetBulkMovieInfo(List tmdbIds); diff --git a/src/NzbDrone.Core/MetadataSource/ISearchForNewMovie.cs b/src/NzbDrone.Core/MetadataSource/ISearchForNewMovie.cs index 2907fc117..0e9cbeb60 100644 --- a/src/NzbDrone.Core/MetadataSource/ISearchForNewMovie.cs +++ b/src/NzbDrone.Core/MetadataSource/ISearchForNewMovie.cs @@ -1,12 +1,13 @@ using System.Collections.Generic; +using System.Threading.Tasks; using NzbDrone.Core.Movies; namespace NzbDrone.Core.MetadataSource { public interface ISearchForNewMovie { - List SearchForNewMovie(string title); + Task> SearchForNewMovie(string title); - MovieMetadata MapMovieToTmdbMovie(MovieMetadata movie); + Task MapMovieToTmdbMovie(MovieMetadata movie); } } diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs index d27823c07..df6ea247f 100644 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs +++ b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Net; +using System.Threading.Tasks; using Newtonsoft.Json; using NLog; using NzbDrone.Common.Cloud; @@ -70,7 +71,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook return new HashSet(response.Resource); } - public Tuple> GetMovieInfo(int tmdbId) + public async Task>> GetMovieInfo(int tmdbId) { var httpRequest = _radarrMetadata.Create() .SetSegment("route", "movie") @@ -80,7 +81,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook httpRequest.AllowAutoRedirect = true; httpRequest.SuppressHttpError = true; - var httpResponse = _httpClient.Get(httpRequest); + var httpResponse = await _httpClient.GetAsync(httpRequest); if (httpResponse.HasHttpError) { @@ -158,7 +159,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook return movies; } - public MovieMetadata GetMovieByImdbId(string imdbId) + public async Task GetMovieByImdbId(string imdbId) { imdbId = Parser.Parser.NormalizeImdbId(imdbId); @@ -175,7 +176,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook httpRequest.AllowAutoRedirect = true; httpRequest.SuppressHttpError = true; - var httpResponse = _httpClient.Get>(httpRequest); + var httpResponse = await _httpClient.GetAsync>(httpRequest); if (httpResponse.HasHttpError) { @@ -310,7 +311,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook return title; } - public MovieMetadata MapMovieToTmdbMovie(MovieMetadata movie) + public async Task MapMovieToTmdbMovie(MovieMetadata movie) { try { @@ -325,7 +326,8 @@ namespace NzbDrone.Core.MetadataSource.SkyHook return newMovie; } - newMovie = GetMovieInfo(movie.TmdbId).Item1; + var movieInfo = await GetMovieInfo(movie.TmdbId); + newMovie = movieInfo.Item1; } else if (movie.ImdbId.IsNotNullOrWhiteSpace()) { @@ -336,7 +338,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook return newMovie; } - newMovie = GetMovieByImdbId(movie.ImdbId); + newMovie = await GetMovieByImdbId(movie.ImdbId); } else { @@ -346,7 +348,8 @@ namespace NzbDrone.Core.MetadataSource.SkyHook yearStr = $" {movie.Year}"; } - var newMovieObject = SearchForNewMovie(movie.Title + yearStr).FirstOrDefault(); + var searchedNewMovies = await SearchForNewMovie(movie.Title + yearStr); + var newMovieObject = searchedNewMovies.FirstOrDefault(); if (newMovieObject == null) { @@ -373,7 +376,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook } } - public List SearchForNewMovie(string title) + public async Task> SearchForNewMovie(string title) { try { @@ -400,7 +403,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook { try { - var movieLookup = GetMovieByImdbId(parserResult.ImdbId); + var movieLookup = await GetMovieByImdbId(parserResult.ImdbId); return movieLookup == null ? new List() : new List { _movieService.FindByTmdbId(movieLookup.TmdbId) ?? new Movie { MovieMetadata = movieLookup } }; } catch (Exception) @@ -413,7 +416,8 @@ namespace NzbDrone.Core.MetadataSource.SkyHook { try { - var movieLookup = GetMovieInfo(parserResult.TmdbId).Item1; + var movieInfo = await GetMovieInfo(parserResult.TmdbId); + var movieLookup = movieInfo.Item1; return movieLookup == null ? new List() : new List { _movieService.FindByTmdbId(movieLookup.TmdbId) ?? new Movie { MovieMetadata = movieLookup } }; } catch (Exception) @@ -438,7 +442,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook try { - var movieLookup = GetMovieByImdbId(imdbid); + var movieLookup = await GetMovieByImdbId(imdbid); return movieLookup == null ? new List() : new List { _movieService.FindByTmdbId(movieLookup.TmdbId) ?? new Movie { MovieMetadata = movieLookup } }; } catch (MovieNotFoundException) @@ -460,7 +464,8 @@ namespace NzbDrone.Core.MetadataSource.SkyHook try { - var movieLookup = GetMovieInfo(tmdbid).Item1; + var movieInfo = await GetMovieInfo(tmdbid); + var movieLookup = movieInfo.Item1; return movieLookup == null ? new List() : new List { _movieService.FindByTmdbId(movieLookup.TmdbId) ?? new Movie { MovieMetadata = movieLookup } }; } catch (MovieNotFoundException) @@ -482,7 +487,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook request.AllowAutoRedirect = true; request.SuppressHttpError = true; - var httpResponse = _httpClient.Get>(request); + var httpResponse = await _httpClient.GetAsync>(request); return httpResponse.Resource.SelectList(MapSearchResult); } diff --git a/src/NzbDrone.Core/Movies/AddMovieService.cs b/src/NzbDrone.Core/Movies/AddMovieService.cs index 798be5f96..7d1bcde9f 100644 --- a/src/NzbDrone.Core/Movies/AddMovieService.cs +++ b/src/NzbDrone.Core/Movies/AddMovieService.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading.Tasks; using FluentValidation; using FluentValidation.Results; using NLog; @@ -15,8 +16,8 @@ namespace NzbDrone.Core.Movies { public interface IAddMovieService { - Movie AddMovie(Movie newMovie); - List AddMovies(List newMovies, bool ignoreErrors = false); + Task AddMovie(Movie newMovie); + Task> AddMovies(List newMovies, bool ignoreErrors = false); } public class AddMovieService : IAddMovieService @@ -43,11 +44,11 @@ namespace NzbDrone.Core.Movies _logger = logger; } - public Movie AddMovie(Movie newMovie) + public async Task AddMovie(Movie newMovie) { Ensure.That(newMovie, () => newMovie).IsNotNull(); - newMovie = AddSkyhookData(newMovie); + newMovie = await AddSkyhookData(newMovie); newMovie = SetPropertiesAndValidate(newMovie); _logger.Info("Adding Movie {0} Path: [{1}]", newMovie, newMovie.Path); @@ -60,7 +61,7 @@ namespace NzbDrone.Core.Movies return newMovie; } - public List AddMovies(List newMovies, bool ignoreErrors = false) + public async Task> AddMovies(List newMovies, bool ignoreErrors = false) { var added = DateTime.UtcNow; var moviesToAdd = new List(); @@ -71,7 +72,7 @@ namespace NzbDrone.Core.Movies try { - var movie = AddSkyhookData(m); + var movie = await AddSkyhookData(m); movie = SetPropertiesAndValidate(movie); movie.Added = added; @@ -95,13 +96,14 @@ namespace NzbDrone.Core.Movies return _movieService.AddMovies(moviesToAdd); } - private Movie AddSkyhookData(Movie newMovie) + private async Task AddSkyhookData(Movie newMovie) { var movie = new Movie(); try { - movie.MovieMetadata = _movieInfo.GetMovieInfo(newMovie.TmdbId).Item1; + var movieInfo = await _movieInfo.GetMovieInfo(newMovie.TmdbId); + movie.MovieMetadata = movieInfo.Item1; } catch (MovieNotFoundException) { diff --git a/src/NzbDrone.Core/Movies/RefreshCollectionService.cs b/src/NzbDrone.Core/Movies/RefreshCollectionService.cs index 69e93e72d..104dc2157 100644 --- a/src/NzbDrone.Core/Movies/RefreshCollectionService.cs +++ b/src/NzbDrone.Core/Movies/RefreshCollectionService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using NLog; using NzbDrone.Common.Instrumentation.Extensions; using NzbDrone.Core.Exceptions; @@ -116,7 +117,7 @@ namespace NzbDrone.Core.Movies return false; } - private void SyncCollectionMovies(MovieCollection collection) + private async Task SyncCollectionMovies(MovieCollection collection) { if (collection.Monitored) { @@ -127,7 +128,7 @@ namespace NzbDrone.Core.Movies if (moviesToAdd.Any()) { - _addMovieService.AddMovies(moviesToAdd.Select(m => new Movie + await _addMovieService.AddMovies(moviesToAdd.Select(m => new Movie { TmdbId = m.TmdbId, Title = m.Title, @@ -153,7 +154,7 @@ namespace NzbDrone.Core.Movies foreach (var collectionId in message.CollectionIds) { var newCollection = RefreshCollectionInfo(collectionId); - SyncCollectionMovies(newCollection); + SyncCollectionMovies(newCollection).GetAwaiter().GetResult(); } } else @@ -171,7 +172,7 @@ namespace NzbDrone.Core.Movies newCollection = RefreshCollectionInfo(collection.Id); } - SyncCollectionMovies(newCollection); + SyncCollectionMovies(newCollection).GetAwaiter().GetResult(); } catch (MovieNotFoundException) { diff --git a/src/NzbDrone.Core/Movies/RefreshMovieService.cs b/src/NzbDrone.Core/Movies/RefreshMovieService.cs index 2416e1a83..55bc3cdb8 100644 --- a/src/NzbDrone.Core/Movies/RefreshMovieService.cs +++ b/src/NzbDrone.Core/Movies/RefreshMovieService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using NLog; using NzbDrone.Common.Instrumentation.Extensions; using NzbDrone.Core.AutoTagging; @@ -69,7 +70,7 @@ namespace NzbDrone.Core.Movies _logger = logger; } - private Movie RefreshMovieInfo(int movieId) + private async Task RefreshMovieInfo(int movieId) { // Get the movie before updating, that way any changes made to the movie after the refresh started, // but before this movie was refreshed won't be lost. @@ -83,7 +84,7 @@ namespace NzbDrone.Core.Movies try { - var tuple = _movieInfo.GetMovieInfo(movie.TmdbId); + var tuple = await _movieInfo.GetMovieInfo(movie.TmdbId); movieInfo = tuple.Item1; credits = tuple.Item2; } @@ -250,7 +251,7 @@ namespace NzbDrone.Core.Movies try { - movie = RefreshMovieInfo(movieId); + movie = RefreshMovieInfo(movieId).GetAwaiter().GetResult(); UpdateTags(movie); RescanMovie(movie, isNew, trigger); } @@ -286,7 +287,7 @@ namespace NzbDrone.Core.Movies { try { - movieLocal = RefreshMovieInfo(movieLocal.Id); + movieLocal = RefreshMovieInfo(movieLocal.Id).GetAwaiter().GetResult(); } catch (MovieNotFoundException) { diff --git a/src/Radarr.Api.V3/ImportLists/ImportListMoviesController.cs b/src/Radarr.Api.V3/ImportLists/ImportListMoviesController.cs index 42188bdf8..a7362fdc0 100644 --- a/src/Radarr.Api.V3/ImportLists/ImportListMoviesController.cs +++ b/src/Radarr.Api.V3/ImportLists/ImportListMoviesController.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using NzbDrone.Core.Configuration; using NzbDrone.Core.ImportLists; @@ -54,6 +55,7 @@ namespace Radarr.Api.V3.ImportLists } [HttpGet] + [Produces("application/json")] public object GetDiscoverMovies(bool includeRecommendations = false) { var movieLanguage = (Language)_configService.MovieInfoLanguage; @@ -100,11 +102,14 @@ namespace Radarr.Api.V3.ImportLists } [HttpPost] - public object AddMovies([FromBody] List resource) + [Consumes("application/json")] + [Produces("application/json")] + public async Task> AddMovies([FromBody] List resource) { var newMovies = resource.ToModel(); + var addedMovies = await _addMovieService.AddMovies(newMovies, true); - return _addMovieService.AddMovies(newMovies, true).ToResource(0); + return addedMovies.ToResource(0); } private IEnumerable MapToResource(IEnumerable movies, Language language) diff --git a/src/Radarr.Api.V3/Movies/MovieController.cs b/src/Radarr.Api.V3/Movies/MovieController.cs index 8fc92f549..9f26d9859 100644 --- a/src/Radarr.Api.V3/Movies/MovieController.cs +++ b/src/Radarr.Api.V3/Movies/MovieController.cs @@ -219,9 +219,9 @@ namespace Radarr.Api.V3.Movies } [RestPostById] - public ActionResult AddMovie(MovieResource moviesResource) + public async Task> AddMovie(MovieResource moviesResource) { - var movie = _addMovieService.AddMovie(moviesResource.ToModel()); + var movie = await _addMovieService.AddMovie(moviesResource.ToModel()); return Created(movie.Id); } diff --git a/src/Radarr.Api.V3/Movies/MovieImportController.cs b/src/Radarr.Api.V3/Movies/MovieImportController.cs index f49941bd8..0a3774341 100644 --- a/src/Radarr.Api.V3/Movies/MovieImportController.cs +++ b/src/Radarr.Api.V3/Movies/MovieImportController.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using NzbDrone.Core.Movies; using Radarr.Http; @@ -24,11 +25,14 @@ namespace Radarr.Api.V3.Movies } [HttpPost] - public object Import([FromBody] List resource) + [Consumes("application/json")] + [Produces("application/json")] + public async Task> Import([FromBody] List resource) { var newMovies = resource.ToModel(); + var addedMovies = await _addMovieService.AddMovies(newMovies); - return _addMovieService.AddMovies(newMovies).ToResource(0); + return addedMovies.ToResource(0); } } } diff --git a/src/Radarr.Api.V3/Movies/MovieLookupController.cs b/src/Radarr.Api.V3/Movies/MovieLookupController.cs index 8a8c82498..057dba51e 100644 --- a/src/Radarr.Api.V3/Movies/MovieLookupController.cs +++ b/src/Radarr.Api.V3/Movies/MovieLookupController.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using NzbDrone.Core.Configuration; using NzbDrone.Core.Languages; @@ -45,28 +46,34 @@ namespace Radarr.Api.V3.Movies } [HttpGet("tmdb")] - public object SearchByTmdbId(int tmdbId) + [Produces("application/json")] + public async Task SearchByTmdbId(int tmdbId) { var availDelay = _configService.AvailabilityDelay; - var result = new Movie { MovieMetadata = _movieInfo.GetMovieInfo(tmdbId).Item1 }; + var movieInfo = await _movieInfo.GetMovieInfo(tmdbId); + var result = new Movie { MovieMetadata = movieInfo.Item1 }; var translation = result.MovieMetadata.Value.Translations.FirstOrDefault(t => t.Language == (Language)_configService.MovieInfoLanguage); + return result.ToResource(availDelay, translation); } [HttpGet("imdb")] - public object SearchByImdbId(string imdbId) + [Produces("application/json")] + public async Task SearchByImdbId(string imdbId) { - var result = new Movie { MovieMetadata = _movieInfo.GetMovieByImdbId(imdbId) }; + var result = new Movie { MovieMetadata = await _movieInfo.GetMovieByImdbId(imdbId) }; var availDelay = _configService.AvailabilityDelay; var translation = result.MovieMetadata.Value.Translations.FirstOrDefault(t => t.Language == (Language)_configService.MovieInfoLanguage); + return result.ToResource(availDelay, translation); } [HttpGet] - public object Search([FromQuery] string term) + [Produces("application/json")] + public async Task> Search([FromQuery] string term) { - var searchResults = _searchProxy.SearchForNewMovie(term); + var searchResults = await _searchProxy.SearchForNewMovie(term); return MapToResource(searchResults); }