Adds per-playout REST for classic-playout alternate schedules and
block-playout templates, plus the default-deco read-side deferred from S3:
- GET/PUT /api/playouts/{id}/alternate-schedules (Classic only; 422 otherwise)
- GET/PUT /api/playouts/{id}/templates (Block only; 422 otherwise)
- PlayoutResponseModel gains decoId/decoName (GetPlayoutById includes Deco)
PUT assigns Index from array order (top = highest priority, last = catch-all
default), mirroring the Blazor editors. Alternate-schedule PUT requires a
non-empty list and existing ProgramScheduleIds; template PUT requires existing
TemplateIds and any supplied DecoTemplateId. Regenerates the OpenAPI spec.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using ErsatzTV.Application.Playouts;
|
||||
using ErsatzTV.Application.ProgramSchedules;
|
||||
using ErsatzTV.Application.Scheduling;
|
||||
using ErsatzTV.Controllers.Api.Requests;
|
||||
using ErsatzTV.Core;
|
||||
using ErsatzTV.Core.Api.Playouts;
|
||||
using ErsatzTV.Core.Api.Scheduling;
|
||||
using ErsatzTV.Core.Domain;
|
||||
using ErsatzTV.Core.Domain.Filler;
|
||||
using ErsatzTV.Extensions;
|
||||
@@ -234,6 +236,190 @@ public class PlayoutController(IMediator mediator) : ControllerBase
|
||||
None: () => ApiResults.NotFoundProblem());
|
||||
}
|
||||
|
||||
[HttpGet("/api/playouts/{id:int}/alternate-schedules", Name = "GetPlayoutAlternateSchedules")]
|
||||
[Tags("Playouts")]
|
||||
[EndpointSummary("Get a classic playout's alternate schedules")]
|
||||
[EndpointDescription(
|
||||
"Lists a Classic playout's alternate schedules in priority order (first = highest priority). The last " +
|
||||
"entry is the catch-all default, and its schedule is the playout's default schedule; if no explicit " +
|
||||
"catch-all exists the query synthesizes one from the playout's default schedule. Only valid for Classic " +
|
||||
"playouts; other kinds return 422.")]
|
||||
[EndpointGroupName("general")]
|
||||
[ProducesResponseType(typeof(List<PlayoutAlternateScheduleResponseModel>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status422UnprocessableEntity)]
|
||||
public async Task<IActionResult> GetAlternateSchedules(int id, CancellationToken cancellationToken)
|
||||
{
|
||||
Option<PlayoutNameViewModel> maybePlayout = await mediator.Send(new GetPlayoutById(id), cancellationToken);
|
||||
if (maybePlayout.IsNone)
|
||||
{
|
||||
return ApiResults.NotFoundProblem();
|
||||
}
|
||||
|
||||
foreach (PlayoutNameViewModel playout in maybePlayout)
|
||||
{
|
||||
if (playout.ScheduleKind is not PlayoutScheduleKind.Classic)
|
||||
{
|
||||
return BaseError.New("[AlternateSchedules] are only valid for Classic playouts").ToErrorResult();
|
||||
}
|
||||
}
|
||||
|
||||
List<PlayoutAlternateScheduleViewModel> items =
|
||||
await mediator.Send(new GetPlayoutAlternateSchedules(id), cancellationToken);
|
||||
return new OkObjectResult(items.OrderBy(i => i.Index).Select(ToResponse).ToList());
|
||||
}
|
||||
|
||||
[HttpPut("/api/playouts/{id:int}/alternate-schedules")]
|
||||
[Tags("Playouts")]
|
||||
[EndpointSummary("Replace a classic playout's alternate schedules")]
|
||||
[EndpointDescription(
|
||||
"Replaces a Classic playout's alternate schedules. Items are ordered by priority: the first item is the " +
|
||||
"highest priority and the last item is the catch-all default whose schedule becomes the playout's default " +
|
||||
"schedule. Index is assigned from array order (the request body has no Index field). The list must contain " +
|
||||
"at least one item, and every ProgramScheduleId must exist. Only valid for Classic playouts.")]
|
||||
[EndpointGroupName("general")]
|
||||
[ProducesResponseType(typeof(List<PlayoutAlternateScheduleResponseModel>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status422UnprocessableEntity)]
|
||||
public async Task<IActionResult> ReplaceAlternateSchedules(
|
||||
int id,
|
||||
[Required] [FromBody] ReplacePlayoutAlternateSchedulesRequest request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
Option<PlayoutNameViewModel> maybePlayout = await mediator.Send(new GetPlayoutById(id), cancellationToken);
|
||||
if (maybePlayout.IsNone)
|
||||
{
|
||||
return ApiResults.NotFoundProblem();
|
||||
}
|
||||
|
||||
foreach (PlayoutNameViewModel playout in maybePlayout)
|
||||
{
|
||||
if (playout.ScheduleKind is not PlayoutScheduleKind.Classic)
|
||||
{
|
||||
return BaseError.New("[AlternateSchedules] are only valid for Classic playouts").ToErrorResult();
|
||||
}
|
||||
}
|
||||
|
||||
List<PlayoutAlternateScheduleItemRequest> items = request.Items ?? [];
|
||||
if (items.Count == 0)
|
||||
{
|
||||
return BaseError.New("[Items] must contain at least one alternate schedule").ToErrorResult();
|
||||
}
|
||||
|
||||
List<ProgramScheduleViewModel> schedules =
|
||||
await mediator.Send(new GetAllProgramSchedules(), cancellationToken);
|
||||
var scheduleIds = schedules.Select(s => s.Id).ToHashSet();
|
||||
var missingScheduleIds = items.Select(i => i.ProgramScheduleId).Distinct()
|
||||
.Where(scheduleId => !scheduleIds.Contains(scheduleId)).ToList();
|
||||
if (missingScheduleIds.Count > 0)
|
||||
{
|
||||
return BaseError.New($"[ProgramScheduleId] {missingScheduleIds[0]} does not exist").ToErrorResult();
|
||||
}
|
||||
|
||||
Either<BaseError, Unit> result = await mediator.Send(request.ToCommand(id), cancellationToken);
|
||||
return await result.Match(
|
||||
Left: error => Task.FromResult(error.ToErrorResult()),
|
||||
Right: async _ =>
|
||||
{
|
||||
List<PlayoutAlternateScheduleViewModel> refreshed =
|
||||
await mediator.Send(new GetPlayoutAlternateSchedules(id), cancellationToken);
|
||||
return (IActionResult)new OkObjectResult(refreshed.OrderBy(i => i.Index).Select(ToResponse).ToList());
|
||||
});
|
||||
}
|
||||
|
||||
[HttpGet("/api/playouts/{id:int}/templates", Name = "GetPlayoutTemplates")]
|
||||
[Tags("Playouts")]
|
||||
[EndpointSummary("Get a block playout's templates")]
|
||||
[EndpointDescription(
|
||||
"Lists a Block playout's templates in priority order (first = highest priority). Each template optionally " +
|
||||
"carries a deco template. Only valid for Block playouts; other kinds return 422.")]
|
||||
[EndpointGroupName("general")]
|
||||
[ProducesResponseType(typeof(List<PlayoutTemplateResponseModel>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status422UnprocessableEntity)]
|
||||
public async Task<IActionResult> GetTemplates(int id, CancellationToken cancellationToken)
|
||||
{
|
||||
Option<PlayoutNameViewModel> maybePlayout = await mediator.Send(new GetPlayoutById(id), cancellationToken);
|
||||
if (maybePlayout.IsNone)
|
||||
{
|
||||
return ApiResults.NotFoundProblem();
|
||||
}
|
||||
|
||||
foreach (PlayoutNameViewModel playout in maybePlayout)
|
||||
{
|
||||
if (playout.ScheduleKind is not PlayoutScheduleKind.Block)
|
||||
{
|
||||
return BaseError.New("[Templates] are only valid for Block playouts").ToErrorResult();
|
||||
}
|
||||
}
|
||||
|
||||
List<PlayoutTemplateViewModel> items = await mediator.Send(new GetPlayoutTemplates(id), cancellationToken);
|
||||
return new OkObjectResult(items.OrderBy(i => i.Index).Select(ToResponse).ToList());
|
||||
}
|
||||
|
||||
[HttpPut("/api/playouts/{id:int}/templates")]
|
||||
[Tags("Playouts")]
|
||||
[EndpointSummary("Replace a block playout's templates")]
|
||||
[EndpointDescription(
|
||||
"Replaces a Block playout's templates. Items are ordered by priority (first = highest priority); Index is " +
|
||||
"assigned from array order (the request body has no Index field). Every TemplateId must exist, and any " +
|
||||
"supplied DecoTemplateId must exist. An empty list clears all templates. Only valid for Block playouts.")]
|
||||
[EndpointGroupName("general")]
|
||||
[ProducesResponseType(typeof(List<PlayoutTemplateResponseModel>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status422UnprocessableEntity)]
|
||||
public async Task<IActionResult> ReplaceTemplates(
|
||||
int id,
|
||||
[Required] [FromBody] ReplacePlayoutTemplatesRequest request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
Option<PlayoutNameViewModel> maybePlayout = await mediator.Send(new GetPlayoutById(id), cancellationToken);
|
||||
if (maybePlayout.IsNone)
|
||||
{
|
||||
return ApiResults.NotFoundProblem();
|
||||
}
|
||||
|
||||
foreach (PlayoutNameViewModel playout in maybePlayout)
|
||||
{
|
||||
if (playout.ScheduleKind is not PlayoutScheduleKind.Block)
|
||||
{
|
||||
return BaseError.New("[Templates] are only valid for Block playouts").ToErrorResult();
|
||||
}
|
||||
}
|
||||
|
||||
List<PlayoutTemplateItemRequest> items = request.Items ?? [];
|
||||
|
||||
List<TemplateViewModel> templates = await mediator.Send(new GetAllTemplates(), cancellationToken);
|
||||
var templateIds = templates.Select(t => t.Id).ToHashSet();
|
||||
var missingTemplateIds = items.Select(i => i.TemplateId).Distinct()
|
||||
.Where(templateId => !templateIds.Contains(templateId)).ToList();
|
||||
if (missingTemplateIds.Count > 0)
|
||||
{
|
||||
return BaseError.New($"[TemplateId] {missingTemplateIds[0]} does not exist").ToErrorResult();
|
||||
}
|
||||
|
||||
var decoTemplateIds = items.Where(i => i.DecoTemplateId.HasValue)
|
||||
.Select(i => i.DecoTemplateId!.Value).Distinct().ToList();
|
||||
foreach (int decoTemplateId in decoTemplateIds)
|
||||
{
|
||||
Option<DecoTemplateViewModel> maybeDecoTemplate =
|
||||
await mediator.Send(new GetDecoTemplateById(decoTemplateId), cancellationToken);
|
||||
if (maybeDecoTemplate.IsNone)
|
||||
{
|
||||
return BaseError.New($"[DecoTemplateId] {decoTemplateId} does not exist").ToErrorResult();
|
||||
}
|
||||
}
|
||||
|
||||
Option<BaseError> result = await mediator.Send(request.ToCommand(id), cancellationToken);
|
||||
foreach (BaseError error in result)
|
||||
{
|
||||
return error.ToErrorResult();
|
||||
}
|
||||
|
||||
List<PlayoutTemplateViewModel> refreshed = await mediator.Send(new GetPlayoutTemplates(id), cancellationToken);
|
||||
return new OkObjectResult(refreshed.OrderBy(i => i.Index).Select(ToResponse).ToList());
|
||||
}
|
||||
|
||||
[HttpPost("/api/playouts/reset-all", Name = "ResetAllPlayouts")]
|
||||
[Tags("Playouts")]
|
||||
[EndpointSummary("Reset all playouts")]
|
||||
@@ -268,7 +454,46 @@ public class PlayoutController(IMediator mediator) : ControllerBase
|
||||
vm.ScheduleName,
|
||||
vm.ScheduleFile,
|
||||
vm.DbDailyRebuildTime,
|
||||
ToBuildStatus(vm.BuildStatus));
|
||||
ToBuildStatus(vm.BuildStatus),
|
||||
vm.DecoId,
|
||||
vm.DecoName);
|
||||
|
||||
private static PlayoutAlternateScheduleResponseModel ToResponse(PlayoutAlternateScheduleViewModel vm) =>
|
||||
new(
|
||||
vm.Id,
|
||||
vm.Index,
|
||||
vm.ProgramScheduleId,
|
||||
vm.DaysOfWeek,
|
||||
vm.DaysOfMonth,
|
||||
vm.MonthsOfYear,
|
||||
vm.LimitToDateRange,
|
||||
vm.StartMonth,
|
||||
vm.StartDay,
|
||||
vm.StartYear,
|
||||
vm.EndMonth,
|
||||
vm.EndDay,
|
||||
vm.EndYear);
|
||||
|
||||
private static PlayoutTemplateResponseModel ToResponse(PlayoutTemplateViewModel vm) =>
|
||||
new(
|
||||
vm.Id,
|
||||
vm.Index,
|
||||
vm.Template.Id,
|
||||
vm.Template.Name,
|
||||
vm.Template.GroupName,
|
||||
vm.DecoTemplate?.Id,
|
||||
vm.DecoTemplate?.Name,
|
||||
vm.DecoTemplate?.GroupName,
|
||||
vm.DaysOfWeek,
|
||||
vm.DaysOfMonth,
|
||||
vm.MonthsOfYear,
|
||||
vm.LimitToDateRange,
|
||||
vm.StartMonth,
|
||||
vm.StartDay,
|
||||
vm.StartYear,
|
||||
vm.EndMonth,
|
||||
vm.EndDay,
|
||||
vm.EndYear);
|
||||
|
||||
private static PlayoutListItemResponseModel ToListItemResponse(PlayoutNameViewModel vm) =>
|
||||
new(
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
using ErsatzTV.Application.Playouts;
|
||||
|
||||
namespace ErsatzTV.Controllers.Api.Requests;
|
||||
|
||||
public record PlayoutAlternateScheduleItemRequest(
|
||||
int Id,
|
||||
int ProgramScheduleId,
|
||||
List<DayOfWeek> DaysOfWeek,
|
||||
List<int> DaysOfMonth,
|
||||
List<int> MonthsOfYear,
|
||||
bool LimitToDateRange,
|
||||
int StartMonth,
|
||||
int StartDay,
|
||||
int? StartYear,
|
||||
int EndMonth,
|
||||
int EndDay,
|
||||
int? EndYear)
|
||||
{
|
||||
public ReplacePlayoutAlternateSchedule ToReplaceItem(int index) =>
|
||||
new(
|
||||
Id,
|
||||
index,
|
||||
ProgramScheduleId,
|
||||
DaysOfWeek ?? [],
|
||||
DaysOfMonth ?? [],
|
||||
MonthsOfYear ?? [],
|
||||
LimitToDateRange,
|
||||
StartMonth,
|
||||
StartDay,
|
||||
StartYear,
|
||||
EndMonth,
|
||||
EndDay,
|
||||
EndYear);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using ErsatzTV.Application.Scheduling;
|
||||
|
||||
namespace ErsatzTV.Controllers.Api.Requests;
|
||||
|
||||
public record PlayoutTemplateItemRequest(
|
||||
int Id,
|
||||
int TemplateId,
|
||||
int? DecoTemplateId,
|
||||
List<DayOfWeek> DaysOfWeek,
|
||||
List<int> DaysOfMonth,
|
||||
List<int> MonthsOfYear,
|
||||
bool LimitToDateRange,
|
||||
int StartMonth,
|
||||
int StartDay,
|
||||
int? StartYear,
|
||||
int EndMonth,
|
||||
int EndDay,
|
||||
int? EndYear)
|
||||
{
|
||||
public ReplacePlayoutTemplate ToReplaceItem(int index) =>
|
||||
new(
|
||||
Id,
|
||||
index,
|
||||
TemplateId,
|
||||
DecoTemplateId,
|
||||
DaysOfWeek ?? [],
|
||||
DaysOfMonth ?? [],
|
||||
MonthsOfYear ?? [],
|
||||
LimitToDateRange,
|
||||
StartMonth,
|
||||
StartDay,
|
||||
StartYear,
|
||||
EndMonth,
|
||||
EndDay,
|
||||
EndYear);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using ErsatzTV.Application.Playouts;
|
||||
|
||||
namespace ErsatzTV.Controllers.Api.Requests;
|
||||
|
||||
public record ReplacePlayoutAlternateSchedulesRequest(List<PlayoutAlternateScheduleItemRequest> Items)
|
||||
{
|
||||
// Index is assigned from array order: the first item is the highest priority and the last item
|
||||
// is the lowest priority (the catch-all default whose schedule becomes the playout's default
|
||||
// schedule). This mirrors the Blazor editor, which lists items top-to-bottom in priority order
|
||||
// and writes the highest-Index item's schedule as the playout default.
|
||||
public ReplacePlayoutAlternateScheduleItems ToCommand(int playoutId) =>
|
||||
new(
|
||||
playoutId,
|
||||
(Items ?? [])
|
||||
.Select((item, index) => item.ToReplaceItem(index))
|
||||
.ToList());
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using ErsatzTV.Application.Scheduling;
|
||||
|
||||
namespace ErsatzTV.Controllers.Api.Requests;
|
||||
|
||||
public record ReplacePlayoutTemplatesRequest(List<PlayoutTemplateItemRequest> Items)
|
||||
{
|
||||
// Index is assigned from array order (top-to-bottom priority), mirroring the Blazor editor.
|
||||
public ReplacePlayoutTemplateItems ToCommand(int playoutId) =>
|
||||
new(
|
||||
playoutId,
|
||||
(Items ?? [])
|
||||
.Select((item, index) => item.ToReplaceItem(index))
|
||||
.ToList());
|
||||
}
|
||||
@@ -5903,6 +5903,418 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/playouts/{id}/alternate-schedules": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Playouts"
|
||||
],
|
||||
"summary": "Get a classic playout's alternate schedules",
|
||||
"description": "Lists a Classic playout's alternate schedules in priority order (first = highest priority). The last entry is the catch-all default, and its schedule is the playout's default schedule; if no explicit catch-all exists the query synthesizes one from the playout's default schedule. Only valid for Classic playouts; other kinds return 422.",
|
||||
"operationId": "GetPlayoutAlternateSchedules",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/PlayoutAlternateScheduleResponseModel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/PlayoutAlternateScheduleResponseModel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/PlayoutAlternateScheduleResponseModel"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"content": {
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Unprocessable Entity",
|
||||
"content": {
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"tags": [
|
||||
"Playouts"
|
||||
],
|
||||
"summary": "Replace a classic playout's alternate schedules",
|
||||
"description": "Replaces a Classic playout's alternate schedules. Items are ordered by priority: the first item is the highest priority and the last item is the catch-all default whose schedule becomes the playout's default schedule. Index is assigned from array order (the request body has no Index field). The list must contain at least one item, and every ProgramScheduleId must exist. Only valid for Classic playouts.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json-patch+json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ReplacePlayoutAlternateSchedulesRequest"
|
||||
}
|
||||
},
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ReplacePlayoutAlternateSchedulesRequest"
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ReplacePlayoutAlternateSchedulesRequest"
|
||||
}
|
||||
},
|
||||
"application/*+json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ReplacePlayoutAlternateSchedulesRequest"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/PlayoutAlternateScheduleResponseModel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/PlayoutAlternateScheduleResponseModel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/PlayoutAlternateScheduleResponseModel"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"content": {
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Unprocessable Entity",
|
||||
"content": {
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/playouts/{id}/templates": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Playouts"
|
||||
],
|
||||
"summary": "Get a block playout's templates",
|
||||
"description": "Lists a Block playout's templates in priority order (first = highest priority). Each template optionally carries a deco template. Only valid for Block playouts; other kinds return 422.",
|
||||
"operationId": "GetPlayoutTemplates",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/PlayoutTemplateResponseModel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/PlayoutTemplateResponseModel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/PlayoutTemplateResponseModel"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"content": {
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Unprocessable Entity",
|
||||
"content": {
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"tags": [
|
||||
"Playouts"
|
||||
],
|
||||
"summary": "Replace a block playout's templates",
|
||||
"description": "Replaces a Block playout's templates. Items are ordered by priority (first = highest priority); Index is assigned from array order (the request body has no Index field). Every TemplateId must exist, and any supplied DecoTemplateId must exist. An empty list clears all templates. Only valid for Block playouts.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json-patch+json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ReplacePlayoutTemplatesRequest"
|
||||
}
|
||||
},
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ReplacePlayoutTemplatesRequest"
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ReplacePlayoutTemplatesRequest"
|
||||
}
|
||||
},
|
||||
"application/*+json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ReplacePlayoutTemplatesRequest"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/PlayoutTemplateResponseModel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/PlayoutTemplateResponseModel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/PlayoutTemplateResponseModel"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"content": {
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Unprocessable Entity",
|
||||
"content": {
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/playouts/reset-all": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@@ -12983,6 +13395,9 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"DayOfWeek": {
|
||||
"type": "integer"
|
||||
},
|
||||
"DecoBreakContentRequest": {
|
||||
"required": [
|
||||
"id",
|
||||
@@ -14889,6 +15304,180 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"PlayoutAlternateScheduleItemRequest": {
|
||||
"required": [
|
||||
"id",
|
||||
"programScheduleId",
|
||||
"daysOfWeek",
|
||||
"daysOfMonth",
|
||||
"monthsOfYear",
|
||||
"limitToDateRange",
|
||||
"startMonth",
|
||||
"startDay",
|
||||
"startYear",
|
||||
"endMonth",
|
||||
"endDay",
|
||||
"endYear"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"programScheduleId": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"daysOfWeek": {
|
||||
"type": [
|
||||
"null",
|
||||
"array"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/DayOfWeek"
|
||||
}
|
||||
},
|
||||
"daysOfMonth": {
|
||||
"type": [
|
||||
"null",
|
||||
"array"
|
||||
],
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
},
|
||||
"monthsOfYear": {
|
||||
"type": [
|
||||
"null",
|
||||
"array"
|
||||
],
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
},
|
||||
"limitToDateRange": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"startMonth": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"startDay": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"startYear": {
|
||||
"type": [
|
||||
"null",
|
||||
"integer"
|
||||
],
|
||||
"format": "int32"
|
||||
},
|
||||
"endMonth": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"endDay": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"endYear": {
|
||||
"type": [
|
||||
"null",
|
||||
"integer"
|
||||
],
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
},
|
||||
"PlayoutAlternateScheduleResponseModel": {
|
||||
"required": [
|
||||
"id",
|
||||
"index",
|
||||
"programScheduleId",
|
||||
"daysOfWeek",
|
||||
"daysOfMonth",
|
||||
"monthsOfYear",
|
||||
"limitToDateRange",
|
||||
"startMonth",
|
||||
"startDay",
|
||||
"startYear",
|
||||
"endMonth",
|
||||
"endDay",
|
||||
"endYear"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"index": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"programScheduleId": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"daysOfWeek": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/DayOfWeek"
|
||||
}
|
||||
},
|
||||
"daysOfMonth": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
},
|
||||
"monthsOfYear": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
},
|
||||
"limitToDateRange": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"startMonth": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"startDay": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"startYear": {
|
||||
"type": [
|
||||
"null",
|
||||
"integer"
|
||||
],
|
||||
"format": "int32"
|
||||
},
|
||||
"endMonth": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"endDay": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"endYear": {
|
||||
"type": [
|
||||
"null",
|
||||
"integer"
|
||||
],
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
},
|
||||
"PlayoutBuildMode": {
|
||||
"enum": [
|
||||
"Continue",
|
||||
@@ -15028,7 +15617,9 @@
|
||||
"scheduleName",
|
||||
"scheduleFile",
|
||||
"dailyRebuildTime",
|
||||
"buildStatus"
|
||||
"buildStatus",
|
||||
"decoId",
|
||||
"decoName"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -15073,6 +15664,19 @@
|
||||
"$ref": "#/components/schemas/PlayoutBuildStatusResponseModel"
|
||||
}
|
||||
]
|
||||
},
|
||||
"decoId": {
|
||||
"type": [
|
||||
"null",
|
||||
"integer"
|
||||
],
|
||||
"format": "int32"
|
||||
},
|
||||
"decoName": {
|
||||
"type": [
|
||||
"null",
|
||||
"string"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -15108,6 +15712,218 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"PlayoutTemplateItemRequest": {
|
||||
"required": [
|
||||
"id",
|
||||
"templateId",
|
||||
"decoTemplateId",
|
||||
"daysOfWeek",
|
||||
"daysOfMonth",
|
||||
"monthsOfYear",
|
||||
"limitToDateRange",
|
||||
"startMonth",
|
||||
"startDay",
|
||||
"startYear",
|
||||
"endMonth",
|
||||
"endDay",
|
||||
"endYear"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"templateId": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"decoTemplateId": {
|
||||
"type": [
|
||||
"null",
|
||||
"integer"
|
||||
],
|
||||
"format": "int32"
|
||||
},
|
||||
"daysOfWeek": {
|
||||
"type": [
|
||||
"null",
|
||||
"array"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/DayOfWeek"
|
||||
}
|
||||
},
|
||||
"daysOfMonth": {
|
||||
"type": [
|
||||
"null",
|
||||
"array"
|
||||
],
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
},
|
||||
"monthsOfYear": {
|
||||
"type": [
|
||||
"null",
|
||||
"array"
|
||||
],
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
},
|
||||
"limitToDateRange": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"startMonth": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"startDay": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"startYear": {
|
||||
"type": [
|
||||
"null",
|
||||
"integer"
|
||||
],
|
||||
"format": "int32"
|
||||
},
|
||||
"endMonth": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"endDay": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"endYear": {
|
||||
"type": [
|
||||
"null",
|
||||
"integer"
|
||||
],
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
},
|
||||
"PlayoutTemplateResponseModel": {
|
||||
"required": [
|
||||
"id",
|
||||
"index",
|
||||
"templateId",
|
||||
"templateName",
|
||||
"templateGroupName",
|
||||
"decoTemplateId",
|
||||
"decoTemplateName",
|
||||
"decoTemplateGroupName",
|
||||
"daysOfWeek",
|
||||
"daysOfMonth",
|
||||
"monthsOfYear",
|
||||
"limitToDateRange",
|
||||
"startMonth",
|
||||
"startDay",
|
||||
"startYear",
|
||||
"endMonth",
|
||||
"endDay",
|
||||
"endYear"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"index": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"templateId": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"templateName": {
|
||||
"type": "string"
|
||||
},
|
||||
"templateGroupName": {
|
||||
"type": "string"
|
||||
},
|
||||
"decoTemplateId": {
|
||||
"type": [
|
||||
"null",
|
||||
"integer"
|
||||
],
|
||||
"format": "int32"
|
||||
},
|
||||
"decoTemplateName": {
|
||||
"type": [
|
||||
"null",
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"decoTemplateGroupName": {
|
||||
"type": [
|
||||
"null",
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"daysOfWeek": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/DayOfWeek"
|
||||
}
|
||||
},
|
||||
"daysOfMonth": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
},
|
||||
"monthsOfYear": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
},
|
||||
"limitToDateRange": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"startMonth": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"startDay": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"startYear": {
|
||||
"type": [
|
||||
"null",
|
||||
"integer"
|
||||
],
|
||||
"format": "int32"
|
||||
},
|
||||
"endMonth": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"endDay": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"endYear": {
|
||||
"type": [
|
||||
"null",
|
||||
"integer"
|
||||
],
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ProblemDetails": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -15589,6 +16405,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ReplacePlayoutAlternateSchedulesRequest": {
|
||||
"required": [
|
||||
"items"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"items": {
|
||||
"type": [
|
||||
"null",
|
||||
"array"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/PlayoutAlternateScheduleItemRequest"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ReplacePlayoutTemplatesRequest": {
|
||||
"required": [
|
||||
"items"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"items": {
|
||||
"type": [
|
||||
"null",
|
||||
"array"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/PlayoutTemplateItemRequest"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ReplaceScheduleItemsRequest": {
|
||||
"required": [
|
||||
"items"
|
||||
|
||||
Reference in New Issue
Block a user