add multi collections (#315)

* start to add multi-collections

* create multi collection with no items

* edit multi collections

* fix plex credentials threading issue

* add playback order to multi collection items

* group episodes outside of shuffled enumerator

* move playback order onto each schedule item

* fix multi collection grouping

* update changelog
This commit is contained in:
Jason Dove
2021-07-17 21:45:41 -05:00
committed by GitHub
parent 4000c6bc0a
commit 632753ea93
87 changed files with 10828 additions and 197 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,125 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace ErsatzTV.Infrastructure.Migrations
{
public partial class Add_MultiCollection : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "MultiCollectionId",
table: "ProgramScheduleItem",
type: "INTEGER",
nullable: true);
migrationBuilder.AddColumn<int>(
name: "MultiCollectionId",
table: "PlayoutProgramScheduleAnchor",
type: "INTEGER",
nullable: true);
migrationBuilder.CreateTable(
name: "MultiCollection",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Name = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_MultiCollection", x => x.Id);
});
migrationBuilder.CreateTable(
name: "MultiCollectionItem",
columns: table => new
{
MultiCollectionId = table.Column<int>(type: "INTEGER", nullable: false),
CollectionId = table.Column<int>(type: "INTEGER", nullable: false),
ScheduleAsGroup = table.Column<bool>(type: "INTEGER", nullable: false),
PlaybackOrder = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_MultiCollectionItem", x => new { x.MultiCollectionId, x.CollectionId });
table.ForeignKey(
name: "FK_MultiCollectionItem_Collection_CollectionId",
column: x => x.CollectionId,
principalTable: "Collection",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_MultiCollectionItem_MultiCollection_MultiCollectionId",
column: x => x.MultiCollectionId,
principalTable: "MultiCollection",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_ProgramScheduleItem_MultiCollectionId",
table: "ProgramScheduleItem",
column: "MultiCollectionId");
migrationBuilder.CreateIndex(
name: "IX_PlayoutProgramScheduleAnchor_MultiCollectionId",
table: "PlayoutProgramScheduleAnchor",
column: "MultiCollectionId");
migrationBuilder.CreateIndex(
name: "IX_MultiCollectionItem_CollectionId",
table: "MultiCollectionItem",
column: "CollectionId");
migrationBuilder.AddForeignKey(
name: "FK_PlayoutProgramScheduleAnchor_MultiCollection_MultiCollectionId",
table: "PlayoutProgramScheduleAnchor",
column: "MultiCollectionId",
principalTable: "MultiCollection",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_ProgramScheduleItem_MultiCollection_MultiCollectionId",
table: "ProgramScheduleItem",
column: "MultiCollectionId",
principalTable: "MultiCollection",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_PlayoutProgramScheduleAnchor_MultiCollection_MultiCollectionId",
table: "PlayoutProgramScheduleAnchor");
migrationBuilder.DropForeignKey(
name: "FK_ProgramScheduleItem_MultiCollection_MultiCollectionId",
table: "ProgramScheduleItem");
migrationBuilder.DropTable(
name: "MultiCollectionItem");
migrationBuilder.DropTable(
name: "MultiCollection");
migrationBuilder.DropIndex(
name: "IX_ProgramScheduleItem_MultiCollectionId",
table: "ProgramScheduleItem");
migrationBuilder.DropIndex(
name: "IX_PlayoutProgramScheduleAnchor_MultiCollectionId",
table: "PlayoutProgramScheduleAnchor");
migrationBuilder.DropColumn(
name: "MultiCollectionId",
table: "ProgramScheduleItem");
migrationBuilder.DropColumn(
name: "MultiCollectionId",
table: "PlayoutProgramScheduleAnchor");
}
}
}
@@ -0,0 +1,27 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace ErsatzTV.Infrastructure.Migrations
{
public partial class Add_ProgramScheduleItemPlaybackOrder : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "PlaybackOrder",
table: "ProgramScheduleItem",
type: "INTEGER",
nullable: false,
defaultValue: 0);
migrationBuilder.Sql(
"UPDATE ProgramScheduleItem SET PlaybackOrder = (SELECT MediaCollectionPlaybackOrder FROM ProgramSchedule WHERE ProgramSchedule.Id = ProgramScheduleItem.ProgramScheduleId)");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "PlaybackOrder",
table: "ProgramScheduleItem");
}
}
}
@@ -0,0 +1,24 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace ErsatzTV.Infrastructure.Migrations
{
public partial class Remove_ProgramScheduleMediaCollectionPlaybackOrder : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "MediaCollectionPlaybackOrder",
table: "ProgramSchedule");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "MediaCollectionPlaybackOrder",
table: "ProgramSchedule",
type: "INTEGER",
nullable: false,
defaultValue: 0);
}
}
}
@@ -14,7 +14,7 @@ namespace ErsatzTV.Infrastructure.Migrations
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "5.0.7");
.HasAnnotation("ProductVersion", "5.0.8");
modelBuilder.Entity("ErsatzTV.Core.Domain.Actor", b =>
{
@@ -944,6 +944,41 @@ namespace ErsatzTV.Infrastructure.Migrations
b.ToTable("MovieMetadata");
});
modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollection", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Name")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("MultiCollection");
});
modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollectionItem", b =>
{
b.Property<int>("MultiCollectionId")
.HasColumnType("INTEGER");
b.Property<int>("CollectionId")
.HasColumnType("INTEGER");
b.Property<int>("PlaybackOrder")
.HasColumnType("INTEGER");
b.Property<bool>("ScheduleAsGroup")
.HasColumnType("INTEGER");
b.HasKey("MultiCollectionId", "CollectionId");
b.HasIndex("CollectionId");
b.ToTable("MultiCollectionItem");
});
modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoMetadata", b =>
{
b.Property<int>("Id")
@@ -1062,6 +1097,9 @@ namespace ErsatzTV.Infrastructure.Migrations
b.Property<int?>("MediaItemId")
.HasColumnType("INTEGER");
b.Property<int?>("MultiCollectionId")
.HasColumnType("INTEGER");
b.Property<int>("PlayoutId")
.HasColumnType("INTEGER");
@@ -1074,6 +1112,8 @@ namespace ErsatzTV.Infrastructure.Migrations
b.HasIndex("MediaItemId");
b.HasIndex("MultiCollectionId");
b.HasIndex("PlayoutId");
b.HasIndex("ProgramScheduleId");
@@ -1134,9 +1174,6 @@ namespace ErsatzTV.Infrastructure.Migrations
b.Property<bool>("KeepMultiPartEpisodesTogether")
.HasColumnType("INTEGER");
b.Property<int>("MediaCollectionPlaybackOrder")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.HasColumnType("TEXT");
@@ -1172,6 +1209,12 @@ namespace ErsatzTV.Infrastructure.Migrations
b.Property<int?>("MediaItemId")
.HasColumnType("INTEGER");
b.Property<int?>("MultiCollectionId")
.HasColumnType("INTEGER");
b.Property<int>("PlaybackOrder")
.HasColumnType("INTEGER");
b.Property<int>("ProgramScheduleId")
.HasColumnType("INTEGER");
@@ -1184,6 +1227,8 @@ namespace ErsatzTV.Infrastructure.Migrations
b.HasIndex("MediaItemId");
b.HasIndex("MultiCollectionId");
b.HasIndex("ProgramScheduleId");
b.ToTable("ProgramScheduleItem");
@@ -2156,6 +2201,25 @@ namespace ErsatzTV.Infrastructure.Migrations
b.Navigation("Movie");
});
modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollectionItem", b =>
{
b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection")
.WithMany("MultiCollectionItems")
.HasForeignKey("CollectionId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection")
.WithMany("MultiCollectionItems")
.HasForeignKey("MultiCollectionId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Collection");
b.Navigation("MultiCollection");
});
modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoMetadata", b =>
{
b.HasOne("ErsatzTV.Core.Domain.MusicVideo", "MusicVideo")
@@ -2257,6 +2321,11 @@ namespace ErsatzTV.Infrastructure.Migrations
.HasForeignKey("MediaItemId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection")
.WithMany()
.HasForeignKey("MultiCollectionId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout")
.WithMany("ProgramScheduleAnchors")
.HasForeignKey("PlayoutId")
@@ -2294,6 +2363,8 @@ namespace ErsatzTV.Infrastructure.Migrations
b.Navigation("MediaItem");
b.Navigation("MultiCollection");
b.Navigation("Playout");
b.Navigation("ProgramSchedule");
@@ -2333,6 +2404,11 @@ namespace ErsatzTV.Infrastructure.Migrations
.HasForeignKey("MediaItemId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection")
.WithMany()
.HasForeignKey("MultiCollectionId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("ErsatzTV.Core.Domain.ProgramSchedule", "ProgramSchedule")
.WithMany("Items")
.HasForeignKey("ProgramScheduleId")
@@ -2343,6 +2419,8 @@ namespace ErsatzTV.Infrastructure.Migrations
b.Navigation("MediaItem");
b.Navigation("MultiCollection");
b.Navigation("ProgramSchedule");
});
@@ -2781,6 +2859,8 @@ namespace ErsatzTV.Infrastructure.Migrations
modelBuilder.Entity("ErsatzTV.Core.Domain.Collection", b =>
{
b.Navigation("CollectionItems");
b.Navigation("MultiCollectionItems");
});
modelBuilder.Entity("ErsatzTV.Core.Domain.EpisodeMetadata", b =>
@@ -2850,6 +2930,11 @@ namespace ErsatzTV.Infrastructure.Migrations
b.Navigation("Writers");
});
modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollection", b =>
{
b.Navigation("MultiCollectionItems");
});
modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoMetadata", b =>
{
b.Navigation("Actors");