From 3cc45b3022a72cb9def54cf7e21819516c171aea Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Fri, 25 Aug 2017 14:06:47 +0100 Subject: [PATCH] Improvements to the UI and also finished the availability checker #865 #1464 --- src/Ombi.Core.Tests/Ombi.Core.Tests.csproj | 6 +- .../Rule/Request/AutoApproveRuleTests.cs | 24 ++-- .../Rule/Search/ExistingRequestRuleTests.cs | 16 +-- src/Ombi.Core/Engine/MovieSearchEngine.cs | 8 ++ .../Models/Search/SearchViewModel.cs | 15 ++- .../Rule/Rules/Search/ExistingRule.cs | 12 +- .../Rule/Rules/Search/PlexAvailabilityRule.cs | 3 +- .../Rule/Rules/Search/RadarrCacheRule.cs | 7 +- src/Ombi.DependencyInjection/IocExtensions.cs | 23 ++-- .../Ombi.Schedule.Tests.csproj | 21 ++++ .../PlexAvailabilityCheckerTests.cs | 110 ++++++++++++++++++ .../Properties/launchSettings.json | 27 +++++ .../Jobs/Plex/PlexAvailabilityChecker.cs | 2 +- .../Jobs/Plex/PlexContentCacher.cs | 3 +- .../Jobs/Plex/PlexEpisodeCacher.cs | 15 ++- src/Ombi.Store/Entities/PlexContent.cs | 1 + ...r.cs => 20170825114646_Inital.Designer.cs} | 4 +- ...349_Inital.cs => 20170825114646_Inital.cs} | 1 + .../Migrations/OmbiContextModelSnapshot.cs | 2 + .../Requests/IMovieRequestRepository.cs | 3 +- .../Requests/ITvRequestRepository.cs | 3 +- .../Requests/MovieRequestRepository.cs | 25 +++- .../Requests/TvRequestRepository.cs | 16 ++- src/Ombi.sln | 13 ++- .../app/interfaces/ISearchMovieResult.ts | 3 +- .../app/requests/tvrequests.component.html | 10 +- .../app/requests/tvrequests.component.ts | 1 + .../app/search/moviesearch.component.html | 15 +-- .../app/search/search.component.html | 33 +----- .../app/search/tvsearch.component.html | 21 ++-- 30 files changed, 317 insertions(+), 126 deletions(-) create mode 100644 src/Ombi.Schedule.Tests/Ombi.Schedule.Tests.csproj create mode 100644 src/Ombi.Schedule.Tests/PlexAvailabilityCheckerTests.cs create mode 100644 src/Ombi.Schedule.Tests/Properties/launchSettings.json rename src/Ombi.Store/Migrations/{20170824133349_Inital.Designer.cs => 20170825114646_Inital.Designer.cs} (99%) rename src/Ombi.Store/Migrations/{20170824133349_Inital.cs => 20170825114646_Inital.cs} (99%) diff --git a/src/Ombi.Core.Tests/Ombi.Core.Tests.csproj b/src/Ombi.Core.Tests/Ombi.Core.Tests.csproj index 204b0d1b0..20321dae1 100644 --- a/src/Ombi.Core.Tests/Ombi.Core.Tests.csproj +++ b/src/Ombi.Core.Tests/Ombi.Core.Tests.csproj @@ -5,10 +5,10 @@ - - - + + + diff --git a/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs b/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs index 558a7c850..50bf6f0c3 100644 --- a/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs @@ -26,8 +26,8 @@ namespace Ombi.Core.Tests.Rule.Request var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie }; var result = await Rule.Execute(request); - Assert.Equal(result.Success, true); - Assert.Equal(request.Approved, true); + Assert.True(result.Success); + Assert.True(request.Approved); } [Fact] @@ -37,8 +37,8 @@ namespace Ombi.Core.Tests.Rule.Request var request = new BaseRequest() { RequestType = Store.Entities.RequestType.TvShow }; var result = await Rule.Execute(request); - Assert.Equal(result.Success, true); - Assert.Equal(request.Approved, true); + Assert.True(result.Success); + Assert.True(request.Approved); } [Fact] @@ -48,8 +48,8 @@ namespace Ombi.Core.Tests.Rule.Request var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie }; var result = await Rule.Execute(request); - Assert.Equal(result.Success, true); - Assert.Equal(request.Approved, true); + Assert.True(result.Success); + Assert.True(request.Approved); } [Fact] @@ -59,8 +59,8 @@ namespace Ombi.Core.Tests.Rule.Request var request = new BaseRequest() { RequestType = Store.Entities.RequestType.TvShow }; var result = await Rule.Execute(request); - Assert.Equal(result.Success, true); - Assert.Equal(request.Approved, true); + Assert.True(result.Success); + Assert.True(request.Approved); } [Fact] @@ -69,8 +69,8 @@ namespace Ombi.Core.Tests.Rule.Request var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie }; var result = await Rule.Execute(request); - Assert.Equal(result.Success, true); - Assert.Equal(request.Approved, false); + Assert.True(result.Success); + Assert.False(request.Approved); } [Fact] @@ -79,8 +79,8 @@ namespace Ombi.Core.Tests.Rule.Request var request = new BaseRequest() { RequestType = Store.Entities.RequestType.TvShow }; var result = await Rule.Execute(request); - Assert.Equal(result.Success, true); - Assert.Equal(request.Approved, false); + Assert.True(result.Success); + Assert.False(request.Approved); } } } diff --git a/src/Ombi.Core.Tests/Rule/Search/ExistingRequestRuleTests.cs b/src/Ombi.Core.Tests/Rule/Search/ExistingRequestRuleTests.cs index 2516325a5..ab28afa1a 100644 --- a/src/Ombi.Core.Tests/Rule/Search/ExistingRequestRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Search/ExistingRequestRuleTests.cs @@ -33,7 +33,7 @@ namespace Ombi.Core.Tests.Rule.Search Approved = true }; - MovieMock.Setup(x => x.GetRequest(123)).ReturnsAsync(list); + MovieMock.Setup(x => x.GetRequest(123)).Returns(list); var search = new SearchMovieViewModel { Id = 123, @@ -42,7 +42,7 @@ namespace Ombi.Core.Tests.Rule.Search var result = await Rule.Execute(search); Assert.True(result.Success); - Assert.Equal(search.Approved, true); + Assert.False(search.Approved); } [Fact] @@ -54,7 +54,7 @@ namespace Ombi.Core.Tests.Rule.Search Approved = true }; - MovieMock.Setup(x => x.GetRequest(123)).ReturnsAsync(list); + MovieMock.Setup(x => x.GetRequest(123)).Returns(list); var search = new SearchMovieViewModel { Id = 999, @@ -63,7 +63,7 @@ namespace Ombi.Core.Tests.Rule.Search var result = await Rule.Execute(search); Assert.True(result.Success); - Assert.Equal(search.Approved, false); + Assert.False(search.Approved); } [Fact] @@ -82,7 +82,7 @@ namespace Ombi.Core.Tests.Rule.Search } }; - TvMock.Setup(x => x.GetRequest(123)).ReturnsAsync(list); + TvMock.Setup(x => x.GetRequest(123)).Returns(list); var search = new SearchTvShowViewModel { Id = 123, @@ -91,7 +91,7 @@ namespace Ombi.Core.Tests.Rule.Search var result = await Rule.Execute(search); Assert.True(result.Success); - Assert.Equal(search.Approved, true); + Assert.True(search.Approved); } [Fact] @@ -111,7 +111,7 @@ namespace Ombi.Core.Tests.Rule.Search }; - TvMock.Setup(x => x.GetRequest(123)).ReturnsAsync(list); + TvMock.Setup(x => x.GetRequest(123)).Returns(list); var search = new SearchTvShowViewModel() { Id = 999, @@ -120,7 +120,7 @@ namespace Ombi.Core.Tests.Rule.Search var result = await Rule.Execute(search); Assert.True(result.Success); - Assert.Equal(search.Approved, false); + Assert.False(search.Approved); } diff --git a/src/Ombi.Core/Engine/MovieSearchEngine.cs b/src/Ombi.Core/Engine/MovieSearchEngine.cs index 90622cbd6..f4d5230fd 100644 --- a/src/Ombi.Core/Engine/MovieSearchEngine.cs +++ b/src/Ombi.Core/Engine/MovieSearchEngine.cs @@ -148,10 +148,18 @@ namespace Ombi.Core.Engine { var showInfo = await MovieApi.GetMovieInformation(viewMovie.Id); viewMovie.Id = showInfo.Id; // TheMovieDbId + viewMovie.ImdbId = showInfo.ImdbId; } + // So when we run the rule to check if it's available in Plex we need the ImdbId + // But we only pass down the SearchViewModel that doesn't contain this + // So set the ImdbId to viewMovie.Id and then set it back afterwards + var oldId = viewMovie.Id; + viewMovie.CustomId = viewMovie.ImdbId ?? string.Empty; + await RunSearchRules(viewMovie); + viewMovie.Id = oldId; return viewMovie; } diff --git a/src/Ombi.Core/Models/Search/SearchViewModel.cs b/src/Ombi.Core/Models/Search/SearchViewModel.cs index 7890707f1..85ff4786e 100644 --- a/src/Ombi.Core/Models/Search/SearchViewModel.cs +++ b/src/Ombi.Core/Models/Search/SearchViewModel.cs @@ -1,4 +1,6 @@ -namespace Ombi.Core.Models.Search +using System.ComponentModel.DataAnnotations.Schema; + +namespace Ombi.Core.Models.Search { public class SearchViewModel { @@ -7,5 +9,16 @@ public bool Requested { get; set; } public bool Available { get; set; } public string PlexUrl { get; set; } + public string Quality { get; set; } + + + /// + /// This is used for the PlexAvailabilityCheck rule + /// + /// + /// The custom identifier. + /// + [NotMapped] + public string CustomId { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs b/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs index abbafd8f9..b84f9c652 100644 --- a/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs @@ -19,9 +19,9 @@ namespace Ombi.Core.Rule.Rules.Search private IMovieRequestRepository Movie { get; } private ITvRequestRepository Tv { get; } - public async Task Execute(SearchViewModel obj) + public Task Execute(SearchViewModel obj) { - var movieRequests = await Movie.GetRequest(obj.Id); + var movieRequests = Movie.GetRequest(obj.Id); if (movieRequests != null) // Do we already have a request for this? { @@ -29,10 +29,10 @@ namespace Ombi.Core.Rule.Rules.Search obj.Approved = movieRequests.Approved; obj.Available = movieRequests.Available; - return Success(); + return Task.FromResult(Success()); } - var tvRequests = await Tv.GetRequest(obj.Id); + var tvRequests = Tv.GetRequest(obj.Id); if (tvRequests != null) // Do we already have a request for this? { @@ -40,9 +40,9 @@ namespace Ombi.Core.Rule.Rules.Search obj.Approved = tvRequests.ChildRequests.Any(x => x.Approved); obj.Available = tvRequests.ChildRequests.Any(x => x.Available); - return Success(); + return Task.FromResult(Success()); } - return Success(); + return Task.FromResult(Success()); } } } \ No newline at end of file diff --git a/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs b/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs index 9c2a0bbb1..c293e00be 100644 --- a/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs @@ -16,11 +16,12 @@ namespace Ombi.Core.Rule.Rules.Search public async Task Execute(SearchViewModel obj) { - var item = await PlexContentRepository.Get(obj.Id.ToString()); + var item = await PlexContentRepository.Get(obj.CustomId); if (item != null) { obj.Available = true; obj.PlexUrl = item.Url; + obj.Quality = item.Quality; } return Success(); } diff --git a/src/Ombi.Core/Rule/Rules/Search/RadarrCacheRule.cs b/src/Ombi.Core/Rule/Rules/Search/RadarrCacheRule.cs index 033d279a9..b2187e206 100644 --- a/src/Ombi.Core/Rule/Rules/Search/RadarrCacheRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/RadarrCacheRule.cs @@ -1,5 +1,6 @@ using System.Linq; using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; using Ombi.Core.Models.Search; using Ombi.Core.Rule.Interfaces; using Ombi.Store.Context; @@ -15,16 +16,16 @@ namespace Ombi.Core.Rule.Rules.Search private readonly IOmbiContext _ctx; - public Task Execute(SearchViewModel obj) + public async Task Execute(SearchViewModel obj) { // Check if it's in Radarr - var result = _ctx.RadarrCache.FirstOrDefault(x => x.TheMovieDbId == obj.Id); + var result = await _ctx.RadarrCache.FirstOrDefaultAsync(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? } - return Task.FromResult(Success()); + return Success(); } } } \ No newline at end of file diff --git a/src/Ombi.DependencyInjection/IocExtensions.cs b/src/Ombi.DependencyInjection/IocExtensions.cs index de488fbd2..495afd347 100644 --- a/src/Ombi.DependencyInjection/IocExtensions.cs +++ b/src/Ombi.DependencyInjection/IocExtensions.cs @@ -1,6 +1,7 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; +using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; using Ombi.Api.Discord; @@ -89,18 +90,18 @@ namespace Ombi.DependencyInjection { services.AddEntityFrameworkSqlite().AddDbContext(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); + services.AddScoped(); // https://docs.microsoft.com/en-us/aspnet/core/data/entity-framework-6 + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(typeof(ISettingsService<>), typeof(SettingsService<>)); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(typeof(ISettingsService<>), typeof(SettingsService<>)); } public static void RegisterServices(this IServiceCollection services) { diff --git a/src/Ombi.Schedule.Tests/Ombi.Schedule.Tests.csproj b/src/Ombi.Schedule.Tests/Ombi.Schedule.Tests.csproj new file mode 100644 index 000000000..dd9930445 --- /dev/null +++ b/src/Ombi.Schedule.Tests/Ombi.Schedule.Tests.csproj @@ -0,0 +1,21 @@ + + + + netcoreapp1.1 + + + + + + + + + + + + + + + + + diff --git a/src/Ombi.Schedule.Tests/PlexAvailabilityCheckerTests.cs b/src/Ombi.Schedule.Tests/PlexAvailabilityCheckerTests.cs new file mode 100644 index 000000000..6cb2863a4 --- /dev/null +++ b/src/Ombi.Schedule.Tests/PlexAvailabilityCheckerTests.cs @@ -0,0 +1,110 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Castle.Components.DictionaryAdapter; +using Moq; +using NUnit.Framework; +using Ombi.Schedule.Jobs.Plex; +using Ombi.Store.Entities; +using Ombi.Store.Entities.Requests; +using Ombi.Store.Repository; +using Ombi.Store.Repository.Requests; + +namespace Ombi.Schedule.Tests +{ + [TestFixture] + public class PlexAvailabilityCheckerTests + { + public PlexAvailabilityCheckerTests() + { + _repo = new Mock(); + _tv = new Mock(); + _movie = new Mock(); + Checker = new PlexAvailabilityChecker(_repo.Object, _tv.Object, _movie.Object); + } + + private readonly Mock _repo; + private readonly Mock _tv; + private readonly Mock _movie; + private PlexAvailabilityChecker Checker { get; } + + [Test] + public async Task ProcessMovies_ShouldMarkAvailable_WhenInPlex() + { + var request = new MovieRequests + { + ImdbId = "test" + }; + _movie.Setup(x => x.Get()).Returns(new List { request }.AsQueryable()); + _repo.Setup(x => x.Get("test")).ReturnsAsync(new PlexContent()); + + await Checker.Start(); + + _movie.Verify(x => x.Save(), Times.Once); + + Assert.True(request.Available); + } + + [Test] + public async Task ProcessMovies_ShouldNotBeAvailable_WhenInNotPlex() + { + var request = new MovieRequests + { + ImdbId = "test" + }; + _movie.Setup(x => x.Get()).Returns(new List { request }.AsQueryable()); + + await Checker.Start(); + + _movie.Verify(x => x.Save(), Times.Once); + Assert.False(request.Available); + } + + [Test] + [Ignore("EF IAsyncQueryProvider")] + public async Task ProcessTv_ShouldMark_Episode_Available_WhenInPlex() + { + var request = new ChildRequests + { + ParentRequest = new TvRequests {TvDbId = 1}, + SeasonRequests = new EditableList + { + new SeasonRequests + { + Episodes = new EditableList + { + new EpisodeRequests + { + EpisodeNumber = 1, + Season = new SeasonRequests + { + SeasonNumber = 2 + } + } + } + } + } + }; + _tv.Setup(x => x.GetChild()).Returns(new List { request }.AsQueryable()); + _repo.Setup(x => x.GetAllEpisodes()).Returns(new List + { + new PlexEpisode + { + Series = new PlexContent + { + ProviderId = 1.ToString(), + }, + EpisodeNumber = 1, + SeasonNumber = 2 + } + }.AsQueryable); + + await Checker.Start(); + + _tv.Verify(x => x.Save(), Times.Once); + + Assert.True(request.SeasonRequests[0].Episodes[0].Available); + + } + } +} \ No newline at end of file diff --git a/src/Ombi.Schedule.Tests/Properties/launchSettings.json b/src/Ombi.Schedule.Tests/Properties/launchSettings.json new file mode 100644 index 000000000..57de33708 --- /dev/null +++ b/src/Ombi.Schedule.Tests/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:62604/", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Ombi.Schedule.Tests": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:62605/" + } + } +} diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs b/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs index 19ddeb0e1..fb6082eab 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs @@ -27,7 +27,7 @@ namespace Ombi.Schedule.Jobs.Plex private async Task ProcessTv() { - var tv = _tvRepo.GetChild(); + var tv = _tvRepo.GetChild().Where(x => !x.Available); var plexEpisodes = _repo.GetAllEpisodes().Include(x => x.Series); foreach (var child in tv) diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexContentCacher.cs b/src/Ombi.Schedule/Jobs/Plex/PlexContentCacher.cs index dfa8302b5..22b3fe529 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexContentCacher.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexContentCacher.cs @@ -187,7 +187,8 @@ namespace Ombi.Schedule.Jobs.Plex Type = PlexMediaTypeEntity.Movie, Title = movie.title, Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, movie.ratingKey), - Seasons = new List() + Seasons = new List(), + Quality = movie.Media?.FirstOrDefault()?.videoResolution ?? string.Empty }; contentToAdd.Add(item); diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeCacher.cs b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeCacher.cs index c4d24e065..0d777f428 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeCacher.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeCacher.cs @@ -102,24 +102,24 @@ namespace Ombi.Schedule.Jobs.Plex var currentPosition = 0; var ResultCount = 50; var episodes = await _api.GetAllEpisodes(settings.PlexAuthToken, settings.FullUri, section.key, currentPosition, ResultCount); - + var currentData = _repo.GetAllEpisodes(); _log.LogInformation(LoggingEvents.PlexEpisodeCacher, $"Total Epsiodes found for {episodes.MediaContainer.librarySectionTitle} = {episodes.MediaContainer.totalSize}"); - await ProcessEpsiodes(episodes); + await ProcessEpsiodes(episodes, currentData); currentPosition += ResultCount; while (currentPosition < episodes.MediaContainer.totalSize) { var ep = await _api.GetAllEpisodes(settings.PlexAuthToken, settings.FullUri, section.key, currentPosition, ResultCount); - await ProcessEpsiodes(ep); + await ProcessEpsiodes(ep, currentData); _log.LogInformation(LoggingEvents.PlexEpisodeCacher, $"Processed {ResultCount} more episodes. Total Remaining {currentPosition - episodes.MediaContainer.totalSize}"); currentPosition += ResultCount; } } - private async Task ProcessEpsiodes(PlexContainer episodes) + private async Task ProcessEpsiodes(PlexContainer episodes, IQueryable currentEpisodes) { var ep = new HashSet(); foreach (var episode in episodes.MediaContainer.Metadata) @@ -128,6 +128,13 @@ namespace Ombi.Schedule.Jobs.Plex // We have the parent and grandparent rating keys to link up to the season and series //var metadata = _api.GetEpisodeMetaData(server.PlexAuthToken, server.FullUri, episode.ratingKey); + var epExists = currentEpisodes.Any(x => episode.ratingKey == x.Key && + episode.grandparentRatingKey == x.GrandparentKey); + if (epExists) + { + continue; + } + ep.Add(new PlexEpisode { EpisodeNumber = episode.index, diff --git a/src/Ombi.Store/Entities/PlexContent.cs b/src/Ombi.Store/Entities/PlexContent.cs index e07d2e179..0e8295cbc 100644 --- a/src/Ombi.Store/Entities/PlexContent.cs +++ b/src/Ombi.Store/Entities/PlexContent.cs @@ -53,6 +53,7 @@ namespace Ombi.Store.Entities /// public int Key { get; set; } public DateTime AddedAt { get; set; } + public string Quality { get; set; } } [Table("PlexSeasonsContent")] diff --git a/src/Ombi.Store/Migrations/20170824133349_Inital.Designer.cs b/src/Ombi.Store/Migrations/20170825114646_Inital.Designer.cs similarity index 99% rename from src/Ombi.Store/Migrations/20170824133349_Inital.Designer.cs rename to src/Ombi.Store/Migrations/20170825114646_Inital.Designer.cs index 6c555ca10..4f5573b00 100644 --- a/src/Ombi.Store/Migrations/20170824133349_Inital.Designer.cs +++ b/src/Ombi.Store/Migrations/20170825114646_Inital.Designer.cs @@ -10,7 +10,7 @@ using Ombi.Helpers; namespace Ombi.Store.Migrations { [DbContext(typeof(OmbiContext))] - [Migration("20170824133349_Inital")] + [Migration("20170825114646_Inital")] partial class Inital { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -258,6 +258,8 @@ namespace Ombi.Store.Migrations b.Property("ProviderId"); + b.Property("Quality"); + b.Property("ReleaseYear"); b.Property("Title"); diff --git a/src/Ombi.Store/Migrations/20170824133349_Inital.cs b/src/Ombi.Store/Migrations/20170825114646_Inital.cs similarity index 99% rename from src/Ombi.Store/Migrations/20170824133349_Inital.cs rename to src/Ombi.Store/Migrations/20170825114646_Inital.cs index 3e321b694..3229f6fbf 100644 --- a/src/Ombi.Store/Migrations/20170824133349_Inital.cs +++ b/src/Ombi.Store/Migrations/20170825114646_Inital.cs @@ -134,6 +134,7 @@ namespace Ombi.Store.Migrations AddedAt = table.Column(nullable: false), Key = table.Column(nullable: false), ProviderId = table.Column(nullable: true), + Quality = table.Column(nullable: true), ReleaseYear = table.Column(nullable: true), Title = table.Column(nullable: true), Type = table.Column(nullable: false), diff --git a/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs b/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs index 4270f62a0..585745fea 100644 --- a/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs +++ b/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs @@ -257,6 +257,8 @@ namespace Ombi.Store.Migrations b.Property("ProviderId"); + b.Property("Quality"); + b.Property("ReleaseYear"); b.Property("Title"); diff --git a/src/Ombi.Store/Repository/Requests/IMovieRequestRepository.cs b/src/Ombi.Store/Repository/Requests/IMovieRequestRepository.cs index 3d5f0c078..f4e46e272 100644 --- a/src/Ombi.Store/Repository/Requests/IMovieRequestRepository.cs +++ b/src/Ombi.Store/Repository/Requests/IMovieRequestRepository.cs @@ -9,7 +9,8 @@ namespace Ombi.Store.Repository Task Add(MovieRequests request); Task Delete(MovieRequests request); IQueryable Get(); - Task GetRequest(int theMovieDbId); + Task GetRequestAsync(int theMovieDbId); + MovieRequests GetRequest(int theMovieDbId); Task Update(MovieRequests request); Task Save(); } diff --git a/src/Ombi.Store/Repository/Requests/ITvRequestRepository.cs b/src/Ombi.Store/Repository/Requests/ITvRequestRepository.cs index 5a294653a..906f30e44 100644 --- a/src/Ombi.Store/Repository/Requests/ITvRequestRepository.cs +++ b/src/Ombi.Store/Repository/Requests/ITvRequestRepository.cs @@ -11,7 +11,8 @@ namespace Ombi.Store.Repository.Requests Task Delete(TvRequests request); Task DeleteChild(ChildRequests request); IQueryable Get(); - Task GetRequest(int tvDbId); + Task GetRequestAsync(int tvDbId); + TvRequests GetRequest(int tvDbId); Task Update(TvRequests request); Task UpdateChild(ChildRequests request); IQueryable GetChild(); diff --git a/src/Ombi.Store/Repository/Requests/MovieRequestRepository.cs b/src/Ombi.Store/Repository/Requests/MovieRequestRepository.cs index 2f3ab507b..4a280d366 100644 --- a/src/Ombi.Store/Repository/Requests/MovieRequestRepository.cs +++ b/src/Ombi.Store/Repository/Requests/MovieRequestRepository.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; @@ -16,11 +17,27 @@ namespace Ombi.Store.Repository.Requests private IOmbiContext Db { get; } - public async Task GetRequest(int theMovieDbId) + public async Task GetRequestAsync(int theMovieDbId) { - return await Db.MovieRequests.Where(x => x.TheMovieDbId == theMovieDbId) + try + { + return await Db.MovieRequests.Where(x => x.TheMovieDbId == theMovieDbId) + .Include(x => x.RequestedUser) + .FirstOrDefaultAsync(); + } + catch (Exception e) + { + Console.WriteLine(e); + throw; + } + + } + + public MovieRequests GetRequest(int theMovieDbId) + { + return Db.MovieRequests.Where(x => x.TheMovieDbId == theMovieDbId) .Include(x => x.RequestedUser) - .FirstOrDefaultAsync(); + .FirstOrDefault(); } public IQueryable Get() diff --git a/src/Ombi.Store/Repository/Requests/TvRequestRepository.cs b/src/Ombi.Store/Repository/Requests/TvRequestRepository.cs index 09424d20d..8ad975db3 100644 --- a/src/Ombi.Store/Repository/Requests/TvRequestRepository.cs +++ b/src/Ombi.Store/Repository/Requests/TvRequestRepository.cs @@ -15,17 +15,28 @@ namespace Ombi.Store.Repository.Requests private IOmbiContext Db { get; } - public async Task GetRequest(int tvDbId) + public async Task GetRequestAsync(int tvDbId) { return await Db.TvRequests.Where(x => x.TvDbId == tvDbId) .Include(x => x.ChildRequests) - .ThenInclude(x => x.RequestedUser) + .ThenInclude(x => x.RequestedUser) .Include(x => x.ChildRequests) .ThenInclude(x => x.SeasonRequests) .ThenInclude(x => x.Episodes) .FirstOrDefaultAsync(); } + public TvRequests GetRequest(int tvDbId) + { + return Db.TvRequests.Where(x => x.TvDbId == tvDbId) + .Include(x => x.ChildRequests) + .ThenInclude(x => x.RequestedUser) + .Include(x => x.ChildRequests) + .ThenInclude(x => x.SeasonRequests) + .ThenInclude(x => x.Episodes) + .FirstOrDefault(); + } + public IQueryable Get() { return Db.TvRequests @@ -40,6 +51,7 @@ namespace Ombi.Store.Repository.Requests { return Db.ChildRequests .Include(x => x.RequestedUser) + .Include(x => x.ParentRequest) .Include(x => x.SeasonRequests) .ThenInclude(x => x.Episodes) .AsQueryable(); diff --git a/src/Ombi.sln b/src/Ombi.sln index deb6992ea..1a77eafe9 100644 --- a/src/Ombi.sln +++ b/src/Ombi.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26730.8 +VisualStudioVersion = 15.0.26730.3 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi", "Ombi\Ombi.csproj", "{C987AA67-AFE1-468F-ACD3-EAD5A48E1F6A}" EndProject @@ -76,9 +76,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Pushbullet", "Ombi EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Slack", "Ombi.Api.Slack\Ombi.Api.Slack.csproj", "{71708256-9152-4E81-9FCA-E3181A185806}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Mattermost", "Ombi.Api.Mattermost\Ombi.Api.Mattermost.csproj", "{737B2620-FE5A-4135-A017-79C269A7D36C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Mattermost", "Ombi.Api.Mattermost\Ombi.Api.Mattermost.csproj", "{737B2620-FE5A-4135-A017-79C269A7D36C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Pushover", "Ombi.Api.Pushover\Ombi.Api.Pushover.csproj", "{CA55DD4F-4EFF-4906-A848-35FCC7BD5654}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Pushover", "Ombi.Api.Pushover\Ombi.Api.Pushover.csproj", "{CA55DD4F-4EFF-4906-A848-35FCC7BD5654}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Schedule.Tests", "Ombi.Schedule.Tests\Ombi.Schedule.Tests.csproj", "{BDD8B924-016E-4CDA-9FFA-50B0A34BCD3C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -198,6 +200,10 @@ Global {CA55DD4F-4EFF-4906-A848-35FCC7BD5654}.Debug|Any CPU.Build.0 = Debug|Any CPU {CA55DD4F-4EFF-4906-A848-35FCC7BD5654}.Release|Any CPU.ActiveCfg = Release|Any CPU {CA55DD4F-4EFF-4906-A848-35FCC7BD5654}.Release|Any CPU.Build.0 = Release|Any CPU + {BDD8B924-016E-4CDA-9FFA-50B0A34BCD3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BDD8B924-016E-4CDA-9FFA-50B0A34BCD3C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BDD8B924-016E-4CDA-9FFA-50B0A34BCD3C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BDD8B924-016E-4CDA-9FFA-50B0A34BCD3C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -225,6 +231,7 @@ Global {71708256-9152-4E81-9FCA-E3181A185806} = {9293CA11-360A-4C20-A674-B9E794431BF5} {737B2620-FE5A-4135-A017-79C269A7D36C} = {9293CA11-360A-4C20-A674-B9E794431BF5} {CA55DD4F-4EFF-4906-A848-35FCC7BD5654} = {9293CA11-360A-4C20-A674-B9E794431BF5} + {BDD8B924-016E-4CDA-9FFA-50B0A34BCD3C} = {6F42AB98-9196-44C4-B888-D5E409F415A1} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {192E9BF8-00B4-45E4-BCCC-4C215725C869} diff --git a/src/Ombi/ClientApp/app/interfaces/ISearchMovieResult.ts b/src/Ombi/ClientApp/app/interfaces/ISearchMovieResult.ts index 99af3b533..e4488fd4b 100644 --- a/src/Ombi/ClientApp/app/interfaces/ISearchMovieResult.ts +++ b/src/Ombi/ClientApp/app/interfaces/ISearchMovieResult.ts @@ -20,5 +20,6 @@ approved: boolean, requested: boolean, available: boolean, - plexUrl: string + plexUrl: string, + quality:string } \ No newline at end of file diff --git a/src/Ombi/ClientApp/app/requests/tvrequests.component.html b/src/Ombi/ClientApp/app/requests/tvrequests.component.html index 1965fcc97..d49a48198 100644 --- a/src/Ombi/ClientApp/app/requests/tvrequests.component.html +++ b/src/Ombi/ClientApp/app/requests/tvrequests.component.html @@ -43,15 +43,7 @@ {{node.data.status}} -
- Request status: - Available - Processing Request - Request Denied - - Pending Approval - -
+
Release Date: {{node.data.releaseDate | date}}

diff --git a/src/Ombi/ClientApp/app/requests/tvrequests.component.ts b/src/Ombi/ClientApp/app/requests/tvrequests.component.ts index d6094ddb2..a5459cdff 100644 --- a/src/Ombi/ClientApp/app/requests/tvrequests.component.ts +++ b/src/Ombi/ClientApp/app/requests/tvrequests.component.ts @@ -214,6 +214,7 @@ export class TvRequestsComponent implements OnInit, OnDestroy { this.requestService.getTvRequests(this.amountToLoad, 0) .takeUntil(this.subscriptions) .subscribe(x => { + debugger; this.tvRequests = this.transformData(x); }); this.isAdmin = this.identityService.hasRole("Admin"); diff --git a/src/Ombi/ClientApp/app/search/moviesearch.component.html b/src/Ombi/ClientApp/app/search/moviesearch.component.html index b09b1eb25..e9106d264 100644 --- a/src/Ombi/ClientApp/app/search/moviesearch.component.html +++ b/src/Ombi/ClientApp/app/search/moviesearch.component.html @@ -46,7 +46,11 @@ Release Date: {{result.releaseDate | date: 'dd/MM/yyyy'}} + HomePage + + Trailer Available + {{result.quality}}p Processing Request
@@ -58,11 +62,7 @@ - - HomePage - - Trailer
@@ -132,11 +132,12 @@
diff --git a/src/Ombi/ClientApp/app/search/search.component.html b/src/Ombi/ClientApp/app/search/search.component.html index 705ff17ee..e82457259 100644 --- a/src/Ombi/ClientApp/app/search/search.component.html +++ b/src/Ombi/ClientApp/app/search/search.component.html @@ -9,21 +9,10 @@ - - - +
  • TV Shows -
  • - - @@ -33,28 +22,8 @@ - - -
    -
    diff --git a/src/Ombi/ClientApp/app/search/tvsearch.component.html b/src/Ombi/ClientApp/app/search/tvsearch.component.html index eeb45f419..b5c727764 100644 --- a/src/Ombi/ClientApp/app/search/tvsearch.component.html +++ b/src/Ombi/ClientApp/app/search/tvsearch.component.html @@ -44,7 +44,7 @@