using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Jellyfin.Api.Extensions; using Jellyfin.Api.Helpers; using Jellyfin.Api.ModelBinders; using Jellyfin.Extensions; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace Jellyfin.Api.Controllers; /// /// Movies controller. /// [Authorize] [Tags("Movie")] public class MoviesController : BaseJellyfinApiController { private readonly IUserManager _userManager; private readonly IDtoService _dtoService; private readonly ISimilarItemsManager _similarItemsManager; /// /// Initializes a new instance of the class. /// /// Instance of the interface. /// Instance of the interface. /// Instance of the interface. public MoviesController( IUserManager userManager, IDtoService dtoService, ISimilarItemsManager similarItemsManager) { _userManager = userManager; _dtoService = dtoService; _similarItemsManager = similarItemsManager; } /// /// Gets movie recommendations. /// /// 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. /// Optional. The fields to return. /// The max number of categories to return. /// The max number of items to return per category. /// The cancellation token. /// Movie recommendations returned. /// The list of movie recommendations. [HttpGet("Recommendations")] public async Task>> GetMovieRecommendations( [FromQuery] Guid? userId, [FromQuery] Guid? parentId, [FromQuery, ModelBinder(typeof(CommaDelimitedCollectionModelBinder))] ItemFields[] fields, [FromQuery] int categoryLimit = 5, [FromQuery] int itemLimit = 8, CancellationToken cancellationToken = default) { userId = RequestHelpers.GetUserId(User, userId); var user = userId.IsNullOrEmpty() ? null : _userManager.GetUserById(userId.Value); var dtoOptions = new DtoOptions { Fields = fields }; var recommendations = await _similarItemsManager .GetMovieRecommendationsAsync(user, parentId ?? Guid.Empty, categoryLimit, itemLimit, dtoOptions, cancellationToken) .ConfigureAwait(false); return Ok(recommendations.Select(r => new RecommendationDto { BaselineItemName = r.BaselineItemName, CategoryId = r.CategoryId, RecommendationType = r.RecommendationType, Items = _dtoService.GetBaseItemDtos(r.Items, dtoOptions, user) })); } }