diff --git a/src/Jackett.Test/Jackett.Test.csproj b/src/Jackett.Test/Jackett.Test.csproj index cf5bac2f9..e502d514b 100644 --- a/src/Jackett.Test/Jackett.Test.csproj +++ b/src/Jackett.Test/Jackett.Test.csproj @@ -165,6 +165,7 @@ + diff --git a/src/Jackett.Test/Util/TvCategoryParserTests.cs b/src/Jackett.Test/Util/TvCategoryParserTests.cs new file mode 100644 index 000000000..95d9c6f28 --- /dev/null +++ b/src/Jackett.Test/Util/TvCategoryParserTests.cs @@ -0,0 +1,27 @@ +using NUnit.Framework; +using Jackett.Utils; + +namespace JackettTest.Util +{ + [TestFixture] + internal class ParseTvShowQualityTest : TestBase + { + [TestCase("Chuck.S04E05.HDTV.XviD-LOL", 5030)] + [TestCase("Gold.Rush.S04E05.Garnets.or.Gold.REAL.REAL.PROPER.HDTV.x264-W4F", 5030)] + [TestCase("Chuck.S03E17.REAL.PROPER.720p.HDTV.x264-ORENJI-RP", 5040)] + [TestCase("Covert.Affairs.S05E09.REAL.PROPER.HDTV.x264-KILLERS", 5030)] + [TestCase("Mythbusters.S14E01.REAL.PROPER.720p.HDTV.x264-KILLERS", 5040)] + [TestCase("Orange.Is.the.New.Black.s02e06.real.proper.720p.webrip.x264-2hd", 5040)] + [TestCase("Top.Gear.S21E07.Super.Duper.Real.Proper.HDTV.x264-FTP", 5030)] + [TestCase("Top.Gear.S21E07.PROPER.HDTV.x264-RiVER-RP", 5030)] + [TestCase("House.S07E11.PROPER.REAL.RERIP.1080p.BluRay.x264-TENEIGHTY", 5040)] + [TestCase("The.Blacklist.S02E05", 5000)] + [TestCase("The.IT.Crowd.S01.DVD.REMUX.DD2.0.MPEG2-DTG", 5030)] + + public void should_parse_quality_from_title(string title, int quality) + { + Assert.That(TvCategoryParser.ParseTvShowQuality(title), Is.EqualTo(quality)); + } + } +} + diff --git a/src/Jackett/Jackett.csproj b/src/Jackett/Jackett.csproj index ad65375f4..c893c46ba 100644 --- a/src/Jackett/Jackett.csproj +++ b/src/Jackett/Jackett.csproj @@ -311,6 +311,7 @@ + diff --git a/src/Jackett/Utils/TvCategoryParser.cs b/src/Jackett/Utils/TvCategoryParser.cs new file mode 100644 index 000000000..a45902f97 --- /dev/null +++ b/src/Jackett/Utils/TvCategoryParser.cs @@ -0,0 +1,115 @@ +//Regex sourced from Sonarr - https://github.com/Sonarr/Sonarr/blob/develop/src/NzbDrone.Core/Parser/QualityParser.cs + +using System.Text.RegularExpressions; +using Jackett.Models; + +namespace Jackett.Utils +{ + public static class TvCategoryParser + { + + private static readonly Regex SourceRegex = new Regex(@"\b(?: + (?BluRay|Blu-Ray|HDDVD|BD)| + (?WEB[-_. ]DL|WEBDL|WebRip|iTunesHD|WebHD)| + (?HDTV)| + (?BDRip)| + (?BRRip)| + (?DVD|DVDRip|NTSC|PAL|xvidvd)| + (?WS[-_. ]DSR|DSR)| + (?PDTV)| + (?SDTV)| + (?TVRip) + )\b", + RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); + + private static readonly Regex RawHdRegex = new Regex(@"\b(?TrollHD|RawHD|1080i[-_. ]HDTV|Raw[-_. ]HD|MPEG[-_. ]?2)\b", + RegexOptions.Compiled | RegexOptions.IgnoreCase); + + private static readonly Regex ResolutionRegex = new Regex(@"\b(?:(?480p|640x480|848x480)|(?576p)|(?720p|1280x720)|(?1080p|1920x1080))\b", + RegexOptions.Compiled | RegexOptions.IgnoreCase); + + private static readonly Regex CodecRegex = new Regex(@"\b(?:(?x264)|(?h264)|(?XvidHD)|(?Xvid)|(?divx))\b", + RegexOptions.Compiled | RegexOptions.IgnoreCase); + + private static readonly Regex HighDefPdtvRegex = new Regex(@"hr[-_. ]ws", RegexOptions.Compiled | RegexOptions.IgnoreCase); + + + + public static int ParseTvShowQuality(string tvShowFileName) + { + string normalizedName = tvShowFileName.Trim().Replace('_', ' ').Trim().ToLower(); + + var sourceMatch = SourceRegex.Match(normalizedName); + var resolutionMatch = ResolutionRegex.Match(normalizedName); + var codecMatch = CodecRegex.Match(normalizedName); + + if (sourceMatch.Groups["webdl"].Success) + { + if (resolutionMatch.Groups["q1080p"].Success || resolutionMatch.Groups["q720p"].Success) + { + return TorznabCatType.TVHD.ID; + } + + if (resolutionMatch.Groups["q480p"].Success) + { + return TorznabCatType.TVSD.ID; + } + } + + if (sourceMatch.Groups["hdtv"].Success) + { + if (resolutionMatch.Groups["q1080p"].Success || resolutionMatch.Groups["q720p"].Success) + { + return TorznabCatType.TVHD.ID; + } + else + { + return TorznabCatType.TVSD.ID; + } + } + + if (sourceMatch.Groups["bluray"].Success || sourceMatch.Groups["bdrip"].Success || sourceMatch.Groups["brrip"].Success) + { + if (codecMatch.Groups["xvid"].Success || codecMatch.Groups["divx"].Success) + { + return TorznabCatType.TVSD.ID; + } + + if (resolutionMatch.Groups["q1080p"].Success || resolutionMatch.Groups["q720p"].Success) + { + return TorznabCatType.TVHD.ID; + } + + if (resolutionMatch.Groups["q480p"].Success || resolutionMatch.Groups["q576p"].Success) + { + return TorznabCatType.TVSD.ID; + } + } + + if (sourceMatch.Groups["dvd"].Success) + { + return TorznabCatType.TVSD.ID; + } + + if (sourceMatch.Groups["pdtv"].Success || sourceMatch.Groups["sdtv"].Success || sourceMatch.Groups["dsr"].Success || sourceMatch.Groups["tvrip"].Success) + { + if (HighDefPdtvRegex.IsMatch(normalizedName)) + { + return TorznabCatType.TVHD.ID; + } + else + { + return TorznabCatType.TVSD.ID; + } + } + + if (RawHdRegex.IsMatch(normalizedName)) + { + return TorznabCatType.TVHD.ID; + } + + return TorznabCatType.TV.ID; + } + + } +}