mirror of
https://github.com/Sonarr/Sonarr
synced 2026-01-26 17:32:27 +01:00
Use 'includeSubResources' to include sub resources in responses
This commit is contained in:
parent
8ee10adbd4
commit
dbb841f027
15 changed files with 114 additions and 19 deletions
|
|
@ -28,7 +28,7 @@ public CalendarController(IBroadcastSignalRMessage signalR,
|
|||
|
||||
[HttpGet]
|
||||
[Produces("application/json")]
|
||||
public List<EpisodeResource> GetCalendar(DateTime? start, DateTime? end, bool includeUnmonitored = false, bool includeSpecials = true, string tags = "", bool includeSeries = false, bool includeEpisodeFile = false, bool includeEpisodeImages = false)
|
||||
public List<EpisodeResource> GetCalendar(DateTime? start, DateTime? end, bool includeUnmonitored = false, bool includeSpecials = true, string tags = "", [FromQuery] CalendarSubresource[]? includeSubresources = null)
|
||||
{
|
||||
var startUse = start ?? DateTime.Today;
|
||||
var endUse = end ?? DateTime.Today.AddDays(2);
|
||||
|
|
@ -59,6 +59,10 @@ public List<EpisodeResource> GetCalendar(DateTime? start, DateTime? end, bool in
|
|||
result.Add(episode);
|
||||
}
|
||||
|
||||
var includeSeries = includeSubresources.Contains(CalendarSubresource.Series);
|
||||
var includeEpisodeFile = includeSubresources.Contains(CalendarSubresource.EpisodeFile);
|
||||
var includeEpisodeImages = includeSubresources.Contains(CalendarSubresource.Images);
|
||||
|
||||
var resources = MapToResource(result, includeSeries, includeEpisodeFile, includeEpisodeImages);
|
||||
|
||||
return resources.OrderBy(e => e.AirDateUtc).ToList();
|
||||
|
|
|
|||
8
src/Sonarr.Api.V5/Calendar/CalendarSubresource.cs
Normal file
8
src/Sonarr.Api.V5/Calendar/CalendarSubresource.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
namespace Sonarr.Api.V5.Calendar;
|
||||
|
||||
public enum CalendarSubresource
|
||||
{
|
||||
Series,
|
||||
EpisodeFile,
|
||||
Images
|
||||
}
|
||||
|
|
@ -23,8 +23,12 @@ public EpisodeController(ISeriesService seriesService,
|
|||
|
||||
[HttpGet]
|
||||
[Produces("application/json")]
|
||||
public List<EpisodeResource> GetEpisodes(int? seriesId, int? seasonNumber, [FromQuery]List<int> episodeIds, int? episodeFileId, bool includeSeries = false, bool includeEpisodeFile = false, bool includeImages = false)
|
||||
public List<EpisodeResource> GetEpisodes(int? seriesId, int? seasonNumber, [FromQuery]List<int> episodeIds, int? episodeFileId, [FromQuery] EpisodeSubresource[]? includeSubresources = null)
|
||||
{
|
||||
var includeSeries = includeSubresources.Contains(EpisodeSubresource.Series);
|
||||
var includeEpisodeFile = includeSubresources.Contains(EpisodeSubresource.EpisodeFile);
|
||||
var includeImages = includeSubresources.Contains(EpisodeSubresource.Images);
|
||||
|
||||
if (seriesId.HasValue)
|
||||
{
|
||||
if (seasonNumber.HasValue)
|
||||
|
|
@ -59,8 +63,10 @@ public ActionResult<EpisodeResource> SetEpisodeMonitored([FromRoute] int id, [Fr
|
|||
|
||||
[HttpPut("monitor")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult SetEpisodesMonitored([FromBody] EpisodesMonitoredResource resource, [FromQuery] bool includeImages = false)
|
||||
public IActionResult SetEpisodesMonitored([FromBody] EpisodesMonitoredResource resource, [FromQuery] EpisodeSubresource[]? includeSubresources = null)
|
||||
{
|
||||
var includeImages = includeSubresources.Contains(EpisodeSubresource.Images);
|
||||
|
||||
if (resource.EpisodeIds.Count == 1)
|
||||
{
|
||||
_episodeService.SetEpisodeMonitored(resource.EpisodeIds.First(), resource.Monitored);
|
||||
|
|
|
|||
8
src/Sonarr.Api.V5/Episodes/EpisodeSubresource.cs
Normal file
8
src/Sonarr.Api.V5/Episodes/EpisodeSubresource.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
namespace Sonarr.Api.V5.Episodes;
|
||||
|
||||
public enum EpisodeSubresource
|
||||
{
|
||||
Series,
|
||||
EpisodeFile,
|
||||
Images
|
||||
}
|
||||
|
|
@ -62,7 +62,7 @@ protected HistoryResource MapToResource(EpisodeHistory model, bool includeSeries
|
|||
|
||||
[HttpGet]
|
||||
[Produces("application/json")]
|
||||
public PagingResource<HistoryResource> GetHistory([FromQuery] PagingRequestResource paging, bool includeSeries, bool includeEpisode, [FromQuery(Name = "eventType")] int[]? eventTypes, int? episodeId, string? downloadId, [FromQuery] int[]? seriesIds = null, [FromQuery] int[]? languages = null, [FromQuery] int[]? quality = null)
|
||||
public PagingResource<HistoryResource> GetHistory([FromQuery] PagingRequestResource paging, [FromQuery(Name = "eventType")] int[]? eventTypes, int? episodeId, string? downloadId, [FromQuery] int[]? seriesIds = null, [FromQuery] int[]? languages = null, [FromQuery] int[]? quality = null, [FromQuery] HistorySubresource[]? includeSubresources = null)
|
||||
{
|
||||
var pagingResource = new PagingResource<HistoryResource>(paging);
|
||||
var pagingSpec = pagingResource.MapToPagingSpec<HistoryResource, EpisodeHistory>(
|
||||
|
|
@ -94,21 +94,29 @@ public PagingResource<HistoryResource> GetHistory([FromQuery] PagingRequestResou
|
|||
pagingSpec.FilterExpressions.Add(h => seriesIds.Contains(h.SeriesId));
|
||||
}
|
||||
|
||||
var includeSeries = includeSubresources.Contains(HistorySubresource.Series);
|
||||
var includeEpisode = includeSubresources.Contains(HistorySubresource.Episode);
|
||||
|
||||
return pagingSpec.ApplyToPage(h => _historyService.Paged(pagingSpec, languages, quality), h => MapToResource(h, includeSeries, includeEpisode));
|
||||
}
|
||||
|
||||
[HttpGet("since")]
|
||||
[Produces("application/json")]
|
||||
public List<HistoryResource> GetHistorySince(DateTime date, EpisodeHistoryEventType? eventType = null, bool includeSeries = false, bool includeEpisode = false)
|
||||
public List<HistoryResource> GetHistorySince(DateTime date, EpisodeHistoryEventType? eventType = null, [FromQuery] HistorySubresource[]? includeSubresources = null)
|
||||
{
|
||||
var includeSeries = includeSubresources.Contains(HistorySubresource.Series);
|
||||
var includeEpisode = includeSubresources.Contains(HistorySubresource.Episode);
|
||||
|
||||
return _historyService.Since(date, eventType).Select(h => MapToResource(h, includeSeries, includeEpisode)).ToList();
|
||||
}
|
||||
|
||||
[HttpGet("series")]
|
||||
[Produces("application/json")]
|
||||
public List<HistoryResource> GetSeriesHistory(int seriesId, EpisodeHistoryEventType? eventType = null, bool includeSeries = false, bool includeEpisode = false)
|
||||
public List<HistoryResource> GetSeriesHistory(int seriesId, EpisodeHistoryEventType? eventType = null, [FromQuery] HistorySubresource[]? includeSubresources = null)
|
||||
{
|
||||
var series = _seriesService.GetSeries(seriesId);
|
||||
var includeSeries = includeSubresources.Contains(HistorySubresource.Series);
|
||||
var includeEpisode = includeSubresources.Contains(HistorySubresource.Episode);
|
||||
|
||||
return _historyService.GetBySeries(seriesId, eventType).Select(h =>
|
||||
{
|
||||
|
|
@ -120,9 +128,11 @@ public List<HistoryResource> GetSeriesHistory(int seriesId, EpisodeHistoryEventT
|
|||
|
||||
[HttpGet("season")]
|
||||
[Produces("application/json")]
|
||||
public List<HistoryResource> GetSeasonHistory(int seriesId, int seasonNumber, EpisodeHistoryEventType? eventType = null, bool includeSeries = false, bool includeEpisode = false)
|
||||
public List<HistoryResource> GetSeasonHistory(int seriesId, int seasonNumber, EpisodeHistoryEventType? eventType = null, [FromQuery] HistorySubresource[]? includeSubresources = null)
|
||||
{
|
||||
var series = _seriesService.GetSeries(seriesId);
|
||||
var includeSeries = includeSubresources.Contains(HistorySubresource.Series);
|
||||
var includeEpisode = includeSubresources.Contains(HistorySubresource.Episode);
|
||||
|
||||
return _historyService.GetBySeason(seriesId, seasonNumber, eventType).Select(h =>
|
||||
{
|
||||
|
|
@ -134,10 +144,12 @@ public List<HistoryResource> GetSeasonHistory(int seriesId, int seasonNumber, Ep
|
|||
|
||||
[HttpGet("episode")]
|
||||
[Produces("application/json")]
|
||||
public List<HistoryResource> GetEpisodeHistory(int episodeId, EpisodeHistoryEventType? eventType = null, bool includeSeries = false, bool includeEpisode = false)
|
||||
public List<HistoryResource> GetEpisodeHistory(int episodeId, EpisodeHistoryEventType? eventType = null, [FromQuery] HistorySubresource[]? includeSubresources = null)
|
||||
{
|
||||
var episode = _episodeService.GetEpisode(episodeId);
|
||||
var series = _seriesService.GetSeries(episode.SeriesId);
|
||||
var includeSeries = includeSubresources.Contains(HistorySubresource.Series);
|
||||
var includeEpisode = includeSubresources.Contains(HistorySubresource.Episode);
|
||||
|
||||
return _historyService.GetByEpisode(episodeId, eventType)
|
||||
.Select(h =>
|
||||
|
|
|
|||
7
src/Sonarr.Api.V5/History/HistorySubresource.cs
Normal file
7
src/Sonarr.Api.V5/History/HistorySubresource.cs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
namespace Sonarr.Api.V5.History;
|
||||
|
||||
public enum HistorySubresource
|
||||
{
|
||||
Series,
|
||||
Episode
|
||||
}
|
||||
|
|
@ -135,7 +135,7 @@ public object RemoveMany([FromBody] QueueBulkResource resource, [FromQuery] stri
|
|||
|
||||
[HttpGet]
|
||||
[Produces("application/json")]
|
||||
public PagingResource<QueueResource> GetQueue([FromQuery] PagingRequestResource paging, bool includeUnknownSeriesItems = false, bool includeSeries = false, bool includeEpisodes = false, [FromQuery] int[]? seriesIds = null, DownloadProtocol? protocol = null, [FromQuery] int[]? languages = null, [FromQuery] int[]? quality = null, [FromQuery] QueueStatus[]? status = null)
|
||||
public PagingResource<QueueResource> GetQueue([FromQuery] PagingRequestResource paging, bool includeUnknownSeriesItems = false, [FromQuery] int[]? seriesIds = null, DownloadProtocol? protocol = null, [FromQuery] int[]? languages = null, [FromQuery] int[]? quality = null, [FromQuery] QueueStatus[]? status = null, [FromQuery] QueueSubresource[]? includeSubresources = null)
|
||||
{
|
||||
var pagingResource = new PagingResource<QueueResource>(paging);
|
||||
var pagingSpec = pagingResource.MapToPagingSpec<QueueResource, NzbDrone.Core.Queue.Queue>(
|
||||
|
|
@ -164,6 +164,9 @@ public PagingResource<QueueResource> GetQueue([FromQuery] PagingRequestResource
|
|||
"timeleft",
|
||||
SortDirection.Ascending);
|
||||
|
||||
var includeSeries = includeSubresources.Contains(QueueSubresource.Series);
|
||||
var includeEpisodes = includeSubresources.Contains(QueueSubresource.Episodes);
|
||||
|
||||
return pagingSpec.ApplyToPage((spec) => GetQueue(spec, seriesIds?.ToHashSet() ?? [], protocol, languages?.ToHashSet() ?? [], quality?.ToHashSet() ?? [], status?.ToHashSet() ?? [], includeUnknownSeriesItems), (q) => MapToResource(q, includeSeries, includeEpisodes));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,11 +37,13 @@ protected override QueueResource GetResourceById(int id)
|
|||
|
||||
[HttpGet]
|
||||
[Produces("application/json")]
|
||||
public List<QueueResource> GetQueue(int? seriesId, [FromQuery]List<int> episodeIds, bool includeSeries = false, bool includeEpisodes = false)
|
||||
public List<QueueResource> GetQueue(int? seriesId, [FromQuery]List<int> episodeIds, [FromQuery] QueueSubresource[]? includeSubresources = null)
|
||||
{
|
||||
var queue = _queueService.GetQueue();
|
||||
var pending = _pendingReleaseService.GetPendingQueue();
|
||||
var fullQueue = queue.Concat(pending);
|
||||
var includeSeries = includeSubresources.Contains(QueueSubresource.Series);
|
||||
var includeEpisodes = includeSubresources.Contains(QueueSubresource.Episodes);
|
||||
|
||||
if (seriesId.HasValue)
|
||||
{
|
||||
|
|
|
|||
7
src/Sonarr.Api.V5/Queue/QueueSubresource.cs
Normal file
7
src/Sonarr.Api.V5/Queue/QueueSubresource.cs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
namespace Sonarr.Api.V5.Queue;
|
||||
|
||||
public enum QueueSubresource
|
||||
{
|
||||
Series,
|
||||
Episodes
|
||||
}
|
||||
|
|
@ -19,7 +19,6 @@
|
|||
using NzbDrone.Core.Validation.Paths;
|
||||
using NzbDrone.SignalR;
|
||||
using Sonarr.Http;
|
||||
using Sonarr.Http.Extensions;
|
||||
using Sonarr.Http.REST;
|
||||
using Sonarr.Http.REST.Attributes;
|
||||
|
||||
|
|
@ -108,10 +107,11 @@ public SeriesController(IBroadcastSignalRMessage signalRBroadcaster,
|
|||
|
||||
[HttpGet]
|
||||
[Produces("application/json")]
|
||||
public List<SeriesResource> AllSeries(int? tvdbId, bool includeSeasonImages = false)
|
||||
public List<SeriesResource> AllSeries(int? tvdbId, [FromQuery] SeriesSubresource[]? includeSubresources = null)
|
||||
{
|
||||
var seriesStats = _seriesStatisticsService.SeriesStatistics();
|
||||
var seriesResources = new List<SeriesResource>();
|
||||
var includeSeasonImages = includeSubresources.Contains(SeriesSubresource.SeasonImages);
|
||||
|
||||
if (tvdbId.HasValue)
|
||||
{
|
||||
|
|
@ -138,8 +138,10 @@ public override ActionResult<SeriesResource> GetResourceByIdWithErrorHandler(int
|
|||
|
||||
[RestGetById]
|
||||
[Produces("application/json")]
|
||||
public ActionResult<SeriesResource> GetResourceByIdWithErrorHandler(int id, [FromQuery]bool includeSeasonImages = false)
|
||||
public ActionResult<SeriesResource> GetResourceByIdWithErrorHandler(int id, [FromQuery] SeriesSubresource[]? includeSubresources = null)
|
||||
{
|
||||
var includeSeasonImages = includeSubresources.Contains(SeriesSubresource.SeasonImages);
|
||||
|
||||
try
|
||||
{
|
||||
var series = GetSeriesResourceById(id, includeSeasonImages);
|
||||
|
|
@ -154,17 +156,25 @@ public ActionResult<SeriesResource> GetResourceByIdWithErrorHandler(int id, [Fro
|
|||
|
||||
protected override SeriesResource? GetResourceById(int id)
|
||||
{
|
||||
var includeSeasonImages = Request?.GetBooleanQueryParameter("includeSeasonImages", false) ?? false;
|
||||
var includeSubresources = Request.Query["includeSubresources"].Select(v =>
|
||||
{
|
||||
if (Enum.TryParse<SeriesSubresource>(v, true, out var enumValue))
|
||||
{
|
||||
return enumValue;
|
||||
}
|
||||
|
||||
throw new BadRequestException($"The value '{v}' is not valid.");
|
||||
});
|
||||
|
||||
var includeSeasonImages = includeSubresources.Contains(SeriesSubresource.SeasonImages);
|
||||
|
||||
// Parse IncludeImages and use it
|
||||
return GetSeriesResourceById(id, includeSeasonImages);
|
||||
}
|
||||
|
||||
private SeriesResource? GetSeriesResourceById(int id, bool includeSeasonImages = false)
|
||||
private SeriesResource? GetSeriesResourceById(int id, bool includeSeasonImages)
|
||||
{
|
||||
var series = _seriesService.GetSeries(id);
|
||||
|
||||
// Parse IncludeImages and use it
|
||||
return GetSeriesResource(series, includeSeasonImages);
|
||||
}
|
||||
|
||||
|
|
|
|||
6
src/Sonarr.Api.V5/Series/SeriesSubresource.cs
Normal file
6
src/Sonarr.Api.V5/Series/SeriesSubresource.cs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
namespace Sonarr.Api.V5.Series;
|
||||
|
||||
public enum SeriesSubresource
|
||||
{
|
||||
SeasonImages
|
||||
}
|
||||
|
|
@ -28,7 +28,7 @@ public CutoffController(IEpisodeCutoffService episodeCutoffService,
|
|||
|
||||
[HttpGet]
|
||||
[Produces("application/json")]
|
||||
public PagingResource<EpisodeResource> GetCutoffUnmetEpisodes([FromQuery] PagingRequestResource paging, bool includeSeries = false, bool includeEpisodeFile = false, bool includeImages = false, bool monitored = true)
|
||||
public PagingResource<EpisodeResource> GetCutoffUnmetEpisodes([FromQuery] PagingRequestResource paging, bool monitored = true, [FromQuery] CutoffSubresource[]? includeSubresources = null)
|
||||
{
|
||||
var pagingResource = new PagingResource<EpisodeResource>(paging);
|
||||
var pagingSpec = pagingResource.MapToPagingSpec<EpisodeResource, Episode>(
|
||||
|
|
@ -50,6 +50,10 @@ public PagingResource<EpisodeResource> GetCutoffUnmetEpisodes([FromQuery] Paging
|
|||
pagingSpec.FilterExpressions.Add(v => v.Monitored == false || v.Series.Monitored == false);
|
||||
}
|
||||
|
||||
var includeSeries = includeSubresources.Contains(CutoffSubresource.Series);
|
||||
var includeEpisodeFile = includeSubresources.Contains(CutoffSubresource.EpisodeFile);
|
||||
var includeImages = includeSubresources.Contains(CutoffSubresource.Images);
|
||||
|
||||
var resource = pagingSpec.ApplyToPage(_episodeCutoffService.EpisodesWhereCutoffUnmet, v => MapToResource(v, includeSeries, includeEpisodeFile, includeImages));
|
||||
|
||||
return resource;
|
||||
|
|
|
|||
8
src/Sonarr.Api.V5/Wanted/CutoffSubresource.cs
Normal file
8
src/Sonarr.Api.V5/Wanted/CutoffSubresource.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
namespace Sonarr.Api.V5.Wanted;
|
||||
|
||||
public enum CutoffSubresource
|
||||
{
|
||||
Series,
|
||||
EpisodeFile,
|
||||
Images
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ public MissingController(IEpisodeService episodeService,
|
|||
|
||||
[HttpGet]
|
||||
[Produces("application/json")]
|
||||
public PagingResource<EpisodeResource> GetMissingEpisodes([FromQuery] PagingRequestResource paging, bool includeSeries = false, bool includeImages = false, bool monitored = true)
|
||||
public PagingResource<EpisodeResource> GetMissingEpisodes([FromQuery] PagingRequestResource paging, bool monitored = true, [FromQuery] MissingSubresource[]? includeSubresources = null)
|
||||
{
|
||||
var pagingResource = new PagingResource<EpisodeResource>(paging);
|
||||
var pagingSpec = pagingResource.MapToPagingSpec<EpisodeResource, Episode>(
|
||||
|
|
@ -46,6 +46,9 @@ public PagingResource<EpisodeResource> GetMissingEpisodes([FromQuery] PagingRequ
|
|||
pagingSpec.FilterExpressions.Add(v => v.Monitored == false || v.Series.Monitored == false);
|
||||
}
|
||||
|
||||
var includeSeries = includeSubresources.Contains(MissingSubresource.Series);
|
||||
var includeImages = includeSubresources.Contains(MissingSubresource.Images);
|
||||
|
||||
var resource = pagingSpec.ApplyToPage(_episodeService.EpisodesWithoutFiles, v => MapToResource(v, includeSeries, false, includeImages));
|
||||
|
||||
return resource;
|
||||
|
|
|
|||
7
src/Sonarr.Api.V5/Wanted/MissingSubresource.cs
Normal file
7
src/Sonarr.Api.V5/Wanted/MissingSubresource.cs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
namespace Sonarr.Api.V5.Wanted;
|
||||
|
||||
public enum MissingSubresource
|
||||
{
|
||||
Series,
|
||||
Images
|
||||
}
|
||||
Loading…
Reference in a new issue