Drops the YouTube-backed second catalog source entirely: the Local/External split on Track/Album collapses into single concrete entities, Artist/TrackArtist/ExternalTrack/ExternalAlbum and the YouTube service/download pipeline (yt-dlp, MassTransit consumer, routing slip) are deleted, and mixes now source discovery only from local listening history. Includes the RemoveYouTubeIntegration EF Core migration and matching Worker/deploy/compose cleanup (no more yt-dlp/python/deno in the Worker image, no thumbnail-cache/YtDlp config sections).
37 lines
1.5 KiB
C#
37 lines
1.5 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using Musify.Application.Contracts;
|
|
using Musify.Application.Mixes.Responses;
|
|
using Musify.Domain.Entities;
|
|
|
|
namespace Musify.Application.Mixes
|
|
{
|
|
/// <summary>Resolves MixItem rows to their MixItemApplicationResponse shape via a single batched
|
|
/// track lookup, instead of an EF Include chain deep enough (Mix -> Items -> Track -> Owner) to
|
|
/// force a correlated-subquery translation some providers (SQLite, notably) can't produce.</summary>
|
|
internal static class MixItemMapper
|
|
{
|
|
public static async Task<List<MixItemApplicationResponse>> ToResponsesAsync(
|
|
IDatabase database,
|
|
IReadOnlyList<MixItem> orderedItems,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var trackIds = orderedItems.Select(item => item.TrackId).Distinct().ToList();
|
|
|
|
var tracksById = await database.Tracks
|
|
.AsNoTracking()
|
|
.Include(track => track.Owner)
|
|
.Where(track => trackIds.Contains(track.Id))
|
|
.ToDictionaryAsync(track => track.Id, cancellationToken);
|
|
|
|
return orderedItems
|
|
.Where(item => tracksById.ContainsKey(item.TrackId))
|
|
.Select(item =>
|
|
{
|
|
var track = tracksById[item.TrackId];
|
|
return new MixItemApplicationResponse(item.TrackId, track.Title, track.Owner.Name, track.DurationSeconds);
|
|
})
|
|
.ToList();
|
|
}
|
|
}
|
|
}
|