From 7457301d3e9369b8f9188face4b0ed93b288d416 Mon Sep 17 00:00:00 2001 From: Jason Dove <1695733+jasongdove@users.noreply.github.com> Date: Sun, 29 Jun 2025 14:31:56 +0000 Subject: [PATCH] yaml playout skip items expression (#2092) --- CHANGELOG.md | 8 +++++ .../Handlers/YamlPlayoutSkipItemsHandler.cs | 35 +++++++++++++++---- .../Models/YamlPlayoutSkipItemsInstruction.cs | 2 +- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5995e72..0177e8bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - The current time (as a decimal) can also be used in the expression, e.g. `now > 23` - `now = hours + minutes / 60.0 + seconds / 3600.0` - So `10:30 AM` would be `10.5`, `10:45 PM` would be `22.75`, etc +- YAML playout: make `skip_items` an expression + - The following parameters can be used: + - `count`: the total number of items in the content + - `random`: a random number between zero and (count - 1) + - For example: + - `count / 2` will start in the middle of the content + - `random` will start at a random point in the content + - `2` (similar to before this change) will skip the first two items in the content ### Changed - Allow `Other Video` libraries and `Image` libraries to use the same folders diff --git a/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutSkipItemsHandler.cs b/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutSkipItemsHandler.cs index c83e92bd..ad44ea69 100644 --- a/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutSkipItemsHandler.cs +++ b/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutSkipItemsHandler.cs @@ -20,12 +20,6 @@ public class YamlPlayoutSkipItemsHandler(EnumeratorCache enumeratorCache) : IYam return false; } - if (skipItems.SkipItems < 0) - { - logger.LogWarning("Unable to skip invalid number: {Skip}", skipItems.SkipItems); - return false; - } - Option maybeEnumerator = await enumeratorCache.GetCachedEnumeratorForContent( context, skipItems.Content, @@ -33,7 +27,34 @@ public class YamlPlayoutSkipItemsHandler(EnumeratorCache enumeratorCache) : IYam foreach (IMediaCollectionEnumerator enumerator in maybeEnumerator) { - for (var i = 0; i < skipItems.SkipItems; i++) + var expression = new NCalc.Expression(skipItems.SkipItems); + expression.EvaluateParameter += (name, e) => + { + e.Result = name switch + { + "count" => enumerator.Count, + "random" => new Random().Next() % enumerator.Count, + _ => e.Result + }; + }; + + object expressionResult = expression.Evaluate(); + int skipCount = expressionResult switch + { + double doubleResult => (int)Math.Floor(doubleResult), + int intResult => intResult, + _ => 0 + }; + + skipCount %= enumerator.Count; + + if (skipCount < 0) + { + logger.LogWarning("Unable to skip invalid number: {Skip}", skipItems.SkipItems); + return false; + } + + for (var i = 0; i < skipCount; i++) { enumerator.MoveNext(); } diff --git a/ErsatzTV.Core/Scheduling/YamlScheduling/Models/YamlPlayoutSkipItemsInstruction.cs b/ErsatzTV.Core/Scheduling/YamlScheduling/Models/YamlPlayoutSkipItemsInstruction.cs index fbe2ad84..83f0bbbc 100644 --- a/ErsatzTV.Core/Scheduling/YamlScheduling/Models/YamlPlayoutSkipItemsInstruction.cs +++ b/ErsatzTV.Core/Scheduling/YamlScheduling/Models/YamlPlayoutSkipItemsInstruction.cs @@ -5,5 +5,5 @@ namespace ErsatzTV.Core.Scheduling.YamlScheduling.Models; public class YamlPlayoutSkipItemsInstruction : YamlPlayoutInstruction { [YamlMember(Alias = "skip_items", ApplyNamingConventions = false)] - public int SkipItems { get; set; } + public string SkipItems { get; set; } }