diff --git a/Application/PlayLists/Handlers/CreatePlayListCommandHandler.cs b/Application/PlayLists/Handlers/CreatePlayListCommandHandler.cs index c26a888..f4f8ff4 100644 --- a/Application/PlayLists/Handlers/CreatePlayListCommandHandler.cs +++ b/Application/PlayLists/Handlers/CreatePlayListCommandHandler.cs @@ -3,6 +3,7 @@ using DispatchR.Abstractions.Send; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Musify.Application.Configuration; +using Musify.Application.Contracts.Application; using Musify.Application.Contracts.Infrastructure; using Musify.Application.Events; using Musify.Application.PlayLists.Commands; @@ -36,63 +37,12 @@ namespace Musify.Application.PlayLists.Handlers LargePictureKeyName = playListConfiguration.Routes.PresetLargePicture, }; - if (request.Picture is not null) - { - var imageId = Guid.NewGuid(); - var pictureName = $"{imageId}{request.Picture.FileType}"; - var originalImageStorageKey = Path.Join(playListConfiguration.Routes.OriginalPictures, pictureName); + var setPictureResult = request.Picture is null + ? Result.Success() + : await SetPicture(playList, request.Picture, cancellationToken); - var uploadResult = await storageHandler.UploadFileAsync( - request.Picture.FileStream, - request.Picture.ContentType, - storageConfiguration.BucketName, - originalImageStorageKey, - cancellationToken); - - if (!uploadResult.IsSuccess) - { - logger.LogError("Failed to upload picture for PlayList with Id={PlayListId} to storage. Storage handler returned error: {ErrorMessage}", - playList.Id, string.Join("; ", uploadResult.Errors)); - return Result.Error($"Failed to upload picture for PlayList with Id {playList.Id} to storage."); - } - logger.LogInformation("Playlist image uploaded successfully for PlayList with Id={PlayListId}.", playList.Id); - - var smallPictureKeyName = Path.Combine( - playListConfiguration.Routes.SmallPictures, - $"{playList.Id}.{pictureHandler.FileExtension}"); - var mediumPictureKeyName = Path.Combine( - playListConfiguration.Routes.MediumPictures, - $"{playList.Id}.{pictureHandler.FileExtension}"); - var largePictureKeyName = Path.Combine( - playListConfiguration.Routes.LargePictures, - $"{playList.Id}.{pictureHandler.FileExtension}"); - - try - { - await eventBus.PublishAsync(new UpdatePlayListPictureEvent( - playList.Id, - storageConfiguration.BucketName, - originalImageStorageKey, - smallPictureKeyName, - playListConfiguration.PicturesSizes.SmallPictureWidth, - playListConfiguration.PicturesSizes.SmallPictureHeight, - mediumPictureKeyName, - playListConfiguration.PicturesSizes.MediumPictureWidth, - playListConfiguration.PicturesSizes.MediumPictureHeight, - largePictureKeyName, - playListConfiguration.PicturesSizes.LargePictureWidth, - playListConfiguration.PicturesSizes.LargePictureHeight), cancellationToken); - } - catch (Exception exception) - { - logger.LogError(exception, "Failed to publish resize picture event for PlayList with id={PlayListId}.", playList.Id); - return Result.Error($"Failed to publish resize picture event for PlayList with id {playList.Id}."); - } - } - else - { - logger.LogInformation("No picture provided for PlayList with Id={PlayListId}. Using Preset pictures.", playList.Id); - } + if (!setPictureResult.IsSuccess) + return setPictureResult; await database.PlayLists.AddAsync(playList, cancellationToken); await database.SaveChangesAsync(cancellationToken); @@ -100,5 +50,72 @@ namespace Musify.Application.PlayLists.Handlers logger.LogInformation("PlayList with id={PlayListId} created successfully for user with id={UserId}.", playList.Id, request.UserId); return Result.Created(PlayListResponse.FromEntity(playList)); } + + async Task SetPicture(PlayList playList, IFileData picture, CancellationToken cancellationToken) + { + var imageId = Guid.NewGuid(); + var pictureName = $"{imageId}{picture.FileType}"; + var originalImageStorageKey = Path.Join(playListConfiguration.Routes.OriginalPictures, pictureName); + + var uploadResult = await UploadFile(picture, originalImageStorageKey, cancellationToken); + + if (!uploadResult.IsSuccess) + { + logger.LogError("Failed to upload picture for PlayList with Id={PlayListId} to storage. Storage handler returned error: {ErrorMessage}", + playList.Id, string.Join("; ", uploadResult.Errors)); + return Result.Error($"Failed to upload picture for PlayList with Id {playList.Id} to storage."); + } + logger.LogInformation("Playlist image uploaded successfully for PlayList with Id={PlayListId}.", playList.Id); + + try + { + await PublishUpdateEvent(originalImageStorageKey, playList, cancellationToken); + } + catch (Exception exception) + { + logger.LogError(exception, "Failed to publish resize picture event for PlayList with id={PlayListId}.", playList.Id); + return Result.Error($"Failed to publish resize picture event for PlayList with id {playList.Id}."); + } + return Result.Success(); + } + + async Task> UploadFile(IFileData fileData, string storageKeyName, CancellationToken cancellationToken) + { + var uploadFileResult = await storageHandler.UploadFileAsync( + fileData.FileStream, + fileData.ContentType, + storageConfiguration.BucketName, + storageKeyName, + cancellationToken); + + return uploadFileResult; + } + + async Task PublishUpdateEvent(string originalPictureKeyName, PlayList playList, CancellationToken cancellationToken) + { + var smallPictureKeyName = Path.Combine( + playListConfiguration.Routes.SmallPictures, + $"{playList.Id}.{pictureHandler.FileExtension}"); + var mediumPictureKeyName = Path.Combine( + playListConfiguration.Routes.MediumPictures, + $"{playList.Id}.{pictureHandler.FileExtension}"); + var largePictureKeyName = Path.Combine( + playListConfiguration.Routes.LargePictures, + $"{playList.Id}.{pictureHandler.FileExtension}"); + + await eventBus.PublishAsync(new UpdatePlayListPictureEvent( + playList.Id, + storageConfiguration.BucketName, + originalPictureKeyName, + smallPictureKeyName, + playListConfiguration.PicturesSizes.SmallPictureWidth, + playListConfiguration.PicturesSizes.SmallPictureHeight, + mediumPictureKeyName, + playListConfiguration.PicturesSizes.MediumPictureWidth, + playListConfiguration.PicturesSizes.MediumPictureHeight, + largePictureKeyName, + playListConfiguration.PicturesSizes.LargePictureWidth, + playListConfiguration.PicturesSizes.LargePictureHeight), cancellationToken); + } } } \ No newline at end of file diff --git a/Application/PlayLists/Handlers/DeletePlayListCommandHandler.cs b/Application/PlayLists/Handlers/DeletePlayListCommandHandler.cs index 10c1a3c..bcd8486 100644 --- a/Application/PlayLists/Handlers/DeletePlayListCommandHandler.cs +++ b/Application/PlayLists/Handlers/DeletePlayListCommandHandler.cs @@ -47,14 +47,13 @@ namespace Musify.Application.PlayLists.Handlers { var publishResult = await TryPublishRemoveFileEventAsync(playList.Id, key, cancellationToken); - if (!publishResult.IsSuccess) - { + if (!publishResult.IsSuccess && !publishResult.IsNotFound()) return publishResult; - } } database.PlayLists.Remove(playList); await database.SaveChangesAsync(cancellationToken); + return Result.NoContent(); } diff --git a/Application/PlayLists/Handlers/UpdatePlayListCommandHandler.cs b/Application/PlayLists/Handlers/UpdatePlayListCommandHandler.cs index ffd1a0d..b85f857 100644 --- a/Application/PlayLists/Handlers/UpdatePlayListCommandHandler.cs +++ b/Application/PlayLists/Handlers/UpdatePlayListCommandHandler.cs @@ -3,10 +3,12 @@ using DispatchR.Abstractions.Send; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Musify.Application.Configuration; +using Musify.Application.Contracts.Application; using Musify.Application.Contracts.Infrastructure; using Musify.Application.Events; using Musify.Application.PlayLists.Commands; using Musify.Application.PlayLists.Responses; +using Musify.Domain.Entities; namespace Musify.Application.PlayLists.Handlers { @@ -44,64 +46,29 @@ namespace Musify.Application.PlayLists.Handlers { database.PlayLists.Update(playList); await database.SaveChangesAsync(cancellationToken); + logger.LogInformation("Updated PlayList with id={PlayListId} without picture changes.", playList.Id); return Result.Success(PlayListResponse.FromEntity(playList)); } if (playList.SmallPictureKeyName != playListConfiguration.Routes.PresetSmallPicture) { - try - { - await eventBus.PublishAsync(new RemoveFileEvent( - storageConfiguration.BucketName, - playList.SmallPictureKeyName), cancellationToken); - } - catch (Exception exception) - { - logger.LogError(exception, "Failed to publish remove file event for small picture of PlayList id={PlayListId}.", playList.Id); - return Result.Error($"Failed to publish remove file event for PlayList with id {playList.Id}."); - } + await PublishRemoveFileEvent(playList.SmallPictureKeyName, cancellationToken); } if (playList.MediumPictureKeyName != playListConfiguration.Routes.PresetMediumPicture) { - try - { - await eventBus.PublishAsync(new RemoveFileEvent( - storageConfiguration.BucketName, - playList.MediumPictureKeyName), cancellationToken); - } - catch (Exception exception) - { - logger.LogError(exception, "Failed to publish remove file event for medium picture of PlayList id={PlayListId}.", playList.Id); - return Result.Error($"Failed to publish remove file event for PlayList with id {playList.Id}."); - } + await PublishRemoveFileEvent(playList.MediumPictureKeyName, cancellationToken); } if (playList.LargePictureKeyName != playListConfiguration.Routes.PresetLargePicture) { - try - { - await eventBus.PublishAsync(new RemoveFileEvent( - storageConfiguration.BucketName, - playList.LargePictureKeyName), cancellationToken); - } - catch (Exception exception) - { - logger.LogError(exception, "Failed to publish remove file event for large picture of PlayList id={PlayListId}.", playList.Id); - return Result.Error($"Failed to publish remove file event for PlayList with id {playList.Id}."); - } + await PublishRemoveFileEvent(playList.LargePictureKeyName, cancellationToken); } var newImageId = Guid.NewGuid(); var pictureName = $"{newImageId}{request.NewPicture.FileType}"; var newImageStorageKey = Path.Join(playListConfiguration.Routes.OriginalPictures, pictureName); - var uploadResult = await storageHandler.UploadFileAsync( - request.NewPicture.FileStream, - request.NewPicture.ContentType, - storageConfiguration.BucketName, - newImageStorageKey, - cancellationToken); - + var uploadResult = await UploadFile(request.NewPicture, newImageStorageKey, cancellationToken); if (!uploadResult.IsSuccess) { logger.LogError("Failed to upload picture for PlayList with Id={PlayListId} to storage. Storage handler returned error: {ErrorMessage}", @@ -109,6 +76,54 @@ namespace Musify.Application.PlayLists.Handlers return Result.Error($"Failed to upload picture for PlayList with Id {playList.Id} to storage."); } + try + { + await PublishUpdateEvent(newImageStorageKey, playList, cancellationToken); + } + catch (Exception exception) + { + logger.LogError(exception, "Failed to publish update picture event for PlayList with id {PlayListId}.", playList.Id); + return Result.Error($"Failed to publish update picture event for PlayList with id {playList.Id}."); + } + + database.PlayLists.Update(playList); + await database.SaveChangesAsync(cancellationToken); + + logger.LogInformation("Updated PlayList with id={PlayListId} and picture key {PictureKeyName}.", playList.Id, newImageStorageKey); + return Result.Success(PlayListResponse.FromEntity(playList)); + } + + async Task PublishRemoveFileEvent(string keyName, CancellationToken cancellationToken) + { + try + { + await eventBus.PublishAsync(new RemoveFileEvent( + storageConfiguration.BucketName, + keyName), cancellationToken); + + return Result.NoContent(); + } + catch (Exception exception) + { + logger.LogError(exception, "Failed to publish remove file event for key {KeyName}.", keyName); + return Result.Error($"Failed to publish remove file event for key {keyName}."); + } + } + + async Task> UploadFile(IFileData picture, string pictureKeyName, CancellationToken cancellationToken) + { + var uploadFileResult = await storageHandler.UploadFileAsync( + picture.FileStream, + picture.ContentType, + storageConfiguration.BucketName, + pictureKeyName, + cancellationToken); + + return uploadFileResult; + } + + async Task PublishUpdateEvent(string originalPictureKeyName, PlayList playList, CancellationToken cancellationToken) + { var smallPictureKeyName = Path.Combine( playListConfiguration.Routes.SmallPictures, $"{playList.Id}.{pictureHandler.FileExtension}"); @@ -119,33 +134,19 @@ namespace Musify.Application.PlayLists.Handlers playListConfiguration.Routes.LargePictures, $"{playList.Id}.{pictureHandler.FileExtension}"); - try - { - await eventBus.PublishAsync(new UpdatePlayListPictureEvent( - playList.Id, - storageConfiguration.BucketName, - newImageStorageKey, - smallPictureKeyName, - playListConfiguration.PicturesSizes.SmallPictureWidth, - playListConfiguration.PicturesSizes.SmallPictureHeight, - mediumPictureKeyName, - playListConfiguration.PicturesSizes.MediumPictureWidth, - playListConfiguration.PicturesSizes.MediumPictureHeight, - largePictureKeyName, - playListConfiguration.PicturesSizes.LargePictureWidth, - playListConfiguration.PicturesSizes.LargePictureHeight), cancellationToken); - } - catch (Exception exception) - { - logger.LogError(exception, "Failed to publish resize picture event for PlayList id={PlayListId}.", playList.Id); - return Result.Error($"Failed to publish resize picture event for PlayList with id {playList.Id}."); - } - - database.PlayLists.Update(playList); - await database.SaveChangesAsync(cancellationToken); - - logger.LogInformation("Updated PlayList with id={PlayListId} and picture key {PictureKeyName}.", playList.Id, newImageStorageKey); - return Result.Success(PlayListResponse.FromEntity(playList)); + await eventBus.PublishAsync(new UpdatePlayListPictureEvent( + playList.Id, + storageConfiguration.BucketName, + originalPictureKeyName, + smallPictureKeyName, + playListConfiguration.PicturesSizes.SmallPictureWidth, + playListConfiguration.PicturesSizes.SmallPictureHeight, + mediumPictureKeyName, + playListConfiguration.PicturesSizes.MediumPictureWidth, + playListConfiguration.PicturesSizes.MediumPictureHeight, + largePictureKeyName, + playListConfiguration.PicturesSizes.LargePictureWidth, + playListConfiguration.PicturesSizes.LargePictureHeight), cancellationToken); } } } \ No newline at end of file diff --git a/Application/Tracks/Handler/CreateTrackCommandHandler.cs b/Application/Tracks/Handler/CreateTrackCommandHandler.cs index a161797..dd0035e 100644 --- a/Application/Tracks/Handler/CreateTrackCommandHandler.cs +++ b/Application/Tracks/Handler/CreateTrackCommandHandler.cs @@ -82,7 +82,7 @@ namespace Musify.Application.Tracks.Handler trackConfiguration.Routes.LargePictures, $"{track.Id}.{pictureHandler.FileExtension}"); - await eventBus.PublishAsync(new UpdatePlayListPictureEvent( + await eventBus.PublishAsync(new UpdateTrackPictureEvent( track.Id, storageConfiguration.BucketName, originalPictureKeyName,