Add editorconfig and analyzers, format backend code
This commit is contained in:
@@ -0,0 +1,65 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.{csproj,props,targets,slnx,xml}]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.json]
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
[**/Migrations/**.cs]
|
||||||
|
generated_code = true
|
||||||
|
|
||||||
|
[*.cs]
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
csharp_style_namespace_declarations = file_scoped:warning
|
||||||
|
csharp_using_directive_placement = outside_namespace:warning
|
||||||
|
dotnet_sort_system_directives_first = true
|
||||||
|
dotnet_separate_import_directive_groups = false
|
||||||
|
dotnet_diagnostic.IDE0005.severity = warning
|
||||||
|
|
||||||
|
dotnet_style_require_accessibility_modifiers = always:warning
|
||||||
|
csharp_style_var_for_built_in_types = true:suggestion
|
||||||
|
csharp_style_var_when_type_is_apparent = true:suggestion
|
||||||
|
csharp_style_var_elsewhere = true:suggestion
|
||||||
|
csharp_prefer_braces = when_multiline:warning
|
||||||
|
csharp_style_prefer_primary_constructors = true:suggestion
|
||||||
|
csharp_style_expression_bodied_methods = when_on_single_line:suggestion
|
||||||
|
dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion
|
||||||
|
|
||||||
|
dotnet_naming_rule.private_fields.symbols = private_fields
|
||||||
|
dotnet_naming_rule.private_fields.style = camel_case
|
||||||
|
dotnet_naming_rule.private_fields.severity = warning
|
||||||
|
dotnet_naming_symbols.private_fields.applicable_kinds = field
|
||||||
|
dotnet_naming_symbols.private_fields.applicable_accessibilities = private
|
||||||
|
dotnet_naming_symbols.private_fields.required_modifiers =
|
||||||
|
dotnet_naming_style.camel_case.capitalization = camel_case
|
||||||
|
|
||||||
|
dotnet_naming_rule.private_constants.symbols = private_constants
|
||||||
|
dotnet_naming_rule.private_constants.style = pascal_case
|
||||||
|
dotnet_naming_rule.private_constants.severity = warning
|
||||||
|
dotnet_naming_symbols.private_constants.applicable_kinds = field
|
||||||
|
dotnet_naming_symbols.private_constants.required_modifiers = const
|
||||||
|
dotnet_naming_style.pascal_case.capitalization = pascal_case
|
||||||
|
|
||||||
|
# Analyzer rules that would need behaviour or API changes; downgraded in P0, revisit in P15.
|
||||||
|
dotnet_diagnostic.CA1848.severity = suggestion
|
||||||
|
dotnet_diagnostic.CA1873.severity = suggestion
|
||||||
|
dotnet_diagnostic.CA1305.severity = suggestion
|
||||||
|
dotnet_diagnostic.CA1707.severity = suggestion
|
||||||
|
dotnet_diagnostic.CA1859.severity = suggestion
|
||||||
|
dotnet_diagnostic.CA1716.severity = suggestion
|
||||||
|
dotnet_diagnostic.CA1000.severity = suggestion
|
||||||
|
dotnet_diagnostic.CA1725.severity = suggestion
|
||||||
|
dotnet_diagnostic.CA1816.severity = suggestion
|
||||||
|
dotnet_diagnostic.CA1822.severity = suggestion
|
||||||
|
dotnet_diagnostic.CA1852.severity = suggestion
|
||||||
|
dotnet_diagnostic.CA1068.severity = suggestion
|
||||||
|
dotnet_diagnostic.CA1711.severity = suggestion
|
||||||
|
dotnet_diagnostic.CA1861.severity = suggestion
|
||||||
@@ -5,16 +5,16 @@ using Microsoft.Extensions.Logging;
|
|||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
using Musify.Domain.Entities;
|
using Musify.Domain.Entities;
|
||||||
|
|
||||||
namespace Musify.Application.Albums
|
namespace Musify.Application.Albums;
|
||||||
{
|
|
||||||
public record AddTrackToAlbumCommand(long UserId, Guid AlbumId, Guid TrackId)
|
public record AddTrackToAlbumCommand(long UserId, Guid AlbumId, Guid TrackId)
|
||||||
: ICommand<ErrorOr<Success>>;
|
: ICommand<ErrorOr<Success>>;
|
||||||
|
|
||||||
public class AddTrackToAlbumCommandHandler(
|
public class AddTrackToAlbumCommandHandler(
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
ILogger<AddTrackToAlbumCommandHandler> logger)
|
ILogger<AddTrackToAlbumCommandHandler> logger)
|
||||||
: ICommandHandler<AddTrackToAlbumCommand, ErrorOr<Success>>
|
: ICommandHandler<AddTrackToAlbumCommand, ErrorOr<Success>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<Success>> Handle(AddTrackToAlbumCommand request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<Success>> Handle(AddTrackToAlbumCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var album = await database.Albums
|
var album = await database.Albums
|
||||||
@@ -78,5 +78,4 @@ namespace Musify.Application.Albums
|
|||||||
|
|
||||||
return new Success();
|
return new Success();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,18 +2,18 @@ using ErrorOr;
|
|||||||
using Mediator;
|
using Mediator;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Musify.Application.Configuration;
|
|
||||||
using Musify.Application.Shared;
|
|
||||||
using Musify.Application.Events;
|
|
||||||
using Musify.Application.Albums.Responses;
|
using Musify.Application.Albums.Responses;
|
||||||
|
using Musify.Application.Configuration;
|
||||||
|
using Musify.Application.Contracts;
|
||||||
|
using Musify.Application.Events;
|
||||||
using Musify.Application.Services;
|
using Musify.Application.Services;
|
||||||
|
using Musify.Application.Shared;
|
||||||
using Musify.Domain.Entities;
|
using Musify.Domain.Entities;
|
||||||
using Musify.Domain.ValueObjects;
|
using Musify.Domain.ValueObjects;
|
||||||
using Musify.Application.Contracts;
|
|
||||||
|
|
||||||
namespace Musify.Application.Albums
|
namespace Musify.Application.Albums;
|
||||||
{
|
|
||||||
public record CreateAlbumCommand(
|
public record CreateAlbumCommand(
|
||||||
long UserId,
|
long UserId,
|
||||||
string Title,
|
string Title,
|
||||||
string? Description,
|
string? Description,
|
||||||
@@ -21,7 +21,7 @@ namespace Musify.Application.Albums
|
|||||||
Guid PictureIntentId)
|
Guid PictureIntentId)
|
||||||
: ICommand<ErrorOr<AlbumApplicationResponse>>;
|
: ICommand<ErrorOr<AlbumApplicationResponse>>;
|
||||||
|
|
||||||
public class CreateAlbumCommandHandler(
|
public class CreateAlbumCommandHandler(
|
||||||
IEventBus eventBus,
|
IEventBus eventBus,
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
UploadIntentValidator uploadIntentValidator,
|
UploadIntentValidator uploadIntentValidator,
|
||||||
@@ -30,7 +30,7 @@ namespace Musify.Application.Albums
|
|||||||
AlbumConfiguration albumConfiguration,
|
AlbumConfiguration albumConfiguration,
|
||||||
UploadIntentConfiguration uploadIntentConfiguration)
|
UploadIntentConfiguration uploadIntentConfiguration)
|
||||||
: ICommandHandler<CreateAlbumCommand, ErrorOr<AlbumApplicationResponse>>
|
: ICommandHandler<CreateAlbumCommand, ErrorOr<AlbumApplicationResponse>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<AlbumApplicationResponse>> Handle(CreateAlbumCommand request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<AlbumApplicationResponse>> Handle(CreateAlbumCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var userExists = await database.Users
|
var userExists = await database.Users
|
||||||
@@ -124,5 +124,4 @@ namespace Musify.Application.Albums
|
|||||||
return Error.Failure(description: $"Failed to publish create album event for album {albumId}");
|
return Error.Failure(description: $"Failed to publish create album event for album {albumId}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,16 +4,16 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
|
|
||||||
namespace Musify.Application.Albums
|
namespace Musify.Application.Albums;
|
||||||
{
|
|
||||||
public record DeleteAlbumCommand(long UserId, Guid AlbumId)
|
public record DeleteAlbumCommand(long UserId, Guid AlbumId)
|
||||||
: ICommand<ErrorOr<Success>>;
|
: ICommand<ErrorOr<Success>>;
|
||||||
|
|
||||||
public class DeleteAlbumCommandHandler(
|
public class DeleteAlbumCommandHandler(
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
ILogger<DeleteAlbumCommandHandler> logger)
|
ILogger<DeleteAlbumCommandHandler> logger)
|
||||||
: ICommandHandler<DeleteAlbumCommand, ErrorOr<Success>>
|
: ICommandHandler<DeleteAlbumCommand, ErrorOr<Success>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<Success>> Handle(DeleteAlbumCommand request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<Success>> Handle(DeleteAlbumCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var album = await database.Albums
|
var album = await database.Albums
|
||||||
@@ -46,5 +46,4 @@ namespace Musify.Application.Albums
|
|||||||
|
|
||||||
return new Success();
|
return new Success();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Musify.Application.Albums.Responses;
|
using Musify.Application.Albums.Responses;
|
||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
|
|
||||||
namespace Musify.Application.Albums
|
namespace Musify.Application.Albums;
|
||||||
{
|
|
||||||
public record GetAlbumByIdQuery(Guid Id)
|
public record GetAlbumByIdQuery(Guid Id)
|
||||||
: IQuery<ErrorOr<AlbumApplicationResponse>>;
|
: IQuery<ErrorOr<AlbumApplicationResponse>>;
|
||||||
|
|
||||||
public class GetAlbumByIdQueryHandler(IDatabase database)
|
public class GetAlbumByIdQueryHandler(IDatabase database)
|
||||||
: IQueryHandler<GetAlbumByIdQuery, ErrorOr<AlbumApplicationResponse>>
|
: IQueryHandler<GetAlbumByIdQuery, ErrorOr<AlbumApplicationResponse>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<AlbumApplicationResponse>> Handle(GetAlbumByIdQuery request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<AlbumApplicationResponse>> Handle(GetAlbumByIdQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var album = await database.Albums
|
var album = await database.Albums
|
||||||
@@ -34,5 +34,4 @@ namespace Musify.Application.Albums
|
|||||||
|
|
||||||
return AlbumApplicationResponse.FromEntity(album.Album, album.TrackCount, album.CoverTrackIds);
|
return AlbumApplicationResponse.FromEntity(album.Album, album.TrackCount, album.CoverTrackIds);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,19 +5,19 @@ using MimeMapping;
|
|||||||
using Musify.Application.Configuration;
|
using Musify.Application.Configuration;
|
||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
|
|
||||||
namespace Musify.Application.Albums
|
namespace Musify.Application.Albums;
|
||||||
{
|
|
||||||
public record GetAlbumCoverQuery(Guid AlbumId, string Size)
|
public record GetAlbumCoverQuery(Guid AlbumId, string Size)
|
||||||
: IQuery<ErrorOr<AlbumCoverLocation>>;
|
: IQuery<ErrorOr<AlbumCoverLocation>>;
|
||||||
|
|
||||||
public record AlbumCoverLocation(string Bucket, string Key, string ContentType);
|
public record AlbumCoverLocation(string Bucket, string Key, string ContentType);
|
||||||
|
|
||||||
public class GetAlbumCoverQueryHandler(
|
public class GetAlbumCoverQueryHandler(
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
ApplicationStorageConfiguration storageConfiguration,
|
ApplicationStorageConfiguration storageConfiguration,
|
||||||
AlbumConfiguration albumConfiguration)
|
AlbumConfiguration albumConfiguration)
|
||||||
: IQueryHandler<GetAlbumCoverQuery, ErrorOr<AlbumCoverLocation>>
|
: IQueryHandler<GetAlbumCoverQuery, ErrorOr<AlbumCoverLocation>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<AlbumCoverLocation>> Handle(GetAlbumCoverQuery request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<AlbumCoverLocation>> Handle(GetAlbumCoverQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var pictures = await database.Albums.AsNoTracking()
|
var pictures = await database.Albums.AsNoTracking()
|
||||||
@@ -45,5 +45,4 @@ namespace Musify.Application.Albums
|
|||||||
|
|
||||||
private static string? BuildKey(Func<string, string> builder, string? name)
|
private static string? BuildKey(Func<string, string> builder, string? name)
|
||||||
=> string.IsNullOrEmpty(name) ? null : builder(name);
|
=> string.IsNullOrEmpty(name) ? null : builder(name);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,17 +7,17 @@ using Musify.Application.Tracks.Responses;
|
|||||||
using X.PagedList;
|
using X.PagedList;
|
||||||
using X.PagedList.EF;
|
using X.PagedList.EF;
|
||||||
|
|
||||||
namespace Musify.Application.Albums
|
namespace Musify.Application.Albums;
|
||||||
{
|
|
||||||
public record GetAlbumTracksQuery(
|
public record GetAlbumTracksQuery(
|
||||||
Guid AlbumId,
|
Guid AlbumId,
|
||||||
int PageNumber,
|
int PageNumber,
|
||||||
int PageSize)
|
int PageSize)
|
||||||
: IQuery<ErrorOr<PaginatedResponse<TrackApplicationResponse>>>;
|
: IQuery<ErrorOr<PaginatedResponse<TrackApplicationResponse>>>;
|
||||||
|
|
||||||
public class GetAlbumTracksQueryHandler(IDatabase database)
|
public class GetAlbumTracksQueryHandler(IDatabase database)
|
||||||
: IQueryHandler<GetAlbumTracksQuery, ErrorOr<PaginatedResponse<TrackApplicationResponse>>>
|
: IQueryHandler<GetAlbumTracksQuery, ErrorOr<PaginatedResponse<TrackApplicationResponse>>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<PaginatedResponse<TrackApplicationResponse>>> Handle(GetAlbumTracksQuery request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<PaginatedResponse<TrackApplicationResponse>>> Handle(GetAlbumTracksQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var albumExists = await database.Albums
|
var albumExists = await database.Albums
|
||||||
@@ -45,5 +45,4 @@ namespace Musify.Application.Albums
|
|||||||
|
|
||||||
return PaginatedResponse<TrackApplicationResponse>.FromPagedList(pagedTracks);
|
return PaginatedResponse<TrackApplicationResponse>.FromPagedList(pagedTracks);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,17 +3,16 @@ using Mediator;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Musify.Application.Albums.Responses;
|
using Musify.Application.Albums.Responses;
|
||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
using X.PagedList;
|
|
||||||
using X.PagedList.EF;
|
using X.PagedList.EF;
|
||||||
|
|
||||||
namespace Musify.Application.Albums
|
namespace Musify.Application.Albums;
|
||||||
{
|
|
||||||
public record GetAlbumsQuery(string? Title, int PageNumber, int PageSize)
|
public record GetAlbumsQuery(string? Title, int PageNumber, int PageSize)
|
||||||
: IQuery<ErrorOr<AlbumsSearchResponse>>;
|
: IQuery<ErrorOr<AlbumsSearchResponse>>;
|
||||||
|
|
||||||
public class GetAlbumsQueryHandler(IDatabase database)
|
public class GetAlbumsQueryHandler(IDatabase database)
|
||||||
: IQueryHandler<GetAlbumsQuery, ErrorOr<AlbumsSearchResponse>>
|
: IQueryHandler<GetAlbumsQuery, ErrorOr<AlbumsSearchResponse>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<AlbumsSearchResponse>> Handle(GetAlbumsQuery request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<AlbumsSearchResponse>> Handle(GetAlbumsQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var albumsQuery = database.Albums
|
var albumsQuery = database.Albums
|
||||||
@@ -56,5 +55,4 @@ namespace Musify.Application.Albums
|
|||||||
pagedEntities.HasPreviousPage,
|
pagedEntities.HasPreviousPage,
|
||||||
pagedEntities.HasNextPage);
|
pagedEntities.HasNextPage);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ using Musify.Application.Shared;
|
|||||||
using X.PagedList;
|
using X.PagedList;
|
||||||
using X.PagedList.EF;
|
using X.PagedList.EF;
|
||||||
|
|
||||||
namespace Musify.Application.Albums
|
namespace Musify.Application.Albums;
|
||||||
{
|
|
||||||
public record GetAlbumsByUserIdQuery(long UserId, int PageNumber, int PageSize)
|
public record GetAlbumsByUserIdQuery(long UserId, int PageNumber, int PageSize)
|
||||||
: IQuery<ErrorOr<PaginatedResponse<AlbumApplicationResponse>>>;
|
: IQuery<ErrorOr<PaginatedResponse<AlbumApplicationResponse>>>;
|
||||||
|
|
||||||
public class GetAlbumsByUserIdQueryHandler(IDatabase database)
|
public class GetAlbumsByUserIdQueryHandler(IDatabase database)
|
||||||
: IQueryHandler<GetAlbumsByUserIdQuery, ErrorOr<PaginatedResponse<AlbumApplicationResponse>>>
|
: IQueryHandler<GetAlbumsByUserIdQuery, ErrorOr<PaginatedResponse<AlbumApplicationResponse>>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<PaginatedResponse<AlbumApplicationResponse>>> Handle(GetAlbumsByUserIdQuery request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<PaginatedResponse<AlbumApplicationResponse>>> Handle(GetAlbumsByUserIdQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var userExists = await database.Users
|
var userExists = await database.Users
|
||||||
@@ -49,5 +49,4 @@ namespace Musify.Application.Albums
|
|||||||
|
|
||||||
return PaginatedResponse<AlbumApplicationResponse>.FromPagedList(pagedAlbums);
|
return PaginatedResponse<AlbumApplicationResponse>.FromPagedList(pagedAlbums);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Musify.Application.Albums.Responses;
|
using Musify.Application.Albums.Responses;
|
||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
|
|
||||||
namespace Musify.Application.Albums
|
namespace Musify.Application.Albums;
|
||||||
{
|
|
||||||
public record GetRecentlyListenedAlbumsQuery(long UserId, int Limit)
|
public record GetRecentlyListenedAlbumsQuery(long UserId, int Limit)
|
||||||
: IQuery<ErrorOr<IReadOnlyList<AlbumApplicationResponse>>>;
|
: IQuery<ErrorOr<IReadOnlyList<AlbumApplicationResponse>>>;
|
||||||
|
|
||||||
public class GetRecentlyListenedAlbumsQueryHandler(IDatabase database)
|
public class GetRecentlyListenedAlbumsQueryHandler(IDatabase database)
|
||||||
: IQueryHandler<GetRecentlyListenedAlbumsQuery, ErrorOr<IReadOnlyList<AlbumApplicationResponse>>>
|
: IQueryHandler<GetRecentlyListenedAlbumsQuery, ErrorOr<IReadOnlyList<AlbumApplicationResponse>>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<IReadOnlyList<AlbumApplicationResponse>>> Handle(GetRecentlyListenedAlbumsQuery request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<IReadOnlyList<AlbumApplicationResponse>>> Handle(GetRecentlyListenedAlbumsQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var listenedTrackIds = database.ListeningHistories
|
var listenedTrackIds = database.ListeningHistories
|
||||||
@@ -57,5 +57,4 @@ namespace Musify.Application.Albums
|
|||||||
.Select(entry => AlbumApplicationResponse.FromEntity(entry.Album, entry.TrackCount, entry.CoverTrackIds))
|
.Select(entry => AlbumApplicationResponse.FromEntity(entry.Album, entry.TrackCount, entry.CoverTrackIds))
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,16 +4,16 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
|
|
||||||
namespace Musify.Application.Albums
|
namespace Musify.Application.Albums;
|
||||||
{
|
|
||||||
public record RemoveTrackFromAlbumCommand(long UserId, Guid AlbumId, Guid TrackId)
|
public record RemoveTrackFromAlbumCommand(long UserId, Guid AlbumId, Guid TrackId)
|
||||||
: ICommand<ErrorOr<Success>>;
|
: ICommand<ErrorOr<Success>>;
|
||||||
|
|
||||||
public class RemoveTrackFromAlbumCommandHandler(
|
public class RemoveTrackFromAlbumCommandHandler(
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
ILogger<RemoveTrackFromAlbumCommandHandler> logger)
|
ILogger<RemoveTrackFromAlbumCommandHandler> logger)
|
||||||
: ICommandHandler<RemoveTrackFromAlbumCommand, ErrorOr<Success>>
|
: ICommandHandler<RemoveTrackFromAlbumCommand, ErrorOr<Success>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<Success>> Handle(RemoveTrackFromAlbumCommand request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<Success>> Handle(RemoveTrackFromAlbumCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var album = await database.Albums
|
var album = await database.Albums
|
||||||
@@ -55,5 +55,4 @@ namespace Musify.Application.Albums
|
|||||||
|
|
||||||
return new Success();
|
return new Success();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,23 +2,23 @@ using ErrorOr;
|
|||||||
using Mediator;
|
using Mediator;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Musify.Application.Configuration;
|
|
||||||
using Musify.Application.Albums.Responses;
|
using Musify.Application.Albums.Responses;
|
||||||
|
using Musify.Application.Configuration;
|
||||||
|
using Musify.Application.Contracts;
|
||||||
using Musify.Application.Services;
|
using Musify.Application.Services;
|
||||||
using Musify.Domain.Entities;
|
using Musify.Domain.Entities;
|
||||||
using Musify.Domain.ValueObjects;
|
using Musify.Domain.ValueObjects;
|
||||||
using Musify.Application.Contracts;
|
|
||||||
|
|
||||||
namespace Musify.Application.Albums
|
namespace Musify.Application.Albums;
|
||||||
{
|
|
||||||
public record RequestAlbumPictureUploadCommand(
|
public record RequestAlbumPictureUploadCommand(
|
||||||
long UserId,
|
long UserId,
|
||||||
string FileType,
|
string FileType,
|
||||||
string ContentType,
|
string ContentType,
|
||||||
long? ExpectedSizeBytes = null)
|
long? ExpectedSizeBytes = null)
|
||||||
: ICommand<ErrorOr<AlbumPictureUploadResponse>>;
|
: ICommand<ErrorOr<AlbumPictureUploadResponse>>;
|
||||||
|
|
||||||
public class RequestAlbumPictureUploadCommandHandler(
|
public class RequestAlbumPictureUploadCommandHandler(
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
UploadIntentValidator uploadIntentValidator,
|
UploadIntentValidator uploadIntentValidator,
|
||||||
IStorageService storageService,
|
IStorageService storageService,
|
||||||
@@ -27,7 +27,7 @@ namespace Musify.Application.Albums
|
|||||||
AlbumConfiguration albumConfiguration,
|
AlbumConfiguration albumConfiguration,
|
||||||
UploadIntentConfiguration uploadIntentConfiguration)
|
UploadIntentConfiguration uploadIntentConfiguration)
|
||||||
: ICommandHandler<RequestAlbumPictureUploadCommand, ErrorOr<AlbumPictureUploadResponse>>
|
: ICommandHandler<RequestAlbumPictureUploadCommand, ErrorOr<AlbumPictureUploadResponse>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<AlbumPictureUploadResponse>> Handle(RequestAlbumPictureUploadCommand request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<AlbumPictureUploadResponse>> Handle(RequestAlbumPictureUploadCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var userExists = await database.Users
|
var userExists = await database.Users
|
||||||
@@ -101,5 +101,4 @@ namespace Musify.Application.Albums
|
|||||||
return Error.Failure(description: "Failed to generate upload URL");
|
return Error.Failure(description: "Failed to generate upload URL");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using Musify.Domain.Entities;
|
|
||||||
using Musify.Application.Serialization;
|
using Musify.Application.Serialization;
|
||||||
|
using Musify.Domain.Entities;
|
||||||
|
|
||||||
namespace Musify.Application.Albums.Responses
|
namespace Musify.Application.Albums.Responses;
|
||||||
{
|
|
||||||
public record AlbumApplicationResponse(
|
public record AlbumApplicationResponse(
|
||||||
Guid Id,
|
Guid Id,
|
||||||
string Title,
|
string Title,
|
||||||
string? Description,
|
string? Description,
|
||||||
@@ -17,7 +17,7 @@ namespace Musify.Application.Albums.Responses
|
|||||||
DateTime CreatedAt,
|
DateTime CreatedAt,
|
||||||
DateTime UpdatedAt,
|
DateTime UpdatedAt,
|
||||||
IReadOnlyList<Guid> CoverTrackIds)
|
IReadOnlyList<Guid> CoverTrackIds)
|
||||||
{
|
{
|
||||||
public const int CoverTrackCount = 4;
|
public const int CoverTrackCount = 4;
|
||||||
|
|
||||||
public static AlbumApplicationResponse FromEntity(
|
public static AlbumApplicationResponse FromEntity(
|
||||||
@@ -39,5 +39,4 @@ namespace Musify.Application.Albums.Responses
|
|||||||
album.UpdatedAt,
|
album.UpdatedAt,
|
||||||
coverTrackIds ?? []);
|
coverTrackIds ?? []);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace Musify.Application.Albums.Responses
|
namespace Musify.Application.Albums.Responses;
|
||||||
{
|
|
||||||
public record AlbumPictureUploadResponse(
|
public record AlbumPictureUploadResponse(
|
||||||
Guid IntentId,
|
Guid IntentId,
|
||||||
string Bucket,
|
string Bucket,
|
||||||
string Key,
|
string Key,
|
||||||
@@ -8,4 +8,3 @@ namespace Musify.Application.Albums.Responses
|
|||||||
string ContentType,
|
string ContentType,
|
||||||
int ExpiresInSeconds,
|
int ExpiresInSeconds,
|
||||||
string UploadUrl);
|
string UploadUrl);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
namespace Musify.Application.Albums.Responses
|
namespace Musify.Application.Albums.Responses;
|
||||||
|
|
||||||
|
public record AlbumSearchItemResponse(AlbumApplicationResponse Album)
|
||||||
{
|
{
|
||||||
public record AlbumSearchItemResponse(AlbumApplicationResponse Album)
|
|
||||||
{
|
|
||||||
public static AlbumSearchItemResponse FromAlbum(AlbumApplicationResponse album) => new(album);
|
public static AlbumSearchItemResponse FromAlbum(AlbumApplicationResponse album) => new(album);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
namespace Musify.Application.Albums.Responses
|
namespace Musify.Application.Albums.Responses;
|
||||||
{
|
|
||||||
|
|
||||||
public record AlbumsSearchResponse(
|
|
||||||
|
public record AlbumsSearchResponse(
|
||||||
IReadOnlyList<AlbumSearchItemResponse> Items,
|
IReadOnlyList<AlbumSearchItemResponse> Items,
|
||||||
int PageNumber,
|
int PageNumber,
|
||||||
int PageSize,
|
int PageSize,
|
||||||
@@ -9,4 +9,3 @@ namespace Musify.Application.Albums.Responses
|
|||||||
int TotalItemCount,
|
int TotalItemCount,
|
||||||
bool HasPreviousPage,
|
bool HasPreviousPage,
|
||||||
bool HasNextPage);
|
bool HasNextPage);
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,18 +2,18 @@ using ErrorOr;
|
|||||||
using Mediator;
|
using Mediator;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Musify.Application.Configuration;
|
|
||||||
using Musify.Application.Shared;
|
|
||||||
using Musify.Application.Events;
|
|
||||||
using Musify.Application.Albums.Responses;
|
using Musify.Application.Albums.Responses;
|
||||||
|
using Musify.Application.Configuration;
|
||||||
|
using Musify.Application.Contracts;
|
||||||
|
using Musify.Application.Events;
|
||||||
using Musify.Application.Services;
|
using Musify.Application.Services;
|
||||||
|
using Musify.Application.Shared;
|
||||||
using Musify.Domain.Entities;
|
using Musify.Domain.Entities;
|
||||||
using Musify.Domain.ValueObjects;
|
using Musify.Domain.ValueObjects;
|
||||||
using Musify.Application.Contracts;
|
|
||||||
|
|
||||||
namespace Musify.Application.Albums
|
namespace Musify.Application.Albums;
|
||||||
{
|
|
||||||
public record UpdateAlbumCommand(
|
public record UpdateAlbumCommand(
|
||||||
long UserId,
|
long UserId,
|
||||||
Guid AlbumId,
|
Guid AlbumId,
|
||||||
string Title,
|
string Title,
|
||||||
@@ -22,7 +22,7 @@ namespace Musify.Application.Albums
|
|||||||
Guid? NewPictureIntentId)
|
Guid? NewPictureIntentId)
|
||||||
: ICommand<ErrorOr<AlbumApplicationResponse>>;
|
: ICommand<ErrorOr<AlbumApplicationResponse>>;
|
||||||
|
|
||||||
public class UpdateAlbumCommandHandler(
|
public class UpdateAlbumCommandHandler(
|
||||||
IEventBus eventBus,
|
IEventBus eventBus,
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
UploadIntentValidator uploadIntentValidator,
|
UploadIntentValidator uploadIntentValidator,
|
||||||
@@ -31,7 +31,7 @@ namespace Musify.Application.Albums
|
|||||||
AlbumConfiguration albumConfiguration,
|
AlbumConfiguration albumConfiguration,
|
||||||
UploadIntentConfiguration uploadIntentConfiguration)
|
UploadIntentConfiguration uploadIntentConfiguration)
|
||||||
: ICommandHandler<UpdateAlbumCommand, ErrorOr<AlbumApplicationResponse>>
|
: ICommandHandler<UpdateAlbumCommand, ErrorOr<AlbumApplicationResponse>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<AlbumApplicationResponse>> Handle(UpdateAlbumCommand request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<AlbumApplicationResponse>> Handle(UpdateAlbumCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var album = await database.Albums
|
var album = await database.Albums
|
||||||
@@ -146,5 +146,4 @@ namespace Musify.Application.Albums
|
|||||||
return Error.Failure(description: $"Failed to publish update album picture source event for album {albumId}");
|
return Error.Failure(description: $"Failed to publish update album picture source event for album {albumId}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using Mediator;
|
using Mediator;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
[assembly: MediatorOptions(ServiceLifetime = ServiceLifetime.Scoped)]
|
[assembly: MediatorOptions(ServiceLifetime = ServiceLifetime.Scoped)]
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Musify.Application.Shared;
|
using Musify.Application.Shared;
|
||||||
|
|
||||||
namespace Musify.Application.Configuration
|
namespace Musify.Application.Configuration;
|
||||||
|
|
||||||
|
public class AlbumConfiguration
|
||||||
{
|
{
|
||||||
public class AlbumConfiguration
|
|
||||||
{
|
|
||||||
public const string SectionName = "Album";
|
public const string SectionName = "Album";
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
@@ -12,10 +12,10 @@ namespace Musify.Application.Configuration
|
|||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public AlbumPicturesSizes PicturesSizes { get; set; } = new AlbumPicturesSizes();
|
public AlbumPicturesSizes PicturesSizes { get; set; } = new AlbumPicturesSizes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AlbumRoutes
|
public class AlbumRoutes
|
||||||
{
|
{
|
||||||
[Required]
|
[Required]
|
||||||
public string UploadsFolder { get; set; } = "uploads";
|
public string UploadsFolder { get; set; } = "uploads";
|
||||||
|
|
||||||
@@ -54,10 +54,10 @@ namespace Musify.Application.Configuration
|
|||||||
|
|
||||||
public string BuildTempPicturePath(string tempRootPrefix, long userId, string objectName) =>
|
public string BuildTempPicturePath(string tempRootPrefix, long userId, string objectName) =>
|
||||||
StorageKey.Combine(tempRootPrefix, userId.ToString(), ParentFolders, objectName);
|
StorageKey.Combine(tempRootPrefix, userId.ToString(), ParentFolders, objectName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AlbumPicturesSizes
|
public class AlbumPicturesSizes
|
||||||
{
|
{
|
||||||
[Range(1, 1024)]
|
[Range(1, 1024)]
|
||||||
public int SmallPictureWidth { get; set; } = 128;
|
public int SmallPictureWidth { get; set; } = 128;
|
||||||
|
|
||||||
@@ -75,5 +75,4 @@ namespace Musify.Application.Configuration
|
|||||||
|
|
||||||
[Range(1, 1024)]
|
[Range(1, 1024)]
|
||||||
public int LargePictureHeight { get; set; } = 512;
|
public int LargePictureHeight { get; set; } = 512;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace Musify.Application.Configuration
|
namespace Musify.Application.Configuration;
|
||||||
|
|
||||||
|
public class ApplicationStorageConfiguration
|
||||||
{
|
{
|
||||||
public class ApplicationStorageConfiguration
|
|
||||||
{
|
|
||||||
public const string SectionName = "ApplicationStorage";
|
public const string SectionName = "ApplicationStorage";
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[StringLength(128, MinimumLength = 1)]
|
[StringLength(128, MinimumLength = 1)]
|
||||||
public required string Bucket { get; set; }
|
public required string Bucket { get; set; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
using Mediator;
|
using Mediator;
|
||||||
using Musify.Application.Configuration.Responses;
|
using Musify.Application.Configuration.Responses;
|
||||||
|
|
||||||
namespace Musify.Application.Configuration
|
namespace Musify.Application.Configuration;
|
||||||
{
|
|
||||||
|
|
||||||
public record GetPlaybackPublicConfigQuery : IQuery<PlaybackPublicConfigResponse>;
|
|
||||||
|
|
||||||
public class GetPlaybackPublicConfigQueryHandler(PlaybackConfiguration playbackConfiguration)
|
public record GetPlaybackPublicConfigQuery : IQuery<PlaybackPublicConfigResponse>;
|
||||||
|
|
||||||
|
public class GetPlaybackPublicConfigQueryHandler(PlaybackConfiguration playbackConfiguration)
|
||||||
: IQueryHandler<GetPlaybackPublicConfigQuery, PlaybackPublicConfigResponse>
|
: IQueryHandler<GetPlaybackPublicConfigQuery, PlaybackPublicConfigResponse>
|
||||||
{
|
{
|
||||||
public ValueTask<PlaybackPublicConfigResponse> Handle(GetPlaybackPublicConfigQuery query, CancellationToken cancellationToken) =>
|
public ValueTask<PlaybackPublicConfigResponse> Handle(GetPlaybackPublicConfigQuery query, CancellationToken cancellationToken) =>
|
||||||
ValueTask.FromResult(new PlaybackPublicConfigResponse(
|
ValueTask.FromResult(new PlaybackPublicConfigResponse(
|
||||||
playbackConfiguration.AllowAnonymousListening,
|
playbackConfiguration.AllowAnonymousListening,
|
||||||
playbackConfiguration.AnonymousFragmentSeconds));
|
playbackConfiguration.AnonymousFragmentSeconds));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace Musify.Application.Configuration
|
namespace Musify.Application.Configuration;
|
||||||
|
|
||||||
|
public class MixConfiguration
|
||||||
{
|
{
|
||||||
public class MixConfiguration
|
|
||||||
{
|
|
||||||
public const string SectionName = "Mix";
|
public const string SectionName = "Mix";
|
||||||
|
|
||||||
[Range(4, 100)]
|
[Range(4, 100)]
|
||||||
public int ItemsPerMix { get; set; } = 12;
|
public int ItemsPerMix { get; set; } = 12;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Musify.Application.Shared;
|
using Musify.Application.Shared;
|
||||||
|
|
||||||
namespace Musify.Application.Configuration
|
namespace Musify.Application.Configuration;
|
||||||
|
|
||||||
|
public class PlayListConfiguration
|
||||||
{
|
{
|
||||||
public class PlayListConfiguration
|
|
||||||
{
|
|
||||||
public const string SectionName = "PlayList";
|
public const string SectionName = "PlayList";
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
@@ -12,10 +12,10 @@ namespace Musify.Application.Configuration
|
|||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public PlayListPicturesSizes PicturesSizes { get; set; } = new PlayListPicturesSizes();
|
public PlayListPicturesSizes PicturesSizes { get; set; } = new PlayListPicturesSizes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PlayListRoutes
|
public class PlayListRoutes
|
||||||
{
|
{
|
||||||
[Required]
|
[Required]
|
||||||
public string UploadsFolder { get; set; } = "uploads";
|
public string UploadsFolder { get; set; } = "uploads";
|
||||||
|
|
||||||
@@ -54,10 +54,10 @@ namespace Musify.Application.Configuration
|
|||||||
|
|
||||||
public string BuildTempPicturePath(string tempRootPrefix, long userId, string objectName) =>
|
public string BuildTempPicturePath(string tempRootPrefix, long userId, string objectName) =>
|
||||||
StorageKey.Combine(tempRootPrefix, userId.ToString(), ParentFolders, objectName);
|
StorageKey.Combine(tempRootPrefix, userId.ToString(), ParentFolders, objectName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PlayListPicturesSizes
|
public class PlayListPicturesSizes
|
||||||
{
|
{
|
||||||
[Range(1, 1024)]
|
[Range(1, 1024)]
|
||||||
public int SmallPictureWidth { get; set; } = 128;
|
public int SmallPictureWidth { get; set; } = 128;
|
||||||
|
|
||||||
@@ -75,5 +75,4 @@ namespace Musify.Application.Configuration
|
|||||||
|
|
||||||
[Range(1, 1024)]
|
[Range(1, 1024)]
|
||||||
public int LargePictureHeight { get; set; } = 512;
|
public int LargePictureHeight { get; set; } = 512;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace Musify.Application.Configuration
|
namespace Musify.Application.Configuration;
|
||||||
{
|
|
||||||
|
|
||||||
public sealed class PlaybackConfiguration
|
|
||||||
{
|
public sealed class PlaybackConfiguration
|
||||||
|
{
|
||||||
public const string SectionName = "Playback";
|
public const string SectionName = "Playback";
|
||||||
|
|
||||||
public bool AllowAnonymousListening { get; set; }
|
public bool AllowAnonymousListening { get; set; }
|
||||||
@@ -14,5 +14,4 @@ namespace Musify.Application.Configuration
|
|||||||
|
|
||||||
[Range(1, int.MaxValue)]
|
[Range(1, int.MaxValue)]
|
||||||
public int EstimatedAudioBytesPerSecond { get; set; } = 16_000;
|
public int EstimatedAudioBytesPerSecond { get; set; } = 16_000;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -1,5 +1,4 @@
|
|||||||
namespace Musify.Application.Configuration.Responses
|
namespace Musify.Application.Configuration.Responses;
|
||||||
{
|
|
||||||
|
|
||||||
public record PlaybackPublicConfigResponse(bool AllowAnonymousListening, int AnonymousFragmentSeconds);
|
|
||||||
}
|
public record PlaybackPublicConfigResponse(bool AllowAnonymousListening, int AnonymousFragmentSeconds);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace Musify.Application.Configuration
|
namespace Musify.Application.Configuration;
|
||||||
|
|
||||||
|
public class StreamGatewayConfiguration
|
||||||
{
|
{
|
||||||
public class StreamGatewayConfiguration
|
|
||||||
{
|
|
||||||
public const string SectionName = "StreamGateway";
|
public const string SectionName = "StreamGateway";
|
||||||
|
|
||||||
[Url]
|
[Url]
|
||||||
@@ -12,5 +12,4 @@ namespace Musify.Application.Configuration
|
|||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public string AudioFileName { get; set; } = "audio.m4a";
|
public string AudioFileName { get; set; } = "audio.m4a";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Musify.Application.Shared;
|
using Musify.Application.Shared;
|
||||||
|
|
||||||
namespace Musify.Application.Configuration
|
namespace Musify.Application.Configuration;
|
||||||
|
|
||||||
|
public class TrackConfiguration
|
||||||
{
|
{
|
||||||
public class TrackConfiguration
|
|
||||||
{
|
|
||||||
public const string SectionName = "Track";
|
public const string SectionName = "Track";
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
@@ -12,10 +12,10 @@ namespace Musify.Application.Configuration
|
|||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public TrackPicturesSizes PicturesSizes { get; set; } = new TrackPicturesSizes();
|
public TrackPicturesSizes PicturesSizes { get; set; } = new TrackPicturesSizes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TrackRoutes
|
public class TrackRoutes
|
||||||
{
|
{
|
||||||
[Required]
|
[Required]
|
||||||
public string UploadsFolder { get; set; } = "uploads";
|
public string UploadsFolder { get; set; } = "uploads";
|
||||||
|
|
||||||
@@ -91,10 +91,10 @@ namespace Musify.Application.Configuration
|
|||||||
|
|
||||||
public string BuildTempAudioPath(string tempRootPrefix, long userId, string objectName) =>
|
public string BuildTempAudioPath(string tempRootPrefix, long userId, string objectName) =>
|
||||||
StorageKey.Combine(tempRootPrefix, userId.ToString(), ParentFolder, objectName);
|
StorageKey.Combine(tempRootPrefix, userId.ToString(), ParentFolder, objectName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TrackPicturesSizes
|
public class TrackPicturesSizes
|
||||||
{
|
{
|
||||||
[Range(1, 1024)]
|
[Range(1, 1024)]
|
||||||
public int SmallPictureWidth { get; set; } = 128;
|
public int SmallPictureWidth { get; set; } = 128;
|
||||||
|
|
||||||
@@ -112,5 +112,4 @@ namespace Musify.Application.Configuration
|
|||||||
|
|
||||||
[Range(1, 1024)]
|
[Range(1, 1024)]
|
||||||
public int LargePictureHeight { get; set; } = 512;
|
public int LargePictureHeight { get; set; } = 512;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace Musify.Application.Configuration
|
namespace Musify.Application.Configuration;
|
||||||
|
|
||||||
|
public class UploadIntentConfiguration
|
||||||
{
|
{
|
||||||
public class UploadIntentConfiguration
|
|
||||||
{
|
|
||||||
public const string SectionName = "UploadIntent";
|
public const string SectionName = "UploadIntent";
|
||||||
|
|
||||||
[Range(10, 3600)]
|
[Range(10, 3600)]
|
||||||
@@ -38,5 +38,4 @@ namespace Musify.Application.Configuration
|
|||||||
|
|
||||||
[Range(60, 86400)]
|
[Range(60, 86400)]
|
||||||
public int TemporalCleanUpJobIntervalSeconds { get; set; } = 3600;
|
public int TemporalCleanUpJobIntervalSeconds { get; set; } = 3600;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
namespace Musify.Application.Contracts
|
namespace Musify.Application.Contracts;
|
||||||
{
|
|
||||||
public record AudioTranscodeResult(int StatusCode, TimeSpan Duration);
|
public record AudioTranscodeResult(int StatusCode, TimeSpan Duration);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
namespace Musify.Application.Contracts
|
namespace Musify.Application.Contracts;
|
||||||
{
|
|
||||||
public interface IAudioTranscoderService
|
|
||||||
{
|
|
||||||
Task<AudioTranscodeResult> TranscodeToAudioFileAsync(Stream audioStream, string destinationPath, CancellationToken cancellationToken);
|
|
||||||
|
|
||||||
Task<bool> IsValidAudioFileAsync(string filePath, CancellationToken cancellationToken);
|
public interface IAudioTranscoderService
|
||||||
}
|
{
|
||||||
|
public Task<AudioTranscodeResult> TranscodeToAudioFileAsync(Stream audioStream, string destinationPath, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
public Task<bool> IsValidAudioFileAsync(string filePath, CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -1,42 +1,41 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Musify.Domain.Entities;
|
using Musify.Domain.Entities;
|
||||||
|
|
||||||
namespace Musify.Application.Contracts
|
namespace Musify.Application.Contracts;
|
||||||
|
|
||||||
|
public interface IDatabase
|
||||||
{
|
{
|
||||||
public interface IDatabase
|
public DbSet<User> Users { get; }
|
||||||
{
|
|
||||||
DbSet<User> Users { get; }
|
|
||||||
|
|
||||||
DbSet<PlayList> PlayLists { get; }
|
public DbSet<PlayList> PlayLists { get; }
|
||||||
|
|
||||||
DbSet<Album> Albums { get; }
|
public DbSet<Album> Albums { get; }
|
||||||
|
|
||||||
DbSet<AlbumHasTrack> AlbumHasTracks { get; }
|
public DbSet<AlbumHasTrack> AlbumHasTracks { get; }
|
||||||
|
|
||||||
DbSet<Track> Tracks { get; }
|
public DbSet<Track> Tracks { get; }
|
||||||
|
|
||||||
DbSet<UserHasTrack> UserHasTracks { get; }
|
public DbSet<UserHasTrack> UserHasTracks { get; }
|
||||||
|
|
||||||
DbSet<PlayListHasTrack> PlayListHasTracks { get; }
|
public DbSet<PlayListHasTrack> PlayListHasTracks { get; }
|
||||||
|
|
||||||
DbSet<Mix> Mixes { get; }
|
public DbSet<Mix> Mixes { get; }
|
||||||
|
|
||||||
DbSet<MixItem> MixItems { get; }
|
public DbSet<MixItem> MixItems { get; }
|
||||||
|
|
||||||
DbSet<Upload> Uploads { get; }
|
public DbSet<Upload> Uploads { get; }
|
||||||
|
|
||||||
DbSet<UploadIntent> UploadIntents { get; }
|
public DbSet<UploadIntent> UploadIntents { get; }
|
||||||
|
|
||||||
DbSet<ListeningHistory> ListeningHistories { get; }
|
public DbSet<ListeningHistory> ListeningHistories { get; }
|
||||||
|
|
||||||
DbSet<TrackLike> TrackLikes { get; }
|
public DbSet<TrackLike> TrackLikes { get; }
|
||||||
|
|
||||||
DbSet<TrackTag> TrackTags { get; }
|
public DbSet<TrackTag> TrackTags { get; }
|
||||||
|
|
||||||
DbSet<UserFollow> UserFollows { get; }
|
public DbSet<UserFollow> UserFollows { get; }
|
||||||
|
|
||||||
Task<IDatabaseTransaction> BeginTransactionAsync(System.Data.IsolationLevel isolationLevel, CancellationToken cancellationToken);
|
public Task<IDatabaseTransaction> BeginTransactionAsync(System.Data.IsolationLevel isolationLevel, CancellationToken cancellationToken);
|
||||||
|
|
||||||
Task<int> SaveChangesAsync(CancellationToken cancellationToken);
|
public Task<int> SaveChangesAsync(CancellationToken cancellationToken);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
namespace Musify.Application.Contracts
|
namespace Musify.Application.Contracts;
|
||||||
|
|
||||||
|
public interface IDatabaseTransaction : IAsyncDisposable
|
||||||
{
|
{
|
||||||
public interface IDatabaseTransaction : IAsyncDisposable
|
public Task CommitAsync(CancellationToken cancellationToken = default);
|
||||||
{
|
|
||||||
Task CommitAsync(CancellationToken cancellationToken = default);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
namespace Musify.Application.Contracts
|
namespace Musify.Application.Contracts;
|
||||||
|
|
||||||
|
public interface IEventBus
|
||||||
{
|
{
|
||||||
public interface IEventBus
|
public Task PublishAsync<T>(T message, CancellationToken cancellationToken) where T : class;
|
||||||
{
|
|
||||||
Task PublishAsync<T>(T message, CancellationToken cancellationToken) where T : class;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
namespace Musify.Application.Contracts
|
namespace Musify.Application.Contracts;
|
||||||
|
|
||||||
|
public interface IPictureService
|
||||||
{
|
{
|
||||||
public interface IPictureService
|
public Task<Stream> ResizePictureAsWebpAsync(Stream pictureStream, int width, int height, CancellationToken cancellationToken);
|
||||||
{
|
|
||||||
Task<Stream> ResizePictureAsWebpAsync(Stream pictureStream, int width, int height, CancellationToken cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,28 +1,27 @@
|
|||||||
namespace Musify.Application.Contracts
|
namespace Musify.Application.Contracts;
|
||||||
|
|
||||||
|
public interface IStorageService
|
||||||
{
|
{
|
||||||
public interface IStorageService
|
public Task<Stream> GetFileAsync(string bucket, string key, CancellationToken cancellationToken);
|
||||||
{
|
|
||||||
Task<Stream> GetFileAsync(string bucket, string key, CancellationToken cancellationToken);
|
|
||||||
|
|
||||||
Task<ObjectMetaData?> HeadObjectAsync(string bucket, string key, CancellationToken cancellationToken);
|
public Task<ObjectMetaData?> HeadObjectAsync(string bucket, string key, CancellationToken cancellationToken);
|
||||||
|
|
||||||
Task<string> GetUrlAsync(string bucket, string key, TimeSpan ExpirationTime, CancellationToken cancellationToken);
|
public Task<string> GetUrlAsync(string bucket, string key, TimeSpan ExpirationTime, CancellationToken cancellationToken);
|
||||||
|
|
||||||
Task<string> GetUploadUrlAsync(string bucket, string key, string contentType, TimeSpan expirationTime, CancellationToken cancellationToken, bool preventOverwrite = true);
|
public Task<string> GetUploadUrlAsync(string bucket, string key, string contentType, TimeSpan expirationTime, CancellationToken cancellationToken, bool preventOverwrite = true);
|
||||||
|
|
||||||
Task UploadFileAsync(string filePath, string bucket, string key, CancellationToken cancellationToken);
|
public Task UploadFileAsync(string filePath, string bucket, string key, CancellationToken cancellationToken);
|
||||||
|
|
||||||
Task UploadFileAsync(Stream sourceStream, string contentType, string bucket, string key, CancellationToken cancellationToken);
|
public Task UploadFileAsync(Stream sourceStream, string contentType, string bucket, string key, CancellationToken cancellationToken);
|
||||||
|
|
||||||
Task<IReadOnlyList<string>> TransferFilesAsync(string sourceDirectory, string bucket, string route, CancellationToken cancellationToken);
|
public Task<IReadOnlyList<string>> TransferFilesAsync(string sourceDirectory, string bucket, string route, CancellationToken cancellationToken);
|
||||||
|
|
||||||
Task RemoveFileAsync(string bucket, string key, CancellationToken cancellationToken);
|
public Task RemoveFileAsync(string bucket, string key, CancellationToken cancellationToken);
|
||||||
|
|
||||||
Task CopyFileAsync(string sourceBucket, string sourceKey, string destinationBucket, string destinationKey,
|
public Task CopyFileAsync(string sourceBucket, string sourceKey, string destinationBucket, string destinationKey,
|
||||||
CancellationToken cancellationToken);
|
CancellationToken cancellationToken);
|
||||||
|
|
||||||
Task RemoveFolderAsync(string bucket, string folderKey, CancellationToken cancellationToken);
|
public Task RemoveFolderAsync(string bucket, string folderKey, CancellationToken cancellationToken);
|
||||||
|
|
||||||
IAsyncEnumerable<StorageObject> ListObjectsAsync(string bucket, string prefix, CancellationToken cancellationToken);
|
public IAsyncEnumerable<StorageObject> ListObjectsAsync(string bucket, string prefix, CancellationToken cancellationToken);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
namespace Musify.Application.Contracts
|
namespace Musify.Application.Contracts;
|
||||||
|
|
||||||
|
public interface IStreamTicketService
|
||||||
{
|
{
|
||||||
public interface IStreamTicketService
|
public StreamTicket IssueTicket(long? userId, string keyPrefix, long? maxBytes = null);
|
||||||
{
|
|
||||||
|
|
||||||
StreamTicket IssueTicket(long? userId, string keyPrefix, long? maxBytes = null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public record StreamTicket(string Token, int ExpiresInSeconds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public record StreamTicket(string Token, int ExpiresInSeconds);
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
namespace Musify.Application.Contracts
|
namespace Musify.Application.Contracts;
|
||||||
{
|
|
||||||
public record ObjectMetaData(string ContentType, long ContentLength);
|
public record ObjectMetaData(string ContentType, long ContentLength);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
namespace Musify.Application.Contracts
|
namespace Musify.Application.Contracts;
|
||||||
{
|
|
||||||
public record StorageObject(string Key, DateTime LastModifiedUtc);
|
public record StorageObject(string Key, DateTime LastModifiedUtc);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record AlbumPictureProcessed(Guid AlbumId);
|
public record AlbumPictureProcessed(Guid AlbumId);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record AlbumPictureProcessingFailed(Guid AlbumId);
|
public record AlbumPictureProcessingFailed(Guid AlbumId);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record AlbumProcessingFailed(
|
public record AlbumProcessingFailed(
|
||||||
Guid AlbumId,
|
Guid AlbumId,
|
||||||
string? Bucket,
|
string? Bucket,
|
||||||
string? PictureKey);
|
string? PictureKey);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using Musify.Application.Shared;
|
using Musify.Application.Shared;
|
||||||
|
|
||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record CreateAlbumResourcesEvent(
|
public record CreateAlbumResourcesEvent(
|
||||||
Guid AlbumId,
|
Guid AlbumId,
|
||||||
Guid PictureIntentId,
|
Guid PictureIntentId,
|
||||||
string Bucket,
|
string Bucket,
|
||||||
@@ -11,4 +11,3 @@ namespace Musify.Application.Events
|
|||||||
ImageSize Small,
|
ImageSize Small,
|
||||||
ImageSize Medium,
|
ImageSize Medium,
|
||||||
ImageSize Large);
|
ImageSize Large);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using Musify.Application.Shared;
|
using Musify.Application.Shared;
|
||||||
|
|
||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record CreatePlayListResourcesEvent(
|
public record CreatePlayListResourcesEvent(
|
||||||
Guid PlayListId,
|
Guid PlayListId,
|
||||||
Guid PictureIntentId,
|
Guid PictureIntentId,
|
||||||
string Bucket,
|
string Bucket,
|
||||||
@@ -11,4 +11,3 @@ namespace Musify.Application.Events
|
|||||||
ImageSize Small,
|
ImageSize Small,
|
||||||
ImageSize Medium,
|
ImageSize Medium,
|
||||||
ImageSize Large);
|
ImageSize Large);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using Musify.Application.Shared;
|
using Musify.Application.Shared;
|
||||||
|
|
||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record CreateTrackResourcesEvent(
|
public record CreateTrackResourcesEvent(
|
||||||
Guid TrackId,
|
Guid TrackId,
|
||||||
Guid PictureIntentId,
|
Guid PictureIntentId,
|
||||||
Guid AudioIntentId,
|
Guid AudioIntentId,
|
||||||
@@ -15,4 +15,3 @@ namespace Musify.Application.Events
|
|||||||
ImageSize Small,
|
ImageSize Small,
|
||||||
ImageSize Medium,
|
ImageSize Medium,
|
||||||
ImageSize Large);
|
ImageSize Large);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record DeletePlayListEvent(
|
public record DeletePlayListEvent(
|
||||||
Guid PlayListId,
|
Guid PlayListId,
|
||||||
long UserId);
|
long UserId);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record DeleteTrackEvent(
|
public record DeleteTrackEvent(
|
||||||
Guid TrackId,
|
Guid TrackId,
|
||||||
long UserId);
|
long UserId);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record PlayListPictureProcessed(Guid PlayListId);
|
public record PlayListPictureProcessed(Guid PlayListId);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record PlayListPictureProcessingFailed(Guid PlayListId);
|
public record PlayListPictureProcessingFailed(Guid PlayListId);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record PlayListProcessingFailed(
|
public record PlayListProcessingFailed(
|
||||||
Guid PlayListId,
|
Guid PlayListId,
|
||||||
string? Bucket,
|
string? Bucket,
|
||||||
string? PictureKey);
|
string? PictureKey);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record TrackAudioProcessed(Guid TrackId);
|
public record TrackAudioProcessed(Guid TrackId);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record TrackAudioProcessingFailed(Guid TrackId);
|
public record TrackAudioProcessingFailed(Guid TrackId);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record TrackPictureProcessed(Guid TrackId);
|
public record TrackPictureProcessed(Guid TrackId);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record TrackPictureProcessingFailed(Guid TrackId);
|
public record TrackPictureProcessingFailed(Guid TrackId);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record TrackProcessingFailed(
|
public record TrackProcessingFailed(
|
||||||
Guid TrackId,
|
Guid TrackId,
|
||||||
string? Bucket,
|
string? Bucket,
|
||||||
string? PictureKey,
|
string? PictureKey,
|
||||||
string? AudioKey);
|
string? AudioKey);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
using Musify.Application.Shared;
|
using Musify.Application.Shared;
|
||||||
|
|
||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record UpdateAlbumPictureEvent(
|
public record UpdateAlbumPictureEvent(
|
||||||
Guid AlbumId,
|
Guid AlbumId,
|
||||||
string Bucket,
|
string Bucket,
|
||||||
string SourceKey,
|
string SourceKey,
|
||||||
ImageSize Small,
|
ImageSize Small,
|
||||||
ImageSize Medium,
|
ImageSize Medium,
|
||||||
ImageSize Large);
|
ImageSize Large);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using Musify.Application.Shared;
|
using Musify.Application.Shared;
|
||||||
|
|
||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record UpdateAlbumPictureSourceEvent(
|
public record UpdateAlbumPictureSourceEvent(
|
||||||
Guid AlbumId,
|
Guid AlbumId,
|
||||||
Guid PictureIntentId,
|
Guid PictureIntentId,
|
||||||
string Bucket,
|
string Bucket,
|
||||||
@@ -11,4 +11,3 @@ namespace Musify.Application.Events
|
|||||||
ImageSize Small,
|
ImageSize Small,
|
||||||
ImageSize Medium,
|
ImageSize Medium,
|
||||||
ImageSize Large);
|
ImageSize Large);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
using Musify.Application.Shared;
|
using Musify.Application.Shared;
|
||||||
|
|
||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record UpdatePlayListPictureEvent(
|
public record UpdatePlayListPictureEvent(
|
||||||
Guid PlayListId,
|
Guid PlayListId,
|
||||||
string Bucket,
|
string Bucket,
|
||||||
string SourceKey,
|
string SourceKey,
|
||||||
ImageSize Small,
|
ImageSize Small,
|
||||||
ImageSize Medium,
|
ImageSize Medium,
|
||||||
ImageSize Large);
|
ImageSize Large);
|
||||||
}
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using Musify.Application.Shared;
|
using Musify.Application.Shared;
|
||||||
|
|
||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record UpdatePlayListPictureSourceEvent(
|
public record UpdatePlayListPictureSourceEvent(
|
||||||
Guid PlayListId,
|
Guid PlayListId,
|
||||||
Guid PictureIntentId,
|
Guid PictureIntentId,
|
||||||
string Bucket,
|
string Bucket,
|
||||||
@@ -11,4 +11,3 @@ namespace Musify.Application.Events
|
|||||||
ImageSize Small,
|
ImageSize Small,
|
||||||
ImageSize Medium,
|
ImageSize Medium,
|
||||||
ImageSize Large);
|
ImageSize Large);
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record UpdateTrackAudioEvent(
|
public record UpdateTrackAudioEvent(
|
||||||
Guid TrackId,
|
Guid TrackId,
|
||||||
string SourceBucket,
|
string SourceBucket,
|
||||||
string SourceKey,
|
string SourceKey,
|
||||||
string DestinationBucket,
|
string DestinationBucket,
|
||||||
string DestinationFolderKey);
|
string DestinationFolderKey);
|
||||||
}
|
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
using Musify.Application.Shared;
|
using Musify.Application.Shared;
|
||||||
|
|
||||||
namespace Musify.Application.Events
|
namespace Musify.Application.Events;
|
||||||
{
|
|
||||||
public record UpdateTrackPictureEvent(
|
public record UpdateTrackPictureEvent(
|
||||||
Guid TrackId,
|
Guid TrackId,
|
||||||
string Bucket,
|
string Bucket,
|
||||||
string SourceKey,
|
string SourceKey,
|
||||||
ImageSize Small,
|
ImageSize Small,
|
||||||
ImageSize Medium,
|
ImageSize Medium,
|
||||||
ImageSize Large);
|
ImageSize Large);
|
||||||
}
|
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
using Mediator;
|
using Mediator;
|
||||||
using Musify.Domain.ValueObjects;
|
using Musify.Domain.ValueObjects;
|
||||||
|
|
||||||
namespace Musify.Application.Genres
|
namespace Musify.Application.Genres;
|
||||||
{
|
|
||||||
public record GetAvailableGenresQuery : IQuery<IReadOnlyList<AvailableGenreResponse>>;
|
|
||||||
|
|
||||||
public record AvailableGenreResponse(Genre Genre, IReadOnlyList<Genre> IncompatibleWith);
|
public record GetAvailableGenresQuery : IQuery<IReadOnlyList<AvailableGenreResponse>>;
|
||||||
|
|
||||||
public class GetAvailableGenresQueryHandler
|
public record AvailableGenreResponse(Genre Genre, IReadOnlyList<Genre> IncompatibleWith);
|
||||||
|
|
||||||
|
public class GetAvailableGenresQueryHandler
|
||||||
: IQueryHandler<GetAvailableGenresQuery, IReadOnlyList<AvailableGenreResponse>>
|
: IQueryHandler<GetAvailableGenresQuery, IReadOnlyList<AvailableGenreResponse>>
|
||||||
{
|
{
|
||||||
public ValueTask<IReadOnlyList<AvailableGenreResponse>> Handle(GetAvailableGenresQuery request, CancellationToken cancellationToken)
|
public ValueTask<IReadOnlyList<AvailableGenreResponse>> Handle(GetAvailableGenresQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var all = Enum.GetValues<Genre>();
|
var all = Enum.GetValues<Genre>();
|
||||||
@@ -22,5 +22,4 @@ namespace Musify.Application.Genres
|
|||||||
|
|
||||||
return ValueTask.FromResult(result);
|
return ValueTask.FromResult(result);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,15 +3,15 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
using Musify.Domain.ValueObjects;
|
using Musify.Domain.ValueObjects;
|
||||||
|
|
||||||
namespace Musify.Application.Genres
|
namespace Musify.Application.Genres;
|
||||||
{
|
|
||||||
public record GetGenresQuery : IQuery<IReadOnlyList<GenreResponse>>;
|
|
||||||
|
|
||||||
public record GenreResponse(Genre Genre, int TrackCount);
|
public record GetGenresQuery : IQuery<IReadOnlyList<GenreResponse>>;
|
||||||
|
|
||||||
public class GetGenresQueryHandler(IDatabase database)
|
public record GenreResponse(Genre Genre, int TrackCount);
|
||||||
|
|
||||||
|
public class GetGenresQueryHandler(IDatabase database)
|
||||||
: IQueryHandler<GetGenresQuery, IReadOnlyList<GenreResponse>>
|
: IQueryHandler<GetGenresQuery, IReadOnlyList<GenreResponse>>
|
||||||
{
|
{
|
||||||
public async ValueTask<IReadOnlyList<GenreResponse>> Handle(GetGenresQuery request, CancellationToken cancellationToken)
|
public async ValueTask<IReadOnlyList<GenreResponse>> Handle(GetGenresQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var rows = await database.TrackTags
|
var rows = await database.TrackTags
|
||||||
@@ -27,5 +27,4 @@ namespace Musify.Application.Genres
|
|||||||
.Select(row => new GenreResponse(row.Genre, row.TrackCount))
|
.Select(row => new GenreResponse(row.Genre, row.TrackCount))
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,17 +7,17 @@ using Musify.Application.Tracks.Responses;
|
|||||||
using X.PagedList;
|
using X.PagedList;
|
||||||
using X.PagedList.EF;
|
using X.PagedList.EF;
|
||||||
|
|
||||||
namespace Musify.Application.Likes
|
namespace Musify.Application.Likes;
|
||||||
{
|
|
||||||
public record GetLikedTracksQuery(
|
public record GetLikedTracksQuery(
|
||||||
long UserId,
|
long UserId,
|
||||||
int PageNumber,
|
int PageNumber,
|
||||||
int PageSize)
|
int PageSize)
|
||||||
: IQuery<ErrorOr<PaginatedResponse<TrackApplicationResponse>>>;
|
: IQuery<ErrorOr<PaginatedResponse<TrackApplicationResponse>>>;
|
||||||
|
|
||||||
public class GetLikedTracksQueryHandler(IDatabase database)
|
public class GetLikedTracksQueryHandler(IDatabase database)
|
||||||
: IQueryHandler<GetLikedTracksQuery, ErrorOr<PaginatedResponse<TrackApplicationResponse>>>
|
: IQueryHandler<GetLikedTracksQuery, ErrorOr<PaginatedResponse<TrackApplicationResponse>>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<PaginatedResponse<TrackApplicationResponse>>> Handle(GetLikedTracksQuery request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<PaginatedResponse<TrackApplicationResponse>>> Handle(GetLikedTracksQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var likesQuery = database.TrackLikes
|
var likesQuery = database.TrackLikes
|
||||||
@@ -39,5 +39,4 @@ namespace Musify.Application.Likes
|
|||||||
|
|
||||||
return PaginatedResponse<TrackApplicationResponse>.FromPagedList(pagedTracks);
|
return PaginatedResponse<TrackApplicationResponse>.FromPagedList(pagedTracks);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,16 +5,16 @@ using Microsoft.Extensions.Logging;
|
|||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
using Musify.Domain.Entities;
|
using Musify.Domain.Entities;
|
||||||
|
|
||||||
namespace Musify.Application.Likes
|
namespace Musify.Application.Likes;
|
||||||
{
|
|
||||||
public record ToggleTrackLikeCommand(long UserId, Guid TrackId)
|
public record ToggleTrackLikeCommand(long UserId, Guid TrackId)
|
||||||
: ICommand<ErrorOr<bool>>;
|
: ICommand<ErrorOr<bool>>;
|
||||||
|
|
||||||
public class ToggleTrackLikeCommandHandler(
|
public class ToggleTrackLikeCommandHandler(
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
ILogger<ToggleTrackLikeCommandHandler> logger)
|
ILogger<ToggleTrackLikeCommandHandler> logger)
|
||||||
: ICommandHandler<ToggleTrackLikeCommand, ErrorOr<bool>>
|
: ICommandHandler<ToggleTrackLikeCommand, ErrorOr<bool>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<bool>> Handle(ToggleTrackLikeCommand request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<bool>> Handle(ToggleTrackLikeCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var trackExists = await database.Tracks
|
var trackExists = await database.Tracks
|
||||||
@@ -52,5 +52,4 @@ namespace Musify.Application.Likes
|
|||||||
|
|
||||||
return nowLiked;
|
return nowLiked;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,17 +7,17 @@ using Musify.Application.Contracts;
|
|||||||
using Musify.Domain.Entities;
|
using Musify.Domain.Entities;
|
||||||
using Musify.Domain.ValueObjects;
|
using Musify.Domain.ValueObjects;
|
||||||
|
|
||||||
namespace Musify.Application.Mixes
|
namespace Musify.Application.Mixes;
|
||||||
{
|
|
||||||
public record GenerateMixesForUserCommand(long UserId)
|
public record GenerateMixesForUserCommand(long UserId)
|
||||||
: ICommand<ErrorOr<Success>>;
|
: ICommand<ErrorOr<Success>>;
|
||||||
|
|
||||||
public class GenerateMixesForUserCommandHandler(
|
public class GenerateMixesForUserCommandHandler(
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
MixConfiguration mixConfiguration,
|
MixConfiguration mixConfiguration,
|
||||||
ILogger<GenerateMixesForUserCommandHandler> logger)
|
ILogger<GenerateMixesForUserCommandHandler> logger)
|
||||||
: ICommandHandler<GenerateMixesForUserCommand, ErrorOr<Success>>
|
: ICommandHandler<GenerateMixesForUserCommand, ErrorOr<Success>>
|
||||||
{
|
{
|
||||||
private sealed record MixDraft(string Title, string? Subtitle, IReadOnlyList<Guid> TrackIds);
|
private sealed record MixDraft(string Title, string? Subtitle, IReadOnlyList<Guid> TrackIds);
|
||||||
|
|
||||||
public async ValueTask<ErrorOr<Success>> Handle(GenerateMixesForUserCommand request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<Success>> Handle(GenerateMixesForUserCommand request, CancellationToken cancellationToken)
|
||||||
@@ -149,5 +149,4 @@ namespace Musify.Application.Mixes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
using Musify.Application.Mixes.Responses;
|
using Musify.Application.Mixes.Responses;
|
||||||
|
|
||||||
namespace Musify.Application.Mixes
|
namespace Musify.Application.Mixes;
|
||||||
{
|
|
||||||
public record GetMixByIdQuery(long UserId, Guid MixId)
|
public record GetMixByIdQuery(long UserId, Guid MixId)
|
||||||
: IQuery<ErrorOr<MixApplicationResponse>>;
|
: IQuery<ErrorOr<MixApplicationResponse>>;
|
||||||
|
|
||||||
public class GetMixByIdQueryHandler(IDatabase database)
|
public class GetMixByIdQueryHandler(IDatabase database)
|
||||||
: IQueryHandler<GetMixByIdQuery, ErrorOr<MixApplicationResponse>>
|
: IQueryHandler<GetMixByIdQuery, ErrorOr<MixApplicationResponse>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<MixApplicationResponse>> Handle(GetMixByIdQuery request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<MixApplicationResponse>> Handle(GetMixByIdQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var mix = await database.Mixes
|
var mix = await database.Mixes
|
||||||
@@ -27,5 +27,4 @@ namespace Musify.Application.Mixes
|
|||||||
|
|
||||||
return new MixApplicationResponse(mix.Id, mix.Title, mix.Subtitle, items.Count, items);
|
return new MixApplicationResponse(mix.Id, mix.Title, mix.Subtitle, items.Count, items);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
using Musify.Application.Mixes.Responses;
|
using Musify.Application.Mixes.Responses;
|
||||||
|
|
||||||
namespace Musify.Application.Mixes
|
namespace Musify.Application.Mixes;
|
||||||
{
|
|
||||||
public record GetMixesByUserIdQuery(long UserId)
|
public record GetMixesByUserIdQuery(long UserId)
|
||||||
: IQuery<ErrorOr<IReadOnlyList<MixApplicationResponse>>>;
|
: IQuery<ErrorOr<IReadOnlyList<MixApplicationResponse>>>;
|
||||||
|
|
||||||
public class GetMixesByUserIdQueryHandler(IDatabase database)
|
public class GetMixesByUserIdQueryHandler(IDatabase database)
|
||||||
: IQueryHandler<GetMixesByUserIdQuery, ErrorOr<IReadOnlyList<MixApplicationResponse>>>
|
: IQueryHandler<GetMixesByUserIdQuery, ErrorOr<IReadOnlyList<MixApplicationResponse>>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<IReadOnlyList<MixApplicationResponse>>> Handle(GetMixesByUserIdQuery request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<IReadOnlyList<MixApplicationResponse>>> Handle(GetMixesByUserIdQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var mixes = await database.Mixes
|
var mixes = await database.Mixes
|
||||||
@@ -33,5 +33,4 @@ namespace Musify.Application.Mixes
|
|||||||
|
|
||||||
return responses;
|
return responses;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ using Musify.Application.Contracts;
|
|||||||
using Musify.Application.Mixes.Responses;
|
using Musify.Application.Mixes.Responses;
|
||||||
using Musify.Domain.Entities;
|
using Musify.Domain.Entities;
|
||||||
|
|
||||||
namespace Musify.Application.Mixes
|
namespace Musify.Application.Mixes;
|
||||||
{
|
|
||||||
|
|
||||||
internal static class MixItemMapper
|
|
||||||
{
|
internal static class MixItemMapper
|
||||||
|
{
|
||||||
public static async Task<List<MixItemApplicationResponse>> ToResponsesAsync(
|
public static async Task<List<MixItemApplicationResponse>> ToResponsesAsync(
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
IReadOnlyList<MixItem> orderedItems,
|
IReadOnlyList<MixItem> orderedItems,
|
||||||
@@ -36,5 +36,4 @@ namespace Musify.Application.Mixes
|
|||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
namespace Musify.Application.Mixes.Responses
|
namespace Musify.Application.Mixes.Responses;
|
||||||
{
|
|
||||||
public record MixApplicationResponse(
|
public record MixApplicationResponse(
|
||||||
Guid Id,
|
Guid Id,
|
||||||
string Title,
|
string Title,
|
||||||
string? Subtitle,
|
string? Subtitle,
|
||||||
int ItemCount,
|
int ItemCount,
|
||||||
IReadOnlyList<MixItemApplicationResponse> Items)
|
IReadOnlyList<MixItemApplicationResponse> Items)
|
||||||
{
|
{
|
||||||
public const int CoverItemCount = 4;
|
public const int CoverItemCount = 4;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
namespace Musify.Application.Mixes.Responses
|
namespace Musify.Application.Mixes.Responses;
|
||||||
{
|
|
||||||
public record MixItemApplicationResponse(
|
public record MixItemApplicationResponse(
|
||||||
Guid TrackId,
|
Guid TrackId,
|
||||||
string Title,
|
string Title,
|
||||||
string? Artist,
|
string? Artist,
|
||||||
double DurationSeconds,
|
double DurationSeconds,
|
||||||
int ListensCount);
|
int ListensCount);
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,16 +5,16 @@ using Microsoft.Extensions.Logging;
|
|||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
using Musify.Domain.Entities;
|
using Musify.Domain.Entities;
|
||||||
|
|
||||||
namespace Musify.Application.PlayLists
|
namespace Musify.Application.PlayLists;
|
||||||
{
|
|
||||||
public record AddTrackToPlayListCommand(long UserId, Guid PlayListId, Guid TrackId)
|
public record AddTrackToPlayListCommand(long UserId, Guid PlayListId, Guid TrackId)
|
||||||
: ICommand<ErrorOr<Success>>;
|
: ICommand<ErrorOr<Success>>;
|
||||||
|
|
||||||
public class AddTrackToPlayListCommandHandler(
|
public class AddTrackToPlayListCommandHandler(
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
ILogger<AddTrackToPlayListCommandHandler> logger)
|
ILogger<AddTrackToPlayListCommandHandler> logger)
|
||||||
: ICommandHandler<AddTrackToPlayListCommand, ErrorOr<Success>>
|
: ICommandHandler<AddTrackToPlayListCommand, ErrorOr<Success>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<Success>> Handle(AddTrackToPlayListCommand request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<Success>> Handle(AddTrackToPlayListCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var playList = await database.PlayLists
|
var playList = await database.PlayLists
|
||||||
@@ -71,5 +71,4 @@ namespace Musify.Application.PlayLists
|
|||||||
|
|
||||||
return new Success();
|
return new Success();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,17 +3,17 @@ using Mediator;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Musify.Application.Configuration;
|
using Musify.Application.Configuration;
|
||||||
using Musify.Application.Shared;
|
using Musify.Application.Contracts;
|
||||||
using Musify.Application.Events;
|
using Musify.Application.Events;
|
||||||
using Musify.Application.PlayLists.Responses;
|
using Musify.Application.PlayLists.Responses;
|
||||||
using Musify.Application.Services;
|
using Musify.Application.Services;
|
||||||
|
using Musify.Application.Shared;
|
||||||
using Musify.Domain.Entities;
|
using Musify.Domain.Entities;
|
||||||
using Musify.Domain.ValueObjects;
|
using Musify.Domain.ValueObjects;
|
||||||
using Musify.Application.Contracts;
|
|
||||||
|
|
||||||
namespace Musify.Application.PlayLists
|
namespace Musify.Application.PlayLists;
|
||||||
{
|
|
||||||
public record CreatePlayListCommand(
|
public record CreatePlayListCommand(
|
||||||
long UserId,
|
long UserId,
|
||||||
string Name,
|
string Name,
|
||||||
string? Description,
|
string? Description,
|
||||||
@@ -21,7 +21,7 @@ namespace Musify.Application.PlayLists
|
|||||||
PlaylistVisibility Visibility = PlaylistVisibility.Private)
|
PlaylistVisibility Visibility = PlaylistVisibility.Private)
|
||||||
: ICommand<ErrorOr<PlayListApplicationResponse>>;
|
: ICommand<ErrorOr<PlayListApplicationResponse>>;
|
||||||
|
|
||||||
public class CreatePlayListCommandHandler(
|
public class CreatePlayListCommandHandler(
|
||||||
IEventBus eventBus,
|
IEventBus eventBus,
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
UploadIntentValidator uploadIntentValidator,
|
UploadIntentValidator uploadIntentValidator,
|
||||||
@@ -30,7 +30,7 @@ namespace Musify.Application.PlayLists
|
|||||||
PlayListConfiguration playListConfiguration,
|
PlayListConfiguration playListConfiguration,
|
||||||
UploadIntentConfiguration uploadIntentConfiguration)
|
UploadIntentConfiguration uploadIntentConfiguration)
|
||||||
: ICommandHandler<CreatePlayListCommand, ErrorOr<PlayListApplicationResponse>>
|
: ICommandHandler<CreatePlayListCommand, ErrorOr<PlayListApplicationResponse>>
|
||||||
{
|
{
|
||||||
private sealed record ResolvedPlayListPictures(PlayListPictures? Pictures, UploadIntent? Intent);
|
private sealed record ResolvedPlayListPictures(PlayListPictures? Pictures, UploadIntent? Intent);
|
||||||
|
|
||||||
public async ValueTask<ErrorOr<PlayListApplicationResponse>> Handle(CreatePlayListCommand request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<PlayListApplicationResponse>> Handle(CreatePlayListCommand request, CancellationToken cancellationToken)
|
||||||
@@ -142,5 +142,4 @@ namespace Musify.Application.PlayLists
|
|||||||
return Error.Failure(description: $"Failed to publish create playlist event for playlist {playListId}");
|
return Error.Failure(description: $"Failed to publish create playlist event for playlist {playListId}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,17 @@ using Musify.Application.Contracts;
|
|||||||
using Musify.Application.Events;
|
using Musify.Application.Events;
|
||||||
using Musify.Domain.ValueObjects;
|
using Musify.Domain.ValueObjects;
|
||||||
|
|
||||||
namespace Musify.Application.PlayLists
|
namespace Musify.Application.PlayLists;
|
||||||
{
|
|
||||||
public record DeletePlayListCommand(long UserId, Guid PlayListId)
|
public record DeletePlayListCommand(long UserId, Guid PlayListId)
|
||||||
: ICommand<ErrorOr<Success>>;
|
: ICommand<ErrorOr<Success>>;
|
||||||
|
|
||||||
public class DeletePlayListCommandHandler(
|
public class DeletePlayListCommandHandler(
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
IEventBus eventBus,
|
IEventBus eventBus,
|
||||||
ILogger<DeletePlayListCommandHandler> logger)
|
ILogger<DeletePlayListCommandHandler> logger)
|
||||||
: ICommandHandler<DeletePlayListCommand, ErrorOr<Success>>
|
: ICommandHandler<DeletePlayListCommand, ErrorOr<Success>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<Success>> Handle(DeletePlayListCommand request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<Success>> Handle(DeletePlayListCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var playList = await database.PlayLists.SingleOrDefaultAsync(p => p.Id == request.PlayListId, cancellationToken);
|
var playList = await database.PlayLists.SingleOrDefaultAsync(p => p.Id == request.PlayListId, cancellationToken);
|
||||||
@@ -58,5 +58,4 @@ namespace Musify.Application.PlayLists
|
|||||||
|
|
||||||
return new Success();
|
return new Success();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
using ErrorOr;
|
using ErrorOr;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Musify.Application.PlayLists.Responses;
|
|
||||||
using Mediator;
|
using Mediator;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
|
using Musify.Application.PlayLists.Responses;
|
||||||
using Musify.Domain.ValueObjects;
|
using Musify.Domain.ValueObjects;
|
||||||
|
|
||||||
namespace Musify.Application.PlayLists
|
namespace Musify.Application.PlayLists;
|
||||||
{
|
|
||||||
public record GetPlayListByIdQuery(Guid Id, long? RequestingUserId = null)
|
public record GetPlayListByIdQuery(Guid Id, long? RequestingUserId = null)
|
||||||
: IQuery<ErrorOr<PlayListApplicationResponse>>;
|
: IQuery<ErrorOr<PlayListApplicationResponse>>;
|
||||||
|
|
||||||
public class GetPlayListByIdQueryHandler(IDatabase database)
|
public class GetPlayListByIdQueryHandler(IDatabase database)
|
||||||
: IQueryHandler<GetPlayListByIdQuery, ErrorOr<PlayListApplicationResponse>>
|
: IQueryHandler<GetPlayListByIdQuery, ErrorOr<PlayListApplicationResponse>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<PlayListApplicationResponse>> Handle(GetPlayListByIdQuery request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<PlayListApplicationResponse>> Handle(GetPlayListByIdQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var entry = await database.PlayLists
|
var entry = await database.PlayLists
|
||||||
@@ -34,9 +34,10 @@ namespace Musify.Application.PlayLists
|
|||||||
|
|
||||||
if (entry.PlayList.Visibility == PlaylistVisibility.Private
|
if (entry.PlayList.Visibility == PlaylistVisibility.Private
|
||||||
&& entry.PlayList.UserId != request.RequestingUserId)
|
&& entry.PlayList.UserId != request.RequestingUserId)
|
||||||
|
{
|
||||||
return Error.NotFound();
|
return Error.NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
return PlayListApplicationResponse.FromEntity(entry.PlayList, entry.CoverTrackIds);
|
return PlayListApplicationResponse.FromEntity(entry.PlayList, entry.CoverTrackIds);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,19 +5,19 @@ using MimeMapping;
|
|||||||
using Musify.Application.Configuration;
|
using Musify.Application.Configuration;
|
||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
|
|
||||||
namespace Musify.Application.PlayLists
|
namespace Musify.Application.PlayLists;
|
||||||
{
|
|
||||||
public record GetPlayListCoverQuery(Guid PlayListId, string Size)
|
public record GetPlayListCoverQuery(Guid PlayListId, string Size)
|
||||||
: IQuery<ErrorOr<PlayListCoverLocation>>;
|
: IQuery<ErrorOr<PlayListCoverLocation>>;
|
||||||
|
|
||||||
public record PlayListCoverLocation(string Bucket, string Key, string ContentType);
|
public record PlayListCoverLocation(string Bucket, string Key, string ContentType);
|
||||||
|
|
||||||
public class GetPlayListCoverQueryHandler(
|
public class GetPlayListCoverQueryHandler(
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
ApplicationStorageConfiguration storageConfiguration,
|
ApplicationStorageConfiguration storageConfiguration,
|
||||||
PlayListConfiguration playListConfiguration)
|
PlayListConfiguration playListConfiguration)
|
||||||
: IQueryHandler<GetPlayListCoverQuery, ErrorOr<PlayListCoverLocation>>
|
: IQueryHandler<GetPlayListCoverQuery, ErrorOr<PlayListCoverLocation>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<PlayListCoverLocation>> Handle(GetPlayListCoverQuery request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<PlayListCoverLocation>> Handle(GetPlayListCoverQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var pictures = await database.PlayLists.AsNoTracking()
|
var pictures = await database.PlayLists.AsNoTracking()
|
||||||
@@ -45,5 +45,4 @@ namespace Musify.Application.PlayLists
|
|||||||
|
|
||||||
private static string? BuildKey(Func<string, string> builder, string? name)
|
private static string? BuildKey(Func<string, string> builder, string? name)
|
||||||
=> string.IsNullOrEmpty(name) ? null : builder(name);
|
=> string.IsNullOrEmpty(name) ? null : builder(name);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,17 +7,17 @@ using Musify.Application.Tracks.Responses;
|
|||||||
using X.PagedList;
|
using X.PagedList;
|
||||||
using X.PagedList.EF;
|
using X.PagedList.EF;
|
||||||
|
|
||||||
namespace Musify.Application.PlayLists
|
namespace Musify.Application.PlayLists;
|
||||||
{
|
|
||||||
public record GetPlayListTracksQuery(
|
public record GetPlayListTracksQuery(
|
||||||
Guid PlayListId,
|
Guid PlayListId,
|
||||||
int PageNumber,
|
int PageNumber,
|
||||||
int PageSize)
|
int PageSize)
|
||||||
: IQuery<ErrorOr<PaginatedResponse<TrackApplicationResponse>>>;
|
: IQuery<ErrorOr<PaginatedResponse<TrackApplicationResponse>>>;
|
||||||
|
|
||||||
public class GetPlayListTracksQueryHandler(IDatabase database)
|
public class GetPlayListTracksQueryHandler(IDatabase database)
|
||||||
: IQueryHandler<GetPlayListTracksQuery, ErrorOr<PaginatedResponse<TrackApplicationResponse>>>
|
: IQueryHandler<GetPlayListTracksQuery, ErrorOr<PaginatedResponse<TrackApplicationResponse>>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<PaginatedResponse<TrackApplicationResponse>>> Handle(GetPlayListTracksQuery request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<PaginatedResponse<TrackApplicationResponse>>> Handle(GetPlayListTracksQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var playListExists = await database.PlayLists
|
var playListExists = await database.PlayLists
|
||||||
@@ -45,5 +45,4 @@ namespace Musify.Application.PlayLists
|
|||||||
|
|
||||||
return PaginatedResponse<TrackApplicationResponse>.FromPagedList(pagedTracks);
|
return PaginatedResponse<TrackApplicationResponse>.FromPagedList(pagedTracks);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
using ErrorOr;
|
using ErrorOr;
|
||||||
|
using Mediator;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Musify.Application.Shared;
|
using Musify.Application.Contracts;
|
||||||
using Musify.Application.PlayLists.Responses;
|
using Musify.Application.PlayLists.Responses;
|
||||||
|
using Musify.Application.Shared;
|
||||||
using X.PagedList;
|
using X.PagedList;
|
||||||
using X.PagedList.EF;
|
using X.PagedList.EF;
|
||||||
using Mediator;
|
|
||||||
using Musify.Application.Contracts;
|
|
||||||
|
|
||||||
namespace Musify.Application.PlayLists
|
namespace Musify.Application.PlayLists;
|
||||||
{
|
|
||||||
public record GetPlayListsQuery(int PageNumber, int PageSize)
|
public record GetPlayListsQuery(int PageNumber, int PageSize)
|
||||||
: IQuery<ErrorOr<PaginatedResponse<PlayListApplicationResponse>>>;
|
: IQuery<ErrorOr<PaginatedResponse<PlayListApplicationResponse>>>;
|
||||||
|
|
||||||
public class GetPlayListsQueryHandler(IDatabase database)
|
public class GetPlayListsQueryHandler(IDatabase database)
|
||||||
: IQueryHandler<GetPlayListsQuery, ErrorOr<PaginatedResponse<PlayListApplicationResponse>>>
|
: IQueryHandler<GetPlayListsQuery, ErrorOr<PaginatedResponse<PlayListApplicationResponse>>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<PaginatedResponse<PlayListApplicationResponse>>> Handle(GetPlayListsQuery request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<PaginatedResponse<PlayListApplicationResponse>>> Handle(GetPlayListsQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var totalCount = await database.PlayLists.CountAsync(cancellationToken);
|
var totalCount = await database.PlayLists.CountAsync(cancellationToken);
|
||||||
@@ -39,5 +39,4 @@ namespace Musify.Application.PlayLists
|
|||||||
|
|
||||||
return PaginatedResponse<PlayListApplicationResponse>.FromPagedList(pagedPlayLists);
|
return PaginatedResponse<PlayListApplicationResponse>.FromPagedList(pagedPlayLists);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ using Musify.Domain.ValueObjects;
|
|||||||
using X.PagedList;
|
using X.PagedList;
|
||||||
using X.PagedList.EF;
|
using X.PagedList.EF;
|
||||||
|
|
||||||
namespace Musify.Application.PlayLists
|
namespace Musify.Application.PlayLists;
|
||||||
{
|
|
||||||
public record GetPlayListsByUserIdQuery(
|
public record GetPlayListsByUserIdQuery(
|
||||||
long UserId,
|
long UserId,
|
||||||
string? Name,
|
string? Name,
|
||||||
int PageNumber,
|
int PageNumber,
|
||||||
@@ -18,9 +18,9 @@ namespace Musify.Application.PlayLists
|
|||||||
bool OnlyPublic = false)
|
bool OnlyPublic = false)
|
||||||
: IQuery<ErrorOr<PaginatedResponse<PlayListApplicationResponse>>>;
|
: IQuery<ErrorOr<PaginatedResponse<PlayListApplicationResponse>>>;
|
||||||
|
|
||||||
public class GetPlayListsByUserIdQueryHandler(IDatabase database)
|
public class GetPlayListsByUserIdQueryHandler(IDatabase database)
|
||||||
: IQueryHandler<GetPlayListsByUserIdQuery, ErrorOr<PaginatedResponse<PlayListApplicationResponse>>>
|
: IQueryHandler<GetPlayListsByUserIdQuery, ErrorOr<PaginatedResponse<PlayListApplicationResponse>>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<PaginatedResponse<PlayListApplicationResponse>>> Handle(GetPlayListsByUserIdQuery request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<PaginatedResponse<PlayListApplicationResponse>>> Handle(GetPlayListsByUserIdQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var playListsQuery = database.PlayLists
|
var playListsQuery = database.PlayLists
|
||||||
@@ -60,5 +60,4 @@ namespace Musify.Application.PlayLists
|
|||||||
|
|
||||||
return PaginatedResponse<PlayListApplicationResponse>.FromPagedList(pagedPlayLists);
|
return PaginatedResponse<PlayListApplicationResponse>.FromPagedList(pagedPlayLists);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,16 +4,16 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
|
|
||||||
namespace Musify.Application.PlayLists
|
namespace Musify.Application.PlayLists;
|
||||||
{
|
|
||||||
public record RemoveTrackFromPlayListCommand(long UserId, Guid PlayListId, Guid TrackId)
|
public record RemoveTrackFromPlayListCommand(long UserId, Guid PlayListId, Guid TrackId)
|
||||||
: ICommand<ErrorOr<Success>>;
|
: ICommand<ErrorOr<Success>>;
|
||||||
|
|
||||||
public class RemoveTrackFromPlayListCommandHandler(
|
public class RemoveTrackFromPlayListCommandHandler(
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
ILogger<RemoveTrackFromPlayListCommandHandler> logger)
|
ILogger<RemoveTrackFromPlayListCommandHandler> logger)
|
||||||
: ICommandHandler<RemoveTrackFromPlayListCommand, ErrorOr<Success>>
|
: ICommandHandler<RemoveTrackFromPlayListCommand, ErrorOr<Success>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<Success>> Handle(RemoveTrackFromPlayListCommand request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<Success>> Handle(RemoveTrackFromPlayListCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var playList = await database.PlayLists
|
var playList = await database.PlayLists
|
||||||
@@ -45,5 +45,4 @@ namespace Musify.Application.PlayLists
|
|||||||
|
|
||||||
return new Success();
|
return new Success();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,22 +3,22 @@ using Mediator;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Musify.Application.Configuration;
|
using Musify.Application.Configuration;
|
||||||
|
using Musify.Application.Contracts;
|
||||||
using Musify.Application.PlayLists.Responses;
|
using Musify.Application.PlayLists.Responses;
|
||||||
using Musify.Application.Services;
|
using Musify.Application.Services;
|
||||||
using Musify.Domain.Entities;
|
using Musify.Domain.Entities;
|
||||||
using Musify.Domain.ValueObjects;
|
using Musify.Domain.ValueObjects;
|
||||||
using Musify.Application.Contracts;
|
|
||||||
|
|
||||||
namespace Musify.Application.PlayLists
|
namespace Musify.Application.PlayLists;
|
||||||
{
|
|
||||||
public record RequestPlayListPictureUploadCommand(
|
public record RequestPlayListPictureUploadCommand(
|
||||||
long UserId,
|
long UserId,
|
||||||
string FileType,
|
string FileType,
|
||||||
string ContentType,
|
string ContentType,
|
||||||
long? ExpectedSizeBytes = null)
|
long? ExpectedSizeBytes = null)
|
||||||
: ICommand<ErrorOr<PlayListPictureUploadResponse>>;
|
: ICommand<ErrorOr<PlayListPictureUploadResponse>>;
|
||||||
|
|
||||||
public class RequestPlayListPictureUploadCommandHandler(
|
public class RequestPlayListPictureUploadCommandHandler(
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
UploadIntentValidator uploadIntentValidator,
|
UploadIntentValidator uploadIntentValidator,
|
||||||
IStorageService storageService,
|
IStorageService storageService,
|
||||||
@@ -27,7 +27,7 @@ namespace Musify.Application.PlayLists
|
|||||||
PlayListConfiguration playListConfiguration,
|
PlayListConfiguration playListConfiguration,
|
||||||
UploadIntentConfiguration uploadIntentConfiguration)
|
UploadIntentConfiguration uploadIntentConfiguration)
|
||||||
: ICommandHandler<RequestPlayListPictureUploadCommand, ErrorOr<PlayListPictureUploadResponse>>
|
: ICommandHandler<RequestPlayListPictureUploadCommand, ErrorOr<PlayListPictureUploadResponse>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<PlayListPictureUploadResponse>> Handle(RequestPlayListPictureUploadCommand request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<PlayListPictureUploadResponse>> Handle(RequestPlayListPictureUploadCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var userExists = await database.Users
|
var userExists = await database.Users
|
||||||
@@ -101,5 +101,4 @@ namespace Musify.Application.PlayLists
|
|||||||
return Error.Failure(description: "Failed to generate upload URL");
|
return Error.Failure(description: "Failed to generate upload URL");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
using Musify.Domain.Entities;
|
using Musify.Domain.Entities;
|
||||||
using Musify.Domain.ValueObjects;
|
using Musify.Domain.ValueObjects;
|
||||||
|
|
||||||
namespace Musify.Application.PlayLists.Responses
|
namespace Musify.Application.PlayLists.Responses;
|
||||||
{
|
|
||||||
public record PlayListApplicationResponse(
|
public record PlayListApplicationResponse(
|
||||||
Guid Id,
|
Guid Id,
|
||||||
string Name,
|
string Name,
|
||||||
string? Description,
|
string? Description,
|
||||||
@@ -14,7 +14,7 @@ namespace Musify.Application.PlayLists.Responses
|
|||||||
DateTime CreatedAt,
|
DateTime CreatedAt,
|
||||||
DateTime UpdatedAt,
|
DateTime UpdatedAt,
|
||||||
IReadOnlyList<Guid> CoverTrackIds)
|
IReadOnlyList<Guid> CoverTrackIds)
|
||||||
{
|
{
|
||||||
public const int CoverTrackCount = 4;
|
public const int CoverTrackCount = 4;
|
||||||
|
|
||||||
public static PlayListApplicationResponse FromEntity(
|
public static PlayListApplicationResponse FromEntity(
|
||||||
@@ -33,5 +33,4 @@ namespace Musify.Application.PlayLists.Responses
|
|||||||
playList.UpdatedAt,
|
playList.UpdatedAt,
|
||||||
coverTrackIds ?? []);
|
coverTrackIds ?? []);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -1,6 +1,6 @@
|
|||||||
namespace Musify.Application.PlayLists.Responses
|
namespace Musify.Application.PlayLists.Responses;
|
||||||
{
|
|
||||||
public record PlayListPictureUploadResponse(
|
public record PlayListPictureUploadResponse(
|
||||||
Guid IntentId,
|
Guid IntentId,
|
||||||
string Bucket,
|
string Bucket,
|
||||||
string Key,
|
string Key,
|
||||||
@@ -8,4 +8,3 @@ namespace Musify.Application.PlayLists.Responses
|
|||||||
string ContentType,
|
string ContentType,
|
||||||
int ExpiresInSeconds,
|
int ExpiresInSeconds,
|
||||||
string UploadUrl);
|
string UploadUrl);
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,17 +3,17 @@ using Mediator;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Musify.Application.Configuration;
|
using Musify.Application.Configuration;
|
||||||
using Musify.Application.Shared;
|
using Musify.Application.Contracts;
|
||||||
using Musify.Application.Events;
|
using Musify.Application.Events;
|
||||||
using Musify.Application.PlayLists.Responses;
|
using Musify.Application.PlayLists.Responses;
|
||||||
using Musify.Application.Services;
|
using Musify.Application.Services;
|
||||||
|
using Musify.Application.Shared;
|
||||||
using Musify.Domain.Entities;
|
using Musify.Domain.Entities;
|
||||||
using Musify.Domain.ValueObjects;
|
using Musify.Domain.ValueObjects;
|
||||||
using Musify.Application.Contracts;
|
|
||||||
|
|
||||||
namespace Musify.Application.PlayLists
|
namespace Musify.Application.PlayLists;
|
||||||
{
|
|
||||||
public record UpdatePlayListCommand(
|
public record UpdatePlayListCommand(
|
||||||
long UserId,
|
long UserId,
|
||||||
Guid PlayListId,
|
Guid PlayListId,
|
||||||
string? NewName,
|
string? NewName,
|
||||||
@@ -22,7 +22,7 @@ namespace Musify.Application.PlayLists
|
|||||||
PlaylistVisibility? NewVisibility = null)
|
PlaylistVisibility? NewVisibility = null)
|
||||||
: ICommand<ErrorOr<PlayListApplicationResponse>>;
|
: ICommand<ErrorOr<PlayListApplicationResponse>>;
|
||||||
|
|
||||||
public class UpdatePlayListCommandHandler(
|
public class UpdatePlayListCommandHandler(
|
||||||
IEventBus eventBus,
|
IEventBus eventBus,
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
UploadIntentValidator uploadIntentValidator,
|
UploadIntentValidator uploadIntentValidator,
|
||||||
@@ -31,7 +31,7 @@ namespace Musify.Application.PlayLists
|
|||||||
PlayListConfiguration playListConfiguration,
|
PlayListConfiguration playListConfiguration,
|
||||||
UploadIntentConfiguration uploadIntentConfiguration)
|
UploadIntentConfiguration uploadIntentConfiguration)
|
||||||
: ICommandHandler<UpdatePlayListCommand, ErrorOr<PlayListApplicationResponse>>
|
: ICommandHandler<UpdatePlayListCommand, ErrorOr<PlayListApplicationResponse>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<PlayListApplicationResponse>> Handle(UpdatePlayListCommand request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<PlayListApplicationResponse>> Handle(UpdatePlayListCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var playListEntity = await database.PlayLists.SingleOrDefaultAsync(pl => pl.Id == request.PlayListId, cancellationToken);
|
var playListEntity = await database.PlayLists.SingleOrDefaultAsync(pl => pl.Id == request.PlayListId, cancellationToken);
|
||||||
@@ -151,5 +151,4 @@ namespace Musify.Application.PlayLists
|
|||||||
return Error.Failure(description: $"Failed to publish update playlist picture source event for playlist {playListId}");
|
return Error.Failure(description: $"Failed to publish update playlist picture source event for playlist {playListId}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
using ErrorOr;
|
using ErrorOr;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Musify.Application.Configuration;
|
using Musify.Application.Configuration;
|
||||||
|
using Musify.Application.Contracts;
|
||||||
using Musify.Domain.Entities;
|
using Musify.Domain.Entities;
|
||||||
using Musify.Domain.ValueObjects;
|
using Musify.Domain.ValueObjects;
|
||||||
using Musify.Application.Contracts;
|
|
||||||
|
|
||||||
namespace Musify.Application.Services;
|
namespace Musify.Application.Services;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
namespace Musify.Application.Shared
|
namespace Musify.Application.Shared;
|
||||||
{
|
|
||||||
public record ImageSize(
|
public record ImageSize(
|
||||||
string SavePath,
|
string SavePath,
|
||||||
int Width,
|
int Width,
|
||||||
int Height);
|
int Height);
|
||||||
}
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using X.PagedList;
|
using X.PagedList;
|
||||||
|
|
||||||
namespace Musify.Application.Shared
|
namespace Musify.Application.Shared;
|
||||||
{
|
|
||||||
public record PaginatedResponse<T>(
|
public record PaginatedResponse<T>(
|
||||||
IReadOnlyCollection<T> Items,
|
IReadOnlyCollection<T> Items,
|
||||||
int PageNumber,
|
int PageNumber,
|
||||||
int PageSize,
|
int PageSize,
|
||||||
@@ -10,7 +10,7 @@ namespace Musify.Application.Shared
|
|||||||
int TotalItemCount,
|
int TotalItemCount,
|
||||||
bool HasNextPage,
|
bool HasNextPage,
|
||||||
bool HasPreviousPage)
|
bool HasPreviousPage)
|
||||||
{
|
{
|
||||||
public static PaginatedResponse<T> FromPagedList(IPagedList<T> pagedList)
|
public static PaginatedResponse<T> FromPagedList(IPagedList<T> pagedList)
|
||||||
{
|
{
|
||||||
return new PaginatedResponse<T>(
|
return new PaginatedResponse<T>(
|
||||||
@@ -22,5 +22,4 @@ namespace Musify.Application.Shared
|
|||||||
pagedList.HasNextPage,
|
pagedList.HasNextPage,
|
||||||
pagedList.HasPreviousPage);
|
pagedList.HasPreviousPage);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
namespace Musify.Application.Shared
|
namespace Musify.Application.Shared;
|
||||||
|
|
||||||
|
public static class StorageKey
|
||||||
{
|
{
|
||||||
public static class StorageKey
|
|
||||||
{
|
|
||||||
public static string Combine(params string[] segments)
|
public static string Combine(params string[] segments)
|
||||||
{
|
{
|
||||||
return string.Join('/', segments
|
return string.Join('/', segments
|
||||||
.Where(static s => !string.IsNullOrWhiteSpace(s))
|
.Where(static s => !string.IsNullOrWhiteSpace(s))
|
||||||
.Select(static s => s.Trim().Trim('/', '\\')));
|
.Select(static s => s.Trim().Trim('/', '\\')));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,17 +3,17 @@ using Mediator;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Musify.Application.Configuration;
|
using Musify.Application.Configuration;
|
||||||
using Musify.Application.Shared;
|
using Musify.Application.Contracts;
|
||||||
using Musify.Application.Events;
|
using Musify.Application.Events;
|
||||||
using Musify.Application.Tracks.Responses;
|
|
||||||
using Musify.Application.Services;
|
using Musify.Application.Services;
|
||||||
|
using Musify.Application.Shared;
|
||||||
|
using Musify.Application.Tracks.Responses;
|
||||||
using Musify.Domain.Entities;
|
using Musify.Domain.Entities;
|
||||||
using Musify.Domain.ValueObjects;
|
using Musify.Domain.ValueObjects;
|
||||||
using Musify.Application.Contracts;
|
|
||||||
|
|
||||||
namespace Musify.Application.Tracks
|
namespace Musify.Application.Tracks;
|
||||||
{
|
|
||||||
public record CreateTrackCommand(
|
public record CreateTrackCommand(
|
||||||
long UserId,
|
long UserId,
|
||||||
string Title,
|
string Title,
|
||||||
Guid PictureIntentId,
|
Guid PictureIntentId,
|
||||||
@@ -22,7 +22,7 @@ namespace Musify.Application.Tracks
|
|||||||
bool IsExplicit = false)
|
bool IsExplicit = false)
|
||||||
: ICommand<ErrorOr<TrackApplicationResponse>>;
|
: ICommand<ErrorOr<TrackApplicationResponse>>;
|
||||||
|
|
||||||
public class CreateTrackCommandHandler(
|
public class CreateTrackCommandHandler(
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
IEventBus eventBus,
|
IEventBus eventBus,
|
||||||
UploadIntentValidator uploadIntentValidator,
|
UploadIntentValidator uploadIntentValidator,
|
||||||
@@ -31,7 +31,7 @@ namespace Musify.Application.Tracks
|
|||||||
TrackConfiguration trackConfiguration,
|
TrackConfiguration trackConfiguration,
|
||||||
UploadIntentConfiguration uploadIntentConfiguration)
|
UploadIntentConfiguration uploadIntentConfiguration)
|
||||||
: ICommandHandler<CreateTrackCommand, ErrorOr<TrackApplicationResponse>>
|
: ICommandHandler<CreateTrackCommand, ErrorOr<TrackApplicationResponse>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<TrackApplicationResponse>> Handle(CreateTrackCommand request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<TrackApplicationResponse>> Handle(CreateTrackCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var user = await database.Users
|
var user = await database.Users
|
||||||
@@ -157,5 +157,4 @@ namespace Musify.Application.Tracks
|
|||||||
|
|
||||||
return TrackApplicationResponse.FromEntity(trackEntity, listensCount: 0);
|
return TrackApplicationResponse.FromEntity(trackEntity, listensCount: 0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,15 +3,15 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
|
|
||||||
namespace Musify.Application.Tracks
|
namespace Musify.Application.Tracks;
|
||||||
{
|
|
||||||
public record DeleteStaleUncountedListensCommand : ICommand<int>;
|
|
||||||
|
|
||||||
public class DeleteStaleUncountedListensCommandHandler(
|
public record DeleteStaleUncountedListensCommand : ICommand<int>;
|
||||||
|
|
||||||
|
public class DeleteStaleUncountedListensCommandHandler(
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
ILogger<DeleteStaleUncountedListensCommandHandler> logger)
|
ILogger<DeleteStaleUncountedListensCommandHandler> logger)
|
||||||
: ICommandHandler<DeleteStaleUncountedListensCommand, int>
|
: ICommandHandler<DeleteStaleUncountedListensCommand, int>
|
||||||
{
|
{
|
||||||
public async ValueTask<int> Handle(DeleteStaleUncountedListensCommand request, CancellationToken cancellationToken)
|
public async ValueTask<int> Handle(DeleteStaleUncountedListensCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var cutoff = DateTime.UtcNow.AddDays(-ListeningRules.UncountedRetentionDays);
|
var cutoff = DateTime.UtcNow.AddDays(-ListeningRules.UncountedRetentionDays);
|
||||||
@@ -29,5 +29,4 @@ namespace Musify.Application.Tracks
|
|||||||
logger.LogInformation("Deleted {Count} uncounted listens older than {Days} days", stale.Count, ListeningRules.UncountedRetentionDays);
|
logger.LogInformation("Deleted {Count} uncounted listens older than {Days} days", stale.Count, ListeningRules.UncountedRetentionDays);
|
||||||
return stale.Count;
|
return stale.Count;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,24 +2,23 @@ using ErrorOr;
|
|||||||
using Mediator;
|
using Mediator;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Musify.Domain.Entities;
|
|
||||||
using Musify.Domain.ValueObjects;
|
|
||||||
using Musify.Application.Events;
|
|
||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
|
using Musify.Application.Events;
|
||||||
|
using Musify.Domain.ValueObjects;
|
||||||
|
|
||||||
namespace Musify.Application.Tracks
|
namespace Musify.Application.Tracks;
|
||||||
{
|
|
||||||
public record DeleteTrackCommand(
|
public record DeleteTrackCommand(
|
||||||
long UserId,
|
long UserId,
|
||||||
Guid TrackId)
|
Guid TrackId)
|
||||||
: ICommand<ErrorOr<Success>>;
|
: ICommand<ErrorOr<Success>>;
|
||||||
|
|
||||||
public class DeleteTrackCommandHandler(
|
public class DeleteTrackCommandHandler(
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
IEventBus eventBus,
|
IEventBus eventBus,
|
||||||
ILogger<DeleteTrackCommandHandler> logger)
|
ILogger<DeleteTrackCommandHandler> logger)
|
||||||
: ICommandHandler<DeleteTrackCommand, ErrorOr<Success>>
|
: ICommandHandler<DeleteTrackCommand, ErrorOr<Success>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<Success>> Handle(DeleteTrackCommand request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<Success>> Handle(DeleteTrackCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var track = await database.Tracks.SingleOrDefaultAsync(t => t.Id == request.TrackId, cancellationToken);
|
var track = await database.Tracks.SingleOrDefaultAsync(t => t.Id == request.TrackId, cancellationToken);
|
||||||
@@ -67,5 +66,4 @@ namespace Musify.Application.Tracks
|
|||||||
|
|
||||||
return new Success();
|
return new Success();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
using ErrorOr;
|
using ErrorOr;
|
||||||
using Mediator;
|
using Mediator;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
using Musify.Application.Tracks.Responses;
|
using Musify.Application.Tracks.Responses;
|
||||||
|
|
||||||
namespace Musify.Application.Tracks
|
namespace Musify.Application.Tracks;
|
||||||
{
|
|
||||||
public record GetLastTrackListenedByUserIdQuery(long UserId) : IQuery<ErrorOr<TrackApplicationResponse>>;
|
|
||||||
|
|
||||||
public class GetLastTrackListenedByUserIdQueryHandler(IDatabase database)
|
public record GetLastTrackListenedByUserIdQuery(long UserId) : IQuery<ErrorOr<TrackApplicationResponse>>;
|
||||||
|
|
||||||
|
public class GetLastTrackListenedByUserIdQueryHandler(IDatabase database)
|
||||||
: IQueryHandler<GetLastTrackListenedByUserIdQuery, ErrorOr<TrackApplicationResponse>>
|
: IQueryHandler<GetLastTrackListenedByUserIdQuery, ErrorOr<TrackApplicationResponse>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<TrackApplicationResponse>> Handle(GetLastTrackListenedByUserIdQuery query, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<TrackApplicationResponse>> Handle(GetLastTrackListenedByUserIdQuery query, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var track = await database.ListeningHistories
|
var track = await database.ListeningHistories
|
||||||
@@ -26,5 +26,4 @@ namespace Musify.Application.Tracks
|
|||||||
? Error.NotFound("Track.NotFound", "No track found for the given user ID.")
|
? Error.NotFound("Track.NotFound", "No track found for the given user ID.")
|
||||||
: track;
|
: track;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
using Mediator;
|
using Mediator;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
using Musify.Application.Tracks.Responses;
|
using Musify.Application.Tracks.Responses;
|
||||||
|
|
||||||
namespace Musify.Application.Tracks
|
namespace Musify.Application.Tracks;
|
||||||
{
|
|
||||||
public record GetListeningHistoryQuery(long UserId) : IQuery<IEnumerable<TrackApplicationResponse>>;
|
|
||||||
|
|
||||||
public class GetListeningHistoryQueryHandler(
|
public record GetListeningHistoryQuery(long UserId) : IQuery<IEnumerable<TrackApplicationResponse>>;
|
||||||
|
|
||||||
|
public class GetListeningHistoryQueryHandler(
|
||||||
IDatabase database)
|
IDatabase database)
|
||||||
: IQueryHandler<GetListeningHistoryQuery, IEnumerable<TrackApplicationResponse>>
|
: IQueryHandler<GetListeningHistoryQuery, IEnumerable<TrackApplicationResponse>>
|
||||||
{
|
{
|
||||||
public const int ListSize = 15;
|
public const int ListSize = 15;
|
||||||
|
|
||||||
public async ValueTask<IEnumerable<TrackApplicationResponse>> Handle(GetListeningHistoryQuery query, CancellationToken cancellationToken)
|
public async ValueTask<IEnumerable<TrackApplicationResponse>> Handle(GetListeningHistoryQuery query, CancellationToken cancellationToken)
|
||||||
@@ -36,5 +36,4 @@ namespace Musify.Application.Tracks
|
|||||||
.Select(id => tracksById[id])
|
.Select(id => tracksById[id])
|
||||||
.Select(t => TrackApplicationResponse.FromEntity(t.Track, t.ListensCount));
|
.Select(t => TrackApplicationResponse.FromEntity(t.Track, t.ListensCount));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
using Musify.Application.Tracks.Responses;
|
using Musify.Application.Tracks.Responses;
|
||||||
|
|
||||||
namespace Musify.Application.Tracks
|
namespace Musify.Application.Tracks;
|
||||||
{
|
|
||||||
public record GetTrackByIdQuery(Guid TrackId)
|
public record GetTrackByIdQuery(Guid TrackId)
|
||||||
: IQuery<ErrorOr<TrackApplicationResponse>>;
|
: IQuery<ErrorOr<TrackApplicationResponse>>;
|
||||||
|
|
||||||
public class GetTrackByIdQueryHandler(IDatabase database)
|
public class GetTrackByIdQueryHandler(IDatabase database)
|
||||||
: IQueryHandler<GetTrackByIdQuery, ErrorOr<TrackApplicationResponse>>
|
: IQueryHandler<GetTrackByIdQuery, ErrorOr<TrackApplicationResponse>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<TrackApplicationResponse>> Handle(GetTrackByIdQuery request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<TrackApplicationResponse>> Handle(GetTrackByIdQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var entity = await database.Tracks.AsNoTracking()
|
var entity = await database.Tracks.AsNoTracking()
|
||||||
@@ -26,5 +26,4 @@ namespace Musify.Application.Tracks
|
|||||||
|
|
||||||
return TrackApplicationResponse.FromEntity(entity.Track, entity.ListensCount);
|
return TrackApplicationResponse.FromEntity(entity.Track, entity.ListensCount);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,19 +4,19 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Musify.Application.Configuration;
|
using Musify.Application.Configuration;
|
||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
|
|
||||||
namespace Musify.Application.Tracks
|
namespace Musify.Application.Tracks;
|
||||||
{
|
|
||||||
public record GetTrackCoverQuery(Guid TrackId, string Size)
|
public record GetTrackCoverQuery(Guid TrackId, string Size)
|
||||||
: IQuery<ErrorOr<TrackCoverLocation>>;
|
: IQuery<ErrorOr<TrackCoverLocation>>;
|
||||||
|
|
||||||
public record TrackCoverLocation(string Bucket, string Key, string ContentType);
|
public record TrackCoverLocation(string Bucket, string Key, string ContentType);
|
||||||
|
|
||||||
public class GetTrackCoverQueryHandler(
|
public class GetTrackCoverQueryHandler(
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
ApplicationStorageConfiguration storageConfiguration,
|
ApplicationStorageConfiguration storageConfiguration,
|
||||||
TrackConfiguration trackConfiguration)
|
TrackConfiguration trackConfiguration)
|
||||||
: IQueryHandler<GetTrackCoverQuery, ErrorOr<TrackCoverLocation>>
|
: IQueryHandler<GetTrackCoverQuery, ErrorOr<TrackCoverLocation>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<TrackCoverLocation>> Handle(GetTrackCoverQuery request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<TrackCoverLocation>> Handle(GetTrackCoverQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var track = await database.Tracks.AsNoTracking()
|
var track = await database.Tracks.AsNoTracking()
|
||||||
@@ -49,5 +49,4 @@ namespace Musify.Application.Tracks
|
|||||||
|
|
||||||
private static string? BuildKey(Func<string, string> builder, string? name)
|
private static string? BuildKey(Func<string, string> builder, string? name)
|
||||||
=> string.IsNullOrEmpty(name) ? null : builder(name);
|
=> string.IsNullOrEmpty(name) ? null : builder(name);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -7,19 +7,19 @@ using Musify.Application.Contracts;
|
|||||||
using Musify.Application.Services;
|
using Musify.Application.Services;
|
||||||
using Musify.Application.Tracks.Responses;
|
using Musify.Application.Tracks.Responses;
|
||||||
|
|
||||||
namespace Musify.Application.Tracks
|
namespace Musify.Application.Tracks;
|
||||||
{
|
|
||||||
|
|
||||||
public record GetTrackStreamQuery(Guid TrackId, long? UserId)
|
|
||||||
|
public record GetTrackStreamQuery(Guid TrackId, long? UserId)
|
||||||
: IQuery<ErrorOr<TrackStreamResponse>>;
|
: IQuery<ErrorOr<TrackStreamResponse>>;
|
||||||
|
|
||||||
public class GetTrackStreamQueryHandler(
|
public class GetTrackStreamQueryHandler(
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
TrackStreamIssuer streamIssuer,
|
TrackStreamIssuer streamIssuer,
|
||||||
PlaybackConfiguration playbackConfiguration,
|
PlaybackConfiguration playbackConfiguration,
|
||||||
ILogger<GetTrackStreamQueryHandler> logger)
|
ILogger<GetTrackStreamQueryHandler> logger)
|
||||||
: IQueryHandler<GetTrackStreamQuery, ErrorOr<TrackStreamResponse>>
|
: IQueryHandler<GetTrackStreamQuery, ErrorOr<TrackStreamResponse>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<TrackStreamResponse>> Handle(GetTrackStreamQuery request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<TrackStreamResponse>> Handle(GetTrackStreamQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (request.UserId == null && !playbackConfiguration.AllowAnonymousListening)
|
if (request.UserId == null && !playbackConfiguration.AllowAnonymousListening)
|
||||||
@@ -45,5 +45,4 @@ namespace Musify.Application.Tracks
|
|||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
using ErrorOr;
|
using ErrorOr;
|
||||||
using Mediator;
|
using Mediator;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Musify.Application.Tracks.Responses;
|
|
||||||
using X.PagedList;
|
|
||||||
using X.PagedList.EF;
|
|
||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
|
using Musify.Application.Tracks.Responses;
|
||||||
using Musify.Domain.ValueObjects;
|
using Musify.Domain.ValueObjects;
|
||||||
|
using X.PagedList.EF;
|
||||||
|
|
||||||
namespace Musify.Application.Tracks
|
namespace Musify.Application.Tracks;
|
||||||
{
|
|
||||||
public record GetTracksQuery(string? Name, int PageNumber, int PageSize, Genre? Genre = null)
|
public record GetTracksQuery(string? Name, int PageNumber, int PageSize, Genre? Genre = null)
|
||||||
: IQuery<ErrorOr<TracksSearchResponse>>;
|
: IQuery<ErrorOr<TracksSearchResponse>>;
|
||||||
|
|
||||||
public class GetTracksQueryHandler(IDatabase database)
|
public class GetTracksQueryHandler(IDatabase database)
|
||||||
: IQueryHandler<GetTracksQuery, ErrorOr<TracksSearchResponse>>
|
: IQueryHandler<GetTracksQuery, ErrorOr<TracksSearchResponse>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<TracksSearchResponse>> Handle(GetTracksQuery request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<TracksSearchResponse>> Handle(GetTracksQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var tracksQuery = database.UserHasTracks
|
var tracksQuery = database.UserHasTracks
|
||||||
@@ -53,5 +52,4 @@ namespace Musify.Application.Tracks
|
|||||||
pagedEntities.HasPreviousPage,
|
pagedEntities.HasPreviousPage,
|
||||||
pagedEntities.HasNextPage);
|
pagedEntities.HasNextPage);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
using ErrorOr;
|
using ErrorOr;
|
||||||
using Mediator;
|
using Mediator;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Musify.Application.Contracts;
|
||||||
using Musify.Application.Shared;
|
using Musify.Application.Shared;
|
||||||
using Musify.Application.Tracks.Responses;
|
using Musify.Application.Tracks.Responses;
|
||||||
using X.PagedList;
|
using X.PagedList;
|
||||||
using X.PagedList.EF;
|
using X.PagedList.EF;
|
||||||
using Musify.Application.Contracts;
|
|
||||||
|
|
||||||
namespace Musify.Application.Tracks
|
namespace Musify.Application.Tracks;
|
||||||
{
|
|
||||||
public record GetTracksByUserIdQuery(
|
public record GetTracksByUserIdQuery(
|
||||||
long UserId,
|
long UserId,
|
||||||
string? Name,
|
string? Name,
|
||||||
int PageNumber,
|
int PageNumber,
|
||||||
int PageSize)
|
int PageSize)
|
||||||
: IQuery<ErrorOr<PaginatedResponse<TrackApplicationResponse>>>;
|
: IQuery<ErrorOr<PaginatedResponse<TrackApplicationResponse>>>;
|
||||||
|
|
||||||
public class GetTracksByUserIdQueryHandler(IDatabase database)
|
public class GetTracksByUserIdQueryHandler(IDatabase database)
|
||||||
: IQueryHandler<GetTracksByUserIdQuery, ErrorOr<PaginatedResponse<TrackApplicationResponse>>>
|
: IQueryHandler<GetTracksByUserIdQuery, ErrorOr<PaginatedResponse<TrackApplicationResponse>>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<PaginatedResponse<TrackApplicationResponse>>> Handle(GetTracksByUserIdQuery request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<PaginatedResponse<TrackApplicationResponse>>> Handle(GetTracksByUserIdQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var pageNumber = request.PageNumber < 1 ? 1 : request.PageNumber;
|
var pageNumber = request.PageNumber < 1 ? 1 : request.PageNumber;
|
||||||
@@ -49,5 +49,4 @@ namespace Musify.Application.Tracks
|
|||||||
|
|
||||||
return PaginatedResponse<TrackApplicationResponse>.FromPagedList(pagedTracks);
|
return PaginatedResponse<TrackApplicationResponse>.FromPagedList(pagedTracks);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
namespace Musify.Application.Tracks
|
namespace Musify.Application.Tracks;
|
||||||
|
|
||||||
|
public static class ListeningRules
|
||||||
{
|
{
|
||||||
public static class ListeningRules
|
|
||||||
{
|
|
||||||
public const double CountedThresholdSeconds = 30;
|
public const double CountedThresholdSeconds = 30;
|
||||||
public const double CountedThresholdFraction = 0.5;
|
public const double CountedThresholdFraction = 0.5;
|
||||||
public const double DurationToleranceSeconds = 2;
|
public const double DurationToleranceSeconds = 2;
|
||||||
@@ -10,5 +10,4 @@ namespace Musify.Application.Tracks
|
|||||||
|
|
||||||
public static double CountedThreshold(double durationSeconds) =>
|
public static double CountedThreshold(double durationSeconds) =>
|
||||||
Math.Min(CountedThresholdSeconds, durationSeconds * CountedThresholdFraction);
|
Math.Min(CountedThresholdSeconds, durationSeconds * CountedThresholdFraction);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,17 +3,17 @@ using Mediator;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
|
|
||||||
namespace Musify.Application.Tracks
|
namespace Musify.Application.Tracks;
|
||||||
{
|
|
||||||
public record RecordListeningProgressCommand(
|
public record RecordListeningProgressCommand(
|
||||||
long UserId,
|
long UserId,
|
||||||
Guid ListenId,
|
Guid ListenId,
|
||||||
double PlayedSeconds)
|
double PlayedSeconds)
|
||||||
: ICommand<ErrorOr<Success>>;
|
: ICommand<ErrorOr<Success>>;
|
||||||
|
|
||||||
public class RecordListeningProgressCommandHandler(IDatabase database)
|
public class RecordListeningProgressCommandHandler(IDatabase database)
|
||||||
: ICommandHandler<RecordListeningProgressCommand, ErrorOr<Success>>
|
: ICommandHandler<RecordListeningProgressCommand, ErrorOr<Success>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<Success>> Handle(RecordListeningProgressCommand request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<Success>> Handle(RecordListeningProgressCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (!double.IsFinite(request.PlayedSeconds) || request.PlayedSeconds < 0)
|
if (!double.IsFinite(request.PlayedSeconds) || request.PlayedSeconds < 0)
|
||||||
@@ -40,5 +40,4 @@ namespace Musify.Application.Tracks
|
|||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,15 +3,15 @@ using Mediator;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Musify.Application.Configuration;
|
using Musify.Application.Configuration;
|
||||||
|
using Musify.Application.Contracts;
|
||||||
using Musify.Application.Services;
|
using Musify.Application.Services;
|
||||||
using Musify.Application.Tracks.Responses;
|
using Musify.Application.Tracks.Responses;
|
||||||
using Musify.Domain.Entities;
|
using Musify.Domain.Entities;
|
||||||
using Musify.Domain.ValueObjects;
|
using Musify.Domain.ValueObjects;
|
||||||
using Musify.Application.Contracts;
|
|
||||||
|
|
||||||
namespace Musify.Application.Tracks
|
namespace Musify.Application.Tracks;
|
||||||
{
|
|
||||||
public record RequestTrackUploadUrlsCommand(
|
public record RequestTrackUploadUrlsCommand(
|
||||||
long UserId,
|
long UserId,
|
||||||
string PictureFileType,
|
string PictureFileType,
|
||||||
string PictureContentType,
|
string PictureContentType,
|
||||||
@@ -21,7 +21,7 @@ namespace Musify.Application.Tracks
|
|||||||
long? ExpectedAudioSizeBytes = null)
|
long? ExpectedAudioSizeBytes = null)
|
||||||
: ICommand<ErrorOr<TrackUploadUrlsResponse>>;
|
: ICommand<ErrorOr<TrackUploadUrlsResponse>>;
|
||||||
|
|
||||||
public class RequestTrackUploadUrlsCommandHandler(
|
public class RequestTrackUploadUrlsCommandHandler(
|
||||||
IDatabase database,
|
IDatabase database,
|
||||||
UploadIntentValidator uploadIntentValidator,
|
UploadIntentValidator uploadIntentValidator,
|
||||||
IStorageService storageService,
|
IStorageService storageService,
|
||||||
@@ -30,7 +30,7 @@ namespace Musify.Application.Tracks
|
|||||||
TrackConfiguration trackConfiguration,
|
TrackConfiguration trackConfiguration,
|
||||||
UploadIntentConfiguration uploadIntentConfiguration)
|
UploadIntentConfiguration uploadIntentConfiguration)
|
||||||
: ICommandHandler<RequestTrackUploadUrlsCommand, ErrorOr<TrackUploadUrlsResponse>>
|
: ICommandHandler<RequestTrackUploadUrlsCommand, ErrorOr<TrackUploadUrlsResponse>>
|
||||||
{
|
{
|
||||||
public async ValueTask<ErrorOr<TrackUploadUrlsResponse>> Handle(RequestTrackUploadUrlsCommand request, CancellationToken cancellationToken)
|
public async ValueTask<ErrorOr<TrackUploadUrlsResponse>> Handle(RequestTrackUploadUrlsCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var userExists = await database.Users
|
var userExists = await database.Users
|
||||||
@@ -139,5 +139,4 @@ namespace Musify.Application.Tracks
|
|||||||
return Error.Failure(description: "Failed to generate upload URLs");
|
return Error.Failure(description: "Failed to generate upload URLs");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user