From e8c925274abfcea18e84a1c9ed35c80c5cd4adeb Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 14 Apr 2024 07:16:26 +0300 Subject: [PATCH] Implement equality checks for providers --- .../NotificationBaseFixture.cs | 5 +- .../Download/Clients/Aria2/Aria2Settings.cs | 7 ++- .../Blackhole/TorrentBlackholeSettings.cs | 7 ++- .../Blackhole/UsenetBlackholeSettings.cs | 7 ++- .../Download/Clients/Deluge/DelugeSettings.cs | 7 ++- .../Clients/DownloadClientSettingsBase.cs | 30 ++++++++++++ .../DownloadStationSettings.cs | 7 ++- .../Download/Clients/Flood/FloodSettings.cs | 7 ++- .../FreeboxDownloadSettings.cs | 7 ++- .../Clients/Hadouken/HadoukenSettings.cs | 7 ++- .../Clients/NzbVortex/NzbVortexSettings.cs | 7 ++- .../Download/Clients/Nzbget/NzbgetSettings.cs | 7 ++- .../Clients/Pneumatic/PneumaticSettings.cs | 7 ++- .../QBittorrent/QBittorrentSettings.cs | 7 ++- .../Clients/Sabnzbd/SabnzbdSettings.cs | 7 ++- .../Clients/TorrentSeedConfiguration.cs | 2 +- .../Transmission/TransmissionSettings.cs | 7 ++- .../Clients/rTorrent/RTorrentSettings.cs | 7 ++- .../Clients/uTorrent/UTorrentSettings.cs | 7 ++- .../Download/DownloadClientDefinition.cs | 23 ++++++++- .../CouchPotato/CouchPotatoSettings.cs | 7 ++- .../ImportLists/ImportListBaseSettings.cs | 35 -------------- .../ImportLists/ImportListDefinition.cs | 29 ++++++++--- .../ImportLists/ImportListSettingsBase.cs | 30 ++++++++++++ .../ImportLists/Plex/PlexListSettings.cs | 7 ++- .../RSSImport/RSSImportSettings.cs | 7 ++- .../ImportLists/Radarr/RadarrSettings.cs | 10 ++-- .../RadarrList/RadarrListSettings.cs | 9 ++-- .../RadarrList2/IMDb/IMDbListParser.cs | 1 - .../RadarrList2/IMDb/IMDbListSettings.cs | 7 ++- .../RadarrList2/StevenLu/StevenLu2Settings.cs | 29 +++++------ .../Rss/Plex/PlexRssImportSettings.cs | 4 +- .../ImportLists/Rss/RssImportBase.cs | 4 +- .../ImportLists/Rss/RssImportBaseSettings.cs | 13 ++--- .../Rss/RssImportRequestGenerator.cs | 9 ++-- .../ImportLists/Simkl/SimklSettingsBase.cs | 10 ++-- .../Simkl/User/SimklUserSettings.cs | 9 +++- .../ImportLists/StevenLu/StevenLuSettings.cs | 9 ++-- .../TMDb/Company/TMDbCompanySettings.cs | 9 +++- .../TMDb/Keyword/TMDbKeywordSettings.cs | 9 +++- .../ImportLists/TMDb/List/TMDbListSettings.cs | 9 +++- .../TMDb/Person/TMDbPersonSettings.cs | 9 +++- .../TMDb/Popular/TMDbPopularSettings.cs | 11 +++-- .../ImportLists/TMDb/TMDbFilterSettings.cs | 3 +- .../ImportLists/TMDb/TMDbSettings.cs | 7 ++- .../ImportLists/TMDb/User/TMDbUserSettings.cs | 11 +++-- .../Trakt/List/TraktListSettings.cs | 9 +++- .../Trakt/Popular/TraktPopularSettings.cs | 9 +++- .../ImportLists/Trakt/TraktSettingsBase.cs | 7 ++- .../Trakt/User/TraktUserSettings.cs | 9 +++- .../Indexers/FileList/FileListSettings.cs | 7 +-- .../Indexers/HDBits/HDBitsSettings.cs | 3 +- .../Indexers/IPTorrents/IPTorrentsSettings.cs | 7 +-- .../Indexers/IndexerDefinition.cs | 35 ++++++++++++-- .../Indexers/Newznab/NewznabSettings.cs | 7 +-- .../Indexers/Nyaa/NyaaSettings.cs | 7 +-- .../PassThePopcorn/PassThePopcornSettings.cs | 5 +- .../Indexers/SeedCriteriaSettings.cs | 3 +- .../TorrentPotato/TorrentPotatoSettings.cs | 7 +-- .../TorrentRss/TorrentRssIndexerSettings.cs | 7 +-- .../Indexers/Torznab/TorznabSettings.cs | 20 +++++++- .../Notifications/Apprise/AppriseSettings.cs | 5 +- .../CustomScript/CustomScriptSettings.cs | 9 ++-- .../Notifications/Discord/DiscordSettings.cs | 5 +- .../Notifications/Email/EmailSettings.cs | 7 ++- .../Notifications/Gotify/GotifySettings.cs | 7 ++- .../Notifications/Join/JoinSettings.cs | 9 ++-- .../Notifications/Mailgun/MailgunSettings.cs | 7 ++- .../MediaBrowser/MediaBrowserSettings.cs | 7 ++- .../Notifiarr/NotifiarrSettings.cs | 7 ++- .../Notifications/NotificationBase.cs | 2 +- .../Notifications/NotificationDefinition.cs | 48 ++++++++++++++++++- .../Notifications/NotificationSettingsBase.cs | 30 ++++++++++++ .../Notifications/Ntfy/NtfySettings.cs | 9 ++-- .../Plex/Server/PlexServerSettings.cs | 7 ++- .../Notifications/Prowl/ProwlSettings.cs | 7 ++- .../PushBullet/PushBulletSettings.cs | 7 ++- .../Notifications/Pushcut/PushcutSettings.cs | 5 +- .../Pushover/PushoverSettings.cs | 7 ++- .../Pushsafer/PushsaferSettings.cs | 5 +- .../SendGrid/SendGridSettings.cs | 7 ++- .../Notifications/Signal/SignalSettings.cs | 5 +- .../Simplepush/SimplepushSettings.cs | 7 ++- .../Notifications/Slack/SlackSettings.cs | 7 ++- .../Synology/SynologyIndexerSettings.cs | 7 ++- .../Telegram/TelegramSettings.cs | 7 ++- .../Notifications/Trakt/TraktSettings.cs | 7 ++- .../Notifications/Twitter/TwitterSettings.cs | 7 ++- .../Notifications/Webhook/WebhookBase.cs | 3 +- .../Notifications/Webhook/WebhookSettings.cs | 7 ++- .../Notifications/Xbmc/XbmcSettings.cs | 5 +- .../ThingiProvider/ProviderDefinition.cs | 11 +++-- .../Notifications/NotificationResource.cs | 6 +-- src/Radarr.Api.V3/ProviderControllerBase.cs | 4 +- 94 files changed, 539 insertions(+), 352 deletions(-) create mode 100644 src/NzbDrone.Core/Download/Clients/DownloadClientSettingsBase.cs delete mode 100644 src/NzbDrone.Core/ImportLists/ImportListBaseSettings.cs create mode 100644 src/NzbDrone.Core/ImportLists/ImportListSettingsBase.cs create mode 100644 src/NzbDrone.Core/Notifications/NotificationSettingsBase.cs diff --git a/src/NzbDrone.Core.Test/NotificationTests/NotificationBaseFixture.cs b/src/NzbDrone.Core.Test/NotificationTests/NotificationBaseFixture.cs index 3aa4ab2fc..c8a76685d 100644 --- a/src/NzbDrone.Core.Test/NotificationTests/NotificationBaseFixture.cs +++ b/src/NzbDrone.Core.Test/NotificationTests/NotificationBaseFixture.cs @@ -6,7 +6,6 @@ using NUnit.Framework; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Movies; using NzbDrone.Core.Notifications; -using NzbDrone.Core.ThingiProvider; 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 70ffaf7d4..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 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 e70730e22..039236c99 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 19ed1f013..03607073c 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationSettings.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.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 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 6ff08e952..ebaa3eae5 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 = "DownloadClientFloodSettingsAddPaused", 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/FreeboxDownload/FreeboxDownloadSettings.cs b/src/NzbDrone.Core/Download/Clients/FreeboxDownload/FreeboxDownloadSettings.cs index a1c7c84a5..00d88504f 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 54b9aaadf..421b7fa69 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 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 1cf32a22c..25e84e215 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 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 = "DownloadClientSettingsOlderPriorityMovieHelpText")] public int OlderMoviePriority { 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 db3efb503..d41a80d6e 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() { @@ -69,7 +68,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 ef7838f0f..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 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 41fb99f21..7e057ddb8 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 7773baae2..05b797967 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 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 = "DownloadClientSettingsOlderPriorityMovieHelpText")] public int OlderMoviePriority { 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 34c45cf38..8b26f2033 100644 --- a/src/NzbDrone.Core/Download/Clients/TorrentSeedConfiguration.cs +++ b/src/NzbDrone.Core/Download/Clients/TorrentSeedConfiguration.cs @@ -4,7 +4,7 @@ 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 c1f3c8b78..ae9be1acd 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 cd3010d86..9fcd1004f 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 f8cfb1a90..558c8b87a 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 524ca5e5c..8271e5b35 100644 --- a/src/NzbDrone.Core/Download/DownloadClientDefinition.cs +++ b/src/NzbDrone.Core/Download/DownloadClientDefinition.cs @@ -1,13 +1,34 @@ +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/CouchPotato/CouchPotatoSettings.cs b/src/NzbDrone.Core/ImportLists/CouchPotato/CouchPotatoSettings.cs index bc2a93d9c..1bbef8252 100644 --- a/src/NzbDrone.Core/ImportLists/CouchPotato/CouchPotatoSettings.cs +++ b/src/NzbDrone.Core/ImportLists/CouchPotato/CouchPotatoSettings.cs @@ -1,6 +1,5 @@ using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.CouchPotato @@ -15,9 +14,9 @@ namespace NzbDrone.Core.ImportLists.CouchPotato } } - public class CouchPotatoSettings : IProviderConfig + public class CouchPotatoSettings : ImportListSettingsBase { - private static readonly CouchPotatoSettingsValidator Validator = new CouchPotatoSettingsValidator(); + private static readonly CouchPotatoSettingsValidator Validator = new (); public CouchPotatoSettings() { @@ -42,7 +41,7 @@ namespace NzbDrone.Core.ImportLists.CouchPotato [FieldDefinition(4, Label = "Only Wanted", HelpText = "Only add wanted movies.", Type = FieldType.Checkbox)] public bool OnlyActive { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/ImportLists/ImportListBaseSettings.cs b/src/NzbDrone.Core/ImportLists/ImportListBaseSettings.cs deleted file mode 100644 index 53118c8c3..000000000 --- a/src/NzbDrone.Core/ImportLists/ImportListBaseSettings.cs +++ /dev/null @@ -1,35 +0,0 @@ -using FluentValidation; -using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; -using NzbDrone.Core.Validation; - -namespace NzbDrone.Core.ImportLists -{ - public class ImportListBaseSettingsValidator : AbstractValidator - { - public ImportListBaseSettingsValidator() - { - RuleFor(c => c.Link).NotEmpty(); - } - } - - public class ImportListBaseSettings : IProviderConfig - { - private static readonly ImportListBaseSettingsValidator Validator = new ImportListBaseSettingsValidator(); - - public ImportListBaseSettings() - { - Link = "http://rss.imdb.com/list/"; - } - - [FieldDefinition(0, Label = "Link", HelpText = "Link to the list of movies.")] - public string Link { get; set; } - - public bool IsValid => !string.IsNullOrWhiteSpace(Link); - - public 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 b5296cf1f..277f26eb2 100644 --- a/src/NzbDrone.Core/ImportLists/ImportListDefinition.cs +++ b/src/NzbDrone.Core/ImportLists/ImportListDefinition.cs @@ -1,16 +1,13 @@ using System; -using System.Collections.Generic; +using Equ; using NzbDrone.Core.Movies; using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.ImportLists { - public class ImportListDefinition : ProviderDefinition + public class ImportListDefinition : ProviderDefinition, IEquatable { - public ImportListDefinition() - { - Tags = new HashSet(); - } + private static readonly MemberwiseEqualityComparer Comparer = MemberwiseEqualityComparer.ByProperties; public bool Enabled { get; set; } public bool EnableAuto { get; set; } @@ -19,9 +16,29 @@ namespace NzbDrone.Core.ImportLists public int QualityProfileId { get; set; } public string RootFolderPath { get; set; } public bool SearchOnAdd { get; set; } + + [MemberwiseEqualityIgnore] public override bool Enable => Enabled; + [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..8f7290ec5 --- /dev/null +++ b/src/NzbDrone.Core/ImportLists/ImportListSettingsBase.cs @@ -0,0 +1,30 @@ +using System; +using Equ; +using NzbDrone.Core.ThingiProvider; +using NzbDrone.Core.Validation; + +namespace NzbDrone.Core.ImportLists +{ + public abstract class ImportListSettingsBase : IProviderConfig, IEquatable + where TSettings : ImportListSettingsBase + { + 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/ImportLists/Plex/PlexListSettings.cs b/src/NzbDrone.Core/ImportLists/Plex/PlexListSettings.cs index 109fdb425..aff03bb34 100644 --- a/src/NzbDrone.Core/ImportLists/Plex/PlexListSettings.cs +++ b/src/NzbDrone.Core/ImportLists/Plex/PlexListSettings.cs @@ -1,6 +1,5 @@ using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.Plex @@ -15,9 +14,9 @@ namespace NzbDrone.Core.ImportLists.Plex } } - public class PlexListSettings : IProviderConfig + public class PlexListSettings : ImportListSettingsBase { - protected virtual PlexListSettingsValidator Validator => new PlexListSettingsValidator(); + private static readonly PlexListSettingsValidator Validator = new (); public PlexListSettings() { @@ -32,7 +31,7 @@ namespace NzbDrone.Core.ImportLists.Plex [FieldDefinition(99, Label = "Authenticate with Plex.tv", 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/RSSImport/RSSImportSettings.cs b/src/NzbDrone.Core/ImportLists/RSSImport/RSSImportSettings.cs index 874e923f0..ceaf68bce 100644 --- a/src/NzbDrone.Core/ImportLists/RSSImport/RSSImportSettings.cs +++ b/src/NzbDrone.Core/ImportLists/RSSImport/RSSImportSettings.cs @@ -1,6 +1,5 @@ using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.RSSImport @@ -13,9 +12,9 @@ namespace NzbDrone.Core.ImportLists.RSSImport } } - public class RSSImportSettings : IProviderConfig + public class RSSImportSettings : ImportListSettingsBase { - private static readonly RSSImportSettingsValidator Validator = new RSSImportSettingsValidator(); + private static readonly RSSImportSettingsValidator Validator = new (); public RSSImportSettings() { @@ -25,7 +24,7 @@ namespace NzbDrone.Core.ImportLists.RSSImport [FieldDefinition(0, Label = "RSS Link", HelpText = "Link to the rss feed of movies.")] public string Link { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/ImportLists/Radarr/RadarrSettings.cs b/src/NzbDrone.Core/ImportLists/Radarr/RadarrSettings.cs index f3cc3c173..6940350eb 100644 --- a/src/NzbDrone.Core/ImportLists/Radarr/RadarrSettings.cs +++ b/src/NzbDrone.Core/ImportLists/Radarr/RadarrSettings.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.ImportLists.Radarr @@ -16,13 +15,12 @@ namespace NzbDrone.Core.ImportLists.Radarr } } - public class RadarrSettings : IProviderConfig + public class RadarrSettings : ImportListSettingsBase { - private static readonly RadarrSettingsValidator Validator = new RadarrSettingsValidator(); + private static readonly RadarrSettingsValidator Validator = new (); public RadarrSettings() { - BaseUrl = ""; ApiKey = ""; ProfileIds = Array.Empty(); TagIds = Array.Empty(); @@ -30,7 +28,7 @@ namespace NzbDrone.Core.ImportLists.Radarr } [FieldDefinition(0, Label = "Full URL", HelpText = "URL, including port, of the Radarr instance to import from (Radarr 3.0 or higher)")] - public string BaseUrl { get; set; } + public string BaseUrl { get; set; } = string.Empty; [FieldDefinition(1, Label = "API Key", Privacy = PrivacyLevel.ApiKey, HelpText = "Apikey of the Radarr instance to import from (Radarr 3.0 or higher)")] public string ApiKey { get; set; } @@ -44,7 +42,7 @@ namespace NzbDrone.Core.ImportLists.Radarr [FieldDefinition(4, Type = FieldType.Select, SelectOptionsProviderAction = "getRootFolders", Label = "Root Folders", HelpText = "Root Folders from the source instance to import from")] public IEnumerable RootFolderPaths { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/ImportLists/RadarrList/RadarrListSettings.cs b/src/NzbDrone.Core/ImportLists/RadarrList/RadarrListSettings.cs index d6e1c6731..960e106b3 100644 --- a/src/NzbDrone.Core/ImportLists/RadarrList/RadarrListSettings.cs +++ b/src/NzbDrone.Core/ImportLists/RadarrList/RadarrListSettings.cs @@ -1,6 +1,5 @@ -using FluentValidation; +using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.RadarrList @@ -13,14 +12,14 @@ namespace NzbDrone.Core.ImportLists.RadarrList } } - public class RadarrListSettings : IProviderConfig + public class RadarrListSettings : ImportListSettingsBase { - private static readonly RadarrSettingsValidator Validator = new RadarrSettingsValidator(); + private static readonly RadarrSettingsValidator Validator = new (); [FieldDefinition(0, Label = "List URL", HelpText = "The URL for the movie list")] public string Url { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/ImportLists/RadarrList2/IMDb/IMDbListParser.cs b/src/NzbDrone.Core/ImportLists/RadarrList2/IMDb/IMDbListParser.cs index fc38b16c2..c2e85de7f 100644 --- a/src/NzbDrone.Core/ImportLists/RadarrList2/IMDb/IMDbListParser.cs +++ b/src/NzbDrone.Core/ImportLists/RadarrList2/IMDb/IMDbListParser.cs @@ -13,7 +13,6 @@ namespace NzbDrone.Core.ImportLists.RadarrList2.IMDbList private readonly IMDbListSettings _settings; public IMDbListParser(IMDbListSettings settings) - : base() { _settings = settings; } diff --git a/src/NzbDrone.Core/ImportLists/RadarrList2/IMDb/IMDbListSettings.cs b/src/NzbDrone.Core/ImportLists/RadarrList2/IMDb/IMDbListSettings.cs index 74936473c..7547733f2 100644 --- a/src/NzbDrone.Core/ImportLists/RadarrList2/IMDb/IMDbListSettings.cs +++ b/src/NzbDrone.Core/ImportLists/RadarrList2/IMDb/IMDbListSettings.cs @@ -1,6 +1,5 @@ using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.RadarrList2.IMDbList @@ -15,14 +14,14 @@ namespace NzbDrone.Core.ImportLists.RadarrList2.IMDbList } } - public class IMDbListSettings : IProviderConfig + public class IMDbListSettings : ImportListSettingsBase { - private static readonly IMDbSettingsValidator Validator = new IMDbSettingsValidator(); + private static readonly IMDbSettingsValidator Validator = new (); [FieldDefinition(1, Label = "List/User ID", HelpText = "IMDb list ID (e.g ls12345678), IMDb user ID (e.g. ur12345678), 'top250' or 'popular'")] 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/RadarrList2/StevenLu/StevenLu2Settings.cs b/src/NzbDrone.Core/ImportLists/RadarrList2/StevenLu/StevenLu2Settings.cs index 7013abd26..2de297e36 100644 --- a/src/NzbDrone.Core/ImportLists/RadarrList2/StevenLu/StevenLu2Settings.cs +++ b/src/NzbDrone.Core/ImportLists/RadarrList2/StevenLu/StevenLu2Settings.cs @@ -1,6 +1,5 @@ -using FluentValidation; +using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.RadarrList2.StevenLu @@ -9,21 +8,15 @@ namespace NzbDrone.Core.ImportLists.RadarrList2.StevenLu { public StevenLu2SettingsValidator() { - RuleFor(c => c.MinScore).GreaterThanOrEqualTo(x => 5).LessThanOrEqualTo(x => 8); + RuleFor(c => c.MinScore) + .GreaterThanOrEqualTo(x => 5) + .LessThanOrEqualTo(x => 8); } } - public enum StevenLuSource - { - Standard, - Imdb, - Metacritic, - RottenTomatoes - } - - public class StevenLu2Settings : IProviderConfig + public class StevenLu2Settings : ImportListSettingsBase { - private static readonly StevenLu2SettingsValidator Validator = new StevenLu2SettingsValidator(); + private static readonly StevenLu2SettingsValidator Validator = new (); public StevenLu2Settings() { @@ -36,9 +29,17 @@ namespace NzbDrone.Core.ImportLists.RadarrList2.StevenLu [FieldDefinition(1, Label = "Minimum Score", Type = FieldType.Number, HelpText = "Only applies if 'Rating source' is not 'Standard'")] public int MinScore { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } } + + public enum StevenLuSource + { + Standard, + Imdb, + Metacritic, + RottenTomatoes + } } diff --git a/src/NzbDrone.Core/ImportLists/Rss/Plex/PlexRssImportSettings.cs b/src/NzbDrone.Core/ImportLists/Rss/Plex/PlexRssImportSettings.cs index 941b90a4a..f126792c3 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 = "Url", 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 b6b8adeb0..bc1c0a0d9 100644 --- a/src/NzbDrone.Core/ImportLists/Rss/RssImportBase.cs +++ b/src/NzbDrone.Core/ImportLists/Rss/RssImportBase.cs @@ -6,7 +6,7 @@ using NzbDrone.Core.Parser; namespace NzbDrone.Core.ImportLists.Rss { public abstract class RssImportBase : HttpImportListBase - where TSettings : RssImportBaseSettings, new() + where TSettings : RssImportBaseSettings, new() { public override bool Enabled => true; public override bool EnableAuto => false; @@ -32,7 +32,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 581f4434e..f4c54390e 100644 --- a/src/NzbDrone.Core/ImportLists/Rss/RssImportBaseSettings.cs +++ b/src/NzbDrone.Core/ImportLists/Rss/RssImportBaseSettings.cs @@ -1,11 +1,11 @@ using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.Rss { - public class RssImportSettingsValidator : AbstractValidator + public class RssImportSettingsValidator : AbstractValidator + where TSettings : RssImportBaseSettings { public RssImportSettingsValidator() { @@ -13,16 +13,17 @@ namespace NzbDrone.Core.ImportLists.Rss } } - public class RssImportBaseSettings : IProviderConfig + public class RssImportBaseSettings : ImportListSettingsBase + where TSettings : RssImportBaseSettings { - private RssImportSettingsValidator Validator => new (); + private static readonly RssImportSettingsValidator Validator = new (); [FieldDefinition(0, Label = "Url", 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 825eda0d7..577e9ddd7 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 GetMovies() { @@ -18,9 +19,7 @@ namespace NzbDrone.Core.ImportLists.Rss private IEnumerable GetMoviesRequest() { - 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 5fc21a6d5..a613de329 100644 --- a/src/NzbDrone.Core/ImportLists/Simkl/SimklSettingsBase.cs +++ b/src/NzbDrone.Core/ImportLists/Simkl/SimklSettingsBase.cs @@ -2,7 +2,6 @@ using System; using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.Simkl @@ -25,18 +24,17 @@ namespace NzbDrone.Core.ImportLists.Simkl } } - public class SimklSettingsBase : IProviderConfig + 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 string BaseUrl { get; set; } = "https://api.simkl.com"; [FieldDefinition(0, Label = "Access Token", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)] public string AccessToken { get; set; } @@ -53,7 +51,7 @@ namespace NzbDrone.Core.ImportLists.Simkl [FieldDefinition(99, Label = "Authenticate with Simkl", 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 61cc48129..8f91e581d 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() { @@ -23,5 +23,10 @@ namespace NzbDrone.Core.ImportLists.Simkl.User [FieldDefinition(1, Label = "List Type", Type = FieldType.Select, SelectOptions = typeof(SimklUserListType), HelpText = "Type of list you're seeking to import from")] public int ListType { get; set; } + + public override NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } } } diff --git a/src/NzbDrone.Core/ImportLists/StevenLu/StevenLuSettings.cs b/src/NzbDrone.Core/ImportLists/StevenLu/StevenLuSettings.cs index 93ccbf7fe..d92ece325 100644 --- a/src/NzbDrone.Core/ImportLists/StevenLu/StevenLuSettings.cs +++ b/src/NzbDrone.Core/ImportLists/StevenLu/StevenLuSettings.cs @@ -1,6 +1,5 @@ -using FluentValidation; +using FluentValidation; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.StevenLu @@ -13,9 +12,9 @@ namespace NzbDrone.Core.ImportLists.StevenLu } } - public class StevenLuSettings : IProviderConfig + public class StevenLuSettings : ImportListSettingsBase { - private static readonly StevenLuSettingsValidator Validator = new StevenLuSettingsValidator(); + private static readonly StevenLuSettingsValidator Validator = new (); public StevenLuSettings() { @@ -25,7 +24,7 @@ namespace NzbDrone.Core.ImportLists.StevenLu [FieldDefinition(0, Label = "URL", HelpText = "Don't change this unless you know what you are doing.")] public string Link { get; set; } - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/ImportLists/TMDb/Company/TMDbCompanySettings.cs b/src/NzbDrone.Core/ImportLists/TMDb/Company/TMDbCompanySettings.cs index d9b4d0ba6..fd3d01164 100644 --- a/src/NzbDrone.Core/ImportLists/TMDb/Company/TMDbCompanySettings.cs +++ b/src/NzbDrone.Core/ImportLists/TMDb/Company/TMDbCompanySettings.cs @@ -1,13 +1,13 @@ using System.Text.RegularExpressions; using FluentValidation; using NzbDrone.Core.Annotations; +using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.TMDb.Company { public class TMDbCompanySettingsValidator : TMDbSettingsBaseValidator { public TMDbCompanySettingsValidator() - : base() { RuleFor(c => c.CompanyId).Matches(@"^[1-9][0-9]*$", RegexOptions.IgnoreCase); } @@ -15,7 +15,7 @@ namespace NzbDrone.Core.ImportLists.TMDb.Company public class TMDbCompanySettings : TMDbSettingsBase { - protected override AbstractValidator Validator => new TMDbCompanySettingsValidator(); + private static readonly TMDbCompanySettingsValidator Validator = new (); public TMDbCompanySettings() { @@ -24,5 +24,10 @@ namespace NzbDrone.Core.ImportLists.TMDb.Company [FieldDefinition(1, Label = "Company Id", Type = FieldType.Textbox, HelpText = "TMDb Id of Company to Follow")] public string CompanyId { get; set; } + + public override NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } } } diff --git a/src/NzbDrone.Core/ImportLists/TMDb/Keyword/TMDbKeywordSettings.cs b/src/NzbDrone.Core/ImportLists/TMDb/Keyword/TMDbKeywordSettings.cs index 32d64773c..3f217b0a0 100644 --- a/src/NzbDrone.Core/ImportLists/TMDb/Keyword/TMDbKeywordSettings.cs +++ b/src/NzbDrone.Core/ImportLists/TMDb/Keyword/TMDbKeywordSettings.cs @@ -1,13 +1,13 @@ using System.Text.RegularExpressions; using FluentValidation; using NzbDrone.Core.Annotations; +using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.TMDb.Keyword { public class TMDbKeywordSettingsValidator : TMDbSettingsBaseValidator { public TMDbKeywordSettingsValidator() - : base() { RuleFor(c => c.KeywordId).Matches(@"^[1-9][0-9]*$", RegexOptions.IgnoreCase); } @@ -15,7 +15,7 @@ namespace NzbDrone.Core.ImportLists.TMDb.Keyword public class TMDbKeywordSettings : TMDbSettingsBase { - protected override AbstractValidator Validator => new TMDbKeywordSettingsValidator(); + private static readonly TMDbKeywordSettingsValidator Validator = new (); public TMDbKeywordSettings() { @@ -24,5 +24,10 @@ namespace NzbDrone.Core.ImportLists.TMDb.Keyword [FieldDefinition(1, Label = "Keyword Id", Type = FieldType.Textbox, HelpText = "TMDb Id of keyword to Follow")] public string KeywordId { get; set; } + + public override NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } } } diff --git a/src/NzbDrone.Core/ImportLists/TMDb/List/TMDbListSettings.cs b/src/NzbDrone.Core/ImportLists/TMDb/List/TMDbListSettings.cs index bb153dd03..e2ae4f6ad 100644 --- a/src/NzbDrone.Core/ImportLists/TMDb/List/TMDbListSettings.cs +++ b/src/NzbDrone.Core/ImportLists/TMDb/List/TMDbListSettings.cs @@ -1,12 +1,12 @@ using FluentValidation; using NzbDrone.Core.Annotations; +using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.TMDb.List { public class TMDbListSettingsValidator : TMDbSettingsBaseValidator { public TMDbListSettingsValidator() - : base() { RuleFor(c => c.ListId).Matches("^[1-9][0-9]*$").NotEmpty(); } @@ -14,7 +14,7 @@ namespace NzbDrone.Core.ImportLists.TMDb.List public class TMDbListSettings : TMDbSettingsBase { - protected override AbstractValidator Validator => new TMDbListSettingsValidator(); + private static readonly TMDbListSettingsValidator Validator = new (); public TMDbListSettings() { @@ -23,5 +23,10 @@ namespace NzbDrone.Core.ImportLists.TMDb.List [FieldDefinition(1, Label = "ListId", Type = FieldType.Textbox, HelpText = "TMDb Id of List to Follow")] public string ListId { get; set; } + + public override NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } } } diff --git a/src/NzbDrone.Core/ImportLists/TMDb/Person/TMDbPersonSettings.cs b/src/NzbDrone.Core/ImportLists/TMDb/Person/TMDbPersonSettings.cs index de2df5933..1cc836cae 100644 --- a/src/NzbDrone.Core/ImportLists/TMDb/Person/TMDbPersonSettings.cs +++ b/src/NzbDrone.Core/ImportLists/TMDb/Person/TMDbPersonSettings.cs @@ -1,13 +1,13 @@ using System.Text.RegularExpressions; using FluentValidation; using NzbDrone.Core.Annotations; +using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.TMDb.Person { public class TMDbPersonSettingsValidator : TMDbSettingsBaseValidator { public TMDbPersonSettingsValidator() - : base() { RuleFor(c => c.PersonId).Matches(@"^[1-9][0-9]*$", RegexOptions.IgnoreCase); @@ -36,7 +36,7 @@ namespace NzbDrone.Core.ImportLists.TMDb.Person public class TMDbPersonSettings : TMDbSettingsBase { - protected override AbstractValidator Validator => new TMDbPersonSettingsValidator(); + private static readonly TMDbPersonSettingsValidator Validator = new (); public TMDbPersonSettings() { @@ -60,5 +60,10 @@ namespace NzbDrone.Core.ImportLists.TMDb.Person [FieldDefinition(6, Label = "Person Writing Credits", HelpText = "Select if you want to include Writing credits", Type = FieldType.Checkbox)] public bool PersonCastWriting { get; set; } + + public override NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } } } diff --git a/src/NzbDrone.Core/ImportLists/TMDb/Popular/TMDbPopularSettings.cs b/src/NzbDrone.Core/ImportLists/TMDb/Popular/TMDbPopularSettings.cs index 74e84bcf6..d6c041fc8 100644 --- a/src/NzbDrone.Core/ImportLists/TMDb/Popular/TMDbPopularSettings.cs +++ b/src/NzbDrone.Core/ImportLists/TMDb/Popular/TMDbPopularSettings.cs @@ -1,12 +1,12 @@ using FluentValidation; using NzbDrone.Core.Annotations; +using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.TMDb.Popular { public class TMDbPopularSettingsValidator : TMDbSettingsBaseValidator { public TMDbPopularSettingsValidator() - : base() { RuleFor(c => c.TMDbListType).NotNull(); @@ -16,7 +16,7 @@ namespace NzbDrone.Core.ImportLists.TMDb.Popular public class TMDbPopularSettings : TMDbSettingsBase { - protected override AbstractValidator Validator => new TMDbPopularSettingsValidator(); + private static readonly TMDbPopularSettingsValidator Validator = new (); public TMDbPopularSettings() { @@ -27,6 +27,11 @@ namespace NzbDrone.Core.ImportLists.TMDb.Popular public int TMDbListType { get; set; } [FieldDefinition(2)] - public TMDbFilterSettings FilterCriteria { get; set; } = new TMDbFilterSettings(); + public TMDbFilterSettings FilterCriteria { get; set; } = new (); + + public override NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } } } diff --git a/src/NzbDrone.Core/ImportLists/TMDb/TMDbFilterSettings.cs b/src/NzbDrone.Core/ImportLists/TMDb/TMDbFilterSettings.cs index e7ee202a8..42557986a 100644 --- a/src/NzbDrone.Core/ImportLists/TMDb/TMDbFilterSettings.cs +++ b/src/NzbDrone.Core/ImportLists/TMDb/TMDbFilterSettings.cs @@ -1,4 +1,5 @@ using System.Text.RegularExpressions; +using Equ; using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; @@ -53,7 +54,7 @@ namespace NzbDrone.Core.ImportLists.TMDb } } - public class TMDbFilterSettings + public class TMDbFilterSettings : PropertywiseEquatable { public TMDbFilterSettings() { diff --git a/src/NzbDrone.Core/ImportLists/TMDb/TMDbSettings.cs b/src/NzbDrone.Core/ImportLists/TMDb/TMDbSettings.cs index 39da0f830..0c4327b05 100644 --- a/src/NzbDrone.Core/ImportLists/TMDb/TMDbSettings.cs +++ b/src/NzbDrone.Core/ImportLists/TMDb/TMDbSettings.cs @@ -1,5 +1,4 @@ using FluentValidation; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.TMDb @@ -9,12 +8,12 @@ namespace NzbDrone.Core.ImportLists.TMDb { } - public class TMDbSettingsBase : IProviderConfig + public class TMDbSettingsBase : ImportListSettingsBase where TSettings : TMDbSettingsBase { - protected virtual AbstractValidator Validator => new TMDbSettingsBaseValidator(); + private static readonly TMDbSettingsBaseValidator Validator = new (); - public NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate((TSettings)this)); } diff --git a/src/NzbDrone.Core/ImportLists/TMDb/User/TMDbUserSettings.cs b/src/NzbDrone.Core/ImportLists/TMDb/User/TMDbUserSettings.cs index aa01754e5..716f40e88 100644 --- a/src/NzbDrone.Core/ImportLists/TMDb/User/TMDbUserSettings.cs +++ b/src/NzbDrone.Core/ImportLists/TMDb/User/TMDbUserSettings.cs @@ -1,12 +1,12 @@ -using FluentValidation; +using FluentValidation; using NzbDrone.Core.Annotations; +using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.TMDb.User { public class TMDbUserSettingsValidator : TMDbSettingsBaseValidator { public TMDbUserSettingsValidator() - : base() { RuleFor(c => c.ListType).NotEmpty(); RuleFor(c => c.AccessToken).NotEmpty(); @@ -16,7 +16,7 @@ namespace NzbDrone.Core.ImportLists.TMDb.User public class TMDbUserSettings : TMDbSettingsBase { - protected override AbstractValidator Validator => new TMDbUserSettingsValidator(); + private static readonly TMDbUserSettingsValidator Validator = new (); public TMDbUserSettings() { @@ -36,5 +36,10 @@ namespace NzbDrone.Core.ImportLists.TMDb.User [FieldDefinition(99, Label = "Authenticate with TMDB", Type = FieldType.OAuth)] public string SignIn { get; set; } + + 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 1474a3e70..0ae3c98d0 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", Privacy = PrivacyLevel.UserName, HelpText = "Username for the List to import from")] public string Username { get; set; } [FieldDefinition(2, Label = "List Name", HelpText = "List name for import, list must be public or you must have access to the list")] 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 e3ccfb7bc..7c40539f7 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(); @@ -34,7 +34,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() { @@ -59,5 +59,10 @@ namespace NzbDrone.Core.ImportLists.Trakt.Popular [FieldDefinition(5, Label = "Years", HelpText = "Filter movies by year or year range")] 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 613e805fe..c9d9bc467 100644 --- a/src/NzbDrone.Core/ImportLists/Trakt/TraktSettingsBase.cs +++ b/src/NzbDrone.Core/ImportLists/Trakt/TraktSettingsBase.cs @@ -2,7 +2,6 @@ using System; using FluentValidation; using NzbDrone.Common.Extensions; using NzbDrone.Core.Annotations; -using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.ImportLists.Trakt @@ -35,10 +34,10 @@ namespace NzbDrone.Core.ImportLists.Trakt } } - public class TraktSettingsBase : IProviderConfig + public class TraktSettingsBase : ImportListSettingsBase where TSettings : TraktSettingsBase { - protected virtual AbstractValidator Validator => new TraktSettingsBaseValidator(); + private static readonly TraktSettingsBaseValidator Validator = new (); public TraktSettingsBase() { @@ -70,7 +69,7 @@ namespace NzbDrone.Core.ImportLists.Trakt [FieldDefinition(99, Label = "Authenticate with Trakt", 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 9784c858b..c5575b602 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.AuthUser).NotEmpty(); @@ -15,7 +15,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() { @@ -27,5 +27,10 @@ namespace NzbDrone.Core.ImportLists.Trakt.User [FieldDefinition(2, Label = "Username", HelpText = "Username for the List to import from (empty to use Auth User)")] public string Username { get; set; } + + public override NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } } } diff --git a/src/NzbDrone.Core/Indexers/FileList/FileListSettings.cs b/src/NzbDrone.Core/Indexers/FileList/FileListSettings.cs index 6fc1f0c0f..f4d5c9d4b 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; @@ -20,9 +21,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() { @@ -56,7 +57,7 @@ namespace NzbDrone.Core.Indexers.FileList public int MinimumSeeders { get; set; } [FieldDefinition(5)] - public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings(); + public SeedCriteriaSettings SeedCriteria { get; set; } = new (); [FieldDefinition(6, 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 15458d9af..ff77910ae 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; @@ -19,7 +20,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 a43b97bf3..6eede21f4 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; @@ -26,9 +27,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() { @@ -45,7 +46,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 50bea595b..6bd429703 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,17 +15,40 @@ 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; } + [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 1c0f1233f..686246a98 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 5d316c10e..3e8702df0 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; @@ -20,9 +21,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() { @@ -43,7 +44,7 @@ namespace NzbDrone.Core.Indexers.Nyaa 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/PassThePopcorn/PassThePopcornSettings.cs b/src/NzbDrone.Core/Indexers/PassThePopcorn/PassThePopcornSettings.cs index d25f77e94..cf34f958a 100644 --- a/src/NzbDrone.Core/Indexers/PassThePopcorn/PassThePopcornSettings.cs +++ b/src/NzbDrone.Core/Indexers/PassThePopcorn/PassThePopcornSettings.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Equ; using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.Languages; @@ -20,7 +21,7 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn } } - public class PassThePopcornSettings : ITorrentIndexerSettings + public class PassThePopcornSettings : PropertywiseEquatable, ITorrentIndexerSettings { private static readonly PassThePopcornSettingsValidator Validator = new (); @@ -45,7 +46,7 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn 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 bc53b3ad1..fa1f3b0a8 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; @@ -34,7 +35,7 @@ namespace NzbDrone.Core.Indexers } } - public class SeedCriteriaSettings + public class SeedCriteriaSettings : PropertywiseEquatable { [FieldDefinition(0, Type = FieldType.Number, Label = "IndexerSettingsSeedRatio", HelpText = "IndexerSettingsSeedRatioHelpText")] public double? SeedRatio { get; set; } diff --git a/src/NzbDrone.Core/Indexers/TorrentPotato/TorrentPotatoSettings.cs b/src/NzbDrone.Core/Indexers/TorrentPotato/TorrentPotatoSettings.cs index 9702260f8..7ba1acce3 100644 --- a/src/NzbDrone.Core/Indexers/TorrentPotato/TorrentPotatoSettings.cs +++ b/src/NzbDrone.Core/Indexers/TorrentPotato/TorrentPotatoSettings.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.TorrentPotato } } - public class TorrentPotatoSettings : ITorrentIndexerSettings + public class TorrentPotatoSettings : PropertywiseEquatable, ITorrentIndexerSettings { - private static readonly TorrentPotatoSettingsValidator Validator = new TorrentPotatoSettingsValidator(); + private static readonly TorrentPotatoSettingsValidator Validator = new (); public TorrentPotatoSettings() { @@ -43,7 +44,7 @@ namespace NzbDrone.Core.Indexers.TorrentPotato 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/TorrentRss/TorrentRssIndexerSettings.cs b/src/NzbDrone.Core/Indexers/TorrentRss/TorrentRssIndexerSettings.cs index 776069df9..19a0e911a 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; @@ -18,9 +19,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() { @@ -44,7 +45,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/Torznab/TorznabSettings.cs b/src/NzbDrone.Core/Indexers/Torznab/TorznabSettings.cs index 38f08e120..8fe28d2d5 100644 --- a/src/NzbDrone.Core/Indexers/Torznab/TorznabSettings.cs +++ b/src/NzbDrone.Core/Indexers/Torznab/TorznabSettings.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; @@ -42,10 +43,12 @@ namespace NzbDrone.Core.Indexers.Torznab } } - public class TorznabSettings : NewznabSettings, ITorrentIndexerSettings + public class TorznabSettings : NewznabSettings, ITorrentIndexerSettings, IEquatable { private static readonly TorznabSettingsValidator Validator = new (); + private static readonly MemberwiseEqualityComparer Comparer = MemberwiseEqualityComparer.ByProperties; + public TorznabSettings() { MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS; @@ -68,5 +71,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 139fdab81..41b599bfe 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() { @@ -92,7 +91,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 4336d02c3..5545a9148 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", Placeholder = "example@email.com,example1@email.com", 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 9d0aec2c1..0c49e78fe 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 = "NotificationsGotifySettingIncludeMoviePoster", Type = FieldType.Checkbox, HelpText = "NotificationsGotifySettingIncludeMoviePosterHelpText")] public bool IncludeMoviePoster { 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 4d188c61d..df24fcc46 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", Privacy = PrivacyLevel.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 33e0bfb9a..de7ed0852 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, Placeholder = "example@email.com,example1@email.com")] 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 a3f344516..35382cff4 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 @@ -17,9 +16,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() { @@ -55,7 +54,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 7b50efcbd..2f4a655aa 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 45b380707..f347a7ffb 100644 --- a/src/NzbDrone.Core/Notifications/NotificationBase.cs +++ b/src/NzbDrone.Core/Notifications/NotificationBase.cs @@ -8,7 +8,7 @@ using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Notifications { public abstract class NotificationBase : INotification - where TSettings : IProviderConfig, new() + where TSettings : NotificationSettingsBase, new() { protected const string MOVIE_GRABBED_TITLE = "Movie Grabbed"; protected const string MOVIE_DOWNLOADED_TITLE = "Movie Downloaded"; diff --git a/src/NzbDrone.Core/Notifications/NotificationDefinition.cs b/src/NzbDrone.Core/Notifications/NotificationDefinition.cs index 7fd5d54d9..70d8ec9ab 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 OnMovieFileDelete { get; set; } public bool OnMovieFileDeleteForUpgrade { 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 SupportsOnMovieAdded { get; set; } + + [MemberwiseEqualityIgnore] public bool SupportsOnMovieDelete { get; set; } + + [MemberwiseEqualityIgnore] public bool SupportsOnMovieFileDelete { get; set; } + + [MemberwiseEqualityIgnore] public bool SupportsOnMovieFileDeleteForUpgrade { 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) || OnRename || OnMovieAdded || OnMovieDelete || OnMovieFileDelete || (OnMovieFileDelete && OnMovieFileDeleteForUpgrade) || 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 b63514b7d..79850adf6 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", Placeholder = "https://myserver.example.com/radarr")] 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 502266559..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 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 01c8dcf18..427cdd3b7 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 cfebca9ad..c9279e031 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() { @@ -50,7 +49,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/Pushsafer/PushsaferSettings.cs b/src/NzbDrone.Core/Notifications/Pushsafer/PushsaferSettings.cs index ea0aeb104..3b310b3d7 100644 --- a/src/NzbDrone.Core/Notifications/Pushsafer/PushsaferSettings.cs +++ b/src/NzbDrone.Core/Notifications/Pushsafer/PushsaferSettings.cs @@ -4,7 +4,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.Notifications.Pushsafer @@ -23,7 +22,7 @@ namespace NzbDrone.Core.Notifications.Pushsafer } } - public class PushsaferSettings : IProviderConfig + public class PushsaferSettings : NotificationSettingsBase { private static readonly PushsaferSettingsValidator Validator = new (); @@ -60,7 +59,7 @@ namespace NzbDrone.Core.Notifications.Pushsafer [FieldDefinition(8, Label = "Icon Color", Type = FieldType.Textbox, Advanced = true, HelpText = "Icon color in hex format (leave blank to use the default Pushsafer icon color)", HelpLink = "https://www.pushsafer.com/en/pushapi_ext#API-C")] public string IconColor { get; set; } - 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 e65ae95d1..8c6855e48 100644 --- a/src/NzbDrone.Core/Notifications/SendGrid/SendGridSettings.cs +++ b/src/NzbDrone.Core/Notifications/SendGrid/SendGridSettings.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.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, Placeholder = "example@email.com,example1@email.com")] 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 d43155ed6..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 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 995addf97..8b7c48d1f 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs @@ -7,12 +7,11 @@ using NzbDrone.Core.Localization; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Movies; using NzbDrone.Core.Tags; -using NzbDrone.Core.ThingiProvider; 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 1ee1c7e54..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 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/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/Radarr.Api.V3/Notifications/NotificationResource.cs b/src/Radarr.Api.V3/Notifications/NotificationResource.cs index 2aa6b259e..b14517865 100644 --- a/src/Radarr.Api.V3/Notifications/NotificationResource.cs +++ b/src/Radarr.Api.V3/Notifications/NotificationResource.cs @@ -14,6 +14,7 @@ namespace Radarr.Api.V3.Notifications public bool OnMovieFileDelete { get; set; } public bool OnMovieFileDeleteForUpgrade { 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 Radarr.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 Radarr.Api.V3.Notifications resource.OnMovieFileDelete = definition.OnMovieFileDelete; resource.OnMovieFileDeleteForUpgrade = definition.OnMovieFileDeleteForUpgrade; 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 Radarr.Api.V3.Notifications resource.SupportsOnMovieFileDeleteForUpgrade = definition.SupportsOnMovieFileDeleteForUpgrade; 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 Radarr.Api.V3.Notifications definition.OnMovieFileDelete = resource.OnMovieFileDelete; definition.OnMovieFileDeleteForUpgrade = resource.OnMovieFileDeleteForUpgrade; 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 Radarr.Api.V3.Notifications definition.SupportsOnMovieFileDeleteForUpgrade = resource.SupportsOnMovieFileDeleteForUpgrade; definition.SupportsOnHealthIssue = resource.SupportsOnHealthIssue; definition.SupportsOnHealthRestored = resource.SupportsOnHealthRestored; - definition.IncludeHealthWarnings = resource.IncludeHealthWarnings; definition.SupportsOnApplicationUpdate = resource.SupportsOnApplicationUpdate; definition.SupportsOnManualInteractionRequired = resource.SupportsOnManualInteractionRequired; diff --git a/src/Radarr.Api.V3/ProviderControllerBase.cs b/src/Radarr.Api.V3/ProviderControllerBase.cs index aa4d139b3..ea91fcea4 100644 --- a/src/Radarr.Api.V3/ProviderControllerBase.cs +++ b/src/Radarr.Api.V3/ProviderControllerBase.cs @@ -90,10 +90,8 @@ namespace Radarr.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)