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"
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using songrequests_blazor.Data
|
||||
@using songrequests_blazor.Services
|
||||
@inject Microsoft.EntityFrameworkCore.IDbContextFactory<LocalDbContext> DataContextFactory
|
||||
|
||||
<h3>Bibliotheken</h3>
|
||||
|
||||
<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">
|
||||
@itm.Name
|
||||
<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>
|
||||
<button type="button" class="btn btn-secondary" @onclick="args => ShowDialog(itm)">Entfernen</button>
|
||||
</div>
|
||||
@ -61,6 +64,12 @@
|
||||
await modal.CloseAsync();
|
||||
}
|
||||
|
||||
private void RunScan(Library itm)
|
||||
{
|
||||
ScanService.Queue.Add(itm);
|
||||
}
|
||||
|
||||
|
||||
private async Task RemoveItem()
|
||||
{
|
||||
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 AdminUserGUID = "5c2511d0-6a08-4950-babd-d107996749ba";
|
||||
|
||||
@ -1,21 +1,26 @@
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||
using System;
|
||||
using System.Composition;
|
||||
using System.Configuration;
|
||||
using System.Drawing;
|
||||
using TagLib;
|
||||
|
||||
namespace songrequests_blazor.Data
|
||||
{
|
||||
public class Song
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Uri { get; set; } = null!;
|
||||
|
||||
// Tag-Parameter
|
||||
public string Title { get; set; } = null!;
|
||||
public string? Artist { get; set; }
|
||||
public string? Album { get; set; }
|
||||
public int? Year { get; set; }
|
||||
public uint? Year { get; set; }
|
||||
public string? Genre { get; set; }
|
||||
public TimeSpan Length { get; set; }
|
||||
public long Length { get; set; }
|
||||
public byte[]? Cover { get; set; }
|
||||
|
||||
|
||||
// Statistics
|
||||
@ -26,5 +31,20 @@ namespace songrequests_blazor.Data
|
||||
|
||||
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",
|
||||
AccessFailedCount = 0,
|
||||
ConcurrencyStamp = "7d7fc619-fde4-408c-8816-f4ed5f68a60e",
|
||||
ConcurrencyStamp = "0f427274-c406-4fb7-a80f-91fa4fd57cf4",
|
||||
Email = "admin@admin.com",
|
||||
EmailConfirmed = false,
|
||||
LockoutEnabled = false,
|
||||
NormalizedEmail = "ADMIN@ADMIN.COM",
|
||||
NormalizedUserName = "ADMIN@ADMIN.COM",
|
||||
PasswordHash = "AQAAAAIAAYagAAAAECVwoHKYEXKRa9Sp3UeNNeVSEZOUkCEVkYcF09ZOVlLm9VeDEoX8M9NzwegIk0EWrw==",
|
||||
PasswordHash = "AQAAAAIAAYagAAAAEFZWcvwhuJu9C7uVvzbsmUQae3r6sY0py3xFCYortc/Hrb+P1p1fYsCBWp8PRGoIrA==",
|
||||
PhoneNumberConfirmed = false,
|
||||
SecurityStamp = "10af871c-53d6-4dfc-9e69-5d3a97d8a016",
|
||||
SecurityStamp = "8fddb9be-4f1a-411b-9754-64eaef1bd3a3",
|
||||
TwoFactorEnabled = false,
|
||||
UserName = "admin@admin.com"
|
||||
});
|
||||
@ -373,11 +373,14 @@ namespace songrequests_blazor.Migrations
|
||||
b.Property<string>("Artist")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<byte[]>("Cover")
|
||||
.HasColumnType("BLOB");
|
||||
|
||||
b.Property<string>("Genre")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<TimeSpan>("Length")
|
||||
.HasColumnType("TEXT");
|
||||
b.Property<long>("Length")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Library_ID")
|
||||
.HasColumnType("INTEGER");
|
||||
@ -393,12 +396,13 @@ namespace songrequests_blazor.Migrations
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("Year")
|
||||
b.Property<uint?>("Year")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Library_ID");
|
||||
b.HasIndex("Library_ID", "Uri")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Songs");
|
||||
});
|
||||
|
||||
@ -59,6 +59,11 @@ if (googleAuth != null)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Services
|
||||
builder.Services.AddSingleton<IHostedService, ScanService>();
|
||||
//builder.Services.AddHostedService<ScanService>();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// 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 Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.2" />
|
||||
<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>
|
||||
|
||||
</Project>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user