diff --git a/src/NzbDrone.Core.Test/Datastore/Migration/214_add_bluray576p_in_profileFixture.cs b/src/NzbDrone.Core.Test/Datastore/Migration/214_add_bluray576p_in_profileFixture.cs new file mode 100644 index 000000000..8fd403b91 --- /dev/null +++ b/src/NzbDrone.Core.Test/Datastore/Migration/214_add_bluray576p_in_profileFixture.cs @@ -0,0 +1,41 @@ +using System.Linq; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Datastore.Migration; +using NzbDrone.Core.Qualities; +using NzbDrone.Core.Test.Framework; + +namespace NzbDrone.Core.Test.Datastore.Migration +{ + [TestFixture] + public class add_bluray576p_in_profileFixture : MigrationTest + { + private string GenerateQualityJson(int quality, bool allowed) + { + return $"{{ \"quality\": {quality}, \"allowed\": {allowed.ToString().ToLowerInvariant()} }}"; + } + + [Test] + public void should_add_bluray576p_to_old_profile() + { + var db = WithMigrationTestDb(c => + { + c.Insert.IntoTable("QualityProfiles").Row(new + { + Id = 0, + Name = "Bluray", + Cutoff = 7, + Items = $"[{GenerateQualityJson((int)Quality.DVD, true)}, {GenerateQualityJson((int)Quality.Bluray480p, true)}, {GenerateQualityJson((int)Quality.Bluray720p, false)}]" + }); + }); + + var profiles = db.Query("SELECT \"Items\" FROM \"QualityProfiles\" LIMIT 1"); + + var items = profiles.First().Items; + items.Should().HaveCount(4); + items.Select(v => v.Quality).Should().Equal((int)Quality.DVD, (int)Quality.Bluray480p, (int)Quality.Bluray576p, (int)Quality.Bluray720p); + items.Select(v => v.Allowed).Should().Equal(true, true, true, false); + items.Select(v => v.Name).Should().Equal(null, null, null, null); + } + } +} diff --git a/src/NzbDrone.Core.Test/ParserTests/QualityParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/QualityParserFixture.cs index 98475053a..b9f99a146 100644 --- a/src/NzbDrone.Core.Test/ParserTests/QualityParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/QualityParserFixture.cs @@ -15,6 +15,7 @@ public class QualityParserFixture : CoreTest new object[] { Quality.DVD }, new object[] { Quality.WEBDL480p }, new object[] { Quality.Bluray480p }, + new object[] { Quality.Bluray576p }, new object[] { Quality.HDTV720p }, new object[] { Quality.HDTV1080p }, new object[] { Quality.HDTV2160p }, @@ -105,7 +106,6 @@ public void should_parse_webdl480p_quality(string title, bool proper) [TestCase("SERIES.S03E01-06.DUAL.BDRip.AC3.-HELLYWOOD", false)] [TestCase("SERIES.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD.avi", false)] [TestCase("SERIES.S03E01-06.DUAL.XviD.Bluray.AC3.-HELLYWOOD.avi", false)] - [TestCase("The.Series.S01E05.576p.BluRay.DD5.1.x264-HiSD", false)] [TestCase("The.Series.S01E05.480p.BluRay.DD5.1.x264-HiSD", false)] [TestCase("The Series (BD)(640x480(RAW) (BATCH 1) (1-13)", false)] [TestCase("[Doki] Series - 02 (848x480 XviD BD MP3) [95360783]", false)] @@ -124,6 +124,12 @@ public void should_parse_webrip480p_quality(string title, bool proper) ParseAndVerifyQuality(title, Quality.WEBRip480p, proper); } + [TestCase("The.Series.S01E05.576p.BluRay.DD5.1.x264-HiSD", false)] + public void should_parse_bluray576p_quality(string title, bool proper) + { + ParseAndVerifyQuality(title, Quality.Bluray576p, proper); + } + [TestCase("Series - S01E01 - Title [HDTV]", false)] [TestCase("Series - S01E01 - Title [HDTV-720p]", false)] [TestCase("The Series S04E87 REPACK 720p HDTV x264 aAF", true)] diff --git a/src/NzbDrone.Core/Datastore/Migration/214_add_blurary576p_quality_in_profiles.cs b/src/NzbDrone.Core/Datastore/Migration/214_add_blurary576p_quality_in_profiles.cs new file mode 100644 index 000000000..8024313cd --- /dev/null +++ b/src/NzbDrone.Core/Datastore/Migration/214_add_blurary576p_quality_in_profiles.cs @@ -0,0 +1,131 @@ +using System.Collections.Generic; +using System.Data; +using System.Linq; +using Dapper; +using FluentMigrator; +using Newtonsoft.Json; +using NzbDrone.Common.Serializer; +using NzbDrone.Core.Datastore.Migration.Framework; + +namespace NzbDrone.Core.Datastore.Migration +{ + [Migration(214)] + public class add_blurary576p_quality_in_profiles : NzbDroneMigrationBase + { + protected override void MainDbUpgrade() + { + Execute.WithConnection(ConvertProfile); + } + + private void ConvertProfile(IDbConnection conn, IDbTransaction tran) + { + var updater = new ProfileUpdater214(conn, tran); + + updater.InsertQualityAfter(13, 22); // Group Bluray576p with Bluray480p + updater.Commit(); + } + } + + public class Profile214 + { + public int Id { get; set; } + public string Name { get; set; } + public int Cutoff { get; set; } + public List Items { get; set; } + } + + public class ProfileItem214 + { + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int Id { get; set; } + + public string Name { get; set; } + public int? Quality { get; set; } + public List Items { get; set; } + public bool Allowed { get; set; } + + public ProfileItem214() + { + Items = new List(); + } + } + + public class ProfileUpdater214 + { + private readonly IDbConnection _connection; + private readonly IDbTransaction _transaction; + + private List _profiles; + private HashSet _changedProfiles = new HashSet(); + + public ProfileUpdater214(IDbConnection conn, IDbTransaction tran) + { + _connection = conn; + _transaction = tran; + + _profiles = GetProfiles(); + } + + public void Commit() + { + var profilesToUpdate = _changedProfiles.Select(p => new + { + Id = p.Id, + Name = p.Name, + Cutoff = p.Cutoff, + Items = p.Items.ToJson() + }); + + var updateSql = $"UPDATE \"QualityProfiles\" SET \"Name\" = @Name, \"Cutoff\" = @Cutoff, \"Items\" = @Items WHERE \"Id\" = @Id"; + _connection.Execute(updateSql, profilesToUpdate, transaction: _transaction); + + _changedProfiles.Clear(); + } + + public void InsertQualityAfter(int find, int quality) + { + foreach (var profile in _profiles) + { + var findIndex = profile.Items.FindIndex(v => v.Quality == find); + + if (findIndex > -1) + { + profile.Items.Insert(findIndex + 1, new ProfileItem214 + { + Quality = quality, + Allowed = profile.Items[findIndex].Allowed + }); + } + + _changedProfiles.Add(profile); + } + } + + private List GetProfiles() + { + var profiles = new List(); + + using (var getProfilesCmd = _connection.CreateCommand()) + { + getProfilesCmd.Transaction = _transaction; + getProfilesCmd.CommandText = "SELECT \"Id\", \"Name\", \"Cutoff\", \"Items\" FROM \"QualityProfiles\""; + + using (var profileReader = getProfilesCmd.ExecuteReader()) + { + while (profileReader.Read()) + { + profiles.Add(new Profile214 + { + Id = profileReader.GetInt32(0), + Name = profileReader.GetString(1), + Cutoff = profileReader.GetInt32(2), + Items = Json.Deserialize>(profileReader.GetString(3)) + }); + } + } + } + + return profiles; + } + } +} diff --git a/src/NzbDrone.Core/Parser/QualityParser.cs b/src/NzbDrone.Core/Parser/QualityParser.cs index 575727297..d922d86ce 100644 --- a/src/NzbDrone.Core/Parser/QualityParser.cs +++ b/src/NzbDrone.Core/Parser/QualityParser.cs @@ -147,8 +147,14 @@ public static QualityModel ParseQualityName(string name) return result; } - if (resolution == Resolution.R360P || resolution == Resolution.R480P || - resolution == Resolution.R540p || resolution == Resolution.R576p) + if (resolution == Resolution.R576p) + { + result.Quality = Quality.Bluray576p; + return result; + } + + if (resolution == Resolution.R360p || resolution == Resolution.R480p || + resolution == Resolution.R540p) { result.Quality = Quality.Bluray480p; return result; @@ -315,7 +321,7 @@ public static QualityModel ParseQualityName(string name) { result.SourceDetectionSource = QualityDetectionSource.Unknown; - if (resolution == Resolution.R480P) + if (resolution == Resolution.R480p) { result.Quality = Quality.Bluray480p; return result; @@ -345,7 +351,7 @@ public static QualityModel ParseQualityName(string name) { result.SourceDetectionSource = QualityDetectionSource.Name; - if (resolution == Resolution.R360P || resolution == Resolution.R480P || + if (resolution == Resolution.R360p || resolution == Resolution.R480p || resolution == Resolution.R540p || resolution == Resolution.R576p || normalizedName.ContainsIgnoreCase("480p")) { @@ -387,7 +393,7 @@ public static QualityModel ParseQualityName(string name) { result.SourceDetectionSource = QualityDetectionSource.Name; - if (resolution == Resolution.R360P || resolution == Resolution.R480P || + if (resolution == Resolution.R360p || resolution == Resolution.R480p || resolution == Resolution.R540p || resolution == Resolution.R576p || normalizedName.ContainsIgnoreCase("480p")) { @@ -477,7 +483,7 @@ public static QualityModel ParseQualityName(string name) return result; } - if (resolution == Resolution.R360P || resolution == Resolution.R480P || + if (resolution == Resolution.R360p || resolution == Resolution.R480p || resolution == Resolution.R540p || resolution == Resolution.R576p) { result.ResolutionDetectionSource = QualityDetectionSource.Name; @@ -603,12 +609,12 @@ private static Resolution ParseResolution(string name) if (match.Groups["R360p"].Success) { - return Resolution.R360P; + return Resolution.R360p; } if (match.Groups["R480p"].Success) { - return Resolution.R480P; + return Resolution.R480p; } if (match.Groups["R540p"].Success) @@ -707,8 +713,8 @@ private static QualityModel ParseQualityModifiers(string name, string normalized public enum Resolution { - R360P = 360, - R480P = 480, + R360p = 360, + R480p = 480, R540p = 540, R576p = 576, R720p = 720, diff --git a/src/NzbDrone.Core/Profiles/Qualities/QualityProfileService.cs b/src/NzbDrone.Core/Profiles/Qualities/QualityProfileService.cs index c53362b47..4fb494c56 100644 --- a/src/NzbDrone.Core/Profiles/Qualities/QualityProfileService.cs +++ b/src/NzbDrone.Core/Profiles/Qualities/QualityProfileService.cs @@ -98,6 +98,8 @@ public void Handle(ApplicationStartedEvent message) Quality.WEBRip480p, Quality.WEBDL480p, Quality.DVD, + Quality.Bluray480p, + Quality.Bluray576p, Quality.HDTV720p, Quality.HDTV1080p, Quality.WEBRip720p, @@ -112,7 +114,9 @@ public void Handle(ApplicationStartedEvent message) Quality.SDTV, Quality.WEBRip480p, Quality.WEBDL480p, - Quality.DVD); + Quality.DVD, + Quality.Bluray480p, + Quality.Bluray576p); AddDefaultProfile("HD-720p", Quality.HDTV720p, diff --git a/src/NzbDrone.Core/Qualities/Quality.cs b/src/NzbDrone.Core/Qualities/Quality.cs index c04f8d1d7..c8537840b 100644 --- a/src/NzbDrone.Core/Qualities/Quality.cs +++ b/src/NzbDrone.Core/Qualities/Quality.cs @@ -97,6 +97,11 @@ public static Quality Bluray480p get { return new Quality(13, "Bluray-480p", QualitySource.Bluray, 480); } } + public static Quality Bluray576p + { + get { return new Quality(22, "Bluray-576p", QualitySource.Bluray, 576); } + } + public static Quality WEBRip720p { get { return new Quality(14, "WEBRip-720p", QualitySource.WebRip, 720); } @@ -128,6 +133,7 @@ static Quality() WEBRip480p, WEBDL480p, Bluray480p, + Bluray576p, HDTV720p, WEBRip720p, WEBDL720p, @@ -153,23 +159,24 @@ static Quality() new QualityDefinition(Quality.SDTV) { Weight = 2, MinSize = 2, MaxSize = 100, PreferredSize = 95 }, new QualityDefinition(Quality.WEBRip480p) { Weight = 3, MinSize = 2, MaxSize = 100, PreferredSize = 95, GroupName = "WEB 480p" }, new QualityDefinition(Quality.WEBDL480p) { Weight = 3, MinSize = 2, MaxSize = 100, PreferredSize = 95, GroupName = "WEB 480p" }, - new QualityDefinition(Quality.DVD) { Weight = 4, MinSize = 2, MaxSize = 100, PreferredSize = 95, GroupName = "DVD" }, - new QualityDefinition(Quality.Bluray480p) { Weight = 5, MinSize = 2, MaxSize = 100, PreferredSize = 95, GroupName = "DVD" }, - new QualityDefinition(Quality.HDTV720p) { Weight = 6, MinSize = 3, MaxSize = 125, PreferredSize = 95 }, - new QualityDefinition(Quality.HDTV1080p) { Weight = 7, MinSize = 4, MaxSize = 125, PreferredSize = 95 }, - new QualityDefinition(Quality.RAWHD) { Weight = 8, MinSize = 4, MaxSize = null, PreferredSize = 95 }, - new QualityDefinition(Quality.WEBRip720p) { Weight = 9, MinSize = 3, MaxSize = 130, PreferredSize = 95, GroupName = "WEB 720p" }, - new QualityDefinition(Quality.WEBDL720p) { Weight = 9, MinSize = 3, MaxSize = 130, PreferredSize = 95, GroupName = "WEB 720p" }, - new QualityDefinition(Quality.Bluray720p) { Weight = 10, MinSize = 4, MaxSize = 130, PreferredSize = 95 }, - new QualityDefinition(Quality.WEBRip1080p) { Weight = 11, MinSize = 4, MaxSize = 130, PreferredSize = 95, GroupName = "WEB 1080p" }, - new QualityDefinition(Quality.WEBDL1080p) { Weight = 11, MinSize = 4, MaxSize = 130, PreferredSize = 95, GroupName = "WEB 1080p" }, - new QualityDefinition(Quality.Bluray1080p) { Weight = 12, MinSize = 4, MaxSize = 155, PreferredSize = 95 }, - new QualityDefinition(Quality.Bluray1080pRemux) { Weight = 13, MinSize = 35, MaxSize = null, PreferredSize = 95 }, - new QualityDefinition(Quality.HDTV2160p) { Weight = 14, MinSize = 35, MaxSize = 199.9, PreferredSize = 95 }, - new QualityDefinition(Quality.WEBRip2160p) { Weight = 15, MinSize = 35, MaxSize = null, PreferredSize = 95, GroupName = "WEB 2160p" }, - new QualityDefinition(Quality.WEBDL2160p) { Weight = 15, MinSize = 35, MaxSize = null, PreferredSize = 95, GroupName = "WEB 2160p" }, - new QualityDefinition(Quality.Bluray2160p) { Weight = 16, MinSize = 35, MaxSize = null, PreferredSize = 95 }, - new QualityDefinition(Quality.Bluray2160pRemux) { Weight = 17, MinSize = 35, MaxSize = null, PreferredSize = 95 } + new QualityDefinition(Quality.DVD) { Weight = 4, MinSize = 2, MaxSize = 100, PreferredSize = 95 }, + new QualityDefinition(Quality.Bluray480p) { Weight = 5, MinSize = 2, MaxSize = 100, PreferredSize = 95 }, + new QualityDefinition(Quality.Bluray576p) { Weight = 6, MinSize = 2, MaxSize = 100, PreferredSize = 95 }, + new QualityDefinition(Quality.HDTV720p) { Weight = 7, MinSize = 3, MaxSize = 125, PreferredSize = 95 }, + new QualityDefinition(Quality.HDTV1080p) { Weight = 8, MinSize = 4, MaxSize = 125, PreferredSize = 95 }, + new QualityDefinition(Quality.RAWHD) { Weight = 9, MinSize = 4, MaxSize = null, PreferredSize = 95 }, + new QualityDefinition(Quality.WEBRip720p) { Weight = 10, MinSize = 3, MaxSize = 130, PreferredSize = 95, GroupName = "WEB 720p" }, + new QualityDefinition(Quality.WEBDL720p) { Weight = 10, MinSize = 3, MaxSize = 130, PreferredSize = 95, GroupName = "WEB 720p" }, + new QualityDefinition(Quality.Bluray720p) { Weight = 11, MinSize = 4, MaxSize = 130, PreferredSize = 95 }, + new QualityDefinition(Quality.WEBRip1080p) { Weight = 12, MinSize = 4, MaxSize = 130, PreferredSize = 95, GroupName = "WEB 1080p" }, + new QualityDefinition(Quality.WEBDL1080p) { Weight = 12, MinSize = 4, MaxSize = 130, PreferredSize = 95, GroupName = "WEB 1080p" }, + new QualityDefinition(Quality.Bluray1080p) { Weight = 13, MinSize = 4, MaxSize = 155, PreferredSize = 95 }, + new QualityDefinition(Quality.Bluray1080pRemux) { Weight = 14, MinSize = 35, MaxSize = null, PreferredSize = 95 }, + new QualityDefinition(Quality.HDTV2160p) { Weight = 15, MinSize = 35, MaxSize = 199.9, PreferredSize = 95 }, + new QualityDefinition(Quality.WEBRip2160p) { Weight = 16, MinSize = 35, MaxSize = null, PreferredSize = 95, GroupName = "WEB 2160p" }, + new QualityDefinition(Quality.WEBDL2160p) { Weight = 16, MinSize = 35, MaxSize = null, PreferredSize = 95, GroupName = "WEB 2160p" }, + new QualityDefinition(Quality.Bluray2160p) { Weight = 17, MinSize = 35, MaxSize = null, PreferredSize = 95 }, + new QualityDefinition(Quality.Bluray2160pRemux) { Weight = 18, MinSize = 35, MaxSize = null, PreferredSize = 95 } }; }