Track get-or-create for YouTube videos was duplicated between the old GetYouTubeTrackStream query handler (which also wrote to the database) and AddYouTubeTrackToPlayList, with frontend-supplied metadata (title/artist/duration/thumbnail) trusted at add-to-playlist time instead of resolving it server-side. Extract YouTubeTrackProvisioner as the single get-or-create path, resolving structured artist refs (id + name) from YouTube Music so multi-artist songs map to distinct Artist rows. Rename GetYouTubeTrackStream to ResolveYouTubeTrackStream (it writes, so it is a command, not a query) and delegate to the provisioner. AddYouTubeTrackToPlayList slims down to (UserId, PlayListId, VideoId) since all metadata now comes from the provisioner/YouTube API.
62 lines
2.0 KiB
C#
62 lines
2.0 KiB
C#
using Mediator;
|
|
using Musify.Api.Authentication;
|
|
using Musify.Api.Extensions;
|
|
using Musify.Application.Contracts;
|
|
using Musify.Application.YouTube;
|
|
using Musify.Application.YouTube.Responses;
|
|
|
|
namespace Musify.Api.Endpoints;
|
|
|
|
public static class YouTubeEndpoints
|
|
{
|
|
public static IEndpointRouteBuilder MapYouTubeEndpoints(this IEndpointRouteBuilder app)
|
|
{
|
|
var group = app.MapGroup("/youtube")
|
|
.WithTags("YouTube");
|
|
|
|
group.MapGet("/search", SearchTracks)
|
|
.WithName("SearchYouTubeTracks")
|
|
.WithSummary("Search Songs On YouTube Music.")
|
|
.RequireAuthorization()
|
|
.Produces<YouTubeSearchResult>()
|
|
.Produces(StatusCodes.Status401Unauthorized)
|
|
.ProducesValidationProblem();
|
|
|
|
group.MapGet("/tracks/{videoId}/stream", GetTrackStream)
|
|
.WithName("GetYouTubeTrackStream")
|
|
.WithSummary("Resolve Playback For A YouTube Track: Server Stream If Downloaded, Direct YouTube Stream Otherwise.")
|
|
.RequireAuthorization()
|
|
.Produces<YouTubeStreamResponse>()
|
|
.Produces(StatusCodes.Status401Unauthorized)
|
|
.Produces(StatusCodes.Status404NotFound);
|
|
|
|
return app;
|
|
}
|
|
|
|
private static async Task<IResult> GetTrackStream(
|
|
IMediator mediator,
|
|
CurrentUser currentUser,
|
|
string videoId,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var result = await mediator.Send(
|
|
new ResolveYouTubeTrackStreamCommand(videoId, currentUser.RequiredId),
|
|
cancellationToken);
|
|
|
|
return result.ToHttpResult();
|
|
}
|
|
|
|
private static async Task<IResult> SearchTracks(
|
|
IMediator mediator,
|
|
CancellationToken cancellationToken,
|
|
string query,
|
|
string? continuation = null)
|
|
{
|
|
var result = await mediator.Send(
|
|
new SearchYouTubeTracksQuery(query, continuation ?? string.Empty),
|
|
cancellationToken);
|
|
|
|
return result.ToHttpResult();
|
|
}
|
|
}
|