mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-04-24 14:08:44 -04:00
Merge pull request #5091 from crobibero/query-param-array
Use ArrayModelBinder for sortBy and sortOrder
This commit is contained in:
commit
b4d04f9ca5
7 changed files with 29 additions and 38 deletions
|
@ -1,13 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Api.Constants;
|
using Jellyfin.Api.Constants;
|
||||||
using Jellyfin.Api.Extensions;
|
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Controller.Channels;
|
using MediaBrowser.Controller.Channels;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
|
@ -121,9 +120,9 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] Guid? userId,
|
[FromQuery] Guid? userId,
|
||||||
[FromQuery] int? startIndex,
|
[FromQuery] int? startIndex,
|
||||||
[FromQuery] int? limit,
|
[FromQuery] int? limit,
|
||||||
[FromQuery] string? sortOrder,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] SortOrder[] sortOrder,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFilter[] filters,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFilter[] filters,
|
||||||
[FromQuery] string? sortBy,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] sortBy,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields)
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields)
|
||||||
{
|
{
|
||||||
var user = userId.HasValue && !userId.Equals(Guid.Empty)
|
var user = userId.HasValue && !userId.Equals(Guid.Empty)
|
||||||
|
|
|
@ -175,7 +175,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] int? limit,
|
[FromQuery] int? limit,
|
||||||
[FromQuery] bool? recursive,
|
[FromQuery] bool? recursive,
|
||||||
[FromQuery] string? searchTerm,
|
[FromQuery] string? searchTerm,
|
||||||
[FromQuery] string? sortOrder,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] SortOrder[] sortOrder,
|
||||||
[FromQuery] Guid? parentId,
|
[FromQuery] Guid? parentId,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes,
|
||||||
|
@ -184,7 +184,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] bool? isFavorite,
|
[FromQuery] bool? isFavorite,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] imageTypes,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] imageTypes,
|
||||||
[FromQuery] string? sortBy,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] sortBy,
|
||||||
[FromQuery] bool? isPlayed,
|
[FromQuery] bool? isPlayed,
|
||||||
[FromQuery, ModelBinder(typeof(PipeDelimitedArrayModelBinder))] string[] genres,
|
[FromQuery, ModelBinder(typeof(PipeDelimitedArrayModelBinder))] string[] genres,
|
||||||
[FromQuery, ModelBinder(typeof(PipeDelimitedArrayModelBinder))] string[] officialRatings,
|
[FromQuery, ModelBinder(typeof(PipeDelimitedArrayModelBinder))] string[] officialRatings,
|
||||||
|
@ -608,7 +608,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] int? limit,
|
[FromQuery] int? limit,
|
||||||
[FromQuery] bool? recursive,
|
[FromQuery] bool? recursive,
|
||||||
[FromQuery] string? searchTerm,
|
[FromQuery] string? searchTerm,
|
||||||
[FromQuery] string? sortOrder,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] SortOrder[] sortOrder,
|
||||||
[FromQuery] Guid? parentId,
|
[FromQuery] Guid? parentId,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes,
|
||||||
|
@ -617,7 +617,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] bool? isFavorite,
|
[FromQuery] bool? isFavorite,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] imageTypes,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] imageTypes,
|
||||||
[FromQuery] string? sortBy,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] sortBy,
|
||||||
[FromQuery] bool? isPlayed,
|
[FromQuery] bool? isPlayed,
|
||||||
[FromQuery, ModelBinder(typeof(PipeDelimitedArrayModelBinder))] string[] genres,
|
[FromQuery, ModelBinder(typeof(PipeDelimitedArrayModelBinder))] string[] genres,
|
||||||
[FromQuery, ModelBinder(typeof(PipeDelimitedArrayModelBinder))] string[] officialRatings,
|
[FromQuery, ModelBinder(typeof(PipeDelimitedArrayModelBinder))] string[] officialRatings,
|
||||||
|
|
|
@ -553,8 +553,8 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] bool? isSports,
|
[FromQuery] bool? isSports,
|
||||||
[FromQuery] int? startIndex,
|
[FromQuery] int? startIndex,
|
||||||
[FromQuery] int? limit,
|
[FromQuery] int? limit,
|
||||||
[FromQuery] string? sortBy,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] sortBy,
|
||||||
[FromQuery] string? sortOrder,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] SortOrder[] sortOrder,
|
||||||
[FromQuery, ModelBinder(typeof(PipeDelimitedArrayModelBinder))] string[] genres,
|
[FromQuery, ModelBinder(typeof(PipeDelimitedArrayModelBinder))] string[] genres,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] Guid[] genreIds,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] Guid[] genreIds,
|
||||||
[FromQuery] bool? enableImages,
|
[FromQuery] bool? enableImages,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using Jellyfin.Api.Constants;
|
using Jellyfin.Api.Constants;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
|
@ -144,7 +145,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] int? limit,
|
[FromQuery] int? limit,
|
||||||
[FromQuery] bool? recursive,
|
[FromQuery] bool? recursive,
|
||||||
[FromQuery] string? searchTerm,
|
[FromQuery] string? searchTerm,
|
||||||
[FromQuery] string? sortOrder,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] SortOrder[] sortOrder,
|
||||||
[FromQuery] Guid? parentId,
|
[FromQuery] Guid? parentId,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes,
|
||||||
|
@ -152,7 +153,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] bool? isFavorite,
|
[FromQuery] bool? isFavorite,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] imageTypes,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] imageTypes,
|
||||||
[FromQuery] string? sortBy,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] sortBy,
|
||||||
[FromQuery] bool? isPlayed,
|
[FromQuery] bool? isPlayed,
|
||||||
[FromQuery, ModelBinder(typeof(PipeDelimitedArrayModelBinder))] string[] genres,
|
[FromQuery, ModelBinder(typeof(PipeDelimitedArrayModelBinder))] string[] genres,
|
||||||
[FromQuery, ModelBinder(typeof(PipeDelimitedArrayModelBinder))] string[] officialRatings,
|
[FromQuery, ModelBinder(typeof(PipeDelimitedArrayModelBinder))] string[] officialRatings,
|
||||||
|
|
|
@ -7,6 +7,7 @@ using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
@ -70,13 +71,13 @@ namespace Jellyfin.Api.Controllers
|
||||||
public ActionResult<QueryResult<BaseItemDto>> GetYears(
|
public ActionResult<QueryResult<BaseItemDto>> GetYears(
|
||||||
[FromQuery] int? startIndex,
|
[FromQuery] int? startIndex,
|
||||||
[FromQuery] int? limit,
|
[FromQuery] int? limit,
|
||||||
[FromQuery] string? sortOrder,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] SortOrder[] sortOrder,
|
||||||
[FromQuery] Guid? parentId,
|
[FromQuery] Guid? parentId,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes,
|
||||||
[FromQuery] string? sortBy,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] sortBy,
|
||||||
[FromQuery] bool? enableUserData,
|
[FromQuery] bool? enableUserData,
|
||||||
[FromQuery] int? imageTypeLimit,
|
[FromQuery] int? imageTypeLimit,
|
||||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes,
|
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
@ -8,7 +9,6 @@ using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
|
@ -25,35 +25,22 @@ namespace Jellyfin.Api.Helpers
|
||||||
/// <param name="sortBy">Sort By. Comma delimited string.</param>
|
/// <param name="sortBy">Sort By. Comma delimited string.</param>
|
||||||
/// <param name="requestedSortOrder">Sort Order. Comma delimited string.</param>
|
/// <param name="requestedSortOrder">Sort Order. Comma delimited string.</param>
|
||||||
/// <returns>Order By.</returns>
|
/// <returns>Order By.</returns>
|
||||||
public static ValueTuple<string, SortOrder>[] GetOrderBy(string? sortBy, string? requestedSortOrder)
|
public static ValueTuple<string, SortOrder>[] GetOrderBy(IReadOnlyList<string> sortBy, IReadOnlyList<SortOrder> requestedSortOrder)
|
||||||
{
|
{
|
||||||
var val = sortBy;
|
if (sortBy.Count == 0)
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(val))
|
|
||||||
{
|
{
|
||||||
return Array.Empty<ValueTuple<string, SortOrder>>();
|
return Array.Empty<ValueTuple<string, SortOrder>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
var vals = val.Split(',');
|
var result = new ValueTuple<string, SortOrder>[sortBy.Count];
|
||||||
if (string.IsNullOrWhiteSpace(requestedSortOrder))
|
for (var i = 0; i < sortBy.Count; i++)
|
||||||
{
|
{
|
||||||
requestedSortOrder = "Ascending";
|
var sortOrderIndex = requestedSortOrder.Count > i ? i : 0;
|
||||||
}
|
|
||||||
|
|
||||||
var sortOrders = requestedSortOrder.Split(',');
|
var sortOrder = requestedSortOrder.Count > sortOrderIndex
|
||||||
|
? requestedSortOrder[sortOrderIndex]
|
||||||
var result = new ValueTuple<string, SortOrder>[vals.Length];
|
|
||||||
|
|
||||||
for (var i = 0; i < vals.Length; i++)
|
|
||||||
{
|
|
||||||
var sortOrderIndex = sortOrders.Length > i ? i : 0;
|
|
||||||
|
|
||||||
var sortOrderValue = sortOrders.Length > sortOrderIndex ? sortOrders[sortOrderIndex] : null;
|
|
||||||
var sortOrder = string.Equals(sortOrderValue, "Descending", StringComparison.OrdinalIgnoreCase)
|
|
||||||
? SortOrder.Descending
|
|
||||||
: SortOrder.Ascending;
|
: SortOrder.Ascending;
|
||||||
|
result[i] = new ValueTuple<string, SortOrder>(sortBy[i], sortOrder);
|
||||||
result[i] = new ValueTuple<string, SortOrder>(vals[i], sortOrder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Common.Json.Converters;
|
using MediaBrowser.Common.Json.Converters;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
|
@ -106,12 +107,14 @@ namespace Jellyfin.Api.Models.LiveTvDtos
|
||||||
/// Gets or sets specify one or more sort orders, comma delimited. Options: Name, StartDate.
|
/// Gets or sets specify one or more sort orders, comma delimited. Options: Name, StartDate.
|
||||||
/// Optional.
|
/// Optional.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? SortBy { get; set; }
|
[JsonConverter(typeof(JsonCommaDelimitedArrayConverterFactory))]
|
||||||
|
public IReadOnlyList<string> SortBy { get; set; } = Array.Empty<string>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets sort Order - Ascending,Descending.
|
/// Gets or sets sort Order - Ascending,Descending.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? SortOrder { get; set; }
|
[JsonConverter(typeof(JsonCommaDelimitedArrayConverterFactory))]
|
||||||
|
public IReadOnlyList<SortOrder> SortOrder { get; set; } = Array.Empty<SortOrder>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the genres to return guide information for.
|
/// Gets or sets the genres to return guide information for.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue