diff options
Diffstat (limited to 'Jellyfin.Api/Controllers/ItemLookupController.cs')
| -rw-r--r-- | Jellyfin.Api/Controllers/ItemLookupController.cs | 464 |
1 files changed, 231 insertions, 233 deletions
diff --git a/Jellyfin.Api/Controllers/ItemLookupController.cs b/Jellyfin.Api/Controllers/ItemLookupController.cs index b6c5504db..b030e74dd 100644 --- a/Jellyfin.Api/Controllers/ItemLookupController.cs +++ b/Jellyfin.Api/Controllers/ItemLookupController.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using System.Text.Json; using System.Threading; using System.Threading.Tasks; using Jellyfin.Api.Constants; @@ -18,257 +17,256 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; -namespace Jellyfin.Api.Controllers +namespace Jellyfin.Api.Controllers; + +/// <summary> +/// Item lookup controller. +/// </summary> +[Route("")] +[Authorize] +public class ItemLookupController : BaseJellyfinApiController { + private readonly IProviderManager _providerManager; + private readonly IFileSystem _fileSystem; + private readonly ILibraryManager _libraryManager; + private readonly ILogger<ItemLookupController> _logger; + /// <summary> - /// Item lookup controller. + /// Initializes a new instance of the <see cref="ItemLookupController"/> class. /// </summary> - [Route("")] - [Authorize(Policy = Policies.DefaultAuthorization)] - public class ItemLookupController : BaseJellyfinApiController + /// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param> + /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param> + /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param> + /// <param name="logger">Instance of the <see cref="ILogger{ItemLookupController}"/> interface.</param> + public ItemLookupController( + IProviderManager providerManager, + IFileSystem fileSystem, + ILibraryManager libraryManager, + ILogger<ItemLookupController> logger) { - private readonly IProviderManager _providerManager; - private readonly IFileSystem _fileSystem; - private readonly ILibraryManager _libraryManager; - private readonly ILogger<ItemLookupController> _logger; + _providerManager = providerManager; + _fileSystem = fileSystem; + _libraryManager = libraryManager; + _logger = logger; + } - /// <summary> - /// Initializes a new instance of the <see cref="ItemLookupController"/> class. - /// </summary> - /// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param> - /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param> - /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param> - /// <param name="logger">Instance of the <see cref="ILogger{ItemLookupController}"/> interface.</param> - public ItemLookupController( - IProviderManager providerManager, - IFileSystem fileSystem, - ILibraryManager libraryManager, - ILogger<ItemLookupController> logger) + /// <summary> + /// Get the item's external id info. + /// </summary> + /// <param name="itemId">Item id.</param> + /// <response code="200">External id info retrieved.</response> + /// <response code="404">Item not found.</response> + /// <returns>List of external id info.</returns> + [HttpGet("Items/{itemId}/ExternalIdInfos")] + [Authorize(Policy = Policies.RequiresElevation)] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public ActionResult<IEnumerable<ExternalIdInfo>> GetExternalIdInfos([FromRoute, Required] Guid itemId) + { + var item = _libraryManager.GetItemById(itemId); + if (item is null) { - _providerManager = providerManager; - _fileSystem = fileSystem; - _libraryManager = libraryManager; - _logger = logger; + return NotFound(); } - /// <summary> - /// Get the item's external id info. - /// </summary> - /// <param name="itemId">Item id.</param> - /// <response code="200">External id info retrieved.</response> - /// <response code="404">Item not found.</response> - /// <returns>List of external id info.</returns> - [HttpGet("Items/{itemId}/ExternalIdInfos")] - [Authorize(Policy = Policies.RequiresElevation)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult<IEnumerable<ExternalIdInfo>> GetExternalIdInfos([FromRoute, Required] Guid itemId) - { - var item = _libraryManager.GetItemById(itemId); - if (item is null) - { - return NotFound(); - } - - return Ok(_providerManager.GetExternalIdInfos(item)); - } + return Ok(_providerManager.GetExternalIdInfos(item)); + } - /// <summary> - /// Get movie remote search. - /// </summary> - /// <param name="query">Remote search query.</param> - /// <response code="200">Movie remote search executed.</response> - /// <returns> - /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. - /// The task result contains an <see cref="OkResult"/> containing the list of remote search results. - /// </returns> - [HttpPost("Items/RemoteSearch/Movie")] - public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetMovieRemoteSearchResults([FromBody, Required] RemoteSearchQuery<MovieInfo> query) - { - var results = await _providerManager.GetRemoteSearchResults<Movie, MovieInfo>(query, CancellationToken.None) - .ConfigureAwait(false); - return Ok(results); - } + /// <summary> + /// Get movie remote search. + /// </summary> + /// <param name="query">Remote search query.</param> + /// <response code="200">Movie remote search executed.</response> + /// <returns> + /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. + /// The task result contains an <see cref="OkResult"/> containing the list of remote search results. + /// </returns> + [HttpPost("Items/RemoteSearch/Movie")] + public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetMovieRemoteSearchResults([FromBody, Required] RemoteSearchQuery<MovieInfo> query) + { + var results = await _providerManager.GetRemoteSearchResults<Movie, MovieInfo>(query, CancellationToken.None) + .ConfigureAwait(false); + return Ok(results); + } - /// <summary> - /// Get trailer remote search. - /// </summary> - /// <param name="query">Remote search query.</param> - /// <response code="200">Trailer remote search executed.</response> - /// <returns> - /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. - /// The task result contains an <see cref="OkResult"/> containing the list of remote search results. - /// </returns> - [HttpPost("Items/RemoteSearch/Trailer")] - public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetTrailerRemoteSearchResults([FromBody, Required] RemoteSearchQuery<TrailerInfo> query) - { - var results = await _providerManager.GetRemoteSearchResults<Trailer, TrailerInfo>(query, CancellationToken.None) - .ConfigureAwait(false); - return Ok(results); - } + /// <summary> + /// Get trailer remote search. + /// </summary> + /// <param name="query">Remote search query.</param> + /// <response code="200">Trailer remote search executed.</response> + /// <returns> + /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. + /// The task result contains an <see cref="OkResult"/> containing the list of remote search results. + /// </returns> + [HttpPost("Items/RemoteSearch/Trailer")] + public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetTrailerRemoteSearchResults([FromBody, Required] RemoteSearchQuery<TrailerInfo> query) + { + var results = await _providerManager.GetRemoteSearchResults<Trailer, TrailerInfo>(query, CancellationToken.None) + .ConfigureAwait(false); + return Ok(results); + } - /// <summary> - /// Get music video remote search. - /// </summary> - /// <param name="query">Remote search query.</param> - /// <response code="200">Music video remote search executed.</response> - /// <returns> - /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. - /// The task result contains an <see cref="OkResult"/> containing the list of remote search results. - /// </returns> - [HttpPost("Items/RemoteSearch/MusicVideo")] - public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetMusicVideoRemoteSearchResults([FromBody, Required] RemoteSearchQuery<MusicVideoInfo> query) - { - var results = await _providerManager.GetRemoteSearchResults<MusicVideo, MusicVideoInfo>(query, CancellationToken.None) - .ConfigureAwait(false); - return Ok(results); - } + /// <summary> + /// Get music video remote search. + /// </summary> + /// <param name="query">Remote search query.</param> + /// <response code="200">Music video remote search executed.</response> + /// <returns> + /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. + /// The task result contains an <see cref="OkResult"/> containing the list of remote search results. + /// </returns> + [HttpPost("Items/RemoteSearch/MusicVideo")] + public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetMusicVideoRemoteSearchResults([FromBody, Required] RemoteSearchQuery<MusicVideoInfo> query) + { + var results = await _providerManager.GetRemoteSearchResults<MusicVideo, MusicVideoInfo>(query, CancellationToken.None) + .ConfigureAwait(false); + return Ok(results); + } - /// <summary> - /// Get series remote search. - /// </summary> - /// <param name="query">Remote search query.</param> - /// <response code="200">Series remote search executed.</response> - /// <returns> - /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. - /// The task result contains an <see cref="OkResult"/> containing the list of remote search results. - /// </returns> - [HttpPost("Items/RemoteSearch/Series")] - public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetSeriesRemoteSearchResults([FromBody, Required] RemoteSearchQuery<SeriesInfo> query) - { - var results = await _providerManager.GetRemoteSearchResults<Series, SeriesInfo>(query, CancellationToken.None) - .ConfigureAwait(false); - return Ok(results); - } + /// <summary> + /// Get series remote search. + /// </summary> + /// <param name="query">Remote search query.</param> + /// <response code="200">Series remote search executed.</response> + /// <returns> + /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. + /// The task result contains an <see cref="OkResult"/> containing the list of remote search results. + /// </returns> + [HttpPost("Items/RemoteSearch/Series")] + public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetSeriesRemoteSearchResults([FromBody, Required] RemoteSearchQuery<SeriesInfo> query) + { + var results = await _providerManager.GetRemoteSearchResults<Series, SeriesInfo>(query, CancellationToken.None) + .ConfigureAwait(false); + return Ok(results); + } - /// <summary> - /// Get box set remote search. - /// </summary> - /// <param name="query">Remote search query.</param> - /// <response code="200">Box set remote search executed.</response> - /// <returns> - /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. - /// The task result contains an <see cref="OkResult"/> containing the list of remote search results. - /// </returns> - [HttpPost("Items/RemoteSearch/BoxSet")] - public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetBoxSetRemoteSearchResults([FromBody, Required] RemoteSearchQuery<BoxSetInfo> query) - { - var results = await _providerManager.GetRemoteSearchResults<BoxSet, BoxSetInfo>(query, CancellationToken.None) - .ConfigureAwait(false); - return Ok(results); - } + /// <summary> + /// Get box set remote search. + /// </summary> + /// <param name="query">Remote search query.</param> + /// <response code="200">Box set remote search executed.</response> + /// <returns> + /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. + /// The task result contains an <see cref="OkResult"/> containing the list of remote search results. + /// </returns> + [HttpPost("Items/RemoteSearch/BoxSet")] + public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetBoxSetRemoteSearchResults([FromBody, Required] RemoteSearchQuery<BoxSetInfo> query) + { + var results = await _providerManager.GetRemoteSearchResults<BoxSet, BoxSetInfo>(query, CancellationToken.None) + .ConfigureAwait(false); + return Ok(results); + } - /// <summary> - /// Get music artist remote search. - /// </summary> - /// <param name="query">Remote search query.</param> - /// <response code="200">Music artist remote search executed.</response> - /// <returns> - /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. - /// The task result contains an <see cref="OkResult"/> containing the list of remote search results. - /// </returns> - [HttpPost("Items/RemoteSearch/MusicArtist")] - public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetMusicArtistRemoteSearchResults([FromBody, Required] RemoteSearchQuery<ArtistInfo> query) - { - var results = await _providerManager.GetRemoteSearchResults<MusicArtist, ArtistInfo>(query, CancellationToken.None) - .ConfigureAwait(false); - return Ok(results); - } + /// <summary> + /// Get music artist remote search. + /// </summary> + /// <param name="query">Remote search query.</param> + /// <response code="200">Music artist remote search executed.</response> + /// <returns> + /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. + /// The task result contains an <see cref="OkResult"/> containing the list of remote search results. + /// </returns> + [HttpPost("Items/RemoteSearch/MusicArtist")] + public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetMusicArtistRemoteSearchResults([FromBody, Required] RemoteSearchQuery<ArtistInfo> query) + { + var results = await _providerManager.GetRemoteSearchResults<MusicArtist, ArtistInfo>(query, CancellationToken.None) + .ConfigureAwait(false); + return Ok(results); + } - /// <summary> - /// Get music album remote search. - /// </summary> - /// <param name="query">Remote search query.</param> - /// <response code="200">Music album remote search executed.</response> - /// <returns> - /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. - /// The task result contains an <see cref="OkResult"/> containing the list of remote search results. - /// </returns> - [HttpPost("Items/RemoteSearch/MusicAlbum")] - public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetMusicAlbumRemoteSearchResults([FromBody, Required] RemoteSearchQuery<AlbumInfo> query) - { - var results = await _providerManager.GetRemoteSearchResults<MusicAlbum, AlbumInfo>(query, CancellationToken.None) - .ConfigureAwait(false); - return Ok(results); - } + /// <summary> + /// Get music album remote search. + /// </summary> + /// <param name="query">Remote search query.</param> + /// <response code="200">Music album remote search executed.</response> + /// <returns> + /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. + /// The task result contains an <see cref="OkResult"/> containing the list of remote search results. + /// </returns> + [HttpPost("Items/RemoteSearch/MusicAlbum")] + public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetMusicAlbumRemoteSearchResults([FromBody, Required] RemoteSearchQuery<AlbumInfo> query) + { + var results = await _providerManager.GetRemoteSearchResults<MusicAlbum, AlbumInfo>(query, CancellationToken.None) + .ConfigureAwait(false); + return Ok(results); + } - /// <summary> - /// Get person remote search. - /// </summary> - /// <param name="query">Remote search query.</param> - /// <response code="200">Person remote search executed.</response> - /// <returns> - /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. - /// The task result contains an <see cref="OkResult"/> containing the list of remote search results. - /// </returns> - [HttpPost("Items/RemoteSearch/Person")] - [Authorize(Policy = Policies.RequiresElevation)] - public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetPersonRemoteSearchResults([FromBody, Required] RemoteSearchQuery<PersonLookupInfo> query) - { - var results = await _providerManager.GetRemoteSearchResults<Person, PersonLookupInfo>(query, CancellationToken.None) - .ConfigureAwait(false); - return Ok(results); - } + /// <summary> + /// Get person remote search. + /// </summary> + /// <param name="query">Remote search query.</param> + /// <response code="200">Person remote search executed.</response> + /// <returns> + /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. + /// The task result contains an <see cref="OkResult"/> containing the list of remote search results. + /// </returns> + [HttpPost("Items/RemoteSearch/Person")] + [Authorize(Policy = Policies.RequiresElevation)] + public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetPersonRemoteSearchResults([FromBody, Required] RemoteSearchQuery<PersonLookupInfo> query) + { + var results = await _providerManager.GetRemoteSearchResults<Person, PersonLookupInfo>(query, CancellationToken.None) + .ConfigureAwait(false); + return Ok(results); + } - /// <summary> - /// Get book remote search. - /// </summary> - /// <param name="query">Remote search query.</param> - /// <response code="200">Book remote search executed.</response> - /// <returns> - /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. - /// The task result contains an <see cref="OkResult"/> containing the list of remote search results. - /// </returns> - [HttpPost("Items/RemoteSearch/Book")] - public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetBookRemoteSearchResults([FromBody, Required] RemoteSearchQuery<BookInfo> query) - { - var results = await _providerManager.GetRemoteSearchResults<Book, BookInfo>(query, CancellationToken.None) - .ConfigureAwait(false); - return Ok(results); - } + /// <summary> + /// Get book remote search. + /// </summary> + /// <param name="query">Remote search query.</param> + /// <response code="200">Book remote search executed.</response> + /// <returns> + /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. + /// The task result contains an <see cref="OkResult"/> containing the list of remote search results. + /// </returns> + [HttpPost("Items/RemoteSearch/Book")] + public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetBookRemoteSearchResults([FromBody, Required] RemoteSearchQuery<BookInfo> query) + { + var results = await _providerManager.GetRemoteSearchResults<Book, BookInfo>(query, CancellationToken.None) + .ConfigureAwait(false); + return Ok(results); + } - /// <summary> - /// Applies search criteria to an item and refreshes metadata. - /// </summary> - /// <param name="itemId">Item id.</param> - /// <param name="searchResult">The remote search result.</param> - /// <param name="replaceAllImages">Optional. Whether or not to replace all images. Default: True.</param> - /// <response code="204">Item metadata refreshed.</response> - /// <returns> - /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. - /// The task result contains an <see cref="NoContentResult"/>. - /// </returns> - [HttpPost("Items/RemoteSearch/Apply/{itemId}")] - [Authorize(Policy = Policies.RequiresElevation)] - [ProducesResponseType(StatusCodes.Status204NoContent)] - public async Task<ActionResult> ApplySearchCriteria( - [FromRoute, Required] Guid itemId, - [FromBody, Required] RemoteSearchResult searchResult, - [FromQuery] bool replaceAllImages = true) - { - var item = _libraryManager.GetItemById(itemId); - _logger.LogInformation( - "Setting provider id's to item {ItemId}-{ItemName}: {@ProviderIds}", - item.Id, - item.Name, - searchResult.ProviderIds); + /// <summary> + /// Applies search criteria to an item and refreshes metadata. + /// </summary> + /// <param name="itemId">Item id.</param> + /// <param name="searchResult">The remote search result.</param> + /// <param name="replaceAllImages">Optional. Whether or not to replace all images. Default: True.</param> + /// <response code="204">Item metadata refreshed.</response> + /// <returns> + /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results. + /// The task result contains an <see cref="NoContentResult"/>. + /// </returns> + [HttpPost("Items/RemoteSearch/Apply/{itemId}")] + [Authorize(Policy = Policies.RequiresElevation)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + public async Task<ActionResult> ApplySearchCriteria( + [FromRoute, Required] Guid itemId, + [FromBody, Required] RemoteSearchResult searchResult, + [FromQuery] bool replaceAllImages = true) + { + var item = _libraryManager.GetItemById(itemId); + _logger.LogInformation( + "Setting provider id's to item {ItemId}-{ItemName}: {@ProviderIds}", + item.Id, + item.Name, + searchResult.ProviderIds); - // Since the refresh process won't erase provider Ids, we need to set this explicitly now. - item.ProviderIds = searchResult.ProviderIds; - await _providerManager.RefreshFullItem( - item, - new MetadataRefreshOptions(new DirectoryService(_fileSystem)) - { - MetadataRefreshMode = MetadataRefreshMode.FullRefresh, - ImageRefreshMode = MetadataRefreshMode.FullRefresh, - ReplaceAllMetadata = true, - ReplaceAllImages = replaceAllImages, - SearchResult = searchResult, - RemoveOldMetadata = true - }, - CancellationToken.None).ConfigureAwait(false); + // Since the refresh process won't erase provider Ids, we need to set this explicitly now. + item.ProviderIds = searchResult.ProviderIds; + await _providerManager.RefreshFullItem( + item, + new MetadataRefreshOptions(new DirectoryService(_fileSystem)) + { + MetadataRefreshMode = MetadataRefreshMode.FullRefresh, + ImageRefreshMode = MetadataRefreshMode.FullRefresh, + ReplaceAllMetadata = true, + ReplaceAllImages = replaceAllImages, + SearchResult = searchResult, + RemoveOldMetadata = true + }, + CancellationToken.None).ConfigureAwait(false); - return NoContent(); - } + return NoContent(); } } |
