using System; using System.Linq; using Jellyfin.Api.Constants; using Jellyfin.Api.Extensions; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.TV; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Jellyfin.Api.Controllers { /// /// The tv shows controller. /// [Route("/Shows")] [Authorize(Policy = Policies.DefaultAuthorization)] public class TvShowsController : BaseJellyfinApiController { private readonly IUserManager _userManager; private readonly ILibraryManager _libraryManager; private readonly IDtoService _dtoService; private readonly ITVSeriesManager _tvSeriesManager; private readonly IAuthorizationContext _authContext; /// /// Initializes a new instance of the class. /// /// Instance of the interface. /// Instance of the interface. /// Instance of the interface. /// Instance of the interface. /// Instance of the interface. public TvShowsController( IUserManager userManager, ILibraryManager libraryManager, IDtoService dtoService, ITVSeriesManager tvSeriesManager, IAuthorizationContext authContext) { _userManager = userManager; _libraryManager = libraryManager; _dtoService = dtoService; _tvSeriesManager = tvSeriesManager; _authContext = authContext; } /// /// Gets a list of next up episodes. /// /// The user id of the user to get the next up episodes for. /// Optional. The record index to start at. All items with a lower index will be dropped from the results. /// Optional. The maximum number of records to return. /// Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls. /// Optional. Filter by series id. /// Optional. Specify this to localize the search to a specific item or folder. Omit to use the root. /// 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. /// Optional. Include user data. /// Whether to enable the total records count. Defaults to true. /// A with the next up episodes. [HttpGet("NextUp")] public ActionResult> GetNextUp( [FromQuery] Guid userId, [FromQuery] int? startIndex, [FromQuery] int? limit, [FromQuery] string? fields, [FromQuery] string? seriesId, [FromQuery] string? parentId, [FromQuery] bool? enableImges, [FromQuery] int? imageTypeLimit, [FromQuery] string enableImageTypes, [FromQuery] bool? enableUserData, [FromQuery] bool enableTotalRecordCount = true) { var options = new DtoOptions() .AddItemFields(fields) .AddClientFields(Request) .AddAdditionalDtoOptions(enableImges, enableUserData, imageTypeLimit, enableImageTypes); var result = _tvSeriesManager.GetNextUp( new NextUpQuery { Limit = limit, ParentId = parentId, SeriesId = seriesId, StartIndex = startIndex, UserId = userId, EnableTotalRecordCount = enableTotalRecordCount }, options); var user = _userManager.GetUserById(userId); var returnItems = _dtoService.GetBaseItemDtos(result.Items, options, user); return new QueryResult { TotalRecordCount = result.TotalRecordCount, Items = returnItems }; } /// /// Gets a list of upcoming episodes. /// /// The user id of the user to get the upcoming episodes for. /// Optional. The record index to start at. All items with a lower index will be dropped from the results. /// Optional. The maximum number of records to return. /// Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls. /// Optional. Filter by series id. /// Optional. Specify this to localize the search to a specific item or folder. Omit to use the root. /// 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. /// Optional. Include user data. /// Whether to enable the total records count. Defaults to true. /// A with the next up episodes. [HttpGet("Upcoming")] public ActionResult> GetUpcomingEpisodes( [FromQuery] Guid userId, [FromQuery] int? startIndex, [FromQuery] int? limit, [FromQuery] string? fields, [FromQuery] string? seriesId, [FromQuery] string? parentId, [FromQuery] bool? enableImges, [FromQuery] int? imageTypeLimit, [FromQuery] string enableImageTypes, [FromQuery] bool? enableUserData, [FromQuery] bool enableTotalRecordCount = true) { var user = _userManager.GetUserById(userId); var minPremiereDate = DateTime.Now.Date.ToUniversalTime().AddDays(-1); var parentIdGuid = string.IsNullOrWhiteSpace(parentId) ? Guid.Empty : new Guid(parentId); var options = new DtoOptions() .AddItemFields(fields) .AddClientFields(Request) .AddAdditionalDtoOptions(enableImges, enableUserData, imageTypeLimit, enableImageTypes); var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user) { IncludeItemTypes = new[] { nameof(Episode) }, OrderBy = new[] { ItemSortBy.PremiereDate, ItemSortBy.SortName }.Select(i => new ValueTuple(i, SortOrder.Ascending)).ToArray(), MinPremiereDate = minPremiereDate, StartIndex = startIndex, Limit = limit, ParentId = parentIdGuid, Recursive = true, DtoOptions = options }); var returnItems = _dtoService.GetBaseItemDtos(itemsResult, options, user); return new QueryResult { TotalRecordCount = itemsResult.Count, Items = returnItems }; } } }