mirror of
https://github.com/Sonarr/Sonarr.git
synced 2026-03-05 13:20:20 -05:00
Add v5 Connection endpoints
This commit is contained in:
@@ -36,7 +36,7 @@ namespace NzbDrone.Core.Notifications.Plex.Server
|
||||
[FieldDefinition(1, Label = "Host")]
|
||||
public string Host { get; set; }
|
||||
|
||||
[FieldDefinition(2, Label = "Port")]
|
||||
[FieldDefinition(2, Label = "Port", Type = FieldType.Number)]
|
||||
public int Port { get; set; }
|
||||
|
||||
[FieldDefinition(3, Label = "UseSsl", Type = FieldType.Checkbox, HelpText = "NotificationsSettingsUseSslHelpText")]
|
||||
|
||||
12
src/Sonarr.Api.V5/Connections/ConnectionBulkResource.cs
Normal file
12
src/Sonarr.Api.V5/Connections/ConnectionBulkResource.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using NzbDrone.Core.Notifications;
|
||||
using Sonarr.Api.V5.Provider;
|
||||
|
||||
namespace Sonarr.Api.V5.Connections;
|
||||
|
||||
public class ConnectionBulkResource : ProviderBulkResource<ConnectionBulkResource>
|
||||
{
|
||||
}
|
||||
|
||||
public class ConnectionBulkResourceMapper : ProviderBulkResourceMapper<ConnectionBulkResource, NotificationDefinition>
|
||||
{
|
||||
}
|
||||
31
src/Sonarr.Api.V5/Connections/ConnectionController.cs
Normal file
31
src/Sonarr.Api.V5/Connections/ConnectionController.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.Notifications;
|
||||
using NzbDrone.SignalR;
|
||||
using Sonarr.Api.V5.Provider;
|
||||
using Sonarr.Http;
|
||||
|
||||
namespace Sonarr.Api.V5.Connections;
|
||||
|
||||
[V5ApiController]
|
||||
public class ConnectionController : ProviderControllerBase<ConnectionResource, ConnectionBulkResource, INotification, NotificationDefinition>
|
||||
{
|
||||
public static readonly ConnectionResourceMapper ResourceMapper = new();
|
||||
public static readonly ConnectionBulkResourceMapper BulkResourceMapper = new();
|
||||
|
||||
public ConnectionController(IBroadcastSignalRMessage signalRBroadcaster, NotificationFactory notificationFactory)
|
||||
: base(signalRBroadcaster, notificationFactory, "connection", ResourceMapper, BulkResourceMapper)
|
||||
{
|
||||
}
|
||||
|
||||
[NonAction]
|
||||
public override ActionResult<ConnectionResource> UpdateProvider([FromBody] ConnectionBulkResource providerResource)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[NonAction]
|
||||
public override ActionResult DeleteProviders([FromBody] ConnectionBulkResource resource)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
110
src/Sonarr.Api.V5/Connections/ConnectionResource.cs
Normal file
110
src/Sonarr.Api.V5/Connections/ConnectionResource.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
using NzbDrone.Core.Notifications;
|
||||
using Sonarr.Api.V5.Provider;
|
||||
|
||||
namespace Sonarr.Api.V5.Connections;
|
||||
|
||||
public class ConnectionResource : ProviderResource<ConnectionResource>
|
||||
{
|
||||
public string? Link { get; set; }
|
||||
public bool OnGrab { get; set; }
|
||||
public bool OnDownload { get; set; }
|
||||
public bool OnUpgrade { get; set; }
|
||||
public bool OnImportComplete { get; set; }
|
||||
public bool OnRename { get; set; }
|
||||
public bool OnSeriesAdd { get; set; }
|
||||
public bool OnSeriesDelete { get; set; }
|
||||
public bool OnEpisodeFileDelete { get; set; }
|
||||
public bool OnEpisodeFileDeleteForUpgrade { get; set; }
|
||||
public bool OnHealthIssue { get; set; }
|
||||
public bool IncludeHealthWarnings { get; set; }
|
||||
public bool OnHealthRestored { get; set; }
|
||||
public bool OnApplicationUpdate { get; set; }
|
||||
public bool OnManualInteractionRequired { get; set; }
|
||||
public bool SupportsOnGrab { get; set; }
|
||||
public bool SupportsOnDownload { get; set; }
|
||||
public bool SupportsOnUpgrade { get; set; }
|
||||
public bool SupportsOnImportComplete { get; set; }
|
||||
public bool SupportsOnRename { get; set; }
|
||||
public bool SupportsOnSeriesAdd { get; set; }
|
||||
public bool SupportsOnSeriesDelete { get; set; }
|
||||
public bool SupportsOnEpisodeFileDelete { get; set; }
|
||||
public bool SupportsOnEpisodeFileDeleteForUpgrade { get; set; }
|
||||
public bool SupportsOnHealthIssue { get; set; }
|
||||
public bool SupportsOnHealthRestored { get; set; }
|
||||
public bool SupportsOnApplicationUpdate { get; set; }
|
||||
public bool SupportsOnManualInteractionRequired { get; set; }
|
||||
public string? TestCommand { get; set; }
|
||||
}
|
||||
|
||||
public class ConnectionResourceMapper : ProviderResourceMapper<ConnectionResource, NotificationDefinition>
|
||||
{
|
||||
public override ConnectionResource ToResource(NotificationDefinition definition)
|
||||
{
|
||||
var resource = base.ToResource(definition);
|
||||
|
||||
resource.OnGrab = definition.OnGrab;
|
||||
resource.OnDownload = definition.OnDownload;
|
||||
resource.OnUpgrade = definition.OnUpgrade;
|
||||
resource.OnImportComplete = definition.OnImportComplete;
|
||||
resource.OnRename = definition.OnRename;
|
||||
resource.OnSeriesAdd = definition.OnSeriesAdd;
|
||||
resource.OnSeriesDelete = definition.OnSeriesDelete;
|
||||
resource.OnEpisodeFileDelete = definition.OnEpisodeFileDelete;
|
||||
resource.OnEpisodeFileDeleteForUpgrade = definition.OnEpisodeFileDeleteForUpgrade;
|
||||
resource.OnHealthIssue = definition.OnHealthIssue;
|
||||
resource.IncludeHealthWarnings = definition.IncludeHealthWarnings;
|
||||
resource.OnHealthRestored = definition.OnHealthRestored;
|
||||
resource.OnApplicationUpdate = definition.OnApplicationUpdate;
|
||||
resource.OnManualInteractionRequired = definition.OnManualInteractionRequired;
|
||||
resource.SupportsOnGrab = definition.SupportsOnGrab;
|
||||
resource.SupportsOnDownload = definition.SupportsOnDownload;
|
||||
resource.SupportsOnUpgrade = definition.SupportsOnUpgrade;
|
||||
resource.SupportsOnImportComplete = definition.SupportsOnImportComplete;
|
||||
resource.SupportsOnRename = definition.SupportsOnRename;
|
||||
resource.SupportsOnSeriesAdd = definition.SupportsOnSeriesAdd;
|
||||
resource.SupportsOnSeriesDelete = definition.SupportsOnSeriesDelete;
|
||||
resource.SupportsOnEpisodeFileDelete = definition.SupportsOnEpisodeFileDelete;
|
||||
resource.SupportsOnEpisodeFileDeleteForUpgrade = definition.SupportsOnEpisodeFileDeleteForUpgrade;
|
||||
resource.SupportsOnHealthIssue = definition.SupportsOnHealthIssue;
|
||||
resource.SupportsOnHealthRestored = definition.SupportsOnHealthRestored;
|
||||
resource.SupportsOnApplicationUpdate = definition.SupportsOnApplicationUpdate;
|
||||
resource.SupportsOnManualInteractionRequired = definition.SupportsOnManualInteractionRequired;
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
public override NotificationDefinition ToModel(ConnectionResource resource, NotificationDefinition? existingDefinition)
|
||||
{
|
||||
var definition = base.ToModel(resource, existingDefinition);
|
||||
|
||||
definition.OnGrab = resource.OnGrab;
|
||||
definition.OnDownload = resource.OnDownload;
|
||||
definition.OnUpgrade = resource.OnUpgrade;
|
||||
definition.OnImportComplete = resource.OnImportComplete;
|
||||
definition.OnRename = resource.OnRename;
|
||||
definition.OnSeriesAdd = resource.OnSeriesAdd;
|
||||
definition.OnSeriesDelete = resource.OnSeriesDelete;
|
||||
definition.OnEpisodeFileDelete = resource.OnEpisodeFileDelete;
|
||||
definition.OnEpisodeFileDeleteForUpgrade = resource.OnEpisodeFileDeleteForUpgrade;
|
||||
definition.OnHealthIssue = resource.OnHealthIssue;
|
||||
definition.IncludeHealthWarnings = resource.IncludeHealthWarnings;
|
||||
definition.OnHealthRestored = resource.OnHealthRestored;
|
||||
definition.OnApplicationUpdate = resource.OnApplicationUpdate;
|
||||
definition.OnManualInteractionRequired = resource.OnManualInteractionRequired;
|
||||
definition.SupportsOnGrab = resource.SupportsOnGrab;
|
||||
definition.SupportsOnDownload = resource.SupportsOnDownload;
|
||||
definition.SupportsOnUpgrade = resource.SupportsOnUpgrade;
|
||||
definition.SupportsOnImportComplete = resource.SupportsOnImportComplete;
|
||||
definition.SupportsOnRename = resource.SupportsOnRename;
|
||||
definition.SupportsOnSeriesAdd = resource.SupportsOnSeriesAdd;
|
||||
definition.SupportsOnSeriesDelete = resource.SupportsOnSeriesDelete;
|
||||
definition.SupportsOnEpisodeFileDelete = resource.SupportsOnEpisodeFileDelete;
|
||||
definition.SupportsOnEpisodeFileDeleteForUpgrade = resource.SupportsOnEpisodeFileDeleteForUpgrade;
|
||||
definition.SupportsOnHealthIssue = resource.SupportsOnHealthIssue;
|
||||
definition.SupportsOnHealthRestored = resource.SupportsOnHealthRestored;
|
||||
definition.SupportsOnApplicationUpdate = resource.SupportsOnApplicationUpdate;
|
||||
definition.SupportsOnManualInteractionRequired = resource.SupportsOnManualInteractionRequired;
|
||||
|
||||
return definition;
|
||||
}
|
||||
}
|
||||
26
src/Sonarr.Api.V5/Provider/ProviderBulkResource.cs
Normal file
26
src/Sonarr.Api.V5/Provider/ProviderBulkResource.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
|
||||
namespace Sonarr.Api.V5.Provider
|
||||
{
|
||||
public class ProviderBulkResource<T>
|
||||
{
|
||||
public List<int> Ids { get; set; } = [];
|
||||
public List<int>? Tags { get; set; }
|
||||
public ApplyTags ApplyTags { get; set; }
|
||||
}
|
||||
|
||||
public class ProviderBulkResourceMapper<TProviderBulkResource, TProviderDefinition>
|
||||
where TProviderBulkResource : ProviderBulkResource<TProviderBulkResource>, new()
|
||||
where TProviderDefinition : ProviderDefinition, new()
|
||||
{
|
||||
public virtual List<TProviderDefinition> UpdateModel(TProviderBulkResource resource, List<TProviderDefinition> existingDefinitions)
|
||||
{
|
||||
if (resource == null)
|
||||
{
|
||||
return new List<TProviderDefinition>();
|
||||
}
|
||||
|
||||
return existingDefinitions;
|
||||
}
|
||||
}
|
||||
}
|
||||
320
src/Sonarr.Api.V5/Provider/ProviderControllerBase.cs
Normal file
320
src/Sonarr.Api.V5/Provider/ProviderControllerBase.cs
Normal file
@@ -0,0 +1,320 @@
|
||||
using FluentValidation;
|
||||
using FluentValidation.Results;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Datastore.Events;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
using NzbDrone.Core.ThingiProvider.Events;
|
||||
using NzbDrone.Core.Validation;
|
||||
using NzbDrone.SignalR;
|
||||
using Sonarr.Http.REST;
|
||||
using Sonarr.Http.REST.Attributes;
|
||||
|
||||
namespace Sonarr.Api.V5.Provider
|
||||
{
|
||||
public abstract class ProviderControllerBase<TProviderResource, TBulkProviderResource, TProvider, TProviderDefinition> : RestControllerWithSignalR<TProviderResource, TProviderDefinition>,
|
||||
IHandle<ProviderAddedEvent<TProvider>>,
|
||||
IHandle<ProviderUpdatedEvent<TProvider>>,
|
||||
IHandle<ProviderDeletedEvent<TProvider>>
|
||||
where TProviderDefinition : ProviderDefinition, new()
|
||||
where TProvider : IProvider
|
||||
where TProviderResource : ProviderResource<TProviderResource>, new()
|
||||
where TBulkProviderResource : ProviderBulkResource<TBulkProviderResource>, new()
|
||||
{
|
||||
private readonly IProviderFactory<TProvider, TProviderDefinition> _providerFactory;
|
||||
private readonly ProviderResourceMapper<TProviderResource, TProviderDefinition> _resourceMapper;
|
||||
private readonly ProviderBulkResourceMapper<TBulkProviderResource, TProviderDefinition> _bulkResourceMapper;
|
||||
|
||||
protected ProviderControllerBase(IBroadcastSignalRMessage signalRBroadcaster,
|
||||
IProviderFactory<TProvider,
|
||||
TProviderDefinition> providerFactory,
|
||||
string resource,
|
||||
ProviderResourceMapper<TProviderResource, TProviderDefinition> resourceMapper,
|
||||
ProviderBulkResourceMapper<TBulkProviderResource, TProviderDefinition> bulkResourceMapper)
|
||||
: base(signalRBroadcaster)
|
||||
{
|
||||
_providerFactory = providerFactory;
|
||||
_resourceMapper = resourceMapper;
|
||||
_bulkResourceMapper = bulkResourceMapper;
|
||||
|
||||
SharedValidator.RuleFor(c => c.Name).NotEmpty();
|
||||
SharedValidator.RuleFor(c => c.Name).Must((v, c) => !_providerFactory.All().Any(p => p.Name.EqualsIgnoreCase(c) && p.Id != v.Id)).WithMessage("Should be unique");
|
||||
SharedValidator.RuleFor(c => c.Implementation).NotEmpty();
|
||||
SharedValidator.RuleFor(c => c.ConfigContract).NotEmpty();
|
||||
|
||||
PostValidator.RuleFor(c => c.Fields).NotNull();
|
||||
}
|
||||
|
||||
protected override TProviderResource GetResourceById(int id)
|
||||
{
|
||||
var definition = _providerFactory.Get(id);
|
||||
_providerFactory.SetProviderCharacteristics(definition);
|
||||
|
||||
return _resourceMapper.ToResource(definition);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Produces("application/json")]
|
||||
public List<TProviderResource> GetAll()
|
||||
{
|
||||
var providerDefinitions = _providerFactory.All();
|
||||
|
||||
var result = new List<TProviderResource>(providerDefinitions.Count);
|
||||
|
||||
foreach (var definition in providerDefinitions.OrderBy(p => p.ImplementationName))
|
||||
{
|
||||
_providerFactory.SetProviderCharacteristics(definition);
|
||||
|
||||
result.Add(_resourceMapper.ToResource(definition));
|
||||
}
|
||||
|
||||
return result.OrderBy(p => p.Name).ToList();
|
||||
}
|
||||
|
||||
[RestPostById]
|
||||
[Consumes("application/json")]
|
||||
[Produces("application/json")]
|
||||
public ActionResult<TProviderResource> CreateProvider([FromBody] TProviderResource providerResource, [FromQuery] bool forceSave = false)
|
||||
{
|
||||
var providerDefinition = GetDefinition(providerResource, null, true, !forceSave, false);
|
||||
|
||||
if (providerDefinition.Enable)
|
||||
{
|
||||
Test(providerDefinition, !forceSave);
|
||||
}
|
||||
|
||||
providerDefinition = _providerFactory.Create(providerDefinition);
|
||||
|
||||
return Created(providerDefinition.Id);
|
||||
}
|
||||
|
||||
[RestPutById]
|
||||
[Consumes("application/json")]
|
||||
[Produces("application/json")]
|
||||
public ActionResult<TProviderResource> UpdateProvider([FromRoute] int id, [FromBody] TProviderResource providerResource, [FromQuery] bool forceSave = false)
|
||||
{
|
||||
// TODO: Remove fallback to Id from body in next API version bump
|
||||
var existingDefinition = _providerFactory.Find(id) ?? _providerFactory.Find(providerResource.Id);
|
||||
|
||||
if (existingDefinition == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var providerDefinition = GetDefinition(providerResource, existingDefinition, true, !forceSave, false);
|
||||
|
||||
// Compare settings separately because they are not serialized with the definition.
|
||||
var hasDefinitionChanged = !existingDefinition.Equals(providerDefinition) || !existingDefinition.Settings.Equals(providerDefinition.Settings);
|
||||
|
||||
// Only test existing definitions if it is enabled and forceSave isn't set and the definition has changed.
|
||||
if (providerDefinition.Enable && !forceSave && hasDefinitionChanged)
|
||||
{
|
||||
Test(providerDefinition, true);
|
||||
}
|
||||
|
||||
if (hasDefinitionChanged)
|
||||
{
|
||||
_providerFactory.Update(providerDefinition);
|
||||
}
|
||||
|
||||
return Accepted(existingDefinition.Id);
|
||||
}
|
||||
|
||||
[HttpPut("bulk")]
|
||||
[Consumes("application/json")]
|
||||
[Produces("application/json")]
|
||||
public virtual ActionResult<TProviderResource> UpdateProvider([FromBody] TBulkProviderResource providerResource)
|
||||
{
|
||||
if (!providerResource.Ids.Any())
|
||||
{
|
||||
throw new BadRequestException("ids must be provided");
|
||||
}
|
||||
|
||||
var definitionsToUpdate = _providerFactory.Get(providerResource.Ids).ToList();
|
||||
|
||||
foreach (var definition in definitionsToUpdate)
|
||||
{
|
||||
_providerFactory.SetProviderCharacteristics(definition);
|
||||
|
||||
if (providerResource.Tags != null)
|
||||
{
|
||||
var newTags = providerResource.Tags;
|
||||
var applyTags = providerResource.ApplyTags;
|
||||
|
||||
switch (applyTags)
|
||||
{
|
||||
case ApplyTags.Add:
|
||||
newTags.ForEach(t => definition.Tags.Add(t));
|
||||
break;
|
||||
case ApplyTags.Remove:
|
||||
newTags.ForEach(t => definition.Tags.Remove(t));
|
||||
break;
|
||||
case ApplyTags.Replace:
|
||||
definition.Tags = new HashSet<int>(newTags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_bulkResourceMapper.UpdateModel(providerResource, definitionsToUpdate);
|
||||
|
||||
return Accepted(_providerFactory.Update(definitionsToUpdate).Select(x => _resourceMapper.ToResource(x)));
|
||||
}
|
||||
|
||||
private TProviderDefinition GetDefinition(TProviderResource providerResource, TProviderDefinition? existingDefinition, bool validate, bool includeWarnings, bool forceValidate)
|
||||
{
|
||||
var definition = _resourceMapper.ToModel(providerResource, existingDefinition);
|
||||
|
||||
if (validate && (definition.Enable || forceValidate))
|
||||
{
|
||||
Validate(definition, includeWarnings);
|
||||
}
|
||||
|
||||
return definition;
|
||||
}
|
||||
|
||||
[RestDeleteById]
|
||||
public ActionResult DeleteProvider(int id)
|
||||
{
|
||||
_providerFactory.Delete(id);
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpDelete("bulk")]
|
||||
[Consumes("application/json")]
|
||||
public virtual ActionResult DeleteProviders([FromBody] TBulkProviderResource resource)
|
||||
{
|
||||
_providerFactory.Delete(resource.Ids);
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpGet("schema")]
|
||||
[Produces("application/json")]
|
||||
public List<TProviderResource> GetTemplates()
|
||||
{
|
||||
var defaultDefinitions = _providerFactory.GetDefaultDefinitions().OrderBy(p => p.ImplementationName).ToList();
|
||||
|
||||
var result = new List<TProviderResource>(defaultDefinitions.Count);
|
||||
|
||||
foreach (var providerDefinition in defaultDefinitions)
|
||||
{
|
||||
var providerResource = _resourceMapper.ToResource(providerDefinition);
|
||||
var presetDefinitions = _providerFactory.GetPresetDefinitions(providerDefinition);
|
||||
|
||||
providerResource.Presets = presetDefinitions
|
||||
.Select(v => _resourceMapper.ToResource(v))
|
||||
.ToList();
|
||||
|
||||
result.Add(providerResource);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[SkipValidation(true, false)]
|
||||
[HttpPost("test")]
|
||||
[Consumes("application/json")]
|
||||
public ActionResult Test([FromBody] TProviderResource providerResource, [FromQuery] bool forceTest = false)
|
||||
{
|
||||
var existingDefinition = providerResource.Id > 0 ? _providerFactory.Find(providerResource.Id) : null;
|
||||
var providerDefinition = GetDefinition(providerResource, existingDefinition, true, !forceTest, true);
|
||||
|
||||
Test(providerDefinition, true);
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpPost("testall")]
|
||||
[Produces("application/json")]
|
||||
public IActionResult TestAll()
|
||||
{
|
||||
var providerDefinitions = _providerFactory.All()
|
||||
.Where(c => c.Settings.Validate().IsValid && c.Enable)
|
||||
.ToList();
|
||||
var result = new List<ProviderTestAllResult>();
|
||||
|
||||
foreach (var definition in providerDefinitions)
|
||||
{
|
||||
var validationFailures = new List<ValidationFailure>();
|
||||
|
||||
validationFailures.AddRange(definition.Settings.Validate().Errors);
|
||||
validationFailures.AddRange(_providerFactory.Test(definition).Errors);
|
||||
|
||||
result.Add(new ProviderTestAllResult
|
||||
{
|
||||
Id = definition.Id,
|
||||
ValidationFailures = validationFailures
|
||||
});
|
||||
}
|
||||
|
||||
return result.Any(c => !c.IsValid) ? BadRequest(result) : Ok(result);
|
||||
}
|
||||
|
||||
[SkipValidation]
|
||||
[HttpPost("action/{name}")]
|
||||
[Consumes("application/json")]
|
||||
[Produces("application/json")]
|
||||
public IActionResult RequestAction([FromRoute] string name, [FromBody] TProviderResource providerResource)
|
||||
{
|
||||
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());
|
||||
|
||||
var data = _providerFactory.RequestAction(providerDefinition, name, query);
|
||||
|
||||
return Content(data.ToJson(), "application/json");
|
||||
}
|
||||
|
||||
[NonAction]
|
||||
public virtual void Handle(ProviderAddedEvent<TProvider> message)
|
||||
{
|
||||
BroadcastResourceChange(ModelAction.Created, message.Definition.Id);
|
||||
}
|
||||
|
||||
[NonAction]
|
||||
public virtual void Handle(ProviderUpdatedEvent<TProvider> message)
|
||||
{
|
||||
BroadcastResourceChange(ModelAction.Updated, message.Definition.Id);
|
||||
}
|
||||
|
||||
[NonAction]
|
||||
public virtual void Handle(ProviderDeletedEvent<TProvider> message)
|
||||
{
|
||||
BroadcastResourceChange(ModelAction.Deleted, message.ProviderId);
|
||||
}
|
||||
|
||||
private void Validate(TProviderDefinition definition, bool includeWarnings)
|
||||
{
|
||||
var validationResult = definition.Settings.Validate();
|
||||
|
||||
VerifyValidationResult(validationResult, includeWarnings);
|
||||
}
|
||||
|
||||
protected virtual void Test(TProviderDefinition definition, bool includeWarnings)
|
||||
{
|
||||
var validationResult = _providerFactory.Test(definition);
|
||||
|
||||
VerifyValidationResult(validationResult, includeWarnings);
|
||||
}
|
||||
|
||||
protected void VerifyValidationResult(ValidationResult validationResult, bool includeWarnings)
|
||||
{
|
||||
var result = validationResult as NzbDroneValidationResult ?? new NzbDroneValidationResult(validationResult.Errors);
|
||||
|
||||
if (includeWarnings && (!result.IsValid || result.HasWarnings))
|
||||
{
|
||||
throw new ValidationException(result.Failures);
|
||||
}
|
||||
|
||||
if (!result.IsValid)
|
||||
{
|
||||
throw new ValidationException(result.Errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
62
src/Sonarr.Api.V5/Provider/ProviderResource.cs
Normal file
62
src/Sonarr.Api.V5/Provider/ProviderResource.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using NzbDrone.Common.Reflection;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
using Sonarr.Http.ClientSchema;
|
||||
using Sonarr.Http.REST;
|
||||
|
||||
namespace Sonarr.Api.V5.Provider
|
||||
{
|
||||
public class ProviderResource<T> : RestResource
|
||||
{
|
||||
public string? Name { get; set; }
|
||||
public List<Field> Fields { get; set; } = [];
|
||||
public string? ImplementationName { get; set; }
|
||||
public string? Implementation { get; set; }
|
||||
public string? ConfigContract { get; set; }
|
||||
public string? InfoLink { get; set; }
|
||||
public ProviderMessage? Message { get; set; }
|
||||
public HashSet<int> Tags { get; set; } = [];
|
||||
public List<T> Presets { get; set; } = [];
|
||||
}
|
||||
|
||||
public class ProviderResourceMapper<TProviderResource, TProviderDefinition>
|
||||
where TProviderResource : ProviderResource<TProviderResource>, new()
|
||||
where TProviderDefinition : ProviderDefinition, new()
|
||||
{
|
||||
public virtual TProviderResource ToResource(TProviderDefinition definition)
|
||||
{
|
||||
return new TProviderResource
|
||||
{
|
||||
Id = definition.Id,
|
||||
|
||||
Name = definition.Name,
|
||||
ImplementationName = definition.ImplementationName,
|
||||
Implementation = definition.Implementation,
|
||||
ConfigContract = definition.ConfigContract,
|
||||
Message = definition.Message,
|
||||
Tags = definition.Tags,
|
||||
Fields = SchemaBuilder.ToSchema(definition.Settings),
|
||||
|
||||
InfoLink = $"https://wiki.servarr.com/sonarr/supported#{definition.Implementation.ToLower()}"
|
||||
};
|
||||
}
|
||||
|
||||
public virtual TProviderDefinition ToModel(TProviderResource resource, TProviderDefinition? existingDefinition)
|
||||
{
|
||||
var definition = new TProviderDefinition
|
||||
{
|
||||
Id = resource.Id,
|
||||
Name = resource.Name,
|
||||
ImplementationName = resource.ImplementationName,
|
||||
Implementation = resource.Implementation,
|
||||
ConfigContract = resource.ConfigContract,
|
||||
Message = resource.Message,
|
||||
Tags = resource.Tags
|
||||
};
|
||||
|
||||
var configContract = ReflectionExtensions.CoreAssembly.FindTypeByName(definition.ConfigContract);
|
||||
definition.Settings = (IProviderConfig)SchemaBuilder.ReadFromSchema(resource.Fields, configContract, existingDefinition?.Settings);
|
||||
|
||||
return definition;
|
||||
}
|
||||
}
|
||||
}
|
||||
17
src/Sonarr.Api.V5/Provider/ProviderTestAllResult.cs
Normal file
17
src/Sonarr.Api.V5/Provider/ProviderTestAllResult.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using FluentValidation.Results;
|
||||
using NzbDrone.Common.Extensions;
|
||||
|
||||
namespace Sonarr.Api.V5.Provider
|
||||
{
|
||||
public class ProviderTestAllResult
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public bool IsValid => ValidationFailures.Empty();
|
||||
public List<ValidationFailure> ValidationFailures { get; set; }
|
||||
|
||||
public ProviderTestAllResult()
|
||||
{
|
||||
ValidationFailures = new List<ValidationFailure>();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user