From 0a1ea0019daf1cfb2fb069177a9de13091af1260 Mon Sep 17 00:00:00 2001 From: Jeff Byrnes Date: Sun, 16 Jul 2023 21:40:03 -0400 Subject: [PATCH] New: Add ALAC 24bit --- .../072_add_alac_24_quality_in_profiles.cs | 149 ++++++++++++++++++ src/NzbDrone.Core/Parser/QualityParser.cs | 21 +-- .../Qualities/QualityProfileService.cs | 8 +- src/NzbDrone.Core/Qualities/Quality.cs | 7 +- 4 files changed, 163 insertions(+), 22 deletions(-) create mode 100644 src/NzbDrone.Core/Datastore/Migration/072_add_alac_24_quality_in_profiles.cs diff --git a/src/NzbDrone.Core/Datastore/Migration/072_add_alac_24_quality_in_profiles.cs b/src/NzbDrone.Core/Datastore/Migration/072_add_alac_24_quality_in_profiles.cs new file mode 100644 index 000000000..9d7b619e5 --- /dev/null +++ b/src/NzbDrone.Core/Datastore/Migration/072_add_alac_24_quality_in_profiles.cs @@ -0,0 +1,149 @@ +using System.Collections.Generic; +using System.Data; +using System.Linq; +using FluentMigrator; +using Newtonsoft.Json; +using NzbDrone.Common.Serializer; +using NzbDrone.Core.Datastore.Migration.Framework; + +namespace NzbDrone.Core.Datastore.Migration +{ + [Migration(072)] + public class add_alac_24_quality_in_profiles : NzbDroneMigrationBase + { + protected override void MainDbUpgrade() + { + Execute.WithConnection(ConvertProfile); + } + + private void ConvertProfile(IDbConnection conn, IDbTransaction tran) + { + var updater = new QualityProfileUpdater72(conn, tran); + + updater.SplitQualityAppend(21, 37); // ALAC_24 after FLAC 24bit + + updater.Commit(); + } + } + + public class QualityProfile72 + { + public int Id { get; set; } + public string Name { get; set; } + public int Cutoff { get; set; } + public List Items { get; set; } + } + + public class QualityProfileItem72 + { + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int Id { get; set; } + public string Name { get; set; } + public int? Quality { get; set; } + public bool Allowed { get; set; } + public List Items { get; set; } + } + + public class QualityProfileUpdater72 + { + private readonly IDbConnection _connection; + private readonly IDbTransaction _transaction; + + private List _profiles; + private HashSet _changedProfiles = new (); + + public QualityProfileUpdater72(IDbConnection conn, IDbTransaction tran) + { + _connection = conn; + _transaction = tran; + + _profiles = GetProfiles(); + } + + public void Commit() + { + foreach (var profile in _changedProfiles) + { + using (var updateProfileCmd = _connection.CreateCommand()) + { + updateProfileCmd.Transaction = _transaction; + updateProfileCmd.CommandText = "UPDATE \"QualityProfiles\" SET \"Name\" = ?, \"Cutoff\" = ?, \"Items\" = ? WHERE \"Id\" = ?"; + updateProfileCmd.AddParameter(profile.Name); + updateProfileCmd.AddParameter(profile.Cutoff); + updateProfileCmd.AddParameter(profile.Items.ToJson()); + updateProfileCmd.AddParameter(profile.Id); + + updateProfileCmd.ExecuteNonQuery(); + } + } + + _changedProfiles.Clear(); + } + + public void SplitQualityAppend(int find, int quality) + { + foreach (var profile in _profiles) + { + if (profile.Items.Any(v => v.Quality == quality) || + profile.Items.Any(v => v.Items != null && v.Items.Any(b => b.Quality == quality))) + { + continue; + } + + foreach (var item in profile.Items.Where(x => x.Items != null)) + { + var findIndex = item.Items.FindIndex(v => v.Quality == find); + + if (findIndex == -1) + { + continue; + } + + item.Items.Insert(findIndex + 1, new QualityProfileItem72 + { + Quality = quality, + Allowed = true + }); + } + + if (!profile.Items.Any(v => v.Items != null && v.Items.Any(b => b.Quality == quality))) + { + profile.Items.Add(new QualityProfileItem72 + { + Quality = quality, + Allowed = false + }); + } + + _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 QualityProfile72 + { + 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 3f0cc4e76..17faab082 100644 --- a/src/NzbDrone.Core/Parser/QualityParser.cs +++ b/src/NzbDrone.Core/Parser/QualityParser.cs @@ -122,18 +122,10 @@ namespace NzbDrone.Core.Parser break; case Codec.FLAC: - if (sampleSize == SampleSize.S24) - { - result.Quality = Quality.FLAC_24; - } - else - { - result.Quality = Quality.FLAC; - } - + result.Quality = sampleSize == SampleSize.S24 ? Quality.FLAC_24 : Quality.FLAC; break; case Codec.ALAC: - result.Quality = Quality.ALAC; + result.Quality = sampleSize == SampleSize.S24 ? Quality.ALAC_24 : Quality.ALAC; break; case Codec.WAVPACK: result.Quality = Quality.WAVPACK; @@ -518,14 +510,9 @@ namespace NzbDrone.Core.Parser return Quality.Unknown; case Codec.FLAC: - if (sampleSize == 24) - { - return Quality.FLAC_24; - } - - return Quality.FLAC; + return sampleSize == 24 ? Quality.FLAC_24 : Quality.FLAC; case Codec.ALAC: - return Quality.ALAC; + return sampleSize == 24 ? Quality.ALAC_24 : Quality.ALAC; case Codec.WAVPACK: return Quality.WAVPACK; case Codec.APE: diff --git a/src/NzbDrone.Core/Profiles/Qualities/QualityProfileService.cs b/src/NzbDrone.Core/Profiles/Qualities/QualityProfileService.cs index 53917818d..484f33b27 100644 --- a/src/NzbDrone.Core/Profiles/Qualities/QualityProfileService.cs +++ b/src/NzbDrone.Core/Profiles/Qualities/QualityProfileService.cs @@ -131,15 +131,17 @@ namespace NzbDrone.Core.Profiles.Qualities Quality.VORBIS_Q9, Quality.VORBIS_Q10, Quality.WMA, - Quality.ALAC, Quality.FLAC, - Quality.FLAC_24); + Quality.ALAC, + Quality.FLAC_24, + Quality.ALAC_24); AddDefaultProfile("Lossless", Quality.FLAC, Quality.FLAC, Quality.ALAC, - Quality.FLAC_24); + Quality.FLAC_24, + Quality.ALAC_24); AddDefaultProfile("Standard", Quality.MP3_192, diff --git a/src/NzbDrone.Core/Qualities/Quality.cs b/src/NzbDrone.Core/Qualities/Quality.cs index 0085b0683..0e30964ca 100644 --- a/src/NzbDrone.Core/Qualities/Quality.cs +++ b/src/NzbDrone.Core/Qualities/Quality.cs @@ -107,6 +107,7 @@ namespace NzbDrone.Core.Qualities public static Quality MP3_224 => new Quality(34, "MP3-224"); // For Current Files Only public static Quality APE => new Quality(35, "APE"); public static Quality WAVPACK => new Quality(36, "WavPack"); + public static Quality ALAC_24 => new Quality(37, "ALAC 24bit"); static Quality() { @@ -143,11 +144,12 @@ namespace NzbDrone.Core.Qualities VORBIS_Q7, VORBIS_Q6, VORBIS_Q5, - ALAC, FLAC, + ALAC, APE, WAVPACK, FLAC_24, + ALAC_24, WAV }; @@ -190,11 +192,12 @@ namespace NzbDrone.Core.Qualities new QualityDefinition(Quality.VORBIS_Q9) { Weight = 20, MinSize = 0, MaxSize = 350, GroupName = "High Quality Lossy", GroupWeight = 6 }, new QualityDefinition(Quality.AAC_320) { Weight = 20, MinSize = 0, MaxSize = 350, GroupName = "High Quality Lossy", GroupWeight = 6 }, new QualityDefinition(Quality.VORBIS_Q10) { Weight = 21, MinSize = 0, MaxSize = 550, GroupName = "High Quality Lossy", GroupWeight = 6 }, - new QualityDefinition(Quality.ALAC) { Weight = 22, MinSize = 0, MaxSize = null, GroupName = "Lossless", GroupWeight = 7 }, new QualityDefinition(Quality.FLAC) { Weight = 22, MinSize = 0, MaxSize = null, GroupName = "Lossless", GroupWeight = 7 }, + new QualityDefinition(Quality.ALAC) { Weight = 22, MinSize = 0, MaxSize = null, GroupName = "Lossless", GroupWeight = 7 }, new QualityDefinition(Quality.APE) { Weight = 22, MinSize = 0, MaxSize = null, GroupName = "Lossless", GroupWeight = 7 }, new QualityDefinition(Quality.WAVPACK) { Weight = 22, MinSize = 0, MaxSize = null, GroupName = "Lossless", GroupWeight = 7 }, new QualityDefinition(Quality.FLAC_24) { Weight = 23, MinSize = 0, MaxSize = null, GroupName = "Lossless", GroupWeight = 7 }, + new QualityDefinition(Quality.ALAC_24) { Weight = 23, MinSize = 0, MaxSize = null, GroupName = "Lossless", GroupWeight = 7 }, new QualityDefinition(Quality.WAV) { Weight = 24, MinSize = 0, MaxSize = null, GroupWeight = 8 } }; }