diff --git a/src/NzbDrone.Core.Test/NotificationTests/NotificationBaseFixture.cs b/src/NzbDrone.Core.Test/NotificationTests/NotificationBaseFixture.cs index b773ada75..2660b90fe 100644 --- a/src/NzbDrone.Core.Test/NotificationTests/NotificationBaseFixture.cs +++ b/src/NzbDrone.Core.Test/NotificationTests/NotificationBaseFixture.cs @@ -5,7 +5,6 @@ using FluentValidation.Results; using NUnit.Framework; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Notifications; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Tv; using NzbDrone.Core.Validation; using NzbDrone.Test.Common; @@ -15,9 +14,9 @@ namespace NzbDrone.Core.Test.NotificationTests [TestFixture] public class NotificationBaseFixture : TestBase { - private class TestSetting : IProviderConfig + private class TestSetting : NotificationSettingsBase { - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(); } diff --git a/src/NzbDrone.Core/Download/Clients/Aria2/Aria2Settings.cs b/src/NzbDrone.Core/Download/Clients/Aria2/Aria2Settings.cs index f90ea6306..d4d01fb69 100644 --- a/src/NzbDrone.Core/Download/Clients/Aria2/Aria2Settings.cs +++ b/src/NzbDrone.Core/Download/Clients/Aria2/Aria2Settings.cs @@ -1,6 +1,5 @@ using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Download.Clients.Aria2 @@ -13,9 +12,9 @@ namespace NzbDrone.Core.Download.Clients.Aria2 } } - public class Aria2Settings : IProviderConfig + public class Aria2Settings : DownloadClientSettingsBase { - private static readonly Aria2SettingsValidator Validator = new Aria2SettingsValidator(); + private static readonly Aria2SettingsValidator Validator = new (); public Aria2Settings() { @@ -44,7 +43,7 @@ namespace NzbDrone.Core.Download.Clients.Aria2 [FieldDefinition(5, Label = "Directory", Type = FieldType.Textbox, HelpText = "DownloadClientAriaSettingsDirectoryHelpText")] public string Directory { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackholeSettings.cs b/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackholeSettings.cs index ad3010a60..95e1ad385 100644 --- a/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackholeSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackholeSettings.cs @@ -2,7 +2,6 @@ using System.ComponentModel; using FluentValidation; using Newtonsoft.Json; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; using NzbDrone.Core.Validation.Paths; @@ -18,7 +17,7 @@ namespace NzbDrone.Core.Download.Clients.Blackhole } } - public class TorrentBlackholeSettings : IProviderConfig + public class TorrentBlackholeSettings : DownloadClientSettingsBase { public TorrentBlackholeSettings() { @@ -26,7 +25,7 @@ namespace NzbDrone.Core.Download.Clients.Blackhole ReadOnly = true; } - private static readonly TorrentBlackholeSettingsValidator Validator = new TorrentBlackholeSettingsValidator(); + private static readonly TorrentBlackholeSettingsValidator Validator = new (); [FieldDefinition(0, Label = "TorrentBlackholeTorrentFolder", Type = FieldType.Path, HelpText = "BlackholeFolderHelpText")] [FieldToken(TokenField.HelpText, "TorrentBlackholeTorrentFolder", "extension", ".torrent")] @@ -48,7 +47,7 @@ namespace NzbDrone.Core.Download.Clients.Blackhole [FieldDefinition(4, Label = "TorrentBlackholeSaveMagnetFilesReadOnly", Type = FieldType.Checkbox, HelpText = "TorrentBlackholeSaveMagnetFilesReadOnlyHelpText")] public bool ReadOnly { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackholeSettings.cs b/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackholeSettings.cs index ae9603b61..7e97c7ae7 100644 --- a/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackholeSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackholeSettings.cs @@ -1,6 +1,5 @@ -using FluentValidation; +using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; using NzbDrone.Core.Validation.Paths; @@ -15,9 +14,9 @@ namespace NzbDrone.Core.Download.Clients.Blackhole } } - public class UsenetBlackholeSettings : IProviderConfig + public class UsenetBlackholeSettings : DownloadClientSettingsBase { - private static readonly UsenetBlackholeSettingsValidator Validator = new UsenetBlackholeSettingsValidator(); + private static readonly UsenetBlackholeSettingsValidator Validator = new (); [FieldDefinition(0, Label = "UsenetBlackholeNzbFolder", Type = FieldType.Path, HelpText = "BlackholeFolderHelpText")] [FieldToken(TokenField.HelpText, "UsenetBlackholeNzbFolder", "extension", ".nzb")] @@ -26,7 +25,7 @@ namespace NzbDrone.Core.Download.Clients.Blackhole [FieldDefinition(1, Label = "BlackholeWatchFolder", Type = FieldType.Path, HelpText = "BlackholeWatchFolderHelpText")] public string WatchFolder { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Download/Clients/Deluge/DelugeSettings.cs b/src/NzbDrone.Core/Download/Clients/Deluge/DelugeSettings.cs index f18643510..b5108cf24 100644 --- a/src/NzbDrone.Core/Download/Clients/Deluge/DelugeSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/Deluge/DelugeSettings.cs @@ -1,6 +1,5 @@ using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Download.Clients.Deluge @@ -17,9 +16,9 @@ namespace NzbDrone.Core.Download.Clients.Deluge } } - public class DelugeSettings : IProviderConfig + public class DelugeSettings : DownloadClientSettingsBase { - private static readonly DelugeSettingsValidator Validator = new DelugeSettingsValidator(); + private static readonly DelugeSettingsValidator Validator = new (); public DelugeSettings() { @@ -67,7 +66,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge [FieldDefinition(11, Label = "DownloadClientDelugeSettingsDirectoryCompleted", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientDelugeSettingsDirectoryCompletedHelpText")] public string CompletedDirectory { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Download/Clients/DownloadClientSettingsBase.cs b/src/NzbDrone.Core/Download/Clients/DownloadClientSettingsBase.cs new file mode 100644 index 000000000..fa68844e1 --- /dev/null +++ b/src/NzbDrone.Core/Download/Clients/DownloadClientSettingsBase.cs @@ -0,0 +1,30 @@ +using System; +using Equ; +using NzbDrone.Core.ThingiProvider; +using NzbDrone.Core.Validation; + +namespace NzbDrone.Core.Download.Clients +{ + public abstract class DownloadClientSettingsBase : IProviderConfig, IEquatable + where TSettings : DownloadClientSettingsBase + { + private static readonly MemberwiseEqualityComparer Comparer = MemberwiseEqualityComparer.ByProperties; + + public abstract NzbDroneValidationResult Validate(); + + public bool Equals(TSettings other) + { + return Comparer.Equals(this as TSettings, other); + } + + public override bool Equals(object obj) + { + return Equals(obj as TSettings); + } + + public override int GetHashCode() + { + return Comparer.GetHashCode(this as TSettings); + } + } +} diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationSettings.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationSettings.cs index 37a3b0148..735d5f2c8 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationSettings.cs @@ -1,8 +1,7 @@ -using System.Text.RegularExpressions; +using System.Text.RegularExpressions; using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Download.Clients.DownloadStation @@ -26,9 +25,9 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation } } - public class DownloadStationSettings : IProviderConfig + public class DownloadStationSettings : DownloadClientSettingsBase { - private static readonly DownloadStationSettingsValidator Validator = new DownloadStationSettingsValidator(); + private static readonly DownloadStationSettingsValidator Validator = new (); [FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)] public string Host { get; set; } @@ -58,7 +57,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation this.Port = 5000; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Download/Clients/Flood/FloodSettings.cs b/src/NzbDrone.Core/Download/Clients/Flood/FloodSettings.cs index f26e19512..4d582f48f 100644 --- a/src/NzbDrone.Core/Download/Clients/Flood/FloodSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/Flood/FloodSettings.cs @@ -3,7 +3,6 @@ using System.Linq; using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.Download.Clients.Flood.Models; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Download.Clients.Flood @@ -17,9 +16,9 @@ namespace NzbDrone.Core.Download.Clients.Flood } } - public class FloodSettings : IProviderConfig + public class FloodSettings : DownloadClientSettingsBase { - private static readonly FloodSettingsValidator Validator = new FloodSettingsValidator(); + private static readonly FloodSettingsValidator Validator = new (); public FloodSettings() { @@ -69,7 +68,7 @@ namespace NzbDrone.Core.Download.Clients.Flood [FieldDefinition(10, Label = "DownloadClientFloodSettingsStartOnAdd", Type = FieldType.Checkbox)] public bool StartOnAdd { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Download/Clients/FreeboxDownload/FreeboxDownloadSettings.cs b/src/NzbDrone.Core/Download/Clients/FreeboxDownload/FreeboxDownloadSettings.cs index 42b645848..b2ae0d160 100644 --- a/src/NzbDrone.Core/Download/Clients/FreeboxDownload/FreeboxDownloadSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/FreeboxDownload/FreeboxDownloadSettings.cs @@ -2,7 +2,6 @@ using System.Text.RegularExpressions; using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; using NzbDrone.Core.Validation.Paths; @@ -34,9 +33,9 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload } } - public class FreeboxDownloadSettings : IProviderConfig + public class FreeboxDownloadSettings : DownloadClientSettingsBase { - private static readonly FreeboxDownloadSettingsValidator Validator = new FreeboxDownloadSettingsValidator(); + private static readonly FreeboxDownloadSettingsValidator Validator = new (); public FreeboxDownloadSettings() { @@ -84,7 +83,7 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload [FieldDefinition(10, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox)] public bool AddPaused { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenSettings.cs b/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenSettings.cs index 8e560720e..390993df8 100644 --- a/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/Hadouken/HadoukenSettings.cs @@ -1,7 +1,6 @@ -using FluentValidation; +using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Download.Clients.Hadouken @@ -22,9 +21,9 @@ namespace NzbDrone.Core.Download.Clients.Hadouken } } - public class HadoukenSettings : IProviderConfig + public class HadoukenSettings : DownloadClientSettingsBase { - private static readonly HadoukenSettingsValidator Validator = new HadoukenSettingsValidator(); + private static readonly HadoukenSettingsValidator Validator = new (); public HadoukenSettings() { @@ -57,7 +56,7 @@ namespace NzbDrone.Core.Download.Clients.Hadouken [FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "DownloadClientSettingsCategoryHelpText")] public string Category { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Download/Clients/NzbVortex/NzbVortexSettings.cs b/src/NzbDrone.Core/Download/Clients/NzbVortex/NzbVortexSettings.cs index 81a72004e..27da7065d 100644 --- a/src/NzbDrone.Core/Download/Clients/NzbVortex/NzbVortexSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/NzbVortex/NzbVortexSettings.cs @@ -1,7 +1,6 @@ -using FluentValidation; +using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Download.Clients.NzbVortex @@ -23,9 +22,9 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex } } - public class NzbVortexSettings : IProviderConfig + public class NzbVortexSettings : DownloadClientSettingsBase { - private static readonly NzbVortexSettingsValidator Validator = new NzbVortexSettingsValidator(); + private static readonly NzbVortexSettingsValidator Validator = new (); public NzbVortexSettings() { @@ -59,7 +58,7 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex [FieldDefinition(6, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(NzbVortexPriority), HelpText = "DownloadClientSettingsOlderPriorityEpisodeHelpText")] public int OlderTvPriority { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Download/Clients/Nzbget/NzbgetSettings.cs b/src/NzbDrone.Core/Download/Clients/Nzbget/NzbgetSettings.cs index 067867b08..035dd0265 100644 --- a/src/NzbDrone.Core/Download/Clients/Nzbget/NzbgetSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/Nzbget/NzbgetSettings.cs @@ -1,7 +1,6 @@ using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Download.Clients.Nzbget @@ -21,9 +20,9 @@ namespace NzbDrone.Core.Download.Clients.Nzbget } } - public class NzbgetSettings : IProviderConfig + public class NzbgetSettings : DownloadClientSettingsBase { - private static readonly NzbgetSettingsValidator Validator = new NzbgetSettingsValidator(); + private static readonly NzbgetSettingsValidator Validator = new (); public NzbgetSettings() { @@ -67,7 +66,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget [FieldDefinition(9, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox, HelpText = "DownloadClientNzbgetSettingsAddPausedHelpText")] public bool AddPaused { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Download/Clients/Pneumatic/PneumaticSettings.cs b/src/NzbDrone.Core/Download/Clients/Pneumatic/PneumaticSettings.cs index 6cd8a2b89..a18ad3a4b 100644 --- a/src/NzbDrone.Core/Download/Clients/Pneumatic/PneumaticSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/Pneumatic/PneumaticSettings.cs @@ -1,6 +1,5 @@ -using FluentValidation; +using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; using NzbDrone.Core.Validation.Paths; @@ -15,9 +14,9 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic } } - public class PneumaticSettings : IProviderConfig + public class PneumaticSettings : DownloadClientSettingsBase { - private static readonly PneumaticSettingsValidator Validator = new PneumaticSettingsValidator(); + private static readonly PneumaticSettingsValidator Validator = new (); [FieldDefinition(0, Label = "DownloadClientPneumaticSettingsNzbFolder", Type = FieldType.Path, HelpText = "DownloadClientPneumaticSettingsNzbFolderHelpText")] public string NzbFolder { get; set; } @@ -25,7 +24,7 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic [FieldDefinition(1, Label = "DownloadClientPneumaticSettingsStrmFolder", Type = FieldType.Path, HelpText = "DownloadClientPneumaticSettingsStrmFolderHelpText")] public string StrmFolder { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentSettings.cs b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentSettings.cs index 2ad3ae163..d87df8f9c 100644 --- a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentSettings.cs @@ -1,7 +1,6 @@ using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Download.Clients.QBittorrent @@ -19,9 +18,9 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent } } - public class QBittorrentSettings : IProviderConfig + public class QBittorrentSettings : DownloadClientSettingsBase { - private static readonly QBittorrentSettingsValidator Validator = new QBittorrentSettingsValidator(); + private static readonly QBittorrentSettingsValidator Validator = new (); public QBittorrentSettings() { @@ -74,7 +73,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent [FieldDefinition(13, Label = "DownloadClientQbittorrentSettingsContentLayout", Type = FieldType.Select, SelectOptions = typeof(QBittorrentContentLayout), HelpText = "DownloadClientQbittorrentSettingsContentLayoutHelpText")] public int ContentLayout { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdSettings.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdSettings.cs index 33d2e3266..98a499ace 100644 --- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdSettings.cs @@ -1,7 +1,6 @@ -using FluentValidation; +using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Download.Clients.Sabnzbd @@ -32,9 +31,9 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd } } - public class SabnzbdSettings : IProviderConfig + public class SabnzbdSettings : DownloadClientSettingsBase { - private static readonly SabnzbdSettingsValidator Validator = new SabnzbdSettingsValidator(); + private static readonly SabnzbdSettingsValidator Validator = new (); public SabnzbdSettings() { @@ -78,7 +77,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd [FieldDefinition(9, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(SabnzbdPriority), HelpText = "DownloadClientSettingsOlderPriorityEpisodeHelpText")] public int OlderTvPriority { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Download/Clients/TorrentSeedConfiguration.cs b/src/NzbDrone.Core/Download/Clients/TorrentSeedConfiguration.cs index 9c4b279dc..8b26f2033 100644 --- a/src/NzbDrone.Core/Download/Clients/TorrentSeedConfiguration.cs +++ b/src/NzbDrone.Core/Download/Clients/TorrentSeedConfiguration.cs @@ -1,10 +1,10 @@ -using System; +using System; namespace NzbDrone.Core.Download.Clients { public class TorrentSeedConfiguration { - public static TorrentSeedConfiguration DefaultConfiguration = new TorrentSeedConfiguration(); + public static TorrentSeedConfiguration DefaultConfiguration = new (); public double? Ratio { get; set; } public TimeSpan? SeedTime { get; set; } diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionSettings.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionSettings.cs index dae92b1b1..4a34df4aa 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionSettings.cs @@ -2,7 +2,6 @@ using System.Text.RegularExpressions; using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Download.Clients.Transmission @@ -24,9 +23,9 @@ namespace NzbDrone.Core.Download.Clients.Transmission } } - public class TransmissionSettings : IProviderConfig + public class TransmissionSettings : DownloadClientSettingsBase { - private static readonly TransmissionSettingsValidator Validator = new TransmissionSettingsValidator(); + private static readonly TransmissionSettingsValidator Validator = new (); public TransmissionSettings() { @@ -72,7 +71,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission [FieldDefinition(10, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox)] public bool AddPaused { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentSettings.cs b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentSettings.cs index 45822a9f0..df2cbf963 100644 --- a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentSettings.cs @@ -1,6 +1,5 @@ using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Download.Clients.RTorrent @@ -17,9 +16,9 @@ namespace NzbDrone.Core.Download.Clients.RTorrent } } - public class RTorrentSettings : IProviderConfig + public class RTorrentSettings : DownloadClientSettingsBase { - private static readonly RTorrentSettingsValidator Validator = new RTorrentSettingsValidator(); + private static readonly RTorrentSettingsValidator Validator = new (); public RTorrentSettings() { @@ -70,7 +69,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent [FieldDefinition(11, Label = "DownloadClientRTorrentSettingsAddStopped", Type = FieldType.Checkbox, HelpText = "DownloadClientRTorrentSettingsAddStoppedHelpText")] public bool AddStopped { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrentSettings.cs b/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrentSettings.cs index 6c77dd873..5bbc89d6e 100644 --- a/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrentSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrentSettings.cs @@ -1,7 +1,6 @@ using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Download.Clients.UTorrent @@ -17,9 +16,9 @@ namespace NzbDrone.Core.Download.Clients.UTorrent } } - public class UTorrentSettings : IProviderConfig + public class UTorrentSettings : DownloadClientSettingsBase { - private static readonly UTorrentSettingsValidator Validator = new UTorrentSettingsValidator(); + private static readonly UTorrentSettingsValidator Validator = new (); public UTorrentSettings() { @@ -65,7 +64,7 @@ namespace NzbDrone.Core.Download.Clients.UTorrent [FieldToken(TokenField.HelpText, "DownloadClientSettingsInitialState", "clientName", "uTorrent")] public int IntialState { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Download/DownloadClientDefinition.cs b/src/NzbDrone.Core/Download/DownloadClientDefinition.cs index 6de6a4f14..e6941479d 100644 --- a/src/NzbDrone.Core/Download/DownloadClientDefinition.cs +++ b/src/NzbDrone.Core/Download/DownloadClientDefinition.cs @@ -1,14 +1,35 @@ -using NzbDrone.Core.Indexers; +using System; +using Equ; +using NzbDrone.Core.Indexers; using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Download { - public class DownloadClientDefinition : ProviderDefinition + public class DownloadClientDefinition : ProviderDefinition, IEquatable { + private static readonly MemberwiseEqualityComparer Comparer = MemberwiseEqualityComparer.ByProperties; + + [MemberwiseEqualityIgnore] public DownloadProtocol Protocol { get; set; } + public int Priority { get; set; } = 1; public bool RemoveCompletedDownloads { get; set; } = true; public bool RemoveFailedDownloads { get; set; } = true; + + public bool Equals(DownloadClientDefinition other) + { + return Comparer.Equals(this, other); + } + + public override bool Equals(object obj) + { + return Equals(obj as DownloadClientDefinition); + } + + public override int GetHashCode() + { + return Comparer.GetHashCode(this); + } } } diff --git a/src/NzbDrone.Core/ImportLists/AniList/AniListSettingsBase.cs b/src/NzbDrone.Core/ImportLists/AniList/AniListSettingsBase.cs index 208a70bf0..1f6b387cc 100644 --- a/src/NzbDrone.Core/ImportLists/AniList/AniListSettingsBase.cs +++ b/src/NzbDrone.Core/ImportLists/AniList/AniListSettingsBase.cs @@ -29,18 +29,17 @@ namespace NzbDrone.Core.ImportLists.AniList } } - public class AniListSettingsBase : IImportListSettings + public class AniListSettingsBase : ImportListSettingsBase where TSettings : AniListSettingsBase { - protected virtual AbstractValidator Validator => new AniListSettingsBaseValidator(); + private static readonly AniListSettingsBaseValidator Validator = new (); public AniListSettingsBase() { - BaseUrl = "https://graphql.anilist.co"; SignIn = "startOAuth"; } - public string BaseUrl { get; set; } + public override string BaseUrl { get; set; } = "https://graphql.anilist.co"; [FieldDefinition(0, Label = "ImportListsSettingsAccessToken", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)] public string AccessToken { get; set; } @@ -54,7 +53,7 @@ namespace NzbDrone.Core.ImportLists.AniList [FieldDefinition(99, Label = "ImportListsAniListSettingsAuthenticateWithAniList", Type = FieldType.OAuth)] public string SignIn { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate((TSettings)this)); } diff --git a/src/NzbDrone.Core/ImportLists/AniList/List/AniListSettings.cs b/src/NzbDrone.Core/ImportLists/AniList/List/AniListSettings.cs index 3f6c34b14..3a2511be0 100644 --- a/src/NzbDrone.Core/ImportLists/AniList/List/AniListSettings.cs +++ b/src/NzbDrone.Core/ImportLists/AniList/List/AniListSettings.cs @@ -1,12 +1,12 @@ using FluentValidation; using NzbDrone.Core.Annotations; +using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.AniList.List { public class AniListSettingsValidator : AniListSettingsBaseValidator { public AniListSettingsValidator() - : base() { RuleFor(c => c.Username).NotEmpty(); @@ -18,10 +18,11 @@ namespace NzbDrone.Core.ImportLists.AniList.List public class AniListSettings : AniListSettingsBase { - public const string sectionImport = "Import List Status"; + public const string SectionImport = "Import List Status"; + + private static readonly AniListSettingsValidator Validator = new (); public AniListSettings() - : base() { ImportCurrent = true; ImportPlanning = true; @@ -29,42 +30,45 @@ namespace NzbDrone.Core.ImportLists.AniList.List ImportFinished = true; } - protected override AbstractValidator Validator => new AniListSettingsValidator(); - [FieldDefinition(1, Label = "Username", HelpText = "ImportListsAniListSettingsUsernameHelpText")] public string Username { get; set; } - [FieldDefinition(2, Label = "ImportListsAniListSettingsImportWatching", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportWatchingHelpText")] + [FieldDefinition(2, Label = "ImportListsAniListSettingsImportWatching", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportWatchingHelpText")] public bool ImportCurrent { get; set; } - [FieldDefinition(3, Label = "ImportListsAniListSettingsImportPlanning", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportPlanningHelpText")] + [FieldDefinition(3, Label = "ImportListsAniListSettingsImportPlanning", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportPlanningHelpText")] public bool ImportPlanning { get; set; } - [FieldDefinition(4, Label = "ImportListsAniListSettingsImportCompleted", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportCompletedHelpText")] + [FieldDefinition(4, Label = "ImportListsAniListSettingsImportCompleted", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportCompletedHelpText")] public bool ImportCompleted { get; set; } - [FieldDefinition(5, Label = "ImportListsAniListSettingsImportDropped", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportDroppedHelpText")] + [FieldDefinition(5, Label = "ImportListsAniListSettingsImportDropped", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportDroppedHelpText")] public bool ImportDropped { get; set; } - [FieldDefinition(6, Label = "ImportListsAniListSettingsImportPaused", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportPausedHelpText")] + [FieldDefinition(6, Label = "ImportListsAniListSettingsImportPaused", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportPausedHelpText")] public bool ImportPaused { get; set; } - [FieldDefinition(7, Label = "ImportListsAniListSettingsImportRepeating", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportRepeatingHelpText")] + [FieldDefinition(7, Label = "ImportListsAniListSettingsImportRepeating", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportRepeatingHelpText")] public bool ImportRepeating { get; set; } - [FieldDefinition(8, Label = "ImportListsAniListSettingsImportFinished", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportFinishedHelpText")] + [FieldDefinition(8, Label = "ImportListsAniListSettingsImportFinished", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportFinishedHelpText")] public bool ImportFinished { get; set; } - [FieldDefinition(9, Label = "ImportListsAniListSettingsImportReleasing", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportReleasingHelpText")] + [FieldDefinition(9, Label = "ImportListsAniListSettingsImportReleasing", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportReleasingHelpText")] public bool ImportReleasing { get; set; } - [FieldDefinition(10, Label = "ImportListsAniListSettingsImportNotYetReleased", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportNotYetReleasedHelpText")] + [FieldDefinition(10, Label = "ImportListsAniListSettingsImportNotYetReleased", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportNotYetReleasedHelpText")] public bool ImportUnreleased { get; set; } - [FieldDefinition(11, Label = "ImportListsAniListSettingsImportCancelled", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportCancelledHelpText")] + [FieldDefinition(11, Label = "ImportListsAniListSettingsImportCancelled", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportCancelledHelpText")] public bool ImportCancelled { get; set; } - [FieldDefinition(12, Label = "ImportListsAniListSettingsImportHiatus", Type = FieldType.Checkbox, Section = sectionImport, HelpText = "ImportListsAniListSettingsImportHiatusHelpText")] + [FieldDefinition(12, Label = "ImportListsAniListSettingsImportHiatus", Type = FieldType.Checkbox, Section = SectionImport, HelpText = "ImportListsAniListSettingsImportHiatusHelpText")] public bool ImportHiatus { get; set; } + + public override NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } } } diff --git a/src/NzbDrone.Core/ImportLists/Custom/CustomSettings.cs b/src/NzbDrone.Core/ImportLists/Custom/CustomSettings.cs index ef3e98f76..86aec5148 100644 --- a/src/NzbDrone.Core/ImportLists/Custom/CustomSettings.cs +++ b/src/NzbDrone.Core/ImportLists/Custom/CustomSettings.cs @@ -13,19 +13,14 @@ namespace NzbDrone.Core.ImportLists.Custom } } - public class CustomSettings : IImportListSettings + public class CustomSettings : ImportListSettingsBase { - private static readonly CustomSettingsValidator Validator = new CustomSettingsValidator(); - - public CustomSettings() - { - BaseUrl = ""; - } + private static readonly CustomSettingsValidator Validator = new (); [FieldDefinition(0, Label = "ImportListsCustomListSettingsUrl", HelpText = "ImportListsCustomListSettingsUrlHelpText")] - public string BaseUrl { get; set; } + public override string BaseUrl { get; set; } = string.Empty; - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/ImportLists/Imdb/ImdbListSettings.cs b/src/NzbDrone.Core/ImportLists/Imdb/ImdbListSettings.cs index 50a7934c0..7ab193e34 100644 --- a/src/NzbDrone.Core/ImportLists/Imdb/ImdbListSettings.cs +++ b/src/NzbDrone.Core/ImportLists/Imdb/ImdbListSettings.cs @@ -14,16 +14,16 @@ namespace NzbDrone.Core.ImportLists.Imdb } } - public class ImdbListSettings : IImportListSettings + public class ImdbListSettings : ImportListSettingsBase { - private static readonly ImdbSettingsValidator Validator = new ImdbSettingsValidator(); + private static readonly ImdbSettingsValidator Validator = new (); - public string BaseUrl { get; set; } + public override string BaseUrl { get; set; } [FieldDefinition(1, Label = "ImportListsImdbSettingsListId", HelpText = "ImportListsImdbSettingsListIdHelpText")] public string ListId { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/ImportLists/ImportListDefinition.cs b/src/NzbDrone.Core/ImportLists/ImportListDefinition.cs index 31b99c23c..5ce3e9f7a 100644 --- a/src/NzbDrone.Core/ImportLists/ImportListDefinition.cs +++ b/src/NzbDrone.Core/ImportLists/ImportListDefinition.cs @@ -1,11 +1,14 @@ using System; +using Equ; using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Tv; namespace NzbDrone.Core.ImportLists { - public class ImportListDefinition : ProviderDefinition + public class ImportListDefinition : ProviderDefinition, IEquatable { + private static readonly MemberwiseEqualityComparer Comparer = MemberwiseEqualityComparer.ByProperties; + public bool EnableAutomaticAdd { get; set; } public bool SearchForMissingEpisodes { get; set; } public MonitorTypes ShouldMonitor { get; set; } @@ -15,10 +18,31 @@ namespace NzbDrone.Core.ImportLists public bool SeasonFolder { get; set; } public string RootFolderPath { get; set; } + [MemberwiseEqualityIgnore] public override bool Enable => EnableAutomaticAdd; + [MemberwiseEqualityIgnore] public ImportListStatus Status { get; set; } + + [MemberwiseEqualityIgnore] public ImportListType ListType { get; set; } + + [MemberwiseEqualityIgnore] public TimeSpan MinRefreshInterval { get; set; } + + public bool Equals(ImportListDefinition other) + { + return Comparer.Equals(this, other); + } + + public override bool Equals(object obj) + { + return Equals(obj as ImportListDefinition); + } + + public override int GetHashCode() + { + return Comparer.GetHashCode(this); + } } } diff --git a/src/NzbDrone.Core/ImportLists/ImportListSettingsBase.cs b/src/NzbDrone.Core/ImportLists/ImportListSettingsBase.cs new file mode 100644 index 000000000..d94726e70 --- /dev/null +++ b/src/NzbDrone.Core/ImportLists/ImportListSettingsBase.cs @@ -0,0 +1,31 @@ +using System; +using Equ; +using NzbDrone.Core.Validation; + +namespace NzbDrone.Core.ImportLists +{ + public abstract class ImportListSettingsBase : IImportListSettings, IEquatable + where TSettings : ImportListSettingsBase + { + private static readonly MemberwiseEqualityComparer Comparer = MemberwiseEqualityComparer.ByProperties; + + public abstract string BaseUrl { get; set; } + + public abstract NzbDroneValidationResult Validate(); + + public bool Equals(TSettings other) + { + return Comparer.Equals(this as TSettings, other); + } + + public override bool Equals(object obj) + { + return Equals(obj as TSettings); + } + + public override int GetHashCode() + { + return Comparer.GetHashCode(this as TSettings); + } + } +} diff --git a/src/NzbDrone.Core/ImportLists/MyAnimeList/MyAnimeListSettings.cs b/src/NzbDrone.Core/ImportLists/MyAnimeList/MyAnimeListSettings.cs index aad6257c8..e4a76733d 100644 --- a/src/NzbDrone.Core/ImportLists/MyAnimeList/MyAnimeListSettings.cs +++ b/src/NzbDrone.Core/ImportLists/MyAnimeList/MyAnimeListSettings.cs @@ -24,16 +24,11 @@ namespace NzbDrone.Core.ImportLists.MyAnimeList } } - public class MyAnimeListSettings : IImportListSettings + public class MyAnimeListSettings : ImportListSettingsBase { - public string BaseUrl { get; set; } + private static readonly MalSettingsValidator Validator = new (); - protected AbstractValidator Validator => new MalSettingsValidator(); - - public MyAnimeListSettings() - { - BaseUrl = "https://api.myanimelist.net/v2"; - } + public override string BaseUrl { get; set; } = "https://api.myanimelist.net/v2"; [FieldDefinition(0, Label = "ImportListsMyAnimeListSettingsListStatus", Type = FieldType.Select, SelectOptions = typeof(MyAnimeListStatus), HelpText = "ImportListsMyAnimeListSettingsListStatusHelpText")] public int ListStatus { get; set; } @@ -50,7 +45,7 @@ namespace NzbDrone.Core.ImportLists.MyAnimeList [FieldDefinition(99, Label = "ImportListsMyAnimeListSettingsAuthenticateWithMyAnimeList", Type = FieldType.OAuth)] public string SignIn { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/ImportLists/Plex/PlexListSettings.cs b/src/NzbDrone.Core/ImportLists/Plex/PlexListSettings.cs index 0ffbdba2a..db5bee7d5 100644 --- a/src/NzbDrone.Core/ImportLists/Plex/PlexListSettings.cs +++ b/src/NzbDrone.Core/ImportLists/Plex/PlexListSettings.cs @@ -14,9 +14,9 @@ namespace NzbDrone.Core.ImportLists.Plex } } - public class PlexListSettings : IImportListSettings + public class PlexListSettings : ImportListSettingsBase { - protected virtual PlexListSettingsValidator Validator => new PlexListSettingsValidator(); + private static readonly PlexListSettingsValidator Validator = new (); public PlexListSettings() { @@ -25,7 +25,7 @@ namespace NzbDrone.Core.ImportLists.Plex public virtual string Scope => ""; - public string BaseUrl { get; set; } + public override string BaseUrl { get; set; } [FieldDefinition(0, Label = "ImportListsSettingsAccessToken", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)] public string AccessToken { get; set; } @@ -33,7 +33,7 @@ namespace NzbDrone.Core.ImportLists.Plex [FieldDefinition(99, Label = "ImportListsPlexSettingsAuthenticateWithPlex", Type = FieldType.OAuth)] public string SignIn { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/ImportLists/Rss/Plex/PlexRssImportSettings.cs b/src/NzbDrone.Core/ImportLists/Rss/Plex/PlexRssImportSettings.cs index d6d2e1709..1df33858f 100644 --- a/src/NzbDrone.Core/ImportLists/Rss/Plex/PlexRssImportSettings.cs +++ b/src/NzbDrone.Core/ImportLists/Rss/Plex/PlexRssImportSettings.cs @@ -12,9 +12,9 @@ namespace NzbDrone.Core.ImportLists.Rss.Plex } } - public class PlexRssImportSettings : RssImportBaseSettings + public class PlexRssImportSettings : RssImportBaseSettings { - private PlexRssImportSettingsValidator Validator => new (); + private static readonly PlexRssImportSettingsValidator Validator = new (); [FieldDefinition(0, Label = "ImportListsSettingsRssUrl", Type = FieldType.Textbox, HelpLink = "https://app.plex.tv/desktop/#!/settings/watchlist")] public override string Url { get; set; } diff --git a/src/NzbDrone.Core/ImportLists/Rss/RssImportBase.cs b/src/NzbDrone.Core/ImportLists/Rss/RssImportBase.cs index f00a66253..ca711b2e2 100644 --- a/src/NzbDrone.Core/ImportLists/Rss/RssImportBase.cs +++ b/src/NzbDrone.Core/ImportLists/Rss/RssImportBase.cs @@ -8,7 +8,7 @@ using NzbDrone.Core.Parser; namespace NzbDrone.Core.ImportLists.Rss { public class RssImportBase : HttpImportListBase - where TSettings : RssImportBaseSettings, new() + where TSettings : RssImportBaseSettings, new() { public override string Name => "RSS List Base"; public override ImportListType ListType => ImportListType.Advanced; @@ -36,7 +36,7 @@ namespace NzbDrone.Core.ImportLists.Rss public override IImportListRequestGenerator GetRequestGenerator() { - return new RssImportRequestGenerator + return new RssImportRequestGenerator { Settings = Settings }; diff --git a/src/NzbDrone.Core/ImportLists/Rss/RssImportBaseSettings.cs b/src/NzbDrone.Core/ImportLists/Rss/RssImportBaseSettings.cs index 9df9d4dd0..caf37e4cc 100644 --- a/src/NzbDrone.Core/ImportLists/Rss/RssImportBaseSettings.cs +++ b/src/NzbDrone.Core/ImportLists/Rss/RssImportBaseSettings.cs @@ -4,7 +4,8 @@ using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.Rss { - public class RssImportSettingsValidator : AbstractValidator + public class RssImportSettingsValidator : AbstractValidator + where TSettings : RssImportBaseSettings { public RssImportSettingsValidator() { @@ -12,18 +13,19 @@ namespace NzbDrone.Core.ImportLists.Rss } } - public class RssImportBaseSettings : IImportListSettings + public class RssImportBaseSettings : ImportListSettingsBase + where TSettings : RssImportBaseSettings { - private RssImportSettingsValidator Validator => new (); + private static readonly RssImportSettingsValidator Validator = new (); - public string BaseUrl { get; set; } + public override string BaseUrl { get; set; } [FieldDefinition(0, Label = "ImportListsSettingsRssUrl", Type = FieldType.Textbox)] public virtual string Url { get; set; } - public virtual NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { - return new NzbDroneValidationResult(Validator.Validate(this)); + return new NzbDroneValidationResult(Validator.Validate(this as TSettings)); } } } diff --git a/src/NzbDrone.Core/ImportLists/Rss/RssImportRequestGenerator.cs b/src/NzbDrone.Core/ImportLists/Rss/RssImportRequestGenerator.cs index f55c181a7..7f35ac58e 100644 --- a/src/NzbDrone.Core/ImportLists/Rss/RssImportRequestGenerator.cs +++ b/src/NzbDrone.Core/ImportLists/Rss/RssImportRequestGenerator.cs @@ -3,9 +3,10 @@ using NzbDrone.Common.Http; namespace NzbDrone.Core.ImportLists.Rss { - public class RssImportRequestGenerator : IImportListRequestGenerator + public class RssImportRequestGenerator : IImportListRequestGenerator + where TSettings : RssImportBaseSettings, new() { - public RssImportBaseSettings Settings { get; set; } + public RssImportBaseSettings Settings { get; set; } public virtual ImportListPageableRequestChain GetListItems() { @@ -18,9 +19,7 @@ namespace NzbDrone.Core.ImportLists.Rss private IEnumerable GetSeriesRequest() { - var request = new ImportListRequest(Settings.Url, HttpAccept.Rss); - - yield return request; + yield return new ImportListRequest(Settings.Url, HttpAccept.Rss); } } } diff --git a/src/NzbDrone.Core/ImportLists/Simkl/SimklSettingsBase.cs b/src/NzbDrone.Core/ImportLists/Simkl/SimklSettingsBase.cs index 13deba893..d0b4cd3e3 100644 --- a/src/NzbDrone.Core/ImportLists/Simkl/SimklSettingsBase.cs +++ b/src/NzbDrone.Core/ImportLists/Simkl/SimklSettingsBase.cs @@ -24,18 +24,17 @@ namespace NzbDrone.Core.ImportLists.Simkl } } - public class SimklSettingsBase : IImportListSettings + public class SimklSettingsBase : ImportListSettingsBase where TSettings : SimklSettingsBase { - protected virtual AbstractValidator Validator => new SimklSettingsBaseValidator(); + private static readonly SimklSettingsBaseValidator Validator = new (); public SimklSettingsBase() { - BaseUrl = "https://api.simkl.com"; SignIn = "startOAuth"; } - public string BaseUrl { get; set; } + public override string BaseUrl { get; set; } = "https://api.simkl.com"; [FieldDefinition(0, Label = "ImportListsSettingsAccessToken", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)] public string AccessToken { get; set; } @@ -52,7 +51,7 @@ namespace NzbDrone.Core.ImportLists.Simkl [FieldDefinition(99, Label = "ImportListsSimklSettingsAuthenticatewithSimkl", Type = FieldType.OAuth)] public string SignIn { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate((TSettings)this)); } diff --git a/src/NzbDrone.Core/ImportLists/Simkl/User/SimklUserSettings.cs b/src/NzbDrone.Core/ImportLists/Simkl/User/SimklUserSettings.cs index d5342c578..7ce5f34ee 100644 --- a/src/NzbDrone.Core/ImportLists/Simkl/User/SimklUserSettings.cs +++ b/src/NzbDrone.Core/ImportLists/Simkl/User/SimklUserSettings.cs @@ -1,12 +1,12 @@ using FluentValidation; using NzbDrone.Core.Annotations; +using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.Simkl.User { public class SimklUserSettingsValidator : SimklSettingsBaseValidator { public SimklUserSettingsValidator() - : base() { RuleFor(c => c.ListType).NotNull(); } @@ -14,7 +14,7 @@ namespace NzbDrone.Core.ImportLists.Simkl.User public class SimklUserSettings : SimklSettingsBase { - protected override AbstractValidator Validator => new SimklUserSettingsValidator(); + private static readonly SimklUserSettingsValidator Validator = new (); public SimklUserSettings() { @@ -27,5 +27,10 @@ namespace NzbDrone.Core.ImportLists.Simkl.User [FieldDefinition(1, Label = "ImportListsSimklSettingsShowType", Type = FieldType.Select, SelectOptions = typeof(SimklUserShowType), HelpText = "ImportListsSimklSettingsShowTypeHelpText")] public int ShowType { get; set; } + + public override NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } } } diff --git a/src/NzbDrone.Core/ImportLists/Sonarr/SonarrSettings.cs b/src/NzbDrone.Core/ImportLists/Sonarr/SonarrSettings.cs index 77772f003..af1bbd0f7 100644 --- a/src/NzbDrone.Core/ImportLists/Sonarr/SonarrSettings.cs +++ b/src/NzbDrone.Core/ImportLists/Sonarr/SonarrSettings.cs @@ -15,13 +15,12 @@ namespace NzbDrone.Core.ImportLists.Sonarr } } - public class SonarrSettings : IImportListSettings + public class SonarrSettings : ImportListSettingsBase { - private static readonly SonarrSettingsValidator Validator = new SonarrSettingsValidator(); + private static readonly SonarrSettingsValidator Validator = new (); public SonarrSettings() { - BaseUrl = ""; ApiKey = ""; ProfileIds = Array.Empty(); LanguageProfileIds = Array.Empty(); @@ -30,7 +29,7 @@ namespace NzbDrone.Core.ImportLists.Sonarr } [FieldDefinition(0, Label = "ImportListsSonarrSettingsFullUrl", HelpText = "ImportListsSonarrSettingsFullUrlHelpText")] - public string BaseUrl { get; set; } + public override string BaseUrl { get; set; } = string.Empty; [FieldDefinition(1, Label = "ApiKey", HelpText = "ImportListsSonarrSettingsApiKeyHelpText")] public string ApiKey { get; set; } @@ -51,7 +50,7 @@ namespace NzbDrone.Core.ImportLists.Sonarr [FieldDefinition(6, Type = FieldType.Select, SelectOptionsProviderAction = "getLanguageProfiles", Label = "Language Profiles", HelpText = "Language Profiles from the source instance to import from")] public IEnumerable LanguageProfileIds { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/ImportLists/Trakt/List/TraktListSettings.cs b/src/NzbDrone.Core/ImportLists/Trakt/List/TraktListSettings.cs index d6fa02405..62da0dd78 100644 --- a/src/NzbDrone.Core/ImportLists/Trakt/List/TraktListSettings.cs +++ b/src/NzbDrone.Core/ImportLists/Trakt/List/TraktListSettings.cs @@ -1,12 +1,12 @@ using FluentValidation; using NzbDrone.Core.Annotations; +using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.Trakt.List { public class TraktListSettingsValidator : TraktSettingsBaseValidator { public TraktListSettingsValidator() - : base() { RuleFor(c => c.Username).NotEmpty(); RuleFor(c => c.Listname).NotEmpty(); @@ -15,12 +15,17 @@ namespace NzbDrone.Core.ImportLists.Trakt.List public class TraktListSettings : TraktSettingsBase { - protected override AbstractValidator Validator => new TraktListSettingsValidator(); + private static readonly TraktListSettingsValidator Validator = new (); [FieldDefinition(1, Label = "Username", HelpText = "ImportListsTraktSettingsUsernameHelpText")] public string Username { get; set; } [FieldDefinition(2, Label = "ImportListsTraktSettingsListName", HelpText = "ImportListsTraktSettingsListNameHelpText")] public string Listname { get; set; } + + public override NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } } } diff --git a/src/NzbDrone.Core/ImportLists/Trakt/Popular/TraktPopularSettings.cs b/src/NzbDrone.Core/ImportLists/Trakt/Popular/TraktPopularSettings.cs index 6d2fef5fb..43e2e994e 100644 --- a/src/NzbDrone.Core/ImportLists/Trakt/Popular/TraktPopularSettings.cs +++ b/src/NzbDrone.Core/ImportLists/Trakt/Popular/TraktPopularSettings.cs @@ -2,13 +2,13 @@ using System.Text.RegularExpressions; using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; +using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.Trakt.Popular { public class TraktPopularSettingsValidator : TraktSettingsBaseValidator { public TraktPopularSettingsValidator() - : base() { RuleFor(c => c.TraktListType).NotNull(); @@ -28,7 +28,7 @@ namespace NzbDrone.Core.ImportLists.Trakt.Popular public class TraktPopularSettings : TraktSettingsBase { - protected override AbstractValidator Validator => new TraktPopularSettingsValidator(); + private static readonly TraktPopularSettingsValidator Validator = new (); public TraktPopularSettings() { @@ -46,5 +46,10 @@ namespace NzbDrone.Core.ImportLists.Trakt.Popular [FieldDefinition(5, Label = "ImportListsTraktSettingsYears", HelpText = "ImportListsTraktSettingsYearsHelpText")] public string Years { get; set; } + + public override NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } } } diff --git a/src/NzbDrone.Core/ImportLists/Trakt/TraktSettingsBase.cs b/src/NzbDrone.Core/ImportLists/Trakt/TraktSettingsBase.cs index 91ebf19be..5b87ef7cf 100644 --- a/src/NzbDrone.Core/ImportLists/Trakt/TraktSettingsBase.cs +++ b/src/NzbDrone.Core/ImportLists/Trakt/TraktSettingsBase.cs @@ -34,19 +34,18 @@ namespace NzbDrone.Core.ImportLists.Trakt } } - public class TraktSettingsBase : IImportListSettings + public class TraktSettingsBase : ImportListSettingsBase where TSettings : TraktSettingsBase { - protected virtual AbstractValidator Validator => new TraktSettingsBaseValidator(); + private static readonly TraktSettingsBaseValidator Validator = new (); public TraktSettingsBase() { - BaseUrl = "https://api.trakt.tv"; SignIn = "startOAuth"; Limit = 100; } - public string BaseUrl { get; set; } + public override string BaseUrl { get; set; } = "https://api.trakt.tv"; [FieldDefinition(0, Label = "ImportListsSettingsAccessToken", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)] public string AccessToken { get; set; } @@ -69,7 +68,7 @@ namespace NzbDrone.Core.ImportLists.Trakt [FieldDefinition(99, Label = "ImportListsTraktSettingsAuthenticateWithTrakt", Type = FieldType.OAuth)] public string SignIn { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate((TSettings)this)); } diff --git a/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserSettings.cs b/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserSettings.cs index 87becf6f0..9272a358d 100644 --- a/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserSettings.cs +++ b/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserSettings.cs @@ -1,12 +1,12 @@ using FluentValidation; using NzbDrone.Core.Annotations; +using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.Trakt.User { public class TraktUserSettingsValidator : TraktSettingsBaseValidator { public TraktUserSettingsValidator() - : base() { RuleFor(c => c.TraktListType).NotNull(); RuleFor(c => c.TraktWatchedListType).NotNull(); @@ -16,7 +16,7 @@ namespace NzbDrone.Core.ImportLists.Trakt.User public class TraktUserSettings : TraktSettingsBase { - protected override AbstractValidator Validator => new TraktUserSettingsValidator(); + private static readonly TraktUserSettingsValidator Validator = new (); public TraktUserSettings() { @@ -36,6 +36,11 @@ namespace NzbDrone.Core.ImportLists.Trakt.User [FieldDefinition(4, Label = "Username", HelpText = "ImportListsTraktSettingsUserListUsernameHelpText")] public string Username { get; set; } + + public override NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } } public enum TraktUserWatchSorting diff --git a/src/NzbDrone.Core/Indexers/BroadcastheNet/BroadcastheNetSettings.cs b/src/NzbDrone.Core/Indexers/BroadcastheNet/BroadcastheNetSettings.cs index e424a46f8..af0169502 100644 --- a/src/NzbDrone.Core/Indexers/BroadcastheNet/BroadcastheNetSettings.cs +++ b/src/NzbDrone.Core/Indexers/BroadcastheNet/BroadcastheNetSettings.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Equ; using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.Languages; @@ -18,7 +19,7 @@ namespace NzbDrone.Core.Indexers.BroadcastheNet } } - public class BroadcastheNetSettings : ITorrentIndexerSettings + public class BroadcastheNetSettings : PropertywiseEquatable, ITorrentIndexerSettings { private static readonly BroadcastheNetSettingsValidator Validator = new (); diff --git a/src/NzbDrone.Core/Indexers/Fanzub/FanzubSettings.cs b/src/NzbDrone.Core/Indexers/Fanzub/FanzubSettings.cs index 57abc672e..fe46ab0dd 100644 --- a/src/NzbDrone.Core/Indexers/Fanzub/FanzubSettings.cs +++ b/src/NzbDrone.Core/Indexers/Fanzub/FanzubSettings.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Equ; using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.Languages; @@ -15,9 +16,9 @@ namespace NzbDrone.Core.Indexers.Fanzub } } - public class FanzubSettings : IIndexerSettings + public class FanzubSettings : PropertywiseEquatable, IIndexerSettings { - private static readonly FanzubSettingsValidator Validator = new FanzubSettingsValidator(); + private static readonly FanzubSettingsValidator Validator = new (); public FanzubSettings() { diff --git a/src/NzbDrone.Core/Indexers/FileList/FileListSettings.cs b/src/NzbDrone.Core/Indexers/FileList/FileListSettings.cs index 13846a25f..1c8c7477d 100644 --- a/src/NzbDrone.Core/Indexers/FileList/FileListSettings.cs +++ b/src/NzbDrone.Core/Indexers/FileList/FileListSettings.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Equ; using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.Languages; @@ -19,9 +20,9 @@ namespace NzbDrone.Core.Indexers.FileList } } - public class FileListSettings : ITorrentIndexerSettings + public class FileListSettings : PropertywiseEquatable, ITorrentIndexerSettings { - private static readonly FileListSettingsValidator Validator = new FileListSettingsValidator(); + private static readonly FileListSettingsValidator Validator = new (); public FileListSettings() { @@ -61,7 +62,7 @@ namespace NzbDrone.Core.Indexers.FileList public int MinimumSeeders { get; set; } [FieldDefinition(7)] - public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings(); + public SeedCriteriaSettings SeedCriteria { get; set; } = new (); [FieldDefinition(8, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)] public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; } diff --git a/src/NzbDrone.Core/Indexers/HDBits/HDBitsSettings.cs b/src/NzbDrone.Core/Indexers/HDBits/HDBitsSettings.cs index 7d90cfa40..8bab1adde 100644 --- a/src/NzbDrone.Core/Indexers/HDBits/HDBitsSettings.cs +++ b/src/NzbDrone.Core/Indexers/HDBits/HDBitsSettings.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Equ; using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.Languages; @@ -18,7 +19,7 @@ namespace NzbDrone.Core.Indexers.HDBits } } - public class HDBitsSettings : ITorrentIndexerSettings + public class HDBitsSettings : PropertywiseEquatable, ITorrentIndexerSettings { private static readonly HDBitsSettingsValidator Validator = new (); diff --git a/src/NzbDrone.Core/Indexers/IPTorrents/IPTorrentsSettings.cs b/src/NzbDrone.Core/Indexers/IPTorrents/IPTorrentsSettings.cs index 841c98ebf..f9db8deec 100644 --- a/src/NzbDrone.Core/Indexers/IPTorrents/IPTorrentsSettings.cs +++ b/src/NzbDrone.Core/Indexers/IPTorrents/IPTorrentsSettings.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text.RegularExpressions; +using Equ; using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; @@ -25,9 +26,9 @@ namespace NzbDrone.Core.Indexers.IPTorrents } } - public class IPTorrentsSettings : ITorrentIndexerSettings + public class IPTorrentsSettings : PropertywiseEquatable, ITorrentIndexerSettings { - private static readonly IPTorrentsSettingsValidator Validator = new IPTorrentsSettingsValidator(); + private static readonly IPTorrentsSettingsValidator Validator = new (); public IPTorrentsSettings() { @@ -42,7 +43,7 @@ namespace NzbDrone.Core.Indexers.IPTorrents public int MinimumSeeders { get; set; } [FieldDefinition(2)] - public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings(); + public SeedCriteriaSettings SeedCriteria { get; set; } = new (); [FieldDefinition(3, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)] public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; } diff --git a/src/NzbDrone.Core/Indexers/IndexerDefinition.cs b/src/NzbDrone.Core/Indexers/IndexerDefinition.cs index 882624ab4..b6e0326d6 100644 --- a/src/NzbDrone.Core/Indexers/IndexerDefinition.cs +++ b/src/NzbDrone.Core/Indexers/IndexerDefinition.cs @@ -1,9 +1,13 @@ +using System; +using Equ; using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Indexers { - public class IndexerDefinition : ProviderDefinition + public class IndexerDefinition : ProviderDefinition, IEquatable { + private static readonly MemberwiseEqualityComparer Comparer = MemberwiseEqualityComparer.ByProperties; + public const int DefaultPriority = 25; public IndexerDefinition() @@ -11,18 +15,41 @@ namespace NzbDrone.Core.Indexers Priority = DefaultPriority; } + [MemberwiseEqualityIgnore] + public DownloadProtocol Protocol { get; set; } + + [MemberwiseEqualityIgnore] + public bool SupportsRss { get; set; } + + [MemberwiseEqualityIgnore] + public bool SupportsSearch { get; set; } + public bool EnableRss { get; set; } public bool EnableAutomaticSearch { get; set; } public bool EnableInteractiveSearch { get; set; } public int DownloadClientId { get; set; } - public DownloadProtocol Protocol { get; set; } - public bool SupportsRss { get; set; } - public bool SupportsSearch { get; set; } public int Priority { get; set; } public int SeasonSearchMaximumSingleEpisodeAge { get; set; } + [MemberwiseEqualityIgnore] public override bool Enable => EnableRss || EnableAutomaticSearch || EnableInteractiveSearch; + [MemberwiseEqualityIgnore] public IndexerStatus Status { get; set; } + + public bool Equals(IndexerDefinition other) + { + return Comparer.Equals(this, other); + } + + public override bool Equals(object obj) + { + return Equals(obj as IndexerDefinition); + } + + public override int GetHashCode() + { + return Comparer.GetHashCode(this); + } } } diff --git a/src/NzbDrone.Core/Indexers/Newznab/NewznabSettings.cs b/src/NzbDrone.Core/Indexers/Newznab/NewznabSettings.cs index b329140ea..36240529d 100644 --- a/src/NzbDrone.Core/Indexers/Newznab/NewznabSettings.cs +++ b/src/NzbDrone.Core/Indexers/Newznab/NewznabSettings.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; +using Equ; using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; @@ -28,7 +29,7 @@ namespace NzbDrone.Core.Indexers.Newznab return settings.BaseUrl != null && ApiKeyWhiteList.Any(c => settings.BaseUrl.ToLowerInvariant().Contains(c)); } - private static readonly Regex AdditionalParametersRegex = new Regex(@"(&.+?\=.+?)+", RegexOptions.Compiled); + private static readonly Regex AdditionalParametersRegex = new (@"(&.+?\=.+?)+", RegexOptions.Compiled); public NewznabSettingsValidator() { @@ -48,9 +49,9 @@ namespace NzbDrone.Core.Indexers.Newznab } } - public class NewznabSettings : IIndexerSettings + public class NewznabSettings : PropertywiseEquatable, IIndexerSettings { - private static readonly NewznabSettingsValidator Validator = new NewznabSettingsValidator(); + private static readonly NewznabSettingsValidator Validator = new (); public NewznabSettings() { diff --git a/src/NzbDrone.Core/Indexers/Nyaa/NyaaSettings.cs b/src/NzbDrone.Core/Indexers/Nyaa/NyaaSettings.cs index 516c34604..d960a77cc 100644 --- a/src/NzbDrone.Core/Indexers/Nyaa/NyaaSettings.cs +++ b/src/NzbDrone.Core/Indexers/Nyaa/NyaaSettings.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text.RegularExpressions; +using Equ; using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.Languages; @@ -19,9 +20,9 @@ namespace NzbDrone.Core.Indexers.Nyaa } } - public class NyaaSettings : ITorrentIndexerSettings + public class NyaaSettings : PropertywiseEquatable, ITorrentIndexerSettings { - private static readonly NyaaSettingsValidator Validator = new NyaaSettingsValidator(); + private static readonly NyaaSettingsValidator Validator = new (); public NyaaSettings() { @@ -44,7 +45,7 @@ namespace NzbDrone.Core.Indexers.Nyaa public int MinimumSeeders { get; set; } [FieldDefinition(4)] - public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings(); + public SeedCriteriaSettings SeedCriteria { get; set; } = new (); [FieldDefinition(5, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)] public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; } diff --git a/src/NzbDrone.Core/Indexers/SeedCriteriaSettings.cs b/src/NzbDrone.Core/Indexers/SeedCriteriaSettings.cs index af9fad86f..877f17222 100644 --- a/src/NzbDrone.Core/Indexers/SeedCriteriaSettings.cs +++ b/src/NzbDrone.Core/Indexers/SeedCriteriaSettings.cs @@ -1,3 +1,4 @@ +using Equ; using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.Validation; @@ -46,7 +47,7 @@ namespace NzbDrone.Core.Indexers } } - public class SeedCriteriaSettings + public class SeedCriteriaSettings : PropertywiseEquatable { [FieldDefinition(0, Type = FieldType.Textbox, Label = "IndexerSettingsSeedRatio", HelpText = "IndexerSettingsSeedRatioHelpText")] public double? SeedRatio { get; set; } diff --git a/src/NzbDrone.Core/Indexers/TorrentRss/TorrentRssIndexerSettings.cs b/src/NzbDrone.Core/Indexers/TorrentRss/TorrentRssIndexerSettings.cs index 5b3d4f3ef..baefcb04b 100644 --- a/src/NzbDrone.Core/Indexers/TorrentRss/TorrentRssIndexerSettings.cs +++ b/src/NzbDrone.Core/Indexers/TorrentRss/TorrentRssIndexerSettings.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Equ; using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.Languages; @@ -17,9 +18,9 @@ namespace NzbDrone.Core.Indexers.TorrentRss } } - public class TorrentRssIndexerSettings : ITorrentIndexerSettings + public class TorrentRssIndexerSettings : PropertywiseEquatable, ITorrentIndexerSettings { - private static readonly TorrentRssIndexerSettingsValidator Validator = new TorrentRssIndexerSettingsValidator(); + private static readonly TorrentRssIndexerSettingsValidator Validator = new (); public TorrentRssIndexerSettings() { @@ -42,7 +43,7 @@ namespace NzbDrone.Core.Indexers.TorrentRss public int MinimumSeeders { get; set; } [FieldDefinition(4)] - public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings(); + public SeedCriteriaSettings SeedCriteria { get; set; } = new (); [FieldDefinition(5, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)] public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; } diff --git a/src/NzbDrone.Core/Indexers/Torrentleech/TorrentleechSettings.cs b/src/NzbDrone.Core/Indexers/Torrentleech/TorrentleechSettings.cs index 47713230d..12415e24a 100644 --- a/src/NzbDrone.Core/Indexers/Torrentleech/TorrentleechSettings.cs +++ b/src/NzbDrone.Core/Indexers/Torrentleech/TorrentleechSettings.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Equ; using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.Languages; @@ -18,9 +19,9 @@ namespace NzbDrone.Core.Indexers.Torrentleech } } - public class TorrentleechSettings : ITorrentIndexerSettings + public class TorrentleechSettings : PropertywiseEquatable, ITorrentIndexerSettings { - private static readonly TorrentleechSettingsValidator Validator = new TorrentleechSettingsValidator(); + private static readonly TorrentleechSettingsValidator Validator = new (); public TorrentleechSettings() { @@ -39,7 +40,7 @@ namespace NzbDrone.Core.Indexers.Torrentleech public int MinimumSeeders { get; set; } [FieldDefinition(3)] - public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings(); + public SeedCriteriaSettings SeedCriteria { get; set; } = new (); [FieldDefinition(4, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)] public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; } diff --git a/src/NzbDrone.Core/Indexers/Torznab/TorznabSettings.cs b/src/NzbDrone.Core/Indexers/Torznab/TorznabSettings.cs index 6a84b59cd..1936529a7 100644 --- a/src/NzbDrone.Core/Indexers/Torznab/TorznabSettings.cs +++ b/src/NzbDrone.Core/Indexers/Torznab/TorznabSettings.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Text.RegularExpressions; +using Equ; using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; @@ -18,7 +19,7 @@ namespace NzbDrone.Core.Indexers.Torznab return settings.BaseUrl != null && ApiKeyWhiteList.Any(c => settings.BaseUrl.ToLowerInvariant().Contains(c)); } - private static readonly Regex AdditionalParametersRegex = new Regex(@"(&.+?\=.+?)+", RegexOptions.Compiled); + private static readonly Regex AdditionalParametersRegex = new (@"(&.+?\=.+?)+", RegexOptions.Compiled); public TorznabSettingsValidator() { @@ -40,9 +41,11 @@ namespace NzbDrone.Core.Indexers.Torznab } } - public class TorznabSettings : NewznabSettings, ITorrentIndexerSettings + public class TorznabSettings : NewznabSettings, ITorrentIndexerSettings, IEquatable { - private static readonly TorznabSettingsValidator Validator = new TorznabSettingsValidator(); + private static readonly TorznabSettingsValidator Validator = new (); + + private static readonly MemberwiseEqualityComparer Comparer = MemberwiseEqualityComparer.ByProperties; public TorznabSettings() { @@ -53,7 +56,7 @@ namespace NzbDrone.Core.Indexers.Torznab public int MinimumSeeders { get; set; } [FieldDefinition(9)] - public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings(); + public SeedCriteriaSettings SeedCriteria { get; set; } = new (); [FieldDefinition(10, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)] public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; } @@ -62,5 +65,20 @@ namespace NzbDrone.Core.Indexers.Torznab { return new NzbDroneValidationResult(Validator.Validate(this)); } + + public bool Equals(TorznabSettings other) + { + return Comparer.Equals(this, other); + } + + public override bool Equals(object obj) + { + return Equals(obj as TorznabSettings); + } + + public override int GetHashCode() + { + return Comparer.GetHashCode(this); + } } } diff --git a/src/NzbDrone.Core/Notifications/Apprise/AppriseSettings.cs b/src/NzbDrone.Core/Notifications/Apprise/AppriseSettings.cs index 3b86e20ed..978305318 100644 --- a/src/NzbDrone.Core/Notifications/Apprise/AppriseSettings.cs +++ b/src/NzbDrone.Core/Notifications/Apprise/AppriseSettings.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Apprise @@ -35,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Apprise } } - public class AppriseSettings : IProviderConfig + public class AppriseSettings : NotificationSettingsBase { private static readonly AppriseSettingsValidator Validator = new (); @@ -66,7 +65,7 @@ namespace NzbDrone.Core.Notifications.Apprise [FieldDefinition(7, Label = "Password", Type = FieldType.Password, HelpText = "NotificationsAppriseSettingsPasswordHelpText", Privacy = PrivacyLevel.Password)] public string AuthPassword { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/CustomScript/CustomScriptSettings.cs b/src/NzbDrone.Core/Notifications/CustomScript/CustomScriptSettings.cs index 8c52308e5..ecd23d76b 100644 --- a/src/NzbDrone.Core/Notifications/CustomScript/CustomScriptSettings.cs +++ b/src/NzbDrone.Core/Notifications/CustomScript/CustomScriptSettings.cs @@ -1,6 +1,5 @@ -using FluentValidation; +using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; using NzbDrone.Core.Validation.Paths; @@ -16,9 +15,9 @@ namespace NzbDrone.Core.Notifications.CustomScript } } - public class CustomScriptSettings : IProviderConfig + public class CustomScriptSettings : NotificationSettingsBase { - private static readonly CustomScriptSettingsValidator Validator = new CustomScriptSettingsValidator(); + private static readonly CustomScriptSettingsValidator Validator = new (); [FieldDefinition(0, Label = "Path", Type = FieldType.FilePath)] public string Path { get; set; } @@ -26,7 +25,7 @@ namespace NzbDrone.Core.Notifications.CustomScript [FieldDefinition(1, Label = "NotificationsCustomScriptSettingsArguments", HelpText = "NotificationsCustomScriptSettingsArgumentsHelpText", Hidden = HiddenType.HiddenIfNotSet)] public string Arguments { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/Discord/DiscordSettings.cs b/src/NzbDrone.Core/Notifications/Discord/DiscordSettings.cs index 8dbb68ba4..ab6e53dcf 100644 --- a/src/NzbDrone.Core/Notifications/Discord/DiscordSettings.cs +++ b/src/NzbDrone.Core/Notifications/Discord/DiscordSettings.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Discord @@ -14,7 +13,7 @@ namespace NzbDrone.Core.Notifications.Discord } } - public class DiscordSettings : IProviderConfig + public class DiscordSettings : NotificationSettingsBase { public DiscordSettings() { @@ -89,7 +88,7 @@ namespace NzbDrone.Core.Notifications.Discord [FieldDefinition(6, Label = "NotificationsDiscordSettingsOnManualInteractionFields", Advanced = true, SelectOptions = typeof(DiscordManualInteractionFieldType), HelpText = "NotificationsDiscordSettingsOnManualInteractionFieldsHelpText", Type = FieldType.Select)] public IEnumerable ManualInteractionFields { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/Email/EmailSettings.cs b/src/NzbDrone.Core/Notifications/Email/EmailSettings.cs index f6b23caad..d01feda74 100644 --- a/src/NzbDrone.Core/Notifications/Email/EmailSettings.cs +++ b/src/NzbDrone.Core/Notifications/Email/EmailSettings.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Email @@ -26,9 +25,9 @@ namespace NzbDrone.Core.Notifications.Email } } - public class EmailSettings : IProviderConfig + public class EmailSettings : NotificationSettingsBase { - private static readonly EmailSettingsValidator Validator = new EmailSettingsValidator(); + private static readonly EmailSettingsValidator Validator = new (); public EmailSettings() { @@ -66,7 +65,7 @@ namespace NzbDrone.Core.Notifications.Email [FieldDefinition(8, Label = "NotificationsEmailSettingsBccAddress", HelpText = "NotificationsEmailSettingsBccAddressHelpText", Advanced = true)] public IEnumerable Bcc { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/Gotify/GotifySettings.cs b/src/NzbDrone.Core/Notifications/Gotify/GotifySettings.cs index 580ae41d1..b152ef5fe 100644 --- a/src/NzbDrone.Core/Notifications/Gotify/GotifySettings.cs +++ b/src/NzbDrone.Core/Notifications/Gotify/GotifySettings.cs @@ -1,6 +1,5 @@ using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Gotify @@ -14,9 +13,9 @@ namespace NzbDrone.Core.Notifications.Gotify } } - public class GotifySettings : IProviderConfig + public class GotifySettings : NotificationSettingsBase { - private static readonly GotifySettingsValidator Validator = new GotifySettingsValidator(); + private static readonly GotifySettingsValidator Validator = new (); public GotifySettings() { @@ -35,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Gotify [FieldDefinition(3, Label = "NotificationsGotifySettingIncludeSeriesPoster", Type = FieldType.Checkbox, HelpText = "NotificationsGotifySettingIncludeSeriesPosterHelpText")] public bool IncludeSeriesPoster { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/Join/JoinSettings.cs b/src/NzbDrone.Core/Notifications/Join/JoinSettings.cs index bd3046240..9bc429014 100644 --- a/src/NzbDrone.Core/Notifications/Join/JoinSettings.cs +++ b/src/NzbDrone.Core/Notifications/Join/JoinSettings.cs @@ -1,6 +1,5 @@ using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Join @@ -14,15 +13,15 @@ namespace NzbDrone.Core.Notifications.Join } } - public class JoinSettings : IProviderConfig + public class JoinSettings : NotificationSettingsBase { + private static readonly JoinSettingsValidator Validator = new (); + public JoinSettings() { Priority = (int)JoinPriority.Normal; } - private static readonly JoinSettingsValidator Validator = new JoinSettingsValidator(); - [FieldDefinition(0, Label = "ApiKey", HelpText = "NotificationsJoinSettingsApiKeyHelpText", HelpLink = "https://joinjoaomgcd.appspot.com/")] public string ApiKey { get; set; } @@ -35,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Join [FieldDefinition(3, Label = "NotificationsJoinSettingsNotificationPriority", Type = FieldType.Select, SelectOptions = typeof(JoinPriority))] public int Priority { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/Mailgun/MailgunSettings.cs b/src/NzbDrone.Core/Notifications/Mailgun/MailgunSettings.cs index 42802abc0..2e267cddd 100644 --- a/src/NzbDrone.Core/Notifications/Mailgun/MailgunSettings.cs +++ b/src/NzbDrone.Core/Notifications/Mailgun/MailgunSettings.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Mailgun @@ -17,9 +16,9 @@ namespace NzbDrone.Core.Notifications.Mailgun } } - public class MailgunSettings : IProviderConfig + public class MailgunSettings : NotificationSettingsBase { - private static readonly MailGunSettingsValidator Validator = new MailGunSettingsValidator(); + private static readonly MailGunSettingsValidator Validator = new (); public MailgunSettings() { @@ -41,7 +40,7 @@ namespace NzbDrone.Core.Notifications.Mailgun [FieldDefinition(4, Label = "NotificationsEmailSettingsRecipientAddress", Type = FieldType.Tag)] public IEnumerable Recipients { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowserSettings.cs b/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowserSettings.cs index 1d04e9054..369888ceb 100644 --- a/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowserSettings.cs +++ b/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowserSettings.cs @@ -2,7 +2,6 @@ using FluentValidation; using Newtonsoft.Json; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Emby @@ -19,9 +18,9 @@ namespace NzbDrone.Core.Notifications.Emby } } - public class MediaBrowserSettings : IProviderConfig + public class MediaBrowserSettings : NotificationSettingsBase { - private static readonly MediaBrowserSettingsValidator Validator = new MediaBrowserSettingsValidator(); + private static readonly MediaBrowserSettingsValidator Validator = new (); public MediaBrowserSettings() { @@ -65,7 +64,7 @@ namespace NzbDrone.Core.Notifications.Emby public bool IsValid => !string.IsNullOrWhiteSpace(Host) && Port > 0; - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/Notifiarr/NotifiarrSettings.cs b/src/NzbDrone.Core/Notifications/Notifiarr/NotifiarrSettings.cs index dd610b3ba..e0faaede2 100644 --- a/src/NzbDrone.Core/Notifications/Notifiarr/NotifiarrSettings.cs +++ b/src/NzbDrone.Core/Notifications/Notifiarr/NotifiarrSettings.cs @@ -1,6 +1,5 @@ using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Notifiarr @@ -13,14 +12,14 @@ namespace NzbDrone.Core.Notifications.Notifiarr } } - public class NotifiarrSettings : IProviderConfig + public class NotifiarrSettings : NotificationSettingsBase { - private static readonly NotifiarrSettingsValidator Validator = new NotifiarrSettingsValidator(); + private static readonly NotifiarrSettingsValidator Validator = new (); [FieldDefinition(0, Label = "ApiKey", Privacy = PrivacyLevel.ApiKey, HelpText = "NotificationsNotifiarrSettingsApiKeyHelpText", HelpLink = "https://notifiarr.com")] public string ApiKey { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/NotificationBase.cs b/src/NzbDrone.Core/Notifications/NotificationBase.cs index 95fabd545..7c5806833 100644 --- a/src/NzbDrone.Core/Notifications/NotificationBase.cs +++ b/src/NzbDrone.Core/Notifications/NotificationBase.cs @@ -8,7 +8,7 @@ using NzbDrone.Core.Tv; namespace NzbDrone.Core.Notifications { public abstract class NotificationBase : INotification - where TSettings : IProviderConfig, new() + where TSettings : NotificationSettingsBase, new() { protected const string EPISODE_GRABBED_TITLE = "Episode Grabbed"; protected const string EPISODE_DOWNLOADED_TITLE = "Episode Downloaded"; diff --git a/src/NzbDrone.Core/Notifications/NotificationDefinition.cs b/src/NzbDrone.Core/Notifications/NotificationDefinition.cs index a18376d0d..d4ab1be49 100644 --- a/src/NzbDrone.Core/Notifications/NotificationDefinition.cs +++ b/src/NzbDrone.Core/Notifications/NotificationDefinition.cs @@ -1,9 +1,13 @@ +using System; +using Equ; using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Notifications { - public class NotificationDefinition : ProviderDefinition + public class NotificationDefinition : ProviderDefinition, IEquatable { + private static readonly MemberwiseEqualityComparer Comparer = MemberwiseEqualityComparer.ByProperties; + public bool OnGrab { get; set; } public bool OnDownload { get; set; } public bool OnUpgrade { get; set; } @@ -13,23 +17,63 @@ namespace NzbDrone.Core.Notifications public bool OnEpisodeFileDelete { get; set; } public bool OnEpisodeFileDeleteForUpgrade { get; set; } public bool OnHealthIssue { get; set; } + public bool IncludeHealthWarnings { get; set; } public bool OnHealthRestored { get; set; } public bool OnApplicationUpdate { get; set; } public bool OnManualInteractionRequired { get; set; } + + [MemberwiseEqualityIgnore] public bool SupportsOnGrab { get; set; } + + [MemberwiseEqualityIgnore] public bool SupportsOnDownload { get; set; } + + [MemberwiseEqualityIgnore] public bool SupportsOnUpgrade { get; set; } + + [MemberwiseEqualityIgnore] public bool SupportsOnRename { get; set; } + + [MemberwiseEqualityIgnore] public bool SupportsOnSeriesAdd { get; set; } + + [MemberwiseEqualityIgnore] public bool SupportsOnSeriesDelete { get; set; } + + [MemberwiseEqualityIgnore] public bool SupportsOnEpisodeFileDelete { get; set; } + + [MemberwiseEqualityIgnore] public bool SupportsOnEpisodeFileDeleteForUpgrade { get; set; } + + [MemberwiseEqualityIgnore] public bool SupportsOnHealthIssue { get; set; } + + [MemberwiseEqualityIgnore] public bool SupportsOnHealthRestored { get; set; } - public bool IncludeHealthWarnings { get; set; } + + [MemberwiseEqualityIgnore] public bool SupportsOnApplicationUpdate { get; set; } + + [MemberwiseEqualityIgnore] public bool SupportsOnManualInteractionRequired { get; set; } + [MemberwiseEqualityIgnore] public override bool Enable => OnGrab || OnDownload || (OnDownload && OnUpgrade) || OnSeriesAdd || OnSeriesDelete || OnEpisodeFileDelete || (OnEpisodeFileDelete && OnEpisodeFileDeleteForUpgrade) || OnHealthIssue || OnHealthRestored || OnApplicationUpdate || OnManualInteractionRequired; + + public bool Equals(NotificationDefinition other) + { + return Comparer.Equals(this, other); + } + + public override bool Equals(object obj) + { + return Equals(obj as NotificationDefinition); + } + + public override int GetHashCode() + { + return Comparer.GetHashCode(this); + } } } diff --git a/src/NzbDrone.Core/Notifications/NotificationSettingsBase.cs b/src/NzbDrone.Core/Notifications/NotificationSettingsBase.cs new file mode 100644 index 000000000..98b5d34b7 --- /dev/null +++ b/src/NzbDrone.Core/Notifications/NotificationSettingsBase.cs @@ -0,0 +1,30 @@ +using System; +using Equ; +using NzbDrone.Core.ThingiProvider; +using NzbDrone.Core.Validation; + +namespace NzbDrone.Core.Notifications +{ + public abstract class NotificationSettingsBase : IProviderConfig, IEquatable + where TSettings : NotificationSettingsBase + { + private static readonly MemberwiseEqualityComparer Comparer = MemberwiseEqualityComparer.ByProperties; + + public abstract NzbDroneValidationResult Validate(); + + public bool Equals(TSettings other) + { + return Comparer.Equals(this as TSettings, other); + } + + public override bool Equals(object obj) + { + return Equals(obj as TSettings); + } + + public override int GetHashCode() + { + return Comparer.GetHashCode(this as TSettings); + } + } +} diff --git a/src/NzbDrone.Core/Notifications/Ntfy/NtfySettings.cs b/src/NzbDrone.Core/Notifications/Ntfy/NtfySettings.cs index 93ccba5ed..0c6075f01 100644 --- a/src/NzbDrone.Core/Notifications/Ntfy/NtfySettings.cs +++ b/src/NzbDrone.Core/Notifications/Ntfy/NtfySettings.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Ntfy @@ -21,12 +20,12 @@ namespace NzbDrone.Core.Notifications.Ntfy RuleForEach(c => c.Topics).NotEmpty().Matches("[a-zA-Z0-9_-]+").Must(c => !InvalidTopics.Contains(c)).WithMessage("Invalid topic"); } - private static List InvalidTopics => new List { "announcements", "app", "docs", "settings", "stats", "mytopic-rw", "mytopic-ro", "mytopic-wo" }; + private static List InvalidTopics => new () { "announcements", "app", "docs", "settings", "stats", "mytopic-rw", "mytopic-ro", "mytopic-wo" }; } - public class NtfySettings : IProviderConfig + public class NtfySettings : NotificationSettingsBase { - private static readonly NtfySettingsValidator Validator = new NtfySettingsValidator(); + private static readonly NtfySettingsValidator Validator = new (); public NtfySettings() { @@ -59,7 +58,7 @@ namespace NzbDrone.Core.Notifications.Ntfy [FieldDefinition(7, Label = "NotificationsNtfySettingsClickUrl", Type = FieldType.Url, HelpText = "NotificationsNtfySettingsClickUrlHelpText")] public string ClickUrl { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/Plex/Server/PlexServerSettings.cs b/src/NzbDrone.Core/Notifications/Plex/Server/PlexServerSettings.cs index de76f9eef..50ba7f757 100644 --- a/src/NzbDrone.Core/Notifications/Plex/Server/PlexServerSettings.cs +++ b/src/NzbDrone.Core/Notifications/Plex/Server/PlexServerSettings.cs @@ -1,7 +1,6 @@ using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Plex.Server @@ -17,9 +16,9 @@ namespace NzbDrone.Core.Notifications.Plex.Server } } - public class PlexServerSettings : IProviderConfig + public class PlexServerSettings : NotificationSettingsBase { - private static readonly PlexServerSettingsValidator Validator = new PlexServerSettingsValidator(); + private static readonly PlexServerSettingsValidator Validator = new (); public PlexServerSettings() { @@ -62,7 +61,7 @@ namespace NzbDrone.Core.Notifications.Plex.Server public bool IsValid => !string.IsNullOrWhiteSpace(Host); - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs b/src/NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs index 4add832cb..0973f202e 100644 --- a/src/NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs +++ b/src/NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs @@ -1,6 +1,5 @@ -using FluentValidation; +using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Prowl @@ -13,9 +12,9 @@ namespace NzbDrone.Core.Notifications.Prowl } } - public class ProwlSettings : IProviderConfig + public class ProwlSettings : NotificationSettingsBase { - private static readonly ProwlSettingsValidator Validator = new ProwlSettingsValidator(); + private static readonly ProwlSettingsValidator Validator = new (); [FieldDefinition(0, Label = "ApiKey", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://www.prowlapp.com/api_settings.php")] public string ApiKey { get; set; } @@ -25,7 +24,7 @@ namespace NzbDrone.Core.Notifications.Prowl public bool IsValid => !string.IsNullOrWhiteSpace(ApiKey) && Priority >= -2 && Priority <= 2; - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs b/src/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs index a50aee65d..67fb8f5a2 100644 --- a/src/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs +++ b/src/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.PushBullet @@ -15,9 +14,9 @@ namespace NzbDrone.Core.Notifications.PushBullet } } - public class PushBulletSettings : IProviderConfig + public class PushBulletSettings : NotificationSettingsBase { - private static readonly PushBulletSettingsValidator Validator = new PushBulletSettingsValidator(); + private static readonly PushBulletSettingsValidator Validator = new (); public PushBulletSettings() { @@ -37,7 +36,7 @@ namespace NzbDrone.Core.Notifications.PushBullet [FieldDefinition(3, Label = "NotificationsPushBulletSettingSenderId", HelpText = "NotificationsPushBulletSettingSenderIdHelpText")] public string SenderId { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/Pushcut/PushcutSettings.cs b/src/NzbDrone.Core/Notifications/Pushcut/PushcutSettings.cs index cb4d44ce7..5b94fcef4 100644 --- a/src/NzbDrone.Core/Notifications/Pushcut/PushcutSettings.cs +++ b/src/NzbDrone.Core/Notifications/Pushcut/PushcutSettings.cs @@ -1,6 +1,5 @@ using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Pushcut @@ -14,7 +13,7 @@ namespace NzbDrone.Core.Notifications.Pushcut } } - public class PushcutSettings : IProviderConfig + public class PushcutSettings : NotificationSettingsBase { private static readonly PushcutSettingsValidator Validator = new (); @@ -27,7 +26,7 @@ namespace NzbDrone.Core.Notifications.Pushcut [FieldDefinition(2, Label = "NotificationsPushcutSettingsTimeSensitive", Type = FieldType.Checkbox, HelpText = "NotificationsPushcutSettingsTimeSensitiveHelpText")] public bool TimeSensitive { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/Pushover/PushoverSettings.cs b/src/NzbDrone.Core/Notifications/Pushover/PushoverSettings.cs index 7b6c78953..d5450860f 100644 --- a/src/NzbDrone.Core/Notifications/Pushover/PushoverSettings.cs +++ b/src/NzbDrone.Core/Notifications/Pushover/PushoverSettings.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Pushover @@ -17,9 +16,9 @@ namespace NzbDrone.Core.Notifications.Pushover } } - public class PushoverSettings : IProviderConfig + public class PushoverSettings : NotificationSettingsBase { - private static readonly PushoverSettingsValidator Validator = new PushoverSettingsValidator(); + private static readonly PushoverSettingsValidator Validator = new (); public PushoverSettings() { @@ -51,7 +50,7 @@ namespace NzbDrone.Core.Notifications.Pushover public bool IsValid => !string.IsNullOrWhiteSpace(UserKey) && Priority >= -1 && Priority <= 2; - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/SendGrid/SendGridSettings.cs b/src/NzbDrone.Core/Notifications/SendGrid/SendGridSettings.cs index 0add1e793..75b269510 100644 --- a/src/NzbDrone.Core/Notifications/SendGrid/SendGridSettings.cs +++ b/src/NzbDrone.Core/Notifications/SendGrid/SendGridSettings.cs @@ -1,8 +1,7 @@ -using System; +using System; using System.Collections.Generic; using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.SendGrid @@ -18,9 +17,9 @@ namespace NzbDrone.Core.Notifications.SendGrid } } - public class SendGridSettings : IProviderConfig + public class SendGridSettings : NotificationSettingsBase { - private static readonly SendGridSettingsValidator Validator = new SendGridSettingsValidator(); + private static readonly SendGridSettingsValidator Validator = new (); public SendGridSettings() { @@ -39,7 +38,7 @@ namespace NzbDrone.Core.Notifications.SendGrid [FieldDefinition(3, Label = "NotificationsEmailSettingsRecipientAddress", Type = FieldType.Tag)] public IEnumerable Recipients { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/Signal/SignalSettings.cs b/src/NzbDrone.Core/Notifications/Signal/SignalSettings.cs index 500215730..320f505b2 100644 --- a/src/NzbDrone.Core/Notifications/Signal/SignalSettings.cs +++ b/src/NzbDrone.Core/Notifications/Signal/SignalSettings.cs @@ -1,6 +1,5 @@ using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Signal @@ -16,7 +15,7 @@ namespace NzbDrone.Core.Notifications.Signal } } - public class SignalSettings : IProviderConfig + public class SignalSettings : NotificationSettingsBase { private static readonly SignalSettingsValidator Validator = new (); @@ -42,7 +41,7 @@ namespace NzbDrone.Core.Notifications.Signal [FieldDefinition(6, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password, HelpText = "NotificationsSignalSettingsPasswordHelpText")] public string AuthPassword { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/Simplepush/SimplepushSettings.cs b/src/NzbDrone.Core/Notifications/Simplepush/SimplepushSettings.cs index 2e285aeed..3768b71a5 100644 --- a/src/NzbDrone.Core/Notifications/Simplepush/SimplepushSettings.cs +++ b/src/NzbDrone.Core/Notifications/Simplepush/SimplepushSettings.cs @@ -1,6 +1,5 @@ using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Simplepush @@ -13,9 +12,9 @@ namespace NzbDrone.Core.Notifications.Simplepush } } - public class SimplepushSettings : IProviderConfig + public class SimplepushSettings : NotificationSettingsBase { - private static readonly SimplepushSettingsValidator Validator = new SimplepushSettingsValidator(); + private static readonly SimplepushSettingsValidator Validator = new (); [FieldDefinition(0, Label = "NotificationsSimplepushSettingsKey", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://simplepush.io/features")] public string Key { get; set; } @@ -25,7 +24,7 @@ namespace NzbDrone.Core.Notifications.Simplepush public bool IsValid => !string.IsNullOrWhiteSpace(Key); - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/Slack/SlackSettings.cs b/src/NzbDrone.Core/Notifications/Slack/SlackSettings.cs index bd7f10c33..07b62e438 100644 --- a/src/NzbDrone.Core/Notifications/Slack/SlackSettings.cs +++ b/src/NzbDrone.Core/Notifications/Slack/SlackSettings.cs @@ -1,6 +1,5 @@ using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Slack @@ -14,9 +13,9 @@ namespace NzbDrone.Core.Notifications.Slack } } - public class SlackSettings : IProviderConfig + public class SlackSettings : NotificationSettingsBase { - private static readonly SlackSettingsValidator Validator = new SlackSettingsValidator(); + private static readonly SlackSettingsValidator Validator = new (); [FieldDefinition(0, Label = "NotificationsSettingsWebhookUrl", HelpText = "NotificationsSlackSettingsWebhookUrlHelpText", Type = FieldType.Url, HelpLink = "https://my.slack.com/services/new/incoming-webhook/")] public string WebHookUrl { get; set; } @@ -30,7 +29,7 @@ namespace NzbDrone.Core.Notifications.Slack [FieldDefinition(3, Label = "NotificationsSlackSettingsChannel", HelpText = "NotificationsSlackSettingsChannelHelpText", Type = FieldType.Textbox)] public string Channel { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/Synology/SynologyIndexerSettings.cs b/src/NzbDrone.Core/Notifications/Synology/SynologyIndexerSettings.cs index 8bad70a04..966b3b4cc 100644 --- a/src/NzbDrone.Core/Notifications/Synology/SynologyIndexerSettings.cs +++ b/src/NzbDrone.Core/Notifications/Synology/SynologyIndexerSettings.cs @@ -1,6 +1,5 @@ using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Synology @@ -9,9 +8,9 @@ namespace NzbDrone.Core.Notifications.Synology { } - public class SynologyIndexerSettings : IProviderConfig + public class SynologyIndexerSettings : NotificationSettingsBase { - private static readonly SynologyIndexerSettingsValidator Validator = new SynologyIndexerSettingsValidator(); + private static readonly SynologyIndexerSettingsValidator Validator = new (); public SynologyIndexerSettings() { @@ -21,7 +20,7 @@ namespace NzbDrone.Core.Notifications.Synology [FieldDefinition(0, Label = "NotificationsSettingsUpdateLibrary", Type = FieldType.Checkbox, HelpText = "NotificationsSynologySettingsUpdateLibraryHelpText")] public bool UpdateLibrary { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/Telegram/TelegramSettings.cs b/src/NzbDrone.Core/Notifications/Telegram/TelegramSettings.cs index 2b768ce45..f3e4d2499 100644 --- a/src/NzbDrone.Core/Notifications/Telegram/TelegramSettings.cs +++ b/src/NzbDrone.Core/Notifications/Telegram/TelegramSettings.cs @@ -1,6 +1,5 @@ using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Telegram @@ -16,9 +15,9 @@ namespace NzbDrone.Core.Notifications.Telegram } } - public class TelegramSettings : IProviderConfig + public class TelegramSettings : NotificationSettingsBase { - private static readonly TelegramSettingsValidator Validator = new TelegramSettingsValidator(); + private static readonly TelegramSettingsValidator Validator = new (); [FieldDefinition(0, Label = "NotificationsTelegramSettingsBotToken", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://core.telegram.org/bots")] public string BotToken { get; set; } @@ -35,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Telegram [FieldDefinition(4, Label = "NotificationsTelegramSettingsIncludeAppName", Type = FieldType.Checkbox, HelpText = "NotificationsTelegramSettingsIncludeAppNameHelpText")] public bool IncludeAppNameInTitle { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/Trakt/TraktSettings.cs b/src/NzbDrone.Core/Notifications/Trakt/TraktSettings.cs index 0be5677da..cee627621 100644 --- a/src/NzbDrone.Core/Notifications/Trakt/TraktSettings.cs +++ b/src/NzbDrone.Core/Notifications/Trakt/TraktSettings.cs @@ -1,7 +1,6 @@ using System; using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Trakt @@ -16,9 +15,9 @@ namespace NzbDrone.Core.Notifications.Trakt } } - public class TraktSettings : IProviderConfig + public class TraktSettings : NotificationSettingsBase { - private static readonly TraktSettingsValidator Validator = new TraktSettingsValidator(); + private static readonly TraktSettingsValidator Validator = new (); public TraktSettings() { @@ -40,7 +39,7 @@ namespace NzbDrone.Core.Notifications.Trakt [FieldDefinition(4, Label = "NotificationsTraktSettingsAuthenticateWithTrakt", Type = FieldType.OAuth)] public string SignIn { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/Twitter/TwitterSettings.cs b/src/NzbDrone.Core/Notifications/Twitter/TwitterSettings.cs index 448c0976e..d63aac122 100644 --- a/src/NzbDrone.Core/Notifications/Twitter/TwitterSettings.cs +++ b/src/NzbDrone.Core/Notifications/Twitter/TwitterSettings.cs @@ -1,7 +1,6 @@ -using FluentValidation; +using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Twitter @@ -28,9 +27,9 @@ namespace NzbDrone.Core.Notifications.Twitter } } - public class TwitterSettings : IProviderConfig + public class TwitterSettings : NotificationSettingsBase { - private static readonly TwitterSettingsValidator Validator = new TwitterSettingsValidator(); + private static readonly TwitterSettingsValidator Validator = new (); public TwitterSettings() { @@ -59,7 +58,7 @@ namespace NzbDrone.Core.Notifications.Twitter [FieldDefinition(6, Label = "NotificationsTwitterSettingsConnectToTwitter", Type = FieldType.OAuth)] public string AuthorizeNotification { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs index d114a88db..386a7e78b 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs @@ -4,13 +4,12 @@ using System.Linq; using NzbDrone.Core.Configuration; using NzbDrone.Core.Localization; using NzbDrone.Core.MediaFiles; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Tv; namespace NzbDrone.Core.Notifications.Webhook { public abstract class WebhookBase : NotificationBase - where TSettings : IProviderConfig, new() + where TSettings : NotificationSettingsBase, new() { private readonly IConfigFileProvider _configFileProvider; private readonly IConfigService _configService; diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookSettings.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookSettings.cs index f244c7d88..565f454e2 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookSettings.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookSettings.cs @@ -1,7 +1,6 @@ -using System; +using System; using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Webhook @@ -14,9 +13,9 @@ namespace NzbDrone.Core.Notifications.Webhook } } - public class WebhookSettings : IProviderConfig + public class WebhookSettings : NotificationSettingsBase { - private static readonly WebhookSettingsValidator Validator = new WebhookSettingsValidator(); + private static readonly WebhookSettingsValidator Validator = new (); public WebhookSettings() { @@ -35,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Webhook [FieldDefinition(3, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)] public string Password { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Notifications/Xbmc/XbmcSettings.cs b/src/NzbDrone.Core/Notifications/Xbmc/XbmcSettings.cs index 97331f333..efe8741e4 100644 --- a/src/NzbDrone.Core/Notifications/Xbmc/XbmcSettings.cs +++ b/src/NzbDrone.Core/Notifications/Xbmc/XbmcSettings.cs @@ -3,7 +3,6 @@ using FluentValidation; using Newtonsoft.Json; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Xbmc @@ -18,7 +17,7 @@ namespace NzbDrone.Core.Notifications.Xbmc } } - public class XbmcSettings : IProviderConfig + public class XbmcSettings : NotificationSettingsBase { private static readonly XbmcSettingsValidator Validator = new (); @@ -69,7 +68,7 @@ namespace NzbDrone.Core.Notifications.Xbmc [JsonIgnore] public string Address => $"{Host.ToUrlHost()}:{Port}{UrlBase}"; - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Sonarr.Core.csproj b/src/NzbDrone.Core/Sonarr.Core.csproj index 269005cfb..df717ac0b 100644 --- a/src/NzbDrone.Core/Sonarr.Core.csproj +++ b/src/NzbDrone.Core/Sonarr.Core.csproj @@ -1,10 +1,11 @@ - + net6.0 + diff --git a/src/NzbDrone.Core/ThingiProvider/ProviderDefinition.cs b/src/NzbDrone.Core/ThingiProvider/ProviderDefinition.cs index 292bc4bc5..a4c5db45b 100644 --- a/src/NzbDrone.Core/ThingiProvider/ProviderDefinition.cs +++ b/src/NzbDrone.Core/ThingiProvider/ProviderDefinition.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Text.Json.Serialization; +using Equ; using NzbDrone.Core.Datastore; namespace NzbDrone.Core.ThingiProvider @@ -16,20 +17,22 @@ namespace NzbDrone.Core.ThingiProvider public string Name { get; set; } [JsonIgnore] + [MemberwiseEqualityIgnore] public string ImplementationName { get; set; } public string Implementation { get; set; } public string ConfigContract { get; set; } public virtual bool Enable { get; set; } + + [MemberwiseEqualityIgnore] public ProviderMessage Message { get; set; } + public HashSet Tags { get; set; } + [MemberwiseEqualityIgnore] public IProviderConfig Settings { - get - { - return _settings; - } + get => _settings; set { _settings = value; diff --git a/src/Sonarr.Api.V3/Notifications/NotificationResource.cs b/src/Sonarr.Api.V3/Notifications/NotificationResource.cs index e377bfe3a..6e31390cd 100644 --- a/src/Sonarr.Api.V3/Notifications/NotificationResource.cs +++ b/src/Sonarr.Api.V3/Notifications/NotificationResource.cs @@ -14,6 +14,7 @@ namespace Sonarr.Api.V3.Notifications public bool OnEpisodeFileDelete { get; set; } public bool OnEpisodeFileDeleteForUpgrade { get; set; } public bool OnHealthIssue { get; set; } + public bool IncludeHealthWarnings { get; set; } public bool OnHealthRestored { get; set; } public bool OnApplicationUpdate { get; set; } public bool OnManualInteractionRequired { get; set; } @@ -29,7 +30,6 @@ namespace Sonarr.Api.V3.Notifications public bool SupportsOnHealthRestored { get; set; } public bool SupportsOnApplicationUpdate { get; set; } public bool SupportsOnManualInteractionRequired { get; set; } - public bool IncludeHealthWarnings { get; set; } public string TestCommand { get; set; } } @@ -53,6 +53,7 @@ namespace Sonarr.Api.V3.Notifications resource.OnEpisodeFileDelete = definition.OnEpisodeFileDelete; resource.OnEpisodeFileDeleteForUpgrade = definition.OnEpisodeFileDeleteForUpgrade; resource.OnHealthIssue = definition.OnHealthIssue; + resource.IncludeHealthWarnings = definition.IncludeHealthWarnings; resource.OnHealthRestored = definition.OnHealthRestored; resource.OnApplicationUpdate = definition.OnApplicationUpdate; resource.OnManualInteractionRequired = definition.OnManualInteractionRequired; @@ -66,7 +67,6 @@ namespace Sonarr.Api.V3.Notifications resource.SupportsOnEpisodeFileDeleteForUpgrade = definition.SupportsOnEpisodeFileDeleteForUpgrade; resource.SupportsOnHealthIssue = definition.SupportsOnHealthIssue; resource.SupportsOnHealthRestored = definition.SupportsOnHealthRestored; - resource.IncludeHealthWarnings = definition.IncludeHealthWarnings; resource.SupportsOnApplicationUpdate = definition.SupportsOnApplicationUpdate; resource.SupportsOnManualInteractionRequired = definition.SupportsOnManualInteractionRequired; @@ -91,6 +91,7 @@ namespace Sonarr.Api.V3.Notifications definition.OnEpisodeFileDelete = resource.OnEpisodeFileDelete; definition.OnEpisodeFileDeleteForUpgrade = resource.OnEpisodeFileDeleteForUpgrade; definition.OnHealthIssue = resource.OnHealthIssue; + definition.IncludeHealthWarnings = resource.IncludeHealthWarnings; definition.OnHealthRestored = resource.OnHealthRestored; definition.OnApplicationUpdate = resource.OnApplicationUpdate; definition.OnManualInteractionRequired = resource.OnManualInteractionRequired; @@ -104,7 +105,6 @@ namespace Sonarr.Api.V3.Notifications definition.SupportsOnEpisodeFileDeleteForUpgrade = resource.SupportsOnEpisodeFileDeleteForUpgrade; definition.SupportsOnHealthIssue = resource.SupportsOnHealthIssue; definition.SupportsOnHealthRestored = resource.SupportsOnHealthRestored; - definition.IncludeHealthWarnings = resource.IncludeHealthWarnings; definition.SupportsOnApplicationUpdate = resource.SupportsOnApplicationUpdate; definition.SupportsOnManualInteractionRequired = resource.SupportsOnManualInteractionRequired; diff --git a/src/Sonarr.Api.V3/ProviderControllerBase.cs b/src/Sonarr.Api.V3/ProviderControllerBase.cs index 2622b9b02..24a39d7f8 100644 --- a/src/Sonarr.Api.V3/ProviderControllerBase.cs +++ b/src/Sonarr.Api.V3/ProviderControllerBase.cs @@ -90,10 +90,8 @@ namespace Sonarr.Api.V3 var existingDefinition = _providerFactory.Find(providerResource.Id); var providerDefinition = GetDefinition(providerResource, existingDefinition, true, !forceSave, false); - // Comparing via JSON string to eliminate the need for every provider implementation to implement equality checks. // Compare settings separately because they are not serialized with the definition. - var hasDefinitionChanged = STJson.ToJson(existingDefinition) != STJson.ToJson(providerDefinition) || - STJson.ToJson(existingDefinition.Settings) != STJson.ToJson(providerDefinition.Settings); + var hasDefinitionChanged = !existingDefinition.Equals(providerDefinition) || !existingDefinition.Settings.Equals(providerDefinition.Settings); // Only test existing definitions if it is enabled and forceSave isn't set and the definition has changed. if (providerDefinition.Enable && !forceSave && hasDefinitionChanged)