diff options
Diffstat (limited to 'Jellyfin.Api/Controllers')
20 files changed, 155 insertions, 138 deletions
diff --git a/Jellyfin.Api/Controllers/ArtistsController.cs b/Jellyfin.Api/Controllers/ArtistsController.cs index c65dc8620..fed7ed3e5 100644 --- a/Jellyfin.Api/Controllers/ArtistsController.cs +++ b/Jellyfin.Api/Controllers/ArtistsController.cs @@ -3,7 +3,6 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using Jellyfin.Api.Constants; using Jellyfin.Api.Extensions; -using Jellyfin.Api.Helpers; using Jellyfin.Api.ModelBinders; using Jellyfin.Data.Entities; using MediaBrowser.Controller.Dto; @@ -87,7 +86,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] int? startIndex, [FromQuery] int? limit, [FromQuery] string? searchTerm, - [FromQuery] string? parentId, + [FromQuery] Guid? parentId, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes, @@ -119,16 +118,11 @@ namespace Jellyfin.Api.Controllers .AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes); User? user = null; - BaseItem parentItem; + BaseItem parentItem = _libraryManager.GetParentItem(parentId, userId); if (userId.HasValue && !userId.Equals(Guid.Empty)) { user = _userManager.GetUserById(userId.Value); - parentItem = string.IsNullOrEmpty(parentId) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(parentId); - } - else - { - parentItem = string.IsNullOrEmpty(parentId) ? _libraryManager.RootFolder : _libraryManager.GetItemById(parentId); } var query = new InternalItemsQuery(user) @@ -157,15 +151,15 @@ namespace Jellyfin.Api.Controllers EnableTotalRecordCount = enableTotalRecordCount }; - if (!string.IsNullOrWhiteSpace(parentId)) + if (parentId.HasValue) { if (parentItem is Folder) { - query.AncestorIds = new[] { new Guid(parentId) }; + query.AncestorIds = new[] { parentId.Value }; } else { - query.ItemIds = new[] { new Guid(parentId) }; + query.ItemIds = new[] { parentId.Value }; } } @@ -291,7 +285,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] int? startIndex, [FromQuery] int? limit, [FromQuery] string? searchTerm, - [FromQuery] string? parentId, + [FromQuery] Guid? parentId, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes, @@ -323,16 +317,11 @@ namespace Jellyfin.Api.Controllers .AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes); User? user = null; - BaseItem parentItem; + BaseItem parentItem = _libraryManager.GetParentItem(parentId, userId); if (userId.HasValue && !userId.Equals(Guid.Empty)) { user = _userManager.GetUserById(userId.Value); - parentItem = string.IsNullOrEmpty(parentId) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(parentId); - } - else - { - parentItem = string.IsNullOrEmpty(parentId) ? _libraryManager.RootFolder : _libraryManager.GetItemById(parentId); } var query = new InternalItemsQuery(user) @@ -361,15 +350,15 @@ namespace Jellyfin.Api.Controllers EnableTotalRecordCount = enableTotalRecordCount }; - if (!string.IsNullOrWhiteSpace(parentId)) + if (parentId.HasValue) { if (parentItem is Folder) { - query.AncestorIds = new[] { new Guid(parentId) }; + query.AncestorIds = new[] { parentId.Value }; } else { - query.ItemIds = new[] { new Guid(parentId) }; + query.ItemIds = new[] { parentId.Value }; } } diff --git a/Jellyfin.Api/Controllers/AudioController.cs b/Jellyfin.Api/Controllers/AudioController.cs index c22979495..616fe5b91 100644 --- a/Jellyfin.Api/Controllers/AudioController.cs +++ b/Jellyfin.Api/Controllers/AudioController.cs @@ -78,7 +78,7 @@ namespace Jellyfin.Api.Controllers /// <param name="enableMpegtsM2TsMode">Optional. Whether to enable the MpegtsM2Ts mode.</param> /// <param name="videoCodec">Optional. Specify a video codec to encode to, e.g. h264. If omitted the server will auto-select using the url's extension. Options: h265, h264, mpeg4, theora, vpx, wmv.</param> /// <param name="subtitleCodec">Optional. Specify a subtitle codec to encode to.</param> - /// <param name="transcodingReasons">Optional. The transcoding reason.</param> + /// <param name="transcodeReasons">Optional. The transcoding reason.</param> /// <param name="audioStreamIndex">Optional. The index of the audio stream to use. If omitted the first audio stream will be used.</param> /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream will be used.</param> /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> @@ -134,7 +134,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] string? videoCodec, [FromQuery] string? subtitleCodec, - [FromQuery] string? transcodingReasons, + [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext? context, @@ -186,7 +186,7 @@ namespace Jellyfin.Api.Controllers EnableMpegtsM2TsMode = enableMpegtsM2TsMode ?? true, VideoCodec = videoCodec, SubtitleCodec = subtitleCodec, - TranscodeReasons = transcodingReasons, + TranscodeReasons = transcodeReasons, AudioStreamIndex = audioStreamIndex, VideoStreamIndex = videoStreamIndex, Context = context ?? EncodingContext.Static, @@ -243,7 +243,7 @@ namespace Jellyfin.Api.Controllers /// <param name="enableMpegtsM2TsMode">Optional. Whether to enable the MpegtsM2Ts mode.</param> /// <param name="videoCodec">Optional. Specify a video codec to encode to, e.g. h264. If omitted the server will auto-select using the url's extension. Options: h265, h264, mpeg4, theora, vpx, wmv.</param> /// <param name="subtitleCodec">Optional. Specify a subtitle codec to encode to.</param> - /// <param name="transcodingReasons">Optional. The transcoding reason.</param> + /// <param name="transcodeReasons">Optional. The transcoding reason.</param> /// <param name="audioStreamIndex">Optional. The index of the audio stream to use. If omitted the first audio stream will be used.</param> /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream will be used.</param> /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> @@ -299,7 +299,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] string? videoCodec, [FromQuery] string? subtitleCodec, - [FromQuery] string? transcodingReasons, + [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext? context, @@ -351,7 +351,7 @@ namespace Jellyfin.Api.Controllers EnableMpegtsM2TsMode = enableMpegtsM2TsMode ?? true, VideoCodec = videoCodec, SubtitleCodec = subtitleCodec, - TranscodeReasons = transcodingReasons, + TranscodeReasons = transcodeReasons, AudioStreamIndex = audioStreamIndex, VideoStreamIndex = videoStreamIndex, Context = context ?? EncodingContext.Static, diff --git a/Jellyfin.Api/Controllers/ChannelsController.cs b/Jellyfin.Api/Controllers/ChannelsController.cs index c4dc44cc3..b70c76e80 100644 --- a/Jellyfin.Api/Controllers/ChannelsController.cs +++ b/Jellyfin.Api/Controllers/ChannelsController.cs @@ -92,7 +92,7 @@ namespace Jellyfin.Api.Controllers /// <response code="200">Channel features returned.</response> /// <returns>An <see cref="OkResult"/> containing the channel features.</returns> [HttpGet("{channelId}/Features")] - public ActionResult<ChannelFeatures> GetChannelFeatures([FromRoute, Required] string channelId) + public ActionResult<ChannelFeatures> GetChannelFeatures([FromRoute, Required] Guid channelId) { return _channelManager.GetChannelFeatures(channelId); } diff --git a/Jellyfin.Api/Controllers/DisplayPreferencesController.cs b/Jellyfin.Api/Controllers/DisplayPreferencesController.cs index 76f5717e3..8b8f63015 100644 --- a/Jellyfin.Api/Controllers/DisplayPreferencesController.cs +++ b/Jellyfin.Api/Controllers/DisplayPreferencesController.cs @@ -6,6 +6,7 @@ using System.Linq; using Jellyfin.Api.Constants; using Jellyfin.Data.Entities; using Jellyfin.Data.Enums; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller; using MediaBrowser.Model.Entities; using Microsoft.AspNetCore.Authorization; @@ -47,13 +48,19 @@ namespace Jellyfin.Api.Controllers [FromQuery, Required] Guid userId, [FromQuery, Required] string client) { - var displayPreferences = _displayPreferencesManager.GetDisplayPreferences(userId, client); - var itemPreferences = _displayPreferencesManager.GetItemDisplayPreferences(displayPreferences.UserId, Guid.Empty, displayPreferences.Client); + if (!Guid.TryParse(displayPreferencesId, out var itemId)) + { + itemId = displayPreferencesId.GetMD5(); + } + + var displayPreferences = _displayPreferencesManager.GetDisplayPreferences(userId, itemId, client); + var itemPreferences = _displayPreferencesManager.GetItemDisplayPreferences(displayPreferences.UserId, itemId, displayPreferences.Client); + itemPreferences.ItemId = itemId; var dto = new DisplayPreferencesDto { Client = displayPreferences.Client, - Id = displayPreferences.UserId.ToString(), + Id = displayPreferences.ItemId.ToString(), ViewType = itemPreferences.ViewType.ToString(), SortBy = itemPreferences.SortBy, SortOrder = itemPreferences.SortOrder, @@ -81,6 +88,16 @@ namespace Jellyfin.Api.Controllers dto.CustomPrefs["enableNextVideoInfoOverlay"] = displayPreferences.EnableNextVideoInfoOverlay.ToString(CultureInfo.InvariantCulture); dto.CustomPrefs["tvhome"] = displayPreferences.TvHome; + // Load all custom display preferences + var customDisplayPreferences = _displayPreferencesManager.ListCustomItemDisplayPreferences(displayPreferences.UserId, itemId, displayPreferences.Client); + if (customDisplayPreferences != null) + { + foreach (var (key, value) in customDisplayPreferences) + { + dto.CustomPrefs.TryAdd(key, value); + } + } + // This will essentially be a noop if no changes have been made, but new prefs must be saved at least. _displayPreferencesManager.SaveChanges(); @@ -115,7 +132,12 @@ namespace Jellyfin.Api.Controllers HomeSectionType.LatestMedia, HomeSectionType.None, }; - var existingDisplayPreferences = _displayPreferencesManager.GetDisplayPreferences(userId, client); + if (!Guid.TryParse(displayPreferencesId, out var itemId)) + { + itemId = displayPreferencesId.GetMD5(); + } + + var existingDisplayPreferences = _displayPreferencesManager.GetDisplayPreferences(userId, itemId, client); existingDisplayPreferences.IndexBy = Enum.TryParse<IndexingKind>(displayPreferences.IndexBy, true, out var indexBy) ? indexBy : (IndexingKind?)null; existingDisplayPreferences.ShowBackdrop = displayPreferences.ShowBackdrop; existingDisplayPreferences.ShowSidebar = displayPreferences.ShowSidebar; @@ -124,21 +146,33 @@ namespace Jellyfin.Api.Controllers existingDisplayPreferences.ChromecastVersion = displayPreferences.CustomPrefs.TryGetValue("chromecastVersion", out var chromecastVersion) ? Enum.Parse<ChromecastVersion>(chromecastVersion, true) : ChromecastVersion.Stable; + displayPreferences.CustomPrefs.Remove("chromecastVersion"); + existingDisplayPreferences.EnableNextVideoInfoOverlay = displayPreferences.CustomPrefs.TryGetValue("enableNextVideoInfoOverlay", out var enableNextVideoInfoOverlay) ? bool.Parse(enableNextVideoInfoOverlay) : true; + displayPreferences.CustomPrefs.Remove("enableNextVideoInfoOverlay"); + existingDisplayPreferences.SkipBackwardLength = displayPreferences.CustomPrefs.TryGetValue("skipBackLength", out var skipBackLength) ? int.Parse(skipBackLength, CultureInfo.InvariantCulture) : 10000; + displayPreferences.CustomPrefs.Remove("skipBackLength"); + existingDisplayPreferences.SkipForwardLength = displayPreferences.CustomPrefs.TryGetValue("skipForwardLength", out var skipForwardLength) ? int.Parse(skipForwardLength, CultureInfo.InvariantCulture) : 30000; + displayPreferences.CustomPrefs.Remove("skipForwardLength"); + existingDisplayPreferences.DashboardTheme = displayPreferences.CustomPrefs.TryGetValue("dashboardTheme", out var theme) ? theme : string.Empty; + displayPreferences.CustomPrefs.Remove("dashboardTheme"); + existingDisplayPreferences.TvHome = displayPreferences.CustomPrefs.TryGetValue("tvhome", out var home) ? home : string.Empty; + displayPreferences.CustomPrefs.Remove("tvhome"); + existingDisplayPreferences.HomeSections.Clear(); foreach (var key in displayPreferences.CustomPrefs.Keys.Where(key => key.StartsWith("homesection", StringComparison.OrdinalIgnoreCase))) @@ -149,26 +183,34 @@ namespace Jellyfin.Api.Controllers type = order < 7 ? defaults[order] : HomeSectionType.None; } + displayPreferences.CustomPrefs.Remove(key); existingDisplayPreferences.HomeSections.Add(new HomeSection { Order = order, Type = type }); } foreach (var key in displayPreferences.CustomPrefs.Keys.Where(key => key.StartsWith("landing-", StringComparison.OrdinalIgnoreCase))) { - var itemPreferences = _displayPreferencesManager.GetItemDisplayPreferences(existingDisplayPreferences.UserId, Guid.Parse(key.Substring("landing-".Length)), existingDisplayPreferences.Client); - itemPreferences.ViewType = Enum.Parse<ViewType>(displayPreferences.ViewType); + if (Guid.TryParse(key.AsSpan().Slice("landing-".Length), out var preferenceId)) + { + var itemPreferences = _displayPreferencesManager.GetItemDisplayPreferences(existingDisplayPreferences.UserId, preferenceId, existingDisplayPreferences.Client); + itemPreferences.ViewType = Enum.Parse<ViewType>(displayPreferences.ViewType); + displayPreferences.CustomPrefs.Remove(key); + } } - var itemPrefs = _displayPreferencesManager.GetItemDisplayPreferences(existingDisplayPreferences.UserId, Guid.Empty, existingDisplayPreferences.Client); + var itemPrefs = _displayPreferencesManager.GetItemDisplayPreferences(existingDisplayPreferences.UserId, itemId, existingDisplayPreferences.Client); itemPrefs.SortBy = displayPreferences.SortBy; itemPrefs.SortOrder = displayPreferences.SortOrder; itemPrefs.RememberIndexing = displayPreferences.RememberIndexing; itemPrefs.RememberSorting = displayPreferences.RememberSorting; + itemPrefs.ItemId = itemId; if (Enum.TryParse<ViewType>(displayPreferences.ViewType, true, out var viewType)) { itemPrefs.ViewType = viewType; } + // Set all remaining custom preferences. + _displayPreferencesManager.SetCustomItemDisplayPreferences(userId, itemId, existingDisplayPreferences.Client, displayPreferences.CustomPrefs); _displayPreferencesManager.SaveChanges(); return NoContent(); diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs index eff5bd54a..6e85737d2 100644 --- a/Jellyfin.Api/Controllers/DynamicHlsController.cs +++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs @@ -160,7 +160,7 @@ namespace Jellyfin.Api.Controllers /// <param name="enableMpegtsM2TsMode">Optional. Whether to enable the MpegtsM2Ts mode.</param> /// <param name="videoCodec">Optional. Specify a video codec to encode to, e.g. h264. If omitted the server will auto-select using the url's extension. Options: h265, h264, mpeg4, theora, vpx, wmv.</param> /// <param name="subtitleCodec">Optional. Specify a subtitle codec to encode to.</param> - /// <param name="transcodingReasons">Optional. The transcoding reason.</param> + /// <param name="transcodeReasons">Optional. The transcoding reason.</param> /// <param name="audioStreamIndex">Optional. The index of the audio stream to use. If omitted the first audio stream will be used.</param> /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream will be used.</param> /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> @@ -216,7 +216,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] string? videoCodec, [FromQuery] string? subtitleCodec, - [FromQuery] string? transcodingReasons, + [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext context, @@ -268,7 +268,7 @@ namespace Jellyfin.Api.Controllers EnableMpegtsM2TsMode = enableMpegtsM2TsMode ?? true, VideoCodec = videoCodec, SubtitleCodec = subtitleCodec, - TranscodeReasons = transcodingReasons, + TranscodeReasons = transcodeReasons, AudioStreamIndex = audioStreamIndex, VideoStreamIndex = videoStreamIndex, Context = context, @@ -326,7 +326,7 @@ namespace Jellyfin.Api.Controllers /// <param name="enableMpegtsM2TsMode">Optional. Whether to enable the MpegtsM2Ts mode.</param> /// <param name="videoCodec">Optional. Specify a video codec to encode to, e.g. h264. If omitted the server will auto-select using the url's extension. Options: h265, h264, mpeg4, theora, vpx, wmv.</param> /// <param name="subtitleCodec">Optional. Specify a subtitle codec to encode to.</param> - /// <param name="transcodingReasons">Optional. The transcoding reason.</param> + /// <param name="transcodeReasons">Optional. The transcoding reason.</param> /// <param name="audioStreamIndex">Optional. The index of the audio stream to use. If omitted the first audio stream will be used.</param> /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream will be used.</param> /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> @@ -383,7 +383,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] string? videoCodec, [FromQuery] string? subtitleCodec, - [FromQuery] string? transcodingReasons, + [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext context, @@ -435,7 +435,7 @@ namespace Jellyfin.Api.Controllers EnableMpegtsM2TsMode = enableMpegtsM2TsMode ?? true, VideoCodec = videoCodec, SubtitleCodec = subtitleCodec, - TranscodeReasons = transcodingReasons, + TranscodeReasons = transcodeReasons, AudioStreamIndex = audioStreamIndex, VideoStreamIndex = videoStreamIndex, Context = context, @@ -492,7 +492,7 @@ namespace Jellyfin.Api.Controllers /// <param name="enableMpegtsM2TsMode">Optional. Whether to enable the MpegtsM2Ts mode.</param> /// <param name="videoCodec">Optional. Specify a video codec to encode to, e.g. h264. If omitted the server will auto-select using the url's extension. Options: h265, h264, mpeg4, theora, vpx, wmv.</param> /// <param name="subtitleCodec">Optional. Specify a subtitle codec to encode to.</param> - /// <param name="transcodingReasons">Optional. The transcoding reason.</param> + /// <param name="transcodeReasons">Optional. The transcoding reason.</param> /// <param name="audioStreamIndex">Optional. The index of the audio stream to use. If omitted the first audio stream will be used.</param> /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream will be used.</param> /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> @@ -546,7 +546,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] string? videoCodec, [FromQuery] string? subtitleCodec, - [FromQuery] string? transcodingReasons, + [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext context, @@ -598,7 +598,7 @@ namespace Jellyfin.Api.Controllers EnableMpegtsM2TsMode = enableMpegtsM2TsMode ?? true, VideoCodec = videoCodec, SubtitleCodec = subtitleCodec, - TranscodeReasons = transcodingReasons, + TranscodeReasons = transcodeReasons, AudioStreamIndex = audioStreamIndex, VideoStreamIndex = videoStreamIndex, Context = context, @@ -656,7 +656,7 @@ namespace Jellyfin.Api.Controllers /// <param name="enableMpegtsM2TsMode">Optional. Whether to enable the MpegtsM2Ts mode.</param> /// <param name="videoCodec">Optional. Specify a video codec to encode to, e.g. h264. If omitted the server will auto-select using the url's extension. Options: h265, h264, mpeg4, theora, vpx, wmv.</param> /// <param name="subtitleCodec">Optional. Specify a subtitle codec to encode to.</param> - /// <param name="transcodingReasons">Optional. The transcoding reason.</param> + /// <param name="transcodeReasons">Optional. The transcoding reason.</param> /// <param name="audioStreamIndex">Optional. The index of the audio stream to use. If omitted the first audio stream will be used.</param> /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream will be used.</param> /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> @@ -711,7 +711,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] string? videoCodec, [FromQuery] string? subtitleCodec, - [FromQuery] string? transcodingReasons, + [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext context, @@ -763,7 +763,7 @@ namespace Jellyfin.Api.Controllers EnableMpegtsM2TsMode = enableMpegtsM2TsMode ?? true, VideoCodec = videoCodec, SubtitleCodec = subtitleCodec, - TranscodeReasons = transcodingReasons, + TranscodeReasons = transcodeReasons, AudioStreamIndex = audioStreamIndex, VideoStreamIndex = videoStreamIndex, Context = context, @@ -823,7 +823,7 @@ namespace Jellyfin.Api.Controllers /// <param name="enableMpegtsM2TsMode">Optional. Whether to enable the MpegtsM2Ts mode.</param> /// <param name="videoCodec">Optional. Specify a video codec to encode to, e.g. h264. If omitted the server will auto-select using the url's extension. Options: h265, h264, mpeg4, theora, vpx, wmv.</param> /// <param name="subtitleCodec">Optional. Specify a subtitle codec to encode to.</param> - /// <param name="transcodingReasons">Optional. The transcoding reason.</param> + /// <param name="transcodeReasons">Optional. The transcoding reason.</param> /// <param name="audioStreamIndex">Optional. The index of the audio stream to use. If omitted the first audio stream will be used.</param> /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream will be used.</param> /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> @@ -881,7 +881,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] string? videoCodec, [FromQuery] string? subtitleCodec, - [FromQuery] string? transcodingReasons, + [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext context, @@ -933,7 +933,7 @@ namespace Jellyfin.Api.Controllers EnableMpegtsM2TsMode = enableMpegtsM2TsMode ?? true, VideoCodec = videoCodec, SubtitleCodec = subtitleCodec, - TranscodeReasons = transcodingReasons, + TranscodeReasons = transcodeReasons, AudioStreamIndex = audioStreamIndex, VideoStreamIndex = videoStreamIndex, Context = context, @@ -994,7 +994,7 @@ namespace Jellyfin.Api.Controllers /// <param name="enableMpegtsM2TsMode">Optional. Whether to enable the MpegtsM2Ts mode.</param> /// <param name="videoCodec">Optional. Specify a video codec to encode to, e.g. h264. If omitted the server will auto-select using the url's extension. Options: h265, h264, mpeg4, theora, vpx, wmv.</param> /// <param name="subtitleCodec">Optional. Specify a subtitle codec to encode to.</param> - /// <param name="transcodingReasons">Optional. The transcoding reason.</param> + /// <param name="transcodeReasons">Optional. The transcoding reason.</param> /// <param name="audioStreamIndex">Optional. The index of the audio stream to use. If omitted the first audio stream will be used.</param> /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream will be used.</param> /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> @@ -1053,7 +1053,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] string? videoCodec, [FromQuery] string? subtitleCodec, - [FromQuery] string? transcodingReasons, + [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext context, @@ -1105,7 +1105,7 @@ namespace Jellyfin.Api.Controllers EnableMpegtsM2TsMode = enableMpegtsM2TsMode ?? true, VideoCodec = videoCodec, SubtitleCodec = subtitleCodec, - TranscodeReasons = transcodingReasons, + TranscodeReasons = transcodeReasons, AudioStreamIndex = audioStreamIndex, VideoStreamIndex = videoStreamIndex, Context = context, diff --git a/Jellyfin.Api/Controllers/FilterController.cs b/Jellyfin.Api/Controllers/FilterController.cs index 31cb9e273..9220b988f 100644 --- a/Jellyfin.Api/Controllers/FilterController.cs +++ b/Jellyfin.Api/Controllers/FilterController.cs @@ -50,33 +50,24 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult<QueryFiltersLegacy> GetQueryFiltersLegacy( [FromQuery] Guid? userId, - [FromQuery] string? parentId, + [FromQuery] Guid? parentId, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes) { - var parentItem = string.IsNullOrEmpty(parentId) - ? null - : _libraryManager.GetItemById(parentId); - var user = userId.HasValue && !userId.Equals(Guid.Empty) ? _userManager.GetUserById(userId.Value) : null; - if (includeItemTypes.Length == 1 - && (string.Equals(includeItemTypes[0], nameof(BoxSet), StringComparison.OrdinalIgnoreCase) - || string.Equals(includeItemTypes[0], nameof(Playlist), StringComparison.OrdinalIgnoreCase) - || string.Equals(includeItemTypes[0], nameof(Trailer), StringComparison.OrdinalIgnoreCase) - || string.Equals(includeItemTypes[0], "Program", StringComparison.OrdinalIgnoreCase))) + BaseItem? item = null; + if (includeItemTypes.Length != 1 + || !(string.Equals(includeItemTypes[0], nameof(BoxSet), StringComparison.OrdinalIgnoreCase) + || string.Equals(includeItemTypes[0], nameof(Playlist), StringComparison.OrdinalIgnoreCase) + || string.Equals(includeItemTypes[0], nameof(Trailer), StringComparison.OrdinalIgnoreCase) + || string.Equals(includeItemTypes[0], "Program", StringComparison.OrdinalIgnoreCase))) { - parentItem = null; + item = _libraryManager.GetParentItem(parentId, user?.Id); } - var item = string.IsNullOrEmpty(parentId) - ? user == null - ? _libraryManager.RootFolder - : _libraryManager.GetUserRootFolder() - : parentItem; - var query = new InternalItemsQuery { User = user, @@ -92,7 +83,12 @@ namespace Jellyfin.Api.Controllers } }; - var itemList = ((Folder)item!).GetItemList(query); + if (item is not Folder folder) + { + return new QueryFiltersLegacy(); + } + + var itemList = folder.GetItemList(query); return new QueryFiltersLegacy { Years = itemList.Select(i => i.ProductionYear ?? -1) @@ -140,7 +136,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult<QueryFilters> GetQueryFilters( [FromQuery] Guid? userId, - [FromQuery] string? parentId, + [FromQuery] Guid? parentId, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes, [FromQuery] bool? isAiring, [FromQuery] bool? isMovie, @@ -150,14 +146,11 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? isSeries, [FromQuery] bool? recursive) { - var parentItem = string.IsNullOrEmpty(parentId) - ? null - : _libraryManager.GetItemById(parentId); - var user = userId.HasValue && !userId.Equals(Guid.Empty) ? _userManager.GetUserById(userId.Value) : null; + BaseItem? parentItem = null; if (includeItemTypes.Length == 1 && (string.Equals(includeItemTypes[0], nameof(BoxSet), StringComparison.OrdinalIgnoreCase) || string.Equals(includeItemTypes[0], nameof(Playlist), StringComparison.OrdinalIgnoreCase) @@ -166,6 +159,10 @@ namespace Jellyfin.Api.Controllers { parentItem = null; } + else if (parentId.HasValue) + { + parentItem = _libraryManager.GetItemById(parentId.Value); + } var filters = new QueryFilters(); var genreQuery = new InternalItemsQuery(user) diff --git a/Jellyfin.Api/Controllers/GenresController.cs b/Jellyfin.Api/Controllers/GenresController.cs index d2b41e0a8..b6755ed5e 100644 --- a/Jellyfin.Api/Controllers/GenresController.cs +++ b/Jellyfin.Api/Controllers/GenresController.cs @@ -72,7 +72,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] int? startIndex, [FromQuery] int? limit, [FromQuery] string? searchTerm, - [FromQuery] string? parentId, + [FromQuery] Guid? parentId, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes, @@ -109,15 +109,15 @@ namespace Jellyfin.Api.Controllers EnableTotalRecordCount = enableTotalRecordCount }; - if (!string.IsNullOrWhiteSpace(parentId)) + if (parentId.HasValue) { if (parentItem is Folder) { - query.AncestorIds = new[] { new Guid(parentId) }; + query.AncestorIds = new[] { parentId.Value }; } else { - query.ItemIds = new[] { new Guid(parentId) }; + query.ItemIds = new[] { parentId.Value }; } } diff --git a/Jellyfin.Api/Controllers/ItemsController.cs b/Jellyfin.Api/Controllers/ItemsController.cs index b0979fbcf..7e9035f80 100644 --- a/Jellyfin.Api/Controllers/ItemsController.cs +++ b/Jellyfin.Api/Controllers/ItemsController.cs @@ -176,7 +176,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? recursive, [FromQuery] string? searchTerm, [FromQuery] string? sortOrder, - [FromQuery] string? parentId, + [FromQuery] Guid? parentId, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes, @@ -239,14 +239,8 @@ namespace Jellyfin.Api.Controllers parentId = null; } - BaseItem? item = null; + var item = _libraryManager.GetParentItem(parentId, userId); QueryResult<BaseItem> result; - if (!string.IsNullOrEmpty(parentId)) - { - item = _libraryManager.GetItemById(parentId); - } - - item ??= _libraryManager.GetUserRootFolder(); if (!(item is Folder folder)) { @@ -343,7 +337,7 @@ namespace Jellyfin.Api.Controllers ItemIds = ids, MinCommunityRating = minCommunityRating, MinCriticRating = minCriticRating, - ParentId = string.IsNullOrWhiteSpace(parentId) ? Guid.Empty : new Guid(parentId), + ParentId = parentId ?? Guid.Empty, ParentIndexNumber = parentIndexNumber, EnableTotalRecordCount = enableTotalRecordCount, ExcludeItemIds = excludeItemIds, @@ -615,7 +609,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? recursive, [FromQuery] string? searchTerm, [FromQuery] string? sortOrder, - [FromQuery] string? parentId, + [FromQuery] Guid? parentId, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes, @@ -773,7 +767,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] int? startIndex, [FromQuery] int? limit, [FromQuery] string? searchTerm, - [FromQuery] string? parentId, + [FromQuery] Guid? parentId, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes, [FromQuery] bool? enableUserData, @@ -785,7 +779,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? enableImages = true) { var user = _userManager.GetUserById(userId); - var parentIdGuid = string.IsNullOrWhiteSpace(parentId) ? Guid.Empty : new Guid(parentId); + var parentIdGuid = parentId ?? Guid.Empty; var dtoOptions = new DtoOptions { Fields = fields } .AddClientFields(Request) .AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes); diff --git a/Jellyfin.Api/Controllers/LibraryController.cs b/Jellyfin.Api/Controllers/LibraryController.cs index 3ff77e8e0..184843b39 100644 --- a/Jellyfin.Api/Controllers/LibraryController.cs +++ b/Jellyfin.Api/Controllers/LibraryController.cs @@ -362,7 +362,7 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public ActionResult DeleteItems([FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] ids) + public ActionResult DeleteItems([FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] Guid[] ids) { if (ids.Length == 0) { diff --git a/Jellyfin.Api/Controllers/MoviesController.cs b/Jellyfin.Api/Controllers/MoviesController.cs index 75dfd4e68..4d788ad7d 100644 --- a/Jellyfin.Api/Controllers/MoviesController.cs +++ b/Jellyfin.Api/Controllers/MoviesController.cs @@ -65,7 +65,7 @@ namespace Jellyfin.Api.Controllers [HttpGet("Recommendations")] public ActionResult<IEnumerable<RecommendationDto>> GetMovieRecommendations( [FromQuery] Guid? userId, - [FromQuery] string? parentId, + [FromQuery] Guid? parentId, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields, [FromQuery] int categoryLimit = 5, [FromQuery] int itemLimit = 8) @@ -78,7 +78,7 @@ namespace Jellyfin.Api.Controllers var categories = new List<RecommendationDto>(); - var parentIdGuid = string.IsNullOrWhiteSpace(parentId) ? Guid.Empty : new Guid(parentId); + var parentIdGuid = parentId ?? Guid.Empty; var query = new InternalItemsQuery(user) { diff --git a/Jellyfin.Api/Controllers/MusicGenresController.cs b/Jellyfin.Api/Controllers/MusicGenresController.cs index e7d0a61c5..2608a9cd0 100644 --- a/Jellyfin.Api/Controllers/MusicGenresController.cs +++ b/Jellyfin.Api/Controllers/MusicGenresController.cs @@ -72,7 +72,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] int? startIndex, [FromQuery] int? limit, [FromQuery] string? searchTerm, - [FromQuery] string? parentId, + [FromQuery] Guid? parentId, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes, @@ -109,15 +109,15 @@ namespace Jellyfin.Api.Controllers EnableTotalRecordCount = enableTotalRecordCount }; - if (!string.IsNullOrWhiteSpace(parentId)) + if (parentId.HasValue) { if (parentItem is Folder) { - query.AncestorIds = new[] { new Guid(parentId) }; + query.AncestorIds = new[] { parentId.Value }; } else { - query.ItemIds = new[] { new Guid(parentId) }; + query.ItemIds = new[] { parentId.Value }; } } diff --git a/Jellyfin.Api/Controllers/PackageController.cs b/Jellyfin.Api/Controllers/PackageController.cs index 83b359766..6295dfc05 100644 --- a/Jellyfin.Api/Controllers/PackageController.cs +++ b/Jellyfin.Api/Controllers/PackageController.cs @@ -45,13 +45,13 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public async Task<ActionResult<PackageInfo>> GetPackageInfo( [FromRoute, Required] string name, - [FromQuery] string? assemblyGuid) + [FromQuery] Guid? assemblyGuid) { var packages = await _installationManager.GetAvailablePackages().ConfigureAwait(false); var result = _installationManager.FilterPackages( packages, name, - string.IsNullOrEmpty(assemblyGuid) ? default : Guid.Parse(assemblyGuid)) + assemblyGuid ?? default) .FirstOrDefault(); if (result == null) @@ -92,7 +92,7 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.RequiresElevation)] public async Task<ActionResult> InstallPackage( [FromRoute, Required] string name, - [FromQuery] string? assemblyGuid, + [FromQuery] Guid? assemblyGuid, [FromQuery] string? version, [FromQuery] string? repositoryUrl) { @@ -106,7 +106,7 @@ namespace Jellyfin.Api.Controllers var package = _installationManager.GetCompatibleVersions( packages, name, - string.IsNullOrEmpty(assemblyGuid) ? Guid.Empty : Guid.Parse(assemblyGuid), + assemblyGuid ?? Guid.Empty, specificVersion: string.IsNullOrEmpty(version) ? null : Version.Parse(version)) .FirstOrDefault(); diff --git a/Jellyfin.Api/Controllers/PersonsController.cs b/Jellyfin.Api/Controllers/PersonsController.cs index aaad36551..17e631197 100644 --- a/Jellyfin.Api/Controllers/PersonsController.cs +++ b/Jellyfin.Api/Controllers/PersonsController.cs @@ -79,7 +79,7 @@ namespace Jellyfin.Api.Controllers [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludePersonTypes, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] personTypes, - [FromQuery] string? appearsInItemId, + [FromQuery] Guid? appearsInItemId, [FromQuery] Guid? userId, [FromQuery] bool? enableImages = true) { @@ -102,7 +102,7 @@ namespace Jellyfin.Api.Controllers NameContains = searchTerm, User = user, IsFavorite = !isFavorite.HasValue && isFavoriteInFilters ? true : isFavorite, - AppearsInItemId = string.IsNullOrEmpty(appearsInItemId) ? Guid.Empty : Guid.Parse(appearsInItemId), + AppearsInItemId = appearsInItemId ?? Guid.Empty, Limit = limit ?? 0 }); diff --git a/Jellyfin.Api/Controllers/SearchController.cs b/Jellyfin.Api/Controllers/SearchController.cs index 076fe58f1..08255ff8f 100644 --- a/Jellyfin.Api/Controllers/SearchController.cs +++ b/Jellyfin.Api/Controllers/SearchController.cs @@ -86,7 +86,7 @@ namespace Jellyfin.Api.Controllers [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes, - [FromQuery] string? parentId, + [FromQuery] Guid? parentId, [FromQuery] bool? isMovie, [FromQuery] bool? isSeries, [FromQuery] bool? isNews, diff --git a/Jellyfin.Api/Controllers/StudiosController.cs b/Jellyfin.Api/Controllers/StudiosController.cs index 5090bf1de..bb54c59f6 100644 --- a/Jellyfin.Api/Controllers/StudiosController.cs +++ b/Jellyfin.Api/Controllers/StudiosController.cs @@ -71,7 +71,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] int? startIndex, [FromQuery] int? limit, [FromQuery] string? searchTerm, - [FromQuery] string? parentId, + [FromQuery] Guid? parentId, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes, @@ -109,15 +109,15 @@ namespace Jellyfin.Api.Controllers EnableTotalRecordCount = enableTotalRecordCount }; - if (!string.IsNullOrWhiteSpace(parentId)) + if (parentId.HasValue) { if (parentItem is Folder) { - query.AncestorIds = new[] { new Guid(parentId) }; + query.AncestorIds = new[] { parentId.Value }; } else { - query.ItemIds = new[] { new Guid(parentId) }; + query.ItemIds = new[] { parentId.Value }; } } diff --git a/Jellyfin.Api/Controllers/TrailersController.cs b/Jellyfin.Api/Controllers/TrailersController.cs index 5b71fed5a..8e9ece14f 100644 --- a/Jellyfin.Api/Controllers/TrailersController.cs +++ b/Jellyfin.Api/Controllers/TrailersController.cs @@ -145,7 +145,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? recursive, [FromQuery] string? searchTerm, [FromQuery] string? sortOrder, - [FromQuery] string? parentId, + [FromQuery] Guid? parentId, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFilter[] filters, diff --git a/Jellyfin.Api/Controllers/TvShowsController.cs b/Jellyfin.Api/Controllers/TvShowsController.cs index 57b056f50..03fd1846d 100644 --- a/Jellyfin.Api/Controllers/TvShowsController.cs +++ b/Jellyfin.Api/Controllers/TvShowsController.cs @@ -76,7 +76,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] int? limit, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields, [FromQuery] string? seriesId, - [FromQuery] string? parentId, + [FromQuery] Guid? parentId, [FromQuery] bool? enableImges, [FromQuery] int? imageTypeLimit, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes, @@ -132,7 +132,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] int? startIndex, [FromQuery] int? limit, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields, - [FromQuery] string? parentId, + [FromQuery] Guid? parentId, [FromQuery] bool? enableImges, [FromQuery] int? imageTypeLimit, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes, @@ -144,7 +144,7 @@ namespace Jellyfin.Api.Controllers var minPremiereDate = DateTime.Now.Date.ToUniversalTime().AddDays(-1); - var parentIdGuid = string.IsNullOrWhiteSpace(parentId) ? Guid.Empty : new Guid(parentId); + var parentIdGuid = parentId ?? Guid.Empty; var options = new DtoOptions { Fields = fields } .AddClientFields(Request) @@ -194,14 +194,14 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult<QueryResult<BaseItemDto>> GetEpisodes( - [FromRoute, Required] string seriesId, + [FromRoute, Required] Guid seriesId, [FromQuery] Guid? userId, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields, [FromQuery] int? season, - [FromQuery] string? seasonId, + [FromQuery] Guid? seasonId, [FromQuery] bool? isMissing, [FromQuery] string? adjacentTo, - [FromQuery] string? startItemId, + [FromQuery] Guid? startItemId, [FromQuery] int? startIndex, [FromQuery] int? limit, [FromQuery] bool? enableImages, @@ -220,9 +220,9 @@ namespace Jellyfin.Api.Controllers .AddClientFields(Request) .AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes!); - if (!string.IsNullOrWhiteSpace(seasonId)) // Season id was supplied. Get episodes by season id. + if (seasonId.HasValue) // Season id was supplied. Get episodes by season id. { - var item = _libraryManager.GetItemById(new Guid(seasonId)); + var item = _libraryManager.GetItemById(seasonId.Value); if (!(item is Season seasonItem)) { return NotFound("No season exists with Id " + seasonId); @@ -264,10 +264,10 @@ namespace Jellyfin.Api.Controllers .ToList(); } - if (!string.IsNullOrWhiteSpace(startItemId)) + if (startItemId.HasValue) { episodes = episodes - .SkipWhile(i => !string.Equals(i.Id.ToString("N", CultureInfo.InvariantCulture), startItemId, StringComparison.OrdinalIgnoreCase)) + .SkipWhile(i => startItemId.Value.Equals(i.Id)) .ToList(); } @@ -316,7 +316,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult<QueryResult<BaseItemDto>> GetSeasons( - [FromRoute, Required] string seriesId, + [FromRoute, Required] Guid seriesId, [FromQuery] Guid? userId, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields, [FromQuery] bool? isSpecialSeason, diff --git a/Jellyfin.Api/Controllers/VideoHlsController.cs b/Jellyfin.Api/Controllers/VideoHlsController.cs index 2ac16de6b..7e743ee0c 100644 --- a/Jellyfin.Api/Controllers/VideoHlsController.cs +++ b/Jellyfin.Api/Controllers/VideoHlsController.cs @@ -153,7 +153,7 @@ namespace Jellyfin.Api.Controllers /// <param name="enableMpegtsM2TsMode">Optional. Whether to enable the MpegtsM2Ts mode.</param> /// <param name="videoCodec">Optional. Specify a video codec to encode to, e.g. h264. If omitted the server will auto-select using the url's extension. Options: h265, h264, mpeg4, theora, vpx, wmv.</param> /// <param name="subtitleCodec">Optional. Specify a subtitle codec to encode to.</param> - /// <param name="transcodingReasons">Optional. The transcoding reason.</param> + /// <param name="transcodeReasons">Optional. The transcoding reason.</param> /// <param name="audioStreamIndex">Optional. The index of the audio stream to use. If omitted the first audio stream will be used.</param> /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream will be used.</param> /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> @@ -211,7 +211,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] string? videoCodec, [FromQuery] string? subtitleCodec, - [FromQuery] string? transcodingReasons, + [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext context, @@ -266,7 +266,7 @@ namespace Jellyfin.Api.Controllers EnableMpegtsM2TsMode = enableMpegtsM2TsMode ?? true, VideoCodec = videoCodec, SubtitleCodec = subtitleCodec, - TranscodeReasons = transcodingReasons, + TranscodeReasons = transcodeReasons, AudioStreamIndex = audioStreamIndex, VideoStreamIndex = videoStreamIndex, Context = context, diff --git a/Jellyfin.Api/Controllers/VideosController.cs b/Jellyfin.Api/Controllers/VideosController.cs index 8e17b843a..d8bc9df1f 100644 --- a/Jellyfin.Api/Controllers/VideosController.cs +++ b/Jellyfin.Api/Controllers/VideosController.cs @@ -320,7 +320,7 @@ namespace Jellyfin.Api.Controllers /// <param name="enableMpegtsM2TsMode">Optional. Whether to enable the MpegtsM2Ts mode.</param> /// <param name="videoCodec">Optional. Specify a video codec to encode to, e.g. h264. If omitted the server will auto-select using the url's extension. Options: h265, h264, mpeg4, theora, vpx, wmv.</param> /// <param name="subtitleCodec">Optional. Specify a subtitle codec to encode to.</param> - /// <param name="transcodingReasons">Optional. The transcoding reason.</param> + /// <param name="transcodeReasons">Optional. The transcoding reason.</param> /// <param name="audioStreamIndex">Optional. The index of the audio stream to use. If omitted the first audio stream will be used.</param> /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream will be used.</param> /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> @@ -376,7 +376,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] string? videoCodec, [FromQuery] string? subtitleCodec, - [FromQuery] string? transcodingReasons, + [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext context, @@ -430,7 +430,7 @@ namespace Jellyfin.Api.Controllers EnableMpegtsM2TsMode = enableMpegtsM2TsMode ?? true, VideoCodec = videoCodec, SubtitleCodec = subtitleCodec, - TranscodeReasons = transcodingReasons, + TranscodeReasons = transcodeReasons, AudioStreamIndex = audioStreamIndex, VideoStreamIndex = videoStreamIndex, Context = context, @@ -576,7 +576,7 @@ namespace Jellyfin.Api.Controllers /// <param name="enableMpegtsM2TsMode">Optional. Whether to enable the MpegtsM2Ts mode.</param> /// <param name="videoCodec">Optional. Specify a video codec to encode to, e.g. h264. If omitted the server will auto-select using the url's extension. Options: h265, h264, mpeg4, theora, vpx, wmv.</param> /// <param name="subtitleCodec">Optional. Specify a subtitle codec to encode to.</param> - /// <param name="transcodingReasons">Optional. The transcoding reason.</param> + /// <param name="transcodeReasons">Optional. The transcoding reason.</param> /// <param name="audioStreamIndex">Optional. The index of the audio stream to use. If omitted the first audio stream will be used.</param> /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream will be used.</param> /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> @@ -632,7 +632,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? enableMpegtsM2TsMode, [FromQuery] string? videoCodec, [FromQuery] string? subtitleCodec, - [FromQuery] string? transcodingReasons, + [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext context, @@ -683,7 +683,7 @@ namespace Jellyfin.Api.Controllers enableMpegtsM2TsMode, videoCodec, subtitleCodec, - transcodingReasons, + transcodeReasons, audioStreamIndex, videoStreamIndex, context, diff --git a/Jellyfin.Api/Controllers/YearsController.cs b/Jellyfin.Api/Controllers/YearsController.cs index ec7c3de97..48c639b08 100644 --- a/Jellyfin.Api/Controllers/YearsController.cs +++ b/Jellyfin.Api/Controllers/YearsController.cs @@ -71,7 +71,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] int? startIndex, [FromQuery] int? limit, [FromQuery] string? sortOrder, - [FromQuery] string? parentId, + [FromQuery] Guid? parentId, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes, @@ -89,16 +89,11 @@ namespace Jellyfin.Api.Controllers .AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes); User? user = null; - BaseItem parentItem; + BaseItem parentItem = _libraryManager.GetParentItem(parentId, userId); if (userId.HasValue && !userId.Equals(Guid.Empty)) { user = _userManager.GetUserById(userId.Value); - parentItem = string.IsNullOrEmpty(parentId) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(parentId); - } - else - { - parentItem = string.IsNullOrEmpty(parentId) ? _libraryManager.RootFolder : _libraryManager.GetItemById(parentId); } IList<BaseItem> items; |
