< Summary - Jellyfin

Information
Class: Jellyfin.Api.Controllers.ItemLookupController
Assembly: Jellyfin.Api
File(s): /srv/git/jellyfin/Jellyfin.Api/Controllers/ItemLookupController.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 14
Coverable lines: 14
Total lines: 282
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 2
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
GetExternalIdInfos(...)0%620%

File(s)

/srv/git/jellyfin/Jellyfin.Api/Controllers/ItemLookupController.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.ComponentModel.DataAnnotations;
 4using System.Threading;
 5using System.Threading.Tasks;
 6using Jellyfin.Api.Constants;
 7using Jellyfin.Api.Extensions;
 8using Jellyfin.Api.Helpers;
 9using MediaBrowser.Common.Api;
 10using MediaBrowser.Controller.Entities;
 11using MediaBrowser.Controller.Entities.Audio;
 12using MediaBrowser.Controller.Entities.Movies;
 13using MediaBrowser.Controller.Entities.TV;
 14using MediaBrowser.Controller.Library;
 15using MediaBrowser.Controller.Providers;
 16using MediaBrowser.Model.IO;
 17using MediaBrowser.Model.Providers;
 18using Microsoft.AspNetCore.Authorization;
 19using Microsoft.AspNetCore.Http;
 20using Microsoft.AspNetCore.Mvc;
 21using Microsoft.Extensions.Logging;
 22
 23namespace Jellyfin.Api.Controllers;
 24
 25/// <summary>
 26/// Item lookup controller.
 27/// </summary>
 28[Route("")]
 29[Authorize]
 30public class ItemLookupController : BaseJellyfinApiController
 31{
 32    private readonly IProviderManager _providerManager;
 33    private readonly IFileSystem _fileSystem;
 34    private readonly ILibraryManager _libraryManager;
 35    private readonly ILogger<ItemLookupController> _logger;
 36
 37    /// <summary>
 38    /// Initializes a new instance of the <see cref="ItemLookupController"/> class.
 39    /// </summary>
 40    /// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
 41    /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
 42    /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
 43    /// <param name="logger">Instance of the <see cref="ILogger{ItemLookupController}"/> interface.</param>
 044    public ItemLookupController(
 045        IProviderManager providerManager,
 046        IFileSystem fileSystem,
 047        ILibraryManager libraryManager,
 048        ILogger<ItemLookupController> logger)
 49    {
 050        _providerManager = providerManager;
 051        _fileSystem = fileSystem;
 052        _libraryManager = libraryManager;
 053        _logger = logger;
 054    }
 55
 56    /// <summary>
 57    /// Get the item's external id info.
 58    /// </summary>
 59    /// <param name="itemId">Item id.</param>
 60    /// <response code="200">External id info retrieved.</response>
 61    /// <response code="404">Item not found.</response>
 62    /// <returns>List of external id info.</returns>
 63    [HttpGet("Items/{itemId}/ExternalIdInfos")]
 64    [Authorize(Policy = Policies.RequiresElevation)]
 65    [ProducesResponseType(StatusCodes.Status200OK)]
 66    [ProducesResponseType(StatusCodes.Status404NotFound)]
 67    public ActionResult<IEnumerable<ExternalIdInfo>> GetExternalIdInfos([FromRoute, Required] Guid itemId)
 68    {
 069        var item = _libraryManager.GetItemById<BaseItem>(itemId, User.GetUserId());
 070        if (item is null)
 71        {
 072            return NotFound();
 73        }
 74
 075        return Ok(_providerManager.GetExternalIdInfos(item));
 76    }
 77
 78    /// <summary>
 79    /// Get movie remote search.
 80    /// </summary>
 81    /// <param name="query">Remote search query.</param>
 82    /// <response code="200">Movie remote search executed.</response>
 83    /// <returns>
 84    /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results.
 85    /// The task result contains an <see cref="OkResult"/> containing the list of remote search results.
 86    /// </returns>
 87    [HttpPost("Items/RemoteSearch/Movie")]
 88    public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetMovieRemoteSearchResults([FromBody, Required] Re
 89    {
 90        var results = await _providerManager.GetRemoteSearchResults<Movie, MovieInfo>(query, CancellationToken.None)
 91            .ConfigureAwait(false);
 92        return Ok(results);
 93    }
 94
 95    /// <summary>
 96    /// Get trailer remote search.
 97    /// </summary>
 98    /// <param name="query">Remote search query.</param>
 99    /// <response code="200">Trailer remote search executed.</response>
 100    /// <returns>
 101    /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results.
 102    /// The task result contains an <see cref="OkResult"/> containing the list of remote search results.
 103    /// </returns>
 104    [HttpPost("Items/RemoteSearch/Trailer")]
 105    public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetTrailerRemoteSearchResults([FromBody, Required] 
 106    {
 107        var results = await _providerManager.GetRemoteSearchResults<Trailer, TrailerInfo>(query, CancellationToken.None)
 108            .ConfigureAwait(false);
 109        return Ok(results);
 110    }
 111
 112    /// <summary>
 113    /// Get music video remote search.
 114    /// </summary>
 115    /// <param name="query">Remote search query.</param>
 116    /// <response code="200">Music video remote search executed.</response>
 117    /// <returns>
 118    /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results.
 119    /// The task result contains an <see cref="OkResult"/> containing the list of remote search results.
 120    /// </returns>
 121    [HttpPost("Items/RemoteSearch/MusicVideo")]
 122    public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetMusicVideoRemoteSearchResults([FromBody, Require
 123    {
 124        var results = await _providerManager.GetRemoteSearchResults<MusicVideo, MusicVideoInfo>(query, CancellationToken
 125            .ConfigureAwait(false);
 126        return Ok(results);
 127    }
 128
 129    /// <summary>
 130    /// Get series remote search.
 131    /// </summary>
 132    /// <param name="query">Remote search query.</param>
 133    /// <response code="200">Series remote search executed.</response>
 134    /// <returns>
 135    /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results.
 136    /// The task result contains an <see cref="OkResult"/> containing the list of remote search results.
 137    /// </returns>
 138    [HttpPost("Items/RemoteSearch/Series")]
 139    public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetSeriesRemoteSearchResults([FromBody, Required] R
 140    {
 141        var results = await _providerManager.GetRemoteSearchResults<Series, SeriesInfo>(query, CancellationToken.None)
 142            .ConfigureAwait(false);
 143        return Ok(results);
 144    }
 145
 146    /// <summary>
 147    /// Get box set remote search.
 148    /// </summary>
 149    /// <param name="query">Remote search query.</param>
 150    /// <response code="200">Box set remote search executed.</response>
 151    /// <returns>
 152    /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results.
 153    /// The task result contains an <see cref="OkResult"/> containing the list of remote search results.
 154    /// </returns>
 155    [HttpPost("Items/RemoteSearch/BoxSet")]
 156    public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetBoxSetRemoteSearchResults([FromBody, Required] R
 157    {
 158        var results = await _providerManager.GetRemoteSearchResults<BoxSet, BoxSetInfo>(query, CancellationToken.None)
 159            .ConfigureAwait(false);
 160        return Ok(results);
 161    }
 162
 163    /// <summary>
 164    /// Get music artist remote search.
 165    /// </summary>
 166    /// <param name="query">Remote search query.</param>
 167    /// <response code="200">Music artist remote search executed.</response>
 168    /// <returns>
 169    /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results.
 170    /// The task result contains an <see cref="OkResult"/> containing the list of remote search results.
 171    /// </returns>
 172    [HttpPost("Items/RemoteSearch/MusicArtist")]
 173    public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetMusicArtistRemoteSearchResults([FromBody, Requir
 174    {
 175        var results = await _providerManager.GetRemoteSearchResults<MusicArtist, ArtistInfo>(query, CancellationToken.No
 176            .ConfigureAwait(false);
 177        return Ok(results);
 178    }
 179
 180    /// <summary>
 181    /// Get music album remote search.
 182    /// </summary>
 183    /// <param name="query">Remote search query.</param>
 184    /// <response code="200">Music album remote search executed.</response>
 185    /// <returns>
 186    /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results.
 187    /// The task result contains an <see cref="OkResult"/> containing the list of remote search results.
 188    /// </returns>
 189    [HttpPost("Items/RemoteSearch/MusicAlbum")]
 190    public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetMusicAlbumRemoteSearchResults([FromBody, Require
 191    {
 192        var results = await _providerManager.GetRemoteSearchResults<MusicAlbum, AlbumInfo>(query, CancellationToken.None
 193            .ConfigureAwait(false);
 194        return Ok(results);
 195    }
 196
 197    /// <summary>
 198    /// Get person remote search.
 199    /// </summary>
 200    /// <param name="query">Remote search query.</param>
 201    /// <response code="200">Person remote search executed.</response>
 202    /// <returns>
 203    /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results.
 204    /// The task result contains an <see cref="OkResult"/> containing the list of remote search results.
 205    /// </returns>
 206    [HttpPost("Items/RemoteSearch/Person")]
 207    [Authorize(Policy = Policies.RequiresElevation)]
 208    public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetPersonRemoteSearchResults([FromBody, Required] R
 209    {
 210        var results = await _providerManager.GetRemoteSearchResults<Person, PersonLookupInfo>(query, CancellationToken.N
 211            .ConfigureAwait(false);
 212        return Ok(results);
 213    }
 214
 215    /// <summary>
 216    /// Get book remote search.
 217    /// </summary>
 218    /// <param name="query">Remote search query.</param>
 219    /// <response code="200">Book remote search executed.</response>
 220    /// <returns>
 221    /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results.
 222    /// The task result contains an <see cref="OkResult"/> containing the list of remote search results.
 223    /// </returns>
 224    [HttpPost("Items/RemoteSearch/Book")]
 225    public async Task<ActionResult<IEnumerable<RemoteSearchResult>>> GetBookRemoteSearchResults([FromBody, Required] Rem
 226    {
 227        var results = await _providerManager.GetRemoteSearchResults<Book, BookInfo>(query, CancellationToken.None)
 228            .ConfigureAwait(false);
 229        return Ok(results);
 230    }
 231
 232    /// <summary>
 233    /// Applies search criteria to an item and refreshes metadata.
 234    /// </summary>
 235    /// <param name="itemId">Item id.</param>
 236    /// <param name="searchResult">The remote search result.</param>
 237    /// <param name="replaceAllImages">Optional. Whether or not to replace all images. Default: True.</param>
 238    /// <response code="204">Item metadata refreshed.</response>
 239    /// <response code="404">Item not found.</response>
 240    /// <returns>
 241    /// A <see cref="Task" /> that represents the asynchronous operation to get the remote search results.
 242    /// The task result contains an <see cref="NoContentResult"/>.
 243    /// </returns>
 244    [HttpPost("Items/RemoteSearch/Apply/{itemId}")]
 245    [Authorize(Policy = Policies.RequiresElevation)]
 246    [ProducesResponseType(StatusCodes.Status204NoContent)]
 247    [ProducesResponseType(StatusCodes.Status404NotFound)]
 248    public async Task<ActionResult> ApplySearchCriteria(
 249        [FromRoute, Required] Guid itemId,
 250        [FromBody, Required] RemoteSearchResult searchResult,
 251        [FromQuery] bool replaceAllImages = true)
 252    {
 253        var item = _libraryManager.GetItemById<BaseItem>(itemId, User.GetUserId());
 254        if (item is null)
 255        {
 256            return NotFound();
 257        }
 258
 259        _logger.LogInformation(
 260            "Setting provider id's to item {ItemId}-{ItemName}: {@ProviderIds}",
 261            item.Id,
 262            item.Name,
 263            searchResult.ProviderIds);
 264
 265        // Since the refresh process won't erase provider Ids, we need to set this explicitly now.
 266        item.ProviderIds = searchResult.ProviderIds;
 267        await _providerManager.RefreshFullItem(
 268            item,
 269            new MetadataRefreshOptions(new DirectoryService(_fileSystem))
 270            {
 271                MetadataRefreshMode = MetadataRefreshMode.FullRefresh,
 272                ImageRefreshMode = MetadataRefreshMode.FullRefresh,
 273                ReplaceAllMetadata = true,
 274                ReplaceAllImages = replaceAllImages,
 275                SearchResult = searchResult,
 276                RemoveOldMetadata = true
 277            },
 278            CancellationToken.None).ConfigureAwait(false);
 279
 280        return NoContent();
 281    }
 282}