From 1d983801e86a0fba03eef865498095870a0ac162 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Fri, 26 Aug 2011 10:45:59 -0700 Subject: [PATCH] SABnzbd settings will now dynamically get the categories available from SABnzbd when the category drop-box gets focus, it will use values on the page so there is no need to save your settings first. --- NzbDrone.Core.Test/Files/Categories_json.txt | 1 + NzbDrone.Core.Test/NzbDrone.Core.Test.csproj | 3 + NzbDrone.Core.Test/SabProviderTest.cs | 63 ++++++++++++++++++- NzbDrone.Core/Model/SabnzbdCategoryModel.cs | 12 ++++ NzbDrone.Core/NzbDrone.Core.csproj | 1 + .../Providers/Core/ConfigProvider.cs | 2 +- .../Providers/Jobs/PostDownloadScanJob.cs | 2 +- NzbDrone.Core/Providers/SabProvider.cs | 58 +++++++++++++---- NzbDrone.Web/Controllers/CommandController.cs | 22 ++++++- .../Controllers/SettingsController.cs | 8 +-- NzbDrone.Web/Models/SabnzbdSettingsModel.cs | 2 +- NzbDrone.Web/Views/Settings/Sabnzbd.cshtml | 41 +++++++++++- NzbDrone.Web/Views/Settings/Test.cshtml | 39 ++++++++++-- 13 files changed, 228 insertions(+), 26 deletions(-) create mode 100644 NzbDrone.Core.Test/Files/Categories_json.txt create mode 100644 NzbDrone.Core/Model/SabnzbdCategoryModel.cs diff --git a/NzbDrone.Core.Test/Files/Categories_json.txt b/NzbDrone.Core.Test/Files/Categories_json.txt new file mode 100644 index 000000000..fb2c385db --- /dev/null +++ b/NzbDrone.Core.Test/Files/Categories_json.txt @@ -0,0 +1 @@ +{"categories":["*","anime","apps","books","consoles","ds-games","emulation","games","misc","movies","music","pda","resources","test","tv","tv-dvd","unknown","wii-games","xbox-dlc","xbox-xbla","xxx"]} \ No newline at end of file diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index 4ea3d9c4e..b5c5c8787 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -147,6 +147,9 @@ Always + + Always + Always diff --git a/NzbDrone.Core.Test/SabProviderTest.cs b/NzbDrone.Core.Test/SabProviderTest.cs index 4bc15f101..66a33769e 100644 --- a/NzbDrone.Core.Test/SabProviderTest.cs +++ b/NzbDrone.Core.Test/SabProviderTest.cs @@ -292,7 +292,6 @@ namespace NzbDrone.Core.Test Assert.AreEqual(excpected, actual); } - [Test] [Explicit] public void AddNewzbingByUrlSuccess() @@ -335,5 +334,67 @@ namespace NzbDrone.Core.Test //Assert result.Should().BeTrue(); } + + [Test] + public void Get_Categories_Success_Passed_Values() + { + //Setup + const string host = "192.168.5.55"; + const int port = 2222; + const string apikey = "5c770e3197e4fe763423ee7c392c25d1"; + const string username = "admin"; + const string password = "pass"; + + var mocker = new AutoMoqer(); + + mocker.GetMock(MockBehavior.Strict) + .Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=get_cats&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass")) + .Returns(File.ReadAllText(@".\Files\Categories_json.txt")); + + //Act + var result = mocker.Resolve().GetCategories(host, port, apikey, username, password); + + //Assert + result.Should().NotBeNull(); + result.categories.Should().HaveCount(c => c > 0); + result.categories.Should().NotContain("*"); + } + + [Test] + public void Get_Categories_Success_Config_Values() + { + //Setup + const string host = "192.168.5.55"; + const int port = 2222; + const string apikey = "5c770e3197e4fe763423ee7c392c25d1"; + const string username = "admin"; + const string password = "pass"; + + var mocker = new AutoMoqer(); + + var fakeConfig = mocker.GetMock(); + fakeConfig.SetupGet(c => c.SabHost) + .Returns(host); + fakeConfig.SetupGet(c => c.SabPort) + .Returns(port); + fakeConfig.SetupGet(c => c.SabApiKey) + .Returns(apikey); + fakeConfig.SetupGet(c => c.SabUsername) + .Returns(username); + fakeConfig.SetupGet(c => c.SabPassword) + .Returns(password); + + mocker.GetMock(MockBehavior.Strict) + .Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=get_cats&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass")) + .Returns(File.ReadAllText(@".\Files\Categories_json.txt")); + + //Act + var result = mocker.Resolve().GetCategories(); + + //Assert + result.Should().NotBeNull(); + result.categories.Should().HaveCount(c => c > 0); + result.categories.Should().NotContain("*"); + } } } \ No newline at end of file diff --git a/NzbDrone.Core/Model/SabnzbdCategoryModel.cs b/NzbDrone.Core/Model/SabnzbdCategoryModel.cs new file mode 100644 index 000000000..cf3cf34dd --- /dev/null +++ b/NzbDrone.Core/Model/SabnzbdCategoryModel.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NzbDrone.Core.Model +{ + public class SabnzbdCategoryModel + { + public List categories { get; set; } + } +} diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index d027b7d2d..b08a5880e 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -191,6 +191,7 @@ + diff --git a/NzbDrone.Core/Providers/Core/ConfigProvider.cs b/NzbDrone.Core/Providers/Core/ConfigProvider.cs index f34b6cc0b..79518c78c 100644 --- a/NzbDrone.Core/Providers/Core/ConfigProvider.cs +++ b/NzbDrone.Core/Providers/Core/ConfigProvider.cs @@ -157,7 +157,7 @@ namespace NzbDrone.Core.Providers.Core public virtual String SabTvCategory { - get { return GetValue("SabTvCategory", "TV"); } + get { return GetValue("SabTvCategory", "tv"); } set { SetValue("SabTvCategory", value); } } diff --git a/NzbDrone.Core/Providers/Jobs/PostDownloadScanJob.cs b/NzbDrone.Core/Providers/Jobs/PostDownloadScanJob.cs index 0e10a3bea..5f78d500e 100644 --- a/NzbDrone.Core/Providers/Jobs/PostDownloadScanJob.cs +++ b/NzbDrone.Core/Providers/Jobs/PostDownloadScanJob.cs @@ -98,7 +98,7 @@ namespace NzbDrone.Core.Providers.Jobs //Otherwise rename the folder to say it was already processed once by NzbDrone so it will not be continually processed else - _diskProvider.MoveDirectory(subfolderInfo.FullName, Path.Combine(subfolderInfo.Parent.FullName, "_NzbDrone_" + subfolderInfo.Name)); + _diskProvider.MoveDirectory(subfolderInfo.FullName,Path.Combine(subfolderInfo.Parent.FullName, "_NzbDrone_" + subfolderInfo.Name)); } catch (Exception e) diff --git a/NzbDrone.Core/Providers/SabProvider.cs b/NzbDrone.Core/Providers/SabProvider.cs index 734f04026..ec9b427b9 100644 --- a/NzbDrone.Core/Providers/SabProvider.cs +++ b/NzbDrone.Core/Providers/SabProvider.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Web; +using System.Web.Script.Serialization; using System.Xml.Linq; using Ninject; using NLog; @@ -102,17 +103,6 @@ namespace NzbDrone.Core.Providers return false; //Not in Queue } - private string GetSabRequest(string action) - { - return string.Format(@"http://{0}:{1}/api?{2}&apikey={3}&ma_username={4}&ma_password={5}", - _configProvider.SabHost, - _configProvider.SabPort, - action, - _configProvider.SabApiKey, - _configProvider.SabUsername, - _configProvider.SabPassword); - } - public virtual String GetSabTitle(EpisodeParseResult parseResult) { //Show Name - 1x01-1x02 - Episode Name @@ -135,5 +125,51 @@ namespace NzbDrone.Core.Providers return result; } + + public virtual SabnzbdCategoryModel GetCategories(string host = null, int port = 0, string apiKey = null, string username = null, string password = null) + { + //Get saved values if any of these are defaults + if (host == null) + host = _configProvider.SabHost; + + if (port == 0) + port = _configProvider.SabPort; + + if (apiKey == null) + apiKey = _configProvider.SabApiKey; + + if (username == null) + username = _configProvider.SabUsername; + + if (password == null) + password = _configProvider.SabPassword; + + const string action = "mode=get_cats&output=json"; + + var command = string.Format(@"http://{0}:{1}/api?{2}&apikey={3}&ma_username={4}&ma_password={5}", + host, port, action, apiKey, username, password); + + var response = _httpProvider.DownloadString(command); + + if (String.IsNullOrWhiteSpace(response)) + return new SabnzbdCategoryModel{categories = new List()}; + + var deserialized = new JavaScriptSerializer().Deserialize(response); + + deserialized.categories.Remove("*"); + + return deserialized; + } + + private string GetSabRequest(string action) + { + return string.Format(@"http://{0}:{1}/api?{2}&apikey={3}&ma_username={4}&ma_password={5}", + _configProvider.SabHost, + _configProvider.SabPort, + action, + _configProvider.SabApiKey, + _configProvider.SabUsername, + _configProvider.SabPassword); + } } } \ No newline at end of file diff --git a/NzbDrone.Web/Controllers/CommandController.cs b/NzbDrone.Web/Controllers/CommandController.cs index 6a42c1acf..0dbfb58a0 100644 --- a/NzbDrone.Web/Controllers/CommandController.cs +++ b/NzbDrone.Web/Controllers/CommandController.cs @@ -3,17 +3,22 @@ using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; +using NzbDrone.Core.Model; +using NzbDrone.Core.Providers; using NzbDrone.Core.Providers.Jobs; +using NzbDrone.Web.Models; namespace NzbDrone.Web.Controllers { public class CommandController : Controller { private readonly JobProvider _jobProvider; + private readonly SabProvider _sabProvider; - public CommandController(JobProvider jobProvider) + public CommandController(JobProvider jobProvider, SabProvider sabProvider) { _jobProvider = jobProvider; + _sabProvider = sabProvider; } public JsonResult RssSync() @@ -37,5 +42,20 @@ namespace NzbDrone.Web.Controllers return new JsonResult { Data = "ok", JsonRequestBehavior = JsonRequestBehavior.AllowGet }; } + + [HttpPost] + public JsonResult GetSabnzbdCategories(string host, int port, string apiKey, string username, string password) + { + try + { + return new JsonResult {Data = _sabProvider.GetCategories(host, port, apiKey, username, password)}; + } + + catch (Exception ex) + { + //Todo: Log the error + throw; + } + } } } diff --git a/NzbDrone.Web/Controllers/SettingsController.cs b/NzbDrone.Web/Controllers/SettingsController.cs index ff2d4e10a..718ac802c 100644 --- a/NzbDrone.Web/Controllers/SettingsController.cs +++ b/NzbDrone.Web/Controllers/SettingsController.cs @@ -80,8 +80,8 @@ namespace NzbDrone.Web.Controllers public ActionResult Sabnzbd() { - var sabDropDir = _configProvider.SabDropDirectory; - var selectList = new SelectList(new List { sabDropDir }, sabDropDir); + var tvCategory = _configProvider.SabTvCategory; + var tvCategorySelectList = new SelectList(new[] { tvCategory }); var model = new SabnzbdSettingsModel { @@ -92,8 +92,8 @@ namespace NzbDrone.Web.Controllers SabPassword = _configProvider.SabPassword, SabTvCategory = _configProvider.SabTvCategory, SabTvPriority = _configProvider.SabTvPriority, - SabDropDirectory = sabDropDir, - SabDropDirectorySelectList = selectList + SabDropDirectory = _configProvider.SabDropDirectory, + SabTvCategorySelectList = tvCategorySelectList }; return View(model); diff --git a/NzbDrone.Web/Models/SabnzbdSettingsModel.cs b/NzbDrone.Web/Models/SabnzbdSettingsModel.cs index 5b0aef49b..d7e7cc80f 100644 --- a/NzbDrone.Web/Models/SabnzbdSettingsModel.cs +++ b/NzbDrone.Web/Models/SabnzbdSettingsModel.cs @@ -57,6 +57,6 @@ namespace NzbDrone.Web.Models [DisplayFormat(ConvertEmptyStringToNull = false)] public string SabDropDirectory { get; set; } - public SelectList SabDropDirectorySelectList { get; set; } + public SelectList SabTvCategorySelectList { get; set; } } } \ No newline at end of file diff --git a/NzbDrone.Web/Views/Settings/Sabnzbd.cshtml b/NzbDrone.Web/Views/Settings/Sabnzbd.cshtml index 0b4644517..0cf13c4f6 100644 --- a/NzbDrone.Web/Views/Settings/Sabnzbd.cshtml +++ b/NzbDrone.Web/Views/Settings/Sabnzbd.cshtml @@ -54,7 +54,7 @@ - @Html.TextBoxFor(m => m.SabTvCategory, new { @class = "inputClass" }) + @Html.DropDownListFor(m => m.SabTvCategory, Model.SabTvCategorySelectList, new { @class = "inputClass selectClass" })