Merge remote-tracking branch 'upstream/master' into query-fields

This commit is contained in:
crobibero
2020-10-27 13:35:46 -06:00
169 changed files with 1203 additions and 819 deletions

View File

@@ -1,7 +1,7 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Jellyfin.Api.Constants;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Queries;
using MediaBrowser.Model.Activity;
using MediaBrowser.Model.Querying;
using Microsoft.AspNetCore.Authorization;
@@ -39,19 +39,19 @@ namespace Jellyfin.Api.Controllers
/// <returns>A <see cref="QueryResult{ActivityLogEntry}"/> containing the log entries.</returns>
[HttpGet("Entries")]
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<QueryResult<ActivityLogEntry>> GetLogEntries(
public async Task<ActionResult<QueryResult<ActivityLogEntry>>> GetLogEntries(
[FromQuery] int? startIndex,
[FromQuery] int? limit,
[FromQuery] DateTime? minDate,
[FromQuery] bool? hasUserId)
{
var filterFunc = new Func<IQueryable<ActivityLog>, IQueryable<ActivityLog>>(
entries => entries.Where(entry => entry.DateCreated >= minDate
&& (!hasUserId.HasValue || (hasUserId.Value
? entry.UserId != Guid.Empty
: entry.UserId == Guid.Empty))));
return _activityManager.GetPagedResult(filterFunc, startIndex, limit);
return await _activityManager.GetPagedResultAsync(new ActivityLogQuery
{
StartIndex = startIndex,
Limit = limit,
MinDate = minDate,
HasUserId = hasUserId
}).ConfigureAwait(false);
}
}
}

View File

@@ -54,7 +54,7 @@ namespace Jellyfin.Api.Controllers
/// <param name="fields">Optional. Specify additional fields of information to return in the output.</param>
/// <param name="excludeItemTypes">Optional. If specified, results will be filtered out based on item type. This allows multiple, comma delimited.</param>
/// <param name="includeItemTypes">Optional. If specified, results will be filtered based on item type. This allows multiple, comma delimited.</param>
/// <param name="filters">Optional. Specify additional filters to apply. This allows multiple, comma delimited. Options: IsFolder, IsNotFolder, IsUnplayed, IsPlayed, IsFavorite, IsResumable, Likes, Dislikes.</param>
/// <param name="filters">Optional. Specify additional filters to apply.</param>
/// <param name="isFavorite">Optional filter by items that are marked as favorite, or not.</param>
/// <param name="mediaTypes">Optional filter by MediaType. Allows multiple, comma delimited.</param>
/// <param name="genres">Optional. If specified, results will be filtered based on genre. This allows multiple, pipe delimited.</param>
@@ -89,7 +89,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] ItemFields[] fields,
[FromQuery] string? excludeItemTypes,
[FromQuery] string? includeItemTypes,
[FromQuery] string? filters,
[FromQuery] ItemFilter[] filters,
[FromQuery] bool? isFavorite,
[FromQuery] string? mediaTypes,
[FromQuery] string? genres,
@@ -188,7 +188,7 @@ namespace Jellyfin.Api.Controllers
}).Where(i => i != null).Select(i => i!.Id).ToArray();
}
foreach (var filter in RequestHelpers.GetFilters(filters))
foreach (var filter in filters)
{
switch (filter)
{
@@ -263,7 +263,7 @@ namespace Jellyfin.Api.Controllers
/// <param name="fields">Optional. Specify additional fields of information to return in the output.</param>
/// <param name="excludeItemTypes">Optional. If specified, results will be filtered out based on item type. This allows multiple, comma delimited.</param>
/// <param name="includeItemTypes">Optional. If specified, results will be filtered based on item type. This allows multiple, comma delimited.</param>
/// <param name="filters">Optional. Specify additional filters to apply. This allows multiple, comma delimited. Options: IsFolder, IsNotFolder, IsUnplayed, IsPlayed, IsFavorite, IsResumable, Likes, Dislikes.</param>
/// <param name="filters">Optional. Specify additional filters to apply.</param>
/// <param name="isFavorite">Optional filter by items that are marked as favorite, or not.</param>
/// <param name="mediaTypes">Optional filter by MediaType. Allows multiple, comma delimited.</param>
/// <param name="genres">Optional. If specified, results will be filtered based on genre. This allows multiple, pipe delimited.</param>
@@ -298,7 +298,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] ItemFields[] fields,
[FromQuery] string? excludeItemTypes,
[FromQuery] string? includeItemTypes,
[FromQuery] string? filters,
[FromQuery] ItemFilter[] filters,
[FromQuery] bool? isFavorite,
[FromQuery] string? mediaTypes,
[FromQuery] string? genres,
@@ -397,7 +397,7 @@ namespace Jellyfin.Api.Controllers
}).Where(i => i != null).Select(i => i!.Id).ToArray();
}
foreach (var filter in RequestHelpers.GetFilters(filters))
foreach (var filter in filters)
{
switch (filter)
{

View File

@@ -105,7 +105,7 @@ namespace Jellyfin.Api.Controllers
/// <param name="startIndex">Optional. The record index to start at. All items with a lower index will be dropped from the results.</param>
/// <param name="limit">Optional. The maximum number of records to return.</param>
/// <param name="sortOrder">Optional. Sort Order - Ascending,Descending.</param>
/// <param name="filters">Optional. Specify additional filters to apply. This allows multiple, comma delimited. Options: IsFolder, IsNotFolder, IsUnplayed, IsPlayed, IsFavorite, IsResumable, Likes, Dislikes.</param>
/// <param name="filters">Optional. Specify additional filters to apply.</param>
/// <param name="sortBy">Optional. Specify one or more sort orders, comma delimited. Options: Album, AlbumArtist, Artist, Budget, CommunityRating, CriticRating, DateCreated, DatePlayed, PlayCount, PremiereDate, ProductionYear, SortName, Random, Revenue, Runtime.</param>
/// <param name="fields">Optional. Specify additional fields of information to return in the output.</param>
/// <response code="200">Channel items returned.</response>
@@ -121,7 +121,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? startIndex,
[FromQuery] int? limit,
[FromQuery] string? sortOrder,
[FromQuery] string? filters,
[FromQuery] ItemFilter[] filters,
[FromQuery] string? sortBy,
[FromQuery] ItemFields[] fields)
{
@@ -140,7 +140,7 @@ namespace Jellyfin.Api.Controllers
.AddItemFields(fields)
};
foreach (var filter in RequestHelpers.GetFilters(filters))
foreach (var filter in filters)
{
switch (filter)
{
@@ -196,7 +196,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] Guid? userId,
[FromQuery] int? startIndex,
[FromQuery] int? limit,
[FromQuery] string? filters,
[FromQuery] ItemFilter[] filters,
[FromQuery] ItemFields[] fields,
[FromQuery] string? channelIds)
{
@@ -217,7 +217,7 @@ namespace Jellyfin.Api.Controllers
.AddItemFields(fields)
};
foreach (var filter in RequestHelpers.GetFilters(filters))
foreach (var filter in filters)
{
switch (filter)
{

View File

@@ -55,7 +55,7 @@ namespace Jellyfin.Api.Controllers
/// <param name="fields">Optional. Specify additional fields of information to return in the output.</param>
/// <param name="excludeItemTypes">Optional. If specified, results will be filtered out based on item type. This allows multiple, comma delimited.</param>
/// <param name="includeItemTypes">Optional. If specified, results will be filtered in based on item type. This allows multiple, comma delimited.</param>
/// <param name="filters">Optional. Specify additional filters to apply. This allows multiple, comma delimited. Options: IsFolder, IsNotFolder, IsUnplayed, IsPlayed, IsFavorite, IsResumable, Likes, Dislikes.</param>
/// <param name="filters">Optional. Specify additional filters to apply.</param>
/// <param name="isFavorite">Optional filter by items that are marked as favorite, or not.</param>
/// <param name="mediaTypes">Optional filter by MediaType. Allows multiple, comma delimited.</param>
/// <param name="genres">Optional. If specified, results will be filtered based on genre. This allows multiple, pipe delimited.</param>
@@ -90,7 +90,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] ItemFields[] fields,
[FromQuery] string? excludeItemTypes,
[FromQuery] string? includeItemTypes,
[FromQuery] string? filters,
[FromQuery] ItemFilter[] filters,
[FromQuery] bool? isFavorite,
[FromQuery] string? mediaTypes,
[FromQuery] string? genres,
@@ -188,7 +188,7 @@ namespace Jellyfin.Api.Controllers
.ToArray();
}
foreach (var filter in RequestHelpers.GetFilters(filters))
foreach (var filter in filters)
{
switch (filter)
{

View File

@@ -333,7 +333,7 @@ namespace Jellyfin.Api.Controllers
/// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param>
/// <param name="tag">Optional. Supply the cache tag from the item object to receive strong caching headers.</param>
/// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param>
/// <param name="format">Determines the output format of the image - original,gif,jpg,png.</param>
/// <param name="format">Optional. The <see cref="ImageFormat"/> of the returned image.</param>
/// <param name="addPlayedIndicator">Optional. Add a played indicator.</param>
/// <param name="percentPlayed">Optional. Percent to render for the percent played overlay.</param>
/// <param name="unplayedCount">Optional. Unplayed count overlay to render.</param>
@@ -364,7 +364,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? quality,
[FromQuery] string? tag,
[FromQuery] bool? cropWhitespace,
[FromQuery] string? format,
[FromQuery] ImageFormat? format,
[FromQuery] bool? addPlayedIndicator,
[FromQuery] double? percentPlayed,
[FromQuery] int? unplayedCount,
@@ -443,7 +443,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? quality,
[FromRoute, Required] string tag,
[FromQuery] bool? cropWhitespace,
[FromRoute, Required] string format,
[FromRoute, Required] ImageFormat format,
[FromQuery] bool? addPlayedIndicator,
[FromRoute, Required] double percentPlayed,
[FromRoute, Required] int unplayedCount,
@@ -516,7 +516,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute, Required] string name,
[FromRoute, Required] ImageType imageType,
[FromQuery] string tag,
[FromQuery] string format,
[FromQuery] ImageFormat? format,
[FromQuery] int? maxWidth,
[FromQuery] int? maxHeight,
[FromQuery] double? percentPlayed,
@@ -595,7 +595,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute, Required] string name,
[FromRoute, Required] ImageType imageType,
[FromQuery] string tag,
[FromQuery] string format,
[FromQuery] ImageFormat? format,
[FromQuery] int? maxWidth,
[FromQuery] int? maxHeight,
[FromQuery] double? percentPlayed,
@@ -674,7 +674,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute, Required] string name,
[FromRoute, Required] ImageType imageType,
[FromQuery] string tag,
[FromQuery] string format,
[FromQuery] ImageFormat? format,
[FromQuery] int? maxWidth,
[FromQuery] int? maxHeight,
[FromQuery] double? percentPlayed,
@@ -753,7 +753,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute, Required] string name,
[FromRoute, Required] ImageType imageType,
[FromQuery] string tag,
[FromQuery] string format,
[FromQuery] ImageFormat? format,
[FromQuery] int? maxWidth,
[FromQuery] int? maxHeight,
[FromQuery] double? percentPlayed,
@@ -832,7 +832,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute, Required] string name,
[FromRoute, Required] ImageType imageType,
[FromRoute, Required] string tag,
[FromRoute, Required] string format,
[FromRoute, Required] ImageFormat format,
[FromQuery] int? maxWidth,
[FromQuery] int? maxHeight,
[FromQuery] double? percentPlayed,
@@ -911,7 +911,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute, Required] Guid userId,
[FromRoute, Required] ImageType imageType,
[FromQuery] string? tag,
[FromQuery] string? format,
[FromQuery] ImageFormat? format,
[FromQuery] int? maxWidth,
[FromQuery] int? maxHeight,
[FromQuery] double? percentPlayed,
@@ -1038,7 +1038,7 @@ namespace Jellyfin.Api.Controllers
ImageType imageType,
int? imageIndex,
string? tag,
string? format,
ImageFormat? format,
int? maxWidth,
int? maxHeight,
double? percentPlayed,
@@ -1128,12 +1128,11 @@ namespace Jellyfin.Api.Controllers
isHeadRequest).ConfigureAwait(false);
}
private ImageFormat[] GetOutputFormats(string? format)
private ImageFormat[] GetOutputFormats(ImageFormat? format)
{
if (!string.IsNullOrWhiteSpace(format)
&& Enum.TryParse(format, true, out ImageFormat parsedFormat))
if (format.HasValue)
{
return new[] { parsedFormat };
return new[] { format.Value };
}
return GetClientSupportedFormats();
@@ -1157,7 +1156,7 @@ namespace Jellyfin.Api.Controllers
var acceptParam = Request.Query[HeaderNames.Accept];
var supportsWebP = SupportsFormat(supportedFormats, acceptParam, "webp", false);
var supportsWebP = SupportsFormat(supportedFormats, acceptParam, ImageFormat.Webp, false);
if (!supportsWebP)
{
@@ -1179,7 +1178,7 @@ namespace Jellyfin.Api.Controllers
formats.Add(ImageFormat.Jpg);
formats.Add(ImageFormat.Png);
if (SupportsFormat(supportedFormats, acceptParam, "gif", true))
if (SupportsFormat(supportedFormats, acceptParam, ImageFormat.Gif, true))
{
formats.Add(ImageFormat.Gif);
}
@@ -1187,9 +1186,10 @@ namespace Jellyfin.Api.Controllers
return formats.ToArray();
}
private bool SupportsFormat(IReadOnlyCollection<string> requestAcceptTypes, string acceptParam, string format, bool acceptAll)
private bool SupportsFormat(IReadOnlyCollection<string> requestAcceptTypes, string acceptParam, ImageFormat format, bool acceptAll)
{
var mimeType = "image/" + format;
var normalized = format.ToString().ToLowerInvariant();
var mimeType = "image/" + normalized;
if (requestAcceptTypes.Contains(mimeType))
{
@@ -1201,7 +1201,7 @@ namespace Jellyfin.Api.Controllers
return true;
}
return string.Equals(acceptParam, format, StringComparison.OrdinalIgnoreCase);
return string.Equals(acceptParam, normalized, StringComparison.OrdinalIgnoreCase);
}
private async Task<ActionResult> GetImageResult(

View File

@@ -159,7 +159,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] bool? isHd,
[FromQuery] bool? is4K,
[FromQuery] string? locationTypes,
[FromQuery] string? excludeLocationTypes,
[FromQuery] LocationType[] excludeLocationTypes,
[FromQuery] bool? isMissing,
[FromQuery] bool? isUnaired,
[FromQuery] double? minCommunityRating,
@@ -182,7 +182,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] ItemFields[] fields,
[FromQuery] string? excludeItemTypes,
[FromQuery] string? includeItemTypes,
[FromQuery] string? filters,
[FromQuery] ItemFilter[] filters,
[FromQuery] bool? isFavorite,
[FromQuery] string? mediaTypes,
[FromQuery] string? imageTypes,
@@ -365,7 +365,7 @@ namespace Jellyfin.Api.Controllers
query.CollapseBoxSetItems = false;
}
foreach (var filter in RequestHelpers.GetFilters(filters!))
foreach (var filter in filters)
{
switch (filter)
{
@@ -406,12 +406,9 @@ namespace Jellyfin.Api.Controllers
}
// ExcludeLocationTypes
if (!string.IsNullOrEmpty(excludeLocationTypes))
if (excludeLocationTypes.Any(t => t == LocationType.Virtual))
{
if (excludeLocationTypes.Split(',').Select(d => (LocationType)Enum.Parse(typeof(LocationType), d, true)).ToArray().Contains(LocationType.Virtual))
{
query.IsVirtualItem = false;
}
query.IsVirtualItem = false;
}
if (!string.IsNullOrEmpty(locationTypes))

View File

@@ -55,7 +55,7 @@ namespace Jellyfin.Api.Controllers
/// <param name="fields">Optional. Specify additional fields of information to return in the output.</param>
/// <param name="excludeItemTypes">Optional. If specified, results will be filtered out based on item type. This allows multiple, comma delimited.</param>
/// <param name="includeItemTypes">Optional. If specified, results will be filtered in based on item type. This allows multiple, comma delimited.</param>
/// <param name="filters">Optional. Specify additional filters to apply. This allows multiple, comma delimited. Options: IsFolder, IsNotFolder, IsUnplayed, IsPlayed, IsFavorite, IsResumable, Likes, Dislikes.</param>
/// <param name="filters">Optional. Specify additional filters to apply.</param>
/// <param name="isFavorite">Optional filter by items that are marked as favorite, or not.</param>
/// <param name="mediaTypes">Optional filter by MediaType. Allows multiple, comma delimited.</param>
/// <param name="genres">Optional. If specified, results will be filtered based on genre. This allows multiple, pipe delimited.</param>
@@ -89,7 +89,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] ItemFields[] fields,
[FromQuery] string? excludeItemTypes,
[FromQuery] string? includeItemTypes,
[FromQuery] string? filters,
[FromQuery] ItemFilter[] filters,
[FromQuery] bool? isFavorite,
[FromQuery] string? mediaTypes,
[FromQuery] string? genres,
@@ -187,7 +187,7 @@ namespace Jellyfin.Api.Controllers
.ToArray();
}
foreach (var filter in RequestHelpers.GetFilters(filters))
foreach (var filter in filters)
{
switch (filter)
{

View File

@@ -89,7 +89,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] ItemFields[] fields,
[FromQuery] string? excludeItemTypes,
[FromQuery] string? includeItemTypes,
[FromQuery] string? filters,
[FromQuery] ItemFilter[] filters,
[FromQuery] bool? isFavorite,
[FromQuery] string? mediaTypes,
[FromQuery] string? genres,
@@ -187,7 +187,7 @@ namespace Jellyfin.Api.Controllers
.ToArray();
}
foreach (var filter in RequestHelpers.GetFilters(filters))
foreach (var filter in filters)
{
switch (filter)
{

View File

@@ -36,7 +36,7 @@ namespace Jellyfin.Api.Controllers
/// <returns>The list of scheduled tasks.</returns>
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
public IEnumerable<IScheduledTaskWorker> GetTasks(
public IEnumerable<TaskInfo> GetTasks(
[FromQuery] bool? isHidden,
[FromQuery] bool? isEnabled)
{
@@ -57,7 +57,7 @@ namespace Jellyfin.Api.Controllers
}
}
yield return task;
yield return ScheduledTaskHelpers.GetTaskInfo(task);
}
}

View File

@@ -53,7 +53,7 @@ namespace Jellyfin.Api.Controllers
/// <param name="fields">Optional. Specify additional fields of information to return in the output.</param>
/// <param name="excludeItemTypes">Optional. If specified, results will be filtered out based on item type. This allows multiple, comma delimited.</param>
/// <param name="includeItemTypes">Optional. If specified, results will be filtered based on item type. This allows multiple, comma delimited.</param>
/// <param name="filters">Optional. Specify additional filters to apply. This allows multiple, comma delimited. Options: IsFolder, IsNotFolder, IsUnplayed, IsPlayed, IsFavorite, IsResumable, Likes, Dislikes.</param>
/// <param name="filters">Optional. Specify additional filters to apply.</param>
/// <param name="isFavorite">Optional filter by items that are marked as favorite, or not.</param>
/// <param name="mediaTypes">Optional filter by MediaType. Allows multiple, comma delimited.</param>
/// <param name="genres">Optional. If specified, results will be filtered based on genre. This allows multiple, pipe delimited.</param>
@@ -88,7 +88,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] ItemFields[] fields,
[FromQuery] string? excludeItemTypes,
[FromQuery] string? includeItemTypes,
[FromQuery] string? filters,
[FromQuery] ItemFilter[] filters,
[FromQuery] bool? isFavorite,
[FromQuery] string? mediaTypes,
[FromQuery] string? genres,
@@ -188,7 +188,7 @@ namespace Jellyfin.Api.Controllers
.ToArray();
}
foreach (var filter in RequestHelpers.GetFilters(filters))
foreach (var filter in filters)
{
switch (filter)
{

View File

@@ -1,6 +1,7 @@
using System;
using Jellyfin.Api.Constants;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
@@ -124,7 +125,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] bool? isHd,
[FromQuery] bool? is4K,
[FromQuery] string? locationTypes,
[FromQuery] string? excludeLocationTypes,
[FromQuery] LocationType[] excludeLocationTypes,
[FromQuery] bool? isMissing,
[FromQuery] bool? isUnaired,
[FromQuery] double? minCommunityRating,
@@ -146,7 +147,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] string? parentId,
[FromQuery] ItemFields[] fields,
[FromQuery] string? excludeItemTypes,
[FromQuery] string? filters,
[FromQuery] ItemFilter[] filters,
[FromQuery] bool? isFavorite,
[FromQuery] string? mediaTypes,
[FromQuery] string? imageTypes,