From 68c43684907fff72cc53d6b79cdb0a5308fdb754 Mon Sep 17 00:00:00 2001 From: TidusJar Date: Thu, 20 Sep 2018 14:31:48 +0100 Subject: [PATCH] Started on custom quality profiles and root paths !wip --- src/Ombi.Core/Models/UI/UserViewModel.cs | 2 + src/Ombi.Core/Senders/TvSender.cs | 33 +++- src/Ombi.Store/Context/OmbiContext.cs | 3 +- .../Entities/UserQualityProfiles.cs | 23 +++ src/Ombi/ClientApp/app/interfaces/IUser.ts | 10 ++ .../usermanagement-user.component.html | 142 +++++++++++++----- .../usermanagement-user.component.ts | 8 + src/Ombi/Controllers/IdentityController.cs | 60 +++++++- 8 files changed, 232 insertions(+), 49 deletions(-) create mode 100644 src/Ombi.Store/Entities/UserQualityProfiles.cs diff --git a/src/Ombi.Core/Models/UI/UserViewModel.cs b/src/Ombi.Core/Models/UI/UserViewModel.cs index 15045bc0a..8d01c066b 100644 --- a/src/Ombi.Core/Models/UI/UserViewModel.cs +++ b/src/Ombi.Core/Models/UI/UserViewModel.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Ombi.Store.Entities; namespace Ombi.Core.Models.UI { @@ -19,6 +20,7 @@ namespace Ombi.Core.Models.UI public RequestQuotaCountModel EpisodeRequestQuota { get; set; } public RequestQuotaCountModel MovieRequestQuota { get; set; } public int MusicRequestLimit { get; set; } + public UserQualityProfiles UserQualityProfiles { get; set; } } public class ClaimCheckboxes diff --git a/src/Ombi.Core/Senders/TvSender.cs b/src/Ombi.Core/Senders/TvSender.cs index 47d965acc..202edbfa5 100644 --- a/src/Ombi.Core/Senders/TvSender.cs +++ b/src/Ombi.Core/Senders/TvSender.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Ombi.Api.DogNzb; using Ombi.Api.DogNzb.Models; @@ -12,7 +13,9 @@ using Ombi.Api.Sonarr.Models; using Ombi.Core.Settings; using Ombi.Helpers; using Ombi.Settings.Settings.Models.External; +using Ombi.Store.Entities; using Ombi.Store.Entities.Requests; +using Ombi.Store.Repository; namespace Ombi.Core.Senders { @@ -20,7 +23,7 @@ namespace Ombi.Core.Senders { public TvSender(ISonarrApi sonarrApi, ILogger log, ISettingsService sonarrSettings, ISettingsService dog, IDogNzbApi dogApi, ISettingsService srSettings, - ISickRageApi srApi) + ISickRageApi srApi, IRepository userProfiles) { SonarrApi = sonarrApi; Logger = log; @@ -29,6 +32,7 @@ namespace Ombi.Core.Senders DogNzbApi = dogApi; SickRageSettings = srSettings; SickRageApi = srApi; + UserQualityProfiles = userProfiles; } private ISonarrApi SonarrApi { get; } @@ -38,6 +42,7 @@ namespace Ombi.Core.Senders private ISettingsService SonarrSettings { get; } private ISettingsService DogNzbSettings { get; } private ISettingsService SickRageSettings { get; } + private IRepository UserQualityProfiles { get; } public async Task Send(ChildRequests model) { @@ -122,13 +127,25 @@ namespace Ombi.Core.Senders string rootFolderPath; string seriesType; + var profiles = await UserQualityProfiles.GetAll().FirstOrDefaultAsync(x => x.UserId == model.RequestedUserId); + if (model.SeriesType == SeriesType.Anime) { // Get the root path from the rootfolder selected. // For some reason, if we haven't got one use the first root folder in Sonarr - // TODO make this overrideable via the UI rootFolderPath = await GetSonarrRootPath(model.ParentRequest.RootFolder ?? int.Parse(s.RootPathAnime), s); int.TryParse(s.QualityProfileAnime, out qualityToUse); + if (profiles != null) + { + if (profiles.SonarrRootPathAnime > 0) + { + rootFolderPath = await GetSonarrRootPath(profiles.SonarrRootPathAnime, s); + } + if (profiles.SonarrQualityProfileAnime > 0) + { + qualityToUse = profiles.SonarrQualityProfileAnime; + } + } seriesType = "anime"; } @@ -137,8 +154,18 @@ namespace Ombi.Core.Senders int.TryParse(s.QualityProfile, out qualityToUse); // Get the root path from the rootfolder selected. // For some reason, if we haven't got one use the first root folder in Sonarr - // TODO make this overrideable via the UI rootFolderPath = await GetSonarrRootPath(model.ParentRequest.RootFolder ?? int.Parse(s.RootPath), s); + if (profiles != null) + { + if (profiles.SonarrRootPath > 0) + { + rootFolderPath = await GetSonarrRootPath(profiles.SonarrRootPath, s); + } + if (profiles.SonarrQualityProfile > 0) + { + qualityToUse = profiles.SonarrQualityProfile; + } + } seriesType = "standard"; } diff --git a/src/Ombi.Store/Context/OmbiContext.cs b/src/Ombi.Store/Context/OmbiContext.cs index 2fdbaa996..f34b4c57c 100644 --- a/src/Ombi.Store/Context/OmbiContext.cs +++ b/src/Ombi.Store/Context/OmbiContext.cs @@ -51,7 +51,8 @@ namespace Ombi.Store.Context public DbSet SickRageCache { get; set; } public DbSet SickRageEpisodeCache { get; set; } public DbSet RequestSubscription { get; set; } - + public DbSet UserNotificationPreferences { get; set; } + public DbSet UserQualityProfileses { get; set; } public DbSet ApplicationConfigurations { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) diff --git a/src/Ombi.Store/Entities/UserQualityProfiles.cs b/src/Ombi.Store/Entities/UserQualityProfiles.cs new file mode 100644 index 000000000..d944c81b2 --- /dev/null +++ b/src/Ombi.Store/Entities/UserQualityProfiles.cs @@ -0,0 +1,23 @@ +using System.ComponentModel.DataAnnotations.Schema; +using Newtonsoft.Json; +using Ombi.Helpers; + +namespace Ombi.Store.Entities +{ + [Table(nameof(UserQualityProfiles))] + public class UserQualityProfiles : Entity + { + public string UserId { get; set; } + + public int SonarrQualityProfileAnime { get; set; } + public int SonarrRootPathAnime { get; set; } + public int SonarrRootPath { get; set; } + public int SonarrQualityProfile { get; set; } + public int RadarrRootPath { get; set; } + public int RadarrQualityProfile { get; set; } + + [ForeignKey(nameof(UserId))] + [JsonIgnore] + public OmbiUser User { get; set; } + } +} diff --git a/src/Ombi/ClientApp/app/interfaces/IUser.ts b/src/Ombi/ClientApp/app/interfaces/IUser.ts index ff1e7f944..9819ca834 100644 --- a/src/Ombi/ClientApp/app/interfaces/IUser.ts +++ b/src/Ombi/ClientApp/app/interfaces/IUser.ts @@ -15,6 +15,7 @@ export interface IUser { episodeRequestLimit: number; musicRequestLimit: number; userAccessToken: string; + userQualityProfiles: IUserQualityProfiles; // FOR UI episodeRequestQuota: IRemainingRequests | null; @@ -22,6 +23,15 @@ export interface IUser { checked: boolean; } +export interface IUserQualityProfiles { + sonarrQualityProfileAnime: string; + sonarrRootPathAnime: string; + sonarrRootPath: string; + sonarrQualityProfile: string; + radarrRootPath: string; + radarrQualityProfile: string; +} + export interface ICreateWizardUser { username: string; password: string; diff --git a/src/Ombi/ClientApp/app/usermanagement/usermanagement-user.component.html b/src/Ombi/ClientApp/app/usermanagement/usermanagement-user.component.html index f7bf702a0..bdb277d7e 100644 --- a/src/Ombi/ClientApp/app/usermanagement/usermanagement-user.component.html +++ b/src/Ombi/ClientApp/app/usermanagement/usermanagement-user.component.html @@ -89,55 +89,115 @@ - -
-
- + +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+ + + +
+
+
- +
- +
- -
- -
- -
-
-
- -
- -
-
- - - - - -
-
-
-
- -
- -
-
-
+
+ + + + + +
+
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+
- - - +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+
+ +
+
diff --git a/src/Ombi/ClientApp/app/usermanagement/usermanagement-user.component.ts b/src/Ombi/ClientApp/app/usermanagement/usermanagement-user.component.ts index fab37dd59..fda9df8ea 100644 --- a/src/Ombi/ClientApp/app/usermanagement/usermanagement-user.component.ts +++ b/src/Ombi/ClientApp/app/usermanagement/usermanagement-user.component.ts @@ -63,6 +63,14 @@ export class UserManagementUserComponent implements OnInit { musicRequestLimit: 0, episodeRequestQuota: null, movieRequestQuota: null, + userQualityProfiles: { + radarrQualityProfile: "", + radarrRootPath: "", + sonarrQualityProfile: "", + sonarrQualityProfileAnime: "", + sonarrRootPath: "", + sonarrRootPathAnime: "", + }, }; } } diff --git a/src/Ombi/Controllers/IdentityController.cs b/src/Ombi/Controllers/IdentityController.cs index db06c81c7..37290b45f 100644 --- a/src/Ombi/Controllers/IdentityController.cs +++ b/src/Ombi/Controllers/IdentityController.cs @@ -63,6 +63,7 @@ namespace Ombi.Controllers IRepository subscriptionRepository, ISettingsService umSettings, IRepository notificationPreferences, + IRepository userProfiles, IMusicRequestRepository musicRepo, IMovieRequestEngine movieRequestEngine, ITvRequestEngine tvRequestEngine) @@ -90,6 +91,7 @@ namespace Ombi.Controllers TvRequestEngine = tvRequestEngine; MovieRequestEngine = movieRequestEngine; _userNotificationPreferences = notificationPreferences; + _userQualityProfiles = userProfiles; } private OmbiUserManager UserManager { get; } @@ -115,6 +117,7 @@ namespace Ombi.Controllers private readonly IRepository _notificationRepository; private readonly IRepository _requestSubscriptionRepository; private readonly IRepository _userNotificationPreferences; + private readonly IRepository _userQualityProfiles; /// /// This is what the Wizard will call when creating the user for the very first time. @@ -329,16 +332,26 @@ namespace Ombi.Controllers }); } - if (vm.EpisodeRequestLimit > 0) + if (vm.EpisodeRequestLimit > 0) { vm.EpisodeRequestQuota = await TvRequestEngine.GetRemainingRequests(user); } - if (vm.MovieRequestLimit > 0) + if (vm.MovieRequestLimit > 0) { vm.MovieRequestQuota = await MovieRequestEngine.GetRemainingRequests(user); } + // Get the quality profiles + vm.UserQualityProfiles = await _userQualityProfiles.GetAll().FirstOrDefaultAsync(x => x.UserId == user.Id); + if (vm.UserQualityProfiles == null) + { + vm.UserQualityProfiles = new UserQualityProfiles + { + UserId = user.Id + }; + } + return vm; } @@ -397,6 +410,20 @@ namespace Ombi.Controllers }; } + // Add the quality profiles + if (user.UserQualityProfiles != null) + { + user.UserQualityProfiles.UserId = ombiUser.Id; + await _userQualityProfiles.Add(user.UserQualityProfiles); + } + else + { + user.UserQualityProfiles = new UserQualityProfiles + { + UserId = ombiUser.Id + }; + } + return new OmbiIdentityResult { Successful = true @@ -552,8 +579,24 @@ namespace Ombi.Controllers { Errors = messages }; + } + // Add the quality profiles + if (ui.UserQualityProfiles != null) + { + var currentQualityProfiles = await + _userQualityProfiles.GetAll().FirstOrDefaultAsync(x => x.UserId == user.Id); + + currentQualityProfiles.RadarrQualityProfile = ui.UserQualityProfiles.RadarrQualityProfile; + currentQualityProfiles.RadarrRootPath = ui.UserQualityProfiles.RadarrRootPath; + currentQualityProfiles.SonarrQualityProfile = ui.UserQualityProfiles.SonarrQualityProfile; + currentQualityProfiles.SonarrQualityProfileAnime = ui.UserQualityProfiles.SonarrQualityProfileAnime; + currentQualityProfiles.SonarrRootPath = ui.UserQualityProfiles.SonarrRootPath; + currentQualityProfiles.SonarrRootPathAnime = ui.UserQualityProfiles.SonarrRootPathAnime; + + await _userQualityProfiles.SaveChangesAsync(); } + return new OmbiIdentityResult { Successful = true @@ -585,6 +628,8 @@ namespace Ombi.Controllers var moviesUserRequested = MovieRepo.GetAll().Where(x => x.RequestedUserId == userId); var tvUserRequested = TvRepo.GetChild().Where(x => x.RequestedUserId == userId); var musicRequested = MusicRepo.GetAll().Where(x => x.RequestedUserId == userId); + var notificationPreferences = _userNotificationPreferences.GetAll().Where(x => x.UserId == userId); + var userQuality = await _userQualityProfiles.GetAll().FirstOrDefaultAsync(x => x.UserId == userId); if (moviesUserRequested.Any()) { @@ -594,11 +639,18 @@ namespace Ombi.Controllers { await TvRepo.DeleteChildRange(tvUserRequested); } - if (musicRequested.Any()) { await MusicRepo.DeleteRange(musicRequested); } + if (notificationPreferences.Any()) + { + await _userNotificationPreferences.DeleteRange(notificationPreferences); + } + if (userQuality != null) + { + await _userQualityProfiles.Delete(userQuality); + } // Delete any issues and request logs var issues = _issuesRepository.GetAll().Where(x => x.UserReportedId == userId); @@ -903,7 +955,7 @@ namespace Ombi.Controllers } return Json(true); } - + private async Task> AddRoles(IEnumerable roles, OmbiUser ombiUser) { var roleResult = new List();