Implement equality checks for providers

pull/2006/head
Bogdan 3 weeks ago
parent 3492b75287
commit 87ed43b071

@ -3,7 +3,6 @@ using FluentAssertions;
using FluentValidation.Results;
using NUnit.Framework;
using NzbDrone.Core.Notifications;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
using NzbDrone.Test.Common;
@ -12,9 +11,9 @@ namespace NzbDrone.Core.Test.NotificationTests
[TestFixture]
public class NotificationBaseFixture : TestBase
{
private class TestSetting : IProviderConfig
private class TestSetting : NotificationBaseSettings
{
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult();
}

@ -5,6 +5,7 @@ using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using AngleSharp.Html.Parser;
using Equ;
using NLog;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http;
@ -210,7 +211,7 @@ namespace NzbDrone.Core.Indexers.Definitions
public Action<IDictionary<string, string>, DateTime?> CookiesUpdater { get; set; }
}
public class BinSearchSettings : IIndexerSettings
public class BinSearchSettings : MemberwiseEquatable<BinSearchSettings>, IIndexerSettings
{
[FieldDefinition(1, Label = "Base Url", Type = FieldType.Select, SelectOptionsProviderAction = "getUrls", HelpText = "Select which baseurl Prowlarr will use for requests to the site")]
public string BaseUrl { get; set; }

@ -1,3 +1,4 @@
using Equ;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
@ -14,7 +15,7 @@ namespace NzbDrone.Core.Indexers.Headphones
}
}
public class HeadphonesSettings : IIndexerSettings
public class HeadphonesSettings : MemberwiseEquatable<HeadphonesSettings>, IIndexerSettings
{
private static readonly HeadphonesSettingsValidator Validator = new ();

@ -1,5 +1,6 @@
using System.Linq;
using System.Text.RegularExpressions;
using Equ;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
@ -46,7 +47,7 @@ namespace NzbDrone.Core.Indexers.Newznab
}
}
public class NewznabSettings : IIndexerSettings
public class NewznabSettings : MemberwiseEquatable<NewznabSettings>, IIndexerSettings
{
private static readonly NewznabSettingsValidator Validator = new ();
@ -75,6 +76,7 @@ namespace NzbDrone.Core.Indexers.Newznab
[FieldDefinition(7)]
public IndexerBaseSettings BaseSettings { get; set; } = new ();
[MemberwiseEqualityIgnore]
public NewznabCapabilitiesSettings Capabilities { get; set; }
// Field 8 is used by TorznabSettings MinimumSeeders

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using Equ;
using FluentValidation;
using Newtonsoft.Json.Linq;
using NLog;
@ -1178,7 +1179,7 @@ namespace NzbDrone.Core.Indexers.Definitions
}
}
public class NzbIndexSettings : IIndexerSettings
public class NzbIndexSettings : MemberwiseEquatable<NzbIndexSettings>, IIndexerSettings
{
private static readonly NzbIndexSettingsValidator Validator = new ();

@ -1,3 +1,4 @@
using Equ;
using FluentValidation;
using NzbDrone.Core.Annotations;
@ -19,7 +20,7 @@ namespace NzbDrone.Core.Indexers
}
}
public class IndexerBaseSettings
public class IndexerBaseSettings : MemberwiseEquatable<IndexerBaseSettings>
{
[FieldDefinition(1, Type = FieldType.Number, Label = "IndexerSettingsQueryLimit", HelpText = "IndexerSettingsQueryLimitHelpText", Advanced = true)]
public int? QueryLimit { get; set; }

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using Equ;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Indexers.Definitions.Cardigann;
using NzbDrone.Core.Profiles;
@ -10,23 +11,47 @@ namespace NzbDrone.Core.Indexers
{
public class IndexerDefinition : ProviderDefinition
{
public string[] IndexerUrls { get; set; }
public string[] LegacyUrls { get; set; }
[MemberwiseEqualityIgnore]
public IEnumerable<string> IndexerUrls { get; set; }
[MemberwiseEqualityIgnore]
public IEnumerable<string> LegacyUrls { get; set; }
public string Description { get; set; }
public Encoding Encoding { get; set; }
public string Language { get; set; }
[MemberwiseEqualityIgnore]
public DownloadProtocol Protocol { get; set; }
[MemberwiseEqualityIgnore]
public IndexerPrivacy Privacy { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsRss { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsSearch { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsRedirect { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsPagination { get; set; }
[MemberwiseEqualityIgnore]
public IndexerCapabilities Capabilities { get; set; }
public int Priority { get; set; } = 25;
public bool Redirect { get; set; }
public int DownloadClientId { get; set; }
[MemberwiseEqualityIgnore]
public DateTime Added { get; set; }
public int AppProfileId { get; set; }
[MemberwiseEqualityIgnore]
public LazyLoaded<AppSyncProfile> AppProfile { get; set; }
public List<SettingsField> ExtraFields { get; set; } = new ();

@ -1,3 +1,4 @@
using Equ;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
@ -50,7 +51,7 @@ namespace NzbDrone.Core.Indexers
}
}
public class IndexerTorrentBaseSettings
public class IndexerTorrentBaseSettings : MemberwiseEquatable<IndexerTorrentBaseSettings>
{
[FieldDefinition(1, Type = FieldType.Number, Label = "IndexerSettingsAppsMinimumSeeders", HelpText = "IndexerSettingsAppsMinimumSeedersHelpText", Advanced = true)]
public int? AppMinimumSeeders { get; set; }

@ -1,3 +1,4 @@
using Equ;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
@ -14,7 +15,7 @@ namespace NzbDrone.Core.Indexers.Settings
}
}
public class NoAuthTorrentBaseSettings : ITorrentIndexerSettings
public class NoAuthTorrentBaseSettings : MemberwiseEquatable<NoAuthTorrentBaseSettings>, ITorrentIndexerSettings
{
private static readonly NoAuthSettingsValidator<NoAuthTorrentBaseSettings> Validator = new ();

@ -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 : NotificationBaseSettings
{
private static readonly AppriseSettingsValidator Validator = new ();
@ -66,7 +65,7 @@ namespace NzbDrone.Core.Notifications.Apprise
[FieldDefinition(7, Label = "Password", Type = FieldType.Password, HelpText = "HTTP Basic Auth Password", Privacy = PrivacyLevel.Password)]
public string AuthPassword { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
using NzbDrone.Core.Validation.Paths;
@ -16,7 +15,7 @@ namespace NzbDrone.Core.Notifications.CustomScript
}
}
public class CustomScriptSettings : IProviderConfig
public class CustomScriptSettings : NotificationBaseSettings
{
private static readonly CustomScriptSettingsValidator Validator = new CustomScriptSettingsValidator();
@ -26,7 +25,7 @@ namespace NzbDrone.Core.Notifications.CustomScript
[FieldDefinition(1, Label = "Arguments", HelpText = "Arguments to pass to the script", Hidden = HiddenType.HiddenIfNotSet)]
public string Arguments { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

@ -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 : NotificationBaseSettings
{
public DiscordSettings()
{
@ -47,7 +46,7 @@ namespace NzbDrone.Core.Notifications.Discord
[FieldDefinition(4, Label = "On Grab Fields", Advanced = true, SelectOptions = typeof(DiscordGrabFieldType), HelpText = "Change the fields that are passed in for this 'on grab' notification", Type = FieldType.Select)]
public IEnumerable<int> GrabFields { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

@ -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,7 +25,7 @@ namespace NzbDrone.Core.Notifications.Email
}
}
public class EmailSettings : IProviderConfig
public class EmailSettings : NotificationBaseSettings
{
private static readonly EmailSettingsValidator Validator = new EmailSettingsValidator();
@ -65,7 +64,7 @@ namespace NzbDrone.Core.Notifications.Email
[FieldDefinition(8, Label = "BCC Address(es)", HelpText = "Comma separated list of email bcc recipients", Placeholder = "example@email.com,example1@email.com", Advanced = true)]
public IEnumerable<string> Bcc { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Gotify
@ -14,7 +13,7 @@ namespace NzbDrone.Core.Notifications.Gotify
}
}
public class GotifySettings : IProviderConfig
public class GotifySettings : NotificationBaseSettings
{
private static readonly GotifySettingsValidator Validator = new GotifySettingsValidator();
@ -32,7 +31,7 @@ namespace NzbDrone.Core.Notifications.Gotify
[FieldDefinition(2, Label = "Priority", Type = FieldType.Select, SelectOptions = typeof(GotifyPriority), HelpText = "Priority of the notification")]
public int Priority { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Join
@ -14,7 +13,7 @@ namespace NzbDrone.Core.Notifications.Join
}
}
public class JoinSettings : IProviderConfig
public class JoinSettings : NotificationBaseSettings
{
public JoinSettings()
{
@ -35,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Join
[FieldDefinition(3, Label = "Notification Priority", Type = FieldType.Select, SelectOptions = typeof(JoinPriority))]
public int Priority { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

@ -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,7 +16,7 @@ namespace NzbDrone.Core.Notifications.Mailgun
}
}
public class MailgunSettings : IProviderConfig
public class MailgunSettings : NotificationBaseSettings
{
private static readonly MailGunSettingsValidator Validator = new MailGunSettingsValidator();
@ -41,7 +40,7 @@ namespace NzbDrone.Core.Notifications.Mailgun
[FieldDefinition(4, Label = "Recipient Address(es)", Type = FieldType.Tag, Placeholder = "example@email.com,example1@email.com")]
public IEnumerable<string> Recipients { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

@ -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 : NotificationBaseSettings
{
private static readonly NotifiarrSettingsValidator Validator = new NotifiarrSettingsValidator();
[FieldDefinition(0, Label = "API Key", Privacy = PrivacyLevel.ApiKey, HelpText = "Your API key from your profile", HelpLink = "https://notifiarr.com")]
public string APIKey { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

@ -6,7 +6,7 @@ using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Notifications
{
public abstract class NotificationBase<TSettings> : INotification
where TSettings : IProviderConfig, new()
where TSettings : NotificationBaseSettings, new()
{
protected const string RELEASE_GRABBED_TITLE = "Release Grabbed";
protected const string HEALTH_ISSUE_TITLE = "Health Check Failure";

@ -0,0 +1,11 @@
using Equ;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications
{
public abstract class NotificationBaseSettings : MemberwiseEquatable<NotificationBaseSettings>, IProviderConfig
{
public abstract NzbDroneValidationResult Validate();
}
}

@ -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
@ -24,7 +23,7 @@ namespace NzbDrone.Core.Notifications.Ntfy
private static List<string> InvalidTopics => new List<string> { "announcements", "app", "docs", "settings", "stats", "mytopic-rw", "mytopic-ro", "mytopic-wo" };
}
public class NtfySettings : IProviderConfig
public class NtfySettings : NotificationBaseSettings
{
private static readonly NtfySettingsValidator Validator = new NtfySettingsValidator();
@ -58,7 +57,7 @@ namespace NzbDrone.Core.Notifications.Ntfy
[FieldDefinition(7, Label = "Click URL", Type = FieldType.Url, HelpText = "Optional link when user clicks notification")]
public string ClickUrl { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Prowl
@ -13,7 +12,7 @@ namespace NzbDrone.Core.Notifications.Prowl
}
}
public class ProwlSettings : IProviderConfig
public class ProwlSettings : NotificationBaseSettings
{
private static readonly ProwlSettingsValidator Validator = new ProwlSettingsValidator();
@ -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));
}

@ -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,7 +14,7 @@ namespace NzbDrone.Core.Notifications.PushBullet
}
}
public class PushBulletSettings : IProviderConfig
public class PushBulletSettings : NotificationBaseSettings
{
private static readonly PushBulletSettingsValidator Validator = new PushBulletSettingsValidator();
@ -37,7 +36,7 @@ namespace NzbDrone.Core.Notifications.PushBullet
[FieldDefinition(3, Label = "Sender ID", HelpText = "The device ID to send notifications from, use device_iden in the device's URL on pushbullet.com (leave blank to send from yourself)")]
public string SenderId { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

@ -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 : NotificationBaseSettings
{
private static readonly PushcutSettingsValidator Validator = new ();
@ -27,7 +26,7 @@ namespace NzbDrone.Core.Notifications.Pushcut
[FieldDefinition(2, Label = "Time sensitive", Type = FieldType.Checkbox, HelpText = "Check to mark the notification as \"Time-Sensitive\"")]
public bool TimeSensitive { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

@ -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,7 +16,7 @@ namespace NzbDrone.Core.Notifications.Pushover
}
}
public class PushoverSettings : IProviderConfig
public class PushoverSettings : NotificationBaseSettings
{
private static readonly PushoverSettingsValidator Validator = new PushoverSettingsValidator();
@ -51,7 +50,7 @@ namespace NzbDrone.Core.Notifications.Pushover
public bool IsValid => !string.IsNullOrWhiteSpace(UserKey) && Priority >= -1 && Priority <= 2;
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

@ -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,7 +17,7 @@ namespace NzbDrone.Core.Notifications.SendGrid
}
}
public class SendGridSettings : IProviderConfig
public class SendGridSettings : NotificationBaseSettings
{
private static readonly SendGridSettingsValidator Validator = new SendGridSettingsValidator();
@ -39,7 +38,7 @@ namespace NzbDrone.Core.Notifications.SendGrid
[FieldDefinition(3, Label = "Recipient Address(es)", Type = FieldType.Tag, Placeholder = "example@email.com,example1@email.com")]
public IEnumerable<string> Recipients { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

@ -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 : NotificationBaseSettings
{
private static readonly SignalSettingsValidator Validator = new ();
@ -41,7 +40,7 @@ namespace NzbDrone.Core.Notifications.Signal
[FieldDefinition(6, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password, HelpText = "Password used to authenticate requests toward signal-api")]
public string AuthPassword { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Simplepush
@ -13,7 +12,7 @@ namespace NzbDrone.Core.Notifications.Simplepush
}
}
public class SimplepushSettings : IProviderConfig
public class SimplepushSettings : NotificationBaseSettings
{
private static readonly SimplepushSettingsValidator Validator = new SimplepushSettingsValidator();
@ -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));
}

@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Slack
@ -14,7 +13,7 @@ namespace NzbDrone.Core.Notifications.Slack
}
}
public class SlackSettings : IProviderConfig
public class SlackSettings : NotificationBaseSettings
{
private static readonly SlackSettingsValidator Validator = new SlackSettingsValidator();
@ -30,7 +29,7 @@ namespace NzbDrone.Core.Notifications.Slack
[FieldDefinition(3, Label = "Channel", HelpText = "Overrides the default channel for the incoming webhook (#other-channel)", Type = FieldType.Textbox)]
public string Channel { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Telegram
@ -16,7 +15,7 @@ namespace NzbDrone.Core.Notifications.Telegram
}
}
public class TelegramSettings : IProviderConfig
public class TelegramSettings : NotificationBaseSettings
{
private static readonly TelegramSettingsValidator Validator = new TelegramSettingsValidator();
@ -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));
}

@ -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,7 +27,7 @@ namespace NzbDrone.Core.Notifications.Twitter
}
}
public class TwitterSettings : IProviderConfig
public class TwitterSettings : NotificationBaseSettings
{
private static readonly TwitterSettingsValidator Validator = new TwitterSettingsValidator();
@ -59,7 +58,7 @@ namespace NzbDrone.Core.Notifications.Twitter
[FieldDefinition(6, Label = "Connect to Twitter", Type = FieldType.OAuth)]
public string AuthorizeNotification { get; set; }
public NzbDroneValidationResult Validate()
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}

@ -1,10 +1,9 @@
using NzbDrone.Core.Configuration;
using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Notifications.Webhook
{
public abstract class WebhookBase<TSettings> : NotificationBase<TSettings>
where TSettings : IProviderConfig, new()
where TSettings : NotificationBaseSettings, new()
{
private readonly IConfigFileProvider _configFileProvider;
private readonly IConfigService _configService;

@ -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,7 +13,7 @@ namespace NzbDrone.Core.Notifications.Webhook
}
}
public class WebhookSettings : IProviderConfig
public class WebhookSettings : NotificationBaseSettings
{
private static readonly WebhookSettingsValidator Validator = new WebhookSettingsValidator();
@ -35,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Webhook
[FieldDefinition(3, Label = "Password", HelpText = "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));
}

@ -5,6 +5,7 @@
<ItemGroup>
<PackageReference Include="AngleSharp.Xml" Version="1.0.0" />
<PackageReference Include="Dapper" Version="2.0.123" />
<PackageReference Include="Equ" Version="2.3.0" />
<PackageReference Include="MailKit" Version="3.6.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="6.0.25" />
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" />

@ -1,11 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using Equ;
using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.ThingiProvider
{
public abstract class ProviderDefinition : ModelBase
public abstract class ProviderDefinition : ModelBase, IEquatable<ProviderDefinition>
{
private static readonly MemberwiseEqualityComparer<ProviderDefinition> Comparer = MemberwiseEqualityComparer<ProviderDefinition>.ByFields;
protected ProviderDefinition()
{
Tags = new HashSet<int>();
@ -16,6 +20,7 @@ namespace NzbDrone.Core.ThingiProvider
public string Name { get; set; }
[JsonIgnore]
[MemberwiseEqualityIgnore]
public string ImplementationName { get; set; }
public string Implementation { get; set; }
@ -24,12 +29,10 @@ namespace NzbDrone.Core.ThingiProvider
public ProviderMessage Message { get; set; }
public HashSet<int> Tags { get; set; }
[MemberwiseEqualityIgnore]
public IProviderConfig Settings
{
get
{
return _settings;
}
get => _settings;
set
{
_settings = value;
@ -39,5 +42,20 @@ namespace NzbDrone.Core.ThingiProvider
}
}
}
public bool Equals(ProviderDefinition other)
{
return Comparer.Equals(this, other);
}
public override bool Equals(object obj)
{
return Equals(obj as ProviderDefinition);
}
public override int GetHashCode()
{
return Comparer.GetHashCode(this);
}
}
}

@ -13,8 +13,8 @@ namespace Prowlarr.Api.V1.Indexers
{
public class IndexerResource : ProviderResource<IndexerResource>
{
public string[] IndexerUrls { get; set; }
public string[] LegacyUrls { get; set; }
public IEnumerable<string> IndexerUrls { get; set; }
public IEnumerable<string> LegacyUrls { get; set; }
public string DefinitionName { get; set; }
public string Description { get; set; }
public string Language { get; set; }

@ -3,7 +3,6 @@ using System.Linq;
using FluentValidation;
using FluentValidation.Results;
using Microsoft.AspNetCore.Mvc;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
using NzbDrone.Http.REST.Attributes;
@ -90,10 +89,8 @@ namespace Prowlarr.Api.V1
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)

Loading…
Cancel
Save