diff --git a/src/NzbDrone.Core/ThingiProvider/ProviderDefinition.cs b/src/NzbDrone.Core/ThingiProvider/ProviderDefinition.cs index 388bf362f..292bc4bc5 100644 --- a/src/NzbDrone.Core/ThingiProvider/ProviderDefinition.cs +++ b/src/NzbDrone.Core/ThingiProvider/ProviderDefinition.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Text.Json.Serialization; using NzbDrone.Core.Datastore; namespace NzbDrone.Core.ThingiProvider @@ -13,7 +14,10 @@ namespace NzbDrone.Core.ThingiProvider private IProviderConfig _settings; public string Name { get; set; } + + [JsonIgnore] public string ImplementationName { get; set; } + public string Implementation { get; set; } public string ConfigContract { get; set; } public virtual bool Enable { get; set; } diff --git a/src/Prowlarr.Api.V1/ProviderControllerBase.cs b/src/Prowlarr.Api.V1/ProviderControllerBase.cs index f65b916bb..f585e8b52 100644 --- a/src/Prowlarr.Api.V1/ProviderControllerBase.cs +++ b/src/Prowlarr.Api.V1/ProviderControllerBase.cs @@ -3,6 +3,7 @@ using System.Linq; using FluentValidation; using FluentValidation.Results; using Microsoft.AspNetCore.Mvc; +using NzbDrone.Common.Serializer; using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; using NzbDrone.Http.REST.Attributes; @@ -69,7 +70,7 @@ namespace Prowlarr.Api.V1 [Produces("application/json")] public ActionResult CreateProvider([FromBody] TProviderResource providerResource, [FromQuery] bool forceSave = false) { - var providerDefinition = GetDefinition(providerResource, true, !forceSave, false); + var providerDefinition = GetDefinition(providerResource, null, true, !forceSave, false); if (providerDefinition.Enable) { @@ -86,15 +87,24 @@ namespace Prowlarr.Api.V1 [Produces("application/json")] public ActionResult UpdateProvider([FromBody] TProviderResource providerResource, [FromQuery] bool forceSave = false) { - var providerDefinition = GetDefinition(providerResource, true, !forceSave, false); + var existingDefinition = _providerFactory.Find(providerResource.Id); + var providerDefinition = GetDefinition(providerResource, existingDefinition, true, !forceSave, false); - // Only test existing definitions if it is enabled and forceSave isn't set. - if (providerDefinition.Enable && !forceSave) + // Comparing via JSON string to eliminate the need for every provider implementation to implement equality checks. + // Compare settings separately because they are not serialized with the definition. + var hasDefinitionChanged = STJson.ToJson(existingDefinition) != STJson.ToJson(providerDefinition) || + STJson.ToJson(existingDefinition.Settings) != STJson.ToJson(providerDefinition.Settings); + + // Only test existing definitions if it is enabled and forceSave isn't set and the definition has changed. + if (providerDefinition.Enable && !forceSave && hasDefinitionChanged) { Test(providerDefinition, true); } - _providerFactory.Update(providerDefinition); + if (hasDefinitionChanged) + { + _providerFactory.Update(providerDefinition); + } return Accepted(providerResource.Id); } @@ -140,9 +150,8 @@ namespace Prowlarr.Api.V1 return Accepted(_providerFactory.Update(definitionsToUpdate).Select(x => _resourceMapper.ToResource(x))); } - private TProviderDefinition GetDefinition(TProviderResource providerResource, bool validate, bool includeWarnings, bool forceValidate) + private TProviderDefinition GetDefinition(TProviderResource providerResource, TProviderDefinition existingDefinition, bool validate, bool includeWarnings, bool forceValidate) { - var existingDefinition = providerResource.Id > 0 ? _providerFactory.Find(providerResource.Id) : null; var definition = _resourceMapper.ToModel(providerResource, existingDefinition); if (validate && (definition.Enable || forceValidate)) @@ -199,7 +208,8 @@ namespace Prowlarr.Api.V1 [Consumes("application/json")] public object Test([FromBody] TProviderResource providerResource) { - var providerDefinition = GetDefinition(providerResource, true, true, true); + var existingDefinition = providerResource.Id > 0 ? _providerFactory.Find(providerResource.Id) : null; + var providerDefinition = GetDefinition(providerResource, existingDefinition, true, true, true); Test(providerDefinition, true); @@ -232,9 +242,10 @@ namespace Prowlarr.Api.V1 [HttpPost("action/{name}")] [Consumes("application/json")] [Produces("application/json")] - public IActionResult RequestAction(string name, [FromBody] TProviderResource resource) + public IActionResult RequestAction(string name, [FromBody] TProviderResource providerResource) { - var providerDefinition = GetDefinition(resource, false, false, false); + var existingDefinition = providerResource.Id > 0 ? _providerFactory.Find(providerResource.Id) : null; + var providerDefinition = GetDefinition(providerResource, existingDefinition, false, false, false); var query = Request.Query.ToDictionary(x => x.Key, x => x.Value.ToString());