using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using Jellyfin.Api.Constants; using MediaBrowser.Controller; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Providers; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace Jellyfin.Api.Controllers { /// /// Remote Images Controller. /// [Route("")] public class RemoteImageController : BaseJellyfinApiController { private readonly IProviderManager _providerManager; private readonly IServerApplicationPaths _applicationPaths; private readonly ILibraryManager _libraryManager; /// /// Initializes a new instance of the class. /// /// Instance of the interface. /// Instance of the interface. /// Instance of the interface. public RemoteImageController( IProviderManager providerManager, IServerApplicationPaths applicationPaths, ILibraryManager libraryManager) { _providerManager = providerManager; _applicationPaths = applicationPaths; _libraryManager = libraryManager; } /// /// Gets available remote images for an item. /// /// Item Id. /// The image type. /// 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. The image provider to use. /// Optional. Include all languages. /// Remote Images returned. /// Item not found. /// Remote Image Result. [HttpGet("Items/{itemId}/RemoteImages")] [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> GetRemoteImages( [FromRoute, Required] Guid itemId, [FromQuery] ImageType? type, [FromQuery] int? startIndex, [FromQuery] int? limit, [FromQuery] string? providerName, [FromQuery] bool includeAllLanguages = false) { var item = _libraryManager.GetItemById(itemId); if (item is null) { return NotFound(); } var images = await _providerManager.GetAvailableRemoteImages( item, new RemoteImageQuery(providerName ?? string.Empty) { IncludeAllLanguages = includeAllLanguages, IncludeDisabledProviders = true, ImageType = type }, CancellationToken.None) .ConfigureAwait(false); var imageArray = images.ToArray(); var allProviders = _providerManager.GetRemoteImageProviderInfo(item); if (type.HasValue) { allProviders = allProviders.Where(o => o.SupportedImages.Contains(type.Value)); } var result = new RemoteImageResult { TotalRecordCount = imageArray.Length, Providers = allProviders.Select(o => o.Name) .Distinct(StringComparer.OrdinalIgnoreCase) .ToArray() }; if (startIndex.HasValue) { imageArray = imageArray.Skip(startIndex.Value).ToArray(); } if (limit.HasValue) { imageArray = imageArray.Take(limit.Value).ToArray(); } result.Images = imageArray; return result; } /// /// Gets available remote image providers for an item. /// /// Item Id. /// Returned remote image providers. /// Item not found. /// List of remote image providers. [HttpGet("Items/{itemId}/RemoteImages/Providers")] [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult> GetRemoteImageProviders([FromRoute, Required] Guid itemId) { var item = _libraryManager.GetItemById(itemId); if (item is null) { return NotFound(); } return Ok(_providerManager.GetRemoteImageProviderInfo(item)); } /// /// Downloads a remote image for an item. /// /// Item Id. /// The image type. /// The image url. /// Remote image downloaded. /// Remote image not found. /// Download status. [HttpPost("Items/{itemId}/RemoteImages/Download")] [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task DownloadRemoteImage( [FromRoute, Required] Guid itemId, [FromQuery, Required] ImageType type, [FromQuery] string? imageUrl) { var item = _libraryManager.GetItemById(itemId); if (item is null) { return NotFound(); } await _providerManager.SaveImage(item, imageUrl, type, null, CancellationToken.None) .ConfigureAwait(false); await item.UpdateToRepositoryAsync(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false); return NoContent(); } /// /// Gets the full cache path. /// /// The filename. /// System.String. private string GetFullCachePath(string filename) { return Path.Combine(_applicationPaths.CachePath, "remote-images", filename.Substring(0, 1), filename); } } }