diff --git a/src/NzbDrone.Core.Test/IndexerTests/BasicRssParserFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/BasicRssParserFixture.cs index 2eca3586b..30bfeadb0 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/BasicRssParserFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/BasicRssParserFixture.cs @@ -7,19 +7,6 @@ namespace NzbDrone.Core.Test.IndexerTests { public class BasicRssParserFixture : CoreTest { - - [TestCase("Castle.2009.S01E14.English.HDTV.XviD-LOL", "LOL")] - [TestCase("Castle 2009 S01E14 English HDTV XviD LOL", "LOL")] - [TestCase("Acropolis Now S05 EXTRAS DVDRip XviD RUNNER", "RUNNER")] - [TestCase("Punky.Brewster.S01.EXTRAS.DVDRip.XviD-RUNNER", "RUNNER")] - [TestCase("2020.NZ.2011.12.02.PDTV.XviD-C4TV", "C4TV")] - [TestCase("The.Office.S03E115.DVDRip.XviD-OSiTV", "OSiTV")] - public void parse_releaseGroup(string title, string expected) - { - RssParserBase.ParseReleaseGroup(title).Should().Be(expected); - } - - [TestCase("5.64 GB", 6055903887)] [TestCase("5.54 GiB", 5948529705)] [TestCase("398.62 MiB", 417983365)] diff --git a/src/NzbDrone.Core.Test/MediaFiles/ImportApprovedEpisodesFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/ImportApprovedEpisodesFixture.cs index 30b5f804a..7946b53aa 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/ImportApprovedEpisodesFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/ImportApprovedEpisodesFixture.cs @@ -47,7 +47,11 @@ namespace NzbDrone.Core.Test.MediaFiles Series = series, Episodes = new List {episode}, Path = @"C:\Test\TV\30 Rock\30 Rock - S01E01 - Pilot.avi".AsOsAgnostic(), - Quality = new QualityModel(Quality.Bluray720p) + Quality = new QualityModel(Quality.Bluray720p), + ParsedEpisodeInfo = new ParsedEpisodeInfo + { + ReleaseGroup = "DRONE" + } })); } diff --git a/src/NzbDrone.Core.Test/OrganizerTests/GetNewFilenameFixture.cs b/src/NzbDrone.Core.Test/OrganizerTests/GetNewFilenameFixture.cs index cfad01e1d..749dff288 100644 --- a/src/NzbDrone.Core.Test/OrganizerTests/GetNewFilenameFixture.cs +++ b/src/NzbDrone.Core.Test/OrganizerTests/GetNewFilenameFixture.cs @@ -49,7 +49,7 @@ namespace NzbDrone.Core.Test.OrganizerTests .With(e => e.EpisodeNumber = 7) .Build(); - _episodeFile = new EpisodeFile { Quality = new QualityModel(Quality.HDTV720p) }; + _episodeFile = new EpisodeFile { Quality = new QualityModel(Quality.HDTV720p), ReleaseGroup = "DRONE" }; } private void GivenProper() @@ -344,5 +344,14 @@ namespace NzbDrone.Core.Test.OrganizerTests Subject.BuildFilename(new List { _episode1 }, _series, _episodeFile) .Should().Be(title); } + + [Test] + public void should_should_replace_release_group() + { + _namingConfig.StandardEpisodeFormat = "{Release Group}"; + + Subject.BuildFilename(new List { _episode1 }, _series, _episodeFile) + .Should().Be(_episodeFile.ReleaseGroup); + } } } \ No newline at end of file diff --git a/src/NzbDrone.Core.Test/ParserTests/ParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/ParserFixture.cs index 3d25c7086..f797c9f27 100644 --- a/src/NzbDrone.Core.Test/ParserTests/ParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/ParserFixture.cs @@ -452,5 +452,19 @@ namespace NzbDrone.Core.Test.ParserTests Parser.Parser.ParseTitle(title).Should().BeNull(); ExceptionVerification.IgnoreWarns(); } + + [TestCase("Castle.2009.S01E14.English.HDTV.XviD-LOL", "LOL")] + [TestCase("Castle 2009 S01E14 English HDTV XviD LOL", "LOL")] + [TestCase("Acropolis Now S05 EXTRAS DVDRip XviD RUNNER", "RUNNER")] + [TestCase("Punky.Brewster.S01.EXTRAS.DVDRip.XviD-RUNNER", "RUNNER")] + [TestCase("2020.NZ.2011.12.02.PDTV.XviD-C4TV", "C4TV")] + [TestCase("The.Office.S03E115.DVDRip.XviD-OSiTV", "OSiTV")] + [TestCase("The Office - S01E01 - Pilot [HTDV-480p]", "DRONE")] + [TestCase("The Office - S01E01 - Pilot [HTDV-720p]", "DRONE")] + [TestCase("The Office - S01E01 - Pilot [HTDV-1080p]", "DRONE")] + public void parse_releaseGroup(string title, string expected) + { + Parser.Parser.ParseReleaseGroup(title).Should().Be(expected); + } } } diff --git a/src/NzbDrone.Core/Datastore/Migration/032_set_default_release_group.cs b/src/NzbDrone.Core/Datastore/Migration/032_set_default_release_group.cs new file mode 100644 index 000000000..5ecc4e2c0 --- /dev/null +++ b/src/NzbDrone.Core/Datastore/Migration/032_set_default_release_group.cs @@ -0,0 +1,14 @@ +using FluentMigrator; +using NzbDrone.Core.Datastore.Migration.Framework; + +namespace NzbDrone.Core.Datastore.Migration +{ + [Migration(32)] + public class set_default_release_group : NzbDroneMigrationBase + { + protected override void MainDbUpgrade() + { + Execute.Sql("UPDATE EpisodeFiles SET ReleaseGroup = 'DRONE' WHERE ReleaseGroup IS NULL"); + } + } +} diff --git a/src/NzbDrone.Core/History/HistoryService.cs b/src/NzbDrone.Core/History/HistoryService.cs index 9fad974e0..636d092d0 100644 --- a/src/NzbDrone.Core/History/HistoryService.cs +++ b/src/NzbDrone.Core/History/HistoryService.cs @@ -101,7 +101,7 @@ namespace NzbDrone.Core.History history.Data.Add("Indexer", message.Episode.Release.Indexer); history.Data.Add("NzbInfoUrl", message.Episode.Release.InfoUrl); - history.Data.Add("ReleaseGroup", message.Episode.Release.ReleaseGroup); + history.Data.Add("ReleaseGroup", message.Episode.ParsedEpisodeInfo.ReleaseGroup); history.Data.Add("Age", message.Episode.Release.Age.ToString()); if (!String.IsNullOrWhiteSpace(message.DownloadClientId)) diff --git a/src/NzbDrone.Core/Indexers/RssParserBase.cs b/src/NzbDrone.Core/Indexers/RssParserBase.cs index 1065631aa..29ad27ee2 100644 --- a/src/NzbDrone.Core/Indexers/RssParserBase.cs +++ b/src/NzbDrone.Core/Indexers/RssParserBase.cs @@ -70,7 +70,6 @@ namespace NzbDrone.Core.Indexers reportInfo.Title = title; reportInfo.PublishDate = item.PublishDate(); - reportInfo.ReleaseGroup = ParseReleaseGroup(title); reportInfo.DownloadUrl = GetNzbUrl(item); reportInfo.InfoUrl = GetNzbInfoUrl(item); @@ -114,25 +113,6 @@ namespace NzbDrone.Core.Indexers return currentResult; } - public static string ParseReleaseGroup(string title) - { - title = title.Trim(); - var index = title.LastIndexOf('-'); - - if (index < 0) - index = title.LastIndexOf(' '); - - if (index < 0) - return String.Empty; - - var group = title.Substring(index + 1); - - if (@group.Length == title.Length) - return String.Empty; - - return @group.Trim('-', ' ', '[', ']'); - } - private static readonly Regex ReportSizeRegex = new Regex(@"(?\d+\.\d{1,2}|\d+\,\d+\.\d{1,2}|\d+)\W?(?GB|MB|GiB|MiB)", RegexOptions.IgnoreCase | RegexOptions.Compiled); diff --git a/src/NzbDrone.Core/MediaFiles/EpisodeFile.cs b/src/NzbDrone.Core/MediaFiles/EpisodeFile.cs index 943bc731a..7fac2d1ae 100644 --- a/src/NzbDrone.Core/MediaFiles/EpisodeFile.cs +++ b/src/NzbDrone.Core/MediaFiles/EpisodeFile.cs @@ -12,6 +12,7 @@ namespace NzbDrone.Core.MediaFiles public long Size { get; set; } public DateTime DateAdded { get; set; } public string SceneName { get; set; } + public string ReleaseGroup { get; set; } public QualityModel Quality { get; set; } public LazyList Episodes { get; set; } diff --git a/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs b/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs index 0173056f9..92b0bd059 100644 --- a/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs +++ b/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs @@ -68,6 +68,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport episodeFile.Quality = localEpisode.Quality; episodeFile.SeasonNumber = localEpisode.SeasonNumber; episodeFile.Episodes = localEpisode.Episodes; + episodeFile.ReleaseGroup = localEpisode.ParsedEpisodeInfo.ReleaseGroup; if (newDownload) { diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index f3dddff70..98eafe518 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -187,6 +187,7 @@ + diff --git a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs index 9032a2196..004ff68ac 100644 --- a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs +++ b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs @@ -89,6 +89,8 @@ namespace NzbDrone.Core.Organizer {"{Series Title}", series.Title} }; + tokenValues.Add("{Release Group}", episodeFile.ReleaseGroup); + if (series.SeriesType == SeriesTypes.Daily) { pattern = namingConfig.DailyEpisodeFormat; diff --git a/src/NzbDrone.Core/Organizer/FilenameSampleService.cs b/src/NzbDrone.Core/Organizer/FilenameSampleService.cs index 2ea499b9b..668a20966 100644 --- a/src/NzbDrone.Core/Organizer/FilenameSampleService.cs +++ b/src/NzbDrone.Core/Organizer/FilenameSampleService.cs @@ -65,19 +65,22 @@ namespace NzbDrone.Core.Organizer _singleEpisodeFile = new EpisodeFile { Quality = new QualityModel(Quality.HDTV720p), - Path = @"C:\Test\Series.Title.S01E01.720p.HDTV.x264-EVOLVE.mkv" + Path = @"C:\Test\Series.Title.S01E01.720p.HDTV.x264-EVOLVE.mkv", + ReleaseGroup = "RlsGrp" }; _multiEpisodeFile = new EpisodeFile { Quality = new QualityModel(Quality.HDTV720p), - Path = @"C:\Test\Series.Title.S01E01-E02.720p.HDTV.x264-EVOLVE.mkv" + Path = @"C:\Test\Series.Title.S01E01-E02.720p.HDTV.x264-EVOLVE.mkv", + ReleaseGroup = "RlsGrp" }; _dailyEpisodeFile = new EpisodeFile { Quality = new QualityModel(Quality.HDTV720p), - Path = @"C:\Test\Series.Title.2013.10.30.HDTV.x264-EVOLVE.mkv" + Path = @"C:\Test\Series.Title.2013.10.30.HDTV.x264-EVOLVE.mkv", + ReleaseGroup = "RlsGrp" }; } diff --git a/src/NzbDrone.Core/Parser/Model/ParsedEpisodeInfo.cs b/src/NzbDrone.Core/Parser/Model/ParsedEpisodeInfo.cs index d4bbefaac..7ae94f647 100644 --- a/src/NzbDrone.Core/Parser/Model/ParsedEpisodeInfo.cs +++ b/src/NzbDrone.Core/Parser/Model/ParsedEpisodeInfo.cs @@ -15,6 +15,7 @@ namespace NzbDrone.Core.Parser.Model public String AirDate { get; set; } public Language Language { get; set; } public bool FullSeason { get; set; } + public string ReleaseGroup { get; set; } public ParsedEpisodeInfo() { diff --git a/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs b/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs index b5ae81ad8..c920bd8aa 100644 --- a/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs +++ b/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs @@ -28,7 +28,6 @@ namespace NzbDrone.Core.Parser.Model } } - public string ReleaseGroup { get; set; } public int TvRageId { get; set; } } } \ No newline at end of file diff --git a/src/NzbDrone.Core/Parser/Parser.cs b/src/NzbDrone.Core/Parser/Parser.cs index 119711b1d..de2b06ca7 100644 --- a/src/NzbDrone.Core/Parser/Parser.cs +++ b/src/NzbDrone.Core/Parser/Parser.cs @@ -162,6 +162,9 @@ namespace NzbDrone.Core.Parser result.Quality = QualityParser.ParseQuality(title); Logger.Trace("Quality parsed: {0}", result.Quality); + result.ReleaseGroup = ParseReleaseGroup(title); + Logger.Trace("Release Group parsed: {0}", result.ReleaseGroup); + return result; } } @@ -214,6 +217,36 @@ namespace NzbDrone.Core.Parser return MultiPartCleanupRegex.Replace(title, string.Empty).Trim(); } + public static string ParseReleaseGroup(string title) + { + const string defaultReleaseGroup = "DRONE"; + + title = title.Trim(); + var index = title.LastIndexOf('-'); + + if (index < 0) + index = title.LastIndexOf(' '); + + if (index < 0) + return defaultReleaseGroup; + + var group = title.Substring(index + 1); + + if (group.Length == title.Length) + return String.Empty; + + group = group.Trim('-', ' ', '[', ']'); + + if (group.ToLower() == "480p" || + group.ToLower() == "720p" || + group.ToLower() == "1080p") + { + return defaultReleaseGroup; + } + + return group; + } + private static SeriesTitleInfo GetSeriesTitleInfo(string title) { var seriesTitleInfo = new SeriesTitleInfo(); diff --git a/src/UI/Settings/MediaManagement/Naming/NamingViewTemplate.html b/src/UI/Settings/MediaManagement/Naming/NamingViewTemplate.html index a8eb890d2..e7b2e4f61 100644 --- a/src/UI/Settings/MediaManagement/Naming/NamingViewTemplate.html +++ b/src/UI/Settings/MediaManagement/Naming/NamingViewTemplate.html @@ -41,6 +41,7 @@ {{> EpisodeNamingPartial}} {{> EpisodeTitleNamingPartial}} {{> QualityTitleNamingPartial}} + {{> ReleaseGroupNamingPartial}} {{> SeparatorNamingPartial}} @@ -69,6 +70,7 @@ {{> EpisodeNamingPartial}} {{> EpisodeTitleNamingPartial}} {{> QualityTitleNamingPartial}} + {{> ReleaseGroupNamingPartial}} {{> SeparatorNamingPartial}} diff --git a/src/UI/Settings/MediaManagement/Naming/Partials/ReleaseGroupNamingPartial.html b/src/UI/Settings/MediaManagement/Naming/Partials/ReleaseGroupNamingPartial.html new file mode 100644 index 000000000..137d9fce3 --- /dev/null +++ b/src/UI/Settings/MediaManagement/Naming/Partials/ReleaseGroupNamingPartial.html @@ -0,0 +1 @@ +
  • Release Group
  • \ No newline at end of file