Logik zum Scannen von Songverzeichnissen und auslesen von MP3-Tags hinzugefügt
This commit is contained in:
parent
4fe401e360
commit
eef4754bb0
@ -1,7 +1,9 @@
|
|||||||
@page "/options/libraries"
|
@page "/options/libraries"
|
||||||
@using Microsoft.EntityFrameworkCore
|
@using Microsoft.EntityFrameworkCore
|
||||||
@using songrequests_blazor.Data
|
@using songrequests_blazor.Data
|
||||||
|
@using songrequests_blazor.Services
|
||||||
@inject Microsoft.EntityFrameworkCore.IDbContextFactory<LocalDbContext> DataContextFactory
|
@inject Microsoft.EntityFrameworkCore.IDbContextFactory<LocalDbContext> DataContextFactory
|
||||||
|
|
||||||
<h3>Bibliotheken</h3>
|
<h3>Bibliotheken</h3>
|
||||||
|
|
||||||
<a class="btn btn-primary mb-3" href="/options/libraries/edit">Bibliothek anlegen</a>
|
<a class="btn btn-primary mb-3" href="/options/libraries/edit">Bibliothek anlegen</a>
|
||||||
@ -12,6 +14,7 @@
|
|||||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||||
@itm.Name
|
@itm.Name
|
||||||
<div>
|
<div>
|
||||||
|
<button type="button" class="btn btn-secondary" @onclick="args => RunScan(itm)">Scan</button>
|
||||||
<a class="btn btn-primary" href="/options/libraries/edit/@itm.Id">Bearbeiten</a>
|
<a class="btn btn-primary" href="/options/libraries/edit/@itm.Id">Bearbeiten</a>
|
||||||
<button type="button" class="btn btn-secondary" @onclick="args => ShowDialog(itm)">Entfernen</button>
|
<button type="button" class="btn btn-secondary" @onclick="args => ShowDialog(itm)">Entfernen</button>
|
||||||
</div>
|
</div>
|
||||||
@ -61,6 +64,12 @@
|
|||||||
await modal.CloseAsync();
|
await modal.CloseAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void RunScan(Library itm)
|
||||||
|
{
|
||||||
|
ScanService.Queue.Add(itm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task RemoveItem()
|
private async Task RemoveItem()
|
||||||
{
|
{
|
||||||
if (ModalItem == null) return;
|
if (ModalItem == null) return;
|
||||||
|
|||||||
@ -46,6 +46,10 @@ namespace songrequests_blazor.Data
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<Song>(entity => {
|
||||||
|
entity.HasIndex(p => new { p.Library_ID, p.Uri}).IsUnique(); // Datei nur einmal pro Library in DB aufnehmen (eigentlich auch nur einmal insgesamt, aber wir haben hier derzeit keine n:m Beziehung
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
string AdminRoleGUID = "fc985a25-19ce-48ed-8443-c845f550960a";
|
string AdminRoleGUID = "fc985a25-19ce-48ed-8443-c845f550960a";
|
||||||
string AdminUserGUID = "5c2511d0-6a08-4950-babd-d107996749ba";
|
string AdminUserGUID = "5c2511d0-6a08-4950-babd-d107996749ba";
|
||||||
|
|||||||
@ -1,21 +1,26 @@
|
|||||||
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Composition;
|
||||||
using System.Configuration;
|
using System.Configuration;
|
||||||
|
using System.Drawing;
|
||||||
|
using TagLib;
|
||||||
|
|
||||||
namespace songrequests_blazor.Data
|
namespace songrequests_blazor.Data
|
||||||
{
|
{
|
||||||
public class Song
|
public class Song
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
public string Uri { get; set; } = null!;
|
public string Uri { get; set; } = null!;
|
||||||
|
|
||||||
// Tag-Parameter
|
// Tag-Parameter
|
||||||
public string Title { get; set; } = null!;
|
public string Title { get; set; } = null!;
|
||||||
public string? Artist { get; set; }
|
public string? Artist { get; set; }
|
||||||
public string? Album { get; set; }
|
public string? Album { get; set; }
|
||||||
public int? Year { get; set; }
|
public uint? Year { get; set; }
|
||||||
public string? Genre { get; set; }
|
public string? Genre { get; set; }
|
||||||
public TimeSpan Length { get; set; }
|
public long Length { get; set; }
|
||||||
|
public byte[]? Cover { get; set; }
|
||||||
|
|
||||||
|
|
||||||
// Statistics
|
// Statistics
|
||||||
@ -26,5 +31,20 @@ namespace songrequests_blazor.Data
|
|||||||
|
|
||||||
public virtual List<QueuedSong>? Queued { get; set; }
|
public virtual List<QueuedSong>? Queued { get; set; }
|
||||||
|
|
||||||
|
public static Song FromFile(string filename)
|
||||||
|
{
|
||||||
|
var mp3file = TagLib.File.Create(filename);
|
||||||
|
Song song = new();
|
||||||
|
song.Uri = filename;
|
||||||
|
song.Title = mp3file.Tag.Title;
|
||||||
|
song.Artist = mp3file.Tag.FirstPerformer;
|
||||||
|
song.Album = mp3file.Tag.Album;
|
||||||
|
if (mp3file.Tag.Year > 0) song.Year = mp3file.Tag.Year;
|
||||||
|
song.Genre = mp3file.Tag.FirstGenre;
|
||||||
|
song.Length = mp3file.Length;
|
||||||
|
song.Cover = mp3file.Tag.Pictures.Where(p => p.Type == PictureType.FrontCover).FirstOrDefault()?.Data.ToArray();
|
||||||
|
return song;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
562
songrequests_blazor/Migrations/20240630183539_ModifiedSongsAddedCoverAndMore.Designer.cs
generated
Normal file
562
songrequests_blazor/Migrations/20240630183539_ModifiedSongsAddedCoverAndMore.Designer.cs
generated
Normal file
@ -0,0 +1,562 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using songrequests_blazor.Data;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace songrequests_blazor.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(LocalDbContext))]
|
||||||
|
[Migration("20240630183539_ModifiedSongsAddedCoverAndMore")]
|
||||||
|
partial class ModifiedSongsAddedCoverAndMore
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder.HasAnnotation("ProductVersion", "8.0.5");
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("RoleNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoles", (string)null);
|
||||||
|
|
||||||
|
b.HasData(
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = "fc985a25-19ce-48ed-8443-c845f550960a",
|
||||||
|
Name = "Administrator",
|
||||||
|
NormalizedName = "ADMINISTRATOR"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoleClaims", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("AccessFailedCount")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Discriminator")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(13)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("EmailConfirmed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("LockoutEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedEmail")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedUserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumber")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("PhoneNumberConfirmed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("SecurityStamp")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("TwoFactorEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedEmail")
|
||||||
|
.HasDatabaseName("EmailIndex");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedUserName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("UserNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUsers", (string)null);
|
||||||
|
|
||||||
|
b.HasDiscriminator<string>("Discriminator").HasValue("IdentityUser");
|
||||||
|
|
||||||
|
b.UseTphMappingStrategy();
|
||||||
|
|
||||||
|
b.HasData(
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = "5c2511d0-6a08-4950-babd-d107996749ba",
|
||||||
|
AccessFailedCount = 0,
|
||||||
|
ConcurrencyStamp = "704e6e3c-2a36-4fda-b08b-eee6df96c7bd",
|
||||||
|
Email = "admin@admin.com",
|
||||||
|
EmailConfirmed = false,
|
||||||
|
LockoutEnabled = false,
|
||||||
|
NormalizedEmail = "ADMIN@ADMIN.COM",
|
||||||
|
NormalizedUserName = "ADMIN@ADMIN.COM",
|
||||||
|
PasswordHash = "AQAAAAIAAYagAAAAEOdhfzdMz0IiXP6IAztlTIpZmIu/kd+Oe6NOtPF4qDu+d22cPQt6qlepPZxXL5jj4g==",
|
||||||
|
PhoneNumberConfirmed = false,
|
||||||
|
SecurityStamp = "24955bec-23c8-4bc6-bef3-e7d848e2b6ec",
|
||||||
|
TwoFactorEnabled = false,
|
||||||
|
UserName = "admin@admin.com"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserClaims", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderKey")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderDisplayName")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("LoginProvider", "ProviderKey");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserLogins", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserRoles", (string)null);
|
||||||
|
|
||||||
|
b.HasData(
|
||||||
|
new
|
||||||
|
{
|
||||||
|
UserId = "5c2511d0-6a08-4950-babd-d107996749ba",
|
||||||
|
RoleId = "fc985a25-19ce-48ed-8443-c845f550960a"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserTokens", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("QueuedSongs_UserVotes", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserVotesId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("VotedSongsId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("UserVotesId", "VotedSongsId");
|
||||||
|
|
||||||
|
b.HasIndex("VotedSongsId");
|
||||||
|
|
||||||
|
b.ToTable("QueuedSongs_UserVotes");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Sessions_Libraries", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("EnabledLibrariesId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("UsedInSessionsId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("EnabledLibrariesId", "UsedInSessionsId");
|
||||||
|
|
||||||
|
b.HasIndex("UsedInSessionsId");
|
||||||
|
|
||||||
|
b.ToTable("Sessions_Libraries");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.Library", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ScanPaths")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Type")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Libraries");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.QueuedSong", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Added")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("AddedBy_User_ID")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("Played")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Position")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Session_ID")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Song_ID")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AddedBy_User_ID");
|
||||||
|
|
||||||
|
b.HasIndex("Session_ID");
|
||||||
|
|
||||||
|
b.HasIndex("Song_ID");
|
||||||
|
|
||||||
|
b.ToTable("QueuedSongs");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.Session", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Created")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("SessionCode")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Sessions");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.Song", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Album")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Artist")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Cover")
|
||||||
|
.HasColumnType("BLOB");
|
||||||
|
|
||||||
|
b.Property<string>("Genre")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<long>("Length")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Library_ID")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("RequestCount")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Uri")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<uint?>("Year")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("Library_ID");
|
||||||
|
|
||||||
|
b.ToTable("Songs");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.User", b =>
|
||||||
|
{
|
||||||
|
b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser");
|
||||||
|
|
||||||
|
b.HasDiscriminator().HasValue("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("QueuedSongs_UserVotes", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("songrequests_blazor.Data.User", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserVotesId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("songrequests_blazor.Data.QueuedSong", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("VotedSongsId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Sessions_Libraries", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("songrequests_blazor.Data.Library", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("EnabledLibrariesId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("songrequests_blazor.Data.Session", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UsedInSessionsId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.QueuedSong", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("songrequests_blazor.Data.User", "AdddedBy")
|
||||||
|
.WithMany("AddedSongs")
|
||||||
|
.HasForeignKey("AddedBy_User_ID")
|
||||||
|
.HasConstraintName("FK_user_addedsongs");
|
||||||
|
|
||||||
|
b.HasOne("songrequests_blazor.Data.Session", "Session")
|
||||||
|
.WithMany("QueuedSongs")
|
||||||
|
.HasForeignKey("Session_ID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("FK_Session_QueuedSongs");
|
||||||
|
|
||||||
|
b.HasOne("songrequests_blazor.Data.Song", "Song")
|
||||||
|
.WithMany("Queued")
|
||||||
|
.HasForeignKey("Song_ID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("FK_queuedsongs_song");
|
||||||
|
|
||||||
|
b.Navigation("AdddedBy");
|
||||||
|
|
||||||
|
b.Navigation("Session");
|
||||||
|
|
||||||
|
b.Navigation("Song");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.Song", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("songrequests_blazor.Data.Library", "Library")
|
||||||
|
.WithMany("Songs")
|
||||||
|
.HasForeignKey("Library_ID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("FK_library_songs");
|
||||||
|
|
||||||
|
b.Navigation("Library");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.Library", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Songs");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.Session", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("QueuedSongs");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.Song", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Queued");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.User", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("AddedSongs");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace songrequests_blazor.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class ModifiedSongsAddedCoverAndMore : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AlterColumn<long>(
|
||||||
|
name: "Length",
|
||||||
|
table: "Songs",
|
||||||
|
type: "INTEGER",
|
||||||
|
nullable: false,
|
||||||
|
oldClrType: typeof(TimeSpan),
|
||||||
|
oldType: "TEXT");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<byte[]>(
|
||||||
|
name: "Cover",
|
||||||
|
table: "Songs",
|
||||||
|
type: "BLOB",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "AspNetUsers",
|
||||||
|
keyColumn: "Id",
|
||||||
|
keyValue: "5c2511d0-6a08-4950-babd-d107996749ba",
|
||||||
|
columns: new[] { "ConcurrencyStamp", "PasswordHash", "SecurityStamp" },
|
||||||
|
values: new object[] { "704e6e3c-2a36-4fda-b08b-eee6df96c7bd", "AQAAAAIAAYagAAAAEOdhfzdMz0IiXP6IAztlTIpZmIu/kd+Oe6NOtPF4qDu+d22cPQt6qlepPZxXL5jj4g==", "24955bec-23c8-4bc6-bef3-e7d848e2b6ec" });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Cover",
|
||||||
|
table: "Songs");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<TimeSpan>(
|
||||||
|
name: "Length",
|
||||||
|
table: "Songs",
|
||||||
|
type: "TEXT",
|
||||||
|
nullable: false,
|
||||||
|
oldClrType: typeof(long),
|
||||||
|
oldType: "INTEGER");
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "AspNetUsers",
|
||||||
|
keyColumn: "Id",
|
||||||
|
keyValue: "5c2511d0-6a08-4950-babd-d107996749ba",
|
||||||
|
columns: new[] { "ConcurrencyStamp", "PasswordHash", "SecurityStamp" },
|
||||||
|
values: new object[] { "7d7fc619-fde4-408c-8816-f4ed5f68a60e", "AQAAAAIAAYagAAAAECVwoHKYEXKRa9Sp3UeNNeVSEZOUkCEVkYcF09ZOVlLm9VeDEoX8M9NzwegIk0EWrw==", "10af871c-53d6-4dfc-9e69-5d3a97d8a016" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
563
songrequests_blazor/Migrations/20240630184246_AddUniqueKeyToSongs.Designer.cs
generated
Normal file
563
songrequests_blazor/Migrations/20240630184246_AddUniqueKeyToSongs.Designer.cs
generated
Normal file
@ -0,0 +1,563 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using songrequests_blazor.Data;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace songrequests_blazor.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(LocalDbContext))]
|
||||||
|
[Migration("20240630184246_AddUniqueKeyToSongs")]
|
||||||
|
partial class AddUniqueKeyToSongs
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder.HasAnnotation("ProductVersion", "8.0.5");
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("RoleNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoles", (string)null);
|
||||||
|
|
||||||
|
b.HasData(
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = "fc985a25-19ce-48ed-8443-c845f550960a",
|
||||||
|
Name = "Administrator",
|
||||||
|
NormalizedName = "ADMINISTRATOR"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoleClaims", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("AccessFailedCount")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Discriminator")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(13)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("EmailConfirmed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("LockoutEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedEmail")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedUserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumber")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("PhoneNumberConfirmed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("SecurityStamp")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("TwoFactorEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedEmail")
|
||||||
|
.HasDatabaseName("EmailIndex");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedUserName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("UserNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUsers", (string)null);
|
||||||
|
|
||||||
|
b.HasDiscriminator<string>("Discriminator").HasValue("IdentityUser");
|
||||||
|
|
||||||
|
b.UseTphMappingStrategy();
|
||||||
|
|
||||||
|
b.HasData(
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = "5c2511d0-6a08-4950-babd-d107996749ba",
|
||||||
|
AccessFailedCount = 0,
|
||||||
|
ConcurrencyStamp = "0f427274-c406-4fb7-a80f-91fa4fd57cf4",
|
||||||
|
Email = "admin@admin.com",
|
||||||
|
EmailConfirmed = false,
|
||||||
|
LockoutEnabled = false,
|
||||||
|
NormalizedEmail = "ADMIN@ADMIN.COM",
|
||||||
|
NormalizedUserName = "ADMIN@ADMIN.COM",
|
||||||
|
PasswordHash = "AQAAAAIAAYagAAAAEFZWcvwhuJu9C7uVvzbsmUQae3r6sY0py3xFCYortc/Hrb+P1p1fYsCBWp8PRGoIrA==",
|
||||||
|
PhoneNumberConfirmed = false,
|
||||||
|
SecurityStamp = "8fddb9be-4f1a-411b-9754-64eaef1bd3a3",
|
||||||
|
TwoFactorEnabled = false,
|
||||||
|
UserName = "admin@admin.com"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserClaims", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderKey")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderDisplayName")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("LoginProvider", "ProviderKey");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserLogins", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserRoles", (string)null);
|
||||||
|
|
||||||
|
b.HasData(
|
||||||
|
new
|
||||||
|
{
|
||||||
|
UserId = "5c2511d0-6a08-4950-babd-d107996749ba",
|
||||||
|
RoleId = "fc985a25-19ce-48ed-8443-c845f550960a"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserTokens", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("QueuedSongs_UserVotes", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserVotesId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("VotedSongsId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("UserVotesId", "VotedSongsId");
|
||||||
|
|
||||||
|
b.HasIndex("VotedSongsId");
|
||||||
|
|
||||||
|
b.ToTable("QueuedSongs_UserVotes");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Sessions_Libraries", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("EnabledLibrariesId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("UsedInSessionsId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("EnabledLibrariesId", "UsedInSessionsId");
|
||||||
|
|
||||||
|
b.HasIndex("UsedInSessionsId");
|
||||||
|
|
||||||
|
b.ToTable("Sessions_Libraries");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.Library", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ScanPaths")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Type")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Libraries");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.QueuedSong", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Added")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("AddedBy_User_ID")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("Played")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Position")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Session_ID")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Song_ID")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AddedBy_User_ID");
|
||||||
|
|
||||||
|
b.HasIndex("Session_ID");
|
||||||
|
|
||||||
|
b.HasIndex("Song_ID");
|
||||||
|
|
||||||
|
b.ToTable("QueuedSongs");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.Session", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Created")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("SessionCode")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Sessions");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.Song", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Album")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Artist")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Cover")
|
||||||
|
.HasColumnType("BLOB");
|
||||||
|
|
||||||
|
b.Property<string>("Genre")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<long>("Length")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Library_ID")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("RequestCount")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Uri")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<uint?>("Year")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("Library_ID", "Uri")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("Songs");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.User", b =>
|
||||||
|
{
|
||||||
|
b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser");
|
||||||
|
|
||||||
|
b.HasDiscriminator().HasValue("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("QueuedSongs_UserVotes", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("songrequests_blazor.Data.User", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserVotesId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("songrequests_blazor.Data.QueuedSong", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("VotedSongsId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Sessions_Libraries", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("songrequests_blazor.Data.Library", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("EnabledLibrariesId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("songrequests_blazor.Data.Session", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UsedInSessionsId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.QueuedSong", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("songrequests_blazor.Data.User", "AdddedBy")
|
||||||
|
.WithMany("AddedSongs")
|
||||||
|
.HasForeignKey("AddedBy_User_ID")
|
||||||
|
.HasConstraintName("FK_user_addedsongs");
|
||||||
|
|
||||||
|
b.HasOne("songrequests_blazor.Data.Session", "Session")
|
||||||
|
.WithMany("QueuedSongs")
|
||||||
|
.HasForeignKey("Session_ID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("FK_Session_QueuedSongs");
|
||||||
|
|
||||||
|
b.HasOne("songrequests_blazor.Data.Song", "Song")
|
||||||
|
.WithMany("Queued")
|
||||||
|
.HasForeignKey("Song_ID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("FK_queuedsongs_song");
|
||||||
|
|
||||||
|
b.Navigation("AdddedBy");
|
||||||
|
|
||||||
|
b.Navigation("Session");
|
||||||
|
|
||||||
|
b.Navigation("Song");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.Song", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("songrequests_blazor.Data.Library", "Library")
|
||||||
|
.WithMany("Songs")
|
||||||
|
.HasForeignKey("Library_ID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("FK_library_songs");
|
||||||
|
|
||||||
|
b.Navigation("Library");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.Library", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Songs");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.Session", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("QueuedSongs");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.Song", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Queued");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("songrequests_blazor.Data.User", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("AddedSongs");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace songrequests_blazor.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddUniqueKeyToSongs : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_Songs_Library_ID",
|
||||||
|
table: "Songs");
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "AspNetUsers",
|
||||||
|
keyColumn: "Id",
|
||||||
|
keyValue: "5c2511d0-6a08-4950-babd-d107996749ba",
|
||||||
|
columns: new[] { "ConcurrencyStamp", "PasswordHash", "SecurityStamp" },
|
||||||
|
values: new object[] { "0f427274-c406-4fb7-a80f-91fa4fd57cf4", "AQAAAAIAAYagAAAAEFZWcvwhuJu9C7uVvzbsmUQae3r6sY0py3xFCYortc/Hrb+P1p1fYsCBWp8PRGoIrA==", "8fddb9be-4f1a-411b-9754-64eaef1bd3a3" });
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Songs_Library_ID_Uri",
|
||||||
|
table: "Songs",
|
||||||
|
columns: new[] { "Library_ID", "Uri" },
|
||||||
|
unique: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_Songs_Library_ID_Uri",
|
||||||
|
table: "Songs");
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "AspNetUsers",
|
||||||
|
keyColumn: "Id",
|
||||||
|
keyValue: "5c2511d0-6a08-4950-babd-d107996749ba",
|
||||||
|
columns: new[] { "ConcurrencyStamp", "PasswordHash", "SecurityStamp" },
|
||||||
|
values: new object[] { "704e6e3c-2a36-4fda-b08b-eee6df96c7bd", "AQAAAAIAAYagAAAAEOdhfzdMz0IiXP6IAztlTIpZmIu/kd+Oe6NOtPF4qDu+d22cPQt6qlepPZxXL5jj4g==", "24955bec-23c8-4bc6-bef3-e7d848e2b6ec" });
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Songs_Library_ID",
|
||||||
|
table: "Songs",
|
||||||
|
column: "Library_ID");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -151,15 +151,15 @@ namespace songrequests_blazor.Migrations
|
|||||||
{
|
{
|
||||||
Id = "5c2511d0-6a08-4950-babd-d107996749ba",
|
Id = "5c2511d0-6a08-4950-babd-d107996749ba",
|
||||||
AccessFailedCount = 0,
|
AccessFailedCount = 0,
|
||||||
ConcurrencyStamp = "7d7fc619-fde4-408c-8816-f4ed5f68a60e",
|
ConcurrencyStamp = "0f427274-c406-4fb7-a80f-91fa4fd57cf4",
|
||||||
Email = "admin@admin.com",
|
Email = "admin@admin.com",
|
||||||
EmailConfirmed = false,
|
EmailConfirmed = false,
|
||||||
LockoutEnabled = false,
|
LockoutEnabled = false,
|
||||||
NormalizedEmail = "ADMIN@ADMIN.COM",
|
NormalizedEmail = "ADMIN@ADMIN.COM",
|
||||||
NormalizedUserName = "ADMIN@ADMIN.COM",
|
NormalizedUserName = "ADMIN@ADMIN.COM",
|
||||||
PasswordHash = "AQAAAAIAAYagAAAAECVwoHKYEXKRa9Sp3UeNNeVSEZOUkCEVkYcF09ZOVlLm9VeDEoX8M9NzwegIk0EWrw==",
|
PasswordHash = "AQAAAAIAAYagAAAAEFZWcvwhuJu9C7uVvzbsmUQae3r6sY0py3xFCYortc/Hrb+P1p1fYsCBWp8PRGoIrA==",
|
||||||
PhoneNumberConfirmed = false,
|
PhoneNumberConfirmed = false,
|
||||||
SecurityStamp = "10af871c-53d6-4dfc-9e69-5d3a97d8a016",
|
SecurityStamp = "8fddb9be-4f1a-411b-9754-64eaef1bd3a3",
|
||||||
TwoFactorEnabled = false,
|
TwoFactorEnabled = false,
|
||||||
UserName = "admin@admin.com"
|
UserName = "admin@admin.com"
|
||||||
});
|
});
|
||||||
@ -373,11 +373,14 @@ namespace songrequests_blazor.Migrations
|
|||||||
b.Property<string>("Artist")
|
b.Property<string>("Artist")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Cover")
|
||||||
|
.HasColumnType("BLOB");
|
||||||
|
|
||||||
b.Property<string>("Genre")
|
b.Property<string>("Genre")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<TimeSpan>("Length")
|
b.Property<long>("Length")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<int>("Library_ID")
|
b.Property<int>("Library_ID")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
@ -393,12 +396,13 @@ namespace songrequests_blazor.Migrations
|
|||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<int?>("Year")
|
b.Property<uint?>("Year")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.HasIndex("Library_ID");
|
b.HasIndex("Library_ID", "Uri")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
b.ToTable("Songs");
|
b.ToTable("Songs");
|
||||||
});
|
});
|
||||||
|
|||||||
@ -59,6 +59,11 @@ if (googleAuth != null)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Services
|
||||||
|
builder.Services.AddSingleton<IHostedService, ScanService>();
|
||||||
|
//builder.Services.AddHostedService<ScanService>();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
// Configure the HTTP request pipeline.
|
||||||
|
|||||||
91
songrequests_blazor/Services/ScanService.cs
Normal file
91
songrequests_blazor/Services/ScanService.cs
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
using System.IO;
|
||||||
|
using songrequests_blazor.Data;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace songrequests_blazor.Services
|
||||||
|
{
|
||||||
|
public class ScanService : IHostedService, IDisposable
|
||||||
|
{
|
||||||
|
public static BlockingCollection<Library> Queue { get; set; } = new();
|
||||||
|
|
||||||
|
IDbContextFactory<LocalDbContext> _dbContextFactory;
|
||||||
|
|
||||||
|
public ScanService(IDbContextFactory<LocalDbContext> contextFactory)
|
||||||
|
{
|
||||||
|
_dbContextFactory = contextFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddToQueue(Library itm)
|
||||||
|
{
|
||||||
|
if (itm.ScanPaths == null || itm.ScanPaths.Count == 0) return;
|
||||||
|
if (!Queue.Contains(itm)) Queue.Add(itm);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Queue.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Timer? timer;
|
||||||
|
|
||||||
|
public async Task StartAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
timer = new Timer(ScanFiles, cancellationToken, 0, 5000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task StopAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
// BlockingCollection leeren
|
||||||
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
while (Queue.TryTake(out _)) { }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void ScanFiles(object? state)
|
||||||
|
{
|
||||||
|
CancellationToken token;
|
||||||
|
if (state != null)
|
||||||
|
{
|
||||||
|
token = (CancellationToken)state;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
token = new CancellationTokenSource().Token;
|
||||||
|
}
|
||||||
|
while (Queue?.Count > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
Library lib = Queue.Take();
|
||||||
|
List<Song> files = new List<Song>();
|
||||||
|
foreach (var ScanPath in lib.ScanPaths ?? [])
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{DateTime.Now:g} Scanning {ScanPath}");
|
||||||
|
foreach (string file in Directory.GetFiles(ScanPath, "*.mp3", SearchOption.AllDirectories))
|
||||||
|
{
|
||||||
|
if (lib.Songs == null || !lib.Songs.Any(s => s.Uri.Trim().ToLower() == file.Trim().ToLower()))
|
||||||
|
{
|
||||||
|
var song = Song.FromFile(file);
|
||||||
|
song.Library = lib;
|
||||||
|
files.Add(song);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($"{DateTime.Now:g} Adding found files to library...");
|
||||||
|
using (LocalDbContext db = _dbContextFactory.CreateDbContext())
|
||||||
|
{
|
||||||
|
db.Libraries.Update(lib);
|
||||||
|
if (lib.Songs == null) lib.Songs = new();
|
||||||
|
lib.Songs.AddRange(files);
|
||||||
|
db.SaveChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
@ -22,6 +22,8 @@
|
|||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.2" />
|
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.2" />
|
||||||
<PackageReference Include="SpotifyAPI.Web" Version="7.1.1" />
|
<PackageReference Include="SpotifyAPI.Web" Version="7.1.1" />
|
||||||
|
<PackageReference Include="System.Drawing.Common" Version="8.0.6" />
|
||||||
|
<PackageReference Include="taglib-sharp-netstandard2.0" Version="2.1.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user