ImageController.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. using System;
  2. using System.IO;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using MediaBrowser.Controller.Configuration;
  6. using MediaBrowser.Controller.Drawing;
  7. using MediaBrowser.Controller.Library;
  8. using MediaBrowser.Controller.Net;
  9. using MediaBrowser.Controller.Providers;
  10. using MediaBrowser.Model.Entities;
  11. using MediaBrowser.Model.IO;
  12. using MediaBrowser.Model.Net;
  13. using Microsoft.AspNetCore.Mvc;
  14. using Microsoft.Extensions.Logging;
  15. namespace Jellyfin.Api.Controllers
  16. {
  17. /// <summary>
  18. /// Image controller.
  19. /// </summary>
  20. public class ImageController : BaseJellyfinApiController
  21. {
  22. private readonly IUserManager _userManager;
  23. private readonly ILibraryManager _libraryManager;
  24. private readonly IProviderManager _providerManager;
  25. private readonly IImageProcessor _imageProcessor;
  26. private readonly IFileSystem _fileSystem;
  27. private readonly IAuthorizationContext _authContext;
  28. private readonly ILogger<ImageController> _logger;
  29. private readonly IServerConfigurationManager _serverConfigurationManager;
  30. /// <summary>
  31. /// Initializes a new instance of the <see cref="ImageController"/> class.
  32. /// </summary>
  33. /// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
  34. /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
  35. /// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
  36. /// <param name="imageProcessor">Instance of the <see cref="IImageProcessor"/> interface.</param>
  37. /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
  38. /// <param name="authContext">Instance of the <see cref="IAuthorizationContext"/> interface.</param>
  39. /// <param name="logger">Instance of the <see cref="ILogger{ImageController}"/> interface.</param>
  40. /// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
  41. public ImageController(
  42. IUserManager userManager,
  43. ILibraryManager libraryManager,
  44. IProviderManager providerManager,
  45. IImageProcessor imageProcessor,
  46. IFileSystem fileSystem,
  47. IAuthorizationContext authContext,
  48. ILogger<ImageController> logger,
  49. IServerConfigurationManager serverConfigurationManager)
  50. {
  51. _userManager = userManager;
  52. _libraryManager = libraryManager;
  53. _providerManager = providerManager;
  54. _imageProcessor = imageProcessor;
  55. _fileSystem = fileSystem;
  56. _authContext = authContext;
  57. _logger = logger;
  58. _serverConfigurationManager = serverConfigurationManager;
  59. }
  60. /// <summary>
  61. /// Sets the user image.
  62. /// </summary>
  63. /// <param name="userId">User Id.</param>
  64. /// <param name="imageType">(Unused) Image type.</param>
  65. /// <param name="index">(Unused) Image index.</param>
  66. /// <response code="204">Image updated.</response>
  67. /// <returns>A <see cref="NoContentResult"/>.</returns>
  68. [HttpPost("/Users/{userId}/Images/{imageType}")]
  69. [HttpPost("/Users/{userId}/Images/{imageType}/{index}")]
  70. public async Task<ActionResult> PostUserImage(
  71. [FromRoute] Guid userId,
  72. [FromRoute] ImageType imageType,
  73. [FromRoute] int? index)
  74. {
  75. // TODO AssertCanUpdateUser(_authContext, _userManager, id, true);
  76. var user = _userManager.GetUserById(userId);
  77. await using var memoryStream = await GetMemoryStream(Request.Body).ConfigureAwait(false);
  78. // Handle image/png; charset=utf-8
  79. var mimeType = Request.ContentType.Split(';').FirstOrDefault();
  80. var userDataPath = Path.Combine(_serverConfigurationManager.ApplicationPaths.UserConfigurationDirectoryPath, user.Username);
  81. user.ProfileImage = new Data.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + MimeTypes.ToExtension(mimeType)));
  82. await _providerManager
  83. .SaveImage(user, memoryStream, mimeType, user.ProfileImage.Path)
  84. .ConfigureAwait(false);
  85. await _userManager.UpdateUserAsync(user).ConfigureAwait(false);
  86. return NoContent();
  87. }
  88. /// <summary>
  89. /// Delete the user's image.
  90. /// </summary>
  91. /// <param name="userId">User Id.</param>
  92. /// <param name="imageType">(Unused) Image type.</param>
  93. /// <param name="index">(Unused) Image index.</param>
  94. /// <response code="204">Image deleted.</response>
  95. /// <returns>A <see cref="NoContentResult"/>.</returns>
  96. [HttpDelete("/Users/{userId}/Images/{itemType}")]
  97. [HttpDelete("/Users/{userId}/Images/{itemType}/{index}")]
  98. public ActionResult DeleteUserImage(
  99. [FromRoute] Guid userId,
  100. [FromRoute] ImageType imageType,
  101. [FromRoute] int? index)
  102. {
  103. // TODO AssertCanUpdateUser(_authContext, _userManager, userId, true);
  104. var user = _userManager.GetUserById(userId);
  105. try
  106. {
  107. System.IO.File.Delete(user.ProfileImage.Path);
  108. }
  109. catch (IOException e)
  110. {
  111. _logger.LogError(e, "Error deleting user profile image:");
  112. }
  113. _userManager.ClearProfileImage(user);
  114. return NoContent();
  115. }
  116. private static async Task<MemoryStream> GetMemoryStream(Stream inputStream)
  117. {
  118. using var reader = new StreamReader(inputStream);
  119. var text = await reader.ReadToEndAsync().ConfigureAwait(false);
  120. var bytes = Convert.FromBase64String(text);
  121. return new MemoryStream(bytes)
  122. {
  123. Position = 0
  124. };
  125. }
  126. }
  127. }