Browse Source

add wait until instruction (#1815)

pull/1816/head
Jason Dove 2 years 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;
using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Metadata;
using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Interfaces.Repositories;
using ErsatzTV.Core.Interfaces.Scheduling; using ErsatzTV.Core.Interfaces.Scheduling;
using LanguageExt.UnsafeValueAccess;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using YamlDotNet.Serialization; using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NamingConventions;
@ -36,12 +35,10 @@ public class YamlPlayoutBuilder(
return playout; return playout;
} }
// these are only for reset
playout.Seed = new Random().Next();
playout.Items.Clear();
DateTimeOffset currentTime = start; DateTimeOffset currentTime = start;
currentTime = HandleResetActions(playout, playoutDefinition, currentTime);
// load content and content enumerators on demand // load content and content enumerators on demand
Dictionary<string, IMediaCollectionEnumerator> enumerators = new(); Dictionary<string, IMediaCollectionEnumerator> enumerators = new();
System.Collections.Generic.HashSet<string> missingContentKeys = []; System.Collections.Generic.HashSet<string> missingContentKeys = [];
@ -58,18 +55,23 @@ public class YamlPlayoutBuilder(
YamlPlayoutInstruction playoutItem = playoutDefinition.Playout[index]; YamlPlayoutInstruction playoutItem = playoutDefinition.Playout[index];
// repeat resets index into YAML playout // handle instructions that don't reference content
if (playoutItem is YamlPlayoutRepeatInstruction) switch (playoutItem)
{ {
index = 0; case YamlPlayoutWaitUntilInstruction waitUntil:
if (playout.Items.Count == itemsAfterRepeat) currentTime = HandleWaitUntil(currentTime, waitUntil);
{
logger.LogWarning("Repeat encountered without adding any playout items; aborting");
break; 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; itemsAfterRepeat = playout.Items.Count;
continue; continue;
} }
Option<IMediaCollectionEnumerator> maybeEnumerator = await GetCachedEnumeratorForContent( Option<IMediaCollectionEnumerator> maybeEnumerator = await GetCachedEnumeratorForContent(
@ -132,6 +134,59 @@ public class YamlPlayoutBuilder(
return playout; 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() => private async Task<int> GetDaysToBuild() =>
await configElementRepository await configElementRepository
.GetValue<int>(ConfigElementKey.PlayoutDaysToBuild) .GetValue<int>(ConfigElementKey.PlayoutDaysToBuild)
@ -161,7 +216,7 @@ public class YamlPlayoutBuilder(
foreach (IMediaCollectionEnumerator e in maybeEnumerator) foreach (IMediaCollectionEnumerator e in maybeEnumerator)
{ {
enumerator = maybeEnumerator.ValueUnsafe(); enumerator = e;
enumerators.Add(contentKey, enumerator); enumerators.Add(contentKey, enumerator);
} }
} }
@ -231,7 +286,8 @@ public class YamlPlayoutBuilder(
{ "count", typeof(YamlPlayoutCountInstruction) }, { "count", typeof(YamlPlayoutCountInstruction) },
{ "duration", typeof(YamlPlayoutDurationInstruction) }, { "duration", typeof(YamlPlayoutDurationInstruction) },
{ "pad_to_next", typeof(YamlPlayoutPadToNextInstruction) }, { "pad_to_next", typeof(YamlPlayoutPadToNextInstruction) },
{ "repeat", typeof(YamlPlayoutRepeatInstruction) } { "repeat", typeof(YamlPlayoutRepeatInstruction) },
{ "wait_until", typeof(YamlPlayoutWaitUntilInstruction) }
}; };
o.AddUniqueKeyTypeDiscriminator<YamlPlayoutInstruction>(instructionKeyMappings); o.AddUniqueKeyTypeDiscriminator<YamlPlayoutInstruction>(instructionKeyMappings);

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

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

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

@ -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