From 60ab4cd7b12725d698edfdc07292d8d6e5cded5c Mon Sep 17 00:00:00 2001 From: crobibero Date: Wed, 24 Jun 2020 12:23:46 -0600 Subject: move YearsService.cs to Jellyfin.Api --- Jellyfin.Api/Controllers/YearsController.cs | 226 ++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 Jellyfin.Api/Controllers/YearsController.cs (limited to 'Jellyfin.Api/Controllers/YearsController.cs') diff --git a/Jellyfin.Api/Controllers/YearsController.cs b/Jellyfin.Api/Controllers/YearsController.cs new file mode 100644 index 000000000..2d8ef69cb --- /dev/null +++ b/Jellyfin.Api/Controllers/YearsController.cs @@ -0,0 +1,226 @@ +using System; +using Jellyfin.Api.Extensions; +using MediaBrowser.Controller.Dto; +using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Querying; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace Jellyfin.Api.Controllers +{ + public class YearsController : BaseJellyfinApiController + { + private readonly ILibraryManager _libraryManager; + private readonly IUserManager _userManager; + private readonly IDtoService _dtoService; + + /// + /// Get years. + /// + /// Optional. Filter by maximum official rating (PG, PG-13, TV-MA, etc). + /// Optional. Filter by items with theme songs. + /// Optional. Filter by items with theme videos. + /// Optional. Filter by items with subtitles. + /// Optional. Filter by items with special features. + /// Optional. Filter by items with trailers. + /// Optional. Return items that are siblings of a supplied item. + /// Optional. Filter by minimum index number. + /// Optional. Filter by parent index number. + /// Optional. filter by items that have or do not have a parental rating. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + [HttpGet] + public ActionResult> GetYears( + [FromQuery] string maxOfficialRating, + [FromQuery] bool? hasThemeSong, + [FromQuery] bool? hasThemeVideo, + [FromQuery] bool? hasSubtitles, + [FromQuery] bool? hasSpecialFeatures, + [FromQuery] bool? hasTrailer, + [FromQuery] string adjacentTo, + [FromQuery] int? minIndexNumber, + [FromQuery] int? parentIndexNumber, + [FromQuery] bool? hasParentalRating, + [FromQuery] bool? isHd, + [FromQuery] bool? is4k, + [FromQuery] string locationTypes, + [FromQuery] string excludeLocationTypes, + [FromQuery] bool? isMissing, + [FromQuery] bool? isUnaired, + [FromQuery] double? minCommunityRating, + [FromQuery] double? minCriticRating, + [FromQuery] int? airedDuringSeason, + [FromQuery] DateTime? minPremiereDate, + [FromQuery] DateTime? minDateLastSaved, + [FromQuery] DateTime? minDateLastSavedForUser, + [FromQuery] DateTime? maxPremiereDate, + [FromQuery] bool? hasOverview, + [FromQuery] bool? hasImdbId, + [FromQuery] bool? hasTmdbId, + [FromQuery] bool? hasTvdbId, + [FromQuery] string excludeItemIds, + [FromQuery] int? startIndex, + [FromQuery] int? limit, + [FromQuery] string searchTerm, + [FromQuery] string sortOrder, + [FromQuery] string parentId, + [FromQuery] string fields, + [FromQuery] string excludeItemTypes, + [FromQuery] string includeItemTypes, + [FromQuery] string filters, + [FromQuery] bool? isFavorite, + [FromQuery] string mediaTypes, + [FromQuery] string imageTypes, + [FromQuery] string sortBy, + [FromQuery] bool? isPlayed, + [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] string artists, + [FromQuery] string excludeArtistIds, + [FromQuery] string artistIds, + [FromQuery] string albumArtistIds, + [FromQuery] string contributingArtistIds, + [FromQuery] string albums, + [FromQuery] string albumIds, + [FromQuery] string ids, + [FromQuery] string videoTypes, + [FromQuery] Guid userId, + [FromQuery] string minOfficialRating, + [FromQuery] bool? isLocked, + [FromQuery] bool? isPlaceholder, + [FromQuery] bool? hasOfficialRating, + [FromQuery] bool? collapseBoxSetItems, + [FromQuery] int? minWidth, + [FromQuery] int? minHeight, + [FromQuery] int? maxWidth, + [FromQuery] int? maxHeight, + [FromQuery] bool? is3d, + [FromQuery] string seriesStatus, + [FromQuery] string nameStartsWithOrGreater, + [FromQuery] string nameStartsWith, + [FromQuery] string nameLessThan, + [FromQuery] bool recursive = true, + [FromQuery] bool? enableImages = true, + [FromQuery] bool enableTotalRecordCount = true) + { + + } + + /// + /// Gets a year. + /// + /// The year. + /// Optional. Filter by user id, and attach user data. + /// Year returned. + /// Year not found. + /// + /// An containing the year, + /// or a if year not found. + /// + [HttpGet("{year}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public ActionResult GetYear([FromRoute] int year, [FromQuery] Guid userId) + { + var item = _libraryManager.GetYear(year); + if (item == null) + { + return NotFound(); + } + + var dtoOptions = new DtoOptions() + .AddClientFields(Request); + + if (!userId.Equals(Guid.Empty)) + { + var user = _userManager.GetUserById(userId); + return _dtoService.GetBaseItemDto(item, dtoOptions, user); + } + + return _dtoService.GetBaseItemDto(item, dtoOptions); + } + } +} -- cgit v1.2.3 From e72a22c5649d2bb3581b3ee5efd3dbbea370d89c Mon Sep 17 00:00:00 2001 From: crobibero Date: Wed, 24 Jun 2020 13:48:22 -0600 Subject: Move YearsService.cs to Jellyfin.Api --- Jellyfin.Api/Controllers/YearsController.cs | 361 +++++++++++++++++++++------ Jellyfin.Api/Helpers/RequestHelpers.cs | 41 +++ MediaBrowser.Api/UserLibrary/YearsService.cs | 77 ------ 3 files changed, 329 insertions(+), 150 deletions(-) delete mode 100644 MediaBrowser.Api/UserLibrary/YearsService.cs (limited to 'Jellyfin.Api/Controllers/YearsController.cs') diff --git a/Jellyfin.Api/Controllers/YearsController.cs b/Jellyfin.Api/Controllers/YearsController.cs index 2d8ef69cb..a480b78ea 100644 --- a/Jellyfin.Api/Controllers/YearsController.cs +++ b/Jellyfin.Api/Controllers/YearsController.cs @@ -1,6 +1,12 @@ using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; using Jellyfin.Api.Extensions; +using Jellyfin.Api.Helpers; +using Jellyfin.Data.Entities; using MediaBrowser.Controller.Dto; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Querying; @@ -9,12 +15,31 @@ using Microsoft.AspNetCore.Mvc; namespace Jellyfin.Api.Controllers { + /// + /// Years controller. + /// public class YearsController : BaseJellyfinApiController { private readonly ILibraryManager _libraryManager; private readonly IUserManager _userManager; private readonly IDtoService _dtoService; + /// + /// Initializes a new instance of the class. + /// + /// Instance of the interface. + /// Instance of the interface. + /// Instance of the interface. + public YearsController( + ILibraryManager libraryManager, + IUserManager userManager, + IDtoService dtoService) + { + _libraryManager = libraryManager; + _userManager = userManager; + _dtoService = dtoService; + } + /// /// Get years. /// @@ -28,80 +53,157 @@ namespace Jellyfin.Api.Controllers /// Optional. Filter by minimum index number. /// Optional. Filter by parent index number. /// Optional. filter by items that have or do not have a parental rating. - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// + /// Optional. Filter by items that are HD or not. + /// Optional. Filter by items that are 4K or not. + /// Optional. If specified, results will be filtered based on LocationType. This allows multiple, comma delimited. + /// Optional. If specified, results will be excluded based on LocationType. This allows multiple, comma delimited. + /// Optional. Filter by items that are missing episodes or not. + /// Optional. Filter by items that are unaired episodes or not. + /// Optional. Filter by minimum community rating. + /// Optional. Filter by minimum critic rating. + /// Gets all episodes that aired during a season, including specials. + /// Optional. The minimum premiere date. + /// Optional. The minimum last saved date. + /// Optional. The minimum last saved date for user. + /// Optional. The maximum premiere date. + /// Optional. Filter by items that have an overview or not. + /// Optional. Filter by items that have an imdb id or not. + /// Optional. Filter by items that have a tmdb id or not. + /// Optional. Filter by items that have a tvdb id or not. + /// Optional. If specified, results will be filtered by excluding item ids. This allows multiple, comma delimited. + /// Skips over a given number of items within the results. Use for paging. + /// Optional. The maximum number of records to return. + /// Optional. Search term. + /// Sort Order - Ascending,Descending. + /// Specify this to localize the search to a specific item or folder. Omit to use the root. + /// 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. If specified, results will be excluded based on item type. This allows multiple, comma delimited. + /// Optional. If specified, results will be included based on item type. This allows multiple, comma delimited. + /// Optional. Specify additional filters to apply. This allows multiple, comma delimited. Options: IsFolder, IsNotFolder, IsUnplayed, IsPlayed, IsFavorite, IsResumable, Likes, Dislikes. + /// Optional. Filter by items that are marked as favorite, or not. + /// Optional. Filter by MediaType. Allows multiple, comma delimited. + /// Optional. If specified, results will be filtered based on those containing image types. This allows multiple, comma delimited. + /// Optional. Specify one or more sort orders, comma delimited. Options: Album, AlbumArtist, Artist, Budget, CommunityRating, CriticRating, DateCreated, DatePlayed, PlayCount, PremiereDate, ProductionYear, SortName, Random, Revenue, Runtime. + /// Optional. Filter by items that are played, or not. + /// Optional. If specified, results will be filtered based on genre. This allows multiple, pipe delimited. + /// Optional. If specified, results will be filtered based on genre id. This allows multiple, pipe delimited. + /// Optional. If specified, results will be filtered based on OfficialRating. This allows multiple, pipe delimited. + /// Optional. If specified, results will be filtered based on tag. This allows multiple, pipe delimited. + /// Optional. If specified, results will be filtered based on production year. This allows multiple, comma delimited. + /// Optional. Include user data. + /// Optional. The max number of images to return, per image type. + /// Optional. The image types to include in the output. + /// Optional. If specified, results will be filtered to include only those containing the specified person. + /// Optional. If specified, results will be filtered to include only those containing the specified person ids. + /// Optional. If specified, along with Person, results will be filtered to include only those containing the specified person and PersonType. Allows multiple, comma-delimited. + /// Optional. If specified, results will be filtered based on studio. This allows multiple, pipe delimited. + /// Optional. If specified, results will be filtered based on studio id. This allows multiple, pipe delimited. + /// Optional. If specified, results will be filtered based on artist. This allows multiple, pipe delimited. + /// Optional. If specified, results will be excluded based on artist id. This allows multiple, pipe delimited. + /// Optional. If specified, results will be filtered based on artist id. This allows multiple, pipe delimited. + /// Optional. If specified, results will be filtered based on album artist id. This allows multiple, pipe delimited. + /// Optional. If specified, results will be filtered based on contributing artist id. This allows multiple, pipe delimited. + /// Optional. If specified, results will be filtered based on album. This allows multiple, pipe delimited. + /// Optional. If specified, results will be filtered based on album id. This allows multiple, pipe delimited. + /// Optional. If specific items are needed, specify a list of item id's to retrieve. This allows multiple, comma delimited. + /// Optional. Filter by VideoType (videofile, dvd, bluray, iso). Allows multiple, comma delimited. + /// User Id. + /// Optional. Filter by minimum official rating (PG, PG-13, TV-MA, etc). + /// Optional. Filter by items that are locked. + /// Optional. Filter by items that are placeholders. + /// Optional. Filter by items that have official ratings. + /// Whether or not to hide items behind their boxsets. + /// Min width. + /// Min height. + /// Max width. + /// Max height. + /// Optional. Filter by items that are 3D, or not. + /// Optional. Filter by Series Status. Allows multiple, comma delimited. + /// Optional. Filter by items whose name is sorted equally or greater than a given input string. + /// Optional. Filter by items whose name is sorted equally than a given input string. + /// Optional. Filter by items whose name is equally or lesser than a given input string. + /// Search recursively. + /// Optional. Include image information in output. + /// Return total record count. + /// Year query returned. + /// A containing the year result. [HttpGet] + [ProducesResponseType(StatusCodes.Status200OK)] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "maxOfficialRating", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasThemeSong", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasThemeVideo", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasSubtitles", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasSpecialFeatures", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasTrailer", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "adjacentTo", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "minIndexNumber", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "parentIndexNumber", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasParentalRating", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isHd", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "is4k", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "locationTypes", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "excludeLocationTypes", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isMissing", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isUnaired", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "minCommunityRating", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "minCriticRating", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "airedDuringSeason", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "minPremiereDate", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "minDateLastSaved", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "minDateLastSavedForUser", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "maxPremiereDate", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasOverview", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasImdbId", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasTmdbId", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasTvdbId", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "excludeItemIds", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "searchTerm", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "filters", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isFavorite", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "imageTypes", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isPlayed", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "genres", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "genreIds", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "officialRatings", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "tags", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "years", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "person", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "personIds", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "personTypes", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "studios", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "studioIds", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "artists", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "excludeArtistIds", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "artistIds", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "albumArtistIds", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "contributingArtistIds", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "personIds", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "personTypes", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "studios", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "studioIds", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "artists", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "excludeArtistIds", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "artistIds", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "albumArtistIds", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "contributingArtistIds", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "albums", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "albumIds", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "ids", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "videoTypes", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isLocked", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isPlaceholder", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasOfficialRating", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "collapseBoxSetItems", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "minWidth", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "minHeight", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "maxWidth", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "maxHeight", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "is3d", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "seriesStatus", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "nameStartsWithOrGreater", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "nameStartsWith", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "nameLessThan", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "enableTotalRecordCount", Justification = "Imported from ServiceStack")] public ActionResult> GetYears( [FromQuery] string maxOfficialRating, [FromQuery] bool? hasThemeSong, @@ -186,7 +288,88 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? enableImages = true, [FromQuery] bool enableTotalRecordCount = true) { + var dtoOptions = new DtoOptions() + .AddItemFields(fields) + .AddClientFields(Request) + .AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes); + + User? user = null; + BaseItem parentItem; + + if (!userId.Equals(Guid.Empty)) + { + user = _userManager.GetUserById(userId); + parentItem = string.IsNullOrEmpty(parentId) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(parentId); + } + else + { + parentItem = string.IsNullOrEmpty(parentId) ? _libraryManager.RootFolder : _libraryManager.GetItemById(parentId); + } + + IList items; + + var excludeItemTypesArr = RequestHelpers.Split(excludeItemTypes, ',', true); + var includeItemTypesArr = RequestHelpers.Split(includeItemTypes, ',', true); + var mediaTypesArr = RequestHelpers.Split(mediaTypes, ',', true); + + var query = new InternalItemsQuery(user) + { + ExcludeItemTypes = excludeItemTypesArr, + IncludeItemTypes = includeItemTypesArr, + MediaTypes = mediaTypesArr, + DtoOptions = dtoOptions + }; + + bool Filter(BaseItem i) => FilterItem(i, excludeItemTypesArr, includeItemTypesArr, mediaTypesArr); + + if (parentItem.IsFolder) + { + var folder = (Folder)parentItem; + + if (!userId.Equals(Guid.Empty)) + { + items = recursive ? folder.GetRecursiveChildren(user, query).ToList() : folder.GetChildren(user, true).Where(Filter).ToList(); + } + else + { + items = recursive ? folder.GetRecursiveChildren(Filter) : folder.Children.Where(Filter).ToList(); + } + } + else + { + items = new[] { parentItem }.Where(Filter).ToList(); + } + + var extractedItems = GetAllItems(items); + var filteredItems = _libraryManager.Sort(extractedItems, user, RequestHelpers.GetOrderBy(sortBy, sortOrder)); + + var ibnItemsArray = filteredItems.ToList(); + + IEnumerable ibnItems = ibnItemsArray; + + var result = new QueryResult { TotalRecordCount = ibnItemsArray.Count }; + + if (startIndex.HasValue || limit.HasValue) + { + if (startIndex.HasValue) + { + ibnItems = ibnItems.Skip(startIndex.Value); + } + + if (limit.HasValue) + { + ibnItems = ibnItems.Take(limit.Value); + } + } + + var tuples = ibnItems.Select(i => new Tuple>(i, new List())); + + var dtos = tuples.Select(i => _dtoService.GetItemByNameDto(i.Item1, dtoOptions, i.Item2, user)); + + result.Items = dtos.Where(i => i != null).ToArray(); + + return result; } /// @@ -222,5 +405,37 @@ namespace Jellyfin.Api.Controllers return _dtoService.GetBaseItemDto(item, dtoOptions); } + + private bool FilterItem(BaseItem f, IReadOnlyCollection excludeItemTypes, IReadOnlyCollection includeItemTypes, IReadOnlyCollection mediaTypes) + { + // Exclude item types + if (excludeItemTypes.Count > 0 && excludeItemTypes.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + + // Include item types + if (includeItemTypes.Count > 0 && !includeItemTypes.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + + // Include MediaTypes + if (mediaTypes.Count > 0 && !mediaTypes.Contains(f.MediaType ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + + return true; + } + + private IEnumerable GetAllItems(IEnumerable items) + { + return items + .Select(i => i.ProductionYear ?? 0) + .Where(i => i > 0) + .Distinct() + .Select(year => _libraryManager.GetYear(year)); + } } } diff --git a/Jellyfin.Api/Helpers/RequestHelpers.cs b/Jellyfin.Api/Helpers/RequestHelpers.cs index e2a0cf4fa..6ba62b2e4 100644 --- a/Jellyfin.Api/Helpers/RequestHelpers.cs +++ b/Jellyfin.Api/Helpers/RequestHelpers.cs @@ -3,6 +3,7 @@ using System.Linq; using Jellyfin.Data.Enums; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Session; +using MediaBrowser.Model.Entities; using Microsoft.AspNetCore.Http; namespace Jellyfin.Api.Helpers @@ -91,5 +92,45 @@ namespace Jellyfin.Api.Helpers .Select(i => new Guid(i)) .ToArray(); } + + /// + /// Get orderby. + /// + /// Sort by. + /// Sort order. + /// Resulting order by. + internal static ValueTuple[] GetOrderBy(string sortBy, string requestedSortOrder) + { + var val = sortBy; + + if (string.IsNullOrEmpty(val)) + { + return Array.Empty>(); + } + + var vals = val.Split(','); + if (string.IsNullOrWhiteSpace(requestedSortOrder)) + { + requestedSortOrder = "Ascending"; + } + + var sortOrders = requestedSortOrder.Split(','); + + var result = new ValueTuple[vals.Length]; + + for (var i = 0; i < vals.Length; i++) + { + var sortOrderIndex = sortOrders.Length > i ? i : 0; + + var sortOrderValue = sortOrders.Length > sortOrderIndex ? sortOrders[sortOrderIndex] : null; + var sortOrder = string.Equals(sortOrderValue, "Descending", StringComparison.OrdinalIgnoreCase) + ? SortOrder.Descending + : SortOrder.Ascending; + + result[i] = new ValueTuple(vals[i], sortOrder); + } + + return result; + } } } diff --git a/MediaBrowser.Api/UserLibrary/YearsService.cs b/MediaBrowser.Api/UserLibrary/YearsService.cs deleted file mode 100644 index f34884f8b..000000000 --- a/MediaBrowser.Api/UserLibrary/YearsService.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Dto; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Net; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Services; -using Microsoft.Extensions.Logging; - -namespace MediaBrowser.Api.UserLibrary -{ - /// - /// Class GetYears - /// - [Route("/Years", "GET", Summary = "Gets all years from a given item, folder, or the entire library")] - public class GetYears : GetItemsByName - { - } - - /// - /// Class YearsService - /// - [Authenticated] - public class YearsService : BaseItemsByNameService - { - public YearsService( - ILogger logger, - IServerConfigurationManager serverConfigurationManager, - IHttpResultFactory httpResultFactory, - IUserManager userManager, - ILibraryManager libraryManager, - IUserDataManager userDataRepository, - IDtoService dtoService, - IAuthorizationContext authorizationContext) - : base( - logger, - serverConfigurationManager, - httpResultFactory, - userManager, - libraryManager, - userDataRepository, - dtoService, - authorizationContext) - { - } - - /// - /// Gets the specified request. - /// - /// The request. - /// System.Object. - public object Get(GetYears request) - { - var result = GetResult(request); - - return ToOptimizedResult(result); - } - - /// - /// Gets all items. - /// - /// The request. - /// The items. - /// IEnumerable{Tuple{System.StringFunc{System.Int32}}}. - protected override IEnumerable GetAllItems(GetItemsByName request, IList items) - { - return items - .Select(i => i.ProductionYear ?? 0) - .Where(i => i > 0) - .Distinct() - .Select(year => LibraryManager.GetYear(year)); - } - } -} -- cgit v1.2.3 From 1228d6711e44d63eca9f1909a3844fa896ec4587 Mon Sep 17 00:00:00 2001 From: crobibero Date: Wed, 24 Jun 2020 14:35:57 -0600 Subject: remove unused parameters --- Jellyfin.Api/Controllers/YearsController.cs | 212 +--------------------------- 1 file changed, 1 insertion(+), 211 deletions(-) (limited to 'Jellyfin.Api/Controllers/YearsController.cs') diff --git a/Jellyfin.Api/Controllers/YearsController.cs b/Jellyfin.Api/Controllers/YearsController.cs index a480b78ea..a036c818c 100644 --- a/Jellyfin.Api/Controllers/YearsController.cs +++ b/Jellyfin.Api/Controllers/YearsController.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Linq; using Jellyfin.Api.Extensions; using Jellyfin.Api.Helpers; @@ -43,250 +42,41 @@ namespace Jellyfin.Api.Controllers /// /// Get years. /// - /// Optional. Filter by maximum official rating (PG, PG-13, TV-MA, etc). - /// Optional. Filter by items with theme songs. - /// Optional. Filter by items with theme videos. - /// Optional. Filter by items with subtitles. - /// Optional. Filter by items with special features. - /// Optional. Filter by items with trailers. - /// Optional. Return items that are siblings of a supplied item. - /// Optional. Filter by minimum index number. - /// Optional. Filter by parent index number. - /// Optional. filter by items that have or do not have a parental rating. - /// Optional. Filter by items that are HD or not. - /// Optional. Filter by items that are 4K or not. - /// Optional. If specified, results will be filtered based on LocationType. This allows multiple, comma delimited. - /// Optional. If specified, results will be excluded based on LocationType. This allows multiple, comma delimited. - /// Optional. Filter by items that are missing episodes or not. - /// Optional. Filter by items that are unaired episodes or not. - /// Optional. Filter by minimum community rating. - /// Optional. Filter by minimum critic rating. - /// Gets all episodes that aired during a season, including specials. - /// Optional. The minimum premiere date. - /// Optional. The minimum last saved date. - /// Optional. The minimum last saved date for user. - /// Optional. The maximum premiere date. - /// Optional. Filter by items that have an overview or not. - /// Optional. Filter by items that have an imdb id or not. - /// Optional. Filter by items that have a tmdb id or not. - /// Optional. Filter by items that have a tvdb id or not. - /// Optional. If specified, results will be filtered by excluding item ids. This allows multiple, comma delimited. /// Skips over a given number of items within the results. Use for paging. /// Optional. The maximum number of records to return. - /// Optional. Search term. /// Sort Order - Ascending,Descending. /// Specify this to localize the search to a specific item or folder. Omit to use the root. /// 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. If specified, results will be excluded based on item type. This allows multiple, comma delimited. /// Optional. If specified, results will be included based on item type. This allows multiple, comma delimited. - /// Optional. Specify additional filters to apply. This allows multiple, comma delimited. Options: IsFolder, IsNotFolder, IsUnplayed, IsPlayed, IsFavorite, IsResumable, Likes, Dislikes. - /// Optional. Filter by items that are marked as favorite, or not. /// Optional. Filter by MediaType. Allows multiple, comma delimited. - /// Optional. If specified, results will be filtered based on those containing image types. This allows multiple, comma delimited. /// Optional. Specify one or more sort orders, comma delimited. Options: Album, AlbumArtist, Artist, Budget, CommunityRating, CriticRating, DateCreated, DatePlayed, PlayCount, PremiereDate, ProductionYear, SortName, Random, Revenue, Runtime. - /// Optional. Filter by items that are played, or not. - /// Optional. If specified, results will be filtered based on genre. This allows multiple, pipe delimited. - /// Optional. If specified, results will be filtered based on genre id. This allows multiple, pipe delimited. - /// Optional. If specified, results will be filtered based on OfficialRating. This allows multiple, pipe delimited. - /// Optional. If specified, results will be filtered based on tag. This allows multiple, pipe delimited. - /// Optional. If specified, results will be filtered based on production year. This allows multiple, comma delimited. /// Optional. Include user data. /// Optional. The max number of images to return, per image type. /// Optional. The image types to include in the output. - /// Optional. If specified, results will be filtered to include only those containing the specified person. - /// Optional. If specified, results will be filtered to include only those containing the specified person ids. - /// Optional. If specified, along with Person, results will be filtered to include only those containing the specified person and PersonType. Allows multiple, comma-delimited. - /// Optional. If specified, results will be filtered based on studio. This allows multiple, pipe delimited. - /// Optional. If specified, results will be filtered based on studio id. This allows multiple, pipe delimited. - /// Optional. If specified, results will be filtered based on artist. This allows multiple, pipe delimited. - /// Optional. If specified, results will be excluded based on artist id. This allows multiple, pipe delimited. - /// Optional. If specified, results will be filtered based on artist id. This allows multiple, pipe delimited. - /// Optional. If specified, results will be filtered based on album artist id. This allows multiple, pipe delimited. - /// Optional. If specified, results will be filtered based on contributing artist id. This allows multiple, pipe delimited. - /// Optional. If specified, results will be filtered based on album. This allows multiple, pipe delimited. - /// Optional. If specified, results will be filtered based on album id. This allows multiple, pipe delimited. - /// Optional. If specific items are needed, specify a list of item id's to retrieve. This allows multiple, comma delimited. - /// Optional. Filter by VideoType (videofile, dvd, bluray, iso). Allows multiple, comma delimited. /// User Id. - /// Optional. Filter by minimum official rating (PG, PG-13, TV-MA, etc). - /// Optional. Filter by items that are locked. - /// Optional. Filter by items that are placeholders. - /// Optional. Filter by items that have official ratings. - /// Whether or not to hide items behind their boxsets. - /// Min width. - /// Min height. - /// Max width. - /// Max height. - /// Optional. Filter by items that are 3D, or not. - /// Optional. Filter by Series Status. Allows multiple, comma delimited. - /// Optional. Filter by items whose name is sorted equally or greater than a given input string. - /// Optional. Filter by items whose name is sorted equally than a given input string. - /// Optional. Filter by items whose name is equally or lesser than a given input string. /// Search recursively. /// Optional. Include image information in output. - /// Return total record count. /// Year query returned. /// A containing the year result. [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "maxOfficialRating", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasThemeSong", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasThemeVideo", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasSubtitles", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasSpecialFeatures", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasTrailer", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "adjacentTo", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "minIndexNumber", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "parentIndexNumber", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasParentalRating", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isHd", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "is4k", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "locationTypes", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "excludeLocationTypes", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isMissing", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isUnaired", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "minCommunityRating", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "minCriticRating", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "airedDuringSeason", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "minPremiereDate", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "minDateLastSaved", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "minDateLastSavedForUser", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "maxPremiereDate", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasOverview", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasImdbId", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasTmdbId", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasTvdbId", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "excludeItemIds", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "searchTerm", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "filters", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isFavorite", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "imageTypes", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isPlayed", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "genres", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "genreIds", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "officialRatings", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "tags", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "years", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "person", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "personIds", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "personTypes", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "studios", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "studioIds", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "artists", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "excludeArtistIds", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "artistIds", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "albumArtistIds", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "contributingArtistIds", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "personIds", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "personTypes", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "studios", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "studioIds", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "artists", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "excludeArtistIds", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "artistIds", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "albumArtistIds", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "contributingArtistIds", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "albums", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "albumIds", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "ids", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "videoTypes", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isLocked", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isPlaceholder", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "hasOfficialRating", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "collapseBoxSetItems", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "minWidth", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "minHeight", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "maxWidth", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "maxHeight", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "is3d", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "seriesStatus", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "nameStartsWithOrGreater", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "nameStartsWith", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "nameLessThan", Justification = "Imported from ServiceStack")] - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "enableTotalRecordCount", Justification = "Imported from ServiceStack")] public ActionResult> GetYears( - [FromQuery] string maxOfficialRating, - [FromQuery] bool? hasThemeSong, - [FromQuery] bool? hasThemeVideo, - [FromQuery] bool? hasSubtitles, - [FromQuery] bool? hasSpecialFeatures, - [FromQuery] bool? hasTrailer, - [FromQuery] string adjacentTo, - [FromQuery] int? minIndexNumber, - [FromQuery] int? parentIndexNumber, - [FromQuery] bool? hasParentalRating, - [FromQuery] bool? isHd, - [FromQuery] bool? is4k, - [FromQuery] string locationTypes, - [FromQuery] string excludeLocationTypes, - [FromQuery] bool? isMissing, - [FromQuery] bool? isUnaired, - [FromQuery] double? minCommunityRating, - [FromQuery] double? minCriticRating, - [FromQuery] int? airedDuringSeason, - [FromQuery] DateTime? minPremiereDate, - [FromQuery] DateTime? minDateLastSaved, - [FromQuery] DateTime? minDateLastSavedForUser, - [FromQuery] DateTime? maxPremiereDate, - [FromQuery] bool? hasOverview, - [FromQuery] bool? hasImdbId, - [FromQuery] bool? hasTmdbId, - [FromQuery] bool? hasTvdbId, - [FromQuery] string excludeItemIds, [FromQuery] int? startIndex, [FromQuery] int? limit, - [FromQuery] string searchTerm, [FromQuery] string sortOrder, [FromQuery] string parentId, [FromQuery] string fields, [FromQuery] string excludeItemTypes, [FromQuery] string includeItemTypes, - [FromQuery] string filters, - [FromQuery] bool? isFavorite, [FromQuery] string mediaTypes, - [FromQuery] string imageTypes, [FromQuery] string sortBy, - [FromQuery] bool? isPlayed, - [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] string artists, - [FromQuery] string excludeArtistIds, - [FromQuery] string artistIds, - [FromQuery] string albumArtistIds, - [FromQuery] string contributingArtistIds, - [FromQuery] string albums, - [FromQuery] string albumIds, - [FromQuery] string ids, - [FromQuery] string videoTypes, [FromQuery] Guid userId, - [FromQuery] string minOfficialRating, - [FromQuery] bool? isLocked, - [FromQuery] bool? isPlaceholder, - [FromQuery] bool? hasOfficialRating, - [FromQuery] bool? collapseBoxSetItems, - [FromQuery] int? minWidth, - [FromQuery] int? minHeight, - [FromQuery] int? maxWidth, - [FromQuery] int? maxHeight, - [FromQuery] bool? is3d, - [FromQuery] string seriesStatus, - [FromQuery] string nameStartsWithOrGreater, - [FromQuery] string nameStartsWith, - [FromQuery] string nameLessThan, [FromQuery] bool recursive = true, - [FromQuery] bool? enableImages = true, - [FromQuery] bool enableTotalRecordCount = true) + [FromQuery] bool? enableImages = true) { var dtoOptions = new DtoOptions() .AddItemFields(fields) -- 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/YearsController.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/YearsController.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