Implement equality checks for providers

Bogdan 1 month ago
parent f77e27bace
commit 1b015523a9

@ -6,7 +6,6 @@ using NUnit.Framework;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Movies; using NzbDrone.Core.Movies;
using NzbDrone.Core.Notifications; using NzbDrone.Core.Notifications;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
using NzbDrone.Test.Common; using NzbDrone.Test.Common;
@ -15,9 +14,9 @@ namespace NzbDrone.Core.Test.NotificationTests
[TestFixture] [TestFixture]
public class NotificationBaseFixture : TestBase public class NotificationBaseFixture : TestBase
{ {
private class TestSetting : IProviderConfig private class TestSetting : NotificationSettingsBase<TestSetting>
{ {
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(); return new NzbDroneValidationResult();
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.Aria2 namespace NzbDrone.Core.Download.Clients.Aria2
@ -13,9 +12,9 @@ namespace NzbDrone.Core.Download.Clients.Aria2
} }
} }
public class Aria2Settings : IProviderConfig public class Aria2Settings : DownloadClientSettingsBase<Aria2Settings>
{ {
private static readonly Aria2SettingsValidator Validator = new Aria2SettingsValidator(); private static readonly Aria2SettingsValidator Validator = new ();
public Aria2Settings() public Aria2Settings()
{ {
@ -44,7 +43,7 @@ namespace NzbDrone.Core.Download.Clients.Aria2
[FieldDefinition(5, Label = "Directory", Type = FieldType.Textbox, HelpText = "DownloadClientAriaSettingsDirectoryHelpText")] [FieldDefinition(5, Label = "Directory", Type = FieldType.Textbox, HelpText = "DownloadClientAriaSettingsDirectoryHelpText")]
public string Directory { get; set; } public string Directory { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -2,7 +2,6 @@ using System.ComponentModel;
using FluentValidation; using FluentValidation;
using Newtonsoft.Json; using Newtonsoft.Json;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
using NzbDrone.Core.Validation.Paths; using NzbDrone.Core.Validation.Paths;
@ -18,7 +17,7 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
} }
} }
public class TorrentBlackholeSettings : IProviderConfig public class TorrentBlackholeSettings : DownloadClientSettingsBase<TorrentBlackholeSettings>
{ {
public TorrentBlackholeSettings() public TorrentBlackholeSettings()
{ {
@ -26,7 +25,7 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
ReadOnly = true; ReadOnly = true;
} }
private static readonly TorrentBlackholeSettingsValidator Validator = new TorrentBlackholeSettingsValidator(); private static readonly TorrentBlackholeSettingsValidator Validator = new ();
[FieldDefinition(0, Label = "TorrentBlackholeTorrentFolder", Type = FieldType.Path, HelpText = "BlackholeFolderHelpText")] [FieldDefinition(0, Label = "TorrentBlackholeTorrentFolder", Type = FieldType.Path, HelpText = "BlackholeFolderHelpText")]
[FieldToken(TokenField.HelpText, "TorrentBlackholeTorrentFolder", "extension", ".torrent")] [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")] [FieldDefinition(4, Label = "TorrentBlackholeSaveMagnetFilesReadOnly", Type = FieldType.Checkbox, HelpText = "TorrentBlackholeSaveMagnetFilesReadOnlyHelpText")]
public bool ReadOnly { get; set; } public bool ReadOnly { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
using NzbDrone.Core.Validation.Paths; using NzbDrone.Core.Validation.Paths;
@ -15,9 +14,9 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
} }
} }
public class UsenetBlackholeSettings : IProviderConfig public class UsenetBlackholeSettings : DownloadClientSettingsBase<UsenetBlackholeSettings>
{ {
private static readonly UsenetBlackholeSettingsValidator Validator = new UsenetBlackholeSettingsValidator(); private static readonly UsenetBlackholeSettingsValidator Validator = new ();
[FieldDefinition(0, Label = "UsenetBlackholeNzbFolder", Type = FieldType.Path, HelpText = "BlackholeFolderHelpText")] [FieldDefinition(0, Label = "UsenetBlackholeNzbFolder", Type = FieldType.Path, HelpText = "BlackholeFolderHelpText")]
[FieldToken(TokenField.HelpText, "UsenetBlackholeNzbFolder", "extension", ".nzb")] [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")] [FieldDefinition(1, Label = "BlackholeWatchFolder", Type = FieldType.Path, HelpText = "BlackholeWatchFolderHelpText")]
public string WatchFolder { get; set; } public string WatchFolder { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.Deluge namespace NzbDrone.Core.Download.Clients.Deluge
@ -17,9 +16,9 @@ namespace NzbDrone.Core.Download.Clients.Deluge
} }
} }
public class DelugeSettings : IProviderConfig public class DelugeSettings : DownloadClientSettingsBase<DelugeSettings>
{ {
private static readonly DelugeSettingsValidator Validator = new DelugeSettingsValidator(); private static readonly DelugeSettingsValidator Validator = new ();
public DelugeSettings() public DelugeSettings()
{ {
@ -67,7 +66,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
[FieldDefinition(11, Label = "DownloadClientDelugeSettingsDirectoryCompleted", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientDelugeSettingsDirectoryCompletedHelpText")] [FieldDefinition(11, Label = "DownloadClientDelugeSettingsDirectoryCompleted", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientDelugeSettingsDirectoryCompletedHelpText")]
public string CompletedDirectory { get; set; } public string CompletedDirectory { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -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<TSettings> : IProviderConfig, IEquatable<TSettings>
where TSettings : DownloadClientSettingsBase<TSettings>
{
private static readonly MemberwiseEqualityComparer<TSettings> Comparer = MemberwiseEqualityComparer<TSettings>.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);
}
}
}

@ -2,7 +2,6 @@ using System.Text.RegularExpressions;
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.DownloadStation namespace NzbDrone.Core.Download.Clients.DownloadStation
@ -26,9 +25,9 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
} }
} }
public class DownloadStationSettings : IProviderConfig public class DownloadStationSettings : DownloadClientSettingsBase<DownloadStationSettings>
{ {
private static readonly DownloadStationSettingsValidator Validator = new DownloadStationSettingsValidator(); private static readonly DownloadStationSettingsValidator Validator = new ();
[FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)] [FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)]
public string Host { get; set; } public string Host { get; set; }
@ -58,7 +57,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
Port = 5000; Port = 5000;
} }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -3,7 +3,6 @@ using System.Linq;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Download.Clients.Flood.Models; using NzbDrone.Core.Download.Clients.Flood.Models;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.Flood namespace NzbDrone.Core.Download.Clients.Flood
@ -17,9 +16,9 @@ namespace NzbDrone.Core.Download.Clients.Flood
} }
} }
public class FloodSettings : IProviderConfig public class FloodSettings : DownloadClientSettingsBase<FloodSettings>
{ {
private static readonly FloodSettingsValidator Validator = new FloodSettingsValidator(); private static readonly FloodSettingsValidator Validator = new ();
public FloodSettings() public FloodSettings()
{ {
@ -69,7 +68,7 @@ namespace NzbDrone.Core.Download.Clients.Flood
[FieldDefinition(10, Label = "DownloadClientFloodSettingsAddPaused", Type = FieldType.Checkbox)] [FieldDefinition(10, Label = "DownloadClientFloodSettingsAddPaused", Type = FieldType.Checkbox)]
public bool AddPaused { get; set; } public bool AddPaused { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -2,7 +2,6 @@ using System.Text.RegularExpressions;
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
using NzbDrone.Core.Validation.Paths; using NzbDrone.Core.Validation.Paths;
@ -34,9 +33,9 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload
} }
} }
public class FreeboxDownloadSettings : IProviderConfig public class FreeboxDownloadSettings : DownloadClientSettingsBase<FreeboxDownloadSettings>
{ {
private static readonly FreeboxDownloadSettingsValidator Validator = new FreeboxDownloadSettingsValidator(); private static readonly FreeboxDownloadSettingsValidator Validator = new ();
public FreeboxDownloadSettings() public FreeboxDownloadSettings()
{ {
@ -84,7 +83,7 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload
[FieldDefinition(10, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox)] [FieldDefinition(10, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox)]
public bool AddPaused { get; set; } public bool AddPaused { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,7 +1,6 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.Hadouken namespace NzbDrone.Core.Download.Clients.Hadouken
@ -22,9 +21,9 @@ namespace NzbDrone.Core.Download.Clients.Hadouken
} }
} }
public class HadoukenSettings : IProviderConfig public class HadoukenSettings : DownloadClientSettingsBase<HadoukenSettings>
{ {
private static readonly HadoukenSettingsValidator Validator = new HadoukenSettingsValidator(); private static readonly HadoukenSettingsValidator Validator = new ();
public HadoukenSettings() public HadoukenSettings()
{ {
@ -57,7 +56,7 @@ namespace NzbDrone.Core.Download.Clients.Hadouken
[FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "DownloadClientSettingsCategoryHelpText")] [FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "DownloadClientSettingsCategoryHelpText")]
public string Category { get; set; } public string Category { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,7 +1,6 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.NzbVortex namespace NzbDrone.Core.Download.Clients.NzbVortex
@ -23,9 +22,9 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex
} }
} }
public class NzbVortexSettings : IProviderConfig public class NzbVortexSettings : DownloadClientSettingsBase<NzbVortexSettings>
{ {
private static readonly NzbVortexSettingsValidator Validator = new NzbVortexSettingsValidator(); private static readonly NzbVortexSettingsValidator Validator = new ();
public NzbVortexSettings() public NzbVortexSettings()
{ {
@ -59,7 +58,7 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex
[FieldDefinition(6, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(NzbVortexPriority), HelpText = "DownloadClientSettingsOlderPriorityMovieHelpText")] [FieldDefinition(6, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(NzbVortexPriority), HelpText = "DownloadClientSettingsOlderPriorityMovieHelpText")]
public int OlderMoviePriority { get; set; } public int OlderMoviePriority { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,7 +1,6 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.Nzbget namespace NzbDrone.Core.Download.Clients.Nzbget
@ -21,9 +20,9 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
} }
} }
public class NzbgetSettings : IProviderConfig public class NzbgetSettings : DownloadClientSettingsBase<NzbgetSettings>
{ {
private static readonly NzbgetSettingsValidator Validator = new NzbgetSettingsValidator(); private static readonly NzbgetSettingsValidator Validator = new ();
public NzbgetSettings() public NzbgetSettings()
{ {
@ -69,7 +68,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
[FieldDefinition(9, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox, HelpText = "DownloadClientNzbgetSettingsAddPausedHelpText")] [FieldDefinition(9, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox, HelpText = "DownloadClientNzbgetSettingsAddPausedHelpText")]
public bool AddPaused { get; set; } public bool AddPaused { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
using NzbDrone.Core.Validation.Paths; using NzbDrone.Core.Validation.Paths;
@ -15,9 +14,9 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic
} }
} }
public class PneumaticSettings : IProviderConfig public class PneumaticSettings : DownloadClientSettingsBase<PneumaticSettings>
{ {
private static readonly PneumaticSettingsValidator Validator = new PneumaticSettingsValidator(); private static readonly PneumaticSettingsValidator Validator = new ();
[FieldDefinition(0, Label = "DownloadClientPneumaticSettingsNzbFolder", Type = FieldType.Path, HelpText = "DownloadClientPneumaticSettingsNzbFolderHelpText")] [FieldDefinition(0, Label = "DownloadClientPneumaticSettingsNzbFolder", Type = FieldType.Path, HelpText = "DownloadClientPneumaticSettingsNzbFolderHelpText")]
public string NzbFolder { get; set; } public string NzbFolder { get; set; }
@ -25,7 +24,7 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic
[FieldDefinition(1, Label = "DownloadClientPneumaticSettingsStrmFolder", Type = FieldType.Path, HelpText = "DownloadClientPneumaticSettingsStrmFolderHelpText")] [FieldDefinition(1, Label = "DownloadClientPneumaticSettingsStrmFolder", Type = FieldType.Path, HelpText = "DownloadClientPneumaticSettingsStrmFolderHelpText")]
public string StrmFolder { get; set; } public string StrmFolder { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,7 +1,6 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.QBittorrent namespace NzbDrone.Core.Download.Clients.QBittorrent
@ -19,9 +18,9 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
} }
} }
public class QBittorrentSettings : IProviderConfig public class QBittorrentSettings : DownloadClientSettingsBase<QBittorrentSettings>
{ {
private static readonly QBittorrentSettingsValidator Validator = new QBittorrentSettingsValidator(); private static readonly QBittorrentSettingsValidator Validator = new ();
public QBittorrentSettings() public QBittorrentSettings()
{ {
@ -74,7 +73,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
[FieldDefinition(13, Label = "DownloadClientQbittorrentSettingsContentLayout", Type = FieldType.Select, SelectOptions = typeof(QBittorrentContentLayout), HelpText = "DownloadClientQbittorrentSettingsContentLayoutHelpText")] [FieldDefinition(13, Label = "DownloadClientQbittorrentSettingsContentLayout", Type = FieldType.Select, SelectOptions = typeof(QBittorrentContentLayout), HelpText = "DownloadClientQbittorrentSettingsContentLayoutHelpText")]
public int ContentLayout { get; set; } public int ContentLayout { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,7 +1,6 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.Sabnzbd namespace NzbDrone.Core.Download.Clients.Sabnzbd
@ -32,9 +31,9 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
} }
} }
public class SabnzbdSettings : IProviderConfig public class SabnzbdSettings : DownloadClientSettingsBase<SabnzbdSettings>
{ {
private static readonly SabnzbdSettingsValidator Validator = new SabnzbdSettingsValidator(); private static readonly SabnzbdSettingsValidator Validator = new ();
public SabnzbdSettings() public SabnzbdSettings()
{ {
@ -78,7 +77,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
[FieldDefinition(9, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(SabnzbdPriority), HelpText = "DownloadClientSettingsOlderPriorityMovieHelpText")] [FieldDefinition(9, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(SabnzbdPriority), HelpText = "DownloadClientSettingsOlderPriorityMovieHelpText")]
public int OlderMoviePriority { get; set; } public int OlderMoviePriority { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -4,7 +4,7 @@ namespace NzbDrone.Core.Download.Clients
{ {
public class TorrentSeedConfiguration public class TorrentSeedConfiguration
{ {
public static TorrentSeedConfiguration DefaultConfiguration = new TorrentSeedConfiguration(); public static TorrentSeedConfiguration DefaultConfiguration = new ();
public double? Ratio { get; set; } public double? Ratio { get; set; }
public TimeSpan? SeedTime { get; set; } public TimeSpan? SeedTime { get; set; }

@ -2,7 +2,6 @@ using System.Text.RegularExpressions;
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.Transmission namespace NzbDrone.Core.Download.Clients.Transmission
@ -24,9 +23,9 @@ namespace NzbDrone.Core.Download.Clients.Transmission
} }
} }
public class TransmissionSettings : IProviderConfig public class TransmissionSettings : DownloadClientSettingsBase<TransmissionSettings>
{ {
private static readonly TransmissionSettingsValidator Validator = new TransmissionSettingsValidator(); private static readonly TransmissionSettingsValidator Validator = new ();
public TransmissionSettings() public TransmissionSettings()
{ {
@ -72,7 +71,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
[FieldDefinition(10, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox)] [FieldDefinition(10, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox)]
public bool AddPaused { get; set; } public bool AddPaused { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.RTorrent namespace NzbDrone.Core.Download.Clients.RTorrent
@ -17,9 +16,9 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
} }
} }
public class RTorrentSettings : IProviderConfig public class RTorrentSettings : DownloadClientSettingsBase<RTorrentSettings>
{ {
private static readonly RTorrentSettingsValidator Validator = new RTorrentSettingsValidator(); private static readonly RTorrentSettingsValidator Validator = new ();
public RTorrentSettings() public RTorrentSettings()
{ {
@ -70,7 +69,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
[FieldDefinition(11, Label = "DownloadClientRTorrentSettingsAddStopped", Type = FieldType.Checkbox, HelpText = "DownloadClientRTorrentSettingsAddStoppedHelpText")] [FieldDefinition(11, Label = "DownloadClientRTorrentSettingsAddStopped", Type = FieldType.Checkbox, HelpText = "DownloadClientRTorrentSettingsAddStoppedHelpText")]
public bool AddStopped { get; set; } public bool AddStopped { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,7 +1,6 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Download.Clients.UTorrent namespace NzbDrone.Core.Download.Clients.UTorrent
@ -17,9 +16,9 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
} }
} }
public class UTorrentSettings : IProviderConfig public class UTorrentSettings : DownloadClientSettingsBase<UTorrentSettings>
{ {
private static readonly UTorrentSettingsValidator Validator = new UTorrentSettingsValidator(); private static readonly UTorrentSettingsValidator Validator = new ();
public UTorrentSettings() public UTorrentSettings()
{ {
@ -65,7 +64,7 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
[FieldToken(TokenField.HelpText, "DownloadClientSettingsInitialState", "clientName", "uTorrent")] [FieldToken(TokenField.HelpText, "DownloadClientSettingsInitialState", "clientName", "uTorrent")]
public int IntialState { get; set; } public int IntialState { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,13 +1,34 @@
using System;
using Equ;
using NzbDrone.Core.Indexers; using NzbDrone.Core.Indexers;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Download namespace NzbDrone.Core.Download
{ {
public class DownloadClientDefinition : ProviderDefinition public class DownloadClientDefinition : ProviderDefinition, IEquatable<DownloadClientDefinition>
{ {
private static readonly MemberwiseEqualityComparer<DownloadClientDefinition> Comparer = MemberwiseEqualityComparer<DownloadClientDefinition>.ByProperties;
[MemberwiseEqualityIgnore]
public DownloadProtocol Protocol { get; set; } public DownloadProtocol Protocol { get; set; }
public int Priority { get; set; } = 1; public int Priority { get; set; } = 1;
public bool RemoveCompletedDownloads { get; set; } = true; public bool RemoveCompletedDownloads { get; set; } = true;
public bool RemoveFailedDownloads { 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);
}
} }
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.CouchPotato namespace NzbDrone.Core.ImportLists.CouchPotato
@ -15,9 +14,9 @@ namespace NzbDrone.Core.ImportLists.CouchPotato
} }
} }
public class CouchPotatoSettings : IProviderConfig public class CouchPotatoSettings : ImportListSettingsBase<CouchPotatoSettings>
{ {
private static readonly CouchPotatoSettingsValidator Validator = new CouchPotatoSettingsValidator(); private static readonly CouchPotatoSettingsValidator Validator = new ();
public CouchPotatoSettings() public CouchPotatoSettings()
{ {
@ -42,7 +41,7 @@ namespace NzbDrone.Core.ImportLists.CouchPotato
[FieldDefinition(4, Label = "Only Wanted", HelpText = "Only add wanted movies.", Type = FieldType.Checkbox)] [FieldDefinition(4, Label = "Only Wanted", HelpText = "Only add wanted movies.", Type = FieldType.Checkbox)]
public bool OnlyActive { get; set; } public bool OnlyActive { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -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<ImportListBaseSettings>
{
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));
}
}
}

@ -1,16 +1,13 @@
using System; using System;
using System.Collections.Generic; using Equ;
using NzbDrone.Core.Movies; using NzbDrone.Core.Movies;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.ImportLists namespace NzbDrone.Core.ImportLists
{ {
public class ImportListDefinition : ProviderDefinition public class ImportListDefinition : ProviderDefinition, IEquatable<ImportListDefinition>
{ {
public ImportListDefinition() private static readonly MemberwiseEqualityComparer<ImportListDefinition> Comparer = MemberwiseEqualityComparer<ImportListDefinition>.ByProperties;
{
Tags = new HashSet<int>();
}
public bool Enabled { get; set; } public bool Enabled { get; set; }
public bool EnableAuto { get; set; } public bool EnableAuto { get; set; }
@ -19,9 +16,29 @@ namespace NzbDrone.Core.ImportLists
public int QualityProfileId { get; set; } public int QualityProfileId { get; set; }
public string RootFolderPath { get; set; } public string RootFolderPath { get; set; }
public bool SearchOnAdd { get; set; } public bool SearchOnAdd { get; set; }
[MemberwiseEqualityIgnore]
public override bool Enable => Enabled; public override bool Enable => Enabled;
[MemberwiseEqualityIgnore]
public ImportListType ListType { get; set; } public ImportListType ListType { get; set; }
[MemberwiseEqualityIgnore]
public TimeSpan MinRefreshInterval { get; set; } 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);
}
} }
} }

@ -0,0 +1,30 @@
using System;
using Equ;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists
{
public abstract class ImportListSettingsBase<TSettings> : IProviderConfig, IEquatable<TSettings>
where TSettings : ImportListSettingsBase<TSettings>
{
private static readonly MemberwiseEqualityComparer<TSettings> Comparer = MemberwiseEqualityComparer<TSettings>.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);
}
}
}

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.Plex namespace NzbDrone.Core.ImportLists.Plex
@ -15,9 +14,9 @@ namespace NzbDrone.Core.ImportLists.Plex
} }
} }
public class PlexListSettings : IProviderConfig public class PlexListSettings : ImportListSettingsBase<PlexListSettings>
{ {
protected virtual PlexListSettingsValidator Validator => new PlexListSettingsValidator(); private static readonly PlexListSettingsValidator Validator = new ();
public PlexListSettings() public PlexListSettings()
{ {
@ -32,7 +31,7 @@ namespace NzbDrone.Core.ImportLists.Plex
[FieldDefinition(99, Label = "Authenticate with Plex.tv", Type = FieldType.OAuth)] [FieldDefinition(99, Label = "Authenticate with Plex.tv", Type = FieldType.OAuth)]
public string SignIn { get; set; } public string SignIn { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.RSSImport namespace NzbDrone.Core.ImportLists.RSSImport
@ -13,9 +12,9 @@ namespace NzbDrone.Core.ImportLists.RSSImport
} }
} }
public class RSSImportSettings : IProviderConfig public class RSSImportSettings : ImportListSettingsBase<RSSImportSettings>
{ {
private static readonly RSSImportSettingsValidator Validator = new RSSImportSettingsValidator(); private static readonly RSSImportSettingsValidator Validator = new ();
public RSSImportSettings() public RSSImportSettings()
{ {
@ -25,7 +24,7 @@ namespace NzbDrone.Core.ImportLists.RSSImport
[FieldDefinition(0, Label = "RSS Link", HelpText = "Link to the rss feed of movies.")] [FieldDefinition(0, Label = "RSS Link", HelpText = "Link to the rss feed of movies.")]
public string Link { get; set; } public string Link { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -2,7 +2,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.Radarr namespace NzbDrone.Core.ImportLists.Radarr
@ -16,13 +15,12 @@ namespace NzbDrone.Core.ImportLists.Radarr
} }
} }
public class RadarrSettings : IProviderConfig public class RadarrSettings : ImportListSettingsBase<RadarrSettings>
{ {
private static readonly RadarrSettingsValidator Validator = new RadarrSettingsValidator(); private static readonly RadarrSettingsValidator Validator = new ();
public RadarrSettings() public RadarrSettings()
{ {
BaseUrl = "";
ApiKey = ""; ApiKey = "";
ProfileIds = Array.Empty<int>(); ProfileIds = Array.Empty<int>();
TagIds = Array.Empty<int>(); TagIds = Array.Empty<int>();
@ -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)")] [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)")] [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; } 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")] [FieldDefinition(4, Type = FieldType.Select, SelectOptionsProviderAction = "getRootFolders", Label = "Root Folders", HelpText = "Root Folders from the source instance to import from")]
public IEnumerable<string> RootFolderPaths { get; set; } public IEnumerable<string> RootFolderPaths { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.RadarrList namespace NzbDrone.Core.ImportLists.RadarrList
@ -13,14 +12,14 @@ namespace NzbDrone.Core.ImportLists.RadarrList
} }
} }
public class RadarrListSettings : IProviderConfig public class RadarrListSettings : ImportListSettingsBase<RadarrListSettings>
{ {
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")] [FieldDefinition(0, Label = "List URL", HelpText = "The URL for the movie list")]
public string Url { get; set; } public string Url { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -13,7 +13,6 @@ namespace NzbDrone.Core.ImportLists.RadarrList2.IMDbList
private readonly IMDbListSettings _settings; private readonly IMDbListSettings _settings;
public IMDbListParser(IMDbListSettings settings) public IMDbListParser(IMDbListSettings settings)
: base()
{ {
_settings = settings; _settings = settings;
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.RadarrList2.IMDbList namespace NzbDrone.Core.ImportLists.RadarrList2.IMDbList
@ -15,14 +14,14 @@ namespace NzbDrone.Core.ImportLists.RadarrList2.IMDbList
} }
} }
public class IMDbListSettings : IProviderConfig public class IMDbListSettings : ImportListSettingsBase<IMDbListSettings>
{ {
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'")] [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 string ListId { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.RadarrList2.StevenLu namespace NzbDrone.Core.ImportLists.RadarrList2.StevenLu
@ -9,21 +8,15 @@ namespace NzbDrone.Core.ImportLists.RadarrList2.StevenLu
{ {
public StevenLu2SettingsValidator() 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 public class StevenLu2Settings : ImportListSettingsBase<StevenLu2Settings>
{
Standard,
Imdb,
Metacritic,
RottenTomatoes
}
public class StevenLu2Settings : IProviderConfig
{ {
private static readonly StevenLu2SettingsValidator Validator = new StevenLu2SettingsValidator(); private static readonly StevenLu2SettingsValidator Validator = new ();
public StevenLu2Settings() 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'")] [FieldDefinition(1, Label = "Minimum Score", Type = FieldType.Number, HelpText = "Only applies if 'Rating source' is not 'Standard'")]
public int MinScore { get; set; } public int MinScore { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }
} }
public enum StevenLuSource
{
Standard,
Imdb,
Metacritic,
RottenTomatoes
}
} }

@ -12,9 +12,9 @@ namespace NzbDrone.Core.ImportLists.Rss.Plex
} }
} }
public class PlexRssImportSettings : RssImportBaseSettings public class PlexRssImportSettings : RssImportBaseSettings<PlexRssImportSettings>
{ {
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")] [FieldDefinition(0, Label = "Url", Type = FieldType.Textbox, HelpLink = "https://app.plex.tv/desktop/#!/settings/watchlist")]
public override string Url { get; set; } public override string Url { get; set; }

@ -6,7 +6,7 @@ using NzbDrone.Core.Parser;
namespace NzbDrone.Core.ImportLists.Rss namespace NzbDrone.Core.ImportLists.Rss
{ {
public abstract class RssImportBase<TSettings> : HttpImportListBase<TSettings> public abstract class RssImportBase<TSettings> : HttpImportListBase<TSettings>
where TSettings : RssImportBaseSettings, new() where TSettings : RssImportBaseSettings<TSettings>, new()
{ {
public override bool Enabled => true; public override bool Enabled => true;
public override bool EnableAuto => false; public override bool EnableAuto => false;
@ -32,7 +32,7 @@ namespace NzbDrone.Core.ImportLists.Rss
public override IImportListRequestGenerator GetRequestGenerator() public override IImportListRequestGenerator GetRequestGenerator()
{ {
return new RssImportRequestGenerator return new RssImportRequestGenerator<TSettings>
{ {
Settings = Settings Settings = Settings
}; };

@ -1,11 +1,11 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.Rss namespace NzbDrone.Core.ImportLists.Rss
{ {
public class RssImportSettingsValidator : AbstractValidator<RssImportBaseSettings> public class RssImportSettingsValidator<TSettings> : AbstractValidator<TSettings>
where TSettings : RssImportBaseSettings<TSettings>
{ {
public RssImportSettingsValidator() public RssImportSettingsValidator()
{ {
@ -13,16 +13,17 @@ namespace NzbDrone.Core.ImportLists.Rss
} }
} }
public class RssImportBaseSettings : IProviderConfig public class RssImportBaseSettings<TSettings> : ImportListSettingsBase<TSettings>
where TSettings : RssImportBaseSettings<TSettings>
{ {
private RssImportSettingsValidator Validator => new (); private static readonly RssImportSettingsValidator<TSettings> Validator = new ();
[FieldDefinition(0, Label = "Url", Type = FieldType.Textbox)] [FieldDefinition(0, Label = "Url", Type = FieldType.Textbox)]
public virtual string Url { get; set; } 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));
} }
} }
} }

@ -3,9 +3,10 @@ using NzbDrone.Common.Http;
namespace NzbDrone.Core.ImportLists.Rss namespace NzbDrone.Core.ImportLists.Rss
{ {
public class RssImportRequestGenerator : IImportListRequestGenerator public class RssImportRequestGenerator<TSettings> : IImportListRequestGenerator
where TSettings : RssImportBaseSettings<TSettings>, new()
{ {
public RssImportBaseSettings Settings { get; set; } public RssImportBaseSettings<TSettings> Settings { get; set; }
public virtual ImportListPageableRequestChain GetMovies() public virtual ImportListPageableRequestChain GetMovies()
{ {
@ -18,9 +19,7 @@ namespace NzbDrone.Core.ImportLists.Rss
private IEnumerable<ImportListRequest> GetMoviesRequest() private IEnumerable<ImportListRequest> GetMoviesRequest()
{ {
var request = new ImportListRequest(Settings.Url, HttpAccept.Rss); yield return new ImportListRequest(Settings.Url, HttpAccept.Rss);
yield return request;
} }
} }
} }

@ -2,7 +2,6 @@ using System;
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.Simkl namespace NzbDrone.Core.ImportLists.Simkl
@ -25,18 +24,17 @@ namespace NzbDrone.Core.ImportLists.Simkl
} }
} }
public class SimklSettingsBase<TSettings> : IProviderConfig public class SimklSettingsBase<TSettings> : ImportListSettingsBase<TSettings>
where TSettings : SimklSettingsBase<TSettings> where TSettings : SimklSettingsBase<TSettings>
{ {
protected virtual AbstractValidator<TSettings> Validator => new SimklSettingsBaseValidator<TSettings>(); private static readonly SimklSettingsBaseValidator<TSettings> Validator = new ();
public SimklSettingsBase() public SimklSettingsBase()
{ {
BaseUrl = "https://api.simkl.com";
SignIn = "startOAuth"; 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)] [FieldDefinition(0, Label = "Access Token", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)]
public string AccessToken { get; set; } public string AccessToken { get; set; }
@ -53,7 +51,7 @@ namespace NzbDrone.Core.ImportLists.Simkl
[FieldDefinition(99, Label = "Authenticate with Simkl", Type = FieldType.OAuth)] [FieldDefinition(99, Label = "Authenticate with Simkl", Type = FieldType.OAuth)]
public string SignIn { get; set; } public string SignIn { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate((TSettings)this)); return new NzbDroneValidationResult(Validator.Validate((TSettings)this));
} }

@ -1,12 +1,12 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.Simkl.User namespace NzbDrone.Core.ImportLists.Simkl.User
{ {
public class SimklUserSettingsValidator : SimklSettingsBaseValidator<SimklUserSettings> public class SimklUserSettingsValidator : SimklSettingsBaseValidator<SimklUserSettings>
{ {
public SimklUserSettingsValidator() public SimklUserSettingsValidator()
: base()
{ {
RuleFor(c => c.ListType).NotNull(); RuleFor(c => c.ListType).NotNull();
} }
@ -14,7 +14,7 @@ namespace NzbDrone.Core.ImportLists.Simkl.User
public class SimklUserSettings : SimklSettingsBase<SimklUserSettings> public class SimklUserSettings : SimklSettingsBase<SimklUserSettings>
{ {
protected override AbstractValidator<SimklUserSettings> Validator => new SimklUserSettingsValidator(); private static readonly SimklUserSettingsValidator Validator = new ();
public SimklUserSettings() 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")] [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 int ListType { get; set; }
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
} }
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.StevenLu namespace NzbDrone.Core.ImportLists.StevenLu
@ -13,9 +12,9 @@ namespace NzbDrone.Core.ImportLists.StevenLu
} }
} }
public class StevenLuSettings : IProviderConfig public class StevenLuSettings : ImportListSettingsBase<StevenLuSettings>
{ {
private static readonly StevenLuSettingsValidator Validator = new StevenLuSettingsValidator(); private static readonly StevenLuSettingsValidator Validator = new ();
public StevenLuSettings() 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.")] [FieldDefinition(0, Label = "URL", HelpText = "Don't change this unless you know what you are doing.")]
public string Link { get; set; } public string Link { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,13 +1,13 @@
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.TMDb.Company namespace NzbDrone.Core.ImportLists.TMDb.Company
{ {
public class TMDbCompanySettingsValidator : TMDbSettingsBaseValidator<TMDbCompanySettings> public class TMDbCompanySettingsValidator : TMDbSettingsBaseValidator<TMDbCompanySettings>
{ {
public TMDbCompanySettingsValidator() public TMDbCompanySettingsValidator()
: base()
{ {
RuleFor(c => c.CompanyId).Matches(@"^[1-9][0-9]*$", RegexOptions.IgnoreCase); 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<TMDbCompanySettings> public class TMDbCompanySettings : TMDbSettingsBase<TMDbCompanySettings>
{ {
protected override AbstractValidator<TMDbCompanySettings> Validator => new TMDbCompanySettingsValidator(); private static readonly TMDbCompanySettingsValidator Validator = new ();
public TMDbCompanySettings() 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")] [FieldDefinition(1, Label = "Company Id", Type = FieldType.Textbox, HelpText = "TMDb Id of Company to Follow")]
public string CompanyId { get; set; } public string CompanyId { get; set; }
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
} }
} }

@ -1,13 +1,13 @@
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.TMDb.Keyword namespace NzbDrone.Core.ImportLists.TMDb.Keyword
{ {
public class TMDbKeywordSettingsValidator : TMDbSettingsBaseValidator<TMDbKeywordSettings> public class TMDbKeywordSettingsValidator : TMDbSettingsBaseValidator<TMDbKeywordSettings>
{ {
public TMDbKeywordSettingsValidator() public TMDbKeywordSettingsValidator()
: base()
{ {
RuleFor(c => c.KeywordId).Matches(@"^[1-9][0-9]*$", RegexOptions.IgnoreCase); 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<TMDbKeywordSettings> public class TMDbKeywordSettings : TMDbSettingsBase<TMDbKeywordSettings>
{ {
protected override AbstractValidator<TMDbKeywordSettings> Validator => new TMDbKeywordSettingsValidator(); private static readonly TMDbKeywordSettingsValidator Validator = new ();
public TMDbKeywordSettings() 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")] [FieldDefinition(1, Label = "Keyword Id", Type = FieldType.Textbox, HelpText = "TMDb Id of keyword to Follow")]
public string KeywordId { get; set; } public string KeywordId { get; set; }
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
} }
} }

@ -1,12 +1,12 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.TMDb.List namespace NzbDrone.Core.ImportLists.TMDb.List
{ {
public class TMDbListSettingsValidator : TMDbSettingsBaseValidator<TMDbListSettings> public class TMDbListSettingsValidator : TMDbSettingsBaseValidator<TMDbListSettings>
{ {
public TMDbListSettingsValidator() public TMDbListSettingsValidator()
: base()
{ {
RuleFor(c => c.ListId).Matches("^[1-9][0-9]*$").NotEmpty(); RuleFor(c => c.ListId).Matches("^[1-9][0-9]*$").NotEmpty();
} }
@ -14,7 +14,7 @@ namespace NzbDrone.Core.ImportLists.TMDb.List
public class TMDbListSettings : TMDbSettingsBase<TMDbListSettings> public class TMDbListSettings : TMDbSettingsBase<TMDbListSettings>
{ {
protected override AbstractValidator<TMDbListSettings> Validator => new TMDbListSettingsValidator(); private static readonly TMDbListSettingsValidator Validator = new ();
public TMDbListSettings() 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")] [FieldDefinition(1, Label = "ListId", Type = FieldType.Textbox, HelpText = "TMDb Id of List to Follow")]
public string ListId { get; set; } public string ListId { get; set; }
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
} }
} }

@ -1,13 +1,13 @@
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.TMDb.Person namespace NzbDrone.Core.ImportLists.TMDb.Person
{ {
public class TMDbPersonSettingsValidator : TMDbSettingsBaseValidator<TMDbPersonSettings> public class TMDbPersonSettingsValidator : TMDbSettingsBaseValidator<TMDbPersonSettings>
{ {
public TMDbPersonSettingsValidator() public TMDbPersonSettingsValidator()
: base()
{ {
RuleFor(c => c.PersonId).Matches(@"^[1-9][0-9]*$", RegexOptions.IgnoreCase); 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<TMDbPersonSettings> public class TMDbPersonSettings : TMDbSettingsBase<TMDbPersonSettings>
{ {
protected override AbstractValidator<TMDbPersonSettings> Validator => new TMDbPersonSettingsValidator(); private static readonly TMDbPersonSettingsValidator Validator = new ();
public TMDbPersonSettings() 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)] [FieldDefinition(6, Label = "Person Writing Credits", HelpText = "Select if you want to include Writing credits", Type = FieldType.Checkbox)]
public bool PersonCastWriting { get; set; } public bool PersonCastWriting { get; set; }
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
} }
} }

@ -1,12 +1,12 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.TMDb.Popular namespace NzbDrone.Core.ImportLists.TMDb.Popular
{ {
public class TMDbPopularSettingsValidator : TMDbSettingsBaseValidator<TMDbPopularSettings> public class TMDbPopularSettingsValidator : TMDbSettingsBaseValidator<TMDbPopularSettings>
{ {
public TMDbPopularSettingsValidator() public TMDbPopularSettingsValidator()
: base()
{ {
RuleFor(c => c.TMDbListType).NotNull(); RuleFor(c => c.TMDbListType).NotNull();
@ -16,7 +16,7 @@ namespace NzbDrone.Core.ImportLists.TMDb.Popular
public class TMDbPopularSettings : TMDbSettingsBase<TMDbPopularSettings> public class TMDbPopularSettings : TMDbSettingsBase<TMDbPopularSettings>
{ {
protected override AbstractValidator<TMDbPopularSettings> Validator => new TMDbPopularSettingsValidator(); private static readonly TMDbPopularSettingsValidator Validator = new ();
public TMDbPopularSettings() public TMDbPopularSettings()
{ {
@ -27,6 +27,11 @@ namespace NzbDrone.Core.ImportLists.TMDb.Popular
public int TMDbListType { get; set; } public int TMDbListType { get; set; }
[FieldDefinition(2)] [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));
}
} }
} }

@ -1,4 +1,5 @@
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Equ;
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
@ -53,7 +54,7 @@ namespace NzbDrone.Core.ImportLists.TMDb
} }
} }
public class TMDbFilterSettings public class TMDbFilterSettings : PropertywiseEquatable<TMDbFilterSettings>
{ {
public TMDbFilterSettings() public TMDbFilterSettings()
{ {

@ -1,5 +1,4 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.TMDb namespace NzbDrone.Core.ImportLists.TMDb
@ -9,12 +8,12 @@ namespace NzbDrone.Core.ImportLists.TMDb
{ {
} }
public class TMDbSettingsBase<TSettings> : IProviderConfig public class TMDbSettingsBase<TSettings> : ImportListSettingsBase<TSettings>
where TSettings : TMDbSettingsBase<TSettings> where TSettings : TMDbSettingsBase<TSettings>
{ {
protected virtual AbstractValidator<TSettings> Validator => new TMDbSettingsBaseValidator<TSettings>(); private static readonly TMDbSettingsBaseValidator<TSettings> Validator = new ();
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate((TSettings)this)); return new NzbDroneValidationResult(Validator.Validate((TSettings)this));
} }

@ -1,12 +1,12 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.TMDb.User namespace NzbDrone.Core.ImportLists.TMDb.User
{ {
public class TMDbUserSettingsValidator : TMDbSettingsBaseValidator<TMDbUserSettings> public class TMDbUserSettingsValidator : TMDbSettingsBaseValidator<TMDbUserSettings>
{ {
public TMDbUserSettingsValidator() public TMDbUserSettingsValidator()
: base()
{ {
RuleFor(c => c.ListType).NotEmpty(); RuleFor(c => c.ListType).NotEmpty();
RuleFor(c => c.AccessToken).NotEmpty(); RuleFor(c => c.AccessToken).NotEmpty();
@ -16,7 +16,7 @@ namespace NzbDrone.Core.ImportLists.TMDb.User
public class TMDbUserSettings : TMDbSettingsBase<TMDbUserSettings> public class TMDbUserSettings : TMDbSettingsBase<TMDbUserSettings>
{ {
protected override AbstractValidator<TMDbUserSettings> Validator => new TMDbUserSettingsValidator(); private static readonly TMDbUserSettingsValidator Validator = new ();
public TMDbUserSettings() public TMDbUserSettings()
{ {
@ -36,5 +36,10 @@ namespace NzbDrone.Core.ImportLists.TMDb.User
[FieldDefinition(99, Label = "Authenticate with TMDB", Type = FieldType.OAuth)] [FieldDefinition(99, Label = "Authenticate with TMDB", Type = FieldType.OAuth)]
public string SignIn { get; set; } public string SignIn { get; set; }
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
} }
} }

@ -1,12 +1,12 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.Trakt.List namespace NzbDrone.Core.ImportLists.Trakt.List
{ {
public class TraktListSettingsValidator : TraktSettingsBaseValidator<TraktListSettings> public class TraktListSettingsValidator : TraktSettingsBaseValidator<TraktListSettings>
{ {
public TraktListSettingsValidator() public TraktListSettingsValidator()
: base()
{ {
RuleFor(c => c.Username).NotEmpty(); RuleFor(c => c.Username).NotEmpty();
RuleFor(c => c.Listname).NotEmpty(); RuleFor(c => c.Listname).NotEmpty();
@ -15,12 +15,17 @@ namespace NzbDrone.Core.ImportLists.Trakt.List
public class TraktListSettings : TraktSettingsBase<TraktListSettings> public class TraktListSettings : TraktSettingsBase<TraktListSettings>
{ {
protected override AbstractValidator<TraktListSettings> Validator => new TraktListSettingsValidator(); private static readonly TraktListSettingsValidator Validator = new ();
[FieldDefinition(1, Label = "Username", Privacy = PrivacyLevel.UserName, HelpText = "Username for the List to import from")] [FieldDefinition(1, Label = "Username", Privacy = PrivacyLevel.UserName, HelpText = "Username for the List to import from")]
public string Username { get; set; } 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")] [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 string Listname { get; set; }
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
} }
} }

@ -2,13 +2,13 @@ using System.Text.RegularExpressions;
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.Trakt.Popular namespace NzbDrone.Core.ImportLists.Trakt.Popular
{ {
public class TraktPopularSettingsValidator : TraktSettingsBaseValidator<TraktPopularSettings> public class TraktPopularSettingsValidator : TraktSettingsBaseValidator<TraktPopularSettings>
{ {
public TraktPopularSettingsValidator() public TraktPopularSettingsValidator()
: base()
{ {
RuleFor(c => c.TraktListType).NotNull(); RuleFor(c => c.TraktListType).NotNull();
@ -34,7 +34,7 @@ namespace NzbDrone.Core.ImportLists.Trakt.Popular
public class TraktPopularSettings : TraktSettingsBase<TraktPopularSettings> public class TraktPopularSettings : TraktSettingsBase<TraktPopularSettings>
{ {
protected override AbstractValidator<TraktPopularSettings> Validator => new TraktPopularSettingsValidator(); private static readonly TraktPopularSettingsValidator Validator = new ();
public TraktPopularSettings() public TraktPopularSettings()
{ {
@ -59,5 +59,10 @@ namespace NzbDrone.Core.ImportLists.Trakt.Popular
[FieldDefinition(5, Label = "Years", HelpText = "Filter movies by year or year range")] [FieldDefinition(5, Label = "Years", HelpText = "Filter movies by year or year range")]
public string Years { get; set; } public string Years { get; set; }
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
} }
} }

@ -2,7 +2,6 @@ using System;
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.Trakt namespace NzbDrone.Core.ImportLists.Trakt
@ -35,10 +34,10 @@ namespace NzbDrone.Core.ImportLists.Trakt
} }
} }
public class TraktSettingsBase<TSettings> : IProviderConfig public class TraktSettingsBase<TSettings> : ImportListSettingsBase<TSettings>
where TSettings : TraktSettingsBase<TSettings> where TSettings : TraktSettingsBase<TSettings>
{ {
protected virtual AbstractValidator<TSettings> Validator => new TraktSettingsBaseValidator<TSettings>(); private static readonly TraktSettingsBaseValidator<TSettings> Validator = new ();
public TraktSettingsBase() public TraktSettingsBase()
{ {
@ -70,7 +69,7 @@ namespace NzbDrone.Core.ImportLists.Trakt
[FieldDefinition(99, Label = "Authenticate with Trakt", Type = FieldType.OAuth)] [FieldDefinition(99, Label = "Authenticate with Trakt", Type = FieldType.OAuth)]
public string SignIn { get; set; } public string SignIn { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate((TSettings)this)); return new NzbDroneValidationResult(Validator.Validate((TSettings)this));
} }

@ -1,12 +1,12 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.Trakt.User namespace NzbDrone.Core.ImportLists.Trakt.User
{ {
public class TraktUserSettingsValidator : TraktSettingsBaseValidator<TraktUserSettings> public class TraktUserSettingsValidator : TraktSettingsBaseValidator<TraktUserSettings>
{ {
public TraktUserSettingsValidator() public TraktUserSettingsValidator()
: base()
{ {
RuleFor(c => c.TraktListType).NotNull(); RuleFor(c => c.TraktListType).NotNull();
RuleFor(c => c.AuthUser).NotEmpty(); RuleFor(c => c.AuthUser).NotEmpty();
@ -15,7 +15,7 @@ namespace NzbDrone.Core.ImportLists.Trakt.User
public class TraktUserSettings : TraktSettingsBase<TraktUserSettings> public class TraktUserSettings : TraktSettingsBase<TraktUserSettings>
{ {
protected override AbstractValidator<TraktUserSettings> Validator => new TraktUserSettingsValidator(); private static readonly TraktUserSettingsValidator Validator = new ();
public TraktUserSettings() 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)")] [FieldDefinition(2, Label = "Username", HelpText = "Username for the List to import from (empty to use Auth User)")]
public string Username { get; set; } public string Username { get; set; }
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
} }
} }

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Equ;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Languages; using NzbDrone.Core.Languages;
@ -20,9 +21,9 @@ namespace NzbDrone.Core.Indexers.FileList
} }
} }
public class FileListSettings : ITorrentIndexerSettings public class FileListSettings : PropertywiseEquatable<FileListSettings>, ITorrentIndexerSettings
{ {
private static readonly FileListSettingsValidator Validator = new FileListSettingsValidator(); private static readonly FileListSettingsValidator Validator = new ();
public FileListSettings() public FileListSettings()
{ {
@ -56,7 +57,7 @@ namespace NzbDrone.Core.Indexers.FileList
public int MinimumSeeders { get; set; } public int MinimumSeeders { get; set; }
[FieldDefinition(5)] [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)] [FieldDefinition(6, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; } public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Equ;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Languages; using NzbDrone.Core.Languages;
@ -19,7 +20,7 @@ namespace NzbDrone.Core.Indexers.HDBits
} }
} }
public class HDBitsSettings : ITorrentIndexerSettings public class HDBitsSettings : PropertywiseEquatable<HDBitsSettings>, ITorrentIndexerSettings
{ {
private static readonly HDBitsSettingsValidator Validator = new (); private static readonly HDBitsSettingsValidator Validator = new ();

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Equ;
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
@ -26,9 +27,9 @@ namespace NzbDrone.Core.Indexers.IPTorrents
} }
} }
public class IPTorrentsSettings : ITorrentIndexerSettings public class IPTorrentsSettings : PropertywiseEquatable<IPTorrentsSettings>, ITorrentIndexerSettings
{ {
private static readonly IPTorrentsSettingsValidator Validator = new IPTorrentsSettingsValidator(); private static readonly IPTorrentsSettingsValidator Validator = new ();
public IPTorrentsSettings() public IPTorrentsSettings()
{ {
@ -45,7 +46,7 @@ namespace NzbDrone.Core.Indexers.IPTorrents
public int MinimumSeeders { get; set; } public int MinimumSeeders { get; set; }
[FieldDefinition(2)] [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)] [FieldDefinition(3, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; } public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }

@ -1,9 +1,13 @@
using System;
using Equ;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Indexers namespace NzbDrone.Core.Indexers
{ {
public class IndexerDefinition : ProviderDefinition public class IndexerDefinition : ProviderDefinition, IEquatable<IndexerDefinition>
{ {
private static readonly MemberwiseEqualityComparer<IndexerDefinition> Comparer = MemberwiseEqualityComparer<IndexerDefinition>.ByProperties;
public const int DefaultPriority = 25; public const int DefaultPriority = 25;
public IndexerDefinition() public IndexerDefinition()
@ -11,17 +15,40 @@ namespace NzbDrone.Core.Indexers
Priority = DefaultPriority; 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 EnableRss { get; set; }
public bool EnableAutomaticSearch { get; set; } public bool EnableAutomaticSearch { get; set; }
public bool EnableInteractiveSearch { get; set; } public bool EnableInteractiveSearch { get; set; }
public int DownloadClientId { get; set; } public int DownloadClientId { get; set; }
public DownloadProtocol Protocol { get; set; }
public bool SupportsRss { get; set; }
public bool SupportsSearch { get; set; }
public int Priority { get; set; } public int Priority { get; set; }
[MemberwiseEqualityIgnore]
public override bool Enable => EnableRss || EnableAutomaticSearch || EnableInteractiveSearch; public override bool Enable => EnableRss || EnableAutomaticSearch || EnableInteractiveSearch;
[MemberwiseEqualityIgnore]
public IndexerStatus Status { get; set; } 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);
}
} }
} }

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Equ;
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; 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)); 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() public NewznabSettingsValidator()
{ {
@ -48,9 +49,9 @@ namespace NzbDrone.Core.Indexers.Newznab
} }
} }
public class NewznabSettings : IIndexerSettings public class NewznabSettings : PropertywiseEquatable<NewznabSettings>, IIndexerSettings
{ {
private static readonly NewznabSettingsValidator Validator = new NewznabSettingsValidator(); private static readonly NewznabSettingsValidator Validator = new ();
public NewznabSettings() public NewznabSettings()
{ {

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Equ;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Languages; using NzbDrone.Core.Languages;
@ -20,9 +21,9 @@ namespace NzbDrone.Core.Indexers.Nyaa
} }
} }
public class NyaaSettings : ITorrentIndexerSettings public class NyaaSettings : PropertywiseEquatable<NyaaSettings>, ITorrentIndexerSettings
{ {
private static readonly NyaaSettingsValidator Validator = new NyaaSettingsValidator(); private static readonly NyaaSettingsValidator Validator = new ();
public NyaaSettings() public NyaaSettings()
{ {
@ -43,7 +44,7 @@ namespace NzbDrone.Core.Indexers.Nyaa
public int MinimumSeeders { get; set; } public int MinimumSeeders { get; set; }
[FieldDefinition(3)] [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)] [FieldDefinition(4, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; } public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Equ;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Languages; using NzbDrone.Core.Languages;
@ -20,7 +21,7 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
} }
} }
public class PassThePopcornSettings : ITorrentIndexerSettings public class PassThePopcornSettings : PropertywiseEquatable<PassThePopcornSettings>, ITorrentIndexerSettings
{ {
private static readonly PassThePopcornSettingsValidator Validator = new (); private static readonly PassThePopcornSettingsValidator Validator = new ();
@ -45,7 +46,7 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
public int MinimumSeeders { get; set; } public int MinimumSeeders { get; set; }
[FieldDefinition(4)] [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)] [FieldDefinition(5, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; } public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }

@ -1,3 +1,4 @@
using Equ;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
@ -34,7 +35,7 @@ namespace NzbDrone.Core.Indexers
} }
} }
public class SeedCriteriaSettings public class SeedCriteriaSettings : PropertywiseEquatable<SeedCriteriaSettings>
{ {
[FieldDefinition(0, Type = FieldType.Textbox, Label = "Seed Ratio", HelpText = "The ratio a torrent should reach before stopping, empty is download client's default. Ratio should be at least 1.0 and follow the indexers rules")] [FieldDefinition(0, Type = FieldType.Textbox, Label = "Seed Ratio", HelpText = "The ratio a torrent should reach before stopping, empty is download client's default. Ratio should be at least 1.0 and follow the indexers rules")]
public double? SeedRatio { get; set; } public double? SeedRatio { get; set; }

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Equ;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Languages; using NzbDrone.Core.Languages;
@ -18,9 +19,9 @@ namespace NzbDrone.Core.Indexers.TorrentPotato
} }
} }
public class TorrentPotatoSettings : ITorrentIndexerSettings public class TorrentPotatoSettings : PropertywiseEquatable<TorrentPotatoSettings>, ITorrentIndexerSettings
{ {
private static readonly TorrentPotatoSettingsValidator Validator = new TorrentPotatoSettingsValidator(); private static readonly TorrentPotatoSettingsValidator Validator = new ();
public TorrentPotatoSettings() public TorrentPotatoSettings()
{ {
@ -43,7 +44,7 @@ namespace NzbDrone.Core.Indexers.TorrentPotato
public int MinimumSeeders { get; set; } public int MinimumSeeders { get; set; }
[FieldDefinition(4)] [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)] [FieldDefinition(5, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; } public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Equ;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Languages; using NzbDrone.Core.Languages;
@ -18,9 +19,9 @@ namespace NzbDrone.Core.Indexers.TorrentRss
} }
} }
public class TorrentRssIndexerSettings : ITorrentIndexerSettings public class TorrentRssIndexerSettings : PropertywiseEquatable<TorrentRssIndexerSettings>, ITorrentIndexerSettings
{ {
private static readonly TorrentRssIndexerSettingsValidator Validator = new TorrentRssIndexerSettingsValidator(); private static readonly TorrentRssIndexerSettingsValidator Validator = new ();
public TorrentRssIndexerSettings() public TorrentRssIndexerSettings()
{ {
@ -44,7 +45,7 @@ namespace NzbDrone.Core.Indexers.TorrentRss
public int MinimumSeeders { get; set; } public int MinimumSeeders { get; set; }
[FieldDefinition(4)] [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)] [FieldDefinition(5, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; } public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Equ;
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
@ -42,10 +43,12 @@ namespace NzbDrone.Core.Indexers.Torznab
} }
} }
public class TorznabSettings : NewznabSettings, ITorrentIndexerSettings public class TorznabSettings : NewznabSettings, ITorrentIndexerSettings, IEquatable<TorznabSettings>
{ {
private static readonly TorznabSettingsValidator Validator = new (); private static readonly TorznabSettingsValidator Validator = new ();
private static readonly MemberwiseEqualityComparer<TorznabSettings> Comparer = MemberwiseEqualityComparer<TorznabSettings>.ByProperties;
public TorznabSettings() public TorznabSettings()
{ {
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS; MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
@ -68,5 +71,20 @@ namespace NzbDrone.Core.Indexers.Torznab
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); 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);
}
} }
} }

@ -3,7 +3,6 @@ using System.Collections.Generic;
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Apprise namespace NzbDrone.Core.Notifications.Apprise
@ -35,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Apprise
} }
} }
public class AppriseSettings : IProviderConfig public class AppriseSettings : NotificationSettingsBase<AppriseSettings>
{ {
private static readonly AppriseSettingsValidator Validator = new (); 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)] [FieldDefinition(7, Label = "Password", Type = FieldType.Password, HelpText = "NotificationsAppriseSettingsPasswordHelpText", Privacy = PrivacyLevel.Password)]
public string AuthPassword { get; set; } public string AuthPassword { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
using NzbDrone.Core.Validation.Paths; using NzbDrone.Core.Validation.Paths;
@ -16,9 +15,9 @@ namespace NzbDrone.Core.Notifications.CustomScript
} }
} }
public class CustomScriptSettings : IProviderConfig public class CustomScriptSettings : NotificationSettingsBase<CustomScriptSettings>
{ {
private static readonly CustomScriptSettingsValidator Validator = new CustomScriptSettingsValidator(); private static readonly CustomScriptSettingsValidator Validator = new ();
[FieldDefinition(0, Label = "Path", Type = FieldType.FilePath)] [FieldDefinition(0, Label = "Path", Type = FieldType.FilePath)]
public string Path { get; set; } public string Path { get; set; }
@ -26,7 +25,7 @@ namespace NzbDrone.Core.Notifications.CustomScript
[FieldDefinition(1, Label = "NotificationsCustomScriptSettingsArguments", HelpText = "NotificationsCustomScriptSettingsArgumentsHelpText", Hidden = HiddenType.HiddenIfNotSet)] [FieldDefinition(1, Label = "NotificationsCustomScriptSettingsArguments", HelpText = "NotificationsCustomScriptSettingsArgumentsHelpText", Hidden = HiddenType.HiddenIfNotSet)]
public string Arguments { get; set; } public string Arguments { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,7 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Discord namespace NzbDrone.Core.Notifications.Discord
@ -14,7 +13,7 @@ namespace NzbDrone.Core.Notifications.Discord
} }
} }
public class DiscordSettings : IProviderConfig public class DiscordSettings : NotificationSettingsBase<DiscordSettings>
{ {
public DiscordSettings() 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)] [FieldDefinition(6, Label = "NotificationsDiscordSettingsOnManualInteractionFields", Advanced = true, SelectOptions = typeof(DiscordManualInteractionFieldType), HelpText = "NotificationsDiscordSettingsOnManualInteractionFieldsHelpText", Type = FieldType.Select)]
public IEnumerable<int> ManualInteractionFields { get; set; } public IEnumerable<int> ManualInteractionFields { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Email namespace NzbDrone.Core.Notifications.Email
@ -26,9 +25,9 @@ namespace NzbDrone.Core.Notifications.Email
} }
} }
public class EmailSettings : IProviderConfig public class EmailSettings : NotificationSettingsBase<EmailSettings>
{ {
private static readonly EmailSettingsValidator Validator = new EmailSettingsValidator(); private static readonly EmailSettingsValidator Validator = new ();
public EmailSettings() 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)] [FieldDefinition(8, Label = "NotificationsEmailSettingsBccAddress", HelpText = "NotificationsEmailSettingsBccAddressHelpText", Placeholder = "example@email.com,example1@email.com", Advanced = true)]
public IEnumerable<string> Bcc { get; set; } public IEnumerable<string> Bcc { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Gotify namespace NzbDrone.Core.Notifications.Gotify
@ -14,9 +13,9 @@ namespace NzbDrone.Core.Notifications.Gotify
} }
} }
public class GotifySettings : IProviderConfig public class GotifySettings : NotificationSettingsBase<GotifySettings>
{ {
private static readonly GotifySettingsValidator Validator = new GotifySettingsValidator(); private static readonly GotifySettingsValidator Validator = new ();
public GotifySettings() public GotifySettings()
{ {
@ -35,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Gotify
[FieldDefinition(3, Label = "NotificationsGotifySettingIncludeMoviePoster", Type = FieldType.Checkbox, HelpText = "NotificationsGotifySettingIncludeMoviePosterHelpText")] [FieldDefinition(3, Label = "NotificationsGotifySettingIncludeMoviePoster", Type = FieldType.Checkbox, HelpText = "NotificationsGotifySettingIncludeMoviePosterHelpText")]
public bool IncludeMoviePoster { get; set; } public bool IncludeMoviePoster { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Join namespace NzbDrone.Core.Notifications.Join
@ -14,15 +13,15 @@ namespace NzbDrone.Core.Notifications.Join
} }
} }
public class JoinSettings : IProviderConfig public class JoinSettings : NotificationSettingsBase<JoinSettings>
{ {
private static readonly JoinSettingsValidator Validator = new ();
public JoinSettings() public JoinSettings()
{ {
Priority = (int)JoinPriority.Normal; 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/")] [FieldDefinition(0, Label = "ApiKey", Privacy = PrivacyLevel.ApiKey, HelpText = "NotificationsJoinSettingsApiKeyHelpText", HelpLink = "https://joinjoaomgcd.appspot.com/")]
public string ApiKey { get; set; } public string ApiKey { get; set; }
@ -35,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Join
[FieldDefinition(3, Label = "NotificationsJoinSettingsNotificationPriority", Type = FieldType.Select, SelectOptions = typeof(JoinPriority))] [FieldDefinition(3, Label = "NotificationsJoinSettingsNotificationPriority", Type = FieldType.Select, SelectOptions = typeof(JoinPriority))]
public int Priority { get; set; } public int Priority { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -2,7 +2,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Mailgun namespace NzbDrone.Core.Notifications.Mailgun
@ -17,9 +16,9 @@ namespace NzbDrone.Core.Notifications.Mailgun
} }
} }
public class MailgunSettings : IProviderConfig public class MailgunSettings : NotificationSettingsBase<MailgunSettings>
{ {
private static readonly MailGunSettingsValidator Validator = new MailGunSettingsValidator(); private static readonly MailGunSettingsValidator Validator = new ();
public MailgunSettings() 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")] [FieldDefinition(4, Label = "NotificationsEmailSettingsRecipientAddress", Type = FieldType.Tag, Placeholder = "example@email.com,example1@email.com")]
public IEnumerable<string> Recipients { get; set; } public IEnumerable<string> Recipients { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -2,7 +2,6 @@ using FluentValidation;
using Newtonsoft.Json; using Newtonsoft.Json;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Emby namespace NzbDrone.Core.Notifications.Emby
@ -17,9 +16,9 @@ namespace NzbDrone.Core.Notifications.Emby
} }
} }
public class MediaBrowserSettings : IProviderConfig public class MediaBrowserSettings : NotificationSettingsBase<MediaBrowserSettings>
{ {
private static readonly MediaBrowserSettingsValidator Validator = new MediaBrowserSettingsValidator(); private static readonly MediaBrowserSettingsValidator Validator = new ();
public MediaBrowserSettings() public MediaBrowserSettings()
{ {
@ -55,7 +54,7 @@ namespace NzbDrone.Core.Notifications.Emby
public bool IsValid => !string.IsNullOrWhiteSpace(Host) && Port > 0; public bool IsValid => !string.IsNullOrWhiteSpace(Host) && Port > 0;
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Notifiarr namespace NzbDrone.Core.Notifications.Notifiarr
@ -13,14 +12,14 @@ namespace NzbDrone.Core.Notifications.Notifiarr
} }
} }
public class NotifiarrSettings : IProviderConfig public class NotifiarrSettings : NotificationSettingsBase<NotifiarrSettings>
{ {
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")] [FieldDefinition(0, Label = "ApiKey", Privacy = PrivacyLevel.ApiKey, HelpText = "NotificationsNotifiarrSettingsApiKeyHelpText", HelpLink = "https://notifiarr.com")]
public string APIKey { get; set; } public string APIKey { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -8,7 +8,7 @@ using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Notifications namespace NzbDrone.Core.Notifications
{ {
public abstract class NotificationBase<TSettings> : INotification public abstract class NotificationBase<TSettings> : INotification
where TSettings : IProviderConfig, new() where TSettings : NotificationSettingsBase<TSettings>, new()
{ {
protected const string MOVIE_GRABBED_TITLE = "Movie Grabbed"; protected const string MOVIE_GRABBED_TITLE = "Movie Grabbed";
protected const string MOVIE_DOWNLOADED_TITLE = "Movie Downloaded"; protected const string MOVIE_DOWNLOADED_TITLE = "Movie Downloaded";

@ -1,9 +1,13 @@
using System;
using Equ;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Notifications namespace NzbDrone.Core.Notifications
{ {
public class NotificationDefinition : ProviderDefinition public class NotificationDefinition : ProviderDefinition, IEquatable<NotificationDefinition>
{ {
private static readonly MemberwiseEqualityComparer<NotificationDefinition> Comparer = MemberwiseEqualityComparer<NotificationDefinition>.ByProperties;
public bool OnGrab { get; set; } public bool OnGrab { get; set; }
public bool OnDownload { get; set; } public bool OnDownload { get; set; }
public bool OnUpgrade { get; set; } public bool OnUpgrade { get; set; }
@ -13,23 +17,63 @@ namespace NzbDrone.Core.Notifications
public bool OnMovieFileDelete { get; set; } public bool OnMovieFileDelete { get; set; }
public bool OnMovieFileDeleteForUpgrade { get; set; } public bool OnMovieFileDeleteForUpgrade { get; set; }
public bool OnHealthIssue { get; set; } public bool OnHealthIssue { get; set; }
public bool IncludeHealthWarnings { get; set; }
public bool OnHealthRestored { get; set; } public bool OnHealthRestored { get; set; }
public bool OnApplicationUpdate { get; set; } public bool OnApplicationUpdate { get; set; }
public bool OnManualInteractionRequired { get; set; } public bool OnManualInteractionRequired { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnGrab { get; set; } public bool SupportsOnGrab { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnDownload { get; set; } public bool SupportsOnDownload { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnUpgrade { get; set; } public bool SupportsOnUpgrade { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnRename { get; set; } public bool SupportsOnRename { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnMovieAdded { get; set; } public bool SupportsOnMovieAdded { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnMovieDelete { get; set; } public bool SupportsOnMovieDelete { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnMovieFileDelete { get; set; } public bool SupportsOnMovieFileDelete { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnMovieFileDeleteForUpgrade { get; set; } public bool SupportsOnMovieFileDeleteForUpgrade { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnHealthIssue { get; set; } public bool SupportsOnHealthIssue { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnHealthRestored { get; set; } public bool SupportsOnHealthRestored { get; set; }
public bool IncludeHealthWarnings { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnApplicationUpdate { get; set; } public bool SupportsOnApplicationUpdate { get; set; }
[MemberwiseEqualityIgnore]
public bool SupportsOnManualInteractionRequired { get; set; } public bool SupportsOnManualInteractionRequired { get; set; }
[MemberwiseEqualityIgnore]
public override bool Enable => OnGrab || OnDownload || (OnDownload && OnUpgrade) || OnMovieAdded || OnMovieDelete || OnMovieFileDelete || (OnMovieFileDelete && OnMovieFileDeleteForUpgrade) || OnHealthIssue || OnHealthRestored || OnApplicationUpdate || OnManualInteractionRequired; public override bool Enable => OnGrab || OnDownload || (OnDownload && OnUpgrade) || 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);
}
} }
} }

@ -0,0 +1,30 @@
using System;
using Equ;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications
{
public abstract class NotificationSettingsBase<TSettings> : IProviderConfig, IEquatable<TSettings>
where TSettings : NotificationSettingsBase<TSettings>
{
private static readonly MemberwiseEqualityComparer<TSettings> Comparer = MemberwiseEqualityComparer<TSettings>.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);
}
}
}

@ -3,7 +3,6 @@ using System.Collections.Generic;
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Ntfy 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"); RuleForEach(c => c.Topics).NotEmpty().Matches("[a-zA-Z0-9_-]+").Must(c => !InvalidTopics.Contains(c)).WithMessage("Invalid topic");
} }
private static List<string> InvalidTopics => new List<string> { "announcements", "app", "docs", "settings", "stats", "mytopic-rw", "mytopic-ro", "mytopic-wo" }; private static List<string> InvalidTopics => new () { "announcements", "app", "docs", "settings", "stats", "mytopic-rw", "mytopic-ro", "mytopic-wo" };
} }
public class NtfySettings : IProviderConfig public class NtfySettings : NotificationSettingsBase<NtfySettings>
{ {
private static readonly NtfySettingsValidator Validator = new NtfySettingsValidator(); private static readonly NtfySettingsValidator Validator = new ();
public NtfySettings() 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")] [FieldDefinition(7, Label = "NotificationsNtfySettingsClickUrl", Type = FieldType.Url, HelpText = "NotificationsNtfySettingsClickUrlHelpText", Placeholder = "https://myserver.example.com/radarr")]
public string ClickUrl { get; set; } public string ClickUrl { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,7 +1,6 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Plex.Server namespace NzbDrone.Core.Notifications.Plex.Server
@ -17,9 +16,9 @@ namespace NzbDrone.Core.Notifications.Plex.Server
} }
} }
public class PlexServerSettings : IProviderConfig public class PlexServerSettings : NotificationSettingsBase<PlexServerSettings>
{ {
private static readonly PlexServerSettingsValidator Validator = new PlexServerSettingsValidator(); private static readonly PlexServerSettingsValidator Validator = new ();
public PlexServerSettings() public PlexServerSettings()
{ {
@ -62,7 +61,7 @@ namespace NzbDrone.Core.Notifications.Plex.Server
public bool IsValid => !string.IsNullOrWhiteSpace(Host); public bool IsValid => !string.IsNullOrWhiteSpace(Host);
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Prowl namespace NzbDrone.Core.Notifications.Prowl
@ -13,9 +12,9 @@ namespace NzbDrone.Core.Notifications.Prowl
} }
} }
public class ProwlSettings : IProviderConfig public class ProwlSettings : NotificationSettingsBase<ProwlSettings>
{ {
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")] [FieldDefinition(0, Label = "ApiKey", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://www.prowlapp.com/api_settings.php")]
public string ApiKey { get; set; } 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 bool IsValid => !string.IsNullOrWhiteSpace(ApiKey) && Priority >= -2 && Priority <= 2;
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -2,7 +2,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.PushBullet namespace NzbDrone.Core.Notifications.PushBullet
@ -15,9 +14,9 @@ namespace NzbDrone.Core.Notifications.PushBullet
} }
} }
public class PushBulletSettings : IProviderConfig public class PushBulletSettings : NotificationSettingsBase<PushBulletSettings>
{ {
private static readonly PushBulletSettingsValidator Validator = new PushBulletSettingsValidator(); private static readonly PushBulletSettingsValidator Validator = new ();
public PushBulletSettings() public PushBulletSettings()
{ {
@ -37,7 +36,7 @@ namespace NzbDrone.Core.Notifications.PushBullet
[FieldDefinition(3, Label = "NotificationsPushBulletSettingSenderId", HelpText = "NotificationsPushBulletSettingSenderIdHelpText")] [FieldDefinition(3, Label = "NotificationsPushBulletSettingSenderId", HelpText = "NotificationsPushBulletSettingSenderIdHelpText")]
public string SenderId { get; set; } public string SenderId { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Pushcut namespace NzbDrone.Core.Notifications.Pushcut
@ -14,7 +13,7 @@ namespace NzbDrone.Core.Notifications.Pushcut
} }
} }
public class PushcutSettings : IProviderConfig public class PushcutSettings : NotificationSettingsBase<PushcutSettings>
{ {
private static readonly PushcutSettingsValidator Validator = new (); private static readonly PushcutSettingsValidator Validator = new ();
@ -27,7 +26,7 @@ namespace NzbDrone.Core.Notifications.Pushcut
[FieldDefinition(2, Label = "NotificationsPushcutSettingsTimeSensitive", Type = FieldType.Checkbox, HelpText = "NotificationsPushcutSettingsTimeSensitiveHelpText")] [FieldDefinition(2, Label = "NotificationsPushcutSettingsTimeSensitive", Type = FieldType.Checkbox, HelpText = "NotificationsPushcutSettingsTimeSensitiveHelpText")]
public bool TimeSensitive { get; set; } public bool TimeSensitive { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -2,7 +2,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Pushover namespace NzbDrone.Core.Notifications.Pushover
@ -17,9 +16,9 @@ namespace NzbDrone.Core.Notifications.Pushover
} }
} }
public class PushoverSettings : IProviderConfig public class PushoverSettings : NotificationSettingsBase<PushoverSettings>
{ {
private static readonly PushoverSettingsValidator Validator = new PushoverSettingsValidator(); private static readonly PushoverSettingsValidator Validator = new ();
public PushoverSettings() public PushoverSettings()
{ {
@ -50,7 +49,7 @@ namespace NzbDrone.Core.Notifications.Pushover
public bool IsValid => !string.IsNullOrWhiteSpace(UserKey) && Priority >= -1 && Priority <= 2; public bool IsValid => !string.IsNullOrWhiteSpace(UserKey) && Priority >= -1 && Priority <= 2;
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -4,7 +4,6 @@ using System.Text.RegularExpressions;
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Pushsafer namespace NzbDrone.Core.Notifications.Pushsafer
@ -23,7 +22,7 @@ namespace NzbDrone.Core.Notifications.Pushsafer
} }
} }
public class PushsaferSettings : IProviderConfig public class PushsaferSettings : NotificationSettingsBase<PushsaferSettings>
{ {
private static readonly PushsaferSettingsValidator Validator = new (); 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")] [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 string IconColor { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -2,7 +2,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.SendGrid namespace NzbDrone.Core.Notifications.SendGrid
@ -18,9 +17,9 @@ namespace NzbDrone.Core.Notifications.SendGrid
} }
} }
public class SendGridSettings : IProviderConfig public class SendGridSettings : NotificationSettingsBase<SendGridSettings>
{ {
private static readonly SendGridSettingsValidator Validator = new SendGridSettingsValidator(); private static readonly SendGridSettingsValidator Validator = new ();
public SendGridSettings() 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")] [FieldDefinition(3, Label = "NotificationsEmailSettingsRecipientAddress", Type = FieldType.Tag, Placeholder = "example@email.com,example1@email.com")]
public IEnumerable<string> Recipients { get; set; } public IEnumerable<string> Recipients { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Signal namespace NzbDrone.Core.Notifications.Signal
@ -16,7 +15,7 @@ namespace NzbDrone.Core.Notifications.Signal
} }
} }
public class SignalSettings : IProviderConfig public class SignalSettings : NotificationSettingsBase<SignalSettings>
{ {
private static readonly SignalSettingsValidator Validator = new (); 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")] [FieldDefinition(6, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password, HelpText = "NotificationsSignalSettingsPasswordHelpText")]
public string AuthPassword { get; set; } public string AuthPassword { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Simplepush namespace NzbDrone.Core.Notifications.Simplepush
@ -13,9 +12,9 @@ namespace NzbDrone.Core.Notifications.Simplepush
} }
} }
public class SimplepushSettings : IProviderConfig public class SimplepushSettings : NotificationSettingsBase<SimplepushSettings>
{ {
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")] [FieldDefinition(0, Label = "NotificationsSimplepushSettingsKey", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://simplepush.io/features")]
public string Key { get; set; } public string Key { get; set; }
@ -25,7 +24,7 @@ namespace NzbDrone.Core.Notifications.Simplepush
public bool IsValid => !string.IsNullOrWhiteSpace(Key); public bool IsValid => !string.IsNullOrWhiteSpace(Key);
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Slack namespace NzbDrone.Core.Notifications.Slack
@ -14,9 +13,9 @@ namespace NzbDrone.Core.Notifications.Slack
} }
} }
public class SlackSettings : IProviderConfig public class SlackSettings : NotificationSettingsBase<SlackSettings>
{ {
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/")] [FieldDefinition(0, Label = "NotificationsSettingsWebhookUrl", HelpText = "NotificationsSlackSettingsWebhookUrlHelpText", Type = FieldType.Url, HelpLink = "https://my.slack.com/services/new/incoming-webhook/")]
public string WebHookUrl { get; set; } public string WebHookUrl { get; set; }
@ -30,7 +29,7 @@ namespace NzbDrone.Core.Notifications.Slack
[FieldDefinition(3, Label = "NotificationsSlackSettingsChannel", HelpText = "NotificationsSlackSettingsChannelHelpText", Type = FieldType.Textbox)] [FieldDefinition(3, Label = "NotificationsSlackSettingsChannel", HelpText = "NotificationsSlackSettingsChannelHelpText", Type = FieldType.Textbox)]
public string Channel { get; set; } public string Channel { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Synology namespace NzbDrone.Core.Notifications.Synology
@ -9,9 +8,9 @@ namespace NzbDrone.Core.Notifications.Synology
{ {
} }
public class SynologyIndexerSettings : IProviderConfig public class SynologyIndexerSettings : NotificationSettingsBase<SynologyIndexerSettings>
{ {
private static readonly SynologyIndexerSettingsValidator Validator = new SynologyIndexerSettingsValidator(); private static readonly SynologyIndexerSettingsValidator Validator = new ();
public SynologyIndexerSettings() public SynologyIndexerSettings()
{ {
@ -21,7 +20,7 @@ namespace NzbDrone.Core.Notifications.Synology
[FieldDefinition(0, Label = "NotificationsSettingsUpdateLibrary", Type = FieldType.Checkbox, HelpText = "NotificationsSynologySettingsUpdateLibraryHelpText")] [FieldDefinition(0, Label = "NotificationsSettingsUpdateLibrary", Type = FieldType.Checkbox, HelpText = "NotificationsSynologySettingsUpdateLibraryHelpText")]
public bool UpdateLibrary { get; set; } public bool UpdateLibrary { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,6 +1,5 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Telegram namespace NzbDrone.Core.Notifications.Telegram
@ -16,9 +15,9 @@ namespace NzbDrone.Core.Notifications.Telegram
} }
} }
public class TelegramSettings : IProviderConfig public class TelegramSettings : NotificationSettingsBase<TelegramSettings>
{ {
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")] [FieldDefinition(0, Label = "NotificationsTelegramSettingsBotToken", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://core.telegram.org/bots")]
public string BotToken { get; set; } public string BotToken { get; set; }
@ -35,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Telegram
[FieldDefinition(4, Label = "NotificationsTelegramSettingsIncludeAppName", Type = FieldType.Checkbox, HelpText = "NotificationsTelegramSettingsIncludeAppNameHelpText")] [FieldDefinition(4, Label = "NotificationsTelegramSettingsIncludeAppName", Type = FieldType.Checkbox, HelpText = "NotificationsTelegramSettingsIncludeAppNameHelpText")]
public bool IncludeAppNameInTitle { get; set; } public bool IncludeAppNameInTitle { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,7 +1,6 @@
using System; using System;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Trakt namespace NzbDrone.Core.Notifications.Trakt
@ -16,9 +15,9 @@ namespace NzbDrone.Core.Notifications.Trakt
} }
} }
public class TraktSettings : IProviderConfig public class TraktSettings : NotificationSettingsBase<TraktSettings>
{ {
private static readonly TraktSettingsValidator Validator = new TraktSettingsValidator(); private static readonly TraktSettingsValidator Validator = new ();
public TraktSettings() public TraktSettings()
{ {
@ -40,7 +39,7 @@ namespace NzbDrone.Core.Notifications.Trakt
[FieldDefinition(4, Label = "NotificationsTraktSettingsAuthenticateWithTrakt", Type = FieldType.OAuth)] [FieldDefinition(4, Label = "NotificationsTraktSettingsAuthenticateWithTrakt", Type = FieldType.OAuth)]
public string SignIn { get; set; } public string SignIn { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,7 +1,6 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Twitter namespace NzbDrone.Core.Notifications.Twitter
@ -28,9 +27,9 @@ namespace NzbDrone.Core.Notifications.Twitter
} }
} }
public class TwitterSettings : IProviderConfig public class TwitterSettings : NotificationSettingsBase<TwitterSettings>
{ {
private static readonly TwitterSettingsValidator Validator = new TwitterSettingsValidator(); private static readonly TwitterSettingsValidator Validator = new ();
public TwitterSettings() public TwitterSettings()
{ {
@ -59,7 +58,7 @@ namespace NzbDrone.Core.Notifications.Twitter
[FieldDefinition(6, Label = "NotificationsTwitterSettingsConnectToTwitter", Type = FieldType.OAuth)] [FieldDefinition(6, Label = "NotificationsTwitterSettingsConnectToTwitter", Type = FieldType.OAuth)]
public string AuthorizeNotification { get; set; } public string AuthorizeNotification { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -7,12 +7,11 @@ using NzbDrone.Core.Localization;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Movies; using NzbDrone.Core.Movies;
using NzbDrone.Core.Tags; using NzbDrone.Core.Tags;
using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Notifications.Webhook namespace NzbDrone.Core.Notifications.Webhook
{ {
public abstract class WebhookBase<TSettings> : NotificationBase<TSettings> public abstract class WebhookBase<TSettings> : NotificationBase<TSettings>
where TSettings : IProviderConfig, new() where TSettings : NotificationSettingsBase<TSettings>, new()
{ {
private readonly IConfigFileProvider _configFileProvider; private readonly IConfigFileProvider _configFileProvider;
private readonly IConfigService _configService; private readonly IConfigService _configService;

@ -1,7 +1,6 @@
using System; using System;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Webhook namespace NzbDrone.Core.Notifications.Webhook
@ -14,9 +13,9 @@ namespace NzbDrone.Core.Notifications.Webhook
} }
} }
public class WebhookSettings : IProviderConfig public class WebhookSettings : NotificationSettingsBase<WebhookSettings>
{ {
private static readonly WebhookSettingsValidator Validator = new WebhookSettingsValidator(); private static readonly WebhookSettingsValidator Validator = new ();
public WebhookSettings() public WebhookSettings()
{ {
@ -35,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Webhook
[FieldDefinition(3, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)] [FieldDefinition(3, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
public string Password { get; set; } public string Password { get; set; }
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -3,7 +3,6 @@ using FluentValidation;
using Newtonsoft.Json; using Newtonsoft.Json;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Xbmc namespace NzbDrone.Core.Notifications.Xbmc
@ -18,7 +17,7 @@ namespace NzbDrone.Core.Notifications.Xbmc
} }
} }
public class XbmcSettings : IProviderConfig public class XbmcSettings : NotificationSettingsBase<XbmcSettings>
{ {
private static readonly XbmcSettingsValidator Validator = new (); private static readonly XbmcSettingsValidator Validator = new ();
@ -69,7 +68,7 @@ namespace NzbDrone.Core.Notifications.Xbmc
[JsonIgnore] [JsonIgnore]
public string Address => $"{Host.ToUrlHost()}:{Port}{UrlBase}"; public string Address => $"{Host.ToUrlHost()}:{Port}{UrlBase}";
public NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
} }

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using Equ;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.ThingiProvider namespace NzbDrone.Core.ThingiProvider
@ -16,20 +17,22 @@ namespace NzbDrone.Core.ThingiProvider
public string Name { get; set; } public string Name { get; set; }
[JsonIgnore] [JsonIgnore]
[MemberwiseEqualityIgnore]
public string ImplementationName { get; set; } public string ImplementationName { get; set; }
public string Implementation { get; set; } public string Implementation { get; set; }
public string ConfigContract { get; set; } public string ConfigContract { get; set; }
public virtual bool Enable { get; set; } public virtual bool Enable { get; set; }
[MemberwiseEqualityIgnore]
public ProviderMessage Message { get; set; } public ProviderMessage Message { get; set; }
public HashSet<int> Tags { get; set; } public HashSet<int> Tags { get; set; }
[MemberwiseEqualityIgnore]
public IProviderConfig Settings public IProviderConfig Settings
{ {
get get => _settings;
{
return _settings;
}
set set
{ {
_settings = value; _settings = value;

@ -14,6 +14,7 @@ namespace Radarr.Api.V3.Notifications
public bool OnMovieFileDelete { get; set; } public bool OnMovieFileDelete { get; set; }
public bool OnMovieFileDeleteForUpgrade { get; set; } public bool OnMovieFileDeleteForUpgrade { get; set; }
public bool OnHealthIssue { get; set; } public bool OnHealthIssue { get; set; }
public bool IncludeHealthWarnings { get; set; }
public bool OnHealthRestored { get; set; } public bool OnHealthRestored { get; set; }
public bool OnApplicationUpdate { get; set; } public bool OnApplicationUpdate { get; set; }
public bool OnManualInteractionRequired { get; set; } public bool OnManualInteractionRequired { get; set; }
@ -29,7 +30,6 @@ namespace Radarr.Api.V3.Notifications
public bool SupportsOnHealthRestored { get; set; } public bool SupportsOnHealthRestored { get; set; }
public bool SupportsOnApplicationUpdate { get; set; } public bool SupportsOnApplicationUpdate { get; set; }
public bool SupportsOnManualInteractionRequired { get; set; } public bool SupportsOnManualInteractionRequired { get; set; }
public bool IncludeHealthWarnings { get; set; }
public string TestCommand { get; set; } public string TestCommand { get; set; }
} }
@ -53,6 +53,7 @@ namespace Radarr.Api.V3.Notifications
resource.OnMovieFileDelete = definition.OnMovieFileDelete; resource.OnMovieFileDelete = definition.OnMovieFileDelete;
resource.OnMovieFileDeleteForUpgrade = definition.OnMovieFileDeleteForUpgrade; resource.OnMovieFileDeleteForUpgrade = definition.OnMovieFileDeleteForUpgrade;
resource.OnHealthIssue = definition.OnHealthIssue; resource.OnHealthIssue = definition.OnHealthIssue;
resource.IncludeHealthWarnings = definition.IncludeHealthWarnings;
resource.OnHealthRestored = definition.OnHealthRestored; resource.OnHealthRestored = definition.OnHealthRestored;
resource.OnApplicationUpdate = definition.OnApplicationUpdate; resource.OnApplicationUpdate = definition.OnApplicationUpdate;
resource.OnManualInteractionRequired = definition.OnManualInteractionRequired; resource.OnManualInteractionRequired = definition.OnManualInteractionRequired;
@ -66,7 +67,6 @@ namespace Radarr.Api.V3.Notifications
resource.SupportsOnMovieFileDeleteForUpgrade = definition.SupportsOnMovieFileDeleteForUpgrade; resource.SupportsOnMovieFileDeleteForUpgrade = definition.SupportsOnMovieFileDeleteForUpgrade;
resource.SupportsOnHealthIssue = definition.SupportsOnHealthIssue; resource.SupportsOnHealthIssue = definition.SupportsOnHealthIssue;
resource.SupportsOnHealthRestored = definition.SupportsOnHealthRestored; resource.SupportsOnHealthRestored = definition.SupportsOnHealthRestored;
resource.IncludeHealthWarnings = definition.IncludeHealthWarnings;
resource.SupportsOnApplicationUpdate = definition.SupportsOnApplicationUpdate; resource.SupportsOnApplicationUpdate = definition.SupportsOnApplicationUpdate;
resource.SupportsOnManualInteractionRequired = definition.SupportsOnManualInteractionRequired; resource.SupportsOnManualInteractionRequired = definition.SupportsOnManualInteractionRequired;
@ -91,6 +91,7 @@ namespace Radarr.Api.V3.Notifications
definition.OnMovieFileDelete = resource.OnMovieFileDelete; definition.OnMovieFileDelete = resource.OnMovieFileDelete;
definition.OnMovieFileDeleteForUpgrade = resource.OnMovieFileDeleteForUpgrade; definition.OnMovieFileDeleteForUpgrade = resource.OnMovieFileDeleteForUpgrade;
definition.OnHealthIssue = resource.OnHealthIssue; definition.OnHealthIssue = resource.OnHealthIssue;
definition.IncludeHealthWarnings = resource.IncludeHealthWarnings;
definition.OnHealthRestored = resource.OnHealthRestored; definition.OnHealthRestored = resource.OnHealthRestored;
definition.OnApplicationUpdate = resource.OnApplicationUpdate; definition.OnApplicationUpdate = resource.OnApplicationUpdate;
definition.OnManualInteractionRequired = resource.OnManualInteractionRequired; definition.OnManualInteractionRequired = resource.OnManualInteractionRequired;
@ -104,7 +105,6 @@ namespace Radarr.Api.V3.Notifications
definition.SupportsOnMovieFileDeleteForUpgrade = resource.SupportsOnMovieFileDeleteForUpgrade; definition.SupportsOnMovieFileDeleteForUpgrade = resource.SupportsOnMovieFileDeleteForUpgrade;
definition.SupportsOnHealthIssue = resource.SupportsOnHealthIssue; definition.SupportsOnHealthIssue = resource.SupportsOnHealthIssue;
definition.SupportsOnHealthRestored = resource.SupportsOnHealthRestored; definition.SupportsOnHealthRestored = resource.SupportsOnHealthRestored;
definition.IncludeHealthWarnings = resource.IncludeHealthWarnings;
definition.SupportsOnApplicationUpdate = resource.SupportsOnApplicationUpdate; definition.SupportsOnApplicationUpdate = resource.SupportsOnApplicationUpdate;
definition.SupportsOnManualInteractionRequired = resource.SupportsOnManualInteractionRequired; definition.SupportsOnManualInteractionRequired = resource.SupportsOnManualInteractionRequired;

@ -90,10 +90,8 @@ namespace Radarr.Api.V3
var existingDefinition = _providerFactory.Find(providerResource.Id); var existingDefinition = _providerFactory.Find(providerResource.Id);
var providerDefinition = GetDefinition(providerResource, existingDefinition, true, !forceSave, false); 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. // Compare settings separately because they are not serialized with the definition.
var hasDefinitionChanged = STJson.ToJson(existingDefinition) != STJson.ToJson(providerDefinition) || var hasDefinitionChanged = !existingDefinition.Equals(providerDefinition) || !existingDefinition.Settings.Equals(providerDefinition.Settings);
STJson.ToJson(existingDefinition.Settings) != STJson.ToJson(providerDefinition.Settings);
// Only test existing definitions if it is enabled and forceSave isn't set and the definition has changed. // Only test existing definitions if it is enabled and forceSave isn't set and the definition has changed.
if (providerDefinition.Enable && !forceSave && hasDefinitionChanged) if (providerDefinition.Enable && !forceSave && hasDefinitionChanged)

Loading…
Cancel
Save