aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Jellyfin.Api/Auth/BaseAuthorizationHandler.cs2
-rw-r--r--Jellyfin.Api/Controllers/AlbumsController.cs4
-rw-r--r--Jellyfin.Api/Controllers/ArtistsController.cs102
-rw-r--r--Jellyfin.Api/Controllers/ChannelsController.cs22
-rw-r--r--Jellyfin.Api/Controllers/CollectionController.cs6
-rw-r--r--Jellyfin.Api/Controllers/FilterController.cs12
-rw-r--r--Jellyfin.Api/Controllers/GenresController.cs54
-rw-r--r--Jellyfin.Api/Controllers/InstantMixController.cs44
-rw-r--r--Jellyfin.Api/Controllers/ItemsController.cs10
-rw-r--r--Jellyfin.Api/Controllers/LibraryController.cs56
-rw-r--r--Jellyfin.Api/Controllers/LibraryStructureController.cs20
-rw-r--r--Jellyfin.Api/Controllers/LiveTvController.cs156
-rw-r--r--Jellyfin.Api/Controllers/MediaInfoController.cs40
-rw-r--r--Jellyfin.Api/Controllers/MoviesController.cs26
-rw-r--r--Jellyfin.Api/Controllers/MusicGenresController.cs54
-rw-r--r--Jellyfin.Api/Controllers/PersonsController.cs54
-rw-r--r--Jellyfin.Api/Controllers/PlaylistsController.cs4
-rw-r--r--Jellyfin.Api/Controllers/PlaystateController.cs32
-rw-r--r--Jellyfin.Api/Controllers/RemoteImageController.cs2
-rw-r--r--Jellyfin.Api/Controllers/SearchController.cs4
-rw-r--r--Jellyfin.Api/Controllers/SessionController.cs12
-rw-r--r--Jellyfin.Api/Controllers/StudiosController.cs54
-rw-r--r--Jellyfin.Api/Controllers/SubtitleController.cs4
-rw-r--r--Jellyfin.Api/Controllers/SuggestionsController.cs6
-rw-r--r--Jellyfin.Api/Controllers/TrailersController.cs2
-rw-r--r--Jellyfin.Api/Controllers/TvShowsController.cs26
-rw-r--r--Jellyfin.Api/Controllers/UserLibraryController.cs6
-rw-r--r--Jellyfin.Api/Controllers/UserViewsController.cs6
-rw-r--r--Jellyfin.Api/Controllers/VideosController.cs6
-rw-r--r--Jellyfin.Api/Controllers/YearsController.cs12
-rw-r--r--Jellyfin.Api/Helpers/SimilarItemsHelper.cs12
31 files changed, 442 insertions, 408 deletions
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<QueryResult<BaseItemDto>> 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<QueryResult<BaseItemDto>> 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
/// <returns>An <see cref="OkResult"/> containing the artist.</returns>
[HttpGet("{name}")]
[ProducesResponseType(StatusCodes.Status200OK)]
- public ActionResult<BaseItemDto> GetArtistByName([FromRoute] string name, [FromQuery] Guid userId)
+ public ActionResult<BaseItemDto> 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<QueryResult<BaseItemDto>> 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
/// </summary>
/// <param name="name">The name of the collection.</param>
/// <param name="ids">Item Ids to add to the collection.</param>
- /// <param name="isLocked">Whether or not to lock the new collection.</param>
/// <param name="parentId">Optional. Create the collection within a specific folder.</param>
+ /// <param name="isLocked">Whether or not to lock the new collection.</param>
/// <response code="200">Collection created.</response>
/// <returns>A <see cref="CollectionCreationOptions"/> with information about the new collection.</returns>
[HttpPost]
@@ -53,8 +53,8 @@ namespace Jellyfin.Api.Controllers
public ActionResult<CollectionCreationResult> 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
/// <returns>An <see cref="OkResult"/> containing the genre.</returns>
[HttpGet("{genreName}")]
[ProducesResponseType(StatusCodes.Status200OK)]
- public ActionResult<BaseItemDto> GetGenre([FromRoute] string genreName, [FromQuery] Guid userId)
+ public ActionResult<BaseItemDto> 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<QueryResult<BaseItemDto>> 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<QueryResult<BaseItemDto>> 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<QueryResult<BaseItemDto>> 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<QueryResult<BaseItemDto>> 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<QueryResult<BaseItemDto>> 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<QueryResult<BaseItemDto>> 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<QueryResult<BaseItemDto>> 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<BaseItemDto> GetResult(List<BaseItem> items, User user, int? limit, DtoOptions dtoOptions)
+ private QueryResult<BaseItemDto> GetResult(List<BaseItem> 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<QueryResult<BaseItemDto>> 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<ThemeMediaResult> 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<ThemeMediaResult> 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<AllThemeMediaResult> 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<string>()
- : 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<ItemCounts> 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<IEnumerable<BaseItemDto>> GetAncestors([FromRoute] Guid itemId, [FromQuery] Guid userId)
+ public ActionResult<IEnumerable<BaseItemDto>> GetAncestors([FromRoute] Guid itemId, [FromQuery] Guid? userId)
{
var item = _libraryManager.GetItemById(itemId);
@@ -448,8 +450,8 @@ namespace Jellyfin.Api.Controllers
var baseItemDtos = new List<BaseItemDto>();
- 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<QueryResult<BaseItemDto>> 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<LibraryOptionsResultDto> GetLibraryOptionsInfo([FromQuery] string? libraryContentType, [FromQuery] bool isNewLibrary)
+ public ActionResult<LibraryOptionsResultDto> GetLibraryOptionsInfo(
+ [FromQuery] string? libraryContentType,
+ [FromQuery] bool isNewLibrary = false)
{
var result = new LibraryOptionsResultDto();
@@ -878,13 +882,15 @@ namespace Jellyfin.Api.Controllers
private QueryResult<BaseItemDto> 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
/// </summary>
/// <param name="name">The name of the virtual folder.</param>
/// <param name="collectionType">The type of the collection.</param>
- /// <param name="refreshLibrary">Whether to refresh the library.</param>
/// <param name="paths">The paths of the virtual folder.</param>
/// <param name="libraryOptions">The library options.</param>
+ /// <param name="refreshLibrary">Whether to refresh the library.</param>
/// <response code="204">Folder added.</response>
/// <returns>A <see cref="NoContentResult"/>.</returns>
[HttpPost]
@@ -74,9 +74,9 @@ namespace Jellyfin.Api.Controllers
public async Task<ActionResult> 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<ActionResult> 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
/// <param name="isFavorite">Optional. Filter by channels that are favorites, or not.</param>
/// <param name="isLiked">Optional. Filter by channels that are liked, or not.</param>
/// <param name="isDisliked">Optional. Filter by channels that are disliked, or not.</param>
- /// <param name="enableFavoriteSorting">Optional. Incorporate favorite and like status into channel sorting.</param>
/// <param name="enableImages">Optional. Include image information in output.</param>
/// <param name="imageTypeLimit">Optional. The max number of images to return, per image type.</param>
/// <param name="enableImageTypes">"Optional. The image types to include in the output.</param>
@@ -121,6 +120,7 @@ namespace Jellyfin.Api.Controllers
/// <param name="enableUserData">Optional. Include user data.</param>
/// <param name="sortBy">Optional. Key to sort by.</param>
/// <param name="sortOrder">Optional. Sort order.</param>
+ /// <param name="enableFavoriteSorting">Optional. Incorporate favorite and like status into channel sorting.</param>
/// <param name="addCurrentProgram">Optional. Adds current program info to each channel.</param>
/// <response code="200">Available live tv channels returned.</response>
/// <returns>
@@ -131,7 +131,7 @@ namespace Jellyfin.Api.Controllers
[Authorize(Policy = Policies.DefaultAuthorization)]
public ActionResult<QueryResult<BaseItemDto>> 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<BaseItemDto> GetChannel([FromRoute] Guid channelId, [FromQuery] Guid userId)
+ public ActionResult<BaseItemDto> 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<QueryResult<BaseItemDto>> 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<QueryResult<BaseItemDto>> 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<QueryResult<BaseItemDto>> GetRecordingGroups([FromQuery] Guid userId)
+ public ActionResult<QueryResult<BaseItemDto>> GetRecordingGroups([FromQuery] Guid? userId)
{
return new QueryResult<BaseItemDto>();
}
@@ -379,9 +381,11 @@ namespace Jellyfin.Api.Controllers
[HttpGet("Recordings/Folders")]
[ProducesResponseType(StatusCodes.Status200OK)]
[Authorize(Policy = Policies.DefaultAuthorization)]
- public ActionResult<QueryResult<BaseItemDto>> GetRecordingFolders([FromQuery] Guid userId)
+ public ActionResult<QueryResult<BaseItemDto>> 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<BaseItemDto> GetRecording([FromRoute] Guid recordingId, [FromQuery] Guid userId)
+ public ActionResult<BaseItemDto> 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<ActionResult<SeriesTimerInfoDto>> GetDefaultTimer([FromQuery] string programId)
+ public async Task<ActionResult<SeriesTimerInfoDto>> 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<ActionResult<QueryResult<TimerInfoDto>>> 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<ActionResult<QueryResult<BaseItemDto>>> 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<QueryResult<BaseItemDto>> 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<ActionResult<BaseItemDto>> 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<ActionResult<QueryResult<SeriesTimerInfoDto>>> GetSeriesTimers([FromQuery] string sortBy, [FromQuery] SortOrder sortOrder)
+ public async Task<ActionResult<QueryResult<SeriesTimerInfoDto>>> 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<BaseItemDto> GetRecordingGroup([FromQuery] Guid groupId)
+ public ActionResult<BaseItemDto> 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<LiveTvOptions>("livetv");
config.TunerHosts = config.TunerHosts.Where(i => !string.Equals(id, i.Id, StringComparison.OrdinalIgnoreCase)).ToArray();
@@ -990,10 +1000,10 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Adds a listings provider.
/// </summary>
- /// <param name="validateLogin">Validate login.</param>
- /// <param name="validateListings">Validate listings.</param>
/// <param name="pw">Password.</param>
/// <param name="listingsProviderInfo">New listings info.</param>
+ /// <param name="validateListings">Validate listings.</param>
+ /// <param name="validateLogin">Validate login.</param>
/// <response code="200">Created listings provider returned.</response>
/// <returns>A <see cref="OkResult"/> containing the created listings provider.</returns>
[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<ActionResult<ListingsProviderInfo>> 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<ActionResult<IEnumerable<NameIdPair>>> 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<ActionResult<ChannelMappingOptionsDto>> GetChannelMappingOptions([FromQuery] string providerId)
+ public async Task<ActionResult<ChannelMappingOptionsDto>> GetChannelMappingOptions([FromQuery] string? providerId)
{
var config = _configurationManager.GetConfiguration<LiveTvOptions>("livetv");
@@ -1120,9 +1130,9 @@ namespace Jellyfin.Api.Controllers
[Authorize(Policy = Policies.DefaultAuthorization)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<TunerChannelMapping>> 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<ActionResult<IEnumerable<TunerHostInfo>>> DiscoverTuners([FromQuery] bool newDevicesOnly)
+ public async Task<ActionResult<IEnumerable<TunerHostInfo>>> 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
/// <returns>A <see cref="Task"/> containing a <see cref="PlaybackInfoResponse"/> with the playback information.</returns>
[HttpGet("/Items/{itemId}/PlaybackInfo")]
[ProducesResponseType(StatusCodes.Status200OK)]
- public async Task<ActionResult<PlaybackInfoResponse>> GetPlaybackInfo([FromRoute] Guid itemId, [FromQuery] Guid userId)
+ public async Task<ActionResult<PlaybackInfoResponse>> 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<ActionResult<PlaybackInfoResponse>> 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<ActionResult<LiveStreamResponse>> 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
/// <returns>A <see cref="NoContentResult"/> indicating success.</returns>
[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<PlaybackInfoResponse> 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
/// </summary>
/// <param name="userId">Optional. Filter by user id, and attach user data.</param>
/// <param name="parentId">Specify this to localize the search to a specific item or folder. Omit to use the root.</param>
- /// <param name="enableImages">(Unused) Optional. include image information in output.</param>
- /// <param name="enableUserData">(Unused) Optional. include user data.</param>
- /// <param name="imageTypeLimit">(Unused) Optional. the max number of images to return, per image type.</param>
- /// <param name="enableImageTypes">(Unused) Optional. The image types to include in the output.</param>
/// <param name="fields">Optional. The fields to return.</param>
/// <param name="categoryLimit">The max number of categories to return.</param>
/// <param name="itemLimit">The max number of items to return per category.</param>
/// <response code="200">Movie recommendations returned.</response>
/// <returns>The list of movie recommendations.</returns>
[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<IEnumerable<RecommendationDto>> 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<RecommendationDto> GetWithDirector(
- User user,
+ User? user,
IEnumerable<string> names,
int itemLimit,
DtoOptions dtoOptions,
@@ -230,7 +220,7 @@ namespace Jellyfin.Api.Controllers
}
}
- private IEnumerable<RecommendationDto> GetWithActor(User user, IEnumerable<string> names, int itemLimit, DtoOptions dtoOptions, RecommendationType type)
+ private IEnumerable<RecommendationDto> GetWithActor(User? user, IEnumerable<string> names, int itemLimit, DtoOptions dtoOptions, RecommendationType type)
{
var itemTypes = new List<string> { nameof(Movie) };
if (_serverConfigurationManager.Configuration.EnableExternalContentInSuggestions)
@@ -270,7 +260,7 @@ namespace Jellyfin.Api.Controllers
}
}
- private IEnumerable<RecommendationDto> GetSimilarTo(User user, IEnumerable<BaseItem> baselineItems, int itemLimit, DtoOptions dtoOptions, RecommendationType type)
+ private IEnumerable<RecommendationDto> GetSimilarTo(User? user, IEnumerable<BaseItem> baselineItems, int itemLimit, DtoOptions dtoOptions, RecommendationType type)
{
var itemTypes = new List<string> { 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
/// <returns>An <see cref="OkResult"/> containing a <see cref="BaseItemDto"/> with the music genre.</returns>
[HttpGet("{genreName}")]
[ProducesResponseType(StatusCodes.Status200OK)]
- public ActionResult<BaseItemDto> GetMusicGenre([FromRoute] string genreName, [FromQuery] Guid userId)
+ public ActionResult<BaseItemDto> 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<BaseItemDto> GetPerson([FromRoute] string name, [FromQuery] Guid userId)
+ public ActionResult<BaseItemDto> 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
/// <param name="userId">User id.</param>
/// <param name="itemId">Item id.</param>
/// <param name="mediaSourceId">The id of the MediaSource.</param>
- /// <param name="canSeek">Indicates if the client can seek.</param>
/// <param name="audioStreamIndex">The audio stream index.</param>
/// <param name="subtitleStreamIndex">The subtitle stream index.</param>
/// <param name="playMethod">The play method.</param>
/// <param name="liveStreamId">The live stream id.</param>
/// <param name="playSessionId">The play session id.</param>
+ /// <param name="canSeek">Indicates if the client can seek.</param>
/// <response code="204">Play start recorded.</response>
/// <returns>A <see cref="NoContentResult"/>.</returns>
[HttpPost("/Users/{userId}/PlayingItems/{itemId}")]
@@ -202,13 +202,13 @@ namespace Jellyfin.Api.Controllers
public async Task<ActionResult> 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
/// <param name="itemId">Item id.</param>
/// <param name="mediaSourceId">The id of the MediaSource.</param>
/// <param name="positionTicks">Optional. The current position, in ticks. 1 tick = 10000 ms.</param>
- /// <param name="isPaused">Indicates if the player is paused.</param>
- /// <param name="isMuted">Indicates if the player is muted.</param>
/// <param name="audioStreamIndex">The audio stream index.</param>
/// <param name="subtitleStreamIndex">The subtitle stream index.</param>
/// <param name="volumeLevel">Scale of 0-100.</param>
@@ -244,6 +242,8 @@ namespace Jellyfin.Api.Controllers
/// <param name="liveStreamId">The live stream id.</param>
/// <param name="playSessionId">The play session id.</param>
/// <param name="repeatMode">The repeat mode.</param>
+ /// <param name="isPaused">Indicates if the player is paused.</param>
+ /// <param name="isMuted">Indicates if the player is muted.</param>
/// <response code="204">Play progress recorded.</response>
/// <returns>A <see cref="NoContentResult"/>.</returns>
[HttpPost("/Users/{userId}/PlayingItems/{itemId}/Progress")]
@@ -252,17 +252,17 @@ namespace Jellyfin.Api.Controllers
public async Task<ActionResult> 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<ActionResult> 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<SearchHintResult> 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<IEnumerable<SessionInfo>> 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
/// <returns>An <see cref="OkResult"/> containing the studio.</returns>
[HttpGet("{name}")]
[ProducesResponseType(StatusCodes.Status200OK)]
- public ActionResult<BaseItemDto> GetStudio([FromRoute] string name, [FromQuery] Guid userId)
+ public ActionResult<BaseItemDto> 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
/// <param name="userId">The user id.</param>
/// <param name="mediaType">The media types.</param>
/// <param name="type">The type.</param>
- /// <param name="enableTotalRecordCount">Whether to enable the total record count.</param>
/// <param name="startIndex">Optional. The start index.</param>
/// <param name="limit">Optional. The limit.</param>
+ /// <param name="enableTotalRecordCount">Whether to enable the total record count.</param>
/// <response code="200">Suggestions returned.</response>
/// <returns>A <see cref="QueryResult{BaseItemDto}"/> with the suggestions.</returns>
[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<QueryResult<BaseItemDto>> 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<QueryResult<BaseItemDto>> 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<QueryResult<BaseItemDto>> 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<QueryResult<BaseItemDto>> 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<BaseItem> episodes;
@@ -312,7 +318,7 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<QueryResult<BaseItemDto>> 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
/// <returns>An <see cref="OkResult"/> containing the <see cref="UserItemDataDto"/>.</returns>
[HttpPost("/Users/{userId}/Items/{itemId}/Rating")]
[ProducesResponseType(StatusCodes.Status200OK)]
- public ActionResult<UserItemDataDto> UpdateUserItemRating([FromRoute] Guid userId, [FromRoute] Guid itemId, [FromQuery] bool likes)
+ public ActionResult<UserItemDataDto> 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<IEnumerable<BaseItemDto>> 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
/// </summary>
/// <param name="userId">User id.</param>
/// <param name="includeExternalContent">Whether or not to include external views such as channels or live tv.</param>
- /// <param name="includeHidden">Whether or not to include hidden content.</param>
/// <param name="presetViews">Preset views.</param>
+ /// <param name="includeHidden">Whether or not to include hidden content.</param>
/// <response code="200">User views returned.</response>
/// <returns>An <see cref="OkResult"/> containing the user views.</returns>
[HttpGet("/Users/{userId}/Views")]
@@ -65,8 +65,8 @@ namespace Jellyfin.Api.Controllers
public ActionResult<QueryResult<BaseItemDto>> 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<QueryResult<BaseItemDto>> GetAdditionalPart([FromRoute] Guid itemId, [FromQuery] Guid userId)
+ public ActionResult<QueryResult<BaseItemDto>> 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<BaseItemDto> GetYear([FromRoute] int year, [FromQuery] Guid userId)
+ public ActionResult<BaseItemDto> 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<BaseItem, List<PersonInfo>, List<PersonInfo>, 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)