#nullable enable using System; using System.IO; using System.Linq; using System.Threading.Tasks; using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Security; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Devices; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ModelBinding; namespace Jellyfin.Api.Controllers { /// /// Devices Controller. /// [Authenticated] public class DevicesController : BaseJellyfinApiController { private readonly IDeviceManager _deviceManager; private readonly IAuthenticationRepository _authenticationRepository; private readonly ISessionManager _sessionManager; /// /// Initializes a new instance of the class. /// /// Instance of interface. /// Instance of interface. /// Instance of interface. public DevicesController( IDeviceManager deviceManager, IAuthenticationRepository authenticationRepository, ISessionManager sessionManager) { _deviceManager = deviceManager; _authenticationRepository = authenticationRepository; _sessionManager = sessionManager; } /// /// Get Devices. /// /// /// Gets or sets a value indicating whether [supports synchronize]. /// /// Gets or sets the user identifier. /// Device Infos. [HttpGet] [Authenticated(Roles = "Admin")] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult GetDevices([FromQuery] bool? supportsSync, [FromQuery] Guid? userId) { var deviceQuery = new DeviceQuery { SupportsSync = supportsSync, UserId = userId ?? Guid.Empty }; var devices = _deviceManager.GetDevices(deviceQuery); return Ok(devices); } /// /// Get info for a device. /// /// Device Id. /// Device Info. [HttpGet("Info")] [Authenticated(Roles = "Admin")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult GetDeviceInfo([FromQuery, BindRequired] string id) { var deviceInfo = _deviceManager.GetDevice(id); if (deviceInfo == null) { return NotFound(); } return Ok(deviceInfo); } /// /// Get options for a device. /// /// Device Id. /// Device Info. [HttpGet("Options")] [Authenticated(Roles = "Admin")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult GetDeviceOptions([FromQuery, BindRequired] string id) { var deviceInfo = _deviceManager.GetDeviceOptions(id); if (deviceInfo == null) { return NotFound(); } return Ok(deviceInfo); } /// /// Update device options. /// /// Device Id. /// Device Options. /// Status. [HttpPost("Options")] [Authenticated(Roles = "Admin")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult UpdateDeviceOptions( [FromQuery, BindRequired] string id, [FromBody, BindRequired] DeviceOptions deviceOptions) { var existingDeviceOptions = _deviceManager.GetDeviceOptions(id); if (existingDeviceOptions == null) { return NotFound(); } _deviceManager.UpdateDeviceOptions(id, deviceOptions); return Ok(); } /// /// Deletes a device. /// /// Device Id. /// Status. [HttpDelete] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult DeleteDevice([FromQuery, BindRequired] string id) { var sessions = _authenticationRepository.Get(new AuthenticationInfoQuery { DeviceId = id }).Items; foreach (var session in sessions) { _sessionManager.Logout(session); } return Ok(); } /// /// Gets camera upload history for a device. /// /// Device Id. /// Content Upload History. [HttpGet("CameraUploads")] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult GetCameraUploads([FromQuery, BindRequired] string id) { var uploadHistory = _deviceManager.GetCameraUploadHistory(id); return Ok(uploadHistory); } /// /// Uploads content. /// /// Device Id. /// Album. /// Name. /// Id. /// Status. [HttpPost("CameraUploads")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task PostCameraUploadAsync( [FromQuery, BindRequired] string deviceId, [FromQuery, BindRequired] string album, [FromQuery, BindRequired] string name, [FromQuery, BindRequired] string id) { Stream fileStream; string contentType; if (Request.HasFormContentType) { if (Request.Form.Files.Any()) { fileStream = Request.Form.Files[0].OpenReadStream(); contentType = Request.Form.Files[0].ContentType; } else { return BadRequest(); } } else { fileStream = Request.Body; contentType = Request.ContentType; } await _deviceManager.AcceptCameraUpload( deviceId, fileStream, new LocalFileInfo { MimeType = contentType, Album = album, Name = name, Id = id }).ConfigureAwait(false); return Ok(); } } }