using System; using System.ComponentModel.DataAnnotations; using System.Net.Mime; using System.Text.Json; using Jellyfin.Api.Attributes; using Jellyfin.Api.Constants; using Jellyfin.Api.Models.ConfigurationDtos; using Jellyfin.Extensions.Json; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Configuration; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace Jellyfin.Api.Controllers { /// /// Configuration Controller. /// [Route("System")] [Authorize(Policy = Policies.DefaultAuthorization)] public class ConfigurationController : BaseJellyfinApiController { private readonly IServerConfigurationManager _configurationManager; private readonly IMediaEncoder _mediaEncoder; private readonly JsonSerializerOptions _serializerOptions = JsonDefaults.Options; /// /// Initializes a new instance of the class. /// /// Instance of the interface. /// Instance of the interface. public ConfigurationController( IServerConfigurationManager configurationManager, IMediaEncoder mediaEncoder) { _configurationManager = configurationManager; _mediaEncoder = mediaEncoder; } /// /// Gets application configuration. /// /// Application configuration returned. /// Application configuration. [HttpGet("Configuration")] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult GetConfiguration() { return _configurationManager.Configuration; } /// /// Updates application configuration. /// /// Configuration. /// Configuration updated. /// Update status. [HttpPost("Configuration")] [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult UpdateConfiguration([FromBody, Required] ServerConfiguration configuration) { _configurationManager.ReplaceConfiguration(configuration); return NoContent(); } /// /// Gets a named configuration. /// /// Configuration key. /// Configuration returned. /// Configuration. [HttpGet("Configuration/{key}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesFile(MediaTypeNames.Application.Json)] public ActionResult GetNamedConfiguration([FromRoute, Required] string key) { return _configurationManager.GetConfiguration(key); } /// /// Updates named configuration. /// /// Configuration key. /// Configuration. /// Named configuration updated. /// Update status. [HttpPost("Configuration/{key}")] [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult UpdateNamedConfiguration([FromRoute, Required] string key, [FromBody, Required] JsonDocument configuration) { var configurationType = _configurationManager.GetConfigurationType(key); var deserializedConfiguration = configuration.Deserialize(configurationType, _serializerOptions); if (deserializedConfiguration is null) { throw new ArgumentException("Body doesn't contain a valid configuration"); } _configurationManager.SaveConfiguration(key, deserializedConfiguration); return NoContent(); } /// /// Gets a default MetadataOptions object. /// /// Metadata options returned. /// Default MetadataOptions. [HttpGet("Configuration/MetadataOptions/Default")] [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult GetDefaultMetadataOptions() { return new MetadataOptions(); } /// /// Updates the path to the media encoder. /// /// Media encoder path form body. /// Media encoder path updated. /// Status. [HttpPost("MediaEncoder/Path")] [Authorize(Policy = Policies.FirstTimeSetupOrElevated)] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult UpdateMediaEncoderPath([FromBody, Required] MediaEncoderPathDto mediaEncoderPath) { _mediaEncoder.UpdateEncoderPath(mediaEncoderPath.Path, mediaEncoderPath.PathType); return NoContent(); } } }