From d97e306cdae11eb2675161aa2a6d828c739b2b01 Mon Sep 17 00:00:00 2001 From: crobibero Date: Mon, 8 Jun 2020 13:14:41 -0600 Subject: Move PlaylistService to Jellyfin.Api --- Jellyfin.Api/Controllers/PlaylistsController.cs | 198 ++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 Jellyfin.Api/Controllers/PlaylistsController.cs (limited to 'Jellyfin.Api/Controllers/PlaylistsController.cs') diff --git a/Jellyfin.Api/Controllers/PlaylistsController.cs b/Jellyfin.Api/Controllers/PlaylistsController.cs new file mode 100644 index 000000000..0d73962de --- /dev/null +++ b/Jellyfin.Api/Controllers/PlaylistsController.cs @@ -0,0 +1,198 @@ +#nullable enable +#pragma warning disable CA1801 + +using System; +using System.Linq; +using System.Threading.Tasks; +using Jellyfin.Api.Helpers; +using Jellyfin.Api.Models.PlaylistDtos; +using MediaBrowser.Controller.Dto; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Playlists; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Playlists; +using MediaBrowser.Model.Querying; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.ModelBinding; + +namespace Jellyfin.Api.Controllers +{ + /// + /// Playlists controller. + /// + [Authorize] + public class PlaylistsController : BaseJellyfinApiController + { + private readonly IPlaylistManager _playlistManager; + private readonly IDtoService _dtoService; + private readonly IUserManager _userManager; + private readonly ILibraryManager _libraryManager; + + /// + /// Initializes a new instance of the class. + /// + /// Instance of the interface. + /// Instance of the interface. + /// Instance of the interface. + /// Instance of the interface. + public PlaylistsController( + IDtoService dtoService, + IPlaylistManager playlistManager, + IUserManager userManager, + ILibraryManager libraryManager) + { + _dtoService = dtoService; + _playlistManager = playlistManager; + _userManager = userManager; + _libraryManager = libraryManager; + } + + /// + /// Creates a new playlist. + /// + /// The create playlist payload. + /// + /// A that represents the asynchronous operation to create a playlist. + /// The task result contains an indicating success. + /// + [HttpPost] + [ProducesResponseType(StatusCodes.Status200OK)] + public async Task> CreatePlaylist( + [FromBody, BindRequired] CreatePlaylistDto createPlaylistRequest) + { + Guid[] idGuidArray = RequestHelpers.GetGuids(createPlaylistRequest.Ids); + var result = await _playlistManager.CreatePlaylist(new PlaylistCreationRequest + { + Name = createPlaylistRequest.Name, + ItemIdList = idGuidArray, + UserId = createPlaylistRequest.UserId, + MediaType = createPlaylistRequest.MediaType + }).ConfigureAwait(false); + + return result; + } + + /// + /// Adds items to a playlist. + /// + /// The playlist id. + /// Item id, comma delimited. + /// The userId. + /// Items added to playlist. + /// An on success. + [HttpPost("{playlistId}/Items")] + [ProducesResponseType(StatusCodes.Status200OK)] + public ActionResult AddToPlaylist( + [FromRoute] string playlistId, + [FromQuery] string ids, + [FromQuery] Guid userId) + { + _playlistManager.AddToPlaylist(playlistId, RequestHelpers.GetGuids(ids), userId); + return Ok(); + } + + /// + /// Moves a playlist item. + /// + /// The playlist id. + /// The item id. + /// The new index. + /// Item moved to new index. + /// An on success. + [HttpPost("{playlistId}/Items/{itemId}/Move/{newIndex}")] + [ProducesResponseType(StatusCodes.Status200OK)] + public ActionResult MoveItem( + [FromRoute] string playlistId, + [FromRoute] string itemId, + [FromRoute] int newIndex) + { + _playlistManager.MoveItem(playlistId, itemId, newIndex); + return Ok(); + } + + /// + /// Removes items from a playlist. + /// + /// The playlist id. + /// The item ids, comma delimited. + /// Items removed. + /// An on success. + [HttpDelete("{playlistId}/Items")] + [ProducesResponseType(StatusCodes.Status200OK)] + public ActionResult RemoveFromPlaylist([FromRoute] string playlistId, [FromQuery] string entryIds) + { + _playlistManager.RemoveFromPlaylist(playlistId, entryIds.Split(',')); + return Ok(); + } + + /// + /// Gets the original items of a playlist. + /// + /// The playlist id. + /// User id. + /// Optional. The record index to start at. All items with a lower index will be dropped from the results. + /// Optional. The maximum number of records to return. + /// Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimited. Options: Budget, Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines. + /// Optional. Include image information in output. + /// Optional. Include user data. + /// Optional. The max number of images to return, per image type. + /// Optional. The image types to include in the output. + /// Original playlist returned. + /// Playlist not found. + /// The original playlist items. + [HttpGet("{playlistId}/Items")] + public ActionResult> GetPlaylistItems( + [FromRoute] Guid playlistId, + [FromRoute] Guid userId, + [FromRoute] int? startIndex, + [FromRoute] int? limit, + [FromRoute] string fields, + [FromRoute] bool? enableImages, + [FromRoute] bool? enableUserData, + [FromRoute] bool? imageTypeLimit, + [FromRoute] string enableImageTypes) + { + var playlist = (Playlist)_libraryManager.GetItemById(playlistId); + if (playlist == null) + { + return NotFound(); + } + + var user = !userId.Equals(Guid.Empty) ? _userManager.GetUserById(userId) : null; + + var items = playlist.GetManageableItems().ToArray(); + + var count = items.Length; + + if (startIndex.HasValue) + { + items = items.Skip(startIndex.Value).ToArray(); + } + + if (limit.HasValue) + { + items = items.Take(limit.Value).ToArray(); + } + + // TODO var dtoOptions = GetDtoOptions(_authContext, request); + var dtoOptions = new DtoOptions(); + + var dtos = _dtoService.GetBaseItemDtos(items.Select(i => i.Item2).ToList(), dtoOptions, user); + + for (int index = 0; index < dtos.Count; index++) + { + dtos[index].PlaylistItemId = items[index].Item1.Id; + } + + var result = new QueryResult + { + Items = dtos, + TotalRecordCount = count + }; + + return result; + } + } +} -- cgit v1.2.3 From d1ca0cb4c7161b420c32e48824cc5065054b1869 Mon Sep 17 00:00:00 2001 From: crobibero Date: Sat, 20 Jun 2020 16:03:19 -0600 Subject: Use proper DtoOptions extensions --- Jellyfin.Api/Controllers/PlaylistsController.cs | 33 ++++++++++++++----------- Jellyfin.Api/Extensions/DtoExtensions.cs | 2 +- Jellyfin.Api/Helpers/RequestHelpers.cs | 18 ++++++++++++++ 3 files changed, 37 insertions(+), 16 deletions(-) (limited to 'Jellyfin.Api/Controllers/PlaylistsController.cs') diff --git a/Jellyfin.Api/Controllers/PlaylistsController.cs b/Jellyfin.Api/Controllers/PlaylistsController.cs index 0d73962de..9e2a91e10 100644 --- a/Jellyfin.Api/Controllers/PlaylistsController.cs +++ b/Jellyfin.Api/Controllers/PlaylistsController.cs @@ -4,6 +4,7 @@ using System; using System.Linq; using System.Threading.Tasks; +using Jellyfin.Api.Extensions; using Jellyfin.Api.Helpers; using Jellyfin.Api.Models.PlaylistDtos; using MediaBrowser.Controller.Dto; @@ -80,17 +81,17 @@ namespace Jellyfin.Api.Controllers /// The playlist id. /// Item id, comma delimited. /// The userId. - /// Items added to playlist. - /// An on success. + /// Items added to playlist. + /// An on success. [HttpPost("{playlistId}/Items")] - [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult AddToPlaylist( [FromRoute] string playlistId, [FromQuery] string ids, [FromQuery] Guid userId) { _playlistManager.AddToPlaylist(playlistId, RequestHelpers.GetGuids(ids), userId); - return Ok(); + return NoContent(); } /// @@ -99,17 +100,17 @@ namespace Jellyfin.Api.Controllers /// The playlist id. /// The item id. /// The new index. - /// Item moved to new index. - /// An on success. + /// Item moved to new index. + /// An on success. [HttpPost("{playlistId}/Items/{itemId}/Move/{newIndex}")] - [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult MoveItem( [FromRoute] string playlistId, [FromRoute] string itemId, [FromRoute] int newIndex) { _playlistManager.MoveItem(playlistId, itemId, newIndex); - return Ok(); + return NoContent(); } /// @@ -117,14 +118,14 @@ namespace Jellyfin.Api.Controllers /// /// The playlist id. /// The item ids, comma delimited. - /// Items removed. - /// An on success. + /// Items removed. + /// An on success. [HttpDelete("{playlistId}/Items")] - [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult RemoveFromPlaylist([FromRoute] string playlistId, [FromQuery] string entryIds) { _playlistManager.RemoveFromPlaylist(playlistId, entryIds.Split(',')); - return Ok(); + return NoContent(); } /// @@ -151,7 +152,7 @@ namespace Jellyfin.Api.Controllers [FromRoute] string fields, [FromRoute] bool? enableImages, [FromRoute] bool? enableUserData, - [FromRoute] bool? imageTypeLimit, + [FromRoute] int? imageTypeLimit, [FromRoute] string enableImageTypes) { var playlist = (Playlist)_libraryManager.GetItemById(playlistId); @@ -176,8 +177,10 @@ namespace Jellyfin.Api.Controllers items = items.Take(limit.Value).ToArray(); } - // TODO var dtoOptions = GetDtoOptions(_authContext, request); - var dtoOptions = new DtoOptions(); + var dtoOptions = new DtoOptions() + .AddItemFields(fields) + .AddClientFields(Request) + .AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes); var dtos = _dtoService.GetBaseItemDtos(items.Select(i => i.Item2).ToList(), dtoOptions, user); diff --git a/Jellyfin.Api/Extensions/DtoExtensions.cs b/Jellyfin.Api/Extensions/DtoExtensions.cs index 4c587391f..ac248109d 100644 --- a/Jellyfin.Api/Extensions/DtoExtensions.cs +++ b/Jellyfin.Api/Extensions/DtoExtensions.cs @@ -122,7 +122,7 @@ namespace Jellyfin.Api.Extensions /// Enable image types. /// Modified DtoOptions object. internal static DtoOptions AddAdditionalDtoOptions( - in DtoOptions dtoOptions, + this DtoOptions dtoOptions, bool? enableImages, bool? enableUserData, int? imageTypeLimit, diff --git a/Jellyfin.Api/Helpers/RequestHelpers.cs b/Jellyfin.Api/Helpers/RequestHelpers.cs index 2ff40a8a5..e2a0cf4fa 100644 --- a/Jellyfin.Api/Helpers/RequestHelpers.cs +++ b/Jellyfin.Api/Helpers/RequestHelpers.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using Jellyfin.Data.Enums; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Session; @@ -73,5 +74,22 @@ namespace Jellyfin.Api.Helpers return session; } + + /// + /// Get Guid array from string. + /// + /// String value. + /// Guid array. + internal static Guid[] GetGuids(string? value) + { + if (value == null) + { + return Array.Empty(); + } + + return value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) + .Select(i => new Guid(i)) + .ToArray(); + } } } -- cgit v1.2.3 From 472fd5217f25b6849ee4c1de7da92c70b5c1a9b1 Mon Sep 17 00:00:00 2001 From: crobibero Date: Sat, 20 Jun 2020 16:07:09 -0600 Subject: clean up --- Jellyfin.Api/Controllers/PlaylistsController.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'Jellyfin.Api/Controllers/PlaylistsController.cs') diff --git a/Jellyfin.Api/Controllers/PlaylistsController.cs b/Jellyfin.Api/Controllers/PlaylistsController.cs index 9e2a91e10..2e3f6c54a 100644 --- a/Jellyfin.Api/Controllers/PlaylistsController.cs +++ b/Jellyfin.Api/Controllers/PlaylistsController.cs @@ -1,7 +1,4 @@ -#nullable enable -#pragma warning disable CA1801 - -using System; +using System; using System.Linq; using System.Threading.Tasks; using Jellyfin.Api.Extensions; @@ -124,7 +121,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult RemoveFromPlaylist([FromRoute] string playlistId, [FromQuery] string entryIds) { - _playlistManager.RemoveFromPlaylist(playlistId, entryIds.Split(',')); + _playlistManager.RemoveFromPlaylist(playlistId, RequestHelpers.Split(entryIds, ',', true)); return NoContent(); } -- cgit v1.2.3 From 5c6e9f4db58883db43055cd37b2cecd9fa2c12b2 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 22 Jun 2020 15:44:11 +0200 Subject: Add missing authorization policies --- Jellyfin.Api/Controllers/DisplayPreferencesController.cs | 3 ++- Jellyfin.Api/Controllers/FilterController.cs | 3 ++- Jellyfin.Api/Controllers/ImageByNameController.cs | 7 ++++--- Jellyfin.Api/Controllers/ItemLookupController.cs | 2 +- Jellyfin.Api/Controllers/ItemRefreshController.cs | 3 ++- Jellyfin.Api/Controllers/PlaylistsController.cs | 3 ++- Jellyfin.Api/Controllers/PluginsController.cs | 2 +- Jellyfin.Api/Controllers/RemoteImageController.cs | 3 ++- Jellyfin.Api/Controllers/SessionController.cs | 3 ++- Jellyfin.Api/Controllers/UserController.cs | 12 ++++++------ Jellyfin.Api/Controllers/VideosController.cs | 2 +- 11 files changed, 25 insertions(+), 18 deletions(-) (limited to 'Jellyfin.Api/Controllers/PlaylistsController.cs') diff --git a/Jellyfin.Api/Controllers/DisplayPreferencesController.cs b/Jellyfin.Api/Controllers/DisplayPreferencesController.cs index 846cd849a..3f946d9d2 100644 --- a/Jellyfin.Api/Controllers/DisplayPreferencesController.cs +++ b/Jellyfin.Api/Controllers/DisplayPreferencesController.cs @@ -1,6 +1,7 @@ using System.ComponentModel.DataAnnotations; using System.Diagnostics.CodeAnalysis; using System.Threading; +using Jellyfin.Api.Constants; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Entities; using Microsoft.AspNetCore.Authorization; @@ -13,7 +14,7 @@ namespace Jellyfin.Api.Controllers /// /// Display Preferences Controller. /// - [Authorize] + [Authorize(Policy = Policies.DefaultAuthorization)] public class DisplayPreferencesController : BaseJellyfinApiController { private readonly IDisplayPreferencesRepository _displayPreferencesRepository; diff --git a/Jellyfin.Api/Controllers/FilterController.cs b/Jellyfin.Api/Controllers/FilterController.cs index dc5b0d906..0934a116a 100644 --- a/Jellyfin.Api/Controllers/FilterController.cs +++ b/Jellyfin.Api/Controllers/FilterController.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics.CodeAnalysis; using System.Linq; +using Jellyfin.Api.Constants; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; @@ -18,7 +19,7 @@ namespace Jellyfin.Api.Controllers /// /// Filters controller. /// - [Authorize] + [Authorize(Policy = Policies.DefaultAuthorization)] public class FilterController : BaseJellyfinApiController { private readonly ILibraryManager _libraryManager; diff --git a/Jellyfin.Api/Controllers/ImageByNameController.cs b/Jellyfin.Api/Controllers/ImageByNameController.cs index 0e3c32d3c..4800c0608 100644 --- a/Jellyfin.Api/Controllers/ImageByNameController.cs +++ b/Jellyfin.Api/Controllers/ImageByNameController.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Mime; +using Jellyfin.Api.Constants; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; @@ -43,7 +44,7 @@ namespace Jellyfin.Api.Controllers /// Retrieved list of images. /// An containing the list of images. [HttpGet("General")] - [Authorize] + [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetGeneralImages() { @@ -88,7 +89,7 @@ namespace Jellyfin.Api.Controllers /// Retrieved list of images. /// An containing the list of images. [HttpGet("Ratings")] - [Authorize] + [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetRatingImages() { @@ -121,7 +122,7 @@ namespace Jellyfin.Api.Controllers /// Image list retrieved. /// An containing the list of images. [HttpGet("MediaInfo")] - [Authorize] + [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetMediaInfoImages() { diff --git a/Jellyfin.Api/Controllers/ItemLookupController.cs b/Jellyfin.Api/Controllers/ItemLookupController.cs index 75cba450f..44709d0ee 100644 --- a/Jellyfin.Api/Controllers/ItemLookupController.cs +++ b/Jellyfin.Api/Controllers/ItemLookupController.cs @@ -30,7 +30,7 @@ namespace Jellyfin.Api.Controllers /// /// Item lookup controller. /// - [Authorize] + [Authorize(Policy = Policies.DefaultAuthorization)] public class ItemLookupController : BaseJellyfinApiController { private readonly IProviderManager _providerManager; diff --git a/Jellyfin.Api/Controllers/ItemRefreshController.cs b/Jellyfin.Api/Controllers/ItemRefreshController.cs index e527e5410..e6cdf4edb 100644 --- a/Jellyfin.Api/Controllers/ItemRefreshController.cs +++ b/Jellyfin.Api/Controllers/ItemRefreshController.cs @@ -1,6 +1,7 @@ using System; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; +using Jellyfin.Api.Constants; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.IO; @@ -15,7 +16,7 @@ namespace Jellyfin.Api.Controllers /// /// [Authenticated] [Route("/Items")] - [Authorize] + [Authorize(Policy = Policies.DefaultAuthorization)] public class ItemRefreshController : BaseJellyfinApiController { private readonly ILibraryManager _libraryManager; diff --git a/Jellyfin.Api/Controllers/PlaylistsController.cs b/Jellyfin.Api/Controllers/PlaylistsController.cs index 2e3f6c54a..2dc0d2dc7 100644 --- a/Jellyfin.Api/Controllers/PlaylistsController.cs +++ b/Jellyfin.Api/Controllers/PlaylistsController.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Threading.Tasks; +using Jellyfin.Api.Constants; using Jellyfin.Api.Extensions; using Jellyfin.Api.Helpers; using Jellyfin.Api.Models.PlaylistDtos; @@ -20,7 +21,7 @@ namespace Jellyfin.Api.Controllers /// /// Playlists controller. /// - [Authorize] + [Authorize(Policy = Policies.DefaultAuthorization)] public class PlaylistsController : BaseJellyfinApiController { private readonly IPlaylistManager _playlistManager; diff --git a/Jellyfin.Api/Controllers/PluginsController.cs b/Jellyfin.Api/Controllers/PluginsController.cs index f6036b748..979d40119 100644 --- a/Jellyfin.Api/Controllers/PluginsController.cs +++ b/Jellyfin.Api/Controllers/PluginsController.cs @@ -20,7 +20,7 @@ namespace Jellyfin.Api.Controllers /// /// Plugins controller. /// - [Authorize] + [Authorize(Policy = Policies.DefaultAuthorization)] public class PluginsController : BaseJellyfinApiController { private readonly IApplicationHost _appHost; diff --git a/Jellyfin.Api/Controllers/RemoteImageController.cs b/Jellyfin.Api/Controllers/RemoteImageController.cs index 41b7f98ee..a0d14be7a 100644 --- a/Jellyfin.Api/Controllers/RemoteImageController.cs +++ b/Jellyfin.Api/Controllers/RemoteImageController.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Net.Mime; using System.Threading; using System.Threading.Tasks; +using Jellyfin.Api.Constants; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using MediaBrowser.Controller; @@ -25,7 +26,7 @@ namespace Jellyfin.Api.Controllers /// Remote Images Controller. /// [Route("Images")] - [Authorize] + [Authorize(Policy = Policies.DefaultAuthorization)] public class RemoteImageController : BaseJellyfinApiController { private readonly IProviderManager _providerManager; diff --git a/Jellyfin.Api/Controllers/SessionController.cs b/Jellyfin.Api/Controllers/SessionController.cs index 315bc9728..39da4178d 100644 --- a/Jellyfin.Api/Controllers/SessionController.cs +++ b/Jellyfin.Api/Controllers/SessionController.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading; +using Jellyfin.Api.Constants; using Jellyfin.Api.Helpers; using Jellyfin.Data.Enums; using MediaBrowser.Controller.Devices; @@ -57,7 +58,7 @@ namespace Jellyfin.Api.Controllers /// List of sessions returned. /// An with the available sessions. [HttpGet("/Sessions")] - [Authorize] + [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetSessions( [FromQuery] Guid controllableByUserId, diff --git a/Jellyfin.Api/Controllers/UserController.cs b/Jellyfin.Api/Controllers/UserController.cs index 0d57dcc83..c1f417df5 100644 --- a/Jellyfin.Api/Controllers/UserController.cs +++ b/Jellyfin.Api/Controllers/UserController.cs @@ -72,7 +72,7 @@ namespace Jellyfin.Api.Controllers /// Users returned. /// An containing the users. [HttpGet] - [Authorize] + [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isGuest", Justification = "Imported from ServiceStack")] public ActionResult> GetUsers( @@ -237,7 +237,7 @@ namespace Jellyfin.Api.Controllers /// User not found. /// A indicating success or a or a on failure. [HttpPost("{userId}/Password")] - [Authorize] + [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] @@ -295,7 +295,7 @@ namespace Jellyfin.Api.Controllers /// User not found. /// A indicating success or a or a on failure. [HttpPost("{userId}/EasyPassword")] - [Authorize] + [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] @@ -337,7 +337,7 @@ namespace Jellyfin.Api.Controllers /// User update forbidden. /// A indicating success or a or a on failure. [HttpPost("{userId}")] - [Authorize] + [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] @@ -381,7 +381,7 @@ namespace Jellyfin.Api.Controllers /// User policy update forbidden. /// A indicating success or a or a on failure.. [HttpPost("{userId}/Policy")] - [Authorize] + [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] @@ -437,7 +437,7 @@ namespace Jellyfin.Api.Controllers /// User configuration update forbidden. /// A indicating success. [HttpPost("{userId}/Configuration")] - [Authorize] + [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status403Forbidden)] public ActionResult UpdateUserConfiguration( diff --git a/Jellyfin.Api/Controllers/VideosController.cs b/Jellyfin.Api/Controllers/VideosController.cs index 532ce59c5..effe630a9 100644 --- a/Jellyfin.Api/Controllers/VideosController.cs +++ b/Jellyfin.Api/Controllers/VideosController.cs @@ -51,7 +51,7 @@ namespace Jellyfin.Api.Controllers /// Additional parts returned. /// A with the parts. [HttpGet("{itemId}/AdditionalParts")] - [Authorize] + [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetAdditionalPart([FromRoute] Guid itemId, [FromQuery] Guid userId) { -- cgit v1.2.3 From 73bcda7eac6d0785745179fe4b7f58b6bc4ec488 Mon Sep 17 00:00:00 2001 From: crobibero Date: Sat, 27 Jun 2020 10:50:44 -0600 Subject: Make all optional strings nullable --- Jellyfin.Api/Controllers/AlbumsController.cs | 4 +- Jellyfin.Api/Controllers/ApiKeyController.cs | 4 +- Jellyfin.Api/Controllers/CollectionController.cs | 8 ++-- .../Controllers/ConfigurationController.cs | 4 +- Jellyfin.Api/Controllers/DashboardController.cs | 2 +- Jellyfin.Api/Controllers/DevicesController.cs | 8 ++-- .../Controllers/DisplayPreferencesController.cs | 12 +++--- Jellyfin.Api/Controllers/ImageByNameController.cs | 12 +++--- Jellyfin.Api/Controllers/InstantMixController.cs | 16 ++++---- Jellyfin.Api/Controllers/ItemUpdateController.cs | 2 +- Jellyfin.Api/Controllers/LibraryController.cs | 16 ++++---- .../Controllers/LibraryStructureController.cs | 22 +++++------ .../Controllers/NotificationsController.cs | 4 +- Jellyfin.Api/Controllers/PackageController.cs | 8 ++-- Jellyfin.Api/Controllers/PlaylistsController.cs | 14 +++---- Jellyfin.Api/Controllers/PluginsController.cs | 4 +- Jellyfin.Api/Controllers/RemoteImageController.cs | 2 +- .../Controllers/ScheduledTasksController.cs | 8 ++-- Jellyfin.Api/Controllers/SearchController.cs | 10 ++--- Jellyfin.Api/Controllers/SessionController.cs | 46 +++++++++++----------- Jellyfin.Api/Controllers/StartupController.cs | 6 +-- Jellyfin.Api/Controllers/SubtitleController.cs | 14 +++---- Jellyfin.Api/Controllers/SystemController.cs | 2 +- Jellyfin.Api/Controllers/TvShowsController.cs | 8 ++-- Jellyfin.Api/Controllers/UserController.cs | 8 ++-- Jellyfin.Api/Controllers/UserLibraryController.cs | 6 +-- Jellyfin.Api/Controllers/UserViewsController.cs | 2 +- .../Controllers/VideoAttachmentsController.cs | 2 +- Jellyfin.Api/Controllers/VideosController.cs | 2 +- Jellyfin.Api/Controllers/YearsController.cs | 16 ++++---- Jellyfin.Api/Extensions/DtoExtensions.cs | 4 +- Jellyfin.Api/Helpers/RequestHelpers.cs | 10 ++--- Jellyfin.Api/Helpers/SimilarItemsHelper.cs | 2 +- 33 files changed, 143 insertions(+), 145 deletions(-) (limited to 'Jellyfin.Api/Controllers/PlaylistsController.cs') diff --git a/Jellyfin.Api/Controllers/AlbumsController.cs b/Jellyfin.Api/Controllers/AlbumsController.cs index 622123873..70315b0a3 100644 --- a/Jellyfin.Api/Controllers/AlbumsController.cs +++ b/Jellyfin.Api/Controllers/AlbumsController.cs @@ -53,7 +53,7 @@ namespace Jellyfin.Api.Controllers public ActionResult> GetSimilarAlbums( [FromRoute] string albumId, [FromQuery] Guid userId, - [FromQuery] string excludeArtistIds, + [FromQuery] string? excludeArtistIds, [FromQuery] int? limit) { var dtoOptions = new DtoOptions().AddClientFields(Request); @@ -85,7 +85,7 @@ namespace Jellyfin.Api.Controllers public ActionResult> GetSimilarArtists( [FromRoute] string artistId, [FromQuery] Guid userId, - [FromQuery] string excludeArtistIds, + [FromQuery] string? excludeArtistIds, [FromQuery] int? limit) { var dtoOptions = new DtoOptions().AddClientFields(Request); diff --git a/Jellyfin.Api/Controllers/ApiKeyController.cs b/Jellyfin.Api/Controllers/ApiKeyController.cs index ed521c1fc..fef4d7262 100644 --- a/Jellyfin.Api/Controllers/ApiKeyController.cs +++ b/Jellyfin.Api/Controllers/ApiKeyController.cs @@ -65,7 +65,7 @@ namespace Jellyfin.Api.Controllers [HttpPost("Keys")] [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status204NoContent)] - public ActionResult CreateKey([FromQuery, Required] string app) + public ActionResult CreateKey([FromQuery, Required] string? app) { _authRepo.Create(new AuthenticationInfo { @@ -88,7 +88,7 @@ namespace Jellyfin.Api.Controllers [HttpDelete("Keys/{key}")] [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status204NoContent)] - public ActionResult RevokeKey([FromRoute] string key) + public ActionResult RevokeKey([FromRoute] string? key) { _sessionManager.RevokeToken(key); return NoContent(); diff --git a/Jellyfin.Api/Controllers/CollectionController.cs b/Jellyfin.Api/Controllers/CollectionController.cs index 29db0b178..7ff98b251 100644 --- a/Jellyfin.Api/Controllers/CollectionController.cs +++ b/Jellyfin.Api/Controllers/CollectionController.cs @@ -51,8 +51,8 @@ namespace Jellyfin.Api.Controllers [HttpPost] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult CreateCollection( - [FromQuery] string name, - [FromQuery] string ids, + [FromQuery] string? name, + [FromQuery] string? ids, [FromQuery] bool isLocked, [FromQuery] Guid? parentId) { @@ -86,7 +86,7 @@ namespace Jellyfin.Api.Controllers /// A indicating success. [HttpPost("{collectionId}/Items")] [ProducesResponseType(StatusCodes.Status204NoContent)] - public ActionResult AddToCollection([FromRoute] Guid collectionId, [FromQuery] string itemIds) + public ActionResult AddToCollection([FromRoute] Guid collectionId, [FromQuery] string? itemIds) { _collectionManager.AddToCollection(collectionId, RequestHelpers.Split(itemIds, ',', true)); return NoContent(); @@ -101,7 +101,7 @@ namespace Jellyfin.Api.Controllers /// A indicating success. [HttpDelete("{collectionId}/Items")] [ProducesResponseType(StatusCodes.Status204NoContent)] - public ActionResult RemoveFromCollection([FromRoute] Guid collectionId, [FromQuery] string itemIds) + public ActionResult RemoveFromCollection([FromRoute] Guid collectionId, [FromQuery] string? itemIds) { _collectionManager.RemoveFromCollection(collectionId, RequestHelpers.Split(itemIds, ',', true)); return NoContent(); diff --git a/Jellyfin.Api/Controllers/ConfigurationController.cs b/Jellyfin.Api/Controllers/ConfigurationController.cs index d275ed2eb..13933cb33 100644 --- a/Jellyfin.Api/Controllers/ConfigurationController.cs +++ b/Jellyfin.Api/Controllers/ConfigurationController.cs @@ -70,7 +70,7 @@ namespace Jellyfin.Api.Controllers /// Configuration. [HttpGet("Configuration/{key}")] [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult GetNamedConfiguration([FromRoute] string key) + public ActionResult GetNamedConfiguration([FromRoute] string? key) { return _configurationManager.GetConfiguration(key); } @@ -84,7 +84,7 @@ namespace Jellyfin.Api.Controllers [HttpPost("Configuration/{key}")] [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status204NoContent)] - public async Task UpdateNamedConfiguration([FromRoute] string key) + public async Task UpdateNamedConfiguration([FromRoute] string? key) { var configurationType = _configurationManager.GetConfigurationType(key); var configuration = await JsonSerializer.DeserializeAsync(Request.Body, configurationType).ConfigureAwait(false); diff --git a/Jellyfin.Api/Controllers/DashboardController.cs b/Jellyfin.Api/Controllers/DashboardController.cs index 6cfee2463..699ef6bf7 100644 --- a/Jellyfin.Api/Controllers/DashboardController.cs +++ b/Jellyfin.Api/Controllers/DashboardController.cs @@ -122,7 +122,7 @@ namespace Jellyfin.Api.Controllers [HttpGet("/web/ConfigurationPage")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult GetDashboardConfigurationPage([FromQuery] string name) + public ActionResult GetDashboardConfigurationPage([FromQuery] string? name) { IPlugin? plugin = null; Stream? stream = null; diff --git a/Jellyfin.Api/Controllers/DevicesController.cs b/Jellyfin.Api/Controllers/DevicesController.cs index 55ca7b7c0..3cf7b3378 100644 --- a/Jellyfin.Api/Controllers/DevicesController.cs +++ b/Jellyfin.Api/Controllers/DevicesController.cs @@ -65,7 +65,7 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult GetDeviceInfo([FromQuery, BindRequired] string id) + public ActionResult GetDeviceInfo([FromQuery, BindRequired] string? id) { var deviceInfo = _deviceManager.GetDevice(id); if (deviceInfo == null) @@ -87,7 +87,7 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult GetDeviceOptions([FromQuery, BindRequired] string id) + public ActionResult GetDeviceOptions([FromQuery, BindRequired] string? id) { var deviceInfo = _deviceManager.GetDeviceOptions(id); if (deviceInfo == null) @@ -111,7 +111,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult UpdateDeviceOptions( - [FromQuery, BindRequired] string id, + [FromQuery, BindRequired] string? id, [FromBody, BindRequired] DeviceOptions deviceOptions) { var existingDeviceOptions = _deviceManager.GetDeviceOptions(id); @@ -134,7 +134,7 @@ namespace Jellyfin.Api.Controllers [HttpDelete] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult DeleteDevice([FromQuery, BindRequired] string id) + public ActionResult DeleteDevice([FromQuery, BindRequired] string? id) { var existingDevice = _deviceManager.GetDevice(id); if (existingDevice == null) diff --git a/Jellyfin.Api/Controllers/DisplayPreferencesController.cs b/Jellyfin.Api/Controllers/DisplayPreferencesController.cs index 3f946d9d2..1255e6dab 100644 --- a/Jellyfin.Api/Controllers/DisplayPreferencesController.cs +++ b/Jellyfin.Api/Controllers/DisplayPreferencesController.cs @@ -39,9 +39,9 @@ namespace Jellyfin.Api.Controllers [HttpGet("{displayPreferencesId}")] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult GetDisplayPreferences( - [FromRoute] string displayPreferencesId, - [FromQuery] [Required] string userId, - [FromQuery] [Required] string client) + [FromRoute] string? displayPreferencesId, + [FromQuery] [Required] string? userId, + [FromQuery] [Required] string? client) { return _displayPreferencesRepository.GetDisplayPreferences(displayPreferencesId, userId, client); } @@ -59,9 +59,9 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status204NoContent)] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "displayPreferencesId", Justification = "Imported from ServiceStack")] public ActionResult UpdateDisplayPreferences( - [FromRoute] string displayPreferencesId, - [FromQuery, BindRequired] string userId, - [FromQuery, BindRequired] string client, + [FromRoute] string? displayPreferencesId, + [FromQuery, BindRequired] string? userId, + [FromQuery, BindRequired] string? client, [FromBody, BindRequired] DisplayPreferences displayPreferences) { _displayPreferencesRepository.SaveDisplayPreferences( diff --git a/Jellyfin.Api/Controllers/ImageByNameController.cs b/Jellyfin.Api/Controllers/ImageByNameController.cs index 4800c0608..5244c35b8 100644 --- a/Jellyfin.Api/Controllers/ImageByNameController.cs +++ b/Jellyfin.Api/Controllers/ImageByNameController.cs @@ -64,7 +64,7 @@ namespace Jellyfin.Api.Controllers [Produces(MediaTypeNames.Application.Octet)] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult GetGeneralImage([FromRoute] string name, [FromRoute] string type) + public ActionResult GetGeneralImage([FromRoute] string? name, [FromRoute] string? type) { var filename = string.Equals(type, "primary", StringComparison.OrdinalIgnoreCase) ? "folder" @@ -110,8 +110,8 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult GetRatingImage( - [FromRoute] string theme, - [FromRoute] string name) + [FromRoute] string? theme, + [FromRoute] string? name) { return GetImageFile(_applicationPaths.RatingsPath, theme, name); } @@ -143,8 +143,8 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult GetMediaInfoImage( - [FromRoute] string theme, - [FromRoute] string name) + [FromRoute] string? theme, + [FromRoute] string? name) { return GetImageFile(_applicationPaths.MediaInfoImagesPath, theme, name); } @@ -156,7 +156,7 @@ namespace Jellyfin.Api.Controllers /// Theme to search. /// File name to search for. /// A containing the image contents on success, or a if the image could not be found. - private ActionResult GetImageFile(string basePath, string theme, string name) + private ActionResult GetImageFile(string basePath, string? theme, string? name) { var themeFolder = Path.Combine(basePath, theme); if (Directory.Exists(themeFolder)) diff --git a/Jellyfin.Api/Controllers/InstantMixController.cs b/Jellyfin.Api/Controllers/InstantMixController.cs index f1ff770a4..9d945fe2b 100644 --- a/Jellyfin.Api/Controllers/InstantMixController.cs +++ b/Jellyfin.Api/Controllers/InstantMixController.cs @@ -65,7 +65,7 @@ namespace Jellyfin.Api.Controllers [FromRoute] Guid id, [FromQuery] Guid userId, [FromQuery] int? limit, - [FromQuery] string fields, + [FromQuery] string? fields, [FromQuery] bool? enableImages, [FromQuery] bool? enableUserData, [FromQuery] int? imageTypeLimit, @@ -100,7 +100,7 @@ namespace Jellyfin.Api.Controllers [FromRoute] Guid id, [FromQuery] Guid userId, [FromQuery] int? limit, - [FromQuery] string fields, + [FromQuery] string? fields, [FromQuery] bool? enableImages, [FromQuery] bool? enableUserData, [FromQuery] int? imageTypeLimit, @@ -135,7 +135,7 @@ namespace Jellyfin.Api.Controllers [FromRoute] Guid id, [FromQuery] Guid userId, [FromQuery] int? limit, - [FromQuery] string fields, + [FromQuery] string? fields, [FromQuery] bool? enableImages, [FromQuery] bool? enableUserData, [FromQuery] int? imageTypeLimit, @@ -167,10 +167,10 @@ namespace Jellyfin.Api.Controllers [HttpGet("/MusicGenres/{name}/InstantMix")] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetInstantMixFromMusicGenre( - [FromRoute] string name, + [FromRoute] string? name, [FromQuery] Guid userId, [FromQuery] int? limit, - [FromQuery] string fields, + [FromQuery] string? fields, [FromQuery] bool? enableImages, [FromQuery] bool? enableUserData, [FromQuery] int? imageTypeLimit, @@ -204,7 +204,7 @@ namespace Jellyfin.Api.Controllers [FromRoute] Guid id, [FromQuery] Guid userId, [FromQuery] int? limit, - [FromQuery] string fields, + [FromQuery] string? fields, [FromQuery] bool? enableImages, [FromQuery] bool? enableUserData, [FromQuery] int? imageTypeLimit, @@ -239,7 +239,7 @@ namespace Jellyfin.Api.Controllers [FromRoute] Guid id, [FromQuery] Guid userId, [FromQuery] int? limit, - [FromQuery] string fields, + [FromQuery] string? fields, [FromQuery] bool? enableImages, [FromQuery] bool? enableUserData, [FromQuery] int? imageTypeLimit, @@ -274,7 +274,7 @@ namespace Jellyfin.Api.Controllers [FromRoute] Guid id, [FromQuery] Guid userId, [FromQuery] int? limit, - [FromQuery] string fields, + [FromQuery] string? fields, [FromQuery] bool? enableImages, [FromQuery] bool? enableUserData, [FromQuery] int? imageTypeLimit, diff --git a/Jellyfin.Api/Controllers/ItemUpdateController.cs b/Jellyfin.Api/Controllers/ItemUpdateController.cs index 384f250ec..c9b2aafcc 100644 --- a/Jellyfin.Api/Controllers/ItemUpdateController.cs +++ b/Jellyfin.Api/Controllers/ItemUpdateController.cs @@ -193,7 +193,7 @@ namespace Jellyfin.Api.Controllers [HttpPost("/Items/{itemId}/ContentType")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult UpdateItemContentType([FromRoute] Guid itemId, [FromQuery, BindRequired] string contentType) + public ActionResult UpdateItemContentType([FromRoute] Guid itemId, [FromQuery, BindRequired] string? contentType) { var item = _libraryManager.GetItemById(itemId); if (item == null) diff --git a/Jellyfin.Api/Controllers/LibraryController.cs b/Jellyfin.Api/Controllers/LibraryController.cs index 1ecf2ac73..f1106cda6 100644 --- a/Jellyfin.Api/Controllers/LibraryController.cs +++ b/Jellyfin.Api/Controllers/LibraryController.cs @@ -524,7 +524,7 @@ namespace Jellyfin.Api.Controllers [HttpPost("/Library/Series/Updated")] [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status204NoContent)] - public ActionResult PostUpdatedSeries([FromQuery] string tvdbId) + public ActionResult PostUpdatedSeries([FromQuery] string? tvdbId) { var series = _libraryManager.GetItemList(new InternalItemsQuery { @@ -554,7 +554,7 @@ namespace Jellyfin.Api.Controllers [HttpPost("/Library/Movies/Updated")] [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status204NoContent)] - public ActionResult PostUpdatedMovies([FromRoute] string tmdbId, [FromRoute] string imdbId) + public ActionResult PostUpdatedMovies([FromRoute] string? tmdbId, [FromRoute] string? imdbId) { var movies = _libraryManager.GetItemList(new InternalItemsQuery { @@ -687,10 +687,10 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetSimilarItems( [FromRoute] Guid itemId, - [FromQuery] string excludeArtistIds, + [FromQuery] string? excludeArtistIds, [FromQuery] Guid userId, [FromQuery] int? limit, - [FromQuery] string fields) + [FromQuery] string? fields) { var item = itemId.Equals(Guid.Empty) ? (!userId.Equals(Guid.Empty) @@ -737,7 +737,7 @@ namespace Jellyfin.Api.Controllers [HttpGet("/Libraries/AvailableOptions")] [Authorize(Policy = Policies.FirstTimeSetupOrElevated)] [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult GetLibraryOptionsInfo([FromQuery] string libraryContentType, [FromQuery] bool isNewLibrary) + public ActionResult GetLibraryOptionsInfo([FromQuery] string? libraryContentType, [FromQuery] bool isNewLibrary) { var result = new LibraryOptionsResultDto(); @@ -877,10 +877,10 @@ namespace Jellyfin.Api.Controllers private QueryResult GetSimilarItemsResult( BaseItem item, - string excludeArtistIds, + string? excludeArtistIds, Guid userId, int? limit, - string fields, + string? fields, string[] includeItemTypes, bool isMovie) { @@ -942,7 +942,7 @@ namespace Jellyfin.Api.Controllers return result; } - private static string[] GetRepresentativeItemTypes(string contentType) + private static string[] GetRepresentativeItemTypes(string? contentType) { return contentType switch { diff --git a/Jellyfin.Api/Controllers/LibraryStructureController.cs b/Jellyfin.Api/Controllers/LibraryStructureController.cs index e4ac019c9..0c91f8447 100644 --- a/Jellyfin.Api/Controllers/LibraryStructureController.cs +++ b/Jellyfin.Api/Controllers/LibraryStructureController.cs @@ -72,8 +72,8 @@ namespace Jellyfin.Api.Controllers [HttpPost] [ProducesResponseType(StatusCodes.Status204NoContent)] public async Task AddVirtualFolder( - [FromQuery] string name, - [FromQuery] string collectionType, + [FromQuery] string? name, + [FromQuery] string? collectionType, [FromQuery] bool refreshLibrary, [FromQuery] string[] paths, [FromQuery] LibraryOptions libraryOptions) @@ -100,7 +100,7 @@ namespace Jellyfin.Api.Controllers [HttpDelete] [ProducesResponseType(StatusCodes.Status204NoContent)] public async Task RemoveVirtualFolder( - [FromQuery] string name, + [FromQuery] string? name, [FromQuery] bool refreshLibrary) { await _libraryManager.RemoveVirtualFolder(name, refreshLibrary).ConfigureAwait(false); @@ -123,8 +123,8 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] public ActionResult RenameVirtualFolder( - [FromQuery] string name, - [FromQuery] string newName, + [FromQuery] string? name, + [FromQuery] string? newName, [FromQuery] bool refreshLibrary) { if (string.IsNullOrWhiteSpace(name)) @@ -205,8 +205,8 @@ namespace Jellyfin.Api.Controllers [HttpPost("Paths")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult AddMediaPath( - [FromQuery] string name, - [FromQuery] string path, + [FromQuery] string? name, + [FromQuery] string? path, [FromQuery] MediaPathInfo pathInfo, [FromQuery] bool refreshLibrary) { @@ -256,7 +256,7 @@ namespace Jellyfin.Api.Controllers [HttpPost("Paths/Update")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult UpdateMediaPath( - [FromQuery] string name, + [FromQuery] string? name, [FromQuery] MediaPathInfo pathInfo) { if (string.IsNullOrWhiteSpace(name)) @@ -280,8 +280,8 @@ namespace Jellyfin.Api.Controllers [HttpDelete("Paths")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult RemoveMediaPath( - [FromQuery] string name, - [FromQuery] string path, + [FromQuery] string? name, + [FromQuery] string? path, [FromQuery] bool refreshLibrary) { if (string.IsNullOrWhiteSpace(name)) @@ -327,7 +327,7 @@ namespace Jellyfin.Api.Controllers [HttpPost("LibraryOptions")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult UpdateLibraryOptions( - [FromQuery] string id, + [FromQuery] string? id, [FromQuery] LibraryOptions libraryOptions) { var collectionFolder = (CollectionFolder)_libraryManager.GetItemById(id); diff --git a/Jellyfin.Api/Controllers/NotificationsController.cs b/Jellyfin.Api/Controllers/NotificationsController.cs index cfa7545c9..02aa39b24 100644 --- a/Jellyfin.Api/Controllers/NotificationsController.cs +++ b/Jellyfin.Api/Controllers/NotificationsController.cs @@ -93,8 +93,8 @@ namespace Jellyfin.Api.Controllers [HttpPost("Admin")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult CreateAdminNotification( - [FromQuery] string name, - [FromQuery] string description, + [FromQuery] string? name, + [FromQuery] string? description, [FromQuery] string? url, [FromQuery] NotificationLevel? level) { diff --git a/Jellyfin.Api/Controllers/PackageController.cs b/Jellyfin.Api/Controllers/PackageController.cs index 486575d23..68ae05658 100644 --- a/Jellyfin.Api/Controllers/PackageController.cs +++ b/Jellyfin.Api/Controllers/PackageController.cs @@ -40,7 +40,7 @@ namespace Jellyfin.Api.Controllers [HttpGet("/{name}")] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> GetPackageInfo( - [FromRoute] [Required] string name, + [FromRoute] [Required] string? name, [FromQuery] string? assemblyGuid) { var packages = await _installationManager.GetAvailablePackages().ConfigureAwait(false); @@ -80,9 +80,9 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize(Policy = Policies.RequiresElevation)] public async Task InstallPackage( - [FromRoute] [Required] string name, - [FromQuery] string assemblyGuid, - [FromQuery] string version) + [FromRoute] [Required] string? name, + [FromQuery] string? assemblyGuid, + [FromQuery] string? version) { var packages = await _installationManager.GetAvailablePackages().ConfigureAwait(false); var package = _installationManager.GetCompatibleVersions( diff --git a/Jellyfin.Api/Controllers/PlaylistsController.cs b/Jellyfin.Api/Controllers/PlaylistsController.cs index 2dc0d2dc7..d62404fc9 100644 --- a/Jellyfin.Api/Controllers/PlaylistsController.cs +++ b/Jellyfin.Api/Controllers/PlaylistsController.cs @@ -84,8 +84,8 @@ namespace Jellyfin.Api.Controllers [HttpPost("{playlistId}/Items")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult AddToPlaylist( - [FromRoute] string playlistId, - [FromQuery] string ids, + [FromRoute] string? playlistId, + [FromQuery] string? ids, [FromQuery] Guid userId) { _playlistManager.AddToPlaylist(playlistId, RequestHelpers.GetGuids(ids), userId); @@ -103,8 +103,8 @@ namespace Jellyfin.Api.Controllers [HttpPost("{playlistId}/Items/{itemId}/Move/{newIndex}")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult MoveItem( - [FromRoute] string playlistId, - [FromRoute] string itemId, + [FromRoute] string? playlistId, + [FromRoute] string? itemId, [FromRoute] int newIndex) { _playlistManager.MoveItem(playlistId, itemId, newIndex); @@ -120,7 +120,7 @@ namespace Jellyfin.Api.Controllers /// An on success. [HttpDelete("{playlistId}/Items")] [ProducesResponseType(StatusCodes.Status204NoContent)] - public ActionResult RemoveFromPlaylist([FromRoute] string playlistId, [FromQuery] string entryIds) + public ActionResult RemoveFromPlaylist([FromRoute] string? playlistId, [FromQuery] string? entryIds) { _playlistManager.RemoveFromPlaylist(playlistId, RequestHelpers.Split(entryIds, ',', true)); return NoContent(); @@ -147,11 +147,11 @@ namespace Jellyfin.Api.Controllers [FromRoute] Guid userId, [FromRoute] int? startIndex, [FromRoute] int? limit, - [FromRoute] string fields, + [FromRoute] string? fields, [FromRoute] bool? enableImages, [FromRoute] bool? enableUserData, [FromRoute] int? imageTypeLimit, - [FromRoute] string enableImageTypes) + [FromRoute] string? enableImageTypes) { var playlist = (Playlist)_libraryManager.GetItemById(playlistId); if (playlist == null) diff --git a/Jellyfin.Api/Controllers/PluginsController.cs b/Jellyfin.Api/Controllers/PluginsController.cs index fd48983ea..056395a51 100644 --- a/Jellyfin.Api/Controllers/PluginsController.cs +++ b/Jellyfin.Api/Controllers/PluginsController.cs @@ -166,7 +166,7 @@ namespace Jellyfin.Api.Controllers [Obsolete("This endpoint should not be used.")] [HttpPost("RegistrationRecords/{name}")] [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult GetRegistrationStatus([FromRoute] string name) + public ActionResult GetRegistrationStatus([FromRoute] string? name) { return new MBRegistrationRecord { @@ -188,7 +188,7 @@ namespace Jellyfin.Api.Controllers [Obsolete("Paid plugins are not supported")] [HttpGet("/Registrations/{name}")] [ProducesResponseType(StatusCodes.Status501NotImplemented)] - public ActionResult GetRegistration([FromRoute] string name) + public ActionResult GetRegistration([FromRoute] string? name) { // TODO Once we have proper apps and plugins and decide to break compatibility with paid plugins, // delete all these registration endpoints. They are only kept for compatibility. diff --git a/Jellyfin.Api/Controllers/RemoteImageController.cs b/Jellyfin.Api/Controllers/RemoteImageController.cs index a0d14be7a..6fff30129 100644 --- a/Jellyfin.Api/Controllers/RemoteImageController.cs +++ b/Jellyfin.Api/Controllers/RemoteImageController.cs @@ -208,7 +208,7 @@ namespace Jellyfin.Api.Controllers public async Task DownloadRemoteImage( [FromRoute] Guid itemId, [FromQuery, BindRequired] ImageType type, - [FromQuery] string imageUrl) + [FromQuery] string? imageUrl) { var item = _libraryManager.GetItemById(itemId); if (item == null) diff --git a/Jellyfin.Api/Controllers/ScheduledTasksController.cs b/Jellyfin.Api/Controllers/ScheduledTasksController.cs index bf5c3076e..3df325e3b 100644 --- a/Jellyfin.Api/Controllers/ScheduledTasksController.cs +++ b/Jellyfin.Api/Controllers/ScheduledTasksController.cs @@ -71,7 +71,7 @@ namespace Jellyfin.Api.Controllers [HttpGet("{taskId}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult GetTask([FromRoute] string taskId) + public ActionResult GetTask([FromRoute] string? taskId) { var task = _taskManager.ScheduledTasks.FirstOrDefault(i => string.Equals(i.Id, taskId, StringComparison.OrdinalIgnoreCase)); @@ -94,7 +94,7 @@ namespace Jellyfin.Api.Controllers [HttpPost("Running/{taskId}")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult StartTask([FromRoute] string taskId) + public ActionResult StartTask([FromRoute] string? taskId) { var task = _taskManager.ScheduledTasks.FirstOrDefault(o => o.Id.Equals(taskId, StringComparison.OrdinalIgnoreCase)); @@ -118,7 +118,7 @@ namespace Jellyfin.Api.Controllers [HttpDelete("Running/{taskId}")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult StopTask([FromRoute] string taskId) + public ActionResult StopTask([FromRoute] string? taskId) { var task = _taskManager.ScheduledTasks.FirstOrDefault(o => o.Id.Equals(taskId, StringComparison.OrdinalIgnoreCase)); @@ -144,7 +144,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult UpdateTask( - [FromRoute] string taskId, + [FromRoute] string? taskId, [FromBody, BindRequired] TaskTriggerInfo[] triggerInfos) { var task = _taskManager.ScheduledTasks.FirstOrDefault(o => diff --git a/Jellyfin.Api/Controllers/SearchController.cs b/Jellyfin.Api/Controllers/SearchController.cs index d971889db..14dc0815c 100644 --- a/Jellyfin.Api/Controllers/SearchController.cs +++ b/Jellyfin.Api/Controllers/SearchController.cs @@ -81,11 +81,11 @@ namespace Jellyfin.Api.Controllers [FromQuery] int? startIndex, [FromQuery] int? limit, [FromQuery] Guid userId, - [FromQuery, Required] string searchTerm, - [FromQuery] string includeItemTypes, - [FromQuery] string excludeItemTypes, - [FromQuery] string mediaTypes, - [FromQuery] string parentId, + [FromQuery, Required] string? searchTerm, + [FromQuery] string? includeItemTypes, + [FromQuery] string? excludeItemTypes, + [FromQuery] string? mediaTypes, + [FromQuery] string? parentId, [FromQuery] bool? isMovie, [FromQuery] bool? isSeries, [FromQuery] bool? isNews, diff --git a/Jellyfin.Api/Controllers/SessionController.cs b/Jellyfin.Api/Controllers/SessionController.cs index 39da4178d..bd738aa38 100644 --- a/Jellyfin.Api/Controllers/SessionController.cs +++ b/Jellyfin.Api/Controllers/SessionController.cs @@ -62,7 +62,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetSessions( [FromQuery] Guid controllableByUserId, - [FromQuery] string deviceId, + [FromQuery] string? deviceId, [FromQuery] int? activeWithinSeconds) { var result = _sessionManager.Sessions; @@ -123,10 +123,10 @@ namespace Jellyfin.Api.Controllers [HttpPost("/Sessions/{sessionId}/Viewing")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult DisplayContent( - [FromRoute] string sessionId, - [FromQuery] string itemType, - [FromQuery] string itemId, - [FromQuery] string itemName) + [FromRoute] string? sessionId, + [FromQuery] string? itemType, + [FromQuery] string? itemId, + [FromQuery] string? itemName) { var command = new BrowseRequest { @@ -157,7 +157,7 @@ namespace Jellyfin.Api.Controllers [HttpPost("/Sessions/{sessionId}/Playing")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult Play( - [FromRoute] string sessionId, + [FromRoute] string? sessionId, [FromQuery] Guid[] itemIds, [FromQuery] long? startPositionTicks, [FromQuery] PlayCommand playCommand, @@ -191,7 +191,7 @@ namespace Jellyfin.Api.Controllers [HttpPost("/Sessions/{sessionId}/Playing/{command}")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult SendPlaystateCommand( - [FromRoute] string sessionId, + [FromRoute] string? sessionId, [FromBody] PlaystateRequest playstateRequest) { _sessionManager.SendPlaystateCommand( @@ -213,8 +213,8 @@ namespace Jellyfin.Api.Controllers [HttpPost("/Sessions/{sessionId}/System/{command}")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult SendSystemCommand( - [FromRoute] string sessionId, - [FromRoute] string command) + [FromRoute] string? sessionId, + [FromRoute] string? command) { var name = command; if (Enum.TryParse(name, true, out GeneralCommandType commandType)) @@ -244,8 +244,8 @@ namespace Jellyfin.Api.Controllers [HttpPost("/Sessions/{sessionId}/Command/{Command}")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult SendGeneralCommand( - [FromRoute] string sessionId, - [FromRoute] string command) + [FromRoute] string? sessionId, + [FromRoute] string? command) { var currentSession = RequestHelpers.GetSession(_sessionManager, _authContext, Request); @@ -270,7 +270,7 @@ namespace Jellyfin.Api.Controllers [HttpPost("/Sessions/{sessionId}/Command")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult SendFullGeneralCommand( - [FromRoute] string sessionId, + [FromRoute] string? sessionId, [FromBody, Required] GeneralCommand command) { var currentSession = RequestHelpers.GetSession(_sessionManager, _authContext, Request); @@ -303,9 +303,9 @@ namespace Jellyfin.Api.Controllers [HttpPost("/Sessions/{sessionId}/Message")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult SendMessageCommand( - [FromRoute] string sessionId, - [FromQuery] string text, - [FromQuery] string header, + [FromRoute] string? sessionId, + [FromQuery] string? text, + [FromQuery] string? header, [FromQuery] long? timeoutMs) { var command = new MessageCommand @@ -330,7 +330,7 @@ namespace Jellyfin.Api.Controllers [HttpPost("/Sessions/{sessionId}/User/{userId}")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult AddUserToSession( - [FromRoute] string sessionId, + [FromRoute] string? sessionId, [FromRoute] Guid userId) { _sessionManager.AddAdditionalUser(sessionId, userId); @@ -347,7 +347,7 @@ namespace Jellyfin.Api.Controllers [HttpDelete("/Sessions/{sessionId}/User/{userId}")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult RemoveUserFromSession( - [FromRoute] string sessionId, + [FromRoute] string? sessionId, [FromRoute] Guid userId) { _sessionManager.RemoveAdditionalUser(sessionId, userId); @@ -368,9 +368,9 @@ namespace Jellyfin.Api.Controllers [HttpPost("/Sessions/Capabilities")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult PostCapabilities( - [FromQuery] string id, - [FromQuery] string playableMediaTypes, - [FromQuery] string supportedCommands, + [FromQuery] string? id, + [FromQuery] string? playableMediaTypes, + [FromQuery] string? supportedCommands, [FromQuery] bool supportsMediaControl, [FromQuery] bool supportsSync, [FromQuery] bool supportsPersistentIdentifier = true) @@ -401,7 +401,7 @@ namespace Jellyfin.Api.Controllers [HttpPost("/Sessions/Capabilities/Full")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult PostFullCapabilities( - [FromQuery] string id, + [FromQuery] string? id, [FromBody, Required] ClientCapabilities capabilities) { if (string.IsNullOrWhiteSpace(id)) @@ -424,8 +424,8 @@ namespace Jellyfin.Api.Controllers [HttpPost("/Sessions/Viewing")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult ReportViewing( - [FromQuery] string sessionId, - [FromQuery] string itemId) + [FromQuery] string? sessionId, + [FromQuery] string? itemId) { string session = RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id; diff --git a/Jellyfin.Api/Controllers/StartupController.cs b/Jellyfin.Api/Controllers/StartupController.cs index d96b0f993..cc1f797b1 100644 --- a/Jellyfin.Api/Controllers/StartupController.cs +++ b/Jellyfin.Api/Controllers/StartupController.cs @@ -75,9 +75,9 @@ namespace Jellyfin.Api.Controllers [HttpPost("Configuration")] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult UpdateInitialConfiguration( - [FromForm] string uiCulture, - [FromForm] string metadataCountryCode, - [FromForm] string preferredMetadataLanguage) + [FromForm] string? uiCulture, + [FromForm] string? metadataCountryCode, + [FromForm] string? preferredMetadataLanguage) { _config.Configuration.UICulture = uiCulture; _config.Configuration.MetadataCountryCode = metadataCountryCode; diff --git a/Jellyfin.Api/Controllers/SubtitleController.cs b/Jellyfin.Api/Controllers/SubtitleController.cs index 95cc39524..baedafaa6 100644 --- a/Jellyfin.Api/Controllers/SubtitleController.cs +++ b/Jellyfin.Api/Controllers/SubtitleController.cs @@ -112,7 +112,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public async Task>> SearchRemoteSubtitles( [FromRoute] Guid itemId, - [FromRoute] string language, + [FromRoute] string? language, [FromQuery] bool? isPerfectMatch) { var video = (Video)_libraryManager.GetItemById(itemId); @@ -132,7 +132,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status204NoContent)] public async Task DownloadRemoteSubtitles( [FromRoute] Guid itemId, - [FromRoute] string subtitleId) + [FromRoute] string? subtitleId) { var video = (Video)_libraryManager.GetItemById(itemId); @@ -161,7 +161,7 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] [Produces(MediaTypeNames.Application.Octet)] - public async Task GetRemoteSubtitles([FromRoute] string id) + public async Task GetRemoteSubtitles([FromRoute] string? id) { var result = await _subtitleManager.GetRemoteSubtitles(id, CancellationToken.None).ConfigureAwait(false); @@ -186,9 +186,9 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public async Task GetSubtitle( [FromRoute, Required] Guid itemId, - [FromRoute, Required] string mediaSourceId, + [FromRoute, Required] string? mediaSourceId, [FromRoute, Required] int index, - [FromRoute, Required] string format, + [FromRoute, Required] string? format, [FromQuery] long? endPositionTicks, [FromQuery] bool copyTimestamps, [FromQuery] bool addVttTimeMap, @@ -254,7 +254,7 @@ namespace Jellyfin.Api.Controllers public async Task GetSubtitlePlaylist( [FromRoute] Guid itemId, [FromRoute] int index, - [FromRoute] string mediaSourceId, + [FromRoute] string? mediaSourceId, [FromQuery, Required] int segmentLength) { var item = (Video)_libraryManager.GetItemById(itemId); @@ -324,7 +324,7 @@ namespace Jellyfin.Api.Controllers /// A with the new subtitle file. private Task EncodeSubtitles( Guid id, - string mediaSourceId, + string? mediaSourceId, int index, string format, long startPositionTicks, diff --git a/Jellyfin.Api/Controllers/SystemController.cs b/Jellyfin.Api/Controllers/SystemController.cs index e33821b24..bc606f7aa 100644 --- a/Jellyfin.Api/Controllers/SystemController.cs +++ b/Jellyfin.Api/Controllers/SystemController.cs @@ -193,7 +193,7 @@ namespace Jellyfin.Api.Controllers [HttpGet("Logs/Log")] [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult GetLogFile([FromQuery, Required] string name) + public ActionResult GetLogFile([FromQuery, Required] string? name) { var file = _fileSystem.GetFiles(_appPaths.LogDirectoryPath) .First(i => string.Equals(i.Name, name, StringComparison.OrdinalIgnoreCase)); diff --git a/Jellyfin.Api/Controllers/TvShowsController.cs b/Jellyfin.Api/Controllers/TvShowsController.cs index 6738dd8c8..80b6a2488 100644 --- a/Jellyfin.Api/Controllers/TvShowsController.cs +++ b/Jellyfin.Api/Controllers/TvShowsController.cs @@ -190,7 +190,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult> GetEpisodes( - [FromRoute] string seriesId, + [FromRoute] string? seriesId, [FromQuery] Guid userId, [FromQuery] string? fields, [FromQuery] int? season, @@ -311,12 +311,12 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult> GetSeasons( - [FromRoute] string seriesId, + [FromRoute] string? seriesId, [FromQuery] Guid userId, - [FromQuery] string fields, + [FromQuery] string? fields, [FromQuery] bool? isSpecialSeason, [FromQuery] bool? isMissing, - [FromQuery] string adjacentTo, + [FromQuery] string? adjacentTo, [FromQuery] bool? enableImages, [FromQuery] int? imageTypeLimit, [FromQuery] string? enableImageTypes, diff --git a/Jellyfin.Api/Controllers/UserController.cs b/Jellyfin.Api/Controllers/UserController.cs index 9f8d564a7..24194dcc2 100644 --- a/Jellyfin.Api/Controllers/UserController.cs +++ b/Jellyfin.Api/Controllers/UserController.cs @@ -164,8 +164,8 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> AuthenticateUser( [FromRoute, Required] Guid userId, - [FromQuery, BindRequired] string pw, - [FromQuery, BindRequired] string password) + [FromQuery, BindRequired] string? pw, + [FromQuery, BindRequired] string? password) { var user = _userManager.GetUserById(userId); @@ -483,7 +483,7 @@ namespace Jellyfin.Api.Controllers /// A containing a . [HttpPost("ForgotPassword")] [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> ForgotPassword([FromBody] string enteredUsername) + public async Task> ForgotPassword([FromBody] string? enteredUsername) { var isLocal = HttpContext.Connection.RemoteIpAddress.Equals(HttpContext.Connection.LocalIpAddress) || _networkManager.IsInLocalNetwork(HttpContext.Connection.RemoteIpAddress.ToString()); @@ -501,7 +501,7 @@ namespace Jellyfin.Api.Controllers /// A containing a . [HttpPost("ForgotPassword/Pin")] [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> ForgotPasswordPin([FromBody] string pin) + public async Task> ForgotPasswordPin([FromBody] string? pin) { var result = await _userManager.RedeemPasswordResetPin(pin).ConfigureAwait(false); return result; diff --git a/Jellyfin.Api/Controllers/UserLibraryController.cs b/Jellyfin.Api/Controllers/UserLibraryController.cs index 597e70469..ca804ebc9 100644 --- a/Jellyfin.Api/Controllers/UserLibraryController.cs +++ b/Jellyfin.Api/Controllers/UserLibraryController.cs @@ -265,12 +265,12 @@ namespace Jellyfin.Api.Controllers public ActionResult> GetLatestMedia( [FromRoute] Guid userId, [FromQuery] Guid parentId, - [FromQuery] string fields, - [FromQuery] string includeItemTypes, + [FromQuery] string? fields, + [FromQuery] string? includeItemTypes, [FromQuery] bool? isPlayed, [FromQuery] bool? enableImages, [FromQuery] int? imageTypeLimit, - [FromQuery] string enableImageTypes, + [FromQuery] string? enableImageTypes, [FromQuery] bool? enableUserData, [FromQuery] int limit = 20, [FromQuery] bool groupItems = true) diff --git a/Jellyfin.Api/Controllers/UserViewsController.cs b/Jellyfin.Api/Controllers/UserViewsController.cs index 38bf94087..ad8927262 100644 --- a/Jellyfin.Api/Controllers/UserViewsController.cs +++ b/Jellyfin.Api/Controllers/UserViewsController.cs @@ -66,7 +66,7 @@ namespace Jellyfin.Api.Controllers [FromRoute] Guid userId, [FromQuery] bool? includeExternalContent, [FromQuery] bool includeHidden, - [FromQuery] string presetViews) + [FromQuery] string? presetViews) { var query = new UserViewQuery { diff --git a/Jellyfin.Api/Controllers/VideoAttachmentsController.cs b/Jellyfin.Api/Controllers/VideoAttachmentsController.cs index 943ba8af3..eef0a93cd 100644 --- a/Jellyfin.Api/Controllers/VideoAttachmentsController.cs +++ b/Jellyfin.Api/Controllers/VideoAttachmentsController.cs @@ -50,7 +50,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> GetAttachment( [FromRoute] Guid videoId, - [FromRoute] string mediaSourceId, + [FromRoute] string? mediaSourceId, [FromRoute] int index) { try diff --git a/Jellyfin.Api/Controllers/VideosController.cs b/Jellyfin.Api/Controllers/VideosController.cs index effe630a9..fb1141984 100644 --- a/Jellyfin.Api/Controllers/VideosController.cs +++ b/Jellyfin.Api/Controllers/VideosController.cs @@ -133,7 +133,7 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status400BadRequest)] - public ActionResult MergeVersions([FromQuery] string itemIds) + public ActionResult MergeVersions([FromQuery] string? itemIds) { var items = RequestHelpers.Split(itemIds, ',', true) .Select(i => _libraryManager.GetItemById(i)) diff --git a/Jellyfin.Api/Controllers/YearsController.cs b/Jellyfin.Api/Controllers/YearsController.cs index a036c818c..a66a3951e 100644 --- a/Jellyfin.Api/Controllers/YearsController.cs +++ b/Jellyfin.Api/Controllers/YearsController.cs @@ -64,16 +64,16 @@ namespace Jellyfin.Api.Controllers public ActionResult> GetYears( [FromQuery] int? startIndex, [FromQuery] int? limit, - [FromQuery] string sortOrder, - [FromQuery] string parentId, - [FromQuery] string fields, - [FromQuery] string excludeItemTypes, - [FromQuery] string includeItemTypes, - [FromQuery] string mediaTypes, - [FromQuery] string sortBy, + [FromQuery] string? sortOrder, + [FromQuery] string? parentId, + [FromQuery] string? fields, + [FromQuery] string? excludeItemTypes, + [FromQuery] string? includeItemTypes, + [FromQuery] string? mediaTypes, + [FromQuery] string? sortBy, [FromQuery] bool? enableUserData, [FromQuery] int? imageTypeLimit, - [FromQuery] string enableImageTypes, + [FromQuery] string? enableImageTypes, [FromQuery] Guid userId, [FromQuery] bool recursive = true, [FromQuery] bool? enableImages = true) diff --git a/Jellyfin.Api/Extensions/DtoExtensions.cs b/Jellyfin.Api/Extensions/DtoExtensions.cs index ac248109d..e61e9c29d 100644 --- a/Jellyfin.Api/Extensions/DtoExtensions.cs +++ b/Jellyfin.Api/Extensions/DtoExtensions.cs @@ -23,7 +23,7 @@ namespace Jellyfin.Api.Extensions /// DtoOptions object. /// Comma delimited string of fields. /// Modified DtoOptions object. - internal static DtoOptions AddItemFields(this DtoOptions dtoOptions, string fields) + internal static DtoOptions AddItemFields(this DtoOptions dtoOptions, string? fields) { if (string.IsNullOrEmpty(fields)) { @@ -126,7 +126,7 @@ namespace Jellyfin.Api.Extensions bool? enableImages, bool? enableUserData, int? imageTypeLimit, - string enableImageTypes) + string? enableImageTypes) { dtoOptions.EnableImages = enableImages ?? true; diff --git a/Jellyfin.Api/Helpers/RequestHelpers.cs b/Jellyfin.Api/Helpers/RequestHelpers.cs index a8ba98f1f..fd86feb8b 100644 --- a/Jellyfin.Api/Helpers/RequestHelpers.cs +++ b/Jellyfin.Api/Helpers/RequestHelpers.cs @@ -20,7 +20,7 @@ namespace Jellyfin.Api.Helpers /// The char that separates the substrings. /// Option to remove empty substrings from the array. /// An array of the substrings. - internal static string[] Split(string value, char separator, bool removeEmpty) + internal static string[] Split(string? value, char separator, bool removeEmpty) { if (string.IsNullOrWhiteSpace(value)) { @@ -99,16 +99,14 @@ namespace Jellyfin.Api.Helpers /// Sort by. /// Sort order. /// Resulting order by. - internal static ValueTuple[] GetOrderBy(string sortBy, string requestedSortOrder) + internal static ValueTuple[] GetOrderBy(string? sortBy, string? requestedSortOrder) { - var val = sortBy; - - if (string.IsNullOrEmpty(val)) + if (string.IsNullOrEmpty(sortBy)) { return Array.Empty>(); } - var vals = val.Split(','); + var vals = sortBy.Split(','); if (string.IsNullOrWhiteSpace(requestedSortOrder)) { requestedSortOrder = "Ascending"; diff --git a/Jellyfin.Api/Helpers/SimilarItemsHelper.cs b/Jellyfin.Api/Helpers/SimilarItemsHelper.cs index 751e3c481..fd0c31504 100644 --- a/Jellyfin.Api/Helpers/SimilarItemsHelper.cs +++ b/Jellyfin.Api/Helpers/SimilarItemsHelper.cs @@ -23,7 +23,7 @@ namespace Jellyfin.Api.Helpers IDtoService dtoService, Guid userId, string id, - string excludeArtistIds, + string? excludeArtistIds, int? limit, Type[] includeTypes, Func, List, BaseItem, int> getSimilarityScore) -- cgit v1.2.3 From 5d34b07d1ff7239c7961381fc71559d377e7a96b Mon Sep 17 00:00:00 2001 From: crobibero Date: Tue, 7 Jul 2020 09:10:51 -0600 Subject: Make query parameters nullable or set default value --- Jellyfin.Api/Auth/BaseAuthorizationHandler.cs | 2 +- Jellyfin.Api/Controllers/AlbumsController.cs | 4 +- Jellyfin.Api/Controllers/ArtistsController.cs | 102 +++++++------- Jellyfin.Api/Controllers/ChannelsController.cs | 22 +-- Jellyfin.Api/Controllers/CollectionController.cs | 6 +- Jellyfin.Api/Controllers/FilterController.cs | 12 +- Jellyfin.Api/Controllers/GenresController.cs | 54 +++---- Jellyfin.Api/Controllers/InstantMixController.cs | 44 ++++-- Jellyfin.Api/Controllers/ItemsController.cs | 10 +- Jellyfin.Api/Controllers/LibraryController.cs | 56 ++++---- .../Controllers/LibraryStructureController.cs | 20 +-- Jellyfin.Api/Controllers/LiveTvController.cs | 156 +++++++++++---------- Jellyfin.Api/Controllers/MediaInfoController.cs | 40 +++--- Jellyfin.Api/Controllers/MoviesController.cs | 26 ++-- Jellyfin.Api/Controllers/MusicGenresController.cs | 54 +++---- Jellyfin.Api/Controllers/PersonsController.cs | 54 +++---- Jellyfin.Api/Controllers/PlaylistsController.cs | 4 +- Jellyfin.Api/Controllers/PlaystateController.cs | 32 ++--- Jellyfin.Api/Controllers/RemoteImageController.cs | 2 +- Jellyfin.Api/Controllers/SearchController.cs | 4 +- Jellyfin.Api/Controllers/SessionController.cs | 12 +- Jellyfin.Api/Controllers/StudiosController.cs | 54 +++---- Jellyfin.Api/Controllers/SubtitleController.cs | 4 +- Jellyfin.Api/Controllers/SuggestionsController.cs | 6 +- Jellyfin.Api/Controllers/TrailersController.cs | 2 +- Jellyfin.Api/Controllers/TvShowsController.cs | 26 ++-- Jellyfin.Api/Controllers/UserLibraryController.cs | 6 +- Jellyfin.Api/Controllers/UserViewsController.cs | 6 +- Jellyfin.Api/Controllers/VideosController.cs | 6 +- Jellyfin.Api/Controllers/YearsController.cs | 12 +- Jellyfin.Api/Helpers/SimilarItemsHelper.cs | 12 +- 31 files changed, 442 insertions(+), 408 deletions(-) (limited to 'Jellyfin.Api/Controllers/PlaylistsController.cs') diff --git a/Jellyfin.Api/Auth/BaseAuthorizationHandler.cs b/Jellyfin.Api/Auth/BaseAuthorizationHandler.cs index 50b6468db..9fde175d0 100644 --- a/Jellyfin.Api/Auth/BaseAuthorizationHandler.cs +++ b/Jellyfin.Api/Auth/BaseAuthorizationHandler.cs @@ -52,7 +52,7 @@ namespace Jellyfin.Api.Auth { // Ensure claim has userId. var userId = ClaimHelpers.GetUserId(claimsPrincipal); - if (userId == null) + if (!userId.HasValue) { return false; } diff --git a/Jellyfin.Api/Controllers/AlbumsController.cs b/Jellyfin.Api/Controllers/AlbumsController.cs index 70315b0a3..01ba7fc32 100644 --- a/Jellyfin.Api/Controllers/AlbumsController.cs +++ b/Jellyfin.Api/Controllers/AlbumsController.cs @@ -52,7 +52,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetSimilarAlbums( [FromRoute] string albumId, - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] string? excludeArtistIds, [FromQuery] int? limit) { @@ -84,7 +84,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetSimilarArtists( [FromRoute] string artistId, - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] string? excludeArtistIds, [FromQuery] int? limit) { diff --git a/Jellyfin.Api/Controllers/ArtistsController.cs b/Jellyfin.Api/Controllers/ArtistsController.cs index 6b2084170..d39021446 100644 --- a/Jellyfin.Api/Controllers/ArtistsController.cs +++ b/Jellyfin.Api/Controllers/ArtistsController.cs @@ -83,31 +83,31 @@ namespace Jellyfin.Api.Controllers [FromQuery] double? minCommunityRating, [FromQuery] int? startIndex, [FromQuery] int? limit, - [FromQuery] string searchTerm, - [FromQuery] string parentId, - [FromQuery] string fields, - [FromQuery] string excludeItemTypes, - [FromQuery] string includeItemTypes, - [FromQuery] string filters, + [FromQuery] string? searchTerm, + [FromQuery] string? parentId, + [FromQuery] string? fields, + [FromQuery] string? excludeItemTypes, + [FromQuery] string? includeItemTypes, + [FromQuery] string? filters, [FromQuery] bool? isFavorite, - [FromQuery] string mediaTypes, - [FromQuery] string genres, - [FromQuery] string genreIds, - [FromQuery] string officialRatings, - [FromQuery] string tags, - [FromQuery] string years, + [FromQuery] string? mediaTypes, + [FromQuery] string? genres, + [FromQuery] string? genreIds, + [FromQuery] string? officialRatings, + [FromQuery] string? tags, + [FromQuery] string? years, [FromQuery] bool? enableUserData, [FromQuery] int? imageTypeLimit, - [FromQuery] string enableImageTypes, - [FromQuery] string person, - [FromQuery] string personIds, - [FromQuery] string personTypes, - [FromQuery] string studios, - [FromQuery] string studioIds, - [FromQuery] Guid userId, - [FromQuery] string nameStartsWithOrGreater, - [FromQuery] string nameStartsWith, - [FromQuery] string nameLessThan, + [FromQuery] string? enableImageTypes, + [FromQuery] string? person, + [FromQuery] string? personIds, + [FromQuery] string? personTypes, + [FromQuery] string? studios, + [FromQuery] string? studioIds, + [FromQuery] Guid? userId, + [FromQuery] string? nameStartsWithOrGreater, + [FromQuery] string? nameStartsWith, + [FromQuery] string? nameLessThan, [FromQuery] bool? enableImages = true, [FromQuery] bool enableTotalRecordCount = true) { @@ -119,9 +119,9 @@ namespace Jellyfin.Api.Controllers User? user = null; BaseItem parentItem; - if (!userId.Equals(Guid.Empty)) + if (userId.HasValue && !userId.Equals(Guid.Empty)) { - user = _userManager.GetUserById(userId); + user = _userManager.GetUserById(userId.Value); parentItem = string.IsNullOrEmpty(parentId) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(parentId); } else @@ -292,31 +292,31 @@ namespace Jellyfin.Api.Controllers [FromQuery] double? minCommunityRating, [FromQuery] int? startIndex, [FromQuery] int? limit, - [FromQuery] string searchTerm, - [FromQuery] string parentId, - [FromQuery] string fields, - [FromQuery] string excludeItemTypes, - [FromQuery] string includeItemTypes, - [FromQuery] string filters, + [FromQuery] string? searchTerm, + [FromQuery] string? parentId, + [FromQuery] string? fields, + [FromQuery] string? excludeItemTypes, + [FromQuery] string? includeItemTypes, + [FromQuery] string? filters, [FromQuery] bool? isFavorite, - [FromQuery] string mediaTypes, - [FromQuery] string genres, - [FromQuery] string genreIds, - [FromQuery] string officialRatings, - [FromQuery] string tags, - [FromQuery] string years, + [FromQuery] string? mediaTypes, + [FromQuery] string? genres, + [FromQuery] string? genreIds, + [FromQuery] string? officialRatings, + [FromQuery] string? tags, + [FromQuery] string? years, [FromQuery] bool? enableUserData, [FromQuery] int? imageTypeLimit, - [FromQuery] string enableImageTypes, - [FromQuery] string person, - [FromQuery] string personIds, - [FromQuery] string personTypes, - [FromQuery] string studios, - [FromQuery] string studioIds, - [FromQuery] Guid userId, - [FromQuery] string nameStartsWithOrGreater, - [FromQuery] string nameStartsWith, - [FromQuery] string nameLessThan, + [FromQuery] string? enableImageTypes, + [FromQuery] string? person, + [FromQuery] string? personIds, + [FromQuery] string? personTypes, + [FromQuery] string? studios, + [FromQuery] string? studioIds, + [FromQuery] Guid? userId, + [FromQuery] string? nameStartsWithOrGreater, + [FromQuery] string? nameStartsWith, + [FromQuery] string? nameLessThan, [FromQuery] bool? enableImages = true, [FromQuery] bool enableTotalRecordCount = true) { @@ -328,9 +328,9 @@ namespace Jellyfin.Api.Controllers User? user = null; BaseItem parentItem; - if (!userId.Equals(Guid.Empty)) + if (userId.HasValue && !userId.Equals(Guid.Empty)) { - user = _userManager.GetUserById(userId); + user = _userManager.GetUserById(userId.Value); parentItem = string.IsNullOrEmpty(parentId) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(parentId); } else @@ -469,15 +469,15 @@ namespace Jellyfin.Api.Controllers /// An containing the artist. [HttpGet("{name}")] [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult GetArtistByName([FromRoute] string name, [FromQuery] Guid userId) + public ActionResult GetArtistByName([FromRoute] string name, [FromQuery] Guid? userId) { var dtoOptions = new DtoOptions().AddClientFields(Request); var item = _libraryManager.GetArtist(name, dtoOptions); - if (!userId.Equals(Guid.Empty)) + if (userId.HasValue && !userId.Equals(Guid.Empty)) { - var user = _userManager.GetUserById(userId); + var user = _userManager.GetUserById(userId.Value); return _dtoService.GetBaseItemDto(item, dtoOptions, user); } diff --git a/Jellyfin.Api/Controllers/ChannelsController.cs b/Jellyfin.Api/Controllers/ChannelsController.cs index a293a78a0..bdd7dfd96 100644 --- a/Jellyfin.Api/Controllers/ChannelsController.cs +++ b/Jellyfin.Api/Controllers/ChannelsController.cs @@ -53,7 +53,7 @@ namespace Jellyfin.Api.Controllers [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetChannels( - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] int? startIndex, [FromQuery] int? limit, [FromQuery] bool? supportsLatestItems, @@ -64,7 +64,7 @@ namespace Jellyfin.Api.Controllers { Limit = limit, StartIndex = startIndex, - UserId = userId, + UserId = userId ?? Guid.Empty, SupportsLatestItems = supportsLatestItems, SupportsMediaDeletion = supportsMediaDeletion, IsFavorite = isFavorite @@ -124,9 +124,9 @@ namespace Jellyfin.Api.Controllers [FromQuery] string? sortBy, [FromQuery] string? fields) { - var user = userId == null - ? null - : _userManager.GetUserById(userId.Value); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var query = new InternalItemsQuery(user) { @@ -195,13 +195,13 @@ namespace Jellyfin.Api.Controllers [FromQuery] Guid? userId, [FromQuery] int? startIndex, [FromQuery] int? limit, - [FromQuery] string filters, - [FromQuery] string fields, - [FromQuery] string channelIds) + [FromQuery] string? filters, + [FromQuery] string? fields, + [FromQuery] string? channelIds) { - var user = userId == null || userId == Guid.Empty - ? null - : _userManager.GetUserById(userId.Value); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var query = new InternalItemsQuery(user) { diff --git a/Jellyfin.Api/Controllers/CollectionController.cs b/Jellyfin.Api/Controllers/CollectionController.cs index 7ff98b251..6f78a7d84 100644 --- a/Jellyfin.Api/Controllers/CollectionController.cs +++ b/Jellyfin.Api/Controllers/CollectionController.cs @@ -44,8 +44,8 @@ namespace Jellyfin.Api.Controllers /// /// The name of the collection. /// Item Ids to add to the collection. - /// Whether or not to lock the new collection. /// Optional. Create the collection within a specific folder. + /// Whether or not to lock the new collection. /// Collection created. /// A with information about the new collection. [HttpPost] @@ -53,8 +53,8 @@ namespace Jellyfin.Api.Controllers public ActionResult CreateCollection( [FromQuery] string? name, [FromQuery] string? ids, - [FromQuery] bool isLocked, - [FromQuery] Guid? parentId) + [FromQuery] Guid? parentId, + [FromQuery] bool isLocked = false) { var userId = _authContext.GetAuthorizationInfo(Request).UserId; diff --git a/Jellyfin.Api/Controllers/FilterController.cs b/Jellyfin.Api/Controllers/FilterController.cs index 8a0a6ad86..288d4c545 100644 --- a/Jellyfin.Api/Controllers/FilterController.cs +++ b/Jellyfin.Api/Controllers/FilterController.cs @@ -57,9 +57,9 @@ namespace Jellyfin.Api.Controllers ? null : _libraryManager.GetItemById(parentId); - var user = userId == null || userId == Guid.Empty - ? null - : _userManager.GetUserById(userId.Value); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; if (string.Equals(includeItemTypes, nameof(BoxSet), StringComparison.OrdinalIgnoreCase) || string.Equals(includeItemTypes, nameof(Playlist), StringComparison.OrdinalIgnoreCase) @@ -152,9 +152,9 @@ namespace Jellyfin.Api.Controllers ? null : _libraryManager.GetItemById(parentId); - var user = userId == null || userId == Guid.Empty - ? null - : _userManager.GetUserById(userId.Value); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; if (string.Equals(includeItemTypes, nameof(BoxSet), StringComparison.OrdinalIgnoreCase) || string.Equals(includeItemTypes, nameof(Playlist), StringComparison.OrdinalIgnoreCase) diff --git a/Jellyfin.Api/Controllers/GenresController.cs b/Jellyfin.Api/Controllers/GenresController.cs index d57989a8a..55ad71200 100644 --- a/Jellyfin.Api/Controllers/GenresController.cs +++ b/Jellyfin.Api/Controllers/GenresController.cs @@ -84,31 +84,31 @@ namespace Jellyfin.Api.Controllers [FromQuery] double? minCommunityRating, [FromQuery] int? startIndex, [FromQuery] int? limit, - [FromQuery] string searchTerm, - [FromQuery] string parentId, - [FromQuery] string fields, - [FromQuery] string excludeItemTypes, - [FromQuery] string includeItemTypes, - [FromQuery] string filters, + [FromQuery] string? searchTerm, + [FromQuery] string? parentId, + [FromQuery] string? fields, + [FromQuery] string? excludeItemTypes, + [FromQuery] string? includeItemTypes, + [FromQuery] string? filters, [FromQuery] bool? isFavorite, - [FromQuery] string mediaTypes, - [FromQuery] string genres, - [FromQuery] string genreIds, - [FromQuery] string officialRatings, - [FromQuery] string tags, - [FromQuery] string years, + [FromQuery] string? mediaTypes, + [FromQuery] string? genres, + [FromQuery] string? genreIds, + [FromQuery] string? officialRatings, + [FromQuery] string? tags, + [FromQuery] string? years, [FromQuery] bool? enableUserData, [FromQuery] int? imageTypeLimit, - [FromQuery] string enableImageTypes, - [FromQuery] string person, - [FromQuery] string personIds, - [FromQuery] string personTypes, - [FromQuery] string studios, - [FromQuery] string studioIds, - [FromQuery] Guid userId, - [FromQuery] string nameStartsWithOrGreater, - [FromQuery] string nameStartsWith, - [FromQuery] string nameLessThan, + [FromQuery] string? enableImageTypes, + [FromQuery] string? person, + [FromQuery] string? personIds, + [FromQuery] string? personTypes, + [FromQuery] string? studios, + [FromQuery] string? studioIds, + [FromQuery] Guid? userId, + [FromQuery] string? nameStartsWithOrGreater, + [FromQuery] string? nameStartsWith, + [FromQuery] string? nameLessThan, [FromQuery] bool? enableImages = true, [FromQuery] bool enableTotalRecordCount = true) { @@ -120,9 +120,9 @@ namespace Jellyfin.Api.Controllers User? user = null; BaseItem parentItem; - if (!userId.Equals(Guid.Empty)) + if (userId.HasValue && !userId.Equals(Guid.Empty)) { - user = _userManager.GetUserById(userId); + user = _userManager.GetUserById(userId.Value); parentItem = string.IsNullOrEmpty(parentId) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(parentId); } else @@ -260,7 +260,7 @@ namespace Jellyfin.Api.Controllers /// An containing the genre. [HttpGet("{genreName}")] [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult GetGenre([FromRoute] string genreName, [FromQuery] Guid userId) + public ActionResult GetGenre([FromRoute] string genreName, [FromQuery] Guid? userId) { var dtoOptions = new DtoOptions() .AddClientFields(Request); @@ -280,9 +280,9 @@ namespace Jellyfin.Api.Controllers item = _libraryManager.GetGenre(genreName); } - if (!userId.Equals(Guid.Empty)) + if (userId.HasValue && !userId.Equals(Guid.Empty)) { - var user = _userManager.GetUserById(userId); + var user = _userManager.GetUserById(userId.Value); return _dtoService.GetBaseItemDto(item, dtoOptions, user); } diff --git a/Jellyfin.Api/Controllers/InstantMixController.cs b/Jellyfin.Api/Controllers/InstantMixController.cs index 9d945fe2b..bb980af3e 100644 --- a/Jellyfin.Api/Controllers/InstantMixController.cs +++ b/Jellyfin.Api/Controllers/InstantMixController.cs @@ -63,7 +63,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetInstantMixFromSong( [FromRoute] Guid id, - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] int? limit, [FromQuery] string? fields, [FromQuery] bool? enableImages, @@ -72,7 +72,9 @@ namespace Jellyfin.Api.Controllers [FromQuery] string? enableImageTypes) { var item = _libraryManager.GetItemById(id); - var user = _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var dtoOptions = new DtoOptions() .AddItemFields(fields) .AddClientFields(Request) @@ -98,7 +100,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetInstantMixFromAlbum( [FromRoute] Guid id, - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] int? limit, [FromQuery] string? fields, [FromQuery] bool? enableImages, @@ -107,7 +109,9 @@ namespace Jellyfin.Api.Controllers [FromQuery] string? enableImageTypes) { var album = _libraryManager.GetItemById(id); - var user = _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var dtoOptions = new DtoOptions() .AddItemFields(fields) .AddClientFields(Request) @@ -133,7 +137,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetInstantMixFromPlaylist( [FromRoute] Guid id, - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] int? limit, [FromQuery] string? fields, [FromQuery] bool? enableImages, @@ -142,7 +146,9 @@ namespace Jellyfin.Api.Controllers [FromQuery] string? enableImageTypes) { var playlist = (Playlist)_libraryManager.GetItemById(id); - var user = _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var dtoOptions = new DtoOptions() .AddItemFields(fields) .AddClientFields(Request) @@ -168,7 +174,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetInstantMixFromMusicGenre( [FromRoute] string? name, - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] int? limit, [FromQuery] string? fields, [FromQuery] bool? enableImages, @@ -176,7 +182,9 @@ namespace Jellyfin.Api.Controllers [FromQuery] int? imageTypeLimit, [FromQuery] string? enableImageTypes) { - var user = _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var dtoOptions = new DtoOptions() .AddItemFields(fields) .AddClientFields(Request) @@ -202,7 +210,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetInstantMixFromArtists( [FromRoute] Guid id, - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] int? limit, [FromQuery] string? fields, [FromQuery] bool? enableImages, @@ -211,7 +219,9 @@ namespace Jellyfin.Api.Controllers [FromQuery] string? enableImageTypes) { var item = _libraryManager.GetItemById(id); - var user = _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var dtoOptions = new DtoOptions() .AddItemFields(fields) .AddClientFields(Request) @@ -237,7 +247,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetInstantMixFromMusicGenres( [FromRoute] Guid id, - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] int? limit, [FromQuery] string? fields, [FromQuery] bool? enableImages, @@ -246,7 +256,9 @@ namespace Jellyfin.Api.Controllers [FromQuery] string? enableImageTypes) { var item = _libraryManager.GetItemById(id); - var user = _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var dtoOptions = new DtoOptions() .AddItemFields(fields) .AddClientFields(Request) @@ -272,7 +284,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetInstantMixFromItem( [FromRoute] Guid id, - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] int? limit, [FromQuery] string? fields, [FromQuery] bool? enableImages, @@ -281,7 +293,9 @@ namespace Jellyfin.Api.Controllers [FromQuery] string? enableImageTypes) { var item = _libraryManager.GetItemById(id); - var user = _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var dtoOptions = new DtoOptions() .AddItemFields(fields) .AddClientFields(Request) @@ -290,7 +304,7 @@ namespace Jellyfin.Api.Controllers return GetResult(items, user, limit, dtoOptions); } - private QueryResult GetResult(List items, User user, int? limit, DtoOptions dtoOptions) + private QueryResult GetResult(List items, User? user, int? limit, DtoOptions dtoOptions) { var list = items; diff --git a/Jellyfin.Api/Controllers/ItemsController.cs b/Jellyfin.Api/Controllers/ItemsController.cs index e1dd4af10..41fe47db1 100644 --- a/Jellyfin.Api/Controllers/ItemsController.cs +++ b/Jellyfin.Api/Controllers/ItemsController.cs @@ -143,8 +143,8 @@ namespace Jellyfin.Api.Controllers [HttpGet("/Users/{uId}/Items")] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetItems( - [FromRoute] Guid uId, - [FromQuery] Guid userId, + [FromRoute] Guid? uId, + [FromQuery] Guid? userId, [FromQuery] string? maxOfficialRating, [FromQuery] bool? hasThemeSong, [FromQuery] bool? hasThemeVideo, @@ -226,9 +226,11 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? enableImages = true) { // use user id route parameter over query parameter - userId = (uId != null) ? uId : userId; + userId = uId ?? userId; - var user = userId.Equals(Guid.Empty) ? null : _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var dtoOptions = new DtoOptions() .AddItemFields(fields) .AddClientFields(Request) diff --git a/Jellyfin.Api/Controllers/LibraryController.cs b/Jellyfin.Api/Controllers/LibraryController.cs index f1106cda6..2466b2ac8 100644 --- a/Jellyfin.Api/Controllers/LibraryController.cs +++ b/Jellyfin.Api/Controllers/LibraryController.cs @@ -146,11 +146,11 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult GetThemeSongs( [FromRoute] Guid itemId, - [FromQuery] Guid userId, - [FromQuery] bool inheritFromParent) + [FromQuery] Guid? userId, + [FromQuery] bool inheritFromParent = false) { - var user = !userId.Equals(Guid.Empty) - ? _userManager.GetUserById(userId) + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) : null; var item = itemId.Equals(Guid.Empty) @@ -212,11 +212,11 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult GetThemeVideos( [FromRoute] Guid itemId, - [FromQuery] Guid userId, - [FromQuery] bool inheritFromParent) + [FromQuery] Guid? userId, + [FromQuery] bool inheritFromParent = false) { - var user = !userId.Equals(Guid.Empty) - ? _userManager.GetUserById(userId) + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) : null; var item = itemId.Equals(Guid.Empty) @@ -277,8 +277,8 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult GetThemeMedia( [FromRoute] Guid itemId, - [FromQuery] Guid userId, - [FromQuery] bool inheritFromParent) + [FromQuery] Guid? userId, + [FromQuery] bool inheritFromParent = false) { var themeSongs = GetThemeSongs( itemId, @@ -361,12 +361,14 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public ActionResult DeleteItems([FromQuery] string ids) + public ActionResult DeleteItems([FromQuery] string? ids) { - var itemIds = string.IsNullOrWhiteSpace(ids) - ? Array.Empty() - : RequestHelpers.Split(ids, ',', true); + if (string.IsNullOrEmpty(ids)) + { + return NoContent(); + } + var itemIds = RequestHelpers.Split(ids, ',', true); foreach (var i in itemIds) { var item = _libraryManager.GetItemById(i); @@ -403,12 +405,12 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult GetItemCounts( - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] bool? isFavorite) { - var user = userId.Equals(Guid.Empty) - ? null - : _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var counts = new ItemCounts { @@ -437,7 +439,7 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult> GetAncestors([FromRoute] Guid itemId, [FromQuery] Guid userId) + public ActionResult> GetAncestors([FromRoute] Guid itemId, [FromQuery] Guid? userId) { var item = _libraryManager.GetItemById(itemId); @@ -448,8 +450,8 @@ namespace Jellyfin.Api.Controllers var baseItemDtos = new List(); - var user = !userId.Equals(Guid.Empty) - ? _userManager.GetUserById(userId) + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) : null; var dtoOptions = new DtoOptions().AddClientFields(Request); @@ -688,7 +690,7 @@ namespace Jellyfin.Api.Controllers public ActionResult> GetSimilarItems( [FromRoute] Guid itemId, [FromQuery] string? excludeArtistIds, - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] int? limit, [FromQuery] string? fields) { @@ -737,7 +739,9 @@ namespace Jellyfin.Api.Controllers [HttpGet("/Libraries/AvailableOptions")] [Authorize(Policy = Policies.FirstTimeSetupOrElevated)] [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult GetLibraryOptionsInfo([FromQuery] string? libraryContentType, [FromQuery] bool isNewLibrary) + public ActionResult GetLibraryOptionsInfo( + [FromQuery] string? libraryContentType, + [FromQuery] bool isNewLibrary = false) { var result = new LibraryOptionsResultDto(); @@ -878,13 +882,15 @@ namespace Jellyfin.Api.Controllers private QueryResult GetSimilarItemsResult( BaseItem item, string? excludeArtistIds, - Guid userId, + Guid? userId, int? limit, string? fields, string[] includeItemTypes, bool isMovie) { - var user = !userId.Equals(Guid.Empty) ? _userManager.GetUserById(userId) : null; + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var dtoOptions = new DtoOptions() .AddItemFields(fields) .AddClientFields(Request); diff --git a/Jellyfin.Api/Controllers/LibraryStructureController.cs b/Jellyfin.Api/Controllers/LibraryStructureController.cs index 0c91f8447..881d3f192 100644 --- a/Jellyfin.Api/Controllers/LibraryStructureController.cs +++ b/Jellyfin.Api/Controllers/LibraryStructureController.cs @@ -64,9 +64,9 @@ namespace Jellyfin.Api.Controllers /// /// The name of the virtual folder. /// The type of the collection. - /// Whether to refresh the library. /// The paths of the virtual folder. /// The library options. + /// Whether to refresh the library. /// Folder added. /// A . [HttpPost] @@ -74,9 +74,9 @@ namespace Jellyfin.Api.Controllers public async Task AddVirtualFolder( [FromQuery] string? name, [FromQuery] string? collectionType, - [FromQuery] bool refreshLibrary, [FromQuery] string[] paths, - [FromQuery] LibraryOptions libraryOptions) + [FromQuery] LibraryOptions? libraryOptions, + [FromQuery] bool refreshLibrary = false) { libraryOptions ??= new LibraryOptions(); @@ -101,7 +101,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status204NoContent)] public async Task RemoveVirtualFolder( [FromQuery] string? name, - [FromQuery] bool refreshLibrary) + [FromQuery] bool refreshLibrary = false) { await _libraryManager.RemoveVirtualFolder(name, refreshLibrary).ConfigureAwait(false); return NoContent(); @@ -125,7 +125,7 @@ namespace Jellyfin.Api.Controllers public ActionResult RenameVirtualFolder( [FromQuery] string? name, [FromQuery] string? newName, - [FromQuery] bool refreshLibrary) + [FromQuery] bool refreshLibrary = false) { if (string.IsNullOrWhiteSpace(name)) { @@ -207,8 +207,8 @@ namespace Jellyfin.Api.Controllers public ActionResult AddMediaPath( [FromQuery] string? name, [FromQuery] string? path, - [FromQuery] MediaPathInfo pathInfo, - [FromQuery] bool refreshLibrary) + [FromQuery] MediaPathInfo? pathInfo, + [FromQuery] bool refreshLibrary = false) { if (string.IsNullOrWhiteSpace(name)) { @@ -257,7 +257,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult UpdateMediaPath( [FromQuery] string? name, - [FromQuery] MediaPathInfo pathInfo) + [FromQuery] MediaPathInfo? pathInfo) { if (string.IsNullOrWhiteSpace(name)) { @@ -282,7 +282,7 @@ namespace Jellyfin.Api.Controllers public ActionResult RemoveMediaPath( [FromQuery] string? name, [FromQuery] string? path, - [FromQuery] bool refreshLibrary) + [FromQuery] bool refreshLibrary = false) { if (string.IsNullOrWhiteSpace(name)) { @@ -328,7 +328,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult UpdateLibraryOptions( [FromQuery] string? id, - [FromQuery] LibraryOptions libraryOptions) + [FromQuery] LibraryOptions? libraryOptions) { var collectionFolder = (CollectionFolder)_libraryManager.GetItemById(id); diff --git a/Jellyfin.Api/Controllers/LiveTvController.cs b/Jellyfin.Api/Controllers/LiveTvController.cs index 325837ce3..bc5446510 100644 --- a/Jellyfin.Api/Controllers/LiveTvController.cs +++ b/Jellyfin.Api/Controllers/LiveTvController.cs @@ -113,7 +113,6 @@ namespace Jellyfin.Api.Controllers /// Optional. Filter by channels that are favorites, or not. /// Optional. Filter by channels that are liked, or not. /// Optional. Filter by channels that are disliked, or not. - /// Optional. Incorporate favorite and like status into channel sorting. /// Optional. Include image information in output. /// Optional. The max number of images to return, per image type. /// "Optional. The image types to include in the output. @@ -121,6 +120,7 @@ namespace Jellyfin.Api.Controllers /// Optional. Include user data. /// Optional. Key to sort by. /// Optional. Sort order. + /// Optional. Incorporate favorite and like status into channel sorting. /// Optional. Adds current program info to each channel. /// Available live tv channels returned. /// @@ -131,7 +131,7 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.DefaultAuthorization)] public ActionResult> GetChannels( [FromQuery] ChannelType? type, - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] int? startIndex, [FromQuery] bool? isMovie, [FromQuery] bool? isSeries, @@ -142,14 +142,14 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? isFavorite, [FromQuery] bool? isLiked, [FromQuery] bool? isDisliked, - [FromQuery] bool enableFavoriteSorting, [FromQuery] bool? enableImages, [FromQuery] int? imageTypeLimit, - [FromQuery] string enableImageTypes, - [FromQuery] string fields, + [FromQuery] string? enableImageTypes, + [FromQuery] string? fields, [FromQuery] bool? enableUserData, - [FromQuery] string sortBy, + [FromQuery] string? sortBy, [FromQuery] SortOrder? sortOrder, + [FromQuery] bool enableFavoriteSorting = false, [FromQuery] bool addCurrentProgram = true) { var dtoOptions = new DtoOptions() @@ -161,7 +161,7 @@ namespace Jellyfin.Api.Controllers new LiveTvChannelQuery { ChannelType = type, - UserId = userId, + UserId = userId ?? Guid.Empty, StartIndex = startIndex, Limit = limit, IsFavorite = isFavorite, @@ -180,9 +180,9 @@ namespace Jellyfin.Api.Controllers dtoOptions, CancellationToken.None); - var user = userId.Equals(Guid.Empty) - ? null - : _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var fieldsList = dtoOptions.Fields.ToList(); fieldsList.Remove(ItemFields.CanDelete); @@ -210,9 +210,11 @@ namespace Jellyfin.Api.Controllers [HttpGet("Channels/{channelId}")] [ProducesResponseType(StatusCodes.Status200OK)] [Authorize(Policy = Policies.DefaultAuthorization)] - public ActionResult GetChannel([FromRoute] Guid channelId, [FromQuery] Guid userId) + public ActionResult GetChannel([FromRoute] Guid channelId, [FromQuery] Guid? userId) { - var user = _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var item = channelId.Equals(Guid.Empty) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(channelId); @@ -250,17 +252,17 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [Authorize(Policy = Policies.DefaultAuthorization)] public ActionResult> GetRecordings( - [FromQuery] string channelId, - [FromQuery] Guid userId, + [FromQuery] string? channelId, + [FromQuery] Guid? userId, [FromQuery] int? startIndex, [FromQuery] int? limit, [FromQuery] RecordingStatus? status, [FromQuery] bool? isInProgress, - [FromQuery] string seriesTimerId, + [FromQuery] string? seriesTimerId, [FromQuery] bool? enableImages, [FromQuery] int? imageTypeLimit, - [FromQuery] string enableImageTypes, - [FromQuery] string fields, + [FromQuery] string? enableImageTypes, + [FromQuery] string? fields, [FromQuery] bool? enableUserData, [FromQuery] bool? isMovie, [FromQuery] bool? isSeries, @@ -279,7 +281,7 @@ namespace Jellyfin.Api.Controllers new RecordingQuery { ChannelId = channelId, - UserId = userId, + UserId = userId ?? Guid.Empty, StartIndex = startIndex, Limit = limit, Status = status, @@ -336,18 +338,18 @@ namespace Jellyfin.Api.Controllers [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "enableUserData", Justification = "Imported from ServiceStack")] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "enableTotalRecordCount", Justification = "Imported from ServiceStack")] public ActionResult> GetRecordingsSeries( - [FromQuery] string channelId, - [FromQuery] Guid userId, - [FromQuery] string groupId, + [FromQuery] string? channelId, + [FromQuery] Guid? userId, + [FromQuery] string? groupId, [FromQuery] int? startIndex, [FromQuery] int? limit, [FromQuery] RecordingStatus? status, [FromQuery] bool? isInProgress, - [FromQuery] string seriesTimerId, + [FromQuery] string? seriesTimerId, [FromQuery] bool? enableImages, [FromQuery] int? imageTypeLimit, - [FromQuery] string enableImageTypes, - [FromQuery] string fields, + [FromQuery] string? enableImageTypes, + [FromQuery] string? fields, [FromQuery] bool? enableUserData, [FromQuery] bool enableTotalRecordCount = true) { @@ -365,7 +367,7 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.DefaultAuthorization)] [Obsolete("This endpoint is obsolete.")] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "userId", Justification = "Imported from ServiceStack")] - public ActionResult> GetRecordingGroups([FromQuery] Guid userId) + public ActionResult> GetRecordingGroups([FromQuery] Guid? userId) { return new QueryResult(); } @@ -379,9 +381,11 @@ namespace Jellyfin.Api.Controllers [HttpGet("Recordings/Folders")] [ProducesResponseType(StatusCodes.Status200OK)] [Authorize(Policy = Policies.DefaultAuthorization)] - public ActionResult> GetRecordingFolders([FromQuery] Guid userId) + public ActionResult> GetRecordingFolders([FromQuery] Guid? userId) { - var user = userId.Equals(Guid.Empty) ? null : _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var folders = _liveTvManager.GetRecordingFolders(user); var returnArray = _dtoService.GetBaseItemDtos(folders, new DtoOptions(), user); @@ -403,9 +407,11 @@ namespace Jellyfin.Api.Controllers [HttpGet("Recordings/{recordingId}")] [ProducesResponseType(StatusCodes.Status200OK)] [Authorize(Policy = Policies.DefaultAuthorization)] - public ActionResult GetRecording([FromRoute] Guid recordingId, [FromQuery] Guid userId) + public ActionResult GetRecording([FromRoute] Guid recordingId, [FromQuery] Guid? userId) { - var user = _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var item = recordingId.Equals(Guid.Empty) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(recordingId); var dtoOptions = new DtoOptions() @@ -457,7 +463,7 @@ namespace Jellyfin.Api.Controllers [HttpGet("Timers/Defaults")] [ProducesResponseType(StatusCodes.Status200OK)] [Authorize(Policy = Policies.DefaultAuthorization)] - public async Task> GetDefaultTimer([FromQuery] string programId) + public async Task> GetDefaultTimer([FromQuery] string? programId) { return string.IsNullOrEmpty(programId) ? await _liveTvManager.GetNewTimerDefaults(CancellationToken.None).ConfigureAwait(false) @@ -478,8 +484,8 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [Authorize(Policy = Policies.DefaultAuthorization)] public async Task>> GetTimers( - [FromQuery] string channelId, - [FromQuery] string seriesTimerId, + [FromQuery] string? channelId, + [FromQuery] string? seriesTimerId, [FromQuery] bool? isActive, [FromQuery] bool? isScheduled) { @@ -532,8 +538,8 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [Authorize(Policy = Policies.DefaultAuthorization)] public async Task>> GetPrograms( - [FromQuery] string channelIds, - [FromQuery] Guid userId, + [FromQuery] string? channelIds, + [FromQuery] Guid? userId, [FromQuery] DateTime? minStartDate, [FromQuery] bool? hasAired, [FromQuery] bool? isAiring, @@ -547,20 +553,22 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? isSports, [FromQuery] int? startIndex, [FromQuery] int? limit, - [FromQuery] string sortBy, - [FromQuery] string sortOrder, - [FromQuery] string genres, - [FromQuery] string genreIds, + [FromQuery] string? sortBy, + [FromQuery] string? sortOrder, + [FromQuery] string? genres, + [FromQuery] string? genreIds, [FromQuery] bool? enableImages, [FromQuery] int? imageTypeLimit, - [FromQuery] string enableImageTypes, + [FromQuery] string? enableImageTypes, [FromQuery] bool? enableUserData, - [FromQuery] string seriesTimerId, - [FromQuery] Guid librarySeriesId, - [FromQuery] string fields, + [FromQuery] string? seriesTimerId, + [FromQuery] Guid? librarySeriesId, + [FromQuery] string? fields, [FromQuery] bool enableTotalRecordCount = true) { - var user = userId.Equals(Guid.Empty) ? null : _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var query = new InternalItemsQuery(user) { @@ -590,7 +598,7 @@ namespace Jellyfin.Api.Controllers { query.IsSeries = true; - if (_libraryManager.GetItemById(librarySeriesId) is Series series) + if (_libraryManager.GetItemById(librarySeriesId ?? Guid.Empty) is Series series) { query.Name = series.Name; } @@ -684,7 +692,7 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetRecommendedPrograms( - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] int? limit, [FromQuery] bool? isAiring, [FromQuery] bool? hasAired, @@ -695,13 +703,15 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? isSports, [FromQuery] bool? enableImages, [FromQuery] int? imageTypeLimit, - [FromQuery] string enableImageTypes, - [FromQuery] string genreIds, - [FromQuery] string fields, + [FromQuery] string? enableImageTypes, + [FromQuery] string? genreIds, + [FromQuery] string? fields, [FromQuery] bool? enableUserData, [FromQuery] bool enableTotalRecordCount = true) { - var user = _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var query = new InternalItemsQuery(user) { @@ -736,11 +746,11 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public async Task> GetProgram( [FromRoute] string programId, - [FromQuery] Guid userId) + [FromQuery] Guid? userId) { - var user = userId.Equals(Guid.Empty) - ? null - : _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; return await _liveTvManager.GetProgram(programId, CancellationToken.None, user).ConfigureAwait(false); } @@ -856,12 +866,12 @@ namespace Jellyfin.Api.Controllers [HttpGet("SeriesTimers")] [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetSeriesTimers([FromQuery] string sortBy, [FromQuery] SortOrder sortOrder) + public async Task>> GetSeriesTimers([FromQuery] string? sortBy, [FromQuery] SortOrder? sortOrder) { return await _liveTvManager.GetSeriesTimers( new SeriesTimerQuery { - SortOrder = sortOrder, + SortOrder = sortOrder ?? SortOrder.Ascending, SortBy = sortBy }, CancellationToken.None).ConfigureAwait(false); } @@ -925,7 +935,7 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Obsolete("This endpoint is obsolete.")] - public ActionResult GetRecordingGroup([FromQuery] Guid groupId) + public ActionResult GetRecordingGroup([FromQuery] Guid? groupId) { return NotFound(); } @@ -966,7 +976,7 @@ namespace Jellyfin.Api.Controllers [HttpDelete("TunerHosts")] [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status204NoContent)] - public ActionResult DeleteTunerHost([FromQuery] string id) + public ActionResult DeleteTunerHost([FromQuery] string? id) { var config = _configurationManager.GetConfiguration("livetv"); config.TunerHosts = config.TunerHosts.Where(i => !string.Equals(id, i.Id, StringComparison.OrdinalIgnoreCase)).ToArray(); @@ -990,10 +1000,10 @@ namespace Jellyfin.Api.Controllers /// /// Adds a listings provider. /// - /// Validate login. - /// Validate listings. /// Password. /// New listings info. + /// Validate listings. + /// Validate login. /// Created listings provider returned. /// A containing the created listings provider. [HttpGet("ListingProviders")] @@ -1001,10 +1011,10 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [SuppressMessage("Microsoft.Performance", "CA5350:RemoveSha1", MessageId = "AddListingProvider", Justification = "Imported from ServiceStack")] public async Task> AddListingProvider( - [FromQuery] bool validateLogin, - [FromQuery] bool validateListings, - [FromQuery] string pw, - [FromBody] ListingsProviderInfo listingsProviderInfo) + [FromQuery] string? pw, + [FromBody] ListingsProviderInfo listingsProviderInfo, + [FromQuery] bool validateListings = false, + [FromQuery] bool validateLogin = false) { using var sha = SHA1.Create(); if (!string.IsNullOrEmpty(pw)) @@ -1024,7 +1034,7 @@ namespace Jellyfin.Api.Controllers [HttpDelete("ListingProviders")] [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status204NoContent)] - public ActionResult DeleteListingProvider([FromQuery] string id) + public ActionResult DeleteListingProvider([FromQuery] string? id) { _liveTvManager.DeleteListingsProvider(id); return NoContent(); @@ -1043,10 +1053,10 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] public async Task>> GetLineups( - [FromQuery] string id, - [FromQuery] string type, - [FromQuery] string location, - [FromQuery] string country) + [FromQuery] string? id, + [FromQuery] string? type, + [FromQuery] string? location, + [FromQuery] string? country) { return await _liveTvManager.GetLineups(type, id, country, location).ConfigureAwait(false); } @@ -1079,7 +1089,7 @@ namespace Jellyfin.Api.Controllers [HttpGet("ChannelMappingOptions")] [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetChannelMappingOptions([FromQuery] string providerId) + public async Task> GetChannelMappingOptions([FromQuery] string? providerId) { var config = _configurationManager.GetConfiguration("livetv"); @@ -1120,9 +1130,9 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> SetChannelMapping( - [FromQuery] string providerId, - [FromQuery] string tunerChannelId, - [FromQuery] string providerChannelId) + [FromQuery] string? providerId, + [FromQuery] string? tunerChannelId, + [FromQuery] string? providerChannelId) { return await _liveTvManager.SetChannelMapping(providerId, tunerChannelId, providerChannelId).ConfigureAwait(false); } @@ -1149,7 +1159,7 @@ namespace Jellyfin.Api.Controllers [HttpGet("Tuners/Discvover")] [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> DiscoverTuners([FromQuery] bool newDevicesOnly) + public async Task>> DiscoverTuners([FromQuery] bool newDevicesOnly = false) { return await _liveTvManager.DiscoverTuners(newDevicesOnly, CancellationToken.None).ConfigureAwait(false); } diff --git a/Jellyfin.Api/Controllers/MediaInfoController.cs b/Jellyfin.Api/Controllers/MediaInfoController.cs index daf4bf419..da400f510 100644 --- a/Jellyfin.Api/Controllers/MediaInfoController.cs +++ b/Jellyfin.Api/Controllers/MediaInfoController.cs @@ -88,7 +88,7 @@ namespace Jellyfin.Api.Controllers /// A containing a with the playback information. [HttpGet("/Items/{itemId}/PlaybackInfo")] [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetPlaybackInfo([FromRoute] Guid itemId, [FromQuery] Guid userId) + public async Task> GetPlaybackInfo([FromRoute] Guid itemId, [FromQuery] Guid? userId) { return await GetPlaybackInfoInternal(itemId, userId, null, null).ConfigureAwait(false); } @@ -118,16 +118,16 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public async Task> GetPostedPlaybackInfo( [FromRoute] Guid itemId, - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] long? maxStreamingBitrate, [FromQuery] long? startTimeTicks, [FromQuery] int? audioStreamIndex, [FromQuery] int? subtitleStreamIndex, [FromQuery] int? maxAudioChannels, - [FromQuery] string mediaSourceId, - [FromQuery] string liveStreamId, - [FromQuery] DeviceProfile deviceProfile, - [FromQuery] bool autoOpenLiveStream, + [FromQuery] string? mediaSourceId, + [FromQuery] string? liveStreamId, + [FromQuery] DeviceProfile? deviceProfile, + [FromQuery] bool autoOpenLiveStream = false, [FromQuery] bool enableDirectPlay = true, [FromQuery] bool enableDirectStream = true, [FromQuery] bool enableTranscoding = true, @@ -165,12 +165,12 @@ namespace Jellyfin.Api.Controllers authInfo, maxStreamingBitrate ?? profile.MaxStreamingBitrate, startTimeTicks ?? 0, - mediaSourceId, + mediaSourceId ?? string.Empty, audioStreamIndex, subtitleStreamIndex, maxAudioChannels, info!.PlaySessionId!, - userId, + userId ?? Guid.Empty, enableDirectPlay, enableDirectStream, enableTranscoding, @@ -199,7 +199,7 @@ namespace Jellyfin.Api.Controllers PlaySessionId = info.PlaySessionId, StartTimeTicks = startTimeTicks, SubtitleStreamIndex = subtitleStreamIndex, - UserId = userId, + UserId = userId ?? Guid.Empty, OpenToken = mediaSource.OpenToken }).ConfigureAwait(false); @@ -239,16 +239,16 @@ namespace Jellyfin.Api.Controllers [HttpPost("/LiveStreams/Open")] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> OpenLiveStream( - [FromQuery] string openToken, - [FromQuery] Guid userId, - [FromQuery] string playSessionId, + [FromQuery] string? openToken, + [FromQuery] Guid? userId, + [FromQuery] string? playSessionId, [FromQuery] long? maxStreamingBitrate, [FromQuery] long? startTimeTicks, [FromQuery] int? audioStreamIndex, [FromQuery] int? subtitleStreamIndex, [FromQuery] int? maxAudioChannels, - [FromQuery] Guid itemId, - [FromQuery] DeviceProfile deviceProfile, + [FromQuery] Guid? itemId, + [FromQuery] DeviceProfile? deviceProfile, [FromQuery] MediaProtocol[] directPlayProtocols, [FromQuery] bool enableDirectPlay = true, [FromQuery] bool enableDirectStream = true) @@ -256,14 +256,14 @@ namespace Jellyfin.Api.Controllers var request = new LiveStreamRequest { OpenToken = openToken, - UserId = userId, + UserId = userId ?? Guid.Empty, PlaySessionId = playSessionId, MaxStreamingBitrate = maxStreamingBitrate, StartTimeTicks = startTimeTicks, AudioStreamIndex = audioStreamIndex, SubtitleStreamIndex = subtitleStreamIndex, MaxAudioChannels = maxAudioChannels, - ItemId = itemId, + ItemId = itemId ?? Guid.Empty, DeviceProfile = deviceProfile, EnableDirectPlay = enableDirectPlay, EnableDirectStream = enableDirectStream, @@ -280,7 +280,7 @@ namespace Jellyfin.Api.Controllers /// A indicating success. [HttpPost("/LiveStreams/Close")] [ProducesResponseType(StatusCodes.Status204NoContent)] - public ActionResult CloseLiveStream([FromQuery] string liveStreamId) + public ActionResult CloseLiveStream([FromQuery] string? liveStreamId) { _mediaSourceManager.CloseLiveStream(liveStreamId).GetAwaiter().GetResult(); return NoContent(); @@ -325,11 +325,13 @@ namespace Jellyfin.Api.Controllers private async Task GetPlaybackInfoInternal( Guid id, - Guid userId, + Guid? userId, string? mediaSourceId = null, string? liveStreamId = null) { - var user = _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var item = _libraryManager.GetItemById(id); var result = new PlaybackInfoResponse(); diff --git a/Jellyfin.Api/Controllers/MoviesController.cs b/Jellyfin.Api/Controllers/MoviesController.cs index 4dd3613c6..144a7b554 100644 --- a/Jellyfin.Api/Controllers/MoviesController.cs +++ b/Jellyfin.Api/Controllers/MoviesController.cs @@ -55,32 +55,22 @@ namespace Jellyfin.Api.Controllers /// /// Optional. Filter by user id, and attach user data. /// Specify this to localize the search to a specific item or folder. Omit to use the root. - /// (Unused) Optional. include image information in output. - /// (Unused) Optional. include user data. - /// (Unused) Optional. the max number of images to return, per image type. - /// (Unused) Optional. The image types to include in the output. /// Optional. The fields to return. /// The max number of categories to return. /// The max number of items to return per category. /// Movie recommendations returned. /// The list of movie recommendations. [HttpGet("Recommendations")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "enableImages", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "enableUserData", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "imageTypeLimit", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "enableImageTypes", Justification = "Imported from ServiceStack")] public ActionResult> GetMovieRecommendations( - [FromQuery] Guid userId, - [FromQuery] string parentId, - [FromQuery] bool? enableImages, - [FromQuery] bool? enableUserData, - [FromQuery] int? imageTypeLimit, - [FromQuery] string? enableImageTypes, + [FromQuery] Guid? userId, + [FromQuery] string? parentId, [FromQuery] string? fields, [FromQuery] int categoryLimit = 5, [FromQuery] int itemLimit = 8) { - var user = _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var dtoOptions = new DtoOptions() .AddItemFields(fields) .AddClientFields(Request); @@ -185,7 +175,7 @@ namespace Jellyfin.Api.Controllers } private IEnumerable GetWithDirector( - User user, + User? user, IEnumerable names, int itemLimit, DtoOptions dtoOptions, @@ -230,7 +220,7 @@ namespace Jellyfin.Api.Controllers } } - private IEnumerable GetWithActor(User user, IEnumerable names, int itemLimit, DtoOptions dtoOptions, RecommendationType type) + private IEnumerable GetWithActor(User? user, IEnumerable names, int itemLimit, DtoOptions dtoOptions, RecommendationType type) { var itemTypes = new List { nameof(Movie) }; if (_serverConfigurationManager.Configuration.EnableExternalContentInSuggestions) @@ -270,7 +260,7 @@ namespace Jellyfin.Api.Controllers } } - private IEnumerable GetSimilarTo(User user, IEnumerable baselineItems, int itemLimit, DtoOptions dtoOptions, RecommendationType type) + private IEnumerable GetSimilarTo(User? user, IEnumerable baselineItems, int itemLimit, DtoOptions dtoOptions, RecommendationType type) { var itemTypes = new List { nameof(Movie) }; if (_serverConfigurationManager.Configuration.EnableExternalContentInSuggestions) diff --git a/Jellyfin.Api/Controllers/MusicGenresController.cs b/Jellyfin.Api/Controllers/MusicGenresController.cs index 9ac74f199..0d319137a 100644 --- a/Jellyfin.Api/Controllers/MusicGenresController.cs +++ b/Jellyfin.Api/Controllers/MusicGenresController.cs @@ -83,31 +83,31 @@ namespace Jellyfin.Api.Controllers [FromQuery] double? minCommunityRating, [FromQuery] int? startIndex, [FromQuery] int? limit, - [FromQuery] string searchTerm, - [FromQuery] string parentId, - [FromQuery] string fields, - [FromQuery] string excludeItemTypes, - [FromQuery] string includeItemTypes, - [FromQuery] string filters, + [FromQuery] string? searchTerm, + [FromQuery] string? parentId, + [FromQuery] string? fields, + [FromQuery] string? excludeItemTypes, + [FromQuery] string? includeItemTypes, + [FromQuery] string? filters, [FromQuery] bool? isFavorite, - [FromQuery] string mediaTypes, - [FromQuery] string genres, - [FromQuery] string genreIds, - [FromQuery] string officialRatings, - [FromQuery] string tags, - [FromQuery] string years, + [FromQuery] string? mediaTypes, + [FromQuery] string? genres, + [FromQuery] string? genreIds, + [FromQuery] string? officialRatings, + [FromQuery] string? tags, + [FromQuery] string? years, [FromQuery] bool? enableUserData, [FromQuery] int? imageTypeLimit, - [FromQuery] string enableImageTypes, - [FromQuery] string person, - [FromQuery] string personIds, - [FromQuery] string personTypes, - [FromQuery] string studios, - [FromQuery] string studioIds, - [FromQuery] Guid userId, - [FromQuery] string nameStartsWithOrGreater, - [FromQuery] string nameStartsWith, - [FromQuery] string nameLessThan, + [FromQuery] string? enableImageTypes, + [FromQuery] string? person, + [FromQuery] string? personIds, + [FromQuery] string? personTypes, + [FromQuery] string? studios, + [FromQuery] string? studioIds, + [FromQuery] Guid? userId, + [FromQuery] string? nameStartsWithOrGreater, + [FromQuery] string? nameStartsWith, + [FromQuery] string? nameLessThan, [FromQuery] bool? enableImages = true, [FromQuery] bool enableTotalRecordCount = true) { @@ -119,9 +119,9 @@ namespace Jellyfin.Api.Controllers User? user = null; BaseItem parentItem; - if (!userId.Equals(Guid.Empty)) + if (userId.HasValue && !userId.Equals(Guid.Empty)) { - user = _userManager.GetUserById(userId); + user = _userManager.GetUserById(userId.Value); parentItem = string.IsNullOrEmpty(parentId) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(parentId); } else @@ -258,7 +258,7 @@ namespace Jellyfin.Api.Controllers /// An containing a with the music genre. [HttpGet("{genreName}")] [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult GetMusicGenre([FromRoute] string genreName, [FromQuery] Guid userId) + public ActionResult GetMusicGenre([FromRoute] string genreName, [FromQuery] Guid? userId) { var dtoOptions = new DtoOptions().AddClientFields(Request); @@ -273,9 +273,9 @@ namespace Jellyfin.Api.Controllers item = _libraryManager.GetMusicGenre(genreName); } - if (!userId.Equals(Guid.Empty)) + if (userId.HasValue && !userId.Equals(Guid.Empty)) { - var user = _userManager.GetUserById(userId); + var user = _userManager.GetUserById(userId.Value); return _dtoService.GetBaseItemDto(item, dtoOptions, user); } diff --git a/Jellyfin.Api/Controllers/PersonsController.cs b/Jellyfin.Api/Controllers/PersonsController.cs index 03478a20a..23cc23ce7 100644 --- a/Jellyfin.Api/Controllers/PersonsController.cs +++ b/Jellyfin.Api/Controllers/PersonsController.cs @@ -80,31 +80,31 @@ namespace Jellyfin.Api.Controllers [FromQuery] double? minCommunityRating, [FromQuery] int? startIndex, [FromQuery] int? limit, - [FromQuery] string searchTerm, - [FromQuery] string parentId, - [FromQuery] string fields, - [FromQuery] string excludeItemTypes, - [FromQuery] string includeItemTypes, - [FromQuery] string filters, + [FromQuery] string? searchTerm, + [FromQuery] string? parentId, + [FromQuery] string? fields, + [FromQuery] string? excludeItemTypes, + [FromQuery] string? includeItemTypes, + [FromQuery] string? filters, [FromQuery] bool? isFavorite, - [FromQuery] string mediaTypes, - [FromQuery] string genres, - [FromQuery] string genreIds, - [FromQuery] string officialRatings, - [FromQuery] string tags, - [FromQuery] string years, + [FromQuery] string? mediaTypes, + [FromQuery] string? genres, + [FromQuery] string? genreIds, + [FromQuery] string? officialRatings, + [FromQuery] string? tags, + [FromQuery] string? years, [FromQuery] bool? enableUserData, [FromQuery] int? imageTypeLimit, - [FromQuery] string enableImageTypes, - [FromQuery] string person, - [FromQuery] string personIds, - [FromQuery] string personTypes, - [FromQuery] string studios, - [FromQuery] string studioIds, - [FromQuery] Guid userId, - [FromQuery] string nameStartsWithOrGreater, - [FromQuery] string nameStartsWith, - [FromQuery] string nameLessThan, + [FromQuery] string? enableImageTypes, + [FromQuery] string? person, + [FromQuery] string? personIds, + [FromQuery] string? personTypes, + [FromQuery] string? studios, + [FromQuery] string? studioIds, + [FromQuery] Guid? userId, + [FromQuery] string? nameStartsWithOrGreater, + [FromQuery] string? nameStartsWith, + [FromQuery] string? nameLessThan, [FromQuery] bool? enableImages = true, [FromQuery] bool enableTotalRecordCount = true) { @@ -116,9 +116,9 @@ namespace Jellyfin.Api.Controllers User? user = null; BaseItem parentItem; - if (!userId.Equals(Guid.Empty)) + if (userId.HasValue && !userId.Equals(Guid.Empty)) { - user = _userManager.GetUserById(userId); + user = _userManager.GetUserById(userId.Value); parentItem = string.IsNullOrEmpty(parentId) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(parentId); } else @@ -259,7 +259,7 @@ namespace Jellyfin.Api.Controllers [HttpGet("{name}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult GetPerson([FromRoute] string name, [FromQuery] Guid userId) + public ActionResult GetPerson([FromRoute] string name, [FromQuery] Guid? userId) { var dtoOptions = new DtoOptions() .AddClientFields(Request); @@ -270,9 +270,9 @@ namespace Jellyfin.Api.Controllers return NotFound(); } - if (!userId.Equals(Guid.Empty)) + if (userId.HasValue && !userId.Equals(Guid.Empty)) { - var user = _userManager.GetUserById(userId); + var user = _userManager.GetUserById(userId.Value); return _dtoService.GetBaseItemDto(item, dtoOptions, user); } diff --git a/Jellyfin.Api/Controllers/PlaylistsController.cs b/Jellyfin.Api/Controllers/PlaylistsController.cs index d62404fc9..cf4660494 100644 --- a/Jellyfin.Api/Controllers/PlaylistsController.cs +++ b/Jellyfin.Api/Controllers/PlaylistsController.cs @@ -86,9 +86,9 @@ namespace Jellyfin.Api.Controllers public ActionResult AddToPlaylist( [FromRoute] string? playlistId, [FromQuery] string? ids, - [FromQuery] Guid userId) + [FromQuery] Guid? userId) { - _playlistManager.AddToPlaylist(playlistId, RequestHelpers.GetGuids(ids), userId); + _playlistManager.AddToPlaylist(playlistId, RequestHelpers.GetGuids(ids), userId ?? Guid.Empty); return NoContent(); } diff --git a/Jellyfin.Api/Controllers/PlaystateController.cs b/Jellyfin.Api/Controllers/PlaystateController.cs index 05a6edf4e..9fcf04199 100644 --- a/Jellyfin.Api/Controllers/PlaystateController.cs +++ b/Jellyfin.Api/Controllers/PlaystateController.cs @@ -188,12 +188,12 @@ namespace Jellyfin.Api.Controllers /// User id. /// Item id. /// The id of the MediaSource. - /// Indicates if the client can seek. /// The audio stream index. /// The subtitle stream index. /// The play method. /// The live stream id. /// The play session id. + /// Indicates if the client can seek. /// Play start recorded. /// A . [HttpPost("/Users/{userId}/PlayingItems/{itemId}")] @@ -202,13 +202,13 @@ namespace Jellyfin.Api.Controllers public async Task OnPlaybackStart( [FromRoute] Guid userId, [FromRoute] Guid itemId, - [FromQuery] string mediaSourceId, - [FromQuery] bool canSeek, + [FromQuery] string? mediaSourceId, [FromQuery] int? audioStreamIndex, [FromQuery] int? subtitleStreamIndex, [FromQuery] PlayMethod playMethod, - [FromQuery] string liveStreamId, - [FromQuery] string playSessionId) + [FromQuery] string? liveStreamId, + [FromQuery] string playSessionId, + [FromQuery] bool canSeek = false) { var playbackStartInfo = new PlaybackStartInfo { @@ -235,8 +235,6 @@ namespace Jellyfin.Api.Controllers /// Item id. /// The id of the MediaSource. /// Optional. The current position, in ticks. 1 tick = 10000 ms. - /// Indicates if the player is paused. - /// Indicates if the player is muted. /// The audio stream index. /// The subtitle stream index. /// Scale of 0-100. @@ -244,6 +242,8 @@ namespace Jellyfin.Api.Controllers /// The live stream id. /// The play session id. /// The repeat mode. + /// Indicates if the player is paused. + /// Indicates if the player is muted. /// Play progress recorded. /// A . [HttpPost("/Users/{userId}/PlayingItems/{itemId}/Progress")] @@ -252,17 +252,17 @@ namespace Jellyfin.Api.Controllers public async Task OnPlaybackProgress( [FromRoute] Guid userId, [FromRoute] Guid itemId, - [FromQuery] string mediaSourceId, + [FromQuery] string? mediaSourceId, [FromQuery] long? positionTicks, - [FromQuery] bool isPaused, - [FromQuery] bool isMuted, [FromQuery] int? audioStreamIndex, [FromQuery] int? subtitleStreamIndex, [FromQuery] int? volumeLevel, [FromQuery] PlayMethod playMethod, - [FromQuery] string liveStreamId, + [FromQuery] string? liveStreamId, [FromQuery] string playSessionId, - [FromQuery] RepeatMode repeatMode) + [FromQuery] RepeatMode repeatMode, + [FromQuery] bool isPaused = false, + [FromQuery] bool isMuted = false) { var playbackProgressInfo = new PlaybackProgressInfo { @@ -304,11 +304,11 @@ namespace Jellyfin.Api.Controllers public async Task OnPlaybackStopped( [FromRoute] Guid userId, [FromRoute] Guid itemId, - [FromQuery] string mediaSourceId, - [FromQuery] string nextMediaType, + [FromQuery] string? mediaSourceId, + [FromQuery] string? nextMediaType, [FromQuery] long? positionTicks, - [FromQuery] string liveStreamId, - [FromQuery] string playSessionId) + [FromQuery] string? liveStreamId, + [FromQuery] string? playSessionId) { var playbackStopInfo = new PlaybackStopInfo { diff --git a/Jellyfin.Api/Controllers/RemoteImageController.cs b/Jellyfin.Api/Controllers/RemoteImageController.cs index 6fff30129..1b26163cf 100644 --- a/Jellyfin.Api/Controllers/RemoteImageController.cs +++ b/Jellyfin.Api/Controllers/RemoteImageController.cs @@ -74,7 +74,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] int? startIndex, [FromQuery] int? limit, [FromQuery] string providerName, - [FromQuery] bool includeAllLanguages) + [FromQuery] bool includeAllLanguages = false) { var item = _libraryManager.GetItemById(itemId); if (item == null) diff --git a/Jellyfin.Api/Controllers/SearchController.cs b/Jellyfin.Api/Controllers/SearchController.cs index 14dc0815c..2cbd32d2f 100644 --- a/Jellyfin.Api/Controllers/SearchController.cs +++ b/Jellyfin.Api/Controllers/SearchController.cs @@ -80,7 +80,7 @@ namespace Jellyfin.Api.Controllers public ActionResult Get( [FromQuery] int? startIndex, [FromQuery] int? limit, - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery, Required] string? searchTerm, [FromQuery] string? includeItemTypes, [FromQuery] string? excludeItemTypes, @@ -107,7 +107,7 @@ namespace Jellyfin.Api.Controllers IncludePeople = includePeople, IncludeStudios = includeStudios, StartIndex = startIndex, - UserId = userId, + UserId = userId ?? Guid.Empty, IncludeItemTypes = RequestHelpers.Split(includeItemTypes, ',', true), ExcludeItemTypes = RequestHelpers.Split(excludeItemTypes, ',', true), MediaTypes = RequestHelpers.Split(mediaTypes, ',', true), diff --git a/Jellyfin.Api/Controllers/SessionController.cs b/Jellyfin.Api/Controllers/SessionController.cs index bd738aa38..0c98a8e71 100644 --- a/Jellyfin.Api/Controllers/SessionController.cs +++ b/Jellyfin.Api/Controllers/SessionController.cs @@ -61,7 +61,7 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetSessions( - [FromQuery] Guid controllableByUserId, + [FromQuery] Guid? controllableByUserId, [FromQuery] string? deviceId, [FromQuery] int? activeWithinSeconds) { @@ -72,15 +72,15 @@ namespace Jellyfin.Api.Controllers result = result.Where(i => string.Equals(i.DeviceId, deviceId, StringComparison.OrdinalIgnoreCase)); } - if (!controllableByUserId.Equals(Guid.Empty)) + if (controllableByUserId.HasValue && !controllableByUserId.Equals(Guid.Empty)) { result = result.Where(i => i.SupportsRemoteControl); - var user = _userManager.GetUserById(controllableByUserId); + var user = _userManager.GetUserById(controllableByUserId.Value); if (!user.HasPermission(PermissionKind.EnableRemoteControlOfOtherUsers)) { - result = result.Where(i => i.UserId.Equals(Guid.Empty) || i.ContainsUser(controllableByUserId)); + result = result.Where(i => i.UserId.Equals(Guid.Empty) || i.ContainsUser(controllableByUserId.Value)); } if (!user.HasPermission(PermissionKind.EnableSharedDeviceControl)) @@ -371,8 +371,8 @@ namespace Jellyfin.Api.Controllers [FromQuery] string? id, [FromQuery] string? playableMediaTypes, [FromQuery] string? supportedCommands, - [FromQuery] bool supportsMediaControl, - [FromQuery] bool supportsSync, + [FromQuery] bool supportsMediaControl = false, + [FromQuery] bool supportsSync = false, [FromQuery] bool supportsPersistentIdentifier = true) { if (string.IsNullOrWhiteSpace(id)) diff --git a/Jellyfin.Api/Controllers/StudiosController.cs b/Jellyfin.Api/Controllers/StudiosController.cs index 76cf2febf..6f2787d93 100644 --- a/Jellyfin.Api/Controllers/StudiosController.cs +++ b/Jellyfin.Api/Controllers/StudiosController.cs @@ -82,31 +82,31 @@ namespace Jellyfin.Api.Controllers [FromQuery] double? minCommunityRating, [FromQuery] int? startIndex, [FromQuery] int? limit, - [FromQuery] string searchTerm, - [FromQuery] string parentId, - [FromQuery] string fields, - [FromQuery] string excludeItemTypes, - [FromQuery] string includeItemTypes, - [FromQuery] string filters, + [FromQuery] string? searchTerm, + [FromQuery] string? parentId, + [FromQuery] string? fields, + [FromQuery] string? excludeItemTypes, + [FromQuery] string? includeItemTypes, + [FromQuery] string? filters, [FromQuery] bool? isFavorite, - [FromQuery] string mediaTypes, - [FromQuery] string genres, - [FromQuery] string genreIds, - [FromQuery] string officialRatings, - [FromQuery] string tags, - [FromQuery] string years, + [FromQuery] string? mediaTypes, + [FromQuery] string? genres, + [FromQuery] string? genreIds, + [FromQuery] string? officialRatings, + [FromQuery] string? tags, + [FromQuery] string? years, [FromQuery] bool? enableUserData, [FromQuery] int? imageTypeLimit, - [FromQuery] string enableImageTypes, - [FromQuery] string person, - [FromQuery] string personIds, - [FromQuery] string personTypes, - [FromQuery] string studios, - [FromQuery] string studioIds, - [FromQuery] Guid userId, - [FromQuery] string nameStartsWithOrGreater, - [FromQuery] string nameStartsWith, - [FromQuery] string nameLessThan, + [FromQuery] string? enableImageTypes, + [FromQuery] string? person, + [FromQuery] string? personIds, + [FromQuery] string? personTypes, + [FromQuery] string? studios, + [FromQuery] string? studioIds, + [FromQuery] Guid? userId, + [FromQuery] string? nameStartsWithOrGreater, + [FromQuery] string? nameStartsWith, + [FromQuery] string? nameLessThan, [FromQuery] bool? enableImages = true, [FromQuery] bool enableTotalRecordCount = true) { @@ -118,9 +118,9 @@ namespace Jellyfin.Api.Controllers User? user = null; BaseItem parentItem; - if (!userId.Equals(Guid.Empty)) + if (userId.HasValue && !userId.Equals(Guid.Empty)) { - user = _userManager.GetUserById(userId); + user = _userManager.GetUserById(userId.Value); parentItem = string.IsNullOrEmpty(parentId) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(parentId); } else @@ -259,14 +259,14 @@ namespace Jellyfin.Api.Controllers /// An containing the studio. [HttpGet("{name}")] [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult GetStudio([FromRoute] string name, [FromQuery] Guid userId) + public ActionResult GetStudio([FromRoute] string name, [FromQuery] Guid? userId) { var dtoOptions = new DtoOptions().AddClientFields(Request); var item = _libraryManager.GetStudio(name); - if (!userId.Equals(Guid.Empty)) + if (userId.HasValue && !userId.Equals(Guid.Empty)) { - var user = _userManager.GetUserById(userId); + var user = _userManager.GetUserById(userId.Value); return _dtoService.GetBaseItemDto(item, dtoOptions, user); } diff --git a/Jellyfin.Api/Controllers/SubtitleController.cs b/Jellyfin.Api/Controllers/SubtitleController.cs index baedafaa6..1c38b8de5 100644 --- a/Jellyfin.Api/Controllers/SubtitleController.cs +++ b/Jellyfin.Api/Controllers/SubtitleController.cs @@ -190,8 +190,8 @@ namespace Jellyfin.Api.Controllers [FromRoute, Required] int index, [FromRoute, Required] string? format, [FromQuery] long? endPositionTicks, - [FromQuery] bool copyTimestamps, - [FromQuery] bool addVttTimeMap, + [FromQuery] bool copyTimestamps = false, + [FromQuery] bool addVttTimeMap = false, [FromRoute] long startPositionTicks = 0) { if (string.Equals(format, "js", StringComparison.OrdinalIgnoreCase)) diff --git a/Jellyfin.Api/Controllers/SuggestionsController.cs b/Jellyfin.Api/Controllers/SuggestionsController.cs index e1a99a138..bf3c1e2b1 100644 --- a/Jellyfin.Api/Controllers/SuggestionsController.cs +++ b/Jellyfin.Api/Controllers/SuggestionsController.cs @@ -44,9 +44,9 @@ namespace Jellyfin.Api.Controllers /// The user id. /// The media types. /// The type. - /// Whether to enable the total record count. /// Optional. The start index. /// Optional. The limit. + /// Whether to enable the total record count. /// Suggestions returned. /// A with the suggestions. [HttpGet("/Users/{userId}/Suggestions")] @@ -55,9 +55,9 @@ namespace Jellyfin.Api.Controllers [FromRoute] Guid userId, [FromQuery] string? mediaType, [FromQuery] string? type, - [FromQuery] bool enableTotalRecordCount, [FromQuery] int? startIndex, - [FromQuery] int? limit) + [FromQuery] int? limit, + [FromQuery] bool enableTotalRecordCount = false) { var user = !userId.Equals(Guid.Empty) ? _userManager.GetUserById(userId) : null; diff --git a/Jellyfin.Api/Controllers/TrailersController.cs b/Jellyfin.Api/Controllers/TrailersController.cs index bd65abd50..645495551 100644 --- a/Jellyfin.Api/Controllers/TrailersController.cs +++ b/Jellyfin.Api/Controllers/TrailersController.cs @@ -132,7 +132,7 @@ namespace Jellyfin.Api.Controllers [HttpGet("/Trailers")] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetTrailers( - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] string? maxOfficialRating, [FromQuery] bool? hasThemeSong, [FromQuery] bool? hasThemeVideo, diff --git a/Jellyfin.Api/Controllers/TvShowsController.cs b/Jellyfin.Api/Controllers/TvShowsController.cs index 80b6a2488..e5b043621 100644 --- a/Jellyfin.Api/Controllers/TvShowsController.cs +++ b/Jellyfin.Api/Controllers/TvShowsController.cs @@ -69,7 +69,7 @@ namespace Jellyfin.Api.Controllers [HttpGet("NextUp")] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetNextUp( - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] int? startIndex, [FromQuery] int? limit, [FromQuery] string? fields, @@ -93,12 +93,14 @@ namespace Jellyfin.Api.Controllers ParentId = parentId, SeriesId = seriesId, StartIndex = startIndex, - UserId = userId, + UserId = userId ?? Guid.Empty, EnableTotalRecordCount = enableTotalRecordCount }, options); - var user = _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var returnItems = _dtoService.GetBaseItemDtos(result.Items, options, user); @@ -125,7 +127,7 @@ namespace Jellyfin.Api.Controllers [HttpGet("Upcoming")] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetUpcomingEpisodes( - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] int? startIndex, [FromQuery] int? limit, [FromQuery] string? fields, @@ -135,7 +137,9 @@ namespace Jellyfin.Api.Controllers [FromQuery] string? enableImageTypes, [FromQuery] bool? enableUserData) { - var user = _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var minPremiereDate = DateTime.Now.Date.ToUniversalTime().AddDays(-1); @@ -191,7 +195,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult> GetEpisodes( [FromRoute] string? seriesId, - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] string? fields, [FromQuery] int? season, [FromQuery] string? seasonId, @@ -206,7 +210,9 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? enableUserData, [FromQuery] string? sortBy) { - var user = _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; List episodes; @@ -312,7 +318,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult> GetSeasons( [FromRoute] string? seriesId, - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] string? fields, [FromQuery] bool? isSpecialSeason, [FromQuery] bool? isMissing, @@ -322,7 +328,9 @@ namespace Jellyfin.Api.Controllers [FromQuery] string? enableImageTypes, [FromQuery] bool? enableUserData) { - var user = _userManager.GetUserById(userId); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; if (!(_libraryManager.GetItemById(seriesId) is Series series)) { diff --git a/Jellyfin.Api/Controllers/UserLibraryController.cs b/Jellyfin.Api/Controllers/UserLibraryController.cs index ca804ebc9..cedda3b9d 100644 --- a/Jellyfin.Api/Controllers/UserLibraryController.cs +++ b/Jellyfin.Api/Controllers/UserLibraryController.cs @@ -180,7 +180,7 @@ namespace Jellyfin.Api.Controllers /// An containing the . [HttpPost("/Users/{userId}/Items/{itemId}/Rating")] [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult UpdateUserItemRating([FromRoute] Guid userId, [FromRoute] Guid itemId, [FromQuery] bool likes) + public ActionResult UpdateUserItemRating([FromRoute] Guid userId, [FromRoute] Guid itemId, [FromQuery] bool? likes) { return UpdateUserItemRatingInternal(userId, itemId, likes); } @@ -264,7 +264,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetLatestMedia( [FromRoute] Guid userId, - [FromQuery] Guid parentId, + [FromQuery] Guid? parentId, [FromQuery] string? fields, [FromQuery] string? includeItemTypes, [FromQuery] bool? isPlayed, @@ -297,7 +297,7 @@ namespace Jellyfin.Api.Controllers IncludeItemTypes = RequestHelpers.Split(includeItemTypes, ',', true), IsPlayed = isPlayed, Limit = limit, - ParentId = parentId, + ParentId = parentId ?? Guid.Empty, UserId = userId, }, dtoOptions); diff --git a/Jellyfin.Api/Controllers/UserViewsController.cs b/Jellyfin.Api/Controllers/UserViewsController.cs index ad8927262..f4bd451ef 100644 --- a/Jellyfin.Api/Controllers/UserViewsController.cs +++ b/Jellyfin.Api/Controllers/UserViewsController.cs @@ -56,8 +56,8 @@ namespace Jellyfin.Api.Controllers /// /// User id. /// Whether or not to include external views such as channels or live tv. - /// Whether or not to include hidden content. /// Preset views. + /// Whether or not to include hidden content. /// User views returned. /// An containing the user views. [HttpGet("/Users/{userId}/Views")] @@ -65,8 +65,8 @@ namespace Jellyfin.Api.Controllers public ActionResult> GetUserViews( [FromRoute] Guid userId, [FromQuery] bool? includeExternalContent, - [FromQuery] bool includeHidden, - [FromQuery] string? presetViews) + [FromQuery] string? presetViews, + [FromQuery] bool includeHidden = false) { var query = new UserViewQuery { diff --git a/Jellyfin.Api/Controllers/VideosController.cs b/Jellyfin.Api/Controllers/VideosController.cs index fb1141984..e2a44427b 100644 --- a/Jellyfin.Api/Controllers/VideosController.cs +++ b/Jellyfin.Api/Controllers/VideosController.cs @@ -53,9 +53,11 @@ namespace Jellyfin.Api.Controllers [HttpGet("{itemId}/AdditionalParts")] [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult> GetAdditionalPart([FromRoute] Guid itemId, [FromQuery] Guid userId) + public ActionResult> GetAdditionalPart([FromRoute] Guid itemId, [FromQuery] Guid? userId) { - var user = !userId.Equals(Guid.Empty) ? _userManager.GetUserById(userId) : null; + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; var item = itemId.Equals(Guid.Empty) ? (!userId.Equals(Guid.Empty) diff --git a/Jellyfin.Api/Controllers/YearsController.cs b/Jellyfin.Api/Controllers/YearsController.cs index a66a3951e..d09b016a9 100644 --- a/Jellyfin.Api/Controllers/YearsController.cs +++ b/Jellyfin.Api/Controllers/YearsController.cs @@ -74,7 +74,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? enableUserData, [FromQuery] int? imageTypeLimit, [FromQuery] string? enableImageTypes, - [FromQuery] Guid userId, + [FromQuery] Guid? userId, [FromQuery] bool recursive = true, [FromQuery] bool? enableImages = true) { @@ -86,9 +86,9 @@ namespace Jellyfin.Api.Controllers User? user = null; BaseItem parentItem; - if (!userId.Equals(Guid.Empty)) + if (userId.HasValue && !userId.Equals(Guid.Empty)) { - user = _userManager.GetUserById(userId); + user = _userManager.GetUserById(userId.Value); parentItem = string.IsNullOrEmpty(parentId) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(parentId); } else @@ -176,7 +176,7 @@ namespace Jellyfin.Api.Controllers [HttpGet("{year}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult GetYear([FromRoute] int year, [FromQuery] Guid userId) + public ActionResult GetYear([FromRoute] int year, [FromQuery] Guid? userId) { var item = _libraryManager.GetYear(year); if (item == null) @@ -187,9 +187,9 @@ namespace Jellyfin.Api.Controllers var dtoOptions = new DtoOptions() .AddClientFields(Request); - if (!userId.Equals(Guid.Empty)) + if (userId.HasValue && !userId.Equals(Guid.Empty)) { - var user = _userManager.GetUserById(userId); + var user = _userManager.GetUserById(userId.Value); return _dtoService.GetBaseItemDto(item, dtoOptions, user); } diff --git a/Jellyfin.Api/Helpers/SimilarItemsHelper.cs b/Jellyfin.Api/Helpers/SimilarItemsHelper.cs index fd0c31504..b922e76cf 100644 --- a/Jellyfin.Api/Helpers/SimilarItemsHelper.cs +++ b/Jellyfin.Api/Helpers/SimilarItemsHelper.cs @@ -4,7 +4,6 @@ using System.Linq; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; @@ -21,14 +20,16 @@ namespace Jellyfin.Api.Helpers IUserManager userManager, ILibraryManager libraryManager, IDtoService dtoService, - Guid userId, + Guid? userId, string id, string? excludeArtistIds, int? limit, Type[] includeTypes, Func, List, BaseItem, int> getSimilarityScore) { - var user = !userId.Equals(Guid.Empty) ? userManager.GetUserById(userId) : null; + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? userManager.GetUserById(userId.Value) + : null; var item = string.IsNullOrEmpty(id) ? (!userId.Equals(Guid.Empty) ? libraryManager.GetUserRootFolder() : @@ -38,11 +39,10 @@ namespace Jellyfin.Api.Helpers { IncludeItemTypes = includeTypes.Select(i => i.Name).ToArray(), Recursive = true, - DtoOptions = dtoOptions + DtoOptions = dtoOptions, + ExcludeArtistIds = RequestHelpers.GetGuids(excludeArtistIds) }; - query.ExcludeArtistIds = RequestHelpers.GetGuids(excludeArtistIds); - var inputItems = libraryManager.GetItemList(query); var items = GetSimilaritems(item, libraryManager, inputItems, getSimilarityScore) -- cgit v1.2.3