From 57e9b4d264870aad883725af217a9222dbce983c Mon Sep 17 00:00:00 2001 From: Jason Dove <1695733+jasongdove@users.noreply.github.com> Date: Thu, 4 Sep 2025 13:00:48 -0500 Subject: [PATCH] more api docs (#2375) --- .../AddCollectionRequestModel.cs | 7 +++++ .../AddMarathonRequestModel.cs | 18 ++++++++++++ .../AddMultiCollectionRequestModel.cs | 7 +++++ .../AddPlaylistRequestModel.cs | 7 +++++ .../AddSearchQueryRequestModel.cs | 8 +++++ .../ScriptedPlayout/AddShowRequestModel.cs | 7 +++++ .../AddSmartCollectionRequestModel.cs | 7 +++++ .../GraphicsOffRequestModel.cs | 3 ++ .../ScriptedPlayout/GraphicsOnRequestModel.cs | 4 +++ .../ScriptedPlayout/SkipItemsRequestModel.cs | 5 ++++ .../ScriptedPlayout/SkipToItemRequestModel.cs | 7 +++++ .../StartEpgGroupRequestModel.cs | 3 ++ .../ScriptedPlayout/WaitUntilRequestModel.cs | 7 +++++ .../WatermarkOffRequestModel.cs | 3 ++ .../WatermarkOnRequestModel.cs | 3 ++ .../Api/ScriptedScheduleController.cs | 29 +++++++++++++++++-- 16 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 ErsatzTV.Core/Api/ScriptedPlayout/AddSearchQueryRequestModel.cs diff --git a/ErsatzTV.Core/Api/ScriptedPlayout/AddCollectionRequestModel.cs b/ErsatzTV.Core/Api/ScriptedPlayout/AddCollectionRequestModel.cs index 381382aec..23fadd646 100644 --- a/ErsatzTV.Core/Api/ScriptedPlayout/AddCollectionRequestModel.cs +++ b/ErsatzTV.Core/Api/ScriptedPlayout/AddCollectionRequestModel.cs @@ -1,8 +1,15 @@ +using System.ComponentModel; + namespace ErsatzTV.Core.Api.ScriptedPlayout; public record AddCollectionRequestModel { + [Description("Unique name used to reference this content throughout the scripted schedule")] public string Key { get; init; } + + [Description("The name of the existing manual collection")] public string Collection { get; init; } + + [Description("The playback order; only chronological and shuffle are currently supported")] public string Order { get; init; } = "shuffle"; } diff --git a/ErsatzTV.Core/Api/ScriptedPlayout/AddMarathonRequestModel.cs b/ErsatzTV.Core/Api/ScriptedPlayout/AddMarathonRequestModel.cs index e6dd598ee..d73b4e472 100644 --- a/ErsatzTV.Core/Api/ScriptedPlayout/AddMarathonRequestModel.cs +++ b/ErsatzTV.Core/Api/ScriptedPlayout/AddMarathonRequestModel.cs @@ -1,12 +1,30 @@ +using System.ComponentModel; + namespace ErsatzTV.Core.Api.ScriptedPlayout; public record AddMarathonRequestModel { + [Description("Unique name used to reference this content throughout the scripted schedule")] public string Key { get; set; } + + [Description( + "Tells the scheduler how to group the combined content (returned from all guids and searches). Valid values are show, season, artist and album.")] public string GroupBy { get; set; } + + [Description("Playback order within each group; only chronological and shuffle are currently supported")] public string ItemOrder { get; set; } = "shuffle"; + + [Description("List of external content identifiers")] public Dictionary> Guids { get; set; } = []; + + [Description("List of search queries")] public List Searches { get; set; } = []; + + [Description( + "When true, will add every item from a group before moving to the next group. When false, will play one item from a group before moving to the next group.")] public bool PlayAllItems { get; set; } + + [Description( + "When true, will randomize the order of groups. When false, will cycle through groups in a fixed order.")] public bool ShuffleGroups { get; set; } } diff --git a/ErsatzTV.Core/Api/ScriptedPlayout/AddMultiCollectionRequestModel.cs b/ErsatzTV.Core/Api/ScriptedPlayout/AddMultiCollectionRequestModel.cs index ffe16d02c..0568d34a0 100644 --- a/ErsatzTV.Core/Api/ScriptedPlayout/AddMultiCollectionRequestModel.cs +++ b/ErsatzTV.Core/Api/ScriptedPlayout/AddMultiCollectionRequestModel.cs @@ -1,8 +1,15 @@ +using System.ComponentModel; + namespace ErsatzTV.Core.Api.ScriptedPlayout; public record AddMultiCollectionRequestModel { + [Description("Unique name used to reference this content throughout the scripted schedule")] public string Key { get; set; } + + [Description("The name of the existing multi-collection")] public string MultiCollection { get; set; } + + [Description("The playback order; only chronological and shuffle are currently supported")] public string Order { get; set; } = "shuffle"; } diff --git a/ErsatzTV.Core/Api/ScriptedPlayout/AddPlaylistRequestModel.cs b/ErsatzTV.Core/Api/ScriptedPlayout/AddPlaylistRequestModel.cs index 7f8ee2e6a..5dd419ece 100644 --- a/ErsatzTV.Core/Api/ScriptedPlayout/AddPlaylistRequestModel.cs +++ b/ErsatzTV.Core/Api/ScriptedPlayout/AddPlaylistRequestModel.cs @@ -1,8 +1,15 @@ +using System.ComponentModel; + namespace ErsatzTV.Core.Api.ScriptedPlayout; public record AddPlaylistRequestModel { + [Description("Unique name used to reference this content throughout the scripted schedule")] public string Key { get; set; } + + [Description("The name of the existing playlist")] public string Playlist { get; set; } + + [Description("The name of the existing playlist group that contains the named playlist")] public string PlaylistGroup { get; set; } } diff --git a/ErsatzTV.Core/Api/ScriptedPlayout/AddSearchQueryRequestModel.cs b/ErsatzTV.Core/Api/ScriptedPlayout/AddSearchQueryRequestModel.cs new file mode 100644 index 000000000..4428466a6 --- /dev/null +++ b/ErsatzTV.Core/Api/ScriptedPlayout/AddSearchQueryRequestModel.cs @@ -0,0 +1,8 @@ +namespace ErsatzTV.Core.Api.ScriptedPlayout; + +public record AddSearchQueryRequestModel +{ + public string Key { get; set; } + public string Query { get; set; } + public string Order { get; set; } = "shuffle"; +} diff --git a/ErsatzTV.Core/Api/ScriptedPlayout/AddShowRequestModel.cs b/ErsatzTV.Core/Api/ScriptedPlayout/AddShowRequestModel.cs index dbd600e6a..3a3f4510b 100644 --- a/ErsatzTV.Core/Api/ScriptedPlayout/AddShowRequestModel.cs +++ b/ErsatzTV.Core/Api/ScriptedPlayout/AddShowRequestModel.cs @@ -1,8 +1,15 @@ +using System.ComponentModel; + namespace ErsatzTV.Core.Api.ScriptedPlayout; public record AddShowRequestModel { + [Description("Unique name used to reference this content throughout the scripted schedule")] public string Key { get; set; } + + [Description("List of show identifiers")] public Dictionary Guids { get; set; } = []; + + [Description("The playback order; only chronological and shuffle are currently supported")] public string Order { get; set; } = "shuffle"; } diff --git a/ErsatzTV.Core/Api/ScriptedPlayout/AddSmartCollectionRequestModel.cs b/ErsatzTV.Core/Api/ScriptedPlayout/AddSmartCollectionRequestModel.cs index 59e0d7c99..de1fd88af 100644 --- a/ErsatzTV.Core/Api/ScriptedPlayout/AddSmartCollectionRequestModel.cs +++ b/ErsatzTV.Core/Api/ScriptedPlayout/AddSmartCollectionRequestModel.cs @@ -1,8 +1,15 @@ +using System.ComponentModel; + namespace ErsatzTV.Core.Api.ScriptedPlayout; public record AddSmartCollectionRequestModel { + [Description("Unique name used to reference this content throughout the scripted schedule")] public string Key { get; set; } + + [Description("The name of the existing smart collection")] public string SmartCollection { get; set; } + + [Description("The playback order; only chronological and shuffle are currently supported")] public string Order { get; set; } = "shuffle"; } diff --git a/ErsatzTV.Core/Api/ScriptedPlayout/GraphicsOffRequestModel.cs b/ErsatzTV.Core/Api/ScriptedPlayout/GraphicsOffRequestModel.cs index cc2668b61..36a20c380 100644 --- a/ErsatzTV.Core/Api/ScriptedPlayout/GraphicsOffRequestModel.cs +++ b/ErsatzTV.Core/Api/ScriptedPlayout/GraphicsOffRequestModel.cs @@ -1,6 +1,9 @@ +using System.ComponentModel; + namespace ErsatzTV.Core.Api.ScriptedPlayout; public record GraphicsOffRequestModel { + [Description("A list of graphics elements to turn off. All graphics elements will be turned off if this list is null or empty")] public List Graphics { get; set; } = []; } diff --git a/ErsatzTV.Core/Api/ScriptedPlayout/GraphicsOnRequestModel.cs b/ErsatzTV.Core/Api/ScriptedPlayout/GraphicsOnRequestModel.cs index 3b34c33b0..b0a96b9bd 100644 --- a/ErsatzTV.Core/Api/ScriptedPlayout/GraphicsOnRequestModel.cs +++ b/ErsatzTV.Core/Api/ScriptedPlayout/GraphicsOnRequestModel.cs @@ -1,7 +1,11 @@ +using System.ComponentModel; + namespace ErsatzTV.Core.Api.ScriptedPlayout; public record GraphicsOnRequestModel { + [Description("A list of graphics elements to turn on.")] public List Graphics { get; set; } + public Dictionary Variables { get; set; } = []; } diff --git a/ErsatzTV.Core/Api/ScriptedPlayout/SkipItemsRequestModel.cs b/ErsatzTV.Core/Api/ScriptedPlayout/SkipItemsRequestModel.cs index 85eee4f9a..280b73c4c 100644 --- a/ErsatzTV.Core/Api/ScriptedPlayout/SkipItemsRequestModel.cs +++ b/ErsatzTV.Core/Api/ScriptedPlayout/SkipItemsRequestModel.cs @@ -1,7 +1,12 @@ +using System.ComponentModel; + namespace ErsatzTV.Core.Api.ScriptedPlayout; public record SkipItemsRequestModel { + [Description("The 'key' for the content")] public string Content { get; set; } + + [Description("The number of items to skip")] public int Count { get; set; } } diff --git a/ErsatzTV.Core/Api/ScriptedPlayout/SkipToItemRequestModel.cs b/ErsatzTV.Core/Api/ScriptedPlayout/SkipToItemRequestModel.cs index 3f1502099..21aa8e25c 100644 --- a/ErsatzTV.Core/Api/ScriptedPlayout/SkipToItemRequestModel.cs +++ b/ErsatzTV.Core/Api/ScriptedPlayout/SkipToItemRequestModel.cs @@ -1,8 +1,15 @@ +using System.ComponentModel; + namespace ErsatzTV.Core.Api.ScriptedPlayout; public record SkipToItemRequestModel { + [Description("The 'key' for the content")] public string Content { get; set; } + + [Description("The season number")] public int Season { get; set; } + + [Description("The episode number")] public int Episode { get; set; } } diff --git a/ErsatzTV.Core/Api/ScriptedPlayout/StartEpgGroupRequestModel.cs b/ErsatzTV.Core/Api/ScriptedPlayout/StartEpgGroupRequestModel.cs index e399475a5..3d67217c3 100644 --- a/ErsatzTV.Core/Api/ScriptedPlayout/StartEpgGroupRequestModel.cs +++ b/ErsatzTV.Core/Api/ScriptedPlayout/StartEpgGroupRequestModel.cs @@ -1,6 +1,9 @@ +using System.ComponentModel; + namespace ErsatzTV.Core.Api.ScriptedPlayout; public record StartEpgGroupRequestModel { + [Description("When true, will make a new EPG group. When false, will continue the existing EPG group.")] public bool Advance { get; set; } = true; } diff --git a/ErsatzTV.Core/Api/ScriptedPlayout/WaitUntilRequestModel.cs b/ErsatzTV.Core/Api/ScriptedPlayout/WaitUntilRequestModel.cs index 4736ab655..86f427ad2 100644 --- a/ErsatzTV.Core/Api/ScriptedPlayout/WaitUntilRequestModel.cs +++ b/ErsatzTV.Core/Api/ScriptedPlayout/WaitUntilRequestModel.cs @@ -1,8 +1,15 @@ +using System.ComponentModel; + namespace ErsatzTV.Core.Api.ScriptedPlayout; public record WaitUntilRequestModel { + [Description("The time of day to wait (insert unscheduled time) until")] public string When { get; set; } + + [Description("When true, will wait until the specified time tomorrow if it has already passed today.")] public bool Tomorrow { get; set; } + + [Description("When true, the current time of the playout build is allowed to move backward when the playout is reset.")] public bool RewindOnReset { get; set; } } diff --git a/ErsatzTV.Core/Api/ScriptedPlayout/WatermarkOffRequestModel.cs b/ErsatzTV.Core/Api/ScriptedPlayout/WatermarkOffRequestModel.cs index 446f2e697..a26c69f34 100644 --- a/ErsatzTV.Core/Api/ScriptedPlayout/WatermarkOffRequestModel.cs +++ b/ErsatzTV.Core/Api/ScriptedPlayout/WatermarkOffRequestModel.cs @@ -1,6 +1,9 @@ +using System.ComponentModel; + namespace ErsatzTV.Core.Api.ScriptedPlayout; public record WatermarkOffRequestModel { + [Description("A list of existing watermark names to turn off. All (scripted) watermarks will be turned off if this list is null or empty.")] public List Watermark { get; set; } = []; } diff --git a/ErsatzTV.Core/Api/ScriptedPlayout/WatermarkOnRequestModel.cs b/ErsatzTV.Core/Api/ScriptedPlayout/WatermarkOnRequestModel.cs index edd5087aa..4e2a3dfb5 100644 --- a/ErsatzTV.Core/Api/ScriptedPlayout/WatermarkOnRequestModel.cs +++ b/ErsatzTV.Core/Api/ScriptedPlayout/WatermarkOnRequestModel.cs @@ -1,6 +1,9 @@ +using System.ComponentModel; + namespace ErsatzTV.Core.Api.ScriptedPlayout; public record WatermarkOnRequestModel { + [Description("A list of existing watermark names to turn on")] public List Watermark { get; set; } } diff --git a/ErsatzTV/Controllers/Api/ScriptedScheduleController.cs b/ErsatzTV/Controllers/Api/ScriptedScheduleController.cs index c7176a6c2..73b827f93 100644 --- a/ErsatzTV/Controllers/Api/ScriptedScheduleController.cs +++ b/ErsatzTV/Controllers/Api/ScriptedScheduleController.cs @@ -123,6 +123,31 @@ public class ScriptedScheduleController(IScriptedPlayoutBuilderService scriptedP return Ok(); } + [HttpPost("add_search", Name = "AddSearchQuery")] + [Tags("Scripted Content")] + [EndpointSummary("Add a search query")] + public async Task AddSearchQuery( + [FromRoute] + Guid buildId, + [FromBody] + AddSearchQueryRequestModel request, + CancellationToken cancellationToken) + { + ISchedulingEngine engine = scriptedPlayoutBuilderService.GetEngine(buildId); + if (engine == null) + { + return NotFound($"Active build engine not found for build {buildId}."); + } + + if (!Enum.TryParse(request.Order, ignoreCase: true, out PlaybackOrder playbackOrder)) + { + return BadRequest("Invalid playback order."); + } + + await engine.AddSearch(request.Key, request.Query, playbackOrder, cancellationToken); + return Ok(); + } + [HttpPost("add_smart_collection", Name = "AddSmartCollection")] [Tags("Scripted Content")] [EndpointSummary("Add a smart collection")] @@ -328,7 +353,7 @@ public class ScriptedScheduleController(IScriptedPlayoutBuilderService scriptedP [HttpPost("start_epg_group", Name = "StartEpgGroup")] [Tags("Scripted Control")] - [EndpointSummary("Start a new EPG group")] + [EndpointSummary("Start an EPG group")] public IActionResult StartEpgGroup([FromRoute] Guid buildId, [FromBody] StartEpgGroupRequestModel request) { ISchedulingEngine engine = scriptedPlayoutBuilderService.GetEngine(buildId); @@ -343,7 +368,7 @@ public class ScriptedScheduleController(IScriptedPlayoutBuilderService scriptedP [HttpPost("stop_epg_group", Name = "StopEpgGroup")] [Tags("Scripted Control")] - [EndpointSummary("Finish the current EPG group")] + [EndpointSummary("Finish an EPG group")] public IActionResult StopEpgGroup([FromRoute] Guid buildId) { ISchedulingEngine engine = scriptedPlayoutBuilderService.GetEngine(buildId);