Design Prot Merge #1
@@ -22,7 +22,7 @@ namespace Musify.Application.Mixes
|
|||||||
{
|
{
|
||||||
private sealed record SeedArtist(Guid Id, string Name);
|
private sealed record SeedArtist(Guid Id, string Name);
|
||||||
|
|
||||||
private sealed record LocalCandidate(Guid TrackId, string Title, string? Artist, int DurationSeconds);
|
private sealed record LocalCandidate(Guid TrackId, string Title, string? Artist, double DurationSeconds);
|
||||||
|
|
||||||
private sealed record MixDraft(string Title, string? Subtitle, IReadOnlyList<MixItem> Items);
|
private sealed record MixDraft(string Title, string? Subtitle, IReadOnlyList<MixItem> Items);
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ namespace Musify.Application.Mixes
|
|||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.Where(trackArtist => historyTrackIds.Contains(trackArtist.TrackId))
|
.Where(trackArtist => historyTrackIds.Contains(trackArtist.TrackId))
|
||||||
.GroupBy(trackArtist => trackArtist.ArtistId)
|
.GroupBy(trackArtist => trackArtist.ArtistId)
|
||||||
.Select(group => new { ArtistId = group.Key, Listens = group.Count() })
|
.Select(group => new { ArtistId = group.Key, Listens = group.Count() } )
|
||||||
.OrderByDescending(entry => entry.Listens)
|
.OrderByDescending(entry => entry.Listens)
|
||||||
.Take(mixConfiguration.SeedArtistCount)
|
.Take(mixConfiguration.SeedArtistCount)
|
||||||
.ToListAsync(cancellationToken);
|
.ToListAsync(cancellationToken);
|
||||||
@@ -113,10 +113,10 @@ namespace Musify.Application.Mixes
|
|||||||
|
|
||||||
return [.. ranked
|
return [.. ranked
|
||||||
.Where(entry => names.ContainsKey(entry.ArtistId))
|
.Where(entry => names.ContainsKey(entry.ArtistId))
|
||||||
.Select(entry => new SeedArtist(entry.ArtistId, names[entry.ArtistId]))];
|
.Select(entry => new SeedArtist(entry.ArtistId, names[entry.ArtistId])) ];
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Dictionary<Guid, List<MixItem>>> SearchYouTubeAsync(
|
private async Task<Dictionary<Guid, List<MixItem>> > SearchYouTubeAsync(
|
||||||
IReadOnlyList<SeedArtist> seedArtists,
|
IReadOnlyList<SeedArtist> seedArtists,
|
||||||
HashSet<string> excludedVideoIds,
|
HashSet<string> excludedVideoIds,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
@@ -150,7 +150,7 @@ namespace Musify.Application.Mixes
|
|||||||
ThumbnailUrl = Truncate(youTubeMusicService.ResolveArtworkUrl(song.ThumbnailUrl), ThumbnailUrlLength),
|
ThumbnailUrl = Truncate(youTubeMusicService.ResolveArtworkUrl(song.ThumbnailUrl), ThumbnailUrlLength),
|
||||||
DurationSeconds = song.DurationSeconds,
|
DurationSeconds = song.DurationSeconds,
|
||||||
IsExplicit = song.IsExplicit
|
IsExplicit = song.IsExplicit
|
||||||
});
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
byArtist[seed.Id] = songs;
|
byArtist[seed.Id] = songs;
|
||||||
@@ -159,7 +159,7 @@ namespace Musify.Application.Mixes
|
|||||||
return byArtist;
|
return byArtist;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Dictionary<Guid, List<MixItem>>> GetLocalCandidatesAsync(
|
private async Task<Dictionary<Guid, List<MixItem>> > GetLocalCandidatesAsync(
|
||||||
IReadOnlyList<SeedArtist> seedArtists,
|
IReadOnlyList<SeedArtist> seedArtists,
|
||||||
IReadOnlyList<Guid> historyTrackIds,
|
IReadOnlyList<Guid> historyTrackIds,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
@@ -169,7 +169,7 @@ namespace Musify.Application.Mixes
|
|||||||
var links = await database.TrackArtists
|
var links = await database.TrackArtists
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.Where(trackArtist => artistIds.Contains(trackArtist.ArtistId) && !historyTrackIds.Contains(trackArtist.TrackId))
|
.Where(trackArtist => artistIds.Contains(trackArtist.ArtistId) && !historyTrackIds.Contains(trackArtist.TrackId))
|
||||||
.Select(trackArtist => new { trackArtist.ArtistId, trackArtist.TrackId })
|
.Select(trackArtist => new { trackArtist.ArtistId, trackArtist.TrackId } )
|
||||||
.ToListAsync(cancellationToken);
|
.ToListAsync(cancellationToken);
|
||||||
|
|
||||||
var trackIds = links.Select(link => link.TrackId).Distinct().ToList();
|
var trackIds = links.Select(link => link.TrackId).Distinct().ToList();
|
||||||
@@ -279,9 +279,9 @@ namespace Musify.Application.Mixes
|
|||||||
for (var index = 0; index < Math.Max(first.Count, second.Count); index++)
|
for (var index = 0; index < Math.Max(first.Count, second.Count); index++)
|
||||||
{
|
{
|
||||||
if (index < first.Count)
|
if (index < first.Count)
|
||||||
merged.Add(first[index]);
|
merged.Add(first[index] );
|
||||||
if (index < second.Count)
|
if (index < second.Count)
|
||||||
merged.Add(second[index]);
|
merged.Add(second[index] );
|
||||||
}
|
}
|
||||||
|
|
||||||
return merged;
|
return merged;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace Musify.Application.Mixes.Responses
|
|||||||
string Title,
|
string Title,
|
||||||
string? Artist,
|
string? Artist,
|
||||||
string? ThumbnailUrl,
|
string? ThumbnailUrl,
|
||||||
int DurationSeconds,
|
double DurationSeconds,
|
||||||
bool IsExplicit)
|
bool IsExplicit)
|
||||||
{
|
{
|
||||||
public static MixItemApplicationResponse FromEntity(MixItem item) =>
|
public static MixItemApplicationResponse FromEntity(MixItem item) =>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace Musify.Application.Tracks.Responses
|
|||||||
TrackSource Source,
|
TrackSource Source,
|
||||||
string? ExternalId,
|
string? ExternalId,
|
||||||
ProcessingStatus AudioStatus,
|
ProcessingStatus AudioStatus,
|
||||||
int Duration,
|
double Duration,
|
||||||
int ListensCount,
|
int ListensCount,
|
||||||
long? OwnerUserId,
|
long? OwnerUserId,
|
||||||
DateTime CreatedAt,
|
DateTime CreatedAt,
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ namespace Musify.Domain.Entities
|
|||||||
public string? ThumbnailUrl { get; set; }
|
public string? ThumbnailUrl { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public int DurationSeconds { get; set; } = 0;
|
public double DurationSeconds { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public bool IsExplicit { get; set; } = false;
|
public bool IsExplicit { get; set; }
|
||||||
|
|
||||||
[ForeignKey(nameof(MixId))]
|
[ForeignKey(nameof(MixId))]
|
||||||
public Mix Mix { get; set; }
|
public Mix Mix { get; set; }
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace Musify.Domain.Entities
|
|||||||
public required string NormalizedTitle { get; set; }
|
public required string NormalizedTitle { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public int DurationSeconds { get; set; }
|
public double DurationSeconds { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public LifeCycleStatus LifeCycleStatus { get; set; } = LifeCycleStatus.Active;
|
public LifeCycleStatus LifeCycleStatus { get; set; } = LifeCycleStatus.Active;
|
||||||
|
|||||||
+1
-1
@@ -47,7 +47,7 @@ namespace Musify.Infrastructure.MassTransit.Activities.Audio
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var durationSeconds = executeContext.GetVariable<int>(executeContext.Arguments.DurationSecondsVariable)
|
var durationSeconds = executeContext.GetVariable<double>(executeContext.Arguments.DurationSecondsVariable)
|
||||||
?? throw new InvalidOperationException($"Missing routing slip variable {executeContext.Arguments.DurationSecondsVariable}");
|
?? throw new InvalidOperationException($"Missing routing slip variable {executeContext.Arguments.DurationSecondsVariable}");
|
||||||
|
|
||||||
var log = new UpdateTrackAudioLog(
|
var log = new UpdateTrackAudioLog(
|
||||||
|
|||||||
@@ -3,5 +3,5 @@
|
|||||||
public record UpdateTrackAudioLog(
|
public record UpdateTrackAudioLog(
|
||||||
Guid TrackId,
|
Guid TrackId,
|
||||||
string? PreviousAudioFolderName,
|
string? PreviousAudioFolderName,
|
||||||
int PreviousDurationSeconds);
|
double PreviousDurationSeconds);
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+1178
File diff suppressed because it is too large
Load Diff
+22
@@ -0,0 +1,22 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Musify.Infrastructure.Persistence.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class DurationAsDouble : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -360,8 +360,8 @@ namespace Musify.Infrastructure.Persistence.Migrations
|
|||||||
.HasMaxLength(300)
|
.HasMaxLength(300)
|
||||||
.HasColumnType("character varying(300)");
|
.HasColumnType("character varying(300)");
|
||||||
|
|
||||||
b.Property<int>("DurationSeconds")
|
b.Property<double>("DurationSeconds")
|
||||||
.HasColumnType("integer");
|
.HasColumnType("double precision");
|
||||||
|
|
||||||
b.Property<bool>("IsExplicit")
|
b.Property<bool>("IsExplicit")
|
||||||
.HasColumnType("boolean");
|
.HasColumnType("boolean");
|
||||||
@@ -474,8 +474,8 @@ namespace Musify.Infrastructure.Persistence.Migrations
|
|||||||
b.Property<DateTime>("CreatedAt")
|
b.Property<DateTime>("CreatedAt")
|
||||||
.HasColumnType("timestamp with time zone");
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
b.Property<int>("DurationSeconds")
|
b.Property<double>("DurationSeconds")
|
||||||
.HasColumnType("integer");
|
.HasColumnType("double precision");
|
||||||
|
|
||||||
b.Property<int>("LifeCycleStatus")
|
b.Property<int>("LifeCycleStatus")
|
||||||
.HasColumnType("integer");
|
.HasColumnType("integer");
|
||||||
@@ -893,21 +893,25 @@ namespace Musify.Infrastructure.Persistence.Migrations
|
|||||||
.HasColumnType("uuid");
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
b1.Property<string>("LargeName")
|
b1.Property<string>("LargeName")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(64)
|
.HasMaxLength(64)
|
||||||
.HasColumnType("character varying(64)")
|
.HasColumnType("character varying(64)")
|
||||||
.HasColumnName("LargePictureName");
|
.HasColumnName("LargePictureName");
|
||||||
|
|
||||||
b1.Property<string>("MediumName")
|
b1.Property<string>("MediumName")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(64)
|
.HasMaxLength(64)
|
||||||
.HasColumnType("character varying(64)")
|
.HasColumnType("character varying(64)")
|
||||||
.HasColumnName("MediumPictureName");
|
.HasColumnName("MediumPictureName");
|
||||||
|
|
||||||
b1.Property<string>("OriginalName")
|
b1.Property<string>("OriginalName")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(64)
|
.HasMaxLength(64)
|
||||||
.HasColumnType("character varying(64)")
|
.HasColumnType("character varying(64)")
|
||||||
.HasColumnName("OriginalPictureName");
|
.HasColumnName("OriginalPictureName");
|
||||||
|
|
||||||
b1.Property<string>("SmallName")
|
b1.Property<string>("SmallName")
|
||||||
|
.IsRequired()
|
||||||
.HasMaxLength(64)
|
.HasMaxLength(64)
|
||||||
.HasColumnType("character varying(64)")
|
.HasColumnType("character varying(64)")
|
||||||
.HasColumnName("SmallPictureName");
|
.HasColumnName("SmallPictureName");
|
||||||
|
|||||||
Reference in New Issue
Block a user