From 5169ffd6cea7905a6595211708088a939df79f00 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Sat, 12 Feb 2022 22:40:24 +0000 Subject: [PATCH] feat: almost got it all working now --- .../Models/V2/MovieResponse.cs | 7 ++- .../Rule/Search/EmbyAvailabilityRuleTests.cs | 44 +++++++++++++++- .../Search/JellyfinAvailabilityRuleTests.cs | 46 ++++++++++++++++- .../Rule/Search/RadarrCacheRuleTests.cs | 50 +++++++++++++++++-- .../Rule/Rules/Search/EmbyAvailabilityRule.cs | 24 +++++++-- .../Rule/Rules/Search/ExistingRule.cs | 3 +- .../Rules/Search/JellyfinAvailabilityRule.cs | 22 +++++++- .../Rule/Rules/Search/PlexAvailabilityRule.cs | 24 +++++++-- .../Rule/Rules/Search/RadarrCacheRule.cs | 13 +++-- .../Jobs/Plex/PlexAvailabilityChecker.cs | 2 + src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs | 2 +- .../movie/movie-details.component.html | 8 +-- .../movie-information-panel.component.html | 5 ++ .../ClientApp/src/app/pipes/QualityPipe.ts | 3 ++ .../shared/role-directive/role-directive.ts | 2 +- 15 files changed, 227 insertions(+), 28 deletions(-) diff --git a/src/Ombi.Api.Radarr/Models/V2/MovieResponse.cs b/src/Ombi.Api.Radarr/Models/V2/MovieResponse.cs index 6eb2f1c5a..15627d414 100644 --- a/src/Ombi.Api.Radarr/Models/V2/MovieResponse.cs +++ b/src/Ombi.Api.Radarr/Models/V2/MovieResponse.cs @@ -44,7 +44,10 @@ namespace Ombi.Api.Radarr.Models public int id { get; set; } } - + public class MovieQuality + { + public V3.Quality quality { get; set; } + } public class Moviefile { public int movieId { get; set; } @@ -54,7 +57,7 @@ namespace Ombi.Api.Radarr.Models public DateTime dateAdded { get; set; } public string sceneName { get; set; } public int indexerFlags { get; set; } - public V3.Quality quality { get; set; } + public MovieQuality quality { get; set; } public Mediainfo mediaInfo { get; set; } public string originalFilePath { get; set; } public bool qualityCutoffNotMet { get; set; } diff --git a/src/Ombi.Core.Tests/Rule/Search/EmbyAvailabilityRuleTests.cs b/src/Ombi.Core.Tests/Rule/Search/EmbyAvailabilityRuleTests.cs index 966dfe4e3..95be538cd 100644 --- a/src/Ombi.Core.Tests/Rule/Search/EmbyAvailabilityRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Search/EmbyAvailabilityRuleTests.cs @@ -35,7 +35,8 @@ namespace Ombi.Core.Tests.Rule.Search SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new EmbySettings()); ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny())).ReturnsAsync(new EmbyContent { - TheMovieDbId = "123" + TheMovieDbId = "123", + Quality = "1" }); var search = new SearchMovieViewModel() { @@ -47,6 +48,47 @@ namespace Ombi.Core.Tests.Rule.Search Assert.True(search.Available); } + [Test] + public async Task Movie_ShouldBe_Available_WhenFoundInEmby_4K() + { + SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new EmbySettings()); + ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny())).ReturnsAsync(new EmbyContent + { + TheMovieDbId = "123", + Has4K = true + }); + var search = new SearchMovieViewModel() + { + TheMovieDbId = "123", + }; + var result = await Rule.Execute(search); + + Assert.True(result.Success); + Assert.True(search.Available4K); + Assert.False(search.Available); + } + + [Test] + public async Task Movie_ShouldBe_Available_WhenFoundInEmby_Both() + { + SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new EmbySettings()); + ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny())).ReturnsAsync(new EmbyContent + { + TheMovieDbId = "123", + Has4K = true, + Quality = "1" + }); + var search = new SearchMovieViewModel() + { + TheMovieDbId = "123", + }; + var result = await Rule.Execute(search); + + Assert.True(result.Success); + Assert.True(search.Available4K); + Assert.True(search.Available); + } + [Test] public async Task Movie_ShouldBe_NotAvailable_WhenNotFoundInEmby() { diff --git a/src/Ombi.Core.Tests/Rule/Search/JellyfinAvailabilityRuleTests.cs b/src/Ombi.Core.Tests/Rule/Search/JellyfinAvailabilityRuleTests.cs index b733b0b2b..c0034afb7 100644 --- a/src/Ombi.Core.Tests/Rule/Search/JellyfinAvailabilityRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Search/JellyfinAvailabilityRuleTests.cs @@ -35,7 +35,8 @@ namespace Ombi.Core.Tests.Rule.Search SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new JellyfinSettings()); ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny())).ReturnsAsync(new JellyfinContent { - ProviderId = "123" + TheMovieDbId = "123", + Quality = "1080" }); var search = new SearchMovieViewModel() { @@ -47,6 +48,47 @@ namespace Ombi.Core.Tests.Rule.Search Assert.True(search.Available); } + [Test] + public async Task Movie_ShouldBe_Available_WhenFoundInJellyfin_4K() + { + SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new JellyfinSettings()); + ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny())).ReturnsAsync(new JellyfinContent + { + TheMovieDbId = "123", + Has4K = true + }); + var search = new SearchMovieViewModel() + { + TheMovieDbId = "123", + }; + var result = await Rule.Execute(search); + + Assert.True(result.Success); + Assert.False(search.Available); + Assert.True(search.Available4K); + } + + [Test] + public async Task Movie_ShouldBe_Available_WhenFoundInJellyfin_Both() + { + SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new JellyfinSettings()); + ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny())).ReturnsAsync(new JellyfinContent + { + TheMovieDbId = "123", + Has4K = true, + Quality = "1" + }); + var search = new SearchMovieViewModel() + { + TheMovieDbId = "123", + }; + var result = await Rule.Execute(search); + + Assert.True(result.Success); + Assert.True(search.Available); + Assert.True(search.Available4K); + } + [Test] public async Task Movie_Uses_Default_Url_When() { @@ -66,7 +108,7 @@ namespace Ombi.Core.Tests.Rule.Search }); ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny())).ReturnsAsync(new JellyfinContent { - ProviderId = "123", + TheMovieDbId = "123", JellyfinId = 1.ToString() }); var search = new SearchMovieViewModel() diff --git a/src/Ombi.Core.Tests/Rule/Search/RadarrCacheRuleTests.cs b/src/Ombi.Core.Tests/Rule/Search/RadarrCacheRuleTests.cs index 94efe89a2..8c5e0c662 100644 --- a/src/Ombi.Core.Tests/Rule/Search/RadarrCacheRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Search/RadarrCacheRuleTests.cs @@ -28,25 +28,67 @@ namespace Ombi.Core.Tests.Rule.Search { var list = new List(){new RadarrCache { - TheMovieDbId = 123 + TheMovieDbId = 123, + HasRegular = true }}.AsQueryable(); - + ContextMock.Setup(x => x.GetAll()).Returns(list); var request = new SearchMovieViewModel { Id = 123 }; - var result =await Rule.Execute(request); + var result = await Rule.Execute(request); Assert.True(result.Success); Assert.True(request.Approved); } + [Test] + public async Task Should_ReturnAvailabl_WhenMovieIsInRadarr_4K() + { + var list = new List(){new RadarrCache + { + TheMovieDbId = 123, + Has4K = true, + HasFile = true + }}.AsQueryable(); + + ContextMock.Setup(x => x.GetAll()).Returns(list); + + var request = new SearchMovieViewModel { Id = 123 }; + var result = await Rule.Execute(request); + + Assert.True(result.Success); + Assert.False(request.Available); + Assert.True(request.Available4K); + } + + [Test] + public async Task Should_ReturnAvailable_WhenMovieIsInRadarr_Both() + { + var list = new List(){new RadarrCache + { + TheMovieDbId = 123, + Has4K = true, + HasRegular = true, + HasFile = true + }}.AsQueryable(); + + ContextMock.Setup(x => x.GetAll()).Returns(list); + + var request = new SearchMovieViewModel { Id = 123 }; + var result = await Rule.Execute(request); + + Assert.True(result.Success); + Assert.True(request.Available); + Assert.True(request.Available4K); + + } [Test] public async Task Should_ReturnNotApproved_WhenMovieIsNotInRadarr() { var list = DbHelper.GetQueryableMockDbSet(new RadarrCache { - TheMovieDbId = 000012 + TheMovieDbId = 000012, }); ContextMock.Setup(x => x.GetAll()).Returns(list); diff --git a/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs b/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs index e7a629854..4bc42ad04 100644 --- a/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs @@ -63,11 +63,29 @@ namespace Ombi.Core.Rule.Rules.Search } } } - + if (item != null) { - obj.Available = true; - obj.EmbyUrl = item.Url; + if (obj is SearchMovieViewModel movie) + { + if (item.Has4K) + { + movie.Available4K = true; + obj.EmbyUrl = item.Url; + } + + if (item.Quality.HasValue()) + { + obj.Available = true; + obj.EmbyUrl = item.Url; + obj.Quality = item.Quality; + } + } + else + { + obj.Available = true; + obj.EmbyUrl = item.Url; + } if (obj.Type == RequestType.TvShow) { diff --git a/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs b/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs index 27461d20e..a9bf13265 100644 --- a/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs @@ -26,9 +26,8 @@ namespace Ombi.Core.Rule.Rules.Search public async Task Execute(SearchViewModel obj) { - if (obj.Type == RequestType.Movie) + if (obj is SearchMovieViewModel movie) { - var movie = (SearchMovieViewModel)obj; var movieRequests = await Movie.GetRequestAsync(obj.Id); if (movieRequests != null) // Do we already have a request for this? { diff --git a/src/Ombi.Core/Rule/Rules/Search/JellyfinAvailabilityRule.cs b/src/Ombi.Core/Rule/Rules/Search/JellyfinAvailabilityRule.cs index 95a2da80b..f8c69c0f0 100644 --- a/src/Ombi.Core/Rule/Rules/Search/JellyfinAvailabilityRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/JellyfinAvailabilityRule.cs @@ -80,8 +80,26 @@ namespace Ombi.Core.Rule.Rules.Search obj.TheMovieDbId = obj.Id.ToString(); useTheMovieDb = true; } - obj.Available = true; - obj.JellyfinUrl = item.Url; + if (obj is SearchMovieViewModel movie) + { + if (item.Has4K) + { + movie.Available4K = true; + obj.JellyfinUrl = item.Url; + } + + if (item.Quality.HasValue()) + { + obj.Available = true; + obj.EmbyUrl = item.Url; + obj.Quality = item.Quality; + } + } + else + { + obj.Available = true; + obj.JellyfinUrl = item.Url; + } if (obj.Type == RequestType.TvShow) { diff --git a/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs b/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs index 4c05e0fe1..1742f9f20 100644 --- a/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs @@ -89,7 +89,25 @@ namespace Ombi.Core.Rule.Rules.Search obj.TheMovieDbId = obj.Id.ToString(); useTheMovieDb = true; } - obj.Available = true; + + if (obj is SearchMovieViewModel movie) + { + if (item.Has4K) + { + movie.Available4K = true; + } + + if (item.Quality.HasValue()) + { + obj.Available = true; + obj.Quality = item.Quality; + } + } + else + { + obj.Available = true; + } + if (item.Url.StartsWith("http")) { obj.PlexUrl = item.Url; @@ -99,11 +117,9 @@ namespace Ombi.Core.Rule.Rules.Search // legacy content obj.PlexUrl = PlexHelper.BuildPlexMediaUrl(item.Url, host); } - obj.Quality = item.Quality; - if (obj.Type == RequestType.TvShow) + if (obj is SearchTvShowViewModel search) { - var search = (SearchTvShowViewModel)obj; // Let's go through the episodes now if (search.SeasonRequests.Any()) { diff --git a/src/Ombi.Core/Rule/Rules/Search/RadarrCacheRule.cs b/src/Ombi.Core/Rule/Rules/Search/RadarrCacheRule.cs index 105681c82..63546f8c8 100644 --- a/src/Ombi.Core/Rule/Rules/Search/RadarrCacheRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/RadarrCacheRule.cs @@ -18,16 +18,23 @@ namespace Ombi.Core.Rule.Rules.Search public Task Execute(SearchViewModel obj) { - if (obj.Type == RequestType.Movie) + if (obj is SearchMovieViewModel movie) { // Check if it's in Radarr var result = _db.GetAll().FirstOrDefault(x => x.TheMovieDbId == obj.Id); if (result != null) { - obj.Approved = true; // It's in radarr so it's approved... Maybe have a new property called "Processing" or something? + movie.Approved = true; // It's in radarr so it's approved... Maybe have a new property called "Processing" or something? if (result.HasFile) { - obj.Available = true; + if (result.Has4K) + { + movie.Available4K = true; + } + if (result.HasRegular) + { + movie.Available = true; + } } } } diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs b/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs index 90940ccb5..a6e1b205b 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs @@ -209,6 +209,7 @@ namespace Ombi.Schedule.Jobs.Plex if (has4kRequest && item.Has4K) { movie.Available4K = true; + movie.Approved4K = true; movie.MarkedAsAvailable4K = DateTime.Now; } @@ -216,6 +217,7 @@ namespace Ombi.Schedule.Jobs.Plex if (item.Quality.HasValue()) { movie.Available = true; + movie.Approved = true; movie.MarkedAsAvailable = DateTime.Now; } diff --git a/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs b/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs index 3f9816dbe..eb97edeff 100644 --- a/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs +++ b/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs @@ -77,7 +77,7 @@ namespace Ombi.Schedule.Jobs.Radarr { if (m.tmdbId > 0) { - var is4k = m.movieFile?.quality?.resolution >= 2160; + var is4k = m.movieFile?.quality?.quality?.resolution >= 2160; // Do we have a cached movie for this already? var existing = await existingMovies.FirstOrDefaultAsync(x => x.TheMovieDbId == m.tmdbId); diff --git a/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.html b/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.html index 2eed39df9..bb59a771a 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.html +++ b/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.html @@ -79,12 +79,14 @@ - + + - diff --git a/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.html b/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.html index 1fa528159..019e24214 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.html +++ b/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.html @@ -64,6 +64,11 @@
{{movie.quality | quality}}
+
+ {{'MediaDetails.Quality' | translate }}  + {{"4K" | quality}} +
+
{{'MediaDetails.RootFolderOverride' | translate }}
{{request.rootPathOverrideTitle}}
diff --git a/src/Ombi/ClientApp/src/app/pipes/QualityPipe.ts b/src/Ombi/ClientApp/src/app/pipes/QualityPipe.ts index 393e08640..c1f9a4211 100644 --- a/src/Ombi/ClientApp/src/app/pipes/QualityPipe.ts +++ b/src/Ombi/ClientApp/src/app/pipes/QualityPipe.ts @@ -6,6 +6,9 @@ export class QualityPipe implements PipeTransform { if (value.toUpperCase() === "4K" || value.toUpperCase() === "8K") { return value; } + if (value[value.length - 1].toUpperCase() === "P") { + return value; + } return value + "p"; } } \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/shared/role-directive/role-directive.ts b/src/Ombi/ClientApp/src/app/shared/role-directive/role-directive.ts index 906041726..3fa4cad56 100644 --- a/src/Ombi/ClientApp/src/app/shared/role-directive/role-directive.ts +++ b/src/Ombi/ClientApp/src/app/shared/role-directive/role-directive.ts @@ -23,7 +23,7 @@ export class RoleDirective implements OnInit { } private updateView(): void { - if (this.auth.hasRole(this.roleName)) { + if (this.auth.hasRole(this.roleName) || this.auth.hasRole("admin")) { if (this.isHidden) { this.viewContainer.createEmbeddedView(this.templateRef); this.isHidden = false;