Browse Source

add wait until instruction (#1815)

pull/1816/head
Jason Dove 10 months ago committed by GitHub
parent
commit
b83fe53ef1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 88
      ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutBuilder.cs
  2. 3
      ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutDefinition.cs
  3. 10
      ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutWaitUntilInstruction.cs

88
ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutBuilder.cs

@ -2,7 +2,6 @@ using ErsatzTV.Core.Domain; @@ -2,7 +2,6 @@ using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Metadata;
using ErsatzTV.Core.Interfaces.Repositories;
using ErsatzTV.Core.Interfaces.Scheduling;
using LanguageExt.UnsafeValueAccess;
using Microsoft.Extensions.Logging;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
@ -36,12 +35,10 @@ public class YamlPlayoutBuilder( @@ -36,12 +35,10 @@ public class YamlPlayoutBuilder(
return playout;
}
// these are only for reset
playout.Seed = new Random().Next();
playout.Items.Clear();
DateTimeOffset currentTime = start;
currentTime = HandleResetActions(playout, playoutDefinition, currentTime);
// load content and content enumerators on demand
Dictionary<string, IMediaCollectionEnumerator> enumerators = new();
System.Collections.Generic.HashSet<string> missingContentKeys = [];
@ -58,18 +55,23 @@ public class YamlPlayoutBuilder( @@ -58,18 +55,23 @@ public class YamlPlayoutBuilder(
YamlPlayoutInstruction playoutItem = playoutDefinition.Playout[index];
// repeat resets index into YAML playout
if (playoutItem is YamlPlayoutRepeatInstruction)
// handle instructions that don't reference content
switch (playoutItem)
{
index = 0;
if (playout.Items.Count == itemsAfterRepeat)
{
logger.LogWarning("Repeat encountered without adding any playout items; aborting");
case YamlPlayoutWaitUntilInstruction waitUntil:
currentTime = HandleWaitUntil(currentTime, waitUntil);
break;
}
case YamlPlayoutRepeatInstruction:
// repeat resets index into YAML playout
index = 0;
if (playout.Items.Count == itemsAfterRepeat)
{
logger.LogWarning("Repeat encountered without adding any playout items; aborting");
break;
}
itemsAfterRepeat = playout.Items.Count;
continue;
itemsAfterRepeat = playout.Items.Count;
continue;
}
Option<IMediaCollectionEnumerator> maybeEnumerator = await GetCachedEnumeratorForContent(
@ -132,6 +134,59 @@ public class YamlPlayoutBuilder( @@ -132,6 +134,59 @@ public class YamlPlayoutBuilder(
return playout;
}
private DateTimeOffset HandleResetActions(
Playout playout,
YamlPlayoutDefinition playoutDefinition,
DateTimeOffset currentTime)
{
// these are only for reset
playout.Seed = new Random().Next();
playout.Items.Clear();
foreach (YamlPlayoutInstruction instruction in playoutDefinition.Reset)
{
switch (instruction)
{
case YamlPlayoutWaitUntilInstruction waitUntil:
currentTime = HandleWaitUntil(currentTime, waitUntil);
break;
default:
logger.LogInformation(
"Skipping unsupported reset instruction {Instruction}",
instruction.GetType().Name);
break;
}
}
return currentTime;
}
private static DateTimeOffset HandleWaitUntil(DateTimeOffset currentTime, YamlPlayoutWaitUntilInstruction waitUntil)
{
if (TimeOnly.TryParse(waitUntil.WaitUntil, out TimeOnly result))
{
var dayOnly = DateOnly.FromDateTime(currentTime.LocalDateTime);
var timeOnly = TimeOnly.FromDateTime(currentTime.LocalDateTime);
if (timeOnly > result)
{
if (waitUntil.Tomorrow)
{
// this is wrong when offset changes
dayOnly = dayOnly.AddDays(1);
currentTime = new DateTimeOffset(dayOnly, result, currentTime.Offset);
}
}
else
{
// this is wrong when offset changes
currentTime = new DateTimeOffset(dayOnly, result, currentTime.Offset);
}
}
return currentTime;
}
private async Task<int> GetDaysToBuild() =>
await configElementRepository
.GetValue<int>(ConfigElementKey.PlayoutDaysToBuild)
@ -161,7 +216,7 @@ public class YamlPlayoutBuilder( @@ -161,7 +216,7 @@ public class YamlPlayoutBuilder(
foreach (IMediaCollectionEnumerator e in maybeEnumerator)
{
enumerator = maybeEnumerator.ValueUnsafe();
enumerator = e;
enumerators.Add(contentKey, enumerator);
}
}
@ -231,7 +286,8 @@ public class YamlPlayoutBuilder( @@ -231,7 +286,8 @@ public class YamlPlayoutBuilder(
{ "count", typeof(YamlPlayoutCountInstruction) },
{ "duration", typeof(YamlPlayoutDurationInstruction) },
{ "pad_to_next", typeof(YamlPlayoutPadToNextInstruction) },
{ "repeat", typeof(YamlPlayoutRepeatInstruction) }
{ "repeat", typeof(YamlPlayoutRepeatInstruction) },
{ "wait_until", typeof(YamlPlayoutWaitUntilInstruction) }
};
o.AddUniqueKeyTypeDiscriminator<YamlPlayoutInstruction>(instructionKeyMappings);

3
ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutDefinition.cs

@ -3,5 +3,8 @@ namespace ErsatzTV.Core.Scheduling.YamlScheduling; @@ -3,5 +3,8 @@ namespace ErsatzTV.Core.Scheduling.YamlScheduling;
public class YamlPlayoutDefinition
{
public List<YamlPlayoutContentItem> Content { get; set; } = [];
public List<YamlPlayoutInstruction> Reset { get; set; } = [];
public List<YamlPlayoutInstruction> Playout { get; set; } = [];
}

10
ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutWaitUntilInstruction.cs

@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
using YamlDotNet.Serialization;
namespace ErsatzTV.Core.Scheduling.YamlScheduling;
public class YamlPlayoutWaitUntilInstruction : YamlPlayoutInstruction
{
[YamlMember(Alias = "wait_until", ApplyNamingConventions = false)]
public string WaitUntil { get; set; }
public bool Tomorrow { get; set; }
}
Loading…
Cancel
Save