From d78daf8735c85618d2083b6925b41f997d9c01a4 Mon Sep 17 00:00:00 2001 From: Jason Dove Date: Fri, 13 May 2022 15:31:04 -0500 Subject: [PATCH] fix flood checkpoints (#803) --- CHANGELOG.md | 1 + .../Scheduling/PlayoutBuilderTests.cs | 134 ++++++++++++++++++ .../Scheduling/PlayoutModeSchedulerFlood.cs | 6 +- 3 files changed, 140 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 419a3244e..29316db04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Fix some instances of filler getting "stuck" when a filler item is encountered that's too long for the gap - Properly ignore Plex `Other Videos` libraries (`movie` libraries where agent is `com.plexapp.agents.none`) - Fix `Custom Title` for schedule items with `One`, `Multiple` and `Flood` playout modes +- Fix scheduling bug where flood items would sometimes fail to continue after midnight ### Added - Add `metadata_kind` field to search index to allow searching for items with a particular metdata source diff --git a/ErsatzTV.Core.Tests/Scheduling/PlayoutBuilderTests.cs b/ErsatzTV.Core.Tests/Scheduling/PlayoutBuilderTests.cs index 8d89c9853..32af4d16e 100644 --- a/ErsatzTV.Core.Tests/Scheduling/PlayoutBuilderTests.cs +++ b/ErsatzTV.Core.Tests/Scheduling/PlayoutBuilderTests.cs @@ -550,6 +550,140 @@ public class PlayoutBuilderTests result.Items[4].MediaItemId.Should().Be(2); } + [Test] + public async Task FloodContent_Should_FloodAroundFixedContent_One_Multiple_Days() + { + var floodCollection = new Collection + { + Id = 1, + Name = "Flood Items", + MediaItems = new List + { + TestMovie(1, TimeSpan.FromHours(1), new DateTime(2020, 1, 1)), + TestMovie(2, TimeSpan.FromHours(1), new DateTime(2020, 2, 1)) + } + }; + + var fixedCollection = new Collection + { + Id = 2, + Name = "Fixed Items", + MediaItems = new List + { + TestMovie(3, TimeSpan.FromHours(2), new DateTime(2020, 1, 1)) + } + }; + + var fakeRepository = new FakeMediaCollectionRepository( + Map( + (floodCollection.Id, floodCollection.MediaItems.ToList()), + (fixedCollection.Id, fixedCollection.MediaItems.ToList()))); + + var items = new List + { + new ProgramScheduleItemFlood + { + Index = 1, + Collection = floodCollection, + CollectionId = floodCollection.Id, + StartTime = null, + PlaybackOrder = PlaybackOrder.Chronological + }, + new ProgramScheduleItemOne + { + Index = 2, + Collection = fixedCollection, + CollectionId = fixedCollection.Id, + StartTime = TimeSpan.FromHours(3), + PlaybackOrder = PlaybackOrder.Chronological + } + }; + + var playout = new Playout + { + ProgramSchedule = new ProgramSchedule + { + Items = items + }, + Channel = new Channel(Guid.Empty) { Id = 1, Name = "Test Channel" }, + ProgramScheduleAnchors = new List(), + Items = new List() + }; + + var configRepo = new Mock(); + var televisionRepo = new FakeTelevisionRepository(); + var artistRepo = new Mock(); + var builder = new PlayoutBuilder( + configRepo.Object, + fakeRepository, + televisionRepo, + artistRepo.Object, + _logger); + + DateTimeOffset start = HoursAfterMidnight(0); + DateTimeOffset finish = start + TimeSpan.FromHours(30); + + Playout result = await builder.Build(playout, PlayoutBuildMode.Reset, start, finish); + + result.Items.Count.Should().Be(28); + result.Items[0].StartOffset.TimeOfDay.Should().Be(TimeSpan.Zero); + result.Items[0].MediaItemId.Should().Be(1); + result.Items[1].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(1)); + result.Items[1].MediaItemId.Should().Be(2); + result.Items[2].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(2)); + result.Items[2].MediaItemId.Should().Be(1); + result.Items[3].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(3)); + result.Items[3].MediaItemId.Should().Be(3); + result.Items[4].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(5)); + result.Items[4].MediaItemId.Should().Be(2); + result.Items[5].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(6)); + result.Items[5].MediaItemId.Should().Be(1); + result.Items[6].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(7)); + result.Items[6].MediaItemId.Should().Be(2); + result.Items[7].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(8)); + result.Items[7].MediaItemId.Should().Be(1); + result.Items[8].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(9)); + result.Items[8].MediaItemId.Should().Be(2); + result.Items[9].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(10)); + result.Items[9].MediaItemId.Should().Be(1); + result.Items[10].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(11)); + result.Items[10].MediaItemId.Should().Be(2); + result.Items[11].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(12)); + result.Items[11].MediaItemId.Should().Be(1); + result.Items[12].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(13)); + result.Items[12].MediaItemId.Should().Be(2); + result.Items[13].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(14)); + result.Items[13].MediaItemId.Should().Be(1); + result.Items[14].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(15)); + result.Items[14].MediaItemId.Should().Be(2); + result.Items[15].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(16)); + result.Items[15].MediaItemId.Should().Be(1); + result.Items[16].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(17)); + result.Items[16].MediaItemId.Should().Be(2); + result.Items[17].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(18)); + result.Items[17].MediaItemId.Should().Be(1); + result.Items[18].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(19)); + result.Items[18].MediaItemId.Should().Be(2); + result.Items[19].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(20)); + result.Items[19].MediaItemId.Should().Be(1); + result.Items[20].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(21)); + result.Items[20].MediaItemId.Should().Be(2); + result.Items[21].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(22)); + result.Items[21].MediaItemId.Should().Be(1); + result.Items[22].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(23)); + result.Items[22].MediaItemId.Should().Be(2); + result.Items[23].StartOffset.TimeOfDay.Should().Be(TimeSpan.Zero); + result.Items[23].MediaItemId.Should().Be(1); + result.Items[24].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(1)); + result.Items[24].MediaItemId.Should().Be(2); + result.Items[25].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(2)); + result.Items[25].MediaItemId.Should().Be(1); + result.Items[26].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(3)); + result.Items[26].MediaItemId.Should().Be(3); + result.Items[27].StartOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(5)); + result.Items[27].MediaItemId.Should().Be(2); + } + [Test] public async Task FloodContent_Should_FloodAroundFixedContent_Multiple() { diff --git a/ErsatzTV.Core/Scheduling/PlayoutModeSchedulerFlood.cs b/ErsatzTV.Core/Scheduling/PlayoutModeSchedulerFlood.cs index 4f25807ce..85ab481de 100644 --- a/ErsatzTV.Core/Scheduling/PlayoutModeSchedulerFlood.cs +++ b/ErsatzTV.Core/Scheduling/PlayoutModeSchedulerFlood.cs @@ -120,7 +120,11 @@ public class PlayoutModeSchedulerFlood : PlayoutModeSchedulerBase