using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; using Jellyfin.Api.Constants; using MediaBrowser.Common.Updates; using MediaBrowser.Controller.Configuration; using MediaBrowser.Model.Updates; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace Jellyfin.Api.Controllers { /// /// Package Controller. /// [Route("Packages")] [Authorize(Policy = Policies.DefaultAuthorization)] public class PackageController : BaseJellyfinApiController { private readonly IInstallationManager _installationManager; private readonly IServerConfigurationManager _serverConfigurationManager; /// /// Initializes a new instance of the class. /// /// Instance of the interface. /// Instance of the interface. public PackageController(IInstallationManager installationManager, IServerConfigurationManager serverConfigurationManager) { _installationManager = installationManager; _serverConfigurationManager = serverConfigurationManager; } /// /// Gets a package by name or assembly GUID. /// /// The name of the package. /// The GUID of the associated assembly. /// Package retrieved. /// A containing package information. [HttpGet("/{name}")] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> GetPackageInfo( [FromRoute] [Required] string? name, [FromQuery] string? assemblyGuid) { var packages = await _installationManager.GetAvailablePackages().ConfigureAwait(false); var result = _installationManager.FilterPackages( packages, name, string.IsNullOrEmpty(assemblyGuid) ? default : Guid.Parse(assemblyGuid)).FirstOrDefault(); return result; } /// /// Gets available packages. /// /// Available packages returned. /// An containing available packages information. [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> GetPackages() { IEnumerable packages = await _installationManager.GetAvailablePackages().ConfigureAwait(false); return packages; } /// /// Installs a package. /// /// Package name. /// GUID of the associated assembly. /// Optional version. Defaults to latest version. /// Package found. /// Package not found. /// A on success, or a if the package could not be found. [HttpPost("/Installed/{name}")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize(Policy = Policies.RequiresElevation)] public async Task InstallPackage( [FromRoute] [Required] string? name, [FromQuery] string? assemblyGuid, [FromQuery] string? version) { var packages = await _installationManager.GetAvailablePackages().ConfigureAwait(false); var package = _installationManager.GetCompatibleVersions( packages, name, string.IsNullOrEmpty(assemblyGuid) ? Guid.Empty : Guid.Parse(assemblyGuid), string.IsNullOrEmpty(version) ? null : Version.Parse(version)).FirstOrDefault(); if (package == null) { return NotFound(); } await _installationManager.InstallPackage(package).ConfigureAwait(false); return NoContent(); } /// /// Cancels a package installation. /// /// Installation Id. /// Installation cancelled. /// A on successfully cancelling a package installation. [HttpDelete("/Installing/{packageId}")] [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult CancelPackageInstallation( [FromRoute] [Required] Guid packageId) { _installationManager.CancelInstallation(packageId); return NoContent(); } /// /// Gets all package repositories. /// /// Package repositories returned. /// An containing the list of package repositories. [HttpGet("/Repositories")] [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult> GetRepositories() { return _serverConfigurationManager.Configuration.PluginRepositories; } /// /// Sets the enabled and existing package repositories. /// /// The list of package repositories. /// Package repositories saved. /// A . [HttpOptions("/Repositories")] [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult SetRepositories([FromBody] List repositoryInfos) { _serverConfigurationManager.Configuration.PluginRepositories = repositoryInfos; return NoContent(); } } }