Experimental changes
This commit is contained in:
@@ -1,11 +0,0 @@
|
||||
using Ardalis.Result;
|
||||
|
||||
namespace Musify.Application.Contracts.Infrastructure
|
||||
{
|
||||
public interface IAudioTranscoder
|
||||
{
|
||||
Task<Result> TranscodeToDashAsync(Stream audioStream, string destinationPath, CancellationToken cancellationToken);
|
||||
|
||||
Task<Result<bool>> IsValidAudioFileAsync(string filePath, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Musify.Application.Contracts.Infrastructure
|
||||
{
|
||||
public interface IAudioTranscoderService
|
||||
{
|
||||
Task<int> TranscodeToDashAsync(Stream audioStream, string destinationPath, CancellationToken cancellationToken);
|
||||
|
||||
Task<bool> IsValidAudioFileAsync(string filePath, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
using Ardalis.Result;
|
||||
using Musify.Application.Users.Responses;
|
||||
using Musify.Application.Users.Responses;
|
||||
|
||||
namespace Musify.Application.Contracts.Infrastructure
|
||||
{
|
||||
public interface IKeycloakUserService
|
||||
{
|
||||
Task<Result<KeycloakUserResponse>> GetUserByIdAsync(string keycloakId, CancellationToken cancellationToken);
|
||||
Task<KeycloakUserResponse> GetUserByIdAsync(string keycloakId, CancellationToken cancellationToken);
|
||||
|
||||
Task<IReadOnlyCollection<KeycloakUserResponse>> GetUsersAsync(
|
||||
CancellationToken cancellationToken,
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
using Ardalis.Result;
|
||||
|
||||
namespace Musify.Application.Contracts.Infrastructure
|
||||
{
|
||||
public interface IPictureHandler
|
||||
{
|
||||
Task<Result<Stream>> ResizePictureAsWebpAsync(Stream pictureStream, int width, int height, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Musify.Application.Contracts.Infrastructure
|
||||
{
|
||||
public interface IPictureService
|
||||
{
|
||||
Task<Stream> ResizePictureAsWebpAsync(Stream pictureStream, int width, int height, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using Ardalis.Result;
|
||||
|
||||
namespace Musify.Application.Contracts.Infrastructure
|
||||
{
|
||||
public interface IStorageHandler
|
||||
{
|
||||
Task<Result<Stream>> GetFileAsync(string bucket, string key, CancellationToken cancellationToken);
|
||||
|
||||
Task<string> GetUrlAsync(string bucket, string key, TimeSpan ExpirationTime, CancellationToken cancellationToken);
|
||||
|
||||
Task<Result<string>> UploadFileAsync(string filePath, string bucket, string key, CancellationToken cancellationToken);
|
||||
|
||||
Task<Result<string>> UploadFileAsync(Stream sourceStream, string contentType, string bucket, string key, CancellationToken cancellationToken);
|
||||
|
||||
Task<Result> TransferFilesAsync(string sourceDirectory, string bucket, string route, CancellationToken cancellationToken);
|
||||
|
||||
Task<Result> RemoveFileAsync(string bucket, string key, CancellationToken cancellationToken);
|
||||
|
||||
Task<Result> CopyFileAsync(string sourceBucket, string sourceKey, string destinationBucket, string destinationKey,
|
||||
CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
namespace Musify.Application.Contracts.Infrastructure
|
||||
{
|
||||
public interface IStorageService
|
||||
{
|
||||
Task<Stream> GetFileAsync(string bucket, string key, CancellationToken cancellationToken);
|
||||
|
||||
Task<string> GetUrlAsync(string bucket, string key, TimeSpan ExpirationTime, CancellationToken cancellationToken);
|
||||
|
||||
Task UploadFileAsync(string filePath, string bucket, string key, CancellationToken cancellationToken);
|
||||
|
||||
Task UploadFileAsync(Stream sourceStream, string contentType, string bucket, string key, CancellationToken cancellationToken);
|
||||
|
||||
Task TransferFilesAsync(string sourceDirectory, string bucket, string route, CancellationToken cancellationToken);
|
||||
|
||||
Task RemoveFileAsync(string bucket, string key, CancellationToken cancellationToken);
|
||||
|
||||
Task CopyFileAsync(string sourceBucket, string sourceKey, string destinationBucket, string destinationKey,
|
||||
CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ using Musify.Domain.Entities;
|
||||
|
||||
namespace Musify.Application.PlayLists.Handlers
|
||||
{
|
||||
public class CreatePlayListCommandHandler(IEventBus eventBus, IDatabase database, IStorageHandler storageHandler,
|
||||
public class CreatePlayListCommandHandler(IEventBus eventBus, IDatabase database, IStorageService storageHandler,
|
||||
ILogger<CreatePlayListCommandHandler> logger, ApplicationStorageConfiguration storageConfiguration, PlayListConfiguration playListConfiguration)
|
||||
: IRequestHandler<CreatePlayListCommand, Task<Result<PlayListResponse>> >
|
||||
{
|
||||
@@ -80,16 +80,16 @@ namespace Musify.Application.PlayLists.Handlers
|
||||
var pictureName = Guid.NewGuid() + picture.FileType;
|
||||
var pictureKey = Path.Combine(playListConfiguration.Routes.OriginalPicturesPath, pictureName);
|
||||
|
||||
var uploadResult = await storageHandler.UploadFileAsync(picture.FileStream, picture.ContentType, storageConfiguration.BucketName, pictureKey, cancellationToken);
|
||||
if (!uploadResult.IsSuccess)
|
||||
try
|
||||
{
|
||||
logger.LogError("Failed to upload picture for playlist {PlayListId} to storage: {ErrorMessage}",
|
||||
playList.Id, string.Join(", ", uploadResult.Errors));
|
||||
return uploadResult.ToErrorResult();
|
||||
await storageHandler.UploadFileAsync(picture.FileStream, picture.ContentType, storageConfiguration.BucketName, pictureKey, cancellationToken);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Result.Error($"An error occurred while uploading picture for playlist {playList.Id} to storage.");
|
||||
}
|
||||
|
||||
playList.OriginalPictureName = pictureName;
|
||||
|
||||
return Result.Success();
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ using Musify.Domain.Entities;
|
||||
|
||||
namespace Musify.Application.PlayLists.Handlers
|
||||
{
|
||||
public class UpdatePlayListCommandHandler(IEventBus eventBus, IDatabase database, IStorageHandler storageHandler,
|
||||
public class UpdatePlayListCommandHandler(IEventBus eventBus, IDatabase database, IStorageService storageHandler,
|
||||
ILogger<UpdatePlayListCommandHandler> logger, ApplicationStorageConfiguration storageConfiguration,
|
||||
PlayListConfiguration playListConfiguration)
|
||||
: IRequestHandler<UpdatePlayListCommand, Task<Result<PlayListResponse>> >
|
||||
@@ -80,19 +80,20 @@ namespace Musify.Application.PlayLists.Handlers
|
||||
|
||||
var pictureName = Guid.NewGuid() + newPicture.FileType;
|
||||
var pictureKey = Path.Combine(playListConfiguration.Routes.OriginalPicturesPath, pictureName);
|
||||
var uploadResult = await storageHandler.UploadFileAsync(
|
||||
newPicture.FileStream,
|
||||
newPicture.ContentType,
|
||||
storageConfiguration.BucketName,
|
||||
pictureKey,
|
||||
cancellationToken);
|
||||
|
||||
if (!uploadResult.IsSuccess)
|
||||
try
|
||||
{
|
||||
logger.LogError("Failed to upload picture for playlist {PlayListId} to storage: {ErrorMessage}",
|
||||
playList.Id, string.Join("; ", uploadResult.Errors));
|
||||
return Result.Error($"Failed to upload playlist {playList.Id} picture");
|
||||
await storageHandler.UploadFileAsync(
|
||||
newPicture.FileStream,
|
||||
newPicture.ContentType,
|
||||
storageConfiguration.BucketName,
|
||||
pictureKey,
|
||||
cancellationToken);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Result.Error("Failed to upload picture to storage");
|
||||
}
|
||||
|
||||
playList.OriginalPictureName = pictureName;
|
||||
return Result.Success(pictureKey);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ using Musify.Domain.Entities;
|
||||
|
||||
namespace Musify.Application.Tracks.Handler
|
||||
{
|
||||
public class CreateTrackCommandHandler(IDatabase database, IEventBus eventBus, IStorageHandler storageHandler,
|
||||
public class CreateTrackCommandHandler(IDatabase database, IEventBus eventBus, IStorageService storageHandler,
|
||||
ILogger<CreateTrackCommandHandler> logger, ApplicationStorageConfiguration storageConfiguration, TrackConfiguration trackConfiguration)
|
||||
: IRequestHandler<CreateTrackCommand, Task<Result<TrackResponse> >>
|
||||
{
|
||||
@@ -49,33 +49,34 @@ namespace Musify.Application.Tracks.Handler
|
||||
string audioKey,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var pictureUpload = await storageHandler.UploadFileAsync(
|
||||
request.Picture.FileStream,
|
||||
request.Picture.ContentType,
|
||||
storageConfiguration.BucketName,
|
||||
pictureKey,
|
||||
cancellationToken);
|
||||
|
||||
if (!pictureUpload.IsSuccess)
|
||||
try
|
||||
{
|
||||
await storageHandler.UploadFileAsync(
|
||||
request.Picture.FileStream,
|
||||
request.Picture.ContentType,
|
||||
storageConfiguration.BucketName,
|
||||
pictureKey,
|
||||
cancellationToken);
|
||||
}
|
||||
catch
|
||||
{
|
||||
var errors = string.Join(", ", pictureUpload.Errors);
|
||||
return Result.Error($"Failed to upload picture for {request.Title}");
|
||||
}
|
||||
|
||||
var audioUpload = await storageHandler.UploadFileAsync(
|
||||
request.Audio.FileStream,
|
||||
request.Audio.ContentType,
|
||||
storageConfiguration.BucketName,
|
||||
audioKey,
|
||||
cancellationToken);
|
||||
|
||||
if (!audioUpload.IsSuccess)
|
||||
try
|
||||
{
|
||||
await storageHandler.UploadFileAsync(
|
||||
request.Audio.FileStream,
|
||||
request.Audio.ContentType,
|
||||
storageConfiguration.BucketName,
|
||||
audioKey,
|
||||
cancellationToken);
|
||||
}
|
||||
catch
|
||||
{
|
||||
await RollbackFilesAsync(pictureKey, audioKey, cancellationToken);
|
||||
var errors = string.Join(", ", audioUpload.Errors);
|
||||
return Result.Error($"Failed to upload audio for {request.Title}");
|
||||
}
|
||||
|
||||
return Result.Success();
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ using Musify.Domain.Entities;
|
||||
|
||||
namespace Musify.Application.Tracks.Handler
|
||||
{
|
||||
public class DeleteTrackCommandHandler(IDatabase database, IStorageHandler storageHandler, ILogger<DeleteTrackCommandHandler> logger,
|
||||
public class DeleteTrackCommandHandler(IDatabase database, IStorageService storageHandler, ILogger<DeleteTrackCommandHandler> logger,
|
||||
TrackConfiguration trackConfiguration, ApplicationStorageConfiguration storageConfiguration)
|
||||
: IRequestHandler<DeleteTrackCommand, Task<Result>>
|
||||
{
|
||||
|
||||
@@ -20,10 +20,13 @@ namespace Musify.Application.Users.Handlers
|
||||
return Result<UserResponse>.Conflict($"User {request.Id} already exists");
|
||||
}
|
||||
|
||||
var keycloakUser = await keycloakUserClient.GetUserByIdAsync(request.Id.ToString(), cancellationToken);
|
||||
if (!keycloakUser.IsSuccess)
|
||||
KeycloakUserResponse keycloakUser;
|
||||
try
|
||||
{
|
||||
keycloakUser = await keycloakUserClient.GetUserByIdAsync(request.Id.ToString(), cancellationToken);
|
||||
}
|
||||
catch
|
||||
{
|
||||
logger.LogWarning("Keycloak user {UserId} not found", request.Id);
|
||||
return Result.NotFound("Keycloak user not found");
|
||||
}
|
||||
|
||||
@@ -34,9 +37,9 @@ namespace Musify.Application.Users.Handlers
|
||||
logger.LogInformation("Created user {UserId}", newUser.Id);
|
||||
return Result.Created(new UserResponse(
|
||||
newUser.Id.ToString(),
|
||||
keycloakUser.Value.Name,
|
||||
keycloakUser.Value.FirstName,
|
||||
keycloakUser.Value.SecondName,
|
||||
keycloakUser.Name,
|
||||
keycloakUser.FirstName,
|
||||
keycloakUser.SecondName,
|
||||
newUser.CreatedAt,
|
||||
newUser.UpdatedAt));
|
||||
}
|
||||
|
||||
@@ -18,15 +18,21 @@ namespace Musify.Application.Users.Handlers
|
||||
if (user is null)
|
||||
return Result.NotFound("User not found");
|
||||
|
||||
var keycloakUser = await keycloakUserClient.GetUserByIdAsync(user.Id.ToString(), cancellationToken);
|
||||
if (!keycloakUser.IsSuccess)
|
||||
return Result.NotFound("Keycloak user not found");
|
||||
KeycloakUserResponse keycloakUser;
|
||||
try
|
||||
{
|
||||
keycloakUser = await keycloakUserClient.GetUserByIdAsync(user.Id.ToString(), cancellationToken);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Result.Error("Keycloak user not found");
|
||||
}
|
||||
|
||||
return Result.Success(new UserResponse(
|
||||
user.Id.ToString(),
|
||||
keycloakUser.Value.Name,
|
||||
keycloakUser.Value.FirstName,
|
||||
keycloakUser.Value.SecondName,
|
||||
keycloakUser.Name,
|
||||
keycloakUser.FirstName,
|
||||
keycloakUser.SecondName,
|
||||
user.CreatedAt,
|
||||
user.UpdatedAt));
|
||||
}
|
||||
|
||||
@@ -18,15 +18,21 @@ namespace Musify.Application.Users.Handlers
|
||||
if (user is null)
|
||||
return Result.NotFound("User not found");
|
||||
|
||||
var keycloakUser = await keycloakUserClient.GetUserByIdAsync(user.Id.ToString(), cancellationToken);
|
||||
if (!keycloakUser.IsSuccess)
|
||||
KeycloakUserResponse keycloakUser;
|
||||
try
|
||||
{
|
||||
keycloakUser = await keycloakUserClient.GetUserByIdAsync(user.Id.ToString(), cancellationToken);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Result.NotFound("Keycloak user not found");
|
||||
}
|
||||
|
||||
return Result.Success(new UserResponse(
|
||||
user.Id.ToString(),
|
||||
keycloakUser.Value.Name,
|
||||
keycloakUser.Value.FirstName,
|
||||
keycloakUser.Value.SecondName,
|
||||
keycloakUser.Name,
|
||||
keycloakUser.FirstName,
|
||||
keycloakUser.SecondName,
|
||||
user.CreatedAt,
|
||||
user.UpdatedAt));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user