Add v5 tag endpoints

This commit is contained in:
Mark McDowall 2025-11-14 18:26:53 -08:00
parent e89d58985a
commit 20ad1b4410
4 changed files with 186 additions and 0 deletions

View file

@ -0,0 +1,78 @@
using System.Text.RegularExpressions;
using FluentValidation;
using Microsoft.AspNetCore.Mvc;
using NzbDrone.Core.AutoTagging;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Tags;
using NzbDrone.SignalR;
using Sonarr.Http;
using Sonarr.Http.REST;
using Sonarr.Http.REST.Attributes;
namespace Sonarr.Api.V5.Tags;
[V5ApiController]
public class TagController : RestControllerWithSignalR<TagResource, Tag>,
IHandle<TagsUpdatedEvent>,
IHandle<AutoTagsUpdatedEvent>
{
private readonly ITagService _tagService;
public TagController(IBroadcastSignalRMessage signalRBroadcaster,
ITagService tagService)
: base(signalRBroadcaster)
{
_tagService = tagService;
SharedValidator.RuleFor(c => c.Label).Cascade(CascadeMode.Stop)
.NotEmpty()
.Matches("^[a-z0-9-]+$", RegexOptions.IgnoreCase)
.WithMessage("Allowed characters a-z, 0-9 and -");
}
protected override TagResource GetResourceById(int id)
{
return _tagService.GetTag(id).ToResource();
}
[HttpGet]
[Produces("application/json")]
public List<TagResource> GetAll()
{
return _tagService.All().ToResource();
}
[RestPostById]
[Consumes("application/json")]
public ActionResult<TagResource> Create([FromBody] TagResource resource)
{
return Created(_tagService.Add(resource.ToModel()).Id);
}
[RestPutById]
[Consumes("application/json")]
public ActionResult<TagResource> Update([FromBody] TagResource resource)
{
_tagService.Update(resource.ToModel());
return Accepted(resource.Id);
}
[RestDeleteById]
public void DeleteTag(int id)
{
_tagService.Delete(id);
}
[NonAction]
public void Handle(TagsUpdatedEvent message)
{
BroadcastResourceChange(ModelAction.Sync);
}
[NonAction]
public void Handle(AutoTagsUpdatedEvent message)
{
BroadcastResourceChange(ModelAction.Sync);
}
}

View file

@ -0,0 +1,29 @@
using Microsoft.AspNetCore.Mvc;
using NzbDrone.Core.Tags;
using Sonarr.Http;
using Sonarr.Http.REST;
namespace Sonarr.Api.V5.Tags;
[V5ApiController("tag/detail")]
public class TagDetailsController : RestController<TagDetailsResource>
{
private readonly ITagService _tagService;
public TagDetailsController(ITagService tagService)
{
_tagService = tagService;
}
protected override TagDetailsResource GetResourceById(int id)
{
return _tagService.Details(id).ToResource();
}
[HttpGet]
[Produces("application/json")]
public List<TagDetailsResource> GetAll()
{
return _tagService.Details().ToResource();
}
}

View file

@ -0,0 +1,44 @@
using NzbDrone.Core.Tags;
using Sonarr.Http.REST;
namespace Sonarr.Api.V5.Tags;
public class TagDetailsResource : RestResource
{
public string? Label { get; set; }
public List<int> DelayProfileIds { get; set; } = [];
public List<int> ImportListIds { get; set; } = [];
public List<int> NotificationIds { get; set; } = [];
public List<int> RestrictionIds { get; set; } = [];
public List<int> ExcludedReleaseProfileIds { get; set; } = [];
public List<int> IndexerIds { get; set; } = [];
public List<int> DownloadClientIds { get; set; } = [];
public List<int> AutoTagIds { get; set; } = [];
public List<int> SeriesIds { get; set; } = [];
}
public static class TagDetailsResourceMapper
{
public static TagDetailsResource ToResource(this TagDetails model)
{
return new TagDetailsResource
{
Id = model.Id,
Label = model.Label,
DelayProfileIds = model.DelayProfileIds,
ImportListIds = model.ImportListIds,
NotificationIds = model.NotificationIds,
RestrictionIds = model.RestrictionIds,
ExcludedReleaseProfileIds = model.ExcludedReleaseProfileIds,
IndexerIds = model.IndexerIds,
DownloadClientIds = model.DownloadClientIds,
AutoTagIds = model.AutoTagIds,
SeriesIds = model.SeriesIds
};
}
public static List<TagDetailsResource> ToResource(this IEnumerable<TagDetails> models)
{
return models.Select(ToResource).ToList();
}
}

View file

@ -0,0 +1,35 @@
using NzbDrone.Core.Tags;
using Sonarr.Http.REST;
namespace Sonarr.Api.V5.Tags;
public class TagResource : RestResource
{
public string? Label { get; set; }
}
public static class TagResourceMapper
{
public static TagResource ToResource(this Tag model)
{
return new TagResource
{
Id = model.Id,
Label = model.Label
};
}
public static Tag ToModel(this TagResource resource)
{
return new Tag
{
Id = resource.Id,
Label = resource.Label
};
}
public static List<TagResource> ToResource(this IEnumerable<Tag> models)
{
return models.Select(ToResource).ToList();
}
}