From 349829b1385dbe9b81bb42db03453ebaeccdd868 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Mon, 9 Oct 2023 13:55:15 -0700 Subject: [PATCH] fixup! Paging params in API docs Closes #6003 --- .../WantedTests/CutoffUnmetFixture.cs | 2 +- .../ApiTests/WantedTests/MissingFixture.cs | 2 +- .../Client/ClientBase.cs | 5 +- .../History/HistoryController.cs | 17 +- src/Sonarr.Api.V3/Logs/LogController.cs | 10 +- src/Sonarr.Api.V3/Queue/QueueController.cs | 4 +- src/Sonarr.Api.V3/Wanted/CutoffController.cs | 14 +- src/Sonarr.Api.V3/Wanted/MissingController.cs | 14 +- src/Sonarr.Api.V3/openapi.json | 167 ++++++++---------- .../Extensions/RequestExtensions.cs | 74 -------- src/Sonarr.Http/PagingResource.cs | 4 - src/Sonarr.Http/PagingResourceFilter.cs | 8 - 12 files changed, 93 insertions(+), 228 deletions(-) delete mode 100644 src/Sonarr.Http/PagingResourceFilter.cs diff --git a/src/NzbDrone.Integration.Test/ApiTests/WantedTests/CutoffUnmetFixture.cs b/src/NzbDrone.Integration.Test/ApiTests/WantedTests/CutoffUnmetFixture.cs index 1a75068e4..1b4a2b61d 100644 --- a/src/NzbDrone.Integration.Test/ApiTests/WantedTests/CutoffUnmetFixture.cs +++ b/src/NzbDrone.Integration.Test/ApiTests/WantedTests/CutoffUnmetFixture.cs @@ -56,7 +56,7 @@ namespace NzbDrone.Integration.Test.ApiTests.WantedTests var series = EnsureSeries(266189, "The Blacklist", false); EnsureEpisodeFile(series, 1, 1, Quality.SDTV); - var result = WantedCutoffUnmet.GetPaged(0, 15, "airDateUtc", "desc", "monitored", "false"); + var result = WantedCutoffUnmet.GetPaged(0, 15, "airDateUtc", "desc", "monitored", false); result.Records.Should().NotBeEmpty(); } diff --git a/src/NzbDrone.Integration.Test/ApiTests/WantedTests/MissingFixture.cs b/src/NzbDrone.Integration.Test/ApiTests/WantedTests/MissingFixture.cs index a91b954f7..bc6ef9dfa 100644 --- a/src/NzbDrone.Integration.Test/ApiTests/WantedTests/MissingFixture.cs +++ b/src/NzbDrone.Integration.Test/ApiTests/WantedTests/MissingFixture.cs @@ -58,7 +58,7 @@ namespace NzbDrone.Integration.Test.ApiTests.WantedTests { EnsureSeries(266189, "The Blacklist", false); - var result = WantedMissing.GetPaged(0, 15, "airDateUtc", "desc", "monitored", "false"); + var result = WantedMissing.GetPaged(0, 15, "airDateUtc", "desc", "monitored", false); result.Records.Should().NotBeEmpty(); } diff --git a/src/NzbDrone.Integration.Test/Client/ClientBase.cs b/src/NzbDrone.Integration.Test/Client/ClientBase.cs index 8e2091f94..aa45059f6 100644 --- a/src/NzbDrone.Integration.Test/Client/ClientBase.cs +++ b/src/NzbDrone.Integration.Test/Client/ClientBase.cs @@ -102,7 +102,7 @@ namespace NzbDrone.Integration.Test.Client return Get>(request); } - public PagingResource GetPaged(int pageNumber, int pageSize, string sortKey, string sortDir, string filterKey = null, string filterValue = null) + public PagingResource GetPaged(int pageNumber, int pageSize, string sortKey, string sortDir, string filterKey = null, object filterValue = null) { var request = BuildRequest(); request.AddParameter("page", pageNumber); @@ -113,8 +113,7 @@ namespace NzbDrone.Integration.Test.Client if (filterKey != null && filterValue != null) { - request.AddParameter("filterKey", filterKey); - request.AddParameter("filterValue", filterValue); + request.AddParameter(filterKey, filterValue); } return Get>(request); diff --git a/src/Sonarr.Api.V3/History/HistoryController.cs b/src/Sonarr.Api.V3/History/HistoryController.cs index b7cf660ca..088ed9163 100644 --- a/src/Sonarr.Api.V3/History/HistoryController.cs +++ b/src/Sonarr.Api.V3/History/HistoryController.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Mvc; +using NzbDrone.Common.Extensions; using NzbDrone.Core.CustomFormats; using NzbDrone.Core.Datastore; using NzbDrone.Core.DecisionEngine.Specifications; @@ -61,30 +62,24 @@ namespace Sonarr.Api.V3.History [HttpGet] [Produces("application/json")] - public PagingResource GetHistory([FromQuery] PagingRequestResource paging, bool includeSeries, bool includeEpisode) + public PagingResource GetHistory([FromQuery] PagingRequestResource paging, bool includeSeries, bool includeEpisode, int? eventType, int? episodeId, string downloadId) { var pagingResource = new PagingResource(paging); var pagingSpec = pagingResource.MapToPagingSpec("date", SortDirection.Descending); - var eventTypeFilter = pagingResource.Filters.FirstOrDefault(f => f.Key == "eventType"); - var episodeIdFilter = pagingResource.Filters.FirstOrDefault(f => f.Key == "episodeId"); - var downloadIdFilter = pagingResource.Filters.FirstOrDefault(f => f.Key == "downloadId"); - - if (eventTypeFilter != null) + if (eventType.HasValue) { - var filterValue = (EpisodeHistoryEventType)Convert.ToInt32(eventTypeFilter.Value); + var filterValue = (EpisodeHistoryEventType)eventType.Value; pagingSpec.FilterExpressions.Add(v => v.EventType == filterValue); } - if (episodeIdFilter != null) + if (episodeId.HasValue) { - var episodeId = Convert.ToInt32(episodeIdFilter.Value); pagingSpec.FilterExpressions.Add(h => h.EpisodeId == episodeId); } - if (downloadIdFilter != null) + if (downloadId.IsNotNullOrWhiteSpace()) { - var downloadId = downloadIdFilter.Value; pagingSpec.FilterExpressions.Add(h => h.DownloadId == downloadId); } diff --git a/src/Sonarr.Api.V3/Logs/LogController.cs b/src/Sonarr.Api.V3/Logs/LogController.cs index eb28993f2..e838bc7e6 100644 --- a/src/Sonarr.Api.V3/Logs/LogController.cs +++ b/src/Sonarr.Api.V3/Logs/LogController.cs @@ -1,5 +1,5 @@ -using System.Linq; using Microsoft.AspNetCore.Mvc; +using NzbDrone.Common.Extensions; using NzbDrone.Core.Instrumentation; using Sonarr.Http; using Sonarr.Http.Extensions; @@ -18,7 +18,7 @@ namespace Sonarr.Api.V3.Logs [HttpGet] [Produces("application/json")] - public PagingResource GetLogs([FromQuery] PagingRequestResource paging) + public PagingResource GetLogs([FromQuery] PagingRequestResource paging, string level) { var pagingResource = new PagingResource(paging); var pageSpec = pagingResource.MapToPagingSpec(); @@ -28,11 +28,9 @@ namespace Sonarr.Api.V3.Logs pageSpec.SortKey = "id"; } - var levelFilter = pagingResource.Filters.FirstOrDefault(f => f.Key == "level"); - - if (levelFilter != null) + if (level.IsNotNullOrWhiteSpace()) { - switch (levelFilter.Value) + switch (level) { case "fatal": pageSpec.FilterExpressions.Add(h => h.Level == "Fatal"); diff --git a/src/Sonarr.Api.V3/Queue/QueueController.cs b/src/Sonarr.Api.V3/Queue/QueueController.cs index 6259956c3..edb631ee4 100644 --- a/src/Sonarr.Api.V3/Queue/QueueController.cs +++ b/src/Sonarr.Api.V3/Queue/QueueController.cs @@ -135,9 +135,9 @@ namespace Sonarr.Api.V3.Queue [HttpGet] [Produces("application/json")] - public PagingResource GetQueue(bool includeUnknownSeriesItems = false, bool includeSeries = false, bool includeEpisode = false) + public PagingResource GetQueue([FromQuery] PagingRequestResource paging, bool includeUnknownSeriesItems = false, bool includeSeries = false, bool includeEpisode = false) { - var pagingResource = Request.ReadPagingResourceFromRequest(); + var pagingResource = new PagingResource(paging); var pagingSpec = pagingResource.MapToPagingSpec("timeleft", SortDirection.Ascending); return pagingSpec.ApplyToPage((spec) => GetQueue(spec, includeUnknownSeriesItems), (q) => MapToResource(q, includeSeries, includeEpisode)); diff --git a/src/Sonarr.Api.V3/Wanted/CutoffController.cs b/src/Sonarr.Api.V3/Wanted/CutoffController.cs index 47a805829..479212ec7 100644 --- a/src/Sonarr.Api.V3/Wanted/CutoffController.cs +++ b/src/Sonarr.Api.V3/Wanted/CutoffController.cs @@ -1,4 +1,3 @@ -using System.Linq; using Microsoft.AspNetCore.Mvc; using NzbDrone.Core.CustomFormats; using NzbDrone.Core.Datastore; @@ -29,7 +28,7 @@ namespace Sonarr.Api.V3.Wanted [HttpGet] [Produces("application/json")] - public PagingResource GetCutoffUnmetEpisodes([FromQuery] PagingRequestResource paging, bool includeSeries = false, bool includeEpisodeFile = false, bool includeImages = false) + public PagingResource GetCutoffUnmetEpisodes([FromQuery] PagingRequestResource paging, bool includeSeries = false, bool includeEpisodeFile = false, bool includeImages = false, bool monitored = true) { var pagingResource = new PagingResource(paging); var pagingSpec = new PagingSpec @@ -40,16 +39,7 @@ namespace Sonarr.Api.V3.Wanted SortDirection = pagingResource.SortDirection }; - var filter = pagingResource.Filters.FirstOrDefault(f => f.Key == "monitored"); - - if (filter != null && filter.Value == "false") - { - pagingSpec.FilterExpressions.Add(v => v.Monitored == false || v.Series.Monitored == false); - } - else - { - pagingSpec.FilterExpressions.Add(v => v.Monitored == true && v.Series.Monitored == true); - } + pagingSpec.FilterExpressions.Add(v => v.Monitored == monitored || v.Series.Monitored == monitored); var resource = pagingSpec.ApplyToPage(_episodeCutoffService.EpisodesWhereCutoffUnmet, v => MapToResource(v, includeSeries, includeEpisodeFile, includeImages)); diff --git a/src/Sonarr.Api.V3/Wanted/MissingController.cs b/src/Sonarr.Api.V3/Wanted/MissingController.cs index c65b52638..43832c0d2 100644 --- a/src/Sonarr.Api.V3/Wanted/MissingController.cs +++ b/src/Sonarr.Api.V3/Wanted/MissingController.cs @@ -1,4 +1,3 @@ -using System.Linq; using Microsoft.AspNetCore.Mvc; using NzbDrone.Core.CustomFormats; using NzbDrone.Core.Datastore; @@ -25,7 +24,7 @@ namespace Sonarr.Api.V3.Wanted [HttpGet] [Produces("application/json")] - public PagingResource GetMissingEpisodes([FromQuery] PagingRequestResource paging, bool includeSeries = false, bool includeImages = false) + public PagingResource GetMissingEpisodes([FromQuery] PagingRequestResource paging, bool includeSeries = false, bool includeImages = false, bool monitored = true) { var pagingResource = new PagingResource(paging); var pagingSpec = new PagingSpec @@ -36,16 +35,7 @@ namespace Sonarr.Api.V3.Wanted SortDirection = pagingResource.SortDirection }; - var monitoredFilter = pagingResource.Filters.FirstOrDefault(f => f.Key == "monitored"); - - if (monitoredFilter != null && monitoredFilter.Value == "false") - { - pagingSpec.FilterExpressions.Add(v => v.Monitored == false || v.Series.Monitored == false); - } - else - { - pagingSpec.FilterExpressions.Add(v => v.Monitored == true && v.Series.Monitored == true); - } + pagingSpec.FilterExpressions.Add(v => v.Monitored == monitored || v.Series.Monitored == monitored); var resource = pagingSpec.ApplyToPage(_episodeService.EpisodesWithoutFiles, v => MapToResource(v, includeSeries, false, includeImages)); diff --git a/src/Sonarr.Api.V3/openapi.json b/src/Sonarr.Api.V3/openapi.json index f15cc9031..462f08b69 100644 --- a/src/Sonarr.Api.V3/openapi.json +++ b/src/Sonarr.Api.V3/openapi.json @@ -413,16 +413,6 @@ "schema": { "$ref": "#/components/schemas/SortDirection" } - }, - { - "name": "filters", - "in": "query", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PagingResourceFilter" - } - } } ], "responses": { @@ -1126,16 +1116,6 @@ "$ref": "#/components/schemas/SortDirection" } }, - { - "name": "filters", - "in": "query", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PagingResourceFilter" - } - } - }, { "name": "includeSeries", "in": "query", @@ -1159,6 +1139,14 @@ "type": "boolean", "default": false } + }, + { + "name": "monitored", + "in": "query", + "schema": { + "type": "boolean", + "default": true + } } ], "responses": { @@ -2338,16 +2326,6 @@ "$ref": "#/components/schemas/SortDirection" } }, - { - "name": "filters", - "in": "query", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PagingResourceFilter" - } - } - }, { "name": "includeSeries", "in": "query", @@ -2361,6 +2339,29 @@ "schema": { "type": "boolean" } + }, + { + "name": "eventType", + "in": "query", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "episodeId", + "in": "query", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "downloadId", + "in": "query", + "schema": { + "type": "string" + } } ], "responses": { @@ -3789,13 +3790,10 @@ } }, { - "name": "filters", + "name": "level", "in": "query", "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PagingResourceFilter" - } + "type": "string" } } ], @@ -4346,16 +4344,6 @@ "$ref": "#/components/schemas/SortDirection" } }, - { - "name": "filters", - "in": "query", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PagingResourceFilter" - } - } - }, { "name": "includeSeries", "in": "query", @@ -4371,6 +4359,14 @@ "type": "boolean", "default": false } + }, + { + "name": "monitored", + "in": "query", + "schema": { + "type": "boolean", + "default": true + } } ], "responses": { @@ -5426,6 +5422,38 @@ "Queue" ], "parameters": [ + { + "name": "page", + "in": "query", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + }, + { + "name": "pageSize", + "in": "query", + "schema": { + "type": "integer", + "format": "int32", + "default": 10 + } + }, + { + "name": "sortKey", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "sortDirection", + "in": "query", + "schema": { + "$ref": "#/components/schemas/SortDirection" + } + }, { "name": "includeUnknownSeriesItems", "in": "query", @@ -7399,13 +7427,6 @@ "sortDirection": { "$ref": "#/components/schemas/SortDirection" }, - "filters": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PagingResourceFilter" - }, - "nullable": true - }, "totalRecords": { "type": "integer", "format": "int32" @@ -8165,13 +8186,6 @@ "sortDirection": { "$ref": "#/components/schemas/SortDirection" }, - "filters": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PagingResourceFilter" - }, - "nullable": true - }, "totalRecords": { "type": "integer", "format": "int32" @@ -8414,13 +8428,6 @@ "sortDirection": { "$ref": "#/components/schemas/SortDirection" }, - "filters": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PagingResourceFilter" - }, - "nullable": true - }, "totalRecords": { "type": "integer", "format": "int32" @@ -9105,13 +9112,6 @@ "sortDirection": { "$ref": "#/components/schemas/SortDirection" }, - "filters": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PagingResourceFilter" - }, - "nullable": true - }, "totalRecords": { "type": "integer", "format": "int32" @@ -9763,20 +9763,6 @@ }, "additionalProperties": false }, - "PagingResourceFilter": { - "type": "object", - "properties": { - "key": { - "type": "string", - "nullable": true - }, - "value": { - "type": "string", - "nullable": true - } - }, - "additionalProperties": false - }, "ParseResource": { "type": "object", "properties": { @@ -10310,13 +10296,6 @@ "sortDirection": { "$ref": "#/components/schemas/SortDirection" }, - "filters": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PagingResourceFilter" - }, - "nullable": true - }, "totalRecords": { "type": "integer", "format": "int32" diff --git a/src/Sonarr.Http/Extensions/RequestExtensions.cs b/src/Sonarr.Http/Extensions/RequestExtensions.cs index 8e7ed9590..c93685bd1 100644 --- a/src/Sonarr.Http/Extensions/RequestExtensions.cs +++ b/src/Sonarr.Http/Extensions/RequestExtensions.cs @@ -61,80 +61,6 @@ namespace Sonarr.Http.Extensions return defaultValue; } - public static PagingResource ReadPagingResourceFromRequest(this HttpRequest request) - { - if (!int.TryParse(request.Query["PageSize"].ToString(), out var pageSize)) - { - pageSize = 10; - } - - if (!int.TryParse(request.Query["Page"].ToString(), out var page)) - { - page = 1; - } - - var pagingResource = new PagingResource - { - PageSize = pageSize, - Page = page, - Filters = new List() - }; - - if (request.Query["SortKey"].Any()) - { - var sortKey = request.Query["SortKey"].ToString(); - - if (!VALID_SORT_KEYS.Contains(sortKey) && - !TableMapping.Mapper.IsValidSortKey(sortKey)) - { - throw new BadRequestException($"Invalid sort key {sortKey}"); - } - - pagingResource.SortKey = sortKey; - - if (request.Query["SortDirection"].Any()) - { - pagingResource.SortDirection = request.Query["SortDirection"].ToString() - .Equals("ascending", StringComparison.InvariantCultureIgnoreCase) - ? SortDirection.Ascending - : SortDirection.Descending; - } - } - - // For backwards compatibility with v2 - if (request.Query["FilterKey"].Any()) - { - var filter = new PagingResourceFilter - { - Key = request.Query["FilterKey"].ToString() - }; - - if (request.Query["FilterValue"].Any()) - { - filter.Value = request.Query["FilterValue"].ToString(); - } - - pagingResource.Filters.Add(filter); - } - - // v3 uses filters in key=value format - foreach (var pair in request.Query) - { - if (EXCLUDED_KEYS.Contains(pair.Key)) - { - continue; - } - - pagingResource.Filters.Add(new PagingResourceFilter - { - Key = pair.Key, - Value = pair.Value.ToString() - }); - } - - return pagingResource; - } - public static PagingResource ApplyToPage(this PagingSpec pagingSpec, Func, PagingSpec> function, Converter mapper) { pagingSpec = function(pagingSpec); diff --git a/src/Sonarr.Http/PagingResource.cs b/src/Sonarr.Http/PagingResource.cs index dc10003a3..6559d80ab 100644 --- a/src/Sonarr.Http/PagingResource.cs +++ b/src/Sonarr.Http/PagingResource.cs @@ -12,7 +12,6 @@ namespace Sonarr.Http public int? PageSize { get; set; } public string SortKey { get; set; } public SortDirection? SortDirection { get; set; } - public List Filters { get; set; } } public class PagingResource @@ -21,8 +20,6 @@ namespace Sonarr.Http public int PageSize { get; set; } public string SortKey { get; set; } public SortDirection SortDirection { get; set; } - public List Filters { get; set; } - public int TotalRecords { get; set; } public List Records { get; set; } @@ -36,7 +33,6 @@ namespace Sonarr.Http PageSize = requestResource.PageSize ?? 10; SortKey = requestResource.SortKey; SortDirection = requestResource.SortDirection ?? SortDirection.Descending; - Filters = requestResource.Filters ?? new List(); } } diff --git a/src/Sonarr.Http/PagingResourceFilter.cs b/src/Sonarr.Http/PagingResourceFilter.cs deleted file mode 100644 index 303097a9a..000000000 --- a/src/Sonarr.Http/PagingResourceFilter.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Sonarr.Http -{ - public class PagingResourceFilter - { - public string Key { get; set; } - public string Value { get; set; } - } -}