diff --git a/Ombi.Api.Interfaces/ISonarrApi.cs b/Ombi.Api.Interfaces/ISonarrApi.cs index 881f469eb..bce750901 100644 --- a/Ombi.Api.Interfaces/ISonarrApi.cs +++ b/Ombi.Api.Interfaces/ISonarrApi.cs @@ -36,12 +36,11 @@ namespace Ombi.Api.Interfaces List GetProfiles(string apiKey, Uri baseUrl); SonarrAddSeries AddSeries(int tvdbId, string title, int qualityId, bool seasonFolders, string rootPath, - int rootFolderId, int seasonCount, int[] seasons, string apiKey, Uri baseUrl, bool monitor = true, bool searchForMissingEpisodes = false); SonarrAddSeries AddSeriesNew(int tvdbId, string title, int qualityId, bool seasonFolders, string rootPath, - int rootFolderId, int[] seasons, string apiKey, Uri baseUrl, bool monitor = true, + int[] seasons, string apiKey, Uri baseUrl, bool monitor = true, bool searchForMissingEpisodes = false); SystemStatus SystemStatus(string apiKey, Uri baseUrl); diff --git a/Ombi.Api/SonarrApi.cs b/Ombi.Api/SonarrApi.cs index c4c448628..2485150b8 100644 --- a/Ombi.Api/SonarrApi.cs +++ b/Ombi.Api/SonarrApi.cs @@ -78,7 +78,7 @@ namespace Ombi.Api return obj; } - public SonarrAddSeries AddSeries(int tvdbId, string title, int qualityId, bool seasonFolders, string rootPath, int rootFolderId, int seasonCount, int[] seasons, string apiKey, Uri baseUrl, bool monitor = true, bool searchForMissingEpisodes = false) + public SonarrAddSeries AddSeries(int tvdbId, string title, int qualityId, bool seasonFolders, string rootPath, int seasonCount, int[] seasons, string apiKey, Uri baseUrl, bool monitor = true, bool searchForMissingEpisodes = false) { Log.Debug("Adding series {0}", title); Log.Debug("Seasons = {0}, out of {1} seasons", seasons.DumpJson(), seasonCount); @@ -148,7 +148,7 @@ namespace Ombi.Api return result; } - public SonarrAddSeries AddSeriesNew(int tvdbId, string title, int qualityId, bool seasonFolders, string rootPath, int rootFolderId, int[] seasons, string apiKey, Uri baseUrl, bool monitor = true, bool searchForMissingEpisodes = false) + public SonarrAddSeries AddSeriesNew(int tvdbId, string title, int qualityId, bool seasonFolders, string rootPath, int[] seasons, string apiKey, Uri baseUrl, bool monitor = true, bool searchForMissingEpisodes = false) { var request = new RestRequest { diff --git a/Ombi.Core/SettingModels/SonarrSettings.cs b/Ombi.Core/SettingModels/SonarrSettings.cs index ee309e376..ec2edb49a 100644 --- a/Ombi.Core/SettingModels/SonarrSettings.cs +++ b/Ombi.Core/SettingModels/SonarrSettings.cs @@ -33,7 +33,5 @@ namespace Ombi.Core.SettingModels public string QualityProfile { get; set; } public bool SeasonFolders { get; set; } public string RootPath { get; set; } - public string RootFolder { get; set; } - } } \ No newline at end of file diff --git a/Ombi.Core/TvSender.cs b/Ombi.Core/TvSender.cs index 34be1bb76..14146c17f 100644 --- a/Ombi.Core/TvSender.cs +++ b/Ombi.Core/TvSender.cs @@ -34,24 +34,27 @@ using Ombi.Api.Interfaces; using Ombi.Api.Models.SickRage; using Ombi.Api.Models.Sonarr; using Ombi.Core.SettingModels; +using Ombi.Helpers; using Ombi.Store; namespace Ombi.Core { public class TvSender { - public TvSender(ISonarrApi sonarrApi, ISickRageApi srApi) + public TvSender(ISonarrApi sonarrApi, ISickRageApi srApi, ICacheProvider cache) { SonarrApi = sonarrApi; SickrageApi = srApi; + Cache = cache; } private ISonarrApi SonarrApi { get; } private ISickRageApi SickrageApi { get; } + private ICacheProvider Cache { get; } private static Logger Log = LogManager.GetCurrentClassLogger(); public async Task SendToSonarr(SonarrSettings sonarrSettings, RequestedModel model) { - return await SendToSonarr(sonarrSettings, model, string.Empty, string.Empty); + return await SendToSonarr(sonarrSettings, model, string.Empty); } /// @@ -61,7 +64,7 @@ namespace Ombi.Core /// /// /// - public async Task SendToSonarr(SonarrSettings sonarrSettings, RequestedModel model, string qualityId, string rootFolderId) + public async Task SendToSonarr(SonarrSettings sonarrSettings, RequestedModel model, string qualityId) { var qualityProfile = 0; var episodeRequest = model.Episodes.Any(); @@ -82,16 +85,7 @@ namespace Ombi.Core var latest = model.SeasonsRequested?.Equals("Latest", StringComparison.CurrentCultureIgnoreCase); var specificSeasonRequest = model.SeasonList?.Any(); - var rootFolder = 0; - if (!string.IsNullOrEmpty(rootFolderId)) - { - int.TryParse(qualityId, out rootFolder); - } - - if (rootFolder <= 0) - { - int.TryParse(sonarrSettings.RootFolder, out rootFolder); - } + var rootFolderPath = model.RootFolderSelected <= 0 ? sonarrSettings.RootPath : await GetRootPath(model.RootFolderSelected, sonarrSettings); if (episodeRequest) { @@ -107,7 +101,7 @@ namespace Ombi.Core // Series doesn't exist, need to add it as unmonitored. var addResult = await Task.Run(() => SonarrApi.AddSeries(model.ProviderId, model.Title, qualityProfile, - sonarrSettings.SeasonFolders, sonarrSettings.RootPath, 0, rootFolder, new int[0], sonarrSettings.ApiKey, + sonarrSettings.SeasonFolders, rootFolderPath, 0, new int[0], sonarrSettings.ApiKey, sonarrSettings.FullUri, false)); @@ -136,7 +130,7 @@ namespace Ombi.Core { // Set the series as monitored with a season count as 0 so it doesn't search for anything SonarrApi.AddSeriesNew(model.ProviderId, model.Title, qualityProfile, - sonarrSettings.SeasonFolders, sonarrSettings.RootPath, rootFolder, new int[] {1,2,3,4,5,6,7,8,9,10,11,12,13}, sonarrSettings.ApiKey, + sonarrSettings.SeasonFolders, rootFolderPath, new int[] {1,2,3,4,5,6,7,8,9,10,11,12,13}, sonarrSettings.ApiKey, sonarrSettings.FullUri); await Task.Delay(TimeSpan.FromSeconds(1)); @@ -383,5 +377,20 @@ namespace Ombi.Core return selectedSeries; } + + private async Task GetRootPath(int pathId, SonarrSettings sonarrSettings) + { + var rootFoldersResult = await Cache.GetOrSetAsync(CacheKeys.SonarrRootFolders, async () => + { + return await Task.Run(() => SonarrApi.GetRootFolders(sonarrSettings.ApiKey, sonarrSettings.FullUri)); + }); + + foreach (var r in rootFoldersResult.Where(r => r.id == pathId)) + { + return r.path; + } + return string.Empty; + } + } } \ No newline at end of file diff --git a/Ombi.Core/TvSenderOld.cs b/Ombi.Core/TvSenderOld.cs index 5edbda02c..6d819753e 100644 --- a/Ombi.Core/TvSenderOld.cs +++ b/Ombi.Core/TvSenderOld.cs @@ -34,27 +34,30 @@ using Ombi.Api.Interfaces; using Ombi.Api.Models.SickRage; using Ombi.Api.Models.Sonarr; using Ombi.Core.SettingModels; +using Ombi.Helpers; using Ombi.Store; namespace Ombi.Core { public class TvSenderOld { - public TvSenderOld(ISonarrApi sonarrApi, ISickRageApi srApi) + public TvSenderOld(ISonarrApi sonarrApi, ISickRageApi srApi, ICacheProvider cache) { SonarrApi = sonarrApi; SickrageApi = srApi; + Cache = cache; } private ISonarrApi SonarrApi { get; } private ISickRageApi SickrageApi { get; } + private ICacheProvider Cache { get; } private static Logger Log = LogManager.GetCurrentClassLogger(); - public async Task SendToSonarr(SonarrSettings sonarrSettings, RequestedModel model, string rootFolderId = null) + public async Task SendToSonarr(SonarrSettings sonarrSettings, RequestedModel model) { - return await SendToSonarr(sonarrSettings, model, string.Empty, rootFolderId); + return await SendToSonarr(sonarrSettings, model, string.Empty); } - public async Task SendToSonarr(SonarrSettings sonarrSettings, RequestedModel model, string qualityId, string rootFolderId) + public async Task SendToSonarr(SonarrSettings sonarrSettings, RequestedModel model, string qualityId) { var qualityProfile = 0; var episodeRequest = model.Episodes.Any(); @@ -67,16 +70,7 @@ namespace Ombi.Core { int.TryParse(sonarrSettings.QualityProfile, out qualityProfile); } - var rootFolder = 0; - if (!string.IsNullOrEmpty(rootFolderId)) - { - int.TryParse(qualityId, out rootFolder); - } - - if (rootFolder <= 0) - { - int.TryParse(sonarrSettings.RootFolder, out rootFolder); - } + var rootFolderPath = model.RootFolderSelected <= 0 ? sonarrSettings.RootPath : await GetRootPath(model.RootFolderSelected, sonarrSettings); var series = await GetSonarrSeries(sonarrSettings, model.ProviderId); @@ -95,7 +89,7 @@ namespace Ombi.Core // Series doesn't exist, need to add it as unmonitored. var addResult = await Task.Run(() => SonarrApi.AddSeries(model.ProviderId, model.Title, qualityProfile, - sonarrSettings.SeasonFolders, sonarrSettings.RootPath, rootFolder, 0, new int[0], sonarrSettings.ApiKey, + sonarrSettings.SeasonFolders, rootFolderPath, 0, new int[0], sonarrSettings.ApiKey, sonarrSettings.FullUri, false)); @@ -167,7 +161,7 @@ namespace Ombi.Core var result = SonarrApi.AddSeries(model.ProviderId, model.Title, qualityProfile, - sonarrSettings.SeasonFolders, sonarrSettings.RootPath, rootFolder, model.SeasonCount, model.SeasonList, sonarrSettings.ApiKey, + sonarrSettings.SeasonFolders, rootFolderPath, model.SeasonCount, model.SeasonList, sonarrSettings.ApiKey, sonarrSettings.FullUri, true, true); return result; @@ -309,5 +303,20 @@ namespace Ombi.Core return selectedSeries; } + + + private async Task GetRootPath(int pathId, SonarrSettings sonarrSettings) + { + var rootFoldersResult = await Cache.GetOrSetAsync(CacheKeys.SonarrRootFolders, async () => + { + return await Task.Run(() => SonarrApi.GetRootFolders(sonarrSettings.ApiKey, sonarrSettings.FullUri)); + }); + + foreach (var r in rootFoldersResult.Where(r => r.id == pathId)) + { + return r.path; + } + return string.Empty; + } } } \ No newline at end of file diff --git a/Ombi.Services/Jobs/FaultQueueHandler.cs b/Ombi.Services/Jobs/FaultQueueHandler.cs index 61d3a4674..09c311225 100644 --- a/Ombi.Services/Jobs/FaultQueueHandler.cs +++ b/Ombi.Services/Jobs/FaultQueueHandler.cs @@ -53,7 +53,7 @@ namespace Ombi.Services.Jobs ISickRageApi srApi, ISettingsService sonarrSettings, ISettingsService srSettings, ICouchPotatoApi cpApi, ISettingsService cpsettings, IRequestService requestService, ISettingsService hpSettings, IHeadphonesApi headphonesApi, ISettingsService prSettings, - ISecurityExtensions security, IMovieSender movieSender) + ISecurityExtensions security, IMovieSender movieSender, ICacheProvider cache) { Record = record; Repo = repo; @@ -71,6 +71,8 @@ namespace Ombi.Services.Jobs Security = security; PrSettings = prSettings.GetSettings(); MovieSender = movieSender; + + Cache = cache; } private IMovieSender MovieSender { get; } @@ -78,6 +80,7 @@ namespace Ombi.Services.Jobs private IJobRecord Record { get; } private ISonarrApi SonarrApi { get; } private ISickRageApi SrApi { get; } + private ICacheProvider Cache { get; } private ICouchPotatoApi CpApi { get; } private IHeadphonesApi HpApi { get; } private IRequestService RequestService { get; } @@ -163,7 +166,7 @@ namespace Ombi.Services.Jobs try { - var sender = new TvSenderOld(SonarrApi, SrApi); + var sender = new TvSenderOld(SonarrApi, SrApi, Cache); if (sonarr.Enabled) { var task = sender.SendToSonarr(sonarr, tvModel, sonarr.QualityProfile); diff --git a/Ombi.Services/Jobs/PlexAvailabilityChecker.cs b/Ombi.Services/Jobs/PlexAvailabilityChecker.cs index a58b5841c..936b128dc 100644 --- a/Ombi.Services/Jobs/PlexAvailabilityChecker.cs +++ b/Ombi.Services/Jobs/PlexAvailabilityChecker.cs @@ -79,6 +79,7 @@ namespace Ombi.Services.Jobs public void CheckAndUpdateAll() { + var plexSettings = Plex.GetSettings(); if (!ValidateSettings(plexSettings)) diff --git a/Ombi.Store/RequestedModel.cs b/Ombi.Store/RequestedModel.cs index ffd416966..89c30e21e 100644 --- a/Ombi.Store/RequestedModel.cs +++ b/Ombi.Store/RequestedModel.cs @@ -46,6 +46,13 @@ namespace Ombi.Store public List Episodes { get; set; } public bool Denied { get; set; } public string DeniedReason { get; set; } + /// + /// For TV Shows with a custom root folder + /// + /// + /// The root folder selected. + /// + public int RootFolderSelected { get; set; } [JsonIgnore] public List AllUsers diff --git a/Ombi.UI.Tests/TvSenderTests.cs b/Ombi.UI.Tests/TvSenderTests.cs index 8a5191c12..1a766ad67 100644 --- a/Ombi.UI.Tests/TvSenderTests.cs +++ b/Ombi.UI.Tests/TvSenderTests.cs @@ -35,6 +35,7 @@ using Ombi.Api.Interfaces; using Ombi.Api.Models.Sonarr; using Ombi.Core; using Ombi.Core.SettingModels; +using Ombi.Helpers; using Ombi.Store; using Ploeh.AutoFixture; @@ -49,6 +50,7 @@ namespace Ombi.UI.Tests private TvSender Sender { get; set; } private Fixture F { get; set; } + private Mock Cache { get; set; } [SetUp] public void Setup() @@ -56,7 +58,8 @@ namespace Ombi.UI.Tests F = new Fixture(); SonarrMock = new Mock(); SickrageMock = new Mock(); - Sender = new TvSender(SonarrMock.Object, SickrageMock.Object); + Cache = new Mock(); + Sender = new TvSender(SonarrMock.Object, SickrageMock.Object, Cache.Object); } [Test] @@ -66,7 +69,7 @@ namespace Ombi.UI.Tests var seriesResult = new SonarrAddSeries() { title = "ABC"}; SonarrMock.Setup(x => x.GetSeries(It.IsAny(), It.IsAny())).Returns(F.Build().With(x => x.tvdbId, 1).With(x => x.title, "ABC").CreateMany().ToList()); - Sender = new TvSender(SonarrMock.Object, SickrageMock.Object); + Sender = new TvSender(SonarrMock.Object, SickrageMock.Object, Cache.Object); var request = new RequestedModel {SeasonsRequested = "All", ProviderId = 1, Title = "ABC"}; @@ -79,7 +82,6 @@ namespace Ombi.UI.Tests It.IsAny(), It.IsAny(), It.IsAny(), - It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), @@ -100,7 +102,6 @@ namespace Ombi.UI.Tests It.IsAny(), It.IsAny(), It.IsAny(), - It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), @@ -118,7 +119,7 @@ namespace Ombi.UI.Tests SonarrMock.Setup(x => x.GetEpisodes(It.IsAny(), It.IsAny(), It.IsAny())).Returns(F.CreateMany()); - Sender = new TvSender(SonarrMock.Object, SickrageMock.Object); + Sender = new TvSender(SonarrMock.Object, SickrageMock.Object, Cache.Object); var episodes = new List { new EpisodesModel @@ -130,7 +131,7 @@ namespace Ombi.UI.Tests var model = F.Build().With(x => x.ProviderId, 1) .With(x => x.Episodes, episodes).Create(); - var result = await Sender.SendToSonarr(GetSonarrSettings(), model, "2", string.Empty); + var result = await Sender.SendToSonarr(GetSonarrSettings(), model, "2"); Assert.That(result, Is.EqualTo(seriesResult)); SonarrMock.Verify(x => x.AddSeries(It.IsAny(), @@ -139,7 +140,6 @@ namespace Ombi.UI.Tests It.IsAny(), It.IsAny(), It.IsAny(), - It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), diff --git a/Ombi.UI/Content/requests.js b/Ombi.UI/Content/requests.js index 7928f39aa..1d2ad987d 100644 --- a/Ombi.UI/Content/requests.js +++ b/Ombi.UI/Content/requests.js @@ -559,6 +559,25 @@ $(document).on("click", ".approve-with-quality", function (e) { }); +// Change root folder +$(document).on("click", ".change-root-folder", function (e) { + e.preventDefault(); + var $this = $(this); + var $button = $this.parents('.btn-split').children('.change').first(); + var rootFolderId = e.target.id + var $form = $this.parents('form').first(); + + if ($button.text() === " Loading...") { + return; + } + + loadingButton($button.attr('id'), "success"); + + changeRootFolder($form, rootFolderId, function () { + }); + +}); + // Change Availability $(document).on("click", ".change", function (e) { @@ -638,6 +657,37 @@ function approveRequest($form, qualityId, successCallback) { }); } +function changeRootFolder($form, rootFolderId, successCallback) { + + var formData = $form.serialize(); + if (rootFolderId) formData += ("&rootFolderId=" + rootFolderId); + + $.ajax({ + type: $form.prop('method'), + url: $form.prop('action'), + data: formData, + dataType: "json", + success: function (response) { + + if (checkJsonResponse(response)) { + if (response.message) { + generateNotify(response.message, "success"); + } else { + generateNotify("Success! Changed Root Path.", "success"); + } + + if (successCallback) { + successCallback(); + } + } + }, + error: function (e) { + console.log(e); + generateNotify("Something went wrong!", "danger"); + } + }); +} + function denyRequest($form, successCallback) { var formData = $form.serialize(); @@ -808,6 +858,9 @@ function buildRequestContext(result, type) { musicBrainzId: result.musicBrainzId, denied: result.denied, deniedReason: result.deniedReason, + hasRootFolders: result.hasRootFolders, + rootFolders: result.rootFolders, + currentRootPath : result.currentRootPath }; return context; diff --git a/Ombi.UI/ModelDataProviders/SonarrSettingsDataProvider.cs b/Ombi.UI/ModelDataProviders/SonarrSettingsDataProvider.cs index ba4b727bd..7f3474ff8 100644 --- a/Ombi.UI/ModelDataProviders/SonarrSettingsDataProvider.cs +++ b/Ombi.UI/ModelDataProviders/SonarrSettingsDataProvider.cs @@ -52,8 +52,7 @@ namespace Ombi.UI.ModelDataProviders with.Property(x => x.QualityProfile).Description("Sonarr's quality profile").Required(true); with.Property(x => x.SeasonFolders).Description("Sonarr's season folders").Required(false); - - with.Property(x => x.RootFolder).Description("Sonarr's root folder").Required(true); + with.Property(x => x.RootPath).Description("Sonarr's root path").Required(false); }); } diff --git a/Ombi.UI/Models/RequestViewModel.cs b/Ombi.UI/Models/RequestViewModel.cs index cbe59eea4..b31237bdc 100644 --- a/Ombi.UI/Models/RequestViewModel.cs +++ b/Ombi.UI/Models/RequestViewModel.cs @@ -59,5 +59,7 @@ namespace Ombi.UI.Models public bool Denied { get; set; } public string DeniedReason { get; set; } public RootFolderModel[] RootFolders { get; set; } + public bool HasRootFolders { get; set; } + public string CurrentRootPath { get; set; } } } diff --git a/Ombi.UI/Modules/ApprovalModule.cs b/Ombi.UI/Modules/ApprovalModule.cs index 0f92abfb3..667b3e843 100644 --- a/Ombi.UI/Modules/ApprovalModule.cs +++ b/Ombi.UI/Modules/ApprovalModule.cs @@ -50,7 +50,7 @@ namespace Ombi.UI.Modules public ApprovalModule(IRequestService service, ISonarrApi sonarrApi, ISettingsService sonarrSettings, ISickRageApi srApi, ISettingsService srSettings, ISettingsService hpSettings, IHeadphonesApi hpApi, ISettingsService pr, ITransientFaultQueue faultQueue - , ISecurityExtensions security, IMovieSender movieSender) : base("approval", pr, security) + , ISecurityExtensions security, IMovieSender movieSender, ICacheProvider cache) : base("approval", pr, security) { Before += (ctx) => Security.AdminLoginRedirect(ctx, Permissions.Administrator,Permissions.ManageRequests); @@ -64,8 +64,9 @@ namespace Ombi.UI.Modules HeadphoneApi = hpApi; FaultQueue = faultQueue; MovieSender = movieSender; + Cache = cache; - Post["/approve", true] = async (x, ct) => await Approve((int)Request.Form.requestid, (string)Request.Form.qualityId, (string)Request.Form.rootFolderId ?? null); + Post["/approve", true] = async (x, ct) => await Approve((int)Request.Form.requestid, (string)Request.Form.qualityId); Post["/deny", true] = async (x, ct) => await DenyRequest((int)Request.Form.requestid, (string)Request.Form.reason); Post["/approveall", true] = async (x, ct) => await ApproveAll(); Post["/approveallmovies", true] = async (x, ct) => await ApproveAllMovies(); @@ -86,13 +87,14 @@ namespace Ombi.UI.Modules private ISickRageApi SickRageApi { get; } private IHeadphonesApi HeadphoneApi { get; } private ITransientFaultQueue FaultQueue { get; } + private ICacheProvider Cache { get; } /// /// Approves the specified request identifier. /// /// The request identifier. /// - private async Task Approve(int requestId, string qualityId, string rootFolderId = null) + private async Task Approve(int requestId, string qualityId) { Log.Info("approving request {0}", requestId); @@ -110,7 +112,7 @@ namespace Ombi.UI.Modules case RequestType.Movie: return await RequestMovieAndUpdateStatus(request, qualityId); case RequestType.TvShow: - return await RequestTvAndUpdateStatus(request, qualityId, rootFolderId); + return await RequestTvAndUpdateStatus(request, qualityId); case RequestType.Album: return await RequestAlbumAndUpdateStatus(request); default: @@ -118,9 +120,9 @@ namespace Ombi.UI.Modules } } - private async Task RequestTvAndUpdateStatus(RequestedModel request, string qualityId, string rootFolderId) + private async Task RequestTvAndUpdateStatus(RequestedModel request, string qualityId) { - var sender = new TvSenderOld(SonarrApi, SickRageApi); // TODO put back + var sender = new TvSenderOld(SonarrApi, SickRageApi, Cache); // TODO put back var sonarrSettings = await SonarrSettings.GetSettingsAsync(); if (sonarrSettings.Enabled) @@ -435,7 +437,7 @@ namespace Ombi.UI.Modules } if (r.Type == RequestType.TvShow) { - var sender = new TvSenderOld(SonarrApi, SickRageApi); // TODO put back + var sender = new TvSenderOld(SonarrApi, SickRageApi, Cache); // TODO put back var sr = await SickRageSettings.GetSettingsAsync(); var sonarr = await SonarrSettings.GetSettingsAsync(); if (sr.Enabled) diff --git a/Ombi.UI/Modules/RequestsModule.cs b/Ombi.UI/Modules/RequestsModule.cs index 5030a3686..72fbba0f9 100644 --- a/Ombi.UI/Modules/RequestsModule.cs +++ b/Ombi.UI/Modules/RequestsModule.cs @@ -96,6 +96,8 @@ namespace Ombi.UI.Modules Post["/changeavailability", true] = async (x, ct) => await ChangeRequestAvailability((int)Request.Form.Id, (bool)Request.Form.Available); + Post["/changeRootFolder", true] = async (x, ct) => await ChangeRootFolder((int) Request.Form.requestId, (int) Request.Form.rootFolderId); + Get["/UpdateFilters", true] = async (x, ct) => await GetFilterAndSortSettings(); } @@ -160,38 +162,7 @@ namespace Ombi.UI.Modules } } - IEnumerable rootFolders = new List(); - if (IsAdmin) - { - try - { - var sonarrSettings = await SonarrSettings.GetSettingsAsync(); - if (sonarrSettings.Enabled) - { - var result = Cache.GetOrSetAsync(CacheKeys.SonarrRootFolders, async () => - { - return await Task.Run(() => SonarrApi.GetRootFolders(sonarrSettings.ApiKey, sonarrSettings.FullUri)); - }); - rootFolders = result.Result.Select(x => new RootFolderModel { Id = x.id.ToString(), Path = x.path }).ToList(); - } - // @TODO Sick Rage Root Folders - //else - //{ - // var sickRageSettings = await SickRageSettings.GetSettingsAsync(); - // if (sickRageSettings.Enabled) - // { - // qualities = sickRageSettings.Qualities.Select(x => new QualityModel { Id = x.Key, Name = x.Value }).ToList(); - // } - //} - } - catch (Exception e) - { - Log.Info(e); - } - - } - - + var canManageRequest = Security.HasAnyPermissions(User, Permissions.Administrator, Permissions.ManageRequests); var viewModel = dbMovies.Select(movie => new RequestViewModel { @@ -217,7 +188,6 @@ namespace Ombi.UI.Modules Denied = movie.Denied, DeniedReason = movie.DeniedReason, Qualities = qualities.ToArray(), - RootFolders = rootFolders.ToArray(), }).ToList(); return Response.AsJson(viewModel); @@ -225,32 +195,39 @@ namespace Ombi.UI.Modules private async Task GetTvShows() { - var settingsTask = PrSettings.GetSettingsAsync(); - var requests = await Service.GetAllAsync(); requests = requests.Where(x => x.Type == RequestType.TvShow); var dbTv = requests; - var settings = await settingsTask; if (Security.HasPermissions(User, Permissions.UsersCanViewOnlyOwnRequests) && !IsAdmin) { dbTv = dbTv.Where(x => x.UserHasRequested(Username)).ToList(); } IEnumerable qualities = new List(); + IEnumerable rootFolders = new List(); + + var sonarrSettings = await SonarrSettings.GetSettingsAsync(); if (IsAdmin) { try { - var sonarrSettings = await SonarrSettings.GetSettingsAsync(); if (sonarrSettings.Enabled) { - var result = Cache.GetOrSetAsync(CacheKeys.SonarrQualityProfiles, async () => + var result = await Cache.GetOrSetAsync(CacheKeys.SonarrQualityProfiles, async () => { return await Task.Run(() => SonarrApi.GetProfiles(sonarrSettings.ApiKey, sonarrSettings.FullUri)); }); - qualities = result.Result.Select(x => new QualityModel { Id = x.id.ToString(), Name = x.name }).ToList(); - } + qualities = result.Select(x => new QualityModel { Id = x.id.ToString(), Name = x.name }).ToList(); + + + var rootFoldersResult =await Cache.GetOrSetAsync(CacheKeys.SonarrRootFolders, async () => + { + return await Task.Run(() => SonarrApi.GetRootFolders(sonarrSettings.ApiKey, sonarrSettings.FullUri)); + }); + + rootFolders = rootFoldersResult.Select(x => new RootFolderModel { Id = x.id.ToString(), Path = x.path, FreeSpace = x.freespace}).ToList(); + } else { var sickRageSettings = await SickRageSettings.GetSettingsAsync(); @@ -296,11 +273,28 @@ namespace Ombi.UI.Modules TvSeriesRequestType = tv.SeasonsRequested, Qualities = qualities.ToArray(), Episodes = tv.Episodes.ToArray(), + RootFolders = rootFolders.ToArray(), + HasRootFolders = rootFolders.Any(), + CurrentRootPath = GetRootPath(tv.RootFolderSelected, sonarrSettings).Result }).ToList(); return Response.AsJson(viewModel); } + private async Task GetRootPath(int pathId, SonarrSettings sonarrSettings) + { + var rootFoldersResult = await Cache.GetOrSetAsync(CacheKeys.SonarrRootFolders, async () => + { + return await Task.Run(() => SonarrApi.GetRootFolders(sonarrSettings.ApiKey, sonarrSettings.FullUri)); + }); + + foreach (var r in rootFoldersResult.Where(r => r.id == pathId)) + { + return r.path; + } + return string.Empty; + } + private async Task GetAlbumRequests() { var settings = PrSettings.GetSettings(); @@ -464,5 +458,34 @@ namespace Ombi.UI.Modules return Response.AsJson(vm); } - } + + private async Task ChangeRootFolder(int id, int rootFolderId) + { + // Get all root folders + var settings = await SonarrSettings.GetSettingsAsync(); + var rootFolders = SonarrApi.GetRootFolders(settings.ApiKey, settings.FullUri); + + // Get Request + var allRequests = await Service.GetAllAsync(); + var request = allRequests.FirstOrDefault(x => x.Id == id); + + if (request == null) + { + return Response.AsJson(new JsonResponseModel {Result = false}); + } + + foreach (var folder in rootFolders) + { + if (folder.id.Equals(rootFolderId)) + { + request.RootFolderSelected = folder.id; + break; + } + } + + await Service.UpdateRequestAsync(request); + + return Response.AsJson(new JsonResponseModel {Result = true}); + } + } } diff --git a/Ombi.UI/Modules/SearchModule.cs b/Ombi.UI/Modules/SearchModule.cs index 63cc4c03c..75c6352e4 100644 --- a/Ombi.UI/Modules/SearchModule.cs +++ b/Ombi.UI/Modules/SearchModule.cs @@ -1107,7 +1107,7 @@ namespace Ombi.UI.Modules { model.Approved = true; var s = await sonarrSettings; - var sender = new TvSenderOld(SonarrApi, SickrageApi); // TODO put back + var sender = new TvSenderOld(SonarrApi, SickrageApi, Cache); // TODO put back if (s.Enabled) { var result = await sender.SendToSonarr(s, model); diff --git a/Ombi.UI/Ombi.UI.csproj b/Ombi.UI/Ombi.UI.csproj index 3d51318d0..25745546a 100644 --- a/Ombi.UI/Ombi.UI.csproj +++ b/Ombi.UI/Ombi.UI.csproj @@ -798,7 +798,7 @@ Always - + Always diff --git a/Ombi.UI/Views/Admin/Sonarr.cshtml b/Ombi.UI/Views/Admin/Sonarr.cshtml index 7048a4152..025059e94 100644 --- a/Ombi.UI/Views/Admin/Sonarr.cshtml +++ b/Ombi.UI/Views/Admin/Sonarr.cshtml @@ -81,13 +81,13 @@
- +
- +
@@ -176,37 +176,38 @@ } - @if (!string.IsNullOrEmpty(Model.RootFolder)) + @if (!string.IsNullOrEmpty(Model.RootPath)) { - console.log('Hit root folders..'); - - var rootFolderSelected = @Model.RootFolder; - if (!rootFolderSelected) { - return; - } - var $form = $("#mainForm"); - $.ajax({ - type: $form.prop("method"), - data: $form.serialize(), - url: "sonarrrootfolders", - dataType: "json", - success: function(response) { - response.forEach(function(result) { - if (result.id == rootFolderSelected) { - $("#selectRootFolder").append(""); - } else { - $("#selectRootFolder").append(""); - } - }); - }, - error: function(e) { - console.log(e); - generateNotify("Something went wrong!", "danger"); - } - }); - + console.log('Hit root folders..'); + + var rootFolderSelected = @Model.RootPath; + if (!rootFolderSelected) { + return; + } + var $form = $("#mainForm"); + $.ajax({ + type: $form.prop("method"), + data: $form.serialize(), + url: "sonarrrootfolders", + dataType: "json", + success: function(response) { + response.forEach(function(result) { + $('#selectedRootFolder').html(""); + if (result.id == rootFolderSelected) { + $("#selectRootFolder").append(""); + } else { + $("#selectRootFolder").append(""); + } + }); + }, + error: function(e) { + console.log(e); + generateNotify("Something went wrong!", "danger"); + } + }); + } @@ -218,11 +219,12 @@ return; } var qualityProfile = $("#profiles option:selected").val(); + var rootFolder = $("#rootFolders option:selected").val(); var $form = $("#mainForm"); var data = $form.serialize(); - data = data + "&qualityProfile=" + qualityProfile; + data = data + "&qualityProfile=" + qualityProfile + "&rootPath=" + rootFolder; $.ajax({ type: $form.prop("method"), diff --git a/Ombi.UI/Views/Admin/Radarr.cshtml b/Ombi.UI/Views/Integration/Radarr.cshtml similarity index 100% rename from Ombi.UI/Views/Admin/Radarr.cshtml rename to Ombi.UI/Views/Integration/Radarr.cshtml diff --git a/Ombi.UI/Views/Requests/Index.cshtml b/Ombi.UI/Views/Requests/Index.cshtml index 0447e25fa..7199253c7 100644 --- a/Ombi.UI/Views/Requests/Index.cshtml +++ b/Ombi.UI/Views/Requests/Index.cshtml @@ -244,6 +244,11 @@
@UI.Requests_RequestedBy: {{requestedUsers}}
{{/if}}
@UI.Requests_RequestedDate: {{requestedDate}}
+ {{#if admin}} + {{#if currentRootPath}} +
Root Path: {{currentRootPath}}
+ {{/if}} + {{/if}}
{{#if_eq issueId 0}} @*Nothing*@ @@ -275,6 +280,28 @@ {{/if_eq}} + + +
+ + {{#if_eq hasRootFolders true}} +
+ + + +
+ {{/if_eq}} +
+ + + {{#unless denied}}