1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2026-04-18 21:35:27 -04:00

Add v5 Release Profiles endpoints

This commit is contained in:
Mark McDowall
2025-12-29 14:51:10 -08:00
parent 3977d8766c
commit f963a0d972
2 changed files with 144 additions and 0 deletions
@@ -0,0 +1,91 @@
using FluentValidation;
using Microsoft.AspNetCore.Mvc;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Profiles.Releases;
using NzbDrone.Core.Tags;
using Sonarr.Http;
using Sonarr.Http.REST;
using Sonarr.Http.REST.Attributes;
namespace Sonarr.Api.V5.Profiles.Release;
[V5ApiController]
public class ReleaseProfileController : RestController<ReleaseProfileResource>
{
private readonly IReleaseProfileService _profileService;
private readonly IIndexerFactory _indexerFactory;
private readonly ITagService _tagService;
public ReleaseProfileController(IReleaseProfileService profileService, IIndexerFactory indexerFactory, ITagService tagService)
{
_profileService = profileService;
_indexerFactory = indexerFactory;
_tagService = tagService;
SharedValidator.RuleFor(d => d).Custom((restriction, context) =>
{
if (restriction.Required.Empty() && restriction.Ignored.Empty())
{
context.AddFailure(nameof(ReleaseProfile.Required), "'Must contain' or 'Must not contain' is required");
}
if (restriction.Required.Any(t => t.IsNullOrWhiteSpace()))
{
context.AddFailure(nameof(ReleaseProfile.Required), "'Must contain' should not contain whitespaces or an empty string");
}
if (restriction.Ignored.Any(t => t.IsNullOrWhiteSpace()))
{
context.AddFailure(nameof(ReleaseProfile.Ignored), "'Must not contain' should not contain whitespaces or an empty string");
}
if (restriction.Enabled && restriction.IndexerId != 0 && !_indexerFactory.Exists(restriction.IndexerId))
{
context.AddFailure(nameof(ReleaseProfile.IndexerId), "Indexer does not exist");
}
});
SharedValidator.RuleFor(d => d.Tags.Intersect(d.ExcludedTags))
.Empty()
.WithName("ExcludedTags")
.WithMessage(d => $"'{string.Join(", ", _tagService.GetTags(d.Tags.Intersect(d.ExcludedTags)).Select(t => t.Label))}' cannot be in both 'Tags' and 'Excluded Tags'");
}
[RestPostById]
public ActionResult<ReleaseProfileResource> Create([FromBody] ReleaseProfileResource resource)
{
var model = resource.ToModel();
model = _profileService.Add(model);
return Created(model.Id);
}
[RestDeleteById]
public ActionResult DeleteProfile(int id)
{
_profileService.Delete(id);
return NoContent();
}
[RestPutById]
public ActionResult<ReleaseProfileResource> Update([FromBody] ReleaseProfileResource resource)
{
var model = resource.ToModel();
_profileService.Update(model);
return Accepted(model.Id);
}
protected override ReleaseProfileResource GetResourceById(int id)
{
return _profileService.Get(id).ToResource();
}
[HttpGet]
public List<ReleaseProfileResource> GetAll()
{
return _profileService.All().ToResource();
}
}
@@ -0,0 +1,53 @@
using NzbDrone.Core.Profiles.Releases;
using Sonarr.Http.REST;
namespace Sonarr.Api.V5.Profiles.Release;
public class ReleaseProfileResource : RestResource
{
public string? Name { get; set; }
public bool Enabled { get; set; }
public List<string> Required { get; set; } = [];
public List<string> Ignored { get; set; } = [];
public int IndexerId { get; set; }
public HashSet<int> Tags { get; set; } = [];
public HashSet<int> ExcludedTags { get; set; } = [];
}
public static class RestrictionResourceMapper
{
public static ReleaseProfileResource ToResource(this ReleaseProfile model)
{
return new ReleaseProfileResource
{
Id = model.Id,
Name = model.Name,
Enabled = model.Enabled,
Required = model.Required ?? [],
Ignored = model.Ignored ?? [],
IndexerId = model.IndexerId,
Tags = model.Tags ?? [],
ExcludedTags = model.ExcludedTags ?? [],
};
}
public static ReleaseProfile ToModel(this ReleaseProfileResource resource)
{
return new ReleaseProfile
{
Id = resource.Id,
Name = resource.Name,
Enabled = resource.Enabled,
Required = resource.Required,
Ignored = resource.Ignored,
IndexerId = resource.IndexerId,
Tags = resource.Tags,
ExcludedTags = resource.ExcludedTags
};
}
public static List<ReleaseProfileResource> ToResource(this IEnumerable<ReleaseProfile> models)
{
return models.Select(ToResource).ToList();
}
}