DevicesController.cs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. #nullable enable
  2. using System;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Threading.Tasks;
  6. using MediaBrowser.Controller.Devices;
  7. using MediaBrowser.Controller.Net;
  8. using MediaBrowser.Controller.Security;
  9. using MediaBrowser.Controller.Session;
  10. using MediaBrowser.Model.Devices;
  11. using Microsoft.AspNetCore.Http;
  12. using Microsoft.AspNetCore.Mvc;
  13. using Microsoft.AspNetCore.Mvc.ModelBinding;
  14. namespace Jellyfin.Api.Controllers
  15. {
  16. /// <summary>
  17. /// Devices Controller.
  18. /// </summary>
  19. [Authenticated]
  20. public class DevicesController : BaseJellyfinApiController
  21. {
  22. private readonly IDeviceManager _deviceManager;
  23. private readonly IAuthenticationRepository _authenticationRepository;
  24. private readonly ISessionManager _sessionManager;
  25. /// <summary>
  26. /// Initializes a new instance of the <see cref="DevicesController"/> class.
  27. /// </summary>
  28. /// <param name="deviceManager">Instance of <see cref="IDeviceManager"/> interface.</param>
  29. /// <param name="authenticationRepository">Instance of <see cref="IAuthenticationRepository"/> interface.</param>
  30. /// <param name="sessionManager">Instance of <see cref="ISessionManager"/> interface.</param>
  31. public DevicesController(
  32. IDeviceManager deviceManager,
  33. IAuthenticationRepository authenticationRepository,
  34. ISessionManager sessionManager)
  35. {
  36. _deviceManager = deviceManager;
  37. _authenticationRepository = authenticationRepository;
  38. _sessionManager = sessionManager;
  39. }
  40. /// <summary>
  41. /// Get Devices.
  42. /// </summary>
  43. /// <param name="supportsSync">/// Gets or sets a value indicating whether [supports synchronize].</param>
  44. /// <param name="userId">/// Gets or sets the user identifier.</param>
  45. /// <returns>Device Infos.</returns>
  46. [HttpGet]
  47. [Authenticated(Roles = "Admin")]
  48. [ProducesResponseType(typeof(DeviceInfo[]), StatusCodes.Status200OK)]
  49. [ProducesResponseType(typeof(string), StatusCodes.Status500InternalServerError)]
  50. public IActionResult GetDevices([FromQuery] bool? supportsSync, [FromQuery] Guid? userId)
  51. {
  52. try
  53. {
  54. var deviceQuery = new DeviceQuery { SupportsSync = supportsSync, UserId = userId ?? Guid.Empty };
  55. var devices = _deviceManager.GetDevices(deviceQuery);
  56. return Ok(devices);
  57. }
  58. catch (Exception e)
  59. {
  60. return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
  61. }
  62. }
  63. /// <summary>
  64. /// Get info for a device.
  65. /// </summary>
  66. /// <param name="id">Device Id.</param>
  67. /// <returns>Device Info.</returns>
  68. [HttpGet("Info")]
  69. [Authenticated(Roles = "Admin")]
  70. [ProducesResponseType(typeof(DeviceInfo), StatusCodes.Status200OK)]
  71. [ProducesResponseType(StatusCodes.Status404NotFound)]
  72. [ProducesResponseType(typeof(string), StatusCodes.Status500InternalServerError)]
  73. public IActionResult GetDeviceInfo([FromQuery, BindRequired] string id)
  74. {
  75. try
  76. {
  77. var deviceInfo = _deviceManager.GetDevice(id);
  78. if (deviceInfo == null)
  79. {
  80. return NotFound();
  81. }
  82. return Ok(deviceInfo);
  83. }
  84. catch (Exception e)
  85. {
  86. return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
  87. }
  88. }
  89. /// <summary>
  90. /// Get options for a device.
  91. /// </summary>
  92. /// <param name="id">Device Id.</param>
  93. /// <returns>Device Info.</returns>
  94. [HttpGet("Options")]
  95. [Authenticated(Roles = "Admin")]
  96. [ProducesResponseType(typeof(DeviceOptions), StatusCodes.Status200OK)]
  97. [ProducesResponseType(StatusCodes.Status404NotFound)]
  98. [ProducesResponseType(typeof(string), StatusCodes.Status500InternalServerError)]
  99. public IActionResult GetDeviceOptions([FromQuery, BindRequired] string id)
  100. {
  101. try
  102. {
  103. var deviceInfo = _deviceManager.GetDeviceOptions(id);
  104. if (deviceInfo == null)
  105. {
  106. return NotFound();
  107. }
  108. return Ok(deviceInfo);
  109. }
  110. catch (Exception e)
  111. {
  112. return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
  113. }
  114. }
  115. /// <summary>
  116. /// Update device options.
  117. /// </summary>
  118. /// <param name="id">Device Id.</param>
  119. /// <param name="deviceOptions">Device Options.</param>
  120. /// <returns>Status.</returns>
  121. [HttpPost("Options")]
  122. [Authenticated(Roles = "Admin")]
  123. [ProducesResponseType(StatusCodes.Status200OK)]
  124. [ProducesResponseType(StatusCodes.Status404NotFound)]
  125. [ProducesResponseType(typeof(string), StatusCodes.Status500InternalServerError)]
  126. public IActionResult UpdateDeviceOptions(
  127. [FromQuery, BindRequired] string id,
  128. [FromBody, BindRequired] DeviceOptions deviceOptions)
  129. {
  130. try
  131. {
  132. var existingDeviceOptions = _deviceManager.GetDeviceOptions(id);
  133. if (existingDeviceOptions == null)
  134. {
  135. return NotFound();
  136. }
  137. _deviceManager.UpdateDeviceOptions(id, deviceOptions);
  138. return Ok();
  139. }
  140. catch (Exception e)
  141. {
  142. return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
  143. }
  144. }
  145. /// <summary>
  146. /// Deletes a device.
  147. /// </summary>
  148. /// <param name="id">Device Id.</param>
  149. /// <returns>Status.</returns>
  150. [HttpDelete]
  151. [ProducesResponseType(StatusCodes.Status200OK)]
  152. [ProducesResponseType(typeof(string), StatusCodes.Status500InternalServerError)]
  153. public IActionResult DeleteDevice([FromQuery, BindRequired] string id)
  154. {
  155. try
  156. {
  157. var sessions = _authenticationRepository.Get(new AuthenticationInfoQuery { DeviceId = id }).Items;
  158. foreach (var session in sessions)
  159. {
  160. _sessionManager.Logout(session);
  161. }
  162. return Ok();
  163. }
  164. catch (Exception e)
  165. {
  166. return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
  167. }
  168. }
  169. /// <summary>
  170. /// Gets camera upload history for a device.
  171. /// </summary>
  172. /// <param name="id">Device Id.</param>
  173. /// <returns>Content Upload History.</returns>
  174. [HttpGet("CameraUploads")]
  175. [ProducesResponseType(typeof(ContentUploadHistory), StatusCodes.Status200OK)]
  176. [ProducesResponseType(typeof(string), StatusCodes.Status500InternalServerError)]
  177. public IActionResult GetCameraUploads([FromQuery, BindRequired] string id)
  178. {
  179. try
  180. {
  181. var uploadHistory = _deviceManager.GetCameraUploadHistory(id);
  182. return Ok(uploadHistory);
  183. }
  184. catch (Exception e)
  185. {
  186. return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
  187. }
  188. }
  189. /// <summary>
  190. /// Uploads content.
  191. /// </summary>
  192. /// <param name="deviceId">Device Id.</param>
  193. /// <param name="album">Album.</param>
  194. /// <param name="name">Name.</param>
  195. /// <param name="id">Id.</param>
  196. /// <returns>Status.</returns>
  197. [HttpPost("CameraUploads")]
  198. [ProducesResponseType(StatusCodes.Status200OK)]
  199. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  200. [ProducesResponseType(typeof(string), StatusCodes.Status500InternalServerError)]
  201. public async Task<IActionResult> PostCameraUploadAsync(
  202. [FromQuery, BindRequired] string deviceId,
  203. [FromQuery, BindRequired] string album,
  204. [FromQuery, BindRequired] string name,
  205. [FromQuery, BindRequired] string id)
  206. {
  207. try
  208. {
  209. Stream fileStream;
  210. string contentType;
  211. if (Request.HasFormContentType)
  212. {
  213. if (Request.Form.Files.Any())
  214. {
  215. fileStream = Request.Form.Files[0].OpenReadStream();
  216. contentType = Request.Form.Files[0].ContentType;
  217. }
  218. else
  219. {
  220. return BadRequest();
  221. }
  222. }
  223. else
  224. {
  225. fileStream = Request.Body;
  226. contentType = Request.ContentType;
  227. }
  228. await _deviceManager.AcceptCameraUpload(
  229. deviceId,
  230. fileStream,
  231. new LocalFileInfo
  232. {
  233. MimeType = contentType,
  234. Album = album,
  235. Name = name,
  236. Id = id
  237. }).ConfigureAwait(false);
  238. return Ok();
  239. }
  240. catch (Exception e)
  241. {
  242. return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
  243. }
  244. }
  245. }
  246. }