diff --git a/Jellyfin.Api/Controllers/ImageController.cs b/Jellyfin.Api/Controllers/ImageController.cs
new file mode 100644
index 000000000..6742bffc6
--- /dev/null
+++ b/Jellyfin.Api/Controllers/ImageController.cs
@@ -0,0 +1,139 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Drawing;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Net;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Net;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace Jellyfin.Api.Controllers
+{
+ ///
+ /// Image controller.
+ ///
+ public class ImageController : BaseJellyfinApiController
+ {
+ private readonly IUserManager _userManager;
+ private readonly ILibraryManager _libraryManager;
+ private readonly IProviderManager _providerManager;
+ private readonly IImageProcessor _imageProcessor;
+ private readonly IFileSystem _fileSystem;
+ private readonly IAuthorizationContext _authContext;
+ private readonly ILogger _logger;
+ private readonly IServerConfigurationManager _serverConfigurationManager;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Instance of the interface.
+ /// Instance of the interface.
+ /// Instance of the interface.
+ /// Instance of the interface.
+ /// Instance of the interface.
+ /// Instance of the interface.
+ /// Instance of the interface.
+ /// Instance of the interface.
+ public ImageController(
+ IUserManager userManager,
+ ILibraryManager libraryManager,
+ IProviderManager providerManager,
+ IImageProcessor imageProcessor,
+ IFileSystem fileSystem,
+ IAuthorizationContext authContext,
+ ILogger logger,
+ IServerConfigurationManager serverConfigurationManager)
+ {
+ _userManager = userManager;
+ _libraryManager = libraryManager;
+ _providerManager = providerManager;
+ _imageProcessor = imageProcessor;
+ _fileSystem = fileSystem;
+ _authContext = authContext;
+ _logger = logger;
+ _serverConfigurationManager = serverConfigurationManager;
+ }
+
+ ///
+ /// Sets the user image.
+ ///
+ /// User Id.
+ /// (Unused) Image type.
+ /// (Unused) Image index.
+ /// Image updated.
+ /// A .
+ [HttpPost("/Users/{userId}/Images/{imageType}")]
+ [HttpPost("/Users/{userId}/Images/{imageType}/{index}")]
+ public async Task PostUserImage(
+ [FromRoute] Guid userId,
+ [FromRoute] ImageType imageType,
+ [FromRoute] int? index)
+ {
+ // TODO AssertCanUpdateUser(_authContext, _userManager, id, true);
+
+ var user = _userManager.GetUserById(userId);
+ await using var memoryStream = await GetMemoryStream(Request.Body).ConfigureAwait(false);
+
+ // Handle image/png; charset=utf-8
+ var mimeType = Request.ContentType.Split(';').FirstOrDefault();
+ var userDataPath = Path.Combine(_serverConfigurationManager.ApplicationPaths.UserConfigurationDirectoryPath, user.Username);
+ user.ProfileImage = new Data.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + MimeTypes.ToExtension(mimeType)));
+
+ await _providerManager
+ .SaveImage(user, memoryStream, mimeType, user.ProfileImage.Path)
+ .ConfigureAwait(false);
+ await _userManager.UpdateUserAsync(user).ConfigureAwait(false);
+
+ return NoContent();
+ }
+
+ ///
+ /// Delete the user's image.
+ ///
+ /// User Id.
+ /// (Unused) Image type.
+ /// (Unused) Image index.
+ /// Image deleted.
+ /// A .
+ [HttpDelete("/Users/{userId}/Images/{itemType}")]
+ [HttpDelete("/Users/{userId}/Images/{itemType}/{index}")]
+ public ActionResult DeleteUserImage(
+ [FromRoute] Guid userId,
+ [FromRoute] ImageType imageType,
+ [FromRoute] int? index)
+ {
+ // TODO AssertCanUpdateUser(_authContext, _userManager, userId, true);
+
+ var user = _userManager.GetUserById(userId);
+ try
+ {
+ System.IO.File.Delete(user.ProfileImage.Path);
+ }
+ catch (IOException e)
+ {
+ _logger.LogError(e, "Error deleting user profile image:");
+ }
+
+ _userManager.ClearProfileImage(user);
+ return NoContent();
+ }
+
+ private static async Task GetMemoryStream(Stream inputStream)
+ {
+ using var reader = new StreamReader(inputStream);
+ var text = await reader.ReadToEndAsync().ConfigureAwait(false);
+
+ var bytes = Convert.FromBase64String(text);
+ return new MemoryStream(bytes)
+ {
+ Position = 0
+ };
+ }
+ }
+}
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index 0b8ddeacd..48c879bb7 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -163,44 +163,6 @@ namespace MediaBrowser.Api.Images
public string Id { get; set; }
}
- ///
- /// Class DeleteUserImage
- ///
- [Route("/Users/{Id}/Images/{Type}", "DELETE")]
- [Route("/Users/{Id}/Images/{Type}/{Index}", "DELETE")]
- [Authenticated]
- public class DeleteUserImage : DeleteImageRequest, IReturnVoid
- {
- ///
- /// Gets or sets the id.
- ///
- /// The id.
- [ApiMember(Name = "Id", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public Guid Id { get; set; }
- }
-
- ///
- /// Class PostUserImage
- ///
- [Route("/Users/{Id}/Images/{Type}", "POST")]
- [Route("/Users/{Id}/Images/{Type}/{Index}", "POST")]
- [Authenticated]
- public class PostUserImage : DeleteImageRequest, IRequiresRequestStream, IReturnVoid
- {
- ///
- /// Gets or sets the id.
- ///
- /// The id.
- [ApiMember(Name = "Id", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string Id { get; set; }
-
- ///
- /// The raw Http Request Input Stream
- ///
- /// The request stream.
- public Stream RequestStream { get; set; }
- }
-
///
/// Class PostItemImage
///
@@ -438,23 +400,6 @@ namespace MediaBrowser.Api.Images
return GetImage(request, item.Id, item, true);
}
- ///
- /// Posts the specified request.
- ///
- /// The request.
- public Task Post(PostUserImage request)
- {
- var id = Guid.Parse(GetPathValue(1));
-
- AssertCanUpdateUser(_authContext, _userManager, id, true);
-
- request.Type = Enum.Parse(GetPathValue(3).ToString(), true);
-
- var user = _userManager.GetUserById(id);
-
- return PostImage(user, request.RequestStream, Request.ContentType);
- }
-
///
/// Posts the specified request.
///
@@ -470,28 +415,6 @@ namespace MediaBrowser.Api.Images
return PostImage(item, request.RequestStream, request.Type, Request.ContentType);
}
- ///
- /// Deletes the specified request.
- ///
- /// The request.
- public void Delete(DeleteUserImage request)
- {
- var userId = request.Id;
- AssertCanUpdateUser(_authContext, _userManager, userId, true);
-
- var user = _userManager.GetUserById(userId);
- try
- {
- File.Delete(user.ProfileImage.Path);
- }
- catch (IOException e)
- {
- Logger.LogError(e, "Error deleting user profile image:");
- }
-
- _userManager.ClearProfileImage(user);
- }
-
///
/// Deletes the specified request.
///