From 9acfb7330c3fce280aaa2b26131ef452f2bf95d7 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Thu, 19 Jan 2012 21:37:08 -0800 Subject: [PATCH] Check sab queue now takes quality into consideration --- NzbDrone.Core.Test/Files/Queue.txt | 21 +- NzbDrone.Core.Test/ParserTest.cs | 11 +- .../ProviderTests/DownloadProviderTest.cs | 2 +- .../IsAcceptableSizeTestFixture.cs | 4 +- .../IsMonitoredFixture.cs | 6 +- .../QualityNeededFixture.cs | 4 +- .../ProviderTests/SabProviderTest.cs | 324 ++++++------------ NzbDrone.Core/Model/EpisodeParseResult.cs | 19 +- NzbDrone.Core/Model/Sabnzbd/SabHistoryItem.cs | 5 +- NzbDrone.Core/Model/Sabnzbd/SabQueueItem.cs | 14 +- NzbDrone.Core/Parser.cs | 14 +- NzbDrone.Core/Providers/DiskScanProvider.cs | 2 +- NzbDrone.Core/Providers/DownloadProvider.cs | 5 +- NzbDrone.Core/Providers/InventoryProvider.cs | 3 - NzbDrone.Core/Providers/SabProvider.cs | 55 +-- 15 files changed, 202 insertions(+), 287 deletions(-) diff --git a/NzbDrone.Core.Test/Files/Queue.txt b/NzbDrone.Core.Test/Files/Queue.txt index 27c6abf43..e06ae404c 100644 --- a/NzbDrone.Core.Test/Files/Queue.txt +++ b/NzbDrone.Core.Test/Files/Queue.txt @@ -31,7 +31,26 @@ "msgid":"4295398", "verbosity":"", "mb":"785.89", - "filename":"30 Rock - 1x05 - Title [SDTV]", + "filename":"30 Rock - 1x05 - Title [HDTV]", + "priority":"High", + "cat":"Apps", + "mbleft":"785.89", + "percentage":"0", + "nzo_id":"SABnzbd_nzo_wgmb1m", + "unpackopts":"3", + "size":"785.9 MB" + }, + { + "status":"Queued", + "index":0, + "eta":"unknown", + "timeleft":"0:00:00", + "avg_age":"43d", + "script":"None", + "msgid":"4295397", + "verbosity":"", + "mb":"785.89", + "filename":"The Simpsons - 1x05 - Title [HDTV] [Proper]", "priority":"High", "cat":"Apps", "mbleft":"785.89", diff --git a/NzbDrone.Core.Test/ParserTest.cs b/NzbDrone.Core.Test/ParserTest.cs index 01d278e5a..61845fbc8 100644 --- a/NzbDrone.Core.Test/ParserTest.cs +++ b/NzbDrone.Core.Test/ParserTest.cs @@ -135,16 +135,7 @@ public void parsing_our_own_quality_enum() foreach (var qualityEnum in qualityEnums) { - if (qualityEnum.ToString() == QualityTypes.Unknown.ToString()) continue; - - var extention = "mkv"; - - if (qualityEnum.ToString() == QualityTypes.SDTV.ToString() || qualityEnum.ToString() == QualityTypes.DVD.ToString()) - { - extention = "avi"; - } - - var fileName = String.Format("My series S01E01 [{0}].{1}", qualityEnum, extention); + var fileName = String.Format("My series S01E01 [{0}]", qualityEnum); var result = Parser.ParseQuality(fileName); result.QualityType.Should().Be(qualityEnum); } diff --git a/NzbDrone.Core.Test/ProviderTests/DownloadProviderTest.cs b/NzbDrone.Core.Test/ProviderTests/DownloadProviderTest.cs index 64410b9c7..1549f9447 100644 --- a/NzbDrone.Core.Test/ProviderTests/DownloadProviderTest.cs +++ b/NzbDrone.Core.Test/ProviderTests/DownloadProviderTest.cs @@ -34,7 +34,7 @@ public void Download_report_should_send_to_sab_add_to_history_mark_as_grabbed() const string sabTitle = "My fake sab title"; Mocker.GetMock() - .Setup(s => s.IsInQueue(It.IsAny())) + .Setup(s => s.IsInQueue(It.IsAny())) .Returns(false); Mocker.GetMock() diff --git a/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/IsAcceptableSizeTestFixture.cs b/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/IsAcceptableSizeTestFixture.cs index 0930e1d47..acb954dab 100644 --- a/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/IsAcceptableSizeTestFixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/IsAcceptableSizeTestFixture.cs @@ -31,7 +31,7 @@ public void Setup() { parseResultMulti = new EpisodeParseResult { - CleanTitle = "Title", + SeriesTitle = "Title", Language = LanguageType.English, Quality = new Quality(QualityTypes.SDTV, true), EpisodeNumbers = new List { 3, 4 }, @@ -41,7 +41,7 @@ public void Setup() parseResultSingle = new EpisodeParseResult { - CleanTitle = "Title", + SeriesTitle = "Title", Language = LanguageType.English, Quality = new Quality(QualityTypes.SDTV, true), EpisodeNumbers = new List { 3 }, diff --git a/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/IsMonitoredFixture.cs b/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/IsMonitoredFixture.cs index 7b9b3ab4b..50a85e6a4 100644 --- a/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/IsMonitoredFixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/IsMonitoredFixture.cs @@ -32,7 +32,7 @@ public void Setup() { parseResultMulti = new EpisodeParseResult() { - CleanTitle = "Title", + SeriesTitle = "Title", Language = LanguageType.English, Quality = new Quality(QualityTypes.Bluray720p, true), EpisodeNumbers = new List { 3, 4 }, @@ -42,7 +42,7 @@ public void Setup() parseResultSingle = new EpisodeParseResult() { - CleanTitle = "Title", + SeriesTitle = "Title", Language = LanguageType.English, Quality = new Quality(QualityTypes.Bluray720p, true), EpisodeNumbers = new List { 3 }, @@ -52,7 +52,7 @@ public void Setup() parseResultDaily = new EpisodeParseResult() { - CleanTitle = "Title", + SeriesTitle = "Title", Language = LanguageType.English, Quality = new Quality(QualityTypes.Bluray720p, true), AirDate = DateTime.Now.AddDays(-12).Date, diff --git a/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/QualityNeededFixture.cs b/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/QualityNeededFixture.cs index cad8d46d3..74d94f7d1 100644 --- a/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/QualityNeededFixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/InventoryProviderTests/QualityNeededFixture.cs @@ -34,7 +34,7 @@ public void Setup() { parseResultMulti = new EpisodeParseResult { - CleanTitle = "Title", + SeriesTitle = "Title", Language = LanguageType.English, Quality = new Quality(QualityTypes.Bluray720p, true), EpisodeNumbers = new List { 3, 4 }, @@ -44,7 +44,7 @@ public void Setup() parseResultSingle = new EpisodeParseResult { - CleanTitle = "Title", + SeriesTitle = "Title", Language = LanguageType.English, Quality = new Quality(QualityTypes.Bluray720p, true), EpisodeNumbers = new List { 3 }, diff --git a/NzbDrone.Core.Test/ProviderTests/SabProviderTest.cs b/NzbDrone.Core.Test/ProviderTests/SabProviderTest.cs index 1bd46f70c..795f4e316 100644 --- a/NzbDrone.Core.Test/ProviderTests/SabProviderTest.cs +++ b/NzbDrone.Core.Test/ProviderTests/SabProviderTest.cs @@ -1,6 +1,7 @@ // ReSharper disable RedundantUsingDirective using System; +using System.Collections.Generic; using System.IO; using System.Linq; @@ -24,7 +25,8 @@ namespace NzbDrone.Core.Test.ProviderTests // ReSharper disable InconsistentNaming public class SabProviderTest : CoreTest { - private void WithSabConfigValues() + [SetUp] + private void Setup() { //Setup string sabHost = "192.168.5.55"; @@ -32,56 +34,36 @@ private void WithSabConfigValues() string apikey = "5c770e3197e4fe763423ee7c392c25d1"; string username = "admin"; string password = "pass"; + string cat = "tv"; var fakeConfig = Mocker.GetMock(); - fakeConfig.SetupGet(c => c.SabHost) - .Returns(sabHost); - fakeConfig.SetupGet(c => c.SabPort) - .Returns(sabPort); - fakeConfig.SetupGet(c => c.SabApiKey) - .Returns(apikey); - fakeConfig.SetupGet(c => c.SabUsername) - .Returns(username); - fakeConfig.SetupGet(c => c.SabPassword) - .Returns(password); + fakeConfig.SetupGet(c => c.SabHost).Returns(sabHost); + fakeConfig.SetupGet(c => c.SabPort).Returns(sabPort); + fakeConfig.SetupGet(c => c.SabApiKey).Returns(apikey); + fakeConfig.SetupGet(c => c.SabUsername).Returns(username); + fakeConfig.SetupGet(c => c.SabPassword).Returns(password); + fakeConfig.SetupGet(c => c.SabTvCategory).Returns(cat); + } + + + private void WithFullQueue() + { + Mocker.GetMock() + .Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=queue&output=json&start=0&limit=0&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass")) + .Returns(File.ReadAllText(@".\Files\Queue.txt")); + } + + private void WithFailResponse() + { + Mocker.GetMock() + .Setup(s => s.DownloadString(It.IsAny())).Returns("failed"); } [Test] - public void AddByUrlSuccess() + public void add_url_should_format_request_properly() { - //Setup - const string sabHost = "192.168.5.55"; - const int sabPort = 2222; - const string apikey = "5c770e3197e4fe763423ee7c392c25d1"; - const string username = "admin"; - const string password = "pass"; - const SabPriorityType priority = SabPriorityType.Normal; - const string category = "tv"; - - - - - var fakeConfig = Mocker.GetMock(); - fakeConfig.SetupGet(c => c.SabHost) - .Returns(sabHost); - fakeConfig.SetupGet(c => c.SabPort) - .Returns(sabPort); - fakeConfig.SetupGet(c => c.SabApiKey) - .Returns(apikey); - fakeConfig.SetupGet(c => c.SabUsername) - .Returns(username); - fakeConfig.SetupGet(c => c.SabPassword) - .Returns(password); - fakeConfig.SetupGet(c => c.SabTvPriority) - .Returns(priority); - fakeConfig.SetupGet(c => c.SabTvCategory) - .Returns(category); - Mocker.GetMock(MockBehavior.Strict) - .Setup( - s => - s.DownloadString( - "http://192.168.5.55:2222/api?mode=addurl&name=http://www.nzbclub.com/nzb_download.aspx?mid=1950232&priority=0&pp=3&cat=tv&nzbname=This+is+an+Nzb&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass")) + .Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=addurl&name=http://www.nzbclub.com/nzb_download.aspx?mid=1950232&priority=0&pp=3&cat=tv&nzbname=This+is+an+Nzb&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass")) .Returns("ok"); //Act @@ -94,41 +76,10 @@ public void AddByUrlSuccess() [Test] - public void AddByUrlNewzbin() + public void newzbing_add_url_should_format_request_properly() { - //Setup - const string sabHost = "192.168.5.55"; - const int sabPort = 2222; - const string apikey = "5c770e3197e4fe763423ee7c392c25d1"; - const string username = "admin"; - const string password = "pass"; - const SabPriorityType priority = SabPriorityType.Normal; - const string category = "tv"; - - - - - var fakeConfig = Mocker.GetMock(); - fakeConfig.SetupGet(c => c.SabHost) - .Returns(sabHost); - fakeConfig.SetupGet(c => c.SabPort) - .Returns(sabPort); - fakeConfig.SetupGet(c => c.SabApiKey) - .Returns(apikey); - fakeConfig.SetupGet(c => c.SabUsername) - .Returns(username); - fakeConfig.SetupGet(c => c.SabPassword) - .Returns(password); - fakeConfig.SetupGet(c => c.SabTvPriority) - .Returns(priority); - fakeConfig.SetupGet(c => c.SabTvCategory) - .Returns(category); - Mocker.GetMock(MockBehavior.Strict) - .Setup( - s => - s.DownloadString( - "http://192.168.5.55:2222/api?mode=addid&name=6107863&priority=0&pp=3&cat=tv&nzbname=This+is+an+Nzb&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass")) + .Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=addid&name=6107863&priority=0&pp=3&cat=tv&nzbname=This+is+an+Nzb&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass")) .Returns("ok"); //Act @@ -140,37 +91,9 @@ public void AddByUrlNewzbin() } [Test] - public void AddByUrlError() + public void add_by_url_should_detect_and_handle_sab_errors() { - //Setup - string sabHost = "192.168.5.55"; - int sabPort = 2222; - string apikey = "5c770e3197e4fe763423ee7c392c25d1"; - string username = "admin"; - string password = "pass"; - var priority = SabPriorityType.Normal; - string category = "tv"; - - - - var fakeConfig = Mocker.GetMock(); - fakeConfig.SetupGet(c => c.SabHost) - .Returns(sabHost); - fakeConfig.SetupGet(c => c.SabPort) - .Returns(sabPort); - fakeConfig.SetupGet(c => c.SabApiKey) - .Returns(apikey); - fakeConfig.SetupGet(c => c.SabUsername) - .Returns(username); - fakeConfig.SetupGet(c => c.SabPassword) - .Returns(password); - fakeConfig.SetupGet(c => c.SabTvPriority) - .Returns(priority); - fakeConfig.SetupGet(c => c.SabTvCategory) - .Returns(category); - Mocker.GetMock() - .Setup(s => s.DownloadString(It.IsAny())) - .Returns("error"); + WithFailResponse(); //Act var sabProvider = Mocker.Resolve(); @@ -181,14 +104,14 @@ public void AddByUrlError() ExceptionVerification.ExpectedWarns(1); } - [Test] + [TestCase(1, new[] { 2 }, "My Episode Title", QualityTypes.DVD, false, "My Series Name - 1x2 - My Episode Title [DVD]")] [TestCase(1, new[] { 2 }, "My Episode Title", QualityTypes.DVD, true, "My Series Name - 1x2 - My Episode Title [DVD] [Proper]")] [TestCase(1, new[] { 2 }, "", QualityTypes.DVD, true, "My Series Name - 1x2 - [DVD] [Proper]")] [TestCase(1, new[] { 2, 4 }, "My Episode Title", QualityTypes.HDTV, false, "My Series Name - 1x2-1x4 - My Episode Title [HDTV]")] [TestCase(1, new[] { 2, 4 }, "My Episode Title", QualityTypes.HDTV, true, "My Series Name - 1x2-1x4 - My Episode Title [HDTV] [Proper]")] [TestCase(1, new[] { 2, 4 }, "", QualityTypes.HDTV, true, "My Series Name - 1x2-1x4 - [HDTV] [Proper]")] - public void sab_title(int seasons, int[] episodes, string title, QualityTypes quality, bool proper, string expected) + public void create_proper_sab_titles(int seasons, int[] episodes, string title, QualityTypes quality, bool proper, string expected) { var series = Builder.CreateNew() .With(c => c.Title = "My Series Name") @@ -201,7 +124,7 @@ public void sab_title(int seasons, int[] episodes, string title, QualityTypes qu Quality = new Quality(quality, proper), SeasonNumber = seasons, Series = series, - EpisodeTitle = title + EpisodeTitle = title }; //Act @@ -213,9 +136,9 @@ public void sab_title(int seasons, int[] episodes, string title, QualityTypes qu [TestCase(true, "My Series Name - Season 1 [Bluray720p] [Proper]")] [TestCase(false, "My Series Name - Season 1 [Bluray720p]")] - public void sab_season_title(bool proper, string expected) + public void create_proper_sab_season_title(bool proper, string expected) { - + var series = Builder.CreateNew() .With(c => c.Title = "My Series Name") @@ -240,7 +163,7 @@ public void sab_season_title(bool proper, string expected) [TestCase(true, "My Series Name - 2011-12-01 - My Episode Title [Bluray720p] [Proper]")] [TestCase(false, "My Series Name - 2011-12-01 - My Episode Title [Bluray720p]")] - public void sab_daily_series_title(bool proper, string expected) + public void create_proper_sab_daily_titles(bool proper, string expected) { var series = Builder.CreateNew() .With(c => c.IsDaily = true) @@ -249,7 +172,7 @@ public void sab_daily_series_title(bool proper, string expected) var parsResult = new EpisodeParseResult { - AirDate = new DateTime(2011, 12,1), + AirDate = new DateTime(2011, 12, 1), Quality = new Quality(QualityTypes.Bluray720p, proper), Series = series, EpisodeTitle = "My Episode Title", @@ -263,50 +186,7 @@ public void sab_daily_series_title(bool proper, string expected) } [Test] - [Explicit] - public void AddNewzbingByUrlSuccess() - { - //Setup - const string sabHost = "192.168.1.50"; - const int sabPort = 8080; - const string apikey = "f37dc33baec2e5566f5aec666287870d"; - const string username = "root"; - const string password = "*************"; - const SabPriorityType priority = SabPriorityType.Normal; - const string category = "tv"; - - - - - var fakeConfig = Mocker.GetMock(); - fakeConfig.SetupGet(c => c.SabHost) - .Returns(sabHost); - fakeConfig.SetupGet(c => c.SabPort) - .Returns(sabPort); - fakeConfig.SetupGet(c => c.SabApiKey) - .Returns(apikey); - fakeConfig.SetupGet(c => c.SabUsername) - .Returns(username); - fakeConfig.SetupGet(c => c.SabPassword) - .Returns(password); - fakeConfig.SetupGet(c => c.SabTvPriority) - .Returns(priority); - fakeConfig.SetupGet(c => c.SabTvCategory) - .Returns(category); - - - Mocker.SetConstant(new HttpProvider()); - - //Act - bool result = Mocker.Resolve().AddByUrl( - "http://www.newzbin.com/browse/post/6107863/nzb", "Added by unit tests."); - - //Assert - result.Should().BeTrue(); - } - - [Test] - public void Get_Categories_Success_Passed_Values() + public void should_be_able_to_get_categories_when_config_is_passed_in() { //Setup const string host = "192.168.5.55"; @@ -315,7 +195,7 @@ public void Get_Categories_Success_Passed_Values() const string username = "admin"; const string password = "pass"; - + 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")) @@ -330,32 +210,11 @@ public void Get_Categories_Success_Passed_Values() } [Test] - public void Get_Categories_Success_Config_Values() + public void should_be_able_to_get_categories_using_config() { - //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 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")); + .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(); @@ -368,8 +227,6 @@ public void Get_Categories_Success_Config_Values() [Test] public void GetQueue_should_return_an_empty_list_when_the_queue_is_empty() { - WithSabConfigValues(); - Mocker.GetMock() .Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=queue&output=json&start=0&limit=0&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass")) .Returns(File.ReadAllText(@".\Files\QueueEmpty.txt")); @@ -382,43 +239,30 @@ public void GetQueue_should_return_an_empty_list_when_the_queue_is_empty() } [Test] - [ExpectedException(typeof(ApplicationException), ExpectedMessage = "API Key Incorrect")] public void GetQueue_should_return_an_empty_list_when_there_is_an_error_getting_the_queue() { - WithSabConfigValues(); - Mocker.GetMock() .Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=queue&output=json&start=0&limit=0&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass")) .Returns(File.ReadAllText(@".\Files\JsonError.txt")); //Act - var result = Mocker.Resolve().GetQueue(); - - //Assert - result.Should().BeEmpty(); + Assert.Throws(() => Mocker.Resolve().GetQueue(), "API Key Incorrect"); } [Test] public void GetQueue_should_return_a_list_with_items_when_the_queue_has_items() { - WithSabConfigValues(); - - Mocker.GetMock() - .Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=queue&output=json&start=0&limit=0&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass")) - .Returns(File.ReadAllText(@".\Files\Queue.txt")); - + WithFullQueue(); //Act var result = Mocker.Resolve().GetQueue(); //Assert - result.Should().HaveCount(2); + result.Should().HaveCount(3); } [Test] public void GetHistory_should_return_a_list_with_items_when_the_history_has_items() { - WithSabConfigValues(); - Mocker.GetMock() .Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=history&output=json&start=0&limit=0&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass")) .Returns(File.ReadAllText(@".\Files\History.txt")); @@ -433,8 +277,6 @@ public void GetHistory_should_return_a_list_with_items_when_the_history_has_item [Test] public void GetHistory_should_return_an_empty_list_when_the_queue_is_empty() { - WithSabConfigValues(); - Mocker.GetMock() .Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=history&output=json&start=0&limit=0&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass")) .Returns(File.ReadAllText(@".\Files\HistoryEmpty.txt")); @@ -447,20 +289,82 @@ public void GetHistory_should_return_an_empty_list_when_the_queue_is_empty() } [Test] - [ExpectedException(typeof(ApplicationException), ExpectedMessage = "API Key Incorrect")] public void GetHistory_should_return_an_empty_list_when_there_is_an_error_getting_the_queue() { - WithSabConfigValues(); - Mocker.GetMock() .Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=history&output=json&start=0&limit=0&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass")) .Returns(File.ReadAllText(@".\Files\JsonError.txt")); //Act - var result = Mocker.Resolve().GetHistory(); - - //Assert - result.Should().BeEmpty(); + Assert.Throws(() => Mocker.Resolve().GetHistory(), "API Key Incorrect"); } + + [Test] + public void is_in_queue_should_find_if_exact_episode_is_in_queue() + { + WithFullQueue(); + + var parseResult = new EpisodeParseResult + { + EpisodeTitle = "Title", + EpisodeNumbers = new List { 5 }, + SeasonNumber = 1, + Quality = new Quality { QualityType = QualityTypes.SDTV, Proper = false }, + Series = new Series { Title = "30 Rock" }, + }; + + + var result = Mocker.Resolve().IsInQueue(parseResult); + + result.Should().BeTrue(); + } + + [TestCase(2, 5, "30 Rock", QualityTypes.Bluray1080p, true, Description = "Same Series, Diffrent Season, Episode")] + [TestCase(1, 6, "30 Rock", QualityTypes.Bluray1080p, true, Description = "Same series, diffrent episode")] + [TestCase(1, 6, "Some other show", QualityTypes.Bluray1080p, true, Description = "Diffrent series, same season, episdoe")] + [TestCase(1, 5, "Rock", QualityTypes.Bluray1080p, true, Description = "Similar series, same season, episode")] + [TestCase(1, 5, "30 Rock", QualityTypes.Bluray720p, false, Description = "Same series, higher quality")] + [TestCase(1, 5, "30 Rock", QualityTypes.HDTV, true, Description = "Same series, higher quality")] + public void IsInQueue_should_not_find_diffrent_episode_queue(int season, int episode, string title, QualityTypes qualityType, bool proper) + { + WithFullQueue(); + + var parseResult = new EpisodeParseResult + { + EpisodeTitle = "Title", + EpisodeNumbers = new List { episode }, + SeasonNumber = season, + Quality = new Quality { QualityType = qualityType, Proper = proper }, + Series = new Series { Title = title }, + }; + + var result = Mocker.Resolve().IsInQueue(parseResult); + + result.Should().BeFalse(); + } + + [TestCase(1, 5, "30 Rock", QualityTypes.SDTV, false, Description = "Same Series, lower quality")] + [TestCase(1, 5, "30 rocK", QualityTypes.SDTV, false, Description = "Same Series, diffrent casing")] + [TestCase(1, 5, "30 RocK", QualityTypes.HDTV, false, Description = "Same Series, same quality")] + public void IsInQueue_should_find_same_or_lower_quality_episode_queue(int season, int episode, string title, QualityTypes qualityType, bool proper) + { + WithFullQueue(); + + var parseResult = new EpisodeParseResult + { + EpisodeTitle = "Title", + EpisodeNumbers = new List { episode }, + SeasonNumber = season, + Quality = new Quality { QualityType = qualityType, Proper = proper }, + Series = new Series { Title = title }, + }; + + var result = Mocker.Resolve().IsInQueue(parseResult); + + result.Should().BeTrue(); + } + + + } } \ No newline at end of file diff --git a/NzbDrone.Core/Model/EpisodeParseResult.cs b/NzbDrone.Core/Model/EpisodeParseResult.cs index a0de81236..fcd514a24 100644 --- a/NzbDrone.Core/Model/EpisodeParseResult.cs +++ b/NzbDrone.Core/Model/EpisodeParseResult.cs @@ -6,15 +6,22 @@ namespace NzbDrone.Core.Model { public class EpisodeParseResult { - internal string CleanTitle { get; set; } + public string SeriesTitle { get; set; } + public string CleanTitle + { + get + { + return Parser.NormalizeTitle(SeriesTitle); + } + } public string EpisodeTitle { get; set; } - internal int SeasonNumber { get; set; } + public int SeasonNumber { get; set; } - internal List EpisodeNumbers { get; set; } + public List EpisodeNumbers { get; set; } - internal DateTime? AirDate { get; set; } + public DateTime? AirDate { get; set; } public Quality Quality { get; set; } @@ -35,10 +42,10 @@ public class EpisodeParseResult public override string ToString() { if (AirDate != null && EpisodeNumbers == null) - return string.Format("{0} - {1} {2}", CleanTitle, AirDate.Value.ToShortDateString(), Quality); + return string.Format("{0} - {1} {2}", SeriesTitle, AirDate.Value.ToShortDateString(), Quality); if (EpisodeNumbers != null) - return string.Format("{0} - S{1:00}E{2} {3}", CleanTitle, SeasonNumber, + return string.Format("{0} - S{1:00}E{2} {3}", SeriesTitle, SeasonNumber, String.Join("-", EpisodeNumbers), Quality); return NzbTitle; diff --git a/NzbDrone.Core/Model/Sabnzbd/SabHistoryItem.cs b/NzbDrone.Core/Model/Sabnzbd/SabHistoryItem.cs index 306dba60d..87f8f1eda 100644 --- a/NzbDrone.Core/Model/Sabnzbd/SabHistoryItem.cs +++ b/NzbDrone.Core/Model/Sabnzbd/SabHistoryItem.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Linq; using Newtonsoft.Json; namespace NzbDrone.Core.Model.Sabnzbd diff --git a/NzbDrone.Core/Model/Sabnzbd/SabQueueItem.cs b/NzbDrone.Core/Model/Sabnzbd/SabQueueItem.cs index c0e4aa456..773b36f8d 100644 --- a/NzbDrone.Core/Model/Sabnzbd/SabQueueItem.cs +++ b/NzbDrone.Core/Model/Sabnzbd/SabQueueItem.cs @@ -15,8 +15,18 @@ public class SabQueueItem [JsonProperty(PropertyName = "mb")] public decimal Size { get; set; } + private string _title; + [JsonProperty(PropertyName = "filename")] - public string Title { get; set; } + public string Title + { + get { return _title; } + set + { + _title = value; + ParseResult = Parser.ParseTitle(value); + } + } public SabPriorityType Priority { get; set; } @@ -30,5 +40,7 @@ public class SabQueueItem [JsonProperty(PropertyName = "nzo_id")] public string Id { get; set; } + + public EpisodeParseResult ParseResult { private set; get; } } } diff --git a/NzbDrone.Core/Parser.cs b/NzbDrone.Core/Parser.cs index 800d2c0fc..b16a76ffd 100644 --- a/NzbDrone.Core/Parser.cs +++ b/NzbDrone.Core/Parser.cs @@ -117,7 +117,7 @@ internal static EpisodeParseResult ParseTitle(string title) private static EpisodeParseResult ParseMatchCollection(MatchCollection matchCollection) { - var seriesName = NormalizeTitle(matchCollection[0].Groups["title"].Value); + var seriesName = matchCollection[0].Groups["title"].Value; int airyear; Int32.TryParse(matchCollection[0].Groups["airyear"].Value, out airyear); @@ -184,7 +184,7 @@ private static EpisodeParseResult ParseMatchCollection(MatchCollection matchColl }; } - parsedEpisode.CleanTitle = seriesName; + parsedEpisode.SeriesTitle = seriesName; Logger.Trace("Episode Parsed. {0}", parsedEpisode); @@ -307,7 +307,15 @@ internal static Quality ParseQuality(string name) } } - if ((normalizedName.Contains("sdtv") || (result.QualityType == QualityTypes.Unknown && normalizedName.Contains("hdtv"))) && !normalizedName.Contains("mpeg")) + if (name.Contains("[HDTV]")) + { + result.QualityType = QualityTypes.HDTV; + return result; + } + + if ((normalizedName.Contains("sdtv") || + (result.QualityType == QualityTypes.Unknown && normalizedName.Contains("hdtv"))) && + !normalizedName.Contains("mpeg")) { result.QualityType = QualityTypes.SDTV; return result; diff --git a/NzbDrone.Core/Providers/DiskScanProvider.cs b/NzbDrone.Core/Providers/DiskScanProvider.cs index 2362d14c7..3430731a5 100644 --- a/NzbDrone.Core/Providers/DiskScanProvider.cs +++ b/NzbDrone.Core/Providers/DiskScanProvider.cs @@ -115,7 +115,7 @@ public virtual EpisodeFile ImportFile(Series series, string filePath) if (parseResult == null) return null; - parseResult.CleanTitle = series.Title; //replaces the nasty path as title to help with logging + parseResult.SeriesTitle = series.Title; //replaces the nasty path as title to help with logging parseResult.Series = series; var episodes = _episodeProvider.GetEpisodesByParseResult(parseResult); diff --git a/NzbDrone.Core/Providers/DownloadProvider.cs b/NzbDrone.Core/Providers/DownloadProvider.cs index e4abe5342..fb877aa19 100644 --- a/NzbDrone.Core/Providers/DownloadProvider.cs +++ b/NzbDrone.Core/Providers/DownloadProvider.cs @@ -31,14 +31,13 @@ public DownloadProvider() public virtual bool DownloadReport(EpisodeParseResult parseResult) { - var sabTitle = _sabProvider.GetSabTitle(parseResult); - - if (_sabProvider.IsInQueue(sabTitle)) + if (_sabProvider.IsInQueue(parseResult)) { Logger.Warn("Episode {0} is already in sab's queue. skipping.", parseResult); return false; } + var sabTitle = _sabProvider.GetSabTitle(parseResult); var addSuccess = _sabProvider.AddByUrl(parseResult.NzbUrl, sabTitle); if (addSuccess) diff --git a/NzbDrone.Core/Providers/InventoryProvider.cs b/NzbDrone.Core/Providers/InventoryProvider.cs index b4506b2e8..c2cf90f8c 100644 --- a/NzbDrone.Core/Providers/InventoryProvider.cs +++ b/NzbDrone.Core/Providers/InventoryProvider.cs @@ -187,14 +187,11 @@ public virtual bool IsUpgradePossible(Episode episode) { //Used to check if the existing episode can be upgraded by searching (Before we search) - //If no episode file exists on disk, then an upgrade is possible if (episode.EpisodeFileId == 0) return true; - //Get the quality profile for the series var profile = _qualityProvider.Get(episode.Series.QualityProfileId); - //If the current episode file meets or exceeds the cutoff, do not attempt upgrade if (episode.EpisodeFile.Quality >= profile.Cutoff) return false; diff --git a/NzbDrone.Core/Providers/SabProvider.cs b/NzbDrone.Core/Providers/SabProvider.cs index 55a040bf0..4120b2881 100644 --- a/NzbDrone.Core/Providers/SabProvider.cs +++ b/NzbDrone.Core/Providers/SabProvider.cs @@ -1,10 +1,8 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Web; -using System.Web.Script.Serialization; using System.Xml.Linq; using Newtonsoft.Json; using Ninject; @@ -12,7 +10,6 @@ using NzbDrone.Core.Model; using NzbDrone.Core.Model.Sabnzbd; using NzbDrone.Core.Providers.Core; -using NzbDrone.Core.Repository.Quality; namespace NzbDrone.Core.Providers { @@ -75,35 +72,14 @@ private static string GetNzbName(string urlString) return urlString.Replace("&", "%26"); } - public virtual bool IsInQueue(string title) + public virtual bool IsInQueue(EpisodeParseResult newParseResult) { - const string action = "mode=queue&output=xml"; - string request = GetSabRequest(action); - string response = _httpProvider.DownloadString(request); + var queue = GetQueue(); - XDocument xDoc = XDocument.Parse(response); - - //If an Error Occurred, return) - if (xDoc.Descendants("error").Count() != 0) - throw new ApplicationException(xDoc.Descendants("error").FirstOrDefault().Value); - - if (xDoc.Descendants("queue").Count() == 0) - { - Logger.Debug("SAB Queue is empty. retiring false"); - return false; - } - //Get the Count of Items in Queue where 'filename' is Equal to goodName, if not zero, return true (isInQueue))) - if ( - (xDoc.Descendants("slot").Where( - s => s.Element("filename").Value.Equals(title, StringComparison.InvariantCultureIgnoreCase))).Count() != - 0) - { - Logger.Debug("Episode in queue - '{0}'", title); - - return true; - } - - return false; //Not in Queue + return queue.Any(c => String.Equals(c.ParseResult.SeriesTitle, newParseResult.Series.Title, StringComparison.InvariantCultureIgnoreCase) && + c.ParseResult.EpisodeNumbers.SequenceEqual(newParseResult.EpisodeNumbers) && + c.ParseResult.SeasonNumber == newParseResult.SeasonNumber && + c.ParseResult.Quality >= newParseResult.Quality); } public virtual List GetQueue(int start = 0, int limit = 0) @@ -133,7 +109,7 @@ public virtual String GetSabTitle(EpisodeParseResult parseResult) //Handle Full Naming if (parseResult.FullSeason) { - var seasonResult = String.Format("{0} - Season {1} [{2}]", MediaFileProvider.CleanFilename(parseResult.Series.Title), + var seasonResult = String.Format("{0} - Season {1} [{2}]", GetSabSeriesName(parseResult), parseResult.SeasonNumber, parseResult.Quality.QualityType); if (parseResult.Quality.Proper) @@ -144,7 +120,7 @@ public virtual String GetSabTitle(EpisodeParseResult parseResult) if (parseResult.Series.IsDaily) { - var dailyResult = String.Format("{0} - {1:yyyy-MM-dd} - {2} [{3}]", MediaFileProvider.CleanFilename(parseResult.Series.Title), + var dailyResult = String.Format("{0} - {1:yyyy-MM-dd} - {2} [{3}]", GetSabSeriesName(parseResult), parseResult.AirDate, parseResult.EpisodeTitle, parseResult.Quality.QualityType); if (parseResult.Quality.Proper) @@ -164,7 +140,7 @@ public virtual String GetSabTitle(EpisodeParseResult parseResult) var epNumberString = String.Join("-", episodeString); - var result = String.Format("{0} - {1} - {2} [{3}]", MediaFileProvider.CleanFilename(parseResult.Series.Title), epNumberString, parseResult.EpisodeTitle, parseResult.Quality.QualityType); + var result = String.Format("{0} - {1} - {2} [{3}]", GetSabSeriesName(parseResult), epNumberString, parseResult.EpisodeTitle, parseResult.Quality.QualityType); if (parseResult.Quality.Proper) { @@ -174,6 +150,11 @@ public virtual String GetSabTitle(EpisodeParseResult parseResult) return result; } + private static string GetSabSeriesName(EpisodeParseResult parseResult) + { + return MediaFileProvider.CleanFilename(parseResult.Series.Title); + } + public virtual SabCategoryModel 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 @@ -200,11 +181,11 @@ public virtual SabCategoryModel GetCategories(string host = null, int port = 0, var response = _httpProvider.DownloadString(command); if (String.IsNullOrWhiteSpace(response)) - return new SabCategoryModel{categories = new List()}; + return new SabCategoryModel { categories = new List() }; - var deserialized = JsonConvert.DeserializeObject(response); + var categories = JsonConvert.DeserializeObject(response); - return deserialized; + return categories; } private string GetSabRequest(string action) @@ -221,7 +202,7 @@ private string GetSabRequest(string action) private void CheckForError(string response) { var result = JsonConvert.DeserializeObject(response); - + if (result.Status.Equals("false", StringComparison.InvariantCultureIgnoreCase)) throw new ApplicationException(result.Error); }