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 }; } } }