diff --git a/src/NzbDrone.Core.Test/DataAugmentation/Scene/SceneMappingServiceFixture.cs b/src/NzbDrone.Core.Test/DataAugmentation/Scene/SceneMappingServiceFixture.cs index ba4f2cba7..063365886 100644 --- a/src/NzbDrone.Core.Test/DataAugmentation/Scene/SceneMappingServiceFixture.cs +++ b/src/NzbDrone.Core.Test/DataAugmentation/Scene/SceneMappingServiceFixture.cs @@ -177,6 +177,31 @@ namespace NzbDrone.Core.Test.DataAugmentation.Scene ExceptionVerification.ExpectedWarns(1); } + + [TestCase("Working!!", "Working!!", 1)] + [TestCase("Working`!!", "Working`!!", 2)] + [TestCase("Working!!!", "Working!!!", 3)] + [TestCase("Working!!!!", "Working!!!", 3)] + [TestCase("Working !!", "Working!!", 1)] + public void should_return_single_match(string parseTitle, string title, int expectedSeasonNumber) + { + var mappings = new List + { + new SceneMapping { Title = "Working!!", ParseTerm = "working", SearchTerm = "Working!!", TvdbId = 100, SeasonNumber = -1 }, + new SceneMapping { Title = "Working!!", ParseTerm = "working", SearchTerm = "Working!!", TvdbId = 100, SeasonNumber = 1 }, + new SceneMapping { Title = "Working`!!", ParseTerm = "working", SearchTerm = "Working`!!", TvdbId = 100, SeasonNumber = 2 }, + new SceneMapping { Title = "Working!!!", ParseTerm = "working", SearchTerm = "Working!!!", TvdbId = 100, SeasonNumber = 3 }, + }; + + Mocker.GetMock().Setup(c => c.All()).Returns(mappings); + + var tvdbId = Subject.FindTvDbId(parseTitle); + var seasonNumber = Subject.GetSeasonNumber(parseTitle); + + tvdbId.Should().Be(100); + seasonNumber.Should().Be(expectedSeasonNumber); + } + private void AssertNoUpdate() { _provider1.Verify(c => c.GetSceneMappings(), Times.Once()); diff --git a/src/NzbDrone.Core.Test/ParserTests/AbsoluteEpisodeNumberParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/AbsoluteEpisodeNumberParserFixture.cs index 4576499a0..d280a51cf 100644 --- a/src/NzbDrone.Core.Test/ParserTests/AbsoluteEpisodeNumberParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/AbsoluteEpisodeNumberParserFixture.cs @@ -13,13 +13,13 @@ namespace NzbDrone.Core.Test.ParserTests { [TestCase("[SubDESU]_High_School_DxD_07_(1280x720_x264-AAC)_[6B7FD717]", "High School DxD", 7, 0, 0)] [TestCase("[Chihiro]_Working!!_-_06_[848x480_H.264_AAC][859EEAFA]", "Working!!", 6, 0, 0)] - [TestCase("[Commie]_Senki_Zesshou_Symphogear_-_11_[65F220B4]", "Senki_Zesshou_Symphogear", 11, 0, 0)] - [TestCase("[Underwater]_Rinne_no_Lagrange_-_12_(720p)_[5C7BC4F9]", "Rinne_no_Lagrange", 12, 0, 0)] - [TestCase("[Commie]_Rinne_no_Lagrange_-_15_[E76552EA]", "Rinne_no_Lagrange", 15, 0, 0)] - [TestCase("[HorribleSubs]_Hunter_X_Hunter_-_33_[720p]", "Hunter_X_Hunter", 33, 0, 0)] - [TestCase("[HorribleSubs]_Fairy_Tail_-_145_[720p]", "Fairy_Tail", 145, 0, 0)] + [TestCase("[Commie]_Senki_Zesshou_Symphogear_-_11_[65F220B4]", "Senki Zesshou Symphogear", 11, 0, 0)] + [TestCase("[Underwater]_Rinne_no_Lagrange_-_12_(720p)_[5C7BC4F9]", "Rinne no Lagrange", 12, 0, 0)] + [TestCase("[Commie]_Rinne_no_Lagrange_-_15_[E76552EA]", "Rinne no Lagrange", 15, 0, 0)] + [TestCase("[HorribleSubs]_Hunter_X_Hunter_-_33_[720p]", "Hunter X Hunter", 33, 0, 0)] + [TestCase("[HorribleSubs]_Fairy_Tail_-_145_[720p]", "Fairy Tail", 145, 0, 0)] [TestCase("[HorribleSubs] Tonari no Kaibutsu-kun - 13 [1080p].mkv", "Tonari no Kaibutsu-kun", 13, 0, 0)] - [TestCase("[Doremi].Yes.Pretty.Cure.5.Go.Go!.31.[1280x720].[C65D4B1F].mkv", "Yes.Pretty.Cure.5.Go.Go!", 31, 0, 0)] + [TestCase("[Doremi].Yes.Pretty.Cure.5.Go.Go!.31.[1280x720].[C65D4B1F].mkv", "Yes Pretty Cure 5 Go Go!", 31, 0, 0)] [TestCase("[K-F] One Piece 214", "One Piece", 214, 0, 0)] [TestCase("[K-F] One Piece S10E14 214", "One Piece", 214, 10, 14)] [TestCase("[K-F] One Piece 10x14 214", "One Piece", 214, 10, 14)] @@ -32,14 +32,14 @@ namespace NzbDrone.Core.Test.ParserTests [TestCase("Bleach - 031 - The Resolution to Kill [Lunar]", "Bleach", 31, 0, 0)] [TestCase("[ACX]Hack Sign 01 Role Play [Kosaka] [9C57891E].mkv", "Hack Sign", 1, 0, 0)] [TestCase("[SFW-sage] Bakuman S3 - 12 [720p][D07C91FC]", "Bakuman S3", 12, 0, 0)] - [TestCase("ducktales_e66_time_is_money_part_one_marking_time", "DuckTales", 66, 0, 0)] + [TestCase("ducktales_e66_time_is_money_part_one_marking_time", "ducktales", 66, 0, 0)] [TestCase("[Underwater-FFF] No Game No Life - 01 (720p) [27AAA0A0].mkv", "No Game No Life", 1, 0, 0)] [TestCase("[FroZen] Miyuki - 23 [DVD][7F6170E6]", "Miyuki", 23, 0, 0)] [TestCase("[Commie] Yowamushi Pedal - 32 [0BA19D5B]", "Yowamushi Pedal", 32, 0, 0)] [TestCase("[Doki] Mahouka Koukou no Rettousei - 07 (1280x720 Hi10P AAC) [80AF7DDE]", "Mahouka Koukou no Rettousei", 7, 0, 0)] [TestCase("[HorribleSubs] Yowamushi Pedal - 32 [480p]", "Yowamushi Pedal", 32, 0, 0)] [TestCase("[CR] Sailor Moon - 004 [480p][48CE2D0F]", "Sailor Moon", 4, 0, 0)] - [TestCase("[Chibiki] Puchimas!! - 42 [360p][7A4FC77B]", "Puchimas", 42, 0, 0)] + [TestCase("[Chibiki] Puchimas!! - 42 [360p][7A4FC77B]", "Puchimas!!", 42, 0, 0)] [TestCase("[HorribleSubs] Yowamushi Pedal - 32 [1080p]", "Yowamushi Pedal", 32, 0, 0)] [TestCase("[HorribleSubs] Love Live! S2 - 07 [720p]", "Love Live! S2", 7, 0, 0)] [TestCase("[DeadFish] Onee-chan ga Kita - 09v2 [720p][AAC]", "Onee-chan ga Kita", 9, 0, 0)] @@ -54,22 +54,22 @@ namespace NzbDrone.Core.Test.ParserTests [TestCase("Initial D Fifth Stage - 14 DVD - Central Anime", "Initial D Fifth Stage", 14, 0, 0)] [TestCase("Initial_D_Fifth_Stage_-_14(DVD)_-_(Central_Anime)[0183D922].mkv", "Initial D Fifth Stage", 14, 0, 0)] // [TestCase("Initial D - 4th Stage Ep 01.mkv", "Initial D - 4th Stage", 1, 0, 0)] - [TestCase("[ChihiroDesuYo].No.Game.No.Life.-.09.1280x720.10bit.AAC.[24CCE81D]", "No.Game.No.Life", 9, 0, 0)] + [TestCase("[ChihiroDesuYo].No.Game.No.Life.-.09.1280x720.10bit.AAC.[24CCE81D]", "No Game No Life", 9, 0, 0)] [TestCase("Fairy Tail - 001 - Fairy Tail", "Fairy Tail", 001, 0, 0)] [TestCase("Fairy Tail - 049 - The Day of Fated Meeting", "Fairy Tail", 049, 0, 0)] [TestCase("Fairy Tail - 050 - Special Request Watch Out for the Guy You Like!", "Fairy Tail", 050, 0, 0)] [TestCase("Fairy Tail - 099 - Natsu vs. Gildarts", "Fairy Tail", 099, 0, 0)] [TestCase("Fairy Tail - 100 - Mest", "Fairy Tail", 100, 0, 0)] // [TestCase("Fairy Tail - 101 - Mest", "Fairy Tail", 101, 0, 0)] //This gets caught up in the 'see' numbering - [TestCase("[Exiled-Destiny] Angel Beats Ep01 (D2201EC5).mkv", "Angel Beats!", 1, 0, 0)] + [TestCase("[Exiled-Destiny] Angel Beats Ep01 (D2201EC5).mkv", "Angel Beats", 1, 0, 0)] [TestCase("[Commie] Nobunaga the Fool - 23 [5396CA24].mkv", "Nobunaga the Fool", 23, 0, 0)] [TestCase("[FFF] Seikoku no Dragonar - 01 [1FB538B5].mkv", "Seikoku no Dragonar", 1, 0, 0)] - [TestCase("[Hatsuyuki]Fate_Zero-01[1280x720][122E6EF8]", "Fate/Zero", 1, 0, 0)] + [TestCase("[Hatsuyuki]Fate_Zero-01[1280x720][122E6EF8]", "Fate Zero", 1, 0, 0)] [TestCase("[CBM]_Monster_-_11_-_511_Kinderheim_[6C70C4E4].mkv", "Monster", 11, 0, 0)] [TestCase("[HorribleSubs] Log Horizon 2 - 05 [720p].mkv", "Log Horizon 2", 5, 0, 0)] [TestCase("[Commie] Log Horizon 2 - 05 [FCE4D070].mkv", "Log Horizon 2", 5, 0, 0)] [TestCase("[DRONE]Series.Title.100", "Series Title", 100, 0, 0)] - [TestCase("[RlsGrp]Series.Title.2010.S01E01.001.HDTV-720p.x264-DTS", "Series.Title.2010", 1, 1, 1)] + [TestCase("[RlsGrp]Series.Title.2010.S01E01.001.HDTV-720p.x264-DTS", "Series Title 2010", 1, 1, 1)] [TestCase("Dragon Ball Kai - 130 - Found You, Gohan! Harsh Training in the Kaioshin Realm! [Baaro][720p][5A1AD35B].mkv", "Dragon Ball Kai", 130, 0, 0)] [TestCase("Dragon Ball Kai - 131 - A Merged Super-Warrior Is Born, His Name Is Gotenks!! [Baaro][720p][32E03F96].mkv", "Dragon Ball Kai", 131, 0, 0)] [TestCase("[HorribleSubs] Magic Kaito 1412 - 01 [1080p]", "Magic Kaito 1412", 1, 0, 0)] @@ -78,9 +78,9 @@ namespace NzbDrone.Core.Test.ParserTests [TestCase("Knights of Sidonia - 01 [1080p 10b DTSHD-MA eng sub].mkv", "Knights of Sidonia", 1, 0, 0)] [TestCase("Series Title (2010) {01} Episode Title (1).hdtv-720p", "Series Title (2010)", 1, 0, 0)] [TestCase("[HorribleSubs] Shirobako - 20 [720p].mkv", "Shirobako", 20, 0, 0)] - [TestCase("[Hatsuyuki] Dragon Ball Kai (2014) - 017 (115) [1280x720][B2CFBC0F]", "Dragon Ball Kai 2014", 17, 0, 0)] - [TestCase("[Hatsuyuki] Dragon Ball Kai (2014) - 018 (116) [1280x720][C4A3B16E]", "Dragon Ball Kai 2014", 18, 0, 0)] - [TestCase("Dragon Ball Kai (2014) - 39 (137) [v2][720p.HDTV][Unison Fansub]", "Dragon Ball Kai 2014", 39, 0, 0)] + [TestCase("[Hatsuyuki] Dragon Ball Kai (2014) - 017 (115) [1280x720][B2CFBC0F]", "Dragon Ball Kai (2014)", 17, 0, 0)] + [TestCase("[Hatsuyuki] Dragon Ball Kai (2014) - 018 (116) [1280x720][C4A3B16E]", "Dragon Ball Kai (2014)", 18, 0, 0)] + [TestCase("Dragon Ball Kai (2014) - 39 (137) [v2][720p.HDTV][Unison Fansub]", "Dragon Ball Kai (2014)", 39, 0, 0)] [TestCase("[HorribleSubs] Eyeshield 21 - 101 [480p].mkv", "Eyeshield 21", 101, 0, 0)] //[TestCase("", "", 0, 0, 0)] public void should_parse_absolute_numbers(string postTitle, string title, int absoluteEpisodeNumber, int seasonNumber, int episodeNumber) @@ -90,7 +90,7 @@ namespace NzbDrone.Core.Test.ParserTests result.AbsoluteEpisodeNumbers.Single().Should().Be(absoluteEpisodeNumber); result.SeasonNumber.Should().Be(seasonNumber); result.EpisodeNumbers.SingleOrDefault().Should().Be(episodeNumber); - result.SeriesTitle.Should().Be(title.CleanSeriesTitle()); + result.SeriesTitle.Should().Be(title); result.FullSeason.Should().BeFalse(); } @@ -104,7 +104,7 @@ namespace NzbDrone.Core.Test.ParserTests result.AbsoluteEpisodeNumbers.Single().Should().Be(absoluteEpisodeNumber); result.SeasonNumber.Should().Be(0); result.EpisodeNumbers.SingleOrDefault().Should().Be(0); - result.SeriesTitle.Should().Be(title.CleanSeriesTitle()); + result.SeriesTitle.Should().Be(title); result.FullSeason.Should().BeFalse(); result.Special.Should().BeTrue(); } @@ -119,7 +119,7 @@ namespace NzbDrone.Core.Test.ParserTests var result = Parser.Parser.ParseTitle(postTitle); result.Should().NotBeNull(); result.AbsoluteEpisodeNumbers.Should().BeEquivalentTo(absoluteEpisodeNumbers); - result.SeriesTitle.Should().Be(title.CleanSeriesTitle()); + result.SeriesTitle.Should().Be(title); result.FullSeason.Should().BeFalse(); } } diff --git a/src/NzbDrone.Core.Test/ParserTests/DailyEpisodeParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/DailyEpisodeParserFixture.cs index 8a9724dd1..47a4ac6d8 100644 --- a/src/NzbDrone.Core.Test/ParserTests/DailyEpisodeParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/DailyEpisodeParserFixture.cs @@ -14,14 +14,14 @@ namespace NzbDrone.Core.Test.ParserTests { [TestCase("Conan 2011 04 18 Emma Roberts HDTV XviD BFF", "Conan", 2011, 04, 18)] [TestCase("The Tonight Show With Jay Leno 2011 04 15 1080i HDTV DD5 1 MPEG2 TrollHD", "The Tonight Show With Jay Leno", 2011, 04, 15)] - [TestCase("The.Daily.Show.2010.10.11.Johnny.Knoxville.iTouch-MW", "The.Daily.Show", 2010, 10, 11)] - [TestCase("The Daily Show - 2011-04-12 - Gov. Deval Patrick", "The.Daily.Show", 2011, 04, 12)] + [TestCase("The.Daily.Show.2010.10.11.Johnny.Knoxville.iTouch-MW", "The Daily Show", 2010, 10, 11)] + [TestCase("The Daily Show - 2011-04-12 - Gov. Deval Patrick", "The Daily Show", 2011, 04, 12)] [TestCase("2011.01.10 - Denis Leary - HD TV.mkv", "", 2011, 1, 10)] [TestCase("2011.03.13 - Denis Leary - HD TV.mkv", "", 2011, 3, 13)] [TestCase("The Tonight Show with Jay Leno - 2011-06-16 - Larry David, \"Bachelorette\" Ashley Hebert, Pitbull with Ne-Yo", "The Tonight Show with Jay Leno", 2011, 6, 16)] - [TestCase("2020.NZ.2012.16.02.PDTV.XviD-C4TV", "2020nz", 2012, 2, 16)] - [TestCase("2020.NZ.2012.13.02.PDTV.XviD-C4TV", "2020nz", 2012, 2, 13)] - [TestCase("2020.NZ.2011.12.02.PDTV.XviD-C4TV", "2020nz", 2011, 12, 2)] + [TestCase("2020.NZ.2012.16.02.PDTV.XviD-C4TV", "2020 NZ", 2012, 2, 16)] + [TestCase("2020.NZ.2012.13.02.PDTV.XviD-C4TV", "2020 NZ", 2012, 2, 13)] + [TestCase("2020.NZ.2011.12.02.PDTV.XviD-C4TV", "2020 NZ", 2011, 12, 2)] [TestCase("Series Title - 2013-10-30 - Episode Title (1) [HDTV-720p]", "Series Title", 2013, 10, 30)] [TestCase("The_Voice_US_04.28.2014_hdtv.x264.Poke.mp4", "The Voice US", 2014, 4, 28)] [TestCase("At.Midnight.140722.720p.HDTV.x264-YesTV", "At Midnight", 2014, 07, 22)] @@ -34,7 +34,7 @@ namespace NzbDrone.Core.Test.ParserTests var result = Parser.Parser.ParseTitle(postTitle); var airDate = new DateTime(year, month, day); result.Should().NotBeNull(); - result.SeriesTitle.Should().Be(title.CleanSeriesTitle()); + result.SeriesTitle.Should().Be(title); result.AirDate.Should().Be(airDate.ToString(Episode.AIR_DATE_FORMAT)); result.EpisodeNumbers.Should().BeEmpty(); result.AbsoluteEpisodeNumbers.Should().BeEmpty(); diff --git a/src/NzbDrone.Core.Test/ParserTests/HashedReleaseFixture.cs b/src/NzbDrone.Core.Test/ParserTests/HashedReleaseFixture.cs index 70cbe3328..556a14fe8 100644 --- a/src/NzbDrone.Core.Test/ParserTests/HashedReleaseFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/HashedReleaseFixture.cs @@ -14,70 +14,70 @@ namespace NzbDrone.Core.Test.ParserTests new object[] { @"C:\Test\Some.Hashed.Release.S01E01.720p.WEB-DL.AAC2.0.H.264-Mercury\0e895c37245186812cb08aab1529cf8ee389dd05.mkv".AsOsAgnostic(), - "somehashedrelease", + "Some Hashed Release", Quality.WEBDL720p, "Mercury" }, new object[] { @"C:\Test\0e895c37245186812cb08aab1529cf8ee389dd05\Some.Hashed.Release.S01E01.720p.WEB-DL.AAC2.0.H.264-Mercury.mkv".AsOsAgnostic(), - "somehashedrelease", + "Some Hashed Release", Quality.WEBDL720p, "Mercury" }, new object[] { @"C:\Test\Fake.Dir.S01E01-Test\yrucreM-462.H.0.2CAA.LD-BEW.p027.10E10S.esaeleR.dehsaH.emoS.mkv".AsOsAgnostic(), - "somehashedrelease", + "Some Hashed Release", Quality.WEBDL720p, "Mercury" }, new object[] { @"C:\Test\Fake.Dir.S01E01-Test\yrucreM-LN 1.5DD LD-BEW P0801 10E10S esaeleR dehsaH emoS.mkv".AsOsAgnostic(), - "somehashedrelease", + "Some Hashed Release", Quality.WEBDL1080p, "Mercury" }, new object[] { @"C:\Test\Weeds.S01E10.DVDRip.XviD-SONARR\AHFMZXGHEWD660.mkv".AsOsAgnostic(), - "weeds", + "Weeds", Quality.DVD, "SONARR" }, new object[] { @"C:\Test\Deadwood.S02E12.1080p.BluRay.x264-SONARR\Backup_72023S02-12.mkv".AsOsAgnostic(), - "deadwood", + "Deadwood", Quality.Bluray1080p, null }, new object[] { @"C:\Test\Grimm S04E08 Chupacabra 720p WEB-DL DD5 1 H 264-ECI\123.mkv".AsOsAgnostic(), - "grimm", + "Grimm", Quality.WEBDL720p, "ECI" }, new object[] { @"C:\Test\Grimm S04E08 Chupacabra 720p WEB-DL DD5 1 H 264-ECI\abc.mkv".AsOsAgnostic(), - "grimm", + "Grimm", Quality.WEBDL720p, "ECI" }, new object[] { @"C:\Test\Grimm S04E08 Chupacabra 720p WEB-DL DD5 1 H 264-ECI\b00bs.mkv".AsOsAgnostic(), - "grimm", + "Grimm", Quality.WEBDL720p, "ECI" }, new object[] { @"C:\Test\The.Good.Wife.S02E23.720p.HDTV.x264-NZBgeek/cgajsofuejsa501.mkv".AsOsAgnostic(), - "thegoodwife", + "The Good Wife", Quality.HDTV720p, "NZBgeek" } diff --git a/src/NzbDrone.Core.Test/ParserTests/MiniSeriesEpisodeParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/MiniSeriesEpisodeParserFixture.cs index 16d299f4a..4c69fbf41 100644 --- a/src/NzbDrone.Core.Test/ParserTests/MiniSeriesEpisodeParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/MiniSeriesEpisodeParserFixture.cs @@ -12,7 +12,7 @@ namespace NzbDrone.Core.Test.ParserTests public class MiniSeriesEpisodeParserFixture : CoreTest { [TestCase("The.Kennedys.Part.2.DSR.XviD-SYS", "The Kennedys", 2)] - [TestCase("the-pacific-e07-720p", "The Pacific", 7)] + [TestCase("the-pacific-e07-720p", "the-pacific", 7)] [TestCase("Hatfields and McCoys 2012 Part 1 REPACK 720p HDTV x264 2HD", "Hatfields and McCoys 2012", 1)] // [TestCase("Band.Of.Brothers.EP02.Day.Of.Days.DVDRiP.XviD-DEiTY", "Band.Of.Brothers", 2)] // [TestCase("", "", 0, 0)] @@ -23,7 +23,7 @@ namespace NzbDrone.Core.Test.ParserTests result.EpisodeNumbers.Should().HaveCount(1); result.SeasonNumber.Should().Be(1); result.EpisodeNumbers.First().Should().Be(episodeNumber); - result.SeriesTitle.Should().Be(title.CleanSeriesTitle()); + result.SeriesTitle.Should().Be(title); result.AbsoluteEpisodeNumbers.Should().BeEmpty(); result.FullSeason.Should().BeFalse(); } diff --git a/src/NzbDrone.Core.Test/ParserTests/MultiEpisodeParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/MultiEpisodeParserFixture.cs index b3c6bd8e9..7a3367169 100644 --- a/src/NzbDrone.Core.Test/ParserTests/MultiEpisodeParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/MultiEpisodeParserFixture.cs @@ -10,11 +10,11 @@ namespace NzbDrone.Core.Test.ParserTests public class MultiEpisodeParserFixture : CoreTest { [TestCase("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", "WEEDS", 3, new[] { 1, 2, 3, 4, 5, 6 })] - [TestCase("Two.and.a.Half.Men.103.104.720p.HDTV.X264-DIMENSION", "Two.and.a.Half.Men", 1, new[] { 3, 4 })] + [TestCase("Two.and.a.Half.Men.103.104.720p.HDTV.X264-DIMENSION", "Two and a Half Men", 1, new[] { 3, 4 })] [TestCase("Weeds.S03E01.S03E02.720p.HDTV.X264-DIMENSION", "Weeds", 3, new[] { 1, 2 })] [TestCase("The Borgias S01e01 e02 ShoHD On Demand 1080i DD5 1 ALANiS", "The Borgias", 1, new[] { 1, 2 })] - [TestCase("White.Collar.2x04.2x05.720p.BluRay-FUTV", "White.Collar", 2, new[] { 4, 5 })] - [TestCase("Desperate.Housewives.S07E22E23.720p.HDTV.X264-DIMENSION", "Desperate.Housewives", 7, new[] { 22, 23 })] + [TestCase("White.Collar.2x04.2x05.720p.BluRay-FUTV", "White Collar", 2, new[] { 4, 5 })] + [TestCase("Desperate.Housewives.S07E22E23.720p.HDTV.X264-DIMENSION", "Desperate Housewives", 7, new[] { 22, 23 })] [TestCase("Desparate Housewives - S07E22 - S07E23 - And Lots of Security.. [HDTV-720p].mkv", "Desparate Housewives", 7, new[] { 22, 23 })] [TestCase("S03E01.S03E02.720p.HDTV.X264-DIMENSION", "", 3, new[] { 1, 2 })] [TestCase("Desparate Housewives - S07E22 - 7x23 - And Lots of Security.. [HDTV-720p].mkv", "Desparate Housewives", 7, new[] { 22, 23 })] @@ -32,9 +32,9 @@ namespace NzbDrone.Core.Test.ParserTests [TestCase("Kaamelott.S01E91-E100", "Kaamelott", 1, new[] { 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 })] [TestCase("Neighbours.S29E161-E165.PDTV.x264-FQM", "Neighbours", 29, new[] { 161, 162, 163, 164, 165 })] [TestCase("Shortland.Street.S22E5363-E5366.HDTV.x264-FiHTV", "Shortland Street", 22, new[] { 5363, 5364, 5365, 5366 })] - [TestCase("the.office.101.102.hdtv-lol", "The Office", 1, new[] { 1, 2 })] - [TestCase("extant.10708.hdtv-lol.mp4", "Extant", 1, new[] { 7, 8 })] - [TestCase("extant.10910.hdtv-lol.mp4", "Extant", 1, new[] { 9, 10 })] + [TestCase("the.office.101.102.hdtv-lol", "the office", 1, new[] { 1, 2 })] + [TestCase("extant.10708.hdtv-lol.mp4", "extant", 1, new[] { 7, 8 })] + [TestCase("extant.10910.hdtv-lol.mp4", "extant", 1, new[] { 9, 10 })] [TestCase("E.010910.HDTVx264REPACKLOL.mp4", "E", 1, new[] { 9, 10 })] [TestCase("World Series of Poker - 2013x15 - 2013x16 - HD TV.mkv", "World Series of Poker", 2013, new[] { 15, 16 })] [TestCase("The Librarians US S01E01-E02 720p HDTV x264", "The Librarians US", 1, new [] { 1, 2 })] @@ -47,7 +47,7 @@ namespace NzbDrone.Core.Test.ParserTests var result = Parser.Parser.ParseTitle(postTitle); result.SeasonNumber.Should().Be(season); result.EpisodeNumbers.Should().BeEquivalentTo(episodes); - result.SeriesTitle.Should().Be(title.CleanSeriesTitle()); + result.SeriesTitle.Should().Be(title); result.AbsoluteEpisodeNumbers.Should().BeEmpty(); result.FullSeason.Should().BeFalse(); } diff --git a/src/NzbDrone.Core.Test/ParserTests/ParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/ParserFixture.cs index 42ae1f3e6..cf875d2ea 100644 --- a/src/NzbDrone.Core.Test/ParserTests/ParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/ParserFixture.cs @@ -39,7 +39,7 @@ namespace NzbDrone.Core.Test.ParserTests [TestCase("Seed S02E09 HDTV x264-2HD [eztv]-[rarbg.com]", "Seed")] public void should_parse_series_name(String postTitle, String title) { - var result = Parser.Parser.ParseSeriesName(postTitle); + var result = Parser.Parser.ParseSeriesName(postTitle).CleanSeriesTitle(); result.Should().Be(title.CleanSeriesTitle()); } @@ -60,7 +60,7 @@ namespace NzbDrone.Core.Test.ParserTests [TestCase("[scnzbefnet][509103] 2.Broke.Girls.S03E18.720p.HDTV.X264-DIMENSION", "2 Broke Girls")] public void should_remove_request_info_from_title(String postTitle, String title) { - Parser.Parser.ParseTitle(postTitle).SeriesTitle.Should().Be(title.CleanSeriesTitle()); + Parser.Parser.ParseTitle(postTitle).SeriesTitle.Should().Be(title); } } } diff --git a/src/NzbDrone.Core.Test/ParserTests/SeasonParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/SeasonParserFixture.cs index 75ef1ed58..9255b1999 100644 --- a/src/NzbDrone.Core.Test/ParserTests/SeasonParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/SeasonParserFixture.cs @@ -9,10 +9,10 @@ namespace NzbDrone.Core.Test.ParserTests [TestFixture] public class SeasonParserFixture : CoreTest { - [TestCase("30.Rock.Season.04.HDTV.XviD-DIMENSION", "30.Rock", 4)] - [TestCase("Parks.and.Recreation.S02.720p.x264-DIMENSION", "Parks.and.Recreation", 2)] - [TestCase("The.Office.US.S03.720p.x264-DIMENSION", "The.Office.US", 3)] - [TestCase(@"Sons.of.Anarchy.S03.720p.BluRay-CLUE\REWARD", "Sons.of.Anarchy", 3)] + [TestCase("30.Rock.Season.04.HDTV.XviD-DIMENSION", "30 Rock", 4)] + [TestCase("Parks.and.Recreation.S02.720p.x264-DIMENSION", "Parks and Recreation", 2)] + [TestCase("The.Office.US.S03.720p.x264-DIMENSION", "The Office US", 3)] + [TestCase(@"Sons.of.Anarchy.S03.720p.BluRay-CLUE\REWARD", "Sons of Anarchy", 3)] [TestCase("Adventure Time S02 720p HDTV x264 CRON", "Adventure Time", 2)] [TestCase("Sealab.2021.S04.iNTERNAL.DVDRip.XviD-VCDVaULT", "Sealab 2021", 4)] [TestCase("Hawaii Five 0 S01 720p WEB DL DD5 1 H 264 NT", "Hawaii Five 0", 1)] @@ -27,7 +27,7 @@ namespace NzbDrone.Core.Test.ParserTests { var result = Parser.Parser.ParseTitle(postTitle); result.SeasonNumber.Should().Be(season); - result.SeriesTitle.Should().Be(title.CleanSeriesTitle()); + result.SeriesTitle.Should().Be(title); result.EpisodeNumbers.Should().BeEmpty(); result.AbsoluteEpisodeNumbers.Should().BeEmpty(); result.FullSeason.Should().BeTrue(); diff --git a/src/NzbDrone.Core.Test/ParserTests/SeriesTitleInfoFixture.cs b/src/NzbDrone.Core.Test/ParserTests/SeriesTitleInfoFixture.cs index 9c53ec5aa..0809aae05 100644 --- a/src/NzbDrone.Core.Test/ParserTests/SeriesTitleInfoFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/SeriesTitleInfoFixture.cs @@ -44,7 +44,7 @@ namespace NzbDrone.Core.Test.ParserTests var result = Parser.Parser.ParseTitle(title).SeriesTitleInfo; - result.Title.Should().Be("house2004"); + result.Title.Should().Be("House 2004"); } [Test] @@ -54,7 +54,7 @@ namespace NzbDrone.Core.Test.ParserTests var result = Parser.Parser.ParseTitle(title).SeriesTitleInfo; - result.TitleWithoutYear.Should().Be("house"); + result.TitleWithoutYear.Should().Be("House"); } } } diff --git a/src/NzbDrone.Core.Test/ParserTests/SingleEpisodeParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/SingleEpisodeParserFixture.cs index 0da9d69b8..e6bf1dc98 100644 --- a/src/NzbDrone.Core.Test/ParserTests/SingleEpisodeParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/SingleEpisodeParserFixture.cs @@ -10,26 +10,26 @@ namespace NzbDrone.Core.Test.ParserTests [TestFixture] public class SingleEpisodeParserFixture : CoreTest { - [TestCase("Sonny.With.a.Chance.S02E15", "Sonny.With.a.Chance", 2, 15)] - [TestCase("Two.and.a.Half.Me.103.720p.HDTV.X264-DIMENSION", "Two.and.a.Half.Me", 1, 3)] - [TestCase("Two.and.a.Half.Me.113.720p.HDTV.X264-DIMENSION", "Two.and.a.Half.Me", 1, 13)] - [TestCase("Two.and.a.Half.Me.1013.720p.HDTV.X264-DIMENSION", "Two.and.a.Half.Me", 10, 13)] + [TestCase("Sonny.With.a.Chance.S02E15", "Sonny With a Chance", 2, 15)] + [TestCase("Two.and.a.Half.Me.103.720p.HDTV.X264-DIMENSION", "Two and a Half Me", 1, 3)] + [TestCase("Two.and.a.Half.Me.113.720p.HDTV.X264-DIMENSION", "Two and a Half Me", 1, 13)] + [TestCase("Two.and.a.Half.Me.1013.720p.HDTV.X264-DIMENSION", "Two and a Half Me", 10, 13)] [TestCase("Chuck.4x05.HDTV.XviD-LOL", "Chuck", 4, 5)] - [TestCase("The.Girls.Next.Door.S03E06.DVDRip.XviD-WiDE", "The.Girls.Next.Door", 3, 6)] + [TestCase("The.Girls.Next.Door.S03E06.DVDRip.XviD-WiDE", "The Girls Next Door", 3, 6)] [TestCase("Degrassi.S10E27.WS.DSR.XviD-2HD", "Degrassi", 10, 27)] [TestCase("Parenthood.2010.S02E14.HDTV.XviD-LOL", "Parenthood 2010", 2, 14)] [TestCase("Hawaii Five 0 S01E19 720p WEB DL DD5 1 H 264 NT", "Hawaii Five 0", 1, 19)] [TestCase("The Event S01E14 A Message Back 720p WEB DL DD5 1 H264 SURFER", "The Event", 1, 14)] [TestCase("Adam Hills In Gordon St Tonight S01E07 WS PDTV XviD FUtV", "Adam Hills In Gordon St Tonight", 1, 7)] - [TestCase("Adventure.Inc.S03E19.DVDRip.XviD-OSiTV", "Adventure.Inc", 3, 19)] + [TestCase("Adventure.Inc.S03E19.DVDRip.XviD-OSiTV", "Adventure Inc", 3, 19)] [TestCase("S03E09 WS PDTV XviD FUtV", "", 3, 9)] [TestCase("5x10 WS PDTV XviD FUtV", "", 5, 10)] [TestCase("Castle.2009.S01E14.HDTV.XviD-LOL", "Castle 2009", 1, 14)] [TestCase("Pride.and.Prejudice.1995.S03E20.HDTV.XviD-LOL", "Pride and Prejudice 1995", 3, 20)] - [TestCase("The.Office.S03E115.DVDRip.XviD-OSiTV", "The.Office", 3, 115)] + [TestCase("The.Office.S03E115.DVDRip.XviD-OSiTV", "The Office", 3, 115)] [TestCase(@"Parks and Recreation - S02E21 - 94 Meetings - 720p TV.mkv", "Parks and Recreation", 2, 21)] [TestCase(@"24-7 Penguins-Capitals- Road to the NHL Winter Classic - S01E03 - Episode 3.mkv", "24-7 Penguins-Capitals- Road to the NHL Winter Classic", 1, 3)] - [TestCase("Adventure.Inc.S03E19.DVDRip.\"XviD\"-OSiTV", "Adventure.Inc", 3, 19)] + [TestCase("Adventure.Inc.S03E19.DVDRip.\"XviD\"-OSiTV", "Adventure Inc", 3, 19)] [TestCase("Hawaii Five-0 (2010) - 1x05 - Nalowale (Forgotten/Missing)", "Hawaii Five-0 (2010)", 1, 5)] [TestCase("Hawaii Five-0 (2010) - 1x05 - Title", "Hawaii Five-0 (2010)", 1, 5)] [TestCase("House - S06E13 - 5 to 9 [DVD]", "House", 6, 13)] @@ -40,14 +40,14 @@ namespace NzbDrone.Core.Test.ParserTests [TestCase("Brew Masters S01E06 3 Beers For Batali DVDRip XviD SPRiNTER", "Brew Masters", 1, 6)] [TestCase("24 7 Flyers Rangers Road to the NHL Winter Classic Part01 720p HDTV x264 ORENJI", "24 7 Flyers Rangers Road to the NHL Winter Classic", 1, 1)] [TestCase("24 7 Flyers Rangers Road to the NHL Winter Classic Part 02 720p HDTV x264 ORENJI", "24 7 Flyers Rangers Road to the NHL Winter Classic", 1, 2)] - [TestCase("24-7 Flyers-Rangers- Road to the NHL Winter Classic - S01E01 - Part 1", "24 7 Flyers Rangers Road to the NHL Winter Classic", 1, 1)] + [TestCase("24-7 Flyers-Rangers- Road to the NHL Winter Classic - S01E01 - Part 1", "24-7 Flyers-Rangers- Road to the NHL Winter Classic", 1, 1)] [TestCase("S6E02-Unwrapped-(Playing With Food) - [DarkData]", "", 6, 2)] [TestCase("S06E03-Unwrapped-(Number Ones Unwrapped) - [DarkData]", "", 6, 3)] [TestCase("The Mentalist S02E21 18 5 4 720p WEB DL DD5 1 h 264 EbP", "The Mentalist", 2, 21)] [TestCase("01x04 - Halloween, Part 1 - 720p WEB-DL", "", 1, 4)] - [TestCase("extras.s03.e05.ws.dvdrip.xvid-m00tv", "Extras", 3, 5)] - [TestCase("castle.2009.416.hdtv-lol", "Castle 2009", 4, 16)] - [TestCase("hawaii.five-0.2010.217.hdtv-lol", "Hawaii Five-0 (2010)", 2, 17)] + [TestCase("extras.s03.e05.ws.dvdrip.xvid-m00tv", "extras", 3, 5)] + [TestCase("castle.2009.416.hdtv-lol", "castle 2009", 4, 16)] + [TestCase("hawaii.five-0.2010.217.hdtv-lol", "hawaii five-0 2010", 2, 17)] [TestCase("Looney Tunes - S1936E18 - I Love to Singa", "Looney Tunes", 1936, 18)] [TestCase("American_Dad!_-_7x6_-_The_Scarlett_Getter_[SDTV]", "American Dad!", 7, 6)] [TestCase("Falling_Skies_-_1x1_-_Live_and_Learn_[HDTV-720p]", "Falling Skies", 1, 1)] @@ -61,8 +61,8 @@ namespace NzbDrone.Core.Test.ParserTests [TestCase("Top_Gear.19x06.720p_HDTV_x264-FoV", "Top Gear", 19, 6)] [TestCase("Portlandia.S03E10.Alexandra.720p.WEB-DL.AAC2.0.H.264-CROM.mkv", "Portlandia", 3, 10)] [TestCase("(Game of Thrones s03 e - \"Game of Thrones Season 3 Episode 10\"", "Game of Thrones", 3, 10)] - [TestCase("House.Hunters.International.S05E607.720p.hdtv.x264", "House.Hunters.International", 5, 607)] - [TestCase("Adventure.Time.With.Finn.And.Jake.S01E20.720p.BluRay.x264-DEiMOS", "Adventure.Time.With.Finn.And.Jake", 1, 20)] + [TestCase("House.Hunters.International.S05E607.720p.hdtv.x264", "House Hunters International", 5, 607)] + [TestCase("Adventure.Time.With.Finn.And.Jake.S01E20.720p.BluRay.x264-DEiMOS", "Adventure Time With Finn And Jake", 1, 20)] [TestCase("Hostages.S01E04.2-45.PM.[HDTV-720p].mkv", "Hostages", 1, 4)] [TestCase("S01E04", "", 1, 4)] [TestCase("1x04", "", 1, 4)] @@ -71,15 +71,15 @@ namespace NzbDrone.Core.Test.ParserTests [TestCase("666 Park Avenue - S01E01", "666 Park Avenue", 1, 1)] [TestCase("Warehouse 13 - S01E01", "Warehouse 13", 1, 1)] [TestCase("Don't Trust The B---- in Apartment 23.S01E01", "Don't Trust The B---- in Apartment 23", 1, 1)] - [TestCase("Warehouse.13.S01E01", "Warehouse.13", 1, 1)] - [TestCase("Dont.Trust.The.B----.in.Apartment.23.S01E01", "Dont.Trust.The.B----.in.Apartment.23", 1, 1)] + [TestCase("Warehouse.13.S01E01", "Warehouse 13", 1, 1)] + [TestCase("Dont.Trust.The.B----.in.Apartment.23.S01E01", "Dont Trust The B---- in Apartment 23", 1, 1)] [TestCase("24 S01E01", "24", 1, 1)] [TestCase("24.S01E01", "24", 1, 1)] [TestCase("Homeland - 2x12 - The Choice [HDTV-1080p].mkv", "Homeland", 2, 12)] [TestCase("Homeland - 2x4 - New Car Smell [HDTV-1080p].mkv", "Homeland", 2, 4)] [TestCase("Top Gear - 06x11 - 2005.08.07", "Top Gear", 6, 11)] [TestCase("The_Voice_US_s06e19_04.28.2014_hdtv.x264.Poke.mp4", "The Voice US", 6, 19)] - [TestCase("the.100.110.hdtv-lol", "The 100", 1, 10)] + [TestCase("the.100.110.hdtv-lol", "the 100", 1, 10)] [TestCase("2009x09 [SDTV].avi", "", 2009, 9)] [TestCase("S2009E09 [SDTV].avi", "", 2009, 9)] [TestCase("Shark Week S2009E09 [SDTV].avi", "Shark Week", 2009, 9)] @@ -90,23 +90,23 @@ namespace NzbDrone.Core.Test.ParserTests [TestCase("Constantine S1-E1-WEB-DL-1080p-NZBgeek", "Constantine", 1, 1)] [TestCase("Constantine S1E1-WEB-DL-1080p-NZBgeek", "Constantine", 1, 1)] [TestCase("NCIS.S010E16.720p.HDTV.X264-DIMENSION", "NCIS", 10, 16)] - [TestCase("[ www.Torrenting.com ] - Revolution.2012.S02E17.720p.HDTV.X264-DIMENSION", "Revolution2012", 2, 17)] - [TestCase("Revolution.2012.S02E18.720p.HDTV.X264-DIMENSION.mkv", "Revolution2012", 2, 18)] + [TestCase("[ www.Torrenting.com ] - Revolution.2012.S02E17.720p.HDTV.X264-DIMENSION", "Revolution 2012", 2, 17)] + [TestCase("Revolution.2012.S02E18.720p.HDTV.X264-DIMENSION.mkv", "Revolution 2012", 2, 18)] [TestCase("Series - Season 1 - Episode 01 (Resolution).avi", "Series", 1, 1)] [TestCase("5x09 - 100 [720p WEB-DL].mkv", "", 5, 9)] [TestCase("1x03 - 274 [1080p BluRay].mkv", "", 1, 3)] [TestCase("1x03 - The 112th Congress [1080p BluRay].mkv", "", 1, 3)] - [TestCase("Revolution.2012.S02E14.720p.HDTV.X264-DIMENSION [PublicHD].mkv", "Revolution.2012", 2, 14)] + [TestCase("Revolution.2012.S02E14.720p.HDTV.X264-DIMENSION [PublicHD].mkv", "Revolution 2012", 2, 14)] //[TestCase("Sex And The City S6E15 - Catch-38 [RavyDavy].avi", "Sex And The City", 6, 15)] // -38 is getting treated as abs number - [TestCase("Castle.2009.S06E03.720p.HDTV.X264-DIMENSION [PublicHD].mkv", "Castle.2009", 6, 3)] + [TestCase("Castle.2009.S06E03.720p.HDTV.X264-DIMENSION [PublicHD].mkv", "Castle 2009", 6, 3)] [TestCase("19-2.2014.S02E01.720p.HDTV.x264-CROOKS", "19-2 2014", 2, 1)] [TestCase("Community - S01E09 - Debate 109", "Community", 1, 9)] [TestCase("Entourage - S02E02 - My Maserati Does 185", "Entourage", 2, 2)] [TestCase("6x13 - The Family Guy 100th Episode Special", "", 6, 13)] //[TestCase("Heroes - S01E01 - Genesis 101 [HDTV-720p]", "Heroes", 1, 1)] //[TestCase("The 100 S02E01 HDTV x264-KILLERS [eztv]", "The 100", 2, 1)] - [TestCase("The Young And The Restless - S41 E10478 - 2014-08-15", "The Young and The Restless", 41, 10478)] - [TestCase("The Young And The Restless - S42 E10591 - 2015-01-27", "The Young and The Restless", 42, 10591)] + [TestCase("The Young And The Restless - S41 E10478 - 2014-08-15", "The Young And The Restless", 41, 10478)] + [TestCase("The Young And The Restless - S42 E10591 - 2015-01-27", "The Young And The Restless", 42, 10591)] [TestCase("Series Title [1x05] Episode Title", "Series Title", 1, 5)] [TestCase("Series Title [S01E05] Episode Title", "Series Title", 1, 5)] [TestCase("Series Title Season 01 Episode 05 720p", "Series Title", 1, 5)] @@ -118,7 +118,7 @@ namespace NzbDrone.Core.Test.ParserTests result.EpisodeNumbers.Should().HaveCount(1); result.SeasonNumber.Should().Be(seasonNumber); result.EpisodeNumbers.First().Should().Be(episodeNumber); - result.SeriesTitle.Should().Be(title.CleanSeriesTitle()); + result.SeriesTitle.Should().Be(title); result.AbsoluteEpisodeNumbers.Should().BeEmpty(); result.FullSeason.Should().BeFalse(); } diff --git a/src/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs b/src/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs index 8d336d096..082e9560f 100644 --- a/src/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs +++ b/src/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs @@ -29,7 +29,7 @@ namespace NzbDrone.Core.DataAugmentation.Scene private readonly IEnumerable _sceneMappingProviders; private readonly IEventAggregator _eventAggregator; private readonly Logger _logger; - private readonly ICached _getTvdbIdCache; + private readonly ICached> _getTvdbIdCache; private readonly ICached> _findByTvdbIdCache; public SceneMappingService(ISceneMappingRepository repository, @@ -42,7 +42,7 @@ namespace NzbDrone.Core.DataAugmentation.Scene _sceneMappingProviders = sceneMappingProviders; _eventAggregator = eventAggregator; - _getTvdbIdCache = cacheManager.GetCache(GetType(), "tvdb_id"); + _getTvdbIdCache = cacheManager.GetCache>(GetType(), "tvdb_id"); _findByTvdbIdCache = cacheManager.GetCache>(GetType(), "find_tvdb_id"); _logger = logger; } @@ -130,7 +130,7 @@ namespace NzbDrone.Core.DataAugmentation.Scene sceneMapping.Type = sceneMappingProvider.GetType().Name; } - _repository.InsertMany(mappings.DistinctBy(s => s.ParseTerm).ToList()); + _repository.InsertMany(mappings.ToList()); } else { @@ -154,7 +154,31 @@ namespace NzbDrone.Core.DataAugmentation.Scene RefreshCache(); } - return _getTvdbIdCache.Find(title.CleanSeriesTitle()); + var candidates = _getTvdbIdCache.Find(title.CleanSeriesTitle()); + + if (candidates == null) + { + return null; + } + + if (candidates.Count == 1) + { + return candidates.First(); + } + + var exactMatch = candidates.OrderByDescending(v => v.SeasonNumber) + .FirstOrDefault(v => v.Title == title); + + if (exactMatch != null) + { + return exactMatch; + } + + var closestMatch = candidates.OrderBy(v => title.LevenshteinDistance(v.Title, 10, 1, 10)) + .ThenByDescending(v => v.SeasonNumber) + .First(); + + return closestMatch; } private void RefreshCache() @@ -164,9 +188,9 @@ namespace NzbDrone.Core.DataAugmentation.Scene _getTvdbIdCache.Clear(); _findByTvdbIdCache.Clear(); - foreach (var sceneMapping in mappings) + foreach (var sceneMapping in mappings.GroupBy(v => v.ParseTerm)) { - _getTvdbIdCache.Set(sceneMapping.ParseTerm.CleanSeriesTitle(), sceneMapping); + _getTvdbIdCache.Set(sceneMapping.Key, sceneMapping.ToList()); } foreach (var sceneMapping in mappings.GroupBy(x => x.TvdbId)) diff --git a/src/NzbDrone.Core/Parser/Parser.cs b/src/NzbDrone.Core/Parser/Parser.cs index ff00c1c8c..446733629 100644 --- a/src/NzbDrone.Core/Parser/Parser.cs +++ b/src/NzbDrone.Core/Parser/Parser.cs @@ -31,15 +31,15 @@ namespace NzbDrone.Core.Parser RegexOptions.IgnoreCase | RegexOptions.Compiled), //Anime - [SubGroup] Title Absolute Episode Number + Season+Episode - new Regex(@"^(?:\[(?.+?)\](?:_|-|\s|\.)?)(?.+?)(?:(?:\W|_)+(?<absoluteepisode>\d{2,3}))+(?:_|-|\s|\.)+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+).*?(?<hash>[(\[]\w{8}[)\]])?(?:$|\.)", + new Regex(@"^(?:\[(?<subgroup>.+?)\](?:_|-|\s|\.)?)(?<title>.+?)(?:(?:[-_\W](?<![()\[!]))+(?<absoluteepisode>\d{2,3}))+(?:_|-|\s|\.)+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+).*?(?<hash>[(\[]\w{8}[)\]])?(?:$|\.)", RegexOptions.IgnoreCase | RegexOptions.Compiled), //Anime - [SubGroup] Title Season+Episode + Absolute Episode Number - new Regex(@"^(?:\[(?<subgroup>.+?)\](?:_|-|\s|\.)?)(?<title>.+?)(?:\W|_)+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+)(?:(?:_|-|\s|\.)+(?<absoluteepisode>(?<!\d+)\d{2,3}(?!\d+)))+.*?(?<hash>\[\w{8}\])?(?:$|\.)", + new Regex(@"^(?:\[(?<subgroup>.+?)\](?:_|-|\s|\.)?)(?<title>.+?)(?:[-_\W](?<![()\[!]))+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+)(?:(?:_|-|\s|\.)+(?<absoluteepisode>(?<!\d+)\d{2,3}(?!\d+)))+.*?(?<hash>\[\w{8}\])?(?:$|\.)", RegexOptions.IgnoreCase | RegexOptions.Compiled), //Anime - [SubGroup] Title Season+Episode - new Regex(@"^(?:\[(?<subgroup>.+?)\](?:_|-|\s|\.)?)(?<title>.+?)(?:\W|_)+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+)(?:\s|\.).*?(?<hash>\[\w{8}\])?(?:$|\.)", + new Regex(@"^(?:\[(?<subgroup>.+?)\](?:_|-|\s|\.)?)(?<title>.+?)(?:[-_\W](?<![()\[!]))+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+)(?:\s|\.).*?(?<hash>\[\w{8}\])?(?:$|\.)", RegexOptions.IgnoreCase | RegexOptions.Compiled), //Anime - [SubGroup] Title with trailing number Absolute Episode Number @@ -63,15 +63,15 @@ namespace NzbDrone.Core.Parser RegexOptions.IgnoreCase | RegexOptions.Compiled), //Multi-episode Repeated (S01E05 - S01E06, 1x05 - 1x06, etc) - new Regex(@"^(?<title>.+?)(?:(?:[_\W](?<![(\[]))+S?(?<season>(?<!\d+)(?:\d{1,2}|\d{4})(?!\d+))(?:(?:[ex]){1,2}(?<episode>\d{1,3}(?!\d+)))+){2,}", + new Regex(@"^(?<title>.+?)(?:(?:[-_\W](?<![()\[!]))+S?(?<season>(?<!\d+)(?:\d{1,2}|\d{4})(?!\d+))(?:(?:[ex]){1,2}(?<episode>\d{1,3}(?!\d+)))+){2,}", RegexOptions.IgnoreCase | RegexOptions.Compiled), //Episodes with a title, Single episodes (S01E05, 1x05, etc) & Multi-episode (S01E05E06, S01E05-06, S01E05 E06, etc) ** - new Regex(@"^(?<title>.+?)(?:(?:[_\W](?<![(\[]))+S?(?<season>(?<!\d+)(?:\d{1,2}|\d{4})(?!\d+))(?:[ex]|\W[ex]|_){1,2}(?<episode>\d{2,3}(?!\d+))(?:(?:\-|[ex]|\W[ex]|_){1,2}(?<episode>\d{2,3}(?!\d+)))*)\W?(?!\\)", + new Regex(@"^(?<title>.+?)(?:(?:[-_\W](?<![()\[!]))+S?(?<season>(?<!\d+)(?:\d{1,2}|\d{4})(?!\d+))(?:[ex]|\W[ex]|_){1,2}(?<episode>\d{2,3}(?!\d+))(?:(?:\-|[ex]|\W[ex]|_){1,2}(?<episode>\d{2,3}(?!\d+)))*)\W?(?!\\)", RegexOptions.IgnoreCase | RegexOptions.Compiled), //Supports 103/113 naming - new Regex(@"^(?<title>.+?)?(?:(?:[_\W](?<![(\[]))(?<season>(?<!\d+)[1-9])(?<episode>[1-9][0-9]|[0][1-9])(?![a-z]|\d+))+", + new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))+(?<season>(?<!\d+)[1-9])(?<episode>[1-9][0-9]|[0][1-9])(?![a-z]|\d+))+", RegexOptions.IgnoreCase | RegexOptions.Compiled), //Mini-Series, treated as season 1, episodes are labelled as Part01, Part 01, Part.1 @@ -79,7 +79,7 @@ namespace NzbDrone.Core.Parser RegexOptions.IgnoreCase | RegexOptions.Compiled), //Supports Season 01 Episode 03 - new Regex(@"(?:.*(?:\""|^))(?<title>.*?)(?:\W?Season\W?)(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:\W|_)+(?:Episode\W)(?:[-_. ]?(?<episode>(?<!\d+)\d{1,2}(?!\d+)))+", + new Regex(@"(?:.*(?:\""|^))(?<title>.*?)(?:[-_\W](?<![()\[]))+(?:\W?Season\W?)(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:\W|_)+(?:Episode\W)(?:[-_. ]?(?<episode>(?<!\d+)\d{1,2}(?!\d+)))+", RegexOptions.IgnoreCase | RegexOptions.Compiled), //Single episode season or episode S1E1 or S1-E1 @@ -103,7 +103,7 @@ namespace NzbDrone.Core.Parser RegexOptions.IgnoreCase | RegexOptions.Compiled), //Supports 1103/1113 naming - new Regex(@"^(?<title>.+?)?(?:(?:\W|_)?(?<season>(?<!\d+|\(|\[|e|x)\d{2})(?<episode>(?<!e|x)\d{2}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)", + new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<season>(?<!\d+|\(|\[|e|x)\d{2})(?<episode>(?<!e|x)\d{2}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)", RegexOptions.IgnoreCase | RegexOptions.Compiled), //4 digit episode number @@ -113,15 +113,15 @@ namespace NzbDrone.Core.Parser //4 digit episode number //Episodes with a title, Single episodes (S01E05, 1x05, etc) & Multi-episode (S01E05E06, S01E05-06, S01E05 E06, etc) - new Regex(@"^(?<title>.+?)(?:(\W|_)+S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]|_){1,2}(?<episode>\d{4}(?!\d+|i|p)))+)\W?(?!\\)", + new Regex(@"^(?<title>.+?)(?:(?:[-_\W](?<![()\[!]))+S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]|_){1,2}(?<episode>\d{4}(?!\d+|i|p)))+)\W?(?!\\)", RegexOptions.IgnoreCase | RegexOptions.Compiled), //Episodes with a title and season/episode in square brackets - new Regex(@"^(?<title>.+?)(?:(\W|_)+\[S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]|_){1,2}(?<episode>(?<!\d+)\d{2}(?!\d+|i|p)))+\])\W?(?!\\)", + new Regex(@"^(?<title>.+?)(?:(?:[-_\W](?<![()\[!]))+\[S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]|_){1,2}(?<episode>(?<!\d+)\d{2}(?!\d+|i|p)))+\])\W?(?!\\)", RegexOptions.IgnoreCase | RegexOptions.Compiled), //Episodes with single digit episode number (S01E1, S01E5E6, etc) - new Regex(@"^(?<title>.*?)(?:(?:_|-|\s|\.)S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]){1,2}(?<episode>\d{1}))+)+(\W+|_|$)(?!\\)", + new Regex(@"^(?<title>.*?)(?:(?:[-_\W](?<![()\[!]))+S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]){1,2}(?<episode>\d{1}))+)+(\W+|_|$)(?!\\)", RegexOptions.IgnoreCase | RegexOptions.Compiled), //iTunes Season 1\05 Title (Quality).ext @@ -137,7 +137,7 @@ namespace NzbDrone.Core.Parser RegexOptions.IgnoreCase | RegexOptions.Compiled), //Anime - Title {Absolute Episode Number} - new Regex(@"^(?:\[(?<subgroup>.+?)\][-_. ]?)?(?<title>.+?)(?:(?:\W)+(?<absoluteepisode>(?<!\d+)\d{2,3}(?!\d+)))+(?:_|-|\s|\.)*?(?<hash>\[.{8}\])?(?:$|\.)?", + new Regex(@"^(?:\[(?<subgroup>.+?)\][-_. ]?)?(?<title>.+?)(?:(?:[-_\W](?<![()\[!]))+(?<absoluteepisode>(?<!\d+)\d{2,3}(?!\d+)))+(?:_|-|\s|\.)*?(?<hash>\[.{8}\])?(?:$|\.)?", RegexOptions.IgnoreCase | RegexOptions.Compiled), //Extant, terrible multi-episode naming (extant.10708.hdtv-lol.mp4) @@ -543,7 +543,7 @@ namespace NzbDrone.Core.Parser private static ParsedEpisodeInfo ParseMatchCollection(MatchCollection matchCollection) { - var seriesName = matchCollection[0].Groups["title"].Value.Replace('.', ' '); + var seriesName = matchCollection[0].Groups["title"].Value.Replace('.', ' ').Replace('_', ' '); seriesName = RequestInfoRegex.Replace(seriesName, "").Trim(' '); int airYear; @@ -658,7 +658,7 @@ namespace NzbDrone.Core.Parser }; } - result.SeriesTitle = CleanSeriesTitle(seriesName); + result.SeriesTitle = seriesName; result.SeriesTitleInfo = GetSeriesTitleInfo(result.SeriesTitle); Logger.Debug("Episode Parsed. {0}", result); diff --git a/src/NzbDrone.Core/Tv/SeriesService.cs b/src/NzbDrone.Core/Tv/SeriesService.cs index 0a1479ca4..c61bc15e8 100644 --- a/src/NzbDrone.Core/Tv/SeriesService.cs +++ b/src/NzbDrone.Core/Tv/SeriesService.cs @@ -148,7 +148,7 @@ namespace NzbDrone.Core.Tv public Series FindByTitle(string title, int year) { - return _seriesRepository.FindByTitle(title, year); + return _seriesRepository.FindByTitle(title.CleanSeriesTitle(), year); } public void DeleteSeries(int seriesId, bool deleteFiles)