mirror of https://github.com/ErsatzTV/ErsatzTV.git
Browse Source
* configure scheduled playout rebuild * implement scheduled playout rebuild * remove variablepull/377/head
15 changed files with 3432 additions and 13 deletions
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
using System; |
||||
using ErsatzTV.Core; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.Playouts.Commands |
||||
{ |
||||
public record UpdatePlayout |
||||
(int PlayoutId, Option<TimeSpan> DailyRebuildTime) : IRequest<Either<BaseError, PlayoutNameViewModel>>; |
||||
} |
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
using System; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core; |
||||
using ErsatzTV.Core.Domain; |
||||
using ErsatzTV.Infrastructure.Data; |
||||
using ErsatzTV.Infrastructure.Extensions; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using static LanguageExt.Prelude; |
||||
|
||||
namespace ErsatzTV.Application.Playouts.Commands |
||||
{ |
||||
public class UpdatePlayoutHandler : IRequestHandler<UpdatePlayout, Either<BaseError, PlayoutNameViewModel>> |
||||
{ |
||||
private readonly IDbContextFactory<TvContext> _dbContextFactory; |
||||
|
||||
public UpdatePlayoutHandler(IDbContextFactory<TvContext> dbContextFactory) => |
||||
_dbContextFactory = dbContextFactory; |
||||
|
||||
public async Task<Either<BaseError, PlayoutNameViewModel>> Handle( |
||||
UpdatePlayout request, |
||||
CancellationToken cancellationToken) |
||||
{ |
||||
await using TvContext dbContext = _dbContextFactory.CreateDbContext(); |
||||
Validation<BaseError, Playout> validation = await Validate(dbContext, request); |
||||
return await validation.Apply(playout => ApplyUpdateRequest(dbContext, request, playout)); |
||||
} |
||||
|
||||
private static async Task<PlayoutNameViewModel> ApplyUpdateRequest( |
||||
TvContext dbContext, |
||||
UpdatePlayout request, |
||||
Playout playout) |
||||
{ |
||||
playout.DailyRebuildTime = null; |
||||
|
||||
foreach (TimeSpan dailyRebuildTime in request.DailyRebuildTime) |
||||
{ |
||||
playout.DailyRebuildTime = dailyRebuildTime; |
||||
} |
||||
|
||||
await dbContext.SaveChangesAsync(); |
||||
|
||||
return new PlayoutNameViewModel( |
||||
playout.Id, |
||||
playout.Channel.Name, |
||||
playout.Channel.Number, |
||||
playout.ProgramSchedule.Name, |
||||
Optional(playout.DailyRebuildTime)); |
||||
} |
||||
|
||||
private static Task<Validation<BaseError, Playout>> Validate(TvContext dbContext, UpdatePlayout request) => |
||||
PlayoutMustExist(dbContext, request); |
||||
|
||||
private static Task<Validation<BaseError, Playout>> PlayoutMustExist( |
||||
TvContext dbContext, |
||||
UpdatePlayout updatePlayout) => |
||||
dbContext.Playouts |
||||
.Include(p => p.Channel) |
||||
.Include(p => p.ProgramSchedule) |
||||
.SelectOneAsync(p => p.Id, p => p.Id == updatePlayout.PlayoutId) |
||||
.Map(o => o.ToValidation<BaseError>("Playout does not exist.")); |
||||
} |
||||
} |
@ -1,8 +1,12 @@
@@ -1,8 +1,12 @@
|
||||
namespace ErsatzTV.Application.Playouts |
||||
using System; |
||||
using LanguageExt; |
||||
|
||||
namespace ErsatzTV.Application.Playouts |
||||
{ |
||||
public record PlayoutNameViewModel( |
||||
int PlayoutId, |
||||
string ChannelName, |
||||
string ChannelNumber, |
||||
string ScheduleName); |
||||
string ScheduleName, |
||||
Option<TimeSpan> DailyRebuildTime); |
||||
} |
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
using System; |
||||
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
||||
namespace ErsatzTV.Infrastructure.Migrations |
||||
{ |
||||
public partial class Add_PlayoutDailyRebuildTime : Migration |
||||
{ |
||||
protected override void Up(MigrationBuilder migrationBuilder) |
||||
{ |
||||
migrationBuilder.AddColumn<TimeSpan>( |
||||
name: "DailyRebuildTime", |
||||
table: "Playout", |
||||
type: "TEXT", |
||||
nullable: true); |
||||
} |
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder) |
||||
{ |
||||
migrationBuilder.DropColumn( |
||||
name: "DailyRebuildTime", |
||||
table: "Playout"); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,81 @@
@@ -0,0 +1,81 @@
|
||||
@using System.Globalization |
||||
@using ErsatzTV.Application.Playouts |
||||
@using ErsatzTV.Application.Playouts.Commands |
||||
@inject IMediator _mediator |
||||
@inject ISnackbar _snackbar |
||||
@inject ILogger<SchedulePlayoutRebuild> _logger |
||||
|
||||
<MudDialog> |
||||
<DialogContent> |
||||
<EditForm Model="@_dummyModel" OnSubmit="@(_ => Submit())"> |
||||
<MudContainer Class="mb-6"> |
||||
<MudText> |
||||
@FormatText() |
||||
</MudText> |
||||
</MudContainer> |
||||
<MudSelect Class="mb-6 mx-4" Label="Daily Rebuild Time" @bind-Value="_rebuildTime"> |
||||
<MudSelectItem Value="@(Option<TimeSpan>.None)">Do not automatically rebuild</MudSelectItem> |
||||
@for (var i = 1; i < 48; i++) |
||||
{ |
||||
var time = TimeSpan.FromHours(i * 0.5); |
||||
string formatted = DateTime.Today.Add(time).ToShortTimeString(); |
||||
<MudSelectItem Value="@(Option<TimeSpan>.Some(time))">@formatted</MudSelectItem> |
||||
} |
||||
</MudSelect> |
||||
</EditForm> |
||||
</DialogContent> |
||||
<DialogActions> |
||||
<MudButton OnClick="Cancel" ButtonType="ButtonType.Reset">Cancel</MudButton> |
||||
<MudButton Color="Color.Primary" Variant="Variant.Filled" OnClick="Submit"> |
||||
Save Changes |
||||
</MudButton> |
||||
</DialogActions> |
||||
</MudDialog> |
||||
|
||||
@code { |
||||
|
||||
[CascadingParameter] |
||||
MudDialogInstance MudDialog { get; set; } |
||||
|
||||
[Parameter] |
||||
public int PlayoutId { get; set; } |
||||
|
||||
[Parameter] |
||||
public string ChannelName { get; set; } |
||||
|
||||
[Parameter] |
||||
public string ScheduleName { get; set; } |
||||
|
||||
[Parameter] |
||||
public Option<TimeSpan> DailyRebuildTime { get; set; } |
||||
|
||||
private string FormatText() => $"Enter the time that the playout on channel {ChannelName} with schedule {ScheduleName} should rebuild every day"; |
||||
|
||||
private record DummyModel; |
||||
|
||||
private readonly DummyModel _dummyModel = new(); |
||||
|
||||
private Option<TimeSpan> _rebuildTime; |
||||
|
||||
protected override void OnParametersSet() |
||||
{ |
||||
_rebuildTime = DailyRebuildTime; |
||||
} |
||||
|
||||
private async Task Submit() |
||||
{ |
||||
Either<BaseError, PlayoutNameViewModel> maybeResult = |
||||
await _mediator.Send(new UpdatePlayout(PlayoutId, _rebuildTime)); |
||||
|
||||
maybeResult.Match( |
||||
playout => { MudDialog.Close(DialogResult.Ok(playout)); }, |
||||
error => |
||||
{ |
||||
_snackbar.Add(error.Value, Severity.Error); |
||||
_logger.LogError("Error updating Playout: {Error}", error.Value); |
||||
MudDialog.Close(DialogResult.Cancel()); |
||||
}); |
||||
} |
||||
|
||||
private void Cancel(MouseEventArgs e) => MudDialog.Cancel(); |
||||
} |
Loading…
Reference in new issue