aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Api/Controllers/PersonsController.cs
blob: be4b9eded5a4dc142f9d6efcbbf3ecc9df65a473 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Entities;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
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
{
    /// <summary>
    /// Persons controller.
    /// </summary>
    [Authorize(Policy = Policies.DefaultAuthorization)]
    public class PersonsController : BaseJellyfinApiController
    {
        private readonly ILibraryManager _libraryManager;
        private readonly IDtoService _dtoService;
        private readonly IUserManager _userManager;

        /// <summary>
        /// Initializes a new instance of the <see cref="PersonsController"/> class.
        /// </summary>
        /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
        /// <param name="dtoService">Instance of the <see cref="IDtoService"/> interface.</param>
        /// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
        public PersonsController(
            ILibraryManager libraryManager,
            IDtoService dtoService,
            IUserManager userManager)
        {
            _libraryManager = libraryManager;
            _dtoService = dtoService;
            _userManager = userManager;
        }

        /// <summary>
        /// Gets all persons.
        /// </summary>
        /// <param name="limit">Optional. The maximum number of records to return.</param>
        /// <param name="searchTerm">The search term.</param>
        /// <param name="fields">Optional. Specify additional fields of information to return in the output.</param>
        /// <param name="filters">Optional. Specify additional filters to apply.</param>
        /// <param name="isFavorite">Optional filter by items that are marked as favorite, or not. userId is required.</param>
        /// <param name="enableUserData">Optional, include user data.</param>
        /// <param name="imageTypeLimit">Optional, the max number of images to return, per image type.</param>
        /// <param name="enableImageTypes">Optional. The image types to include in the output.</param>
        /// <param name="excludePersonTypes">Optional. If specified results will be filtered to exclude those containing the specified PersonType. Allows multiple, comma-delimited.</param>
        /// <param name="personTypes">Optional. If specified results will be filtered to include only those containing the specified PersonType. Allows multiple, comma-delimited.</param>
        /// <param name="appearsInItemId">Optional. If specified, person results will be filtered on items related to said persons.</param>
        /// <param name="userId">User id.</param>
        /// <param name="enableImages">Optional, include image information in output.</param>
        /// <response code="200">Persons returned.</response>
        /// <returns>An <see cref="OkResult"/> containing the queryresult of persons.</returns>
        [HttpGet]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public ActionResult<QueryResult<BaseItemDto>> GetPersons(
            [FromQuery] int? limit,
            [FromQuery] string? searchTerm,
            [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
            [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFilter[] filters,
            [FromQuery] bool? isFavorite,
            [FromQuery] bool? enableUserData,
            [FromQuery] int? imageTypeLimit,
            [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes,
            [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludePersonTypes,
            [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] personTypes,
            [FromQuery] Guid? appearsInItemId,
            [FromQuery] Guid? userId,
            [FromQuery] bool? enableImages = true)
        {
            var dtoOptions = new DtoOptions { Fields = fields }
                .AddClientFields(Request)
                .AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);

            User? user = userId is null || userId.Value.Equals(default)
                ? null
                : _userManager.GetUserById(userId.Value);

            var isFavoriteInFilters = filters.Any(f => f == ItemFilter.IsFavorite);
            var peopleItems = _libraryManager.GetPeopleItems(new InternalPeopleQuery(
                personTypes,
                excludePersonTypes)
            {
                NameContains = searchTerm,
                User = user,
                IsFavorite = !isFavorite.HasValue && isFavoriteInFilters ? true : isFavorite,
                AppearsInItemId = appearsInItemId ?? Guid.Empty,
                Limit = limit ?? 0
            });

            return new QueryResult<BaseItemDto>(peopleItems.Select(person => _dtoService.GetItemByNameDto(person, dtoOptions, null, user)).ToArray());
        }

        /// <summary>
        /// Get person by name.
        /// </summary>
        /// <param name="name">Person name.</param>
        /// <param name="userId">Optional. Filter by user id, and attach user data.</param>
        /// <response code="200">Person returned.</response>
        /// <response code="404">Person not found.</response>
        /// <returns>An <see cref="OkResult"/> containing the person on success,
        /// or a <see cref="NotFoundResult"/> if person not found.</returns>
        [HttpGet("{name}")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public ActionResult<BaseItemDto> GetPerson([FromRoute, Required] string name, [FromQuery] Guid? userId)
        {
            var dtoOptions = new DtoOptions()
                .AddClientFields(Request);

            var item = _libraryManager.GetPerson(name);
            if (item == null)
            {
                return NotFound();
            }

            if (userId.HasValue && !userId.Value.Equals(default))
            {
                var user = _userManager.GetUserById(userId.Value);
                return _dtoService.GetBaseItemDto(item, dtoOptions, user);
            }

            return _dtoService.GetBaseItemDto(item, dtoOptions);
        }
    }
}