add option to skip missing items in playouts (#795)
This commit is contained in:
@@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
- Add `metadata_kind` field to search index to allow searching for items with a particular metdata source
|
||||
- Valid metadata kinds are `fallback`, `sidecar` (NFO), `external` (from a media server) and `embedded` (songs)
|
||||
- Add autocomplete functionality to search bar to quickly navigate to channels, ffmpeg profiles, collections and schedules by name
|
||||
- Add global setting to skip missing (file-not-found or unavailable) items when building playouts
|
||||
|
||||
### Changed
|
||||
- Replace invalid (control) characters in NFO metadata with replacement character `�` before parsing
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
using ErsatzTV.Core;
|
||||
|
||||
namespace ErsatzTV.Application.Configuration;
|
||||
|
||||
public record UpdatePlayoutDaysToBuild(int DaysToBuild) : IRequest<Either<BaseError, Unit>>;
|
||||
@@ -0,0 +1,5 @@
|
||||
using ErsatzTV.Core;
|
||||
|
||||
namespace ErsatzTV.Application.Configuration;
|
||||
|
||||
public record UpdatePlayoutSettings(PlayoutSettingsViewModel PlayoutSettings) : IRequest<Either<BaseError, Unit>>;
|
||||
+12
-9
@@ -9,13 +9,13 @@ using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace ErsatzTV.Application.Configuration;
|
||||
|
||||
public class UpdatePlayoutDaysToBuildHandler : IRequestHandler<UpdatePlayoutDaysToBuild, Either<BaseError, Unit>>
|
||||
public class UpdatePlayoutSettingsHandler : IRequestHandler<UpdatePlayoutSettings, Either<BaseError, Unit>>
|
||||
{
|
||||
private readonly IConfigElementRepository _configElementRepository;
|
||||
private readonly IDbContextFactory<TvContext> _dbContextFactory;
|
||||
private readonly ChannelWriter<IBackgroundServiceRequest> _workerChannel;
|
||||
|
||||
public UpdatePlayoutDaysToBuildHandler(
|
||||
public UpdatePlayoutSettingsHandler(
|
||||
IConfigElementRepository configElementRepository,
|
||||
IDbContextFactory<TvContext> dbContextFactory,
|
||||
ChannelWriter<IBackgroundServiceRequest> workerChannel)
|
||||
@@ -26,17 +26,20 @@ public class UpdatePlayoutDaysToBuildHandler : IRequestHandler<UpdatePlayoutDays
|
||||
}
|
||||
|
||||
public async Task<Either<BaseError, Unit>> Handle(
|
||||
UpdatePlayoutDaysToBuild request,
|
||||
UpdatePlayoutSettings request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await using TvContext dbContext = _dbContextFactory.CreateDbContext();
|
||||
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
Validation<BaseError, Unit> validation = await Validate(request);
|
||||
return await validation.Apply<Unit, Unit>(_ => ApplyUpdate(dbContext, request.DaysToBuild));
|
||||
return await validation.Apply<Unit, Unit>(_ => ApplyUpdate(dbContext, request.PlayoutSettings));
|
||||
}
|
||||
|
||||
private async Task<Unit> ApplyUpdate(TvContext dbContext, int daysToBuild)
|
||||
private async Task<Unit> ApplyUpdate(TvContext dbContext, PlayoutSettingsViewModel playoutSettings)
|
||||
{
|
||||
await _configElementRepository.Upsert(ConfigElementKey.PlayoutDaysToBuild, daysToBuild);
|
||||
await _configElementRepository.Upsert(ConfigElementKey.PlayoutDaysToBuild, playoutSettings.DaysToBuild);
|
||||
await _configElementRepository.Upsert(
|
||||
ConfigElementKey.PlayoutSkipMissingItems,
|
||||
playoutSettings.SkipMissingItems);
|
||||
|
||||
// continue all playouts to proper number of days
|
||||
List<Playout> playouts = await dbContext.Playouts
|
||||
@@ -50,8 +53,8 @@ public class UpdatePlayoutDaysToBuildHandler : IRequestHandler<UpdatePlayoutDays
|
||||
return Unit.Default;
|
||||
}
|
||||
|
||||
private static Task<Validation<BaseError, Unit>> Validate(UpdatePlayoutDaysToBuild request) =>
|
||||
Optional(request.DaysToBuild)
|
||||
private static Task<Validation<BaseError, Unit>> Validate(UpdatePlayoutSettings request) =>
|
||||
Optional(request.PlayoutSettings.DaysToBuild)
|
||||
.Where(days => days > 0)
|
||||
.Map(_ => Unit.Default)
|
||||
.ToValidation<BaseError>("Days to build must be greater than zero")
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace ErsatzTV.Application.Configuration;
|
||||
|
||||
public class PlayoutSettingsViewModel
|
||||
{
|
||||
public int DaysToBuild { get; set; }
|
||||
public bool SkipMissingItems { get; set; }
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
namespace ErsatzTV.Application.Configuration;
|
||||
|
||||
public record GetPlayoutDaysToBuild : IRequest<int>;
|
||||
@@ -1,16 +0,0 @@
|
||||
using ErsatzTV.Core.Domain;
|
||||
using ErsatzTV.Core.Interfaces.Repositories;
|
||||
|
||||
namespace ErsatzTV.Application.Configuration;
|
||||
|
||||
public class GetPlayoutDaysToBuildHandler : IRequestHandler<GetPlayoutDaysToBuild, int>
|
||||
{
|
||||
private readonly IConfigElementRepository _configElementRepository;
|
||||
|
||||
public GetPlayoutDaysToBuildHandler(IConfigElementRepository configElementRepository) =>
|
||||
_configElementRepository = configElementRepository;
|
||||
|
||||
public Task<int> Handle(GetPlayoutDaysToBuild request, CancellationToken cancellationToken) =>
|
||||
_configElementRepository.GetValue<int>(ConfigElementKey.PlayoutDaysToBuild)
|
||||
.Map(result => result.IfNone(2));
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace ErsatzTV.Application.Configuration;
|
||||
|
||||
public record GetPlayoutSettings : IRequest<PlayoutSettingsViewModel>;
|
||||
@@ -0,0 +1,26 @@
|
||||
using ErsatzTV.Core.Domain;
|
||||
using ErsatzTV.Core.Interfaces.Repositories;
|
||||
|
||||
namespace ErsatzTV.Application.Configuration;
|
||||
|
||||
public class GetPlayoutSettingsHandler : IRequestHandler<GetPlayoutSettings, PlayoutSettingsViewModel>
|
||||
{
|
||||
private readonly IConfigElementRepository _configElementRepository;
|
||||
|
||||
public GetPlayoutSettingsHandler(IConfigElementRepository configElementRepository) =>
|
||||
_configElementRepository = configElementRepository;
|
||||
|
||||
public async Task<PlayoutSettingsViewModel> Handle(GetPlayoutSettings request, CancellationToken cancellationToken)
|
||||
{
|
||||
Option<int> daysToBuild = await _configElementRepository.GetValue<int>(ConfigElementKey.PlayoutDaysToBuild);
|
||||
|
||||
Option<bool> skipMissingItems =
|
||||
await _configElementRepository.GetValue<bool>(ConfigElementKey.PlayoutSkipMissingItems);
|
||||
|
||||
return new PlayoutSettingsViewModel
|
||||
{
|
||||
DaysToBuild = await daysToBuild.IfNoneAsync(2),
|
||||
SkipMissingItems = await skipMissingItems.IfNoneAsync(false)
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -70,6 +70,180 @@ public class PlayoutBuilderTests
|
||||
result.Items.Head().FinishOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(6));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Timeout(2000)]
|
||||
public async Task OnlyFileNotFoundItem_Should_Abort()
|
||||
{
|
||||
var mediaItems = new List<MediaItem>
|
||||
{
|
||||
TestMovie(1, TimeSpan.FromHours(1), DateTime.Today)
|
||||
};
|
||||
|
||||
mediaItems[0].State = MediaItemState.FileNotFound;
|
||||
|
||||
var configRepo = new Mock<IConfigElementRepository>();
|
||||
configRepo.Setup(
|
||||
repo => repo.GetValue<bool>(
|
||||
It.Is<ConfigElementKey>(k => k.Key == ConfigElementKey.PlayoutSkipMissingItems.Key)))
|
||||
.ReturnsAsync(Some(true));
|
||||
|
||||
(PlayoutBuilder builder, Playout playout) =
|
||||
TestDataFloodForItems(mediaItems, PlaybackOrder.Random, configRepo);
|
||||
|
||||
Playout result = await builder.Build(playout, PlayoutBuildMode.Reset);
|
||||
|
||||
configRepo.Verify();
|
||||
|
||||
result.Items.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task FileNotFoundItem_Should_BeSkipped()
|
||||
{
|
||||
var mediaItems = new List<MediaItem>
|
||||
{
|
||||
TestMovie(1, TimeSpan.FromHours(1), DateTime.Today),
|
||||
TestMovie(2, TimeSpan.FromHours(6), DateTime.Today)
|
||||
};
|
||||
|
||||
mediaItems[0].State = MediaItemState.FileNotFound;
|
||||
|
||||
var configRepo = new Mock<IConfigElementRepository>();
|
||||
configRepo.Setup(
|
||||
repo => repo.GetValue<bool>(
|
||||
It.Is<ConfigElementKey>(k => k.Key == ConfigElementKey.PlayoutSkipMissingItems.Key)))
|
||||
.ReturnsAsync(Some(true));
|
||||
|
||||
(PlayoutBuilder builder, Playout playout) =
|
||||
TestDataFloodForItems(mediaItems, PlaybackOrder.Random, configRepo);
|
||||
DateTimeOffset start = HoursAfterMidnight(0);
|
||||
DateTimeOffset finish = start + TimeSpan.FromHours(6);
|
||||
|
||||
Playout result = await builder.Build(playout, PlayoutBuildMode.Reset, start, finish);
|
||||
|
||||
configRepo.Verify();
|
||||
|
||||
result.Items.Count.Should().Be(1);
|
||||
result.Items.Head().MediaItemId.Should().Be(2);
|
||||
result.Items.Head().StartOffset.TimeOfDay.Should().Be(TimeSpan.Zero);
|
||||
result.Items.Head().FinishOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(6));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Timeout(2000)]
|
||||
public async Task OnlyUnavailableItem_Should_Abort()
|
||||
{
|
||||
var mediaItems = new List<MediaItem>
|
||||
{
|
||||
TestMovie(1, TimeSpan.FromHours(1), DateTime.Today)
|
||||
};
|
||||
|
||||
mediaItems[0].State = MediaItemState.Unavailable;
|
||||
|
||||
var configRepo = new Mock<IConfigElementRepository>();
|
||||
configRepo.Setup(
|
||||
repo => repo.GetValue<bool>(
|
||||
It.Is<ConfigElementKey>(k => k.Key == ConfigElementKey.PlayoutSkipMissingItems.Key)))
|
||||
.ReturnsAsync(Some(true));
|
||||
|
||||
(PlayoutBuilder builder, Playout playout) =
|
||||
TestDataFloodForItems(mediaItems, PlaybackOrder.Random, configRepo);
|
||||
|
||||
Playout result = await builder.Build(playout, PlayoutBuildMode.Reset);
|
||||
|
||||
configRepo.Verify();
|
||||
|
||||
result.Items.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task UnavailableItem_Should_BeSkipped()
|
||||
{
|
||||
var mediaItems = new List<MediaItem>
|
||||
{
|
||||
TestMovie(1, TimeSpan.FromHours(1), DateTime.Today),
|
||||
TestMovie(2, TimeSpan.FromHours(6), DateTime.Today)
|
||||
};
|
||||
|
||||
mediaItems[0].State = MediaItemState.Unavailable;
|
||||
|
||||
var configRepo = new Mock<IConfigElementRepository>();
|
||||
configRepo.Setup(
|
||||
repo => repo.GetValue<bool>(
|
||||
It.Is<ConfigElementKey>(k => k.Key == ConfigElementKey.PlayoutSkipMissingItems.Key)))
|
||||
.ReturnsAsync(Some(true));
|
||||
|
||||
(PlayoutBuilder builder, Playout playout) =
|
||||
TestDataFloodForItems(mediaItems, PlaybackOrder.Random, configRepo);
|
||||
DateTimeOffset start = HoursAfterMidnight(0);
|
||||
DateTimeOffset finish = start + TimeSpan.FromHours(6);
|
||||
|
||||
Playout result = await builder.Build(playout, PlayoutBuildMode.Reset, start, finish);
|
||||
|
||||
configRepo.Verify();
|
||||
|
||||
result.Items.Count.Should().Be(1);
|
||||
result.Items.Head().MediaItemId.Should().Be(2);
|
||||
result.Items.Head().StartOffset.TimeOfDay.Should().Be(TimeSpan.Zero);
|
||||
result.Items.Head().FinishOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(6));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task FileNotFound_Should_NotBeSkippedIfConfigured()
|
||||
{
|
||||
var mediaItems = new List<MediaItem>
|
||||
{
|
||||
TestMovie(1, TimeSpan.FromHours(6), DateTime.Today)
|
||||
};
|
||||
|
||||
mediaItems[0].State = MediaItemState.FileNotFound;
|
||||
|
||||
var configRepo = new Mock<IConfigElementRepository>();
|
||||
configRepo.Setup(
|
||||
repo => repo.GetValue<bool>(
|
||||
It.Is<ConfigElementKey>(k => k.Key == ConfigElementKey.PlayoutSkipMissingItems.Key)))
|
||||
.ReturnsAsync(Some(false));
|
||||
|
||||
(PlayoutBuilder builder, Playout playout) =
|
||||
TestDataFloodForItems(mediaItems, PlaybackOrder.Random, configRepo);
|
||||
DateTimeOffset start = HoursAfterMidnight(0);
|
||||
DateTimeOffset finish = start + TimeSpan.FromHours(6);
|
||||
|
||||
Playout result = await builder.Build(playout, PlayoutBuildMode.Reset, start, finish);
|
||||
|
||||
result.Items.Count.Should().Be(1);
|
||||
result.Items.Head().StartOffset.TimeOfDay.Should().Be(TimeSpan.Zero);
|
||||
result.Items.Head().FinishOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(6));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Unavailable_Should_NotBeSkippedIfConfigured()
|
||||
{
|
||||
var mediaItems = new List<MediaItem>
|
||||
{
|
||||
TestMovie(1, TimeSpan.FromHours(6), DateTime.Today)
|
||||
};
|
||||
|
||||
mediaItems[0].State = MediaItemState.Unavailable;
|
||||
|
||||
var configRepo = new Mock<IConfigElementRepository>();
|
||||
configRepo.Setup(
|
||||
repo => repo.GetValue<bool>(
|
||||
It.Is<ConfigElementKey>(k => k.Key == ConfigElementKey.PlayoutSkipMissingItems.Key)))
|
||||
.ReturnsAsync(Some(false));
|
||||
|
||||
(PlayoutBuilder builder, Playout playout) =
|
||||
TestDataFloodForItems(mediaItems, PlaybackOrder.Random, configRepo);
|
||||
DateTimeOffset start = HoursAfterMidnight(0);
|
||||
DateTimeOffset finish = start + TimeSpan.FromHours(6);
|
||||
|
||||
Playout result = await builder.Build(playout, PlayoutBuildMode.Reset, start, finish);
|
||||
|
||||
result.Items.Count.Should().Be(1);
|
||||
result.Items.Head().StartOffset.TimeOfDay.Should().Be(TimeSpan.Zero);
|
||||
result.Items.Head().FinishOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(6));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task InitialFlood_Should_StartAtMidnight()
|
||||
{
|
||||
@@ -2142,11 +2316,20 @@ public class PlayoutBuilderTests
|
||||
MovieMetadata = new List<MovieMetadata> { new() { ReleaseDate = aired } },
|
||||
MediaVersions = new List<MediaVersion>
|
||||
{
|
||||
new() { Duration = duration }
|
||||
new()
|
||||
{
|
||||
Duration = duration, MediaFiles = new List<MediaFile>
|
||||
{
|
||||
new() { Path = $"/fake/path/{id}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private TestData TestDataFloodForItems(List<MediaItem> mediaItems, PlaybackOrder playbackOrder)
|
||||
private TestData TestDataFloodForItems(
|
||||
List<MediaItem> mediaItems,
|
||||
PlaybackOrder playbackOrder,
|
||||
Mock<IConfigElementRepository> configMock = null)
|
||||
{
|
||||
var mediaCollection = new Collection
|
||||
{
|
||||
@@ -2154,7 +2337,8 @@ public class PlayoutBuilderTests
|
||||
MediaItems = mediaItems
|
||||
};
|
||||
|
||||
var configRepo = new Mock<IConfigElementRepository>();
|
||||
Mock<IConfigElementRepository> configRepo = configMock ?? new Mock<IConfigElementRepository>();
|
||||
|
||||
var collectionRepo = new FakeMediaCollectionRepository(Map((mediaCollection.Id, mediaItems)));
|
||||
var televisionRepo = new FakeTelevisionRepository();
|
||||
var artistRepo = new Mock<IArtistRepository>();
|
||||
|
||||
@@ -33,4 +33,5 @@ public class ConfigElementKey
|
||||
public static ConfigElementKey FillerPresetsPageSize => new("pages.filler_presets.page_size");
|
||||
public static ConfigElementKey LibraryRefreshInterval => new("scanner.library_refresh_interval");
|
||||
public static ConfigElementKey PlayoutDaysToBuild => new("playout.days_to_build");
|
||||
public static ConfigElementKey PlayoutSkipMissingItems => new("playout.skip_missing_items");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using ErsatzTV.Core.Domain;
|
||||
using ErsatzTV.Core.Extensions;
|
||||
using ErsatzTV.Core.Interfaces.Repositories;
|
||||
using ErsatzTV.Core.Interfaces.Scheduling;
|
||||
using LanguageExt.UnsafeValueAccess;
|
||||
@@ -234,7 +235,13 @@ public class PlayoutBuilder : IPlayoutBuilder
|
||||
return None;
|
||||
}
|
||||
|
||||
Option<CollectionKey> maybeEmptyCollection = await CheckForEmptyCollections(collectionMediaItems);
|
||||
Option<bool> skipMissingItems =
|
||||
await _configElementRepository.GetValue<bool>(ConfigElementKey.PlayoutSkipMissingItems);
|
||||
|
||||
Option<CollectionKey> maybeEmptyCollection = await CheckForEmptyCollections(
|
||||
collectionMediaItems,
|
||||
await skipMissingItems.IfNoneAsync(false));
|
||||
|
||||
foreach (CollectionKey emptyCollection in maybeEmptyCollection)
|
||||
{
|
||||
Option<string> maybeName = await _mediaCollectionRepository.GetNameFromKey(emptyCollection);
|
||||
@@ -496,12 +503,13 @@ public class PlayoutBuilder : IPlayoutBuilder
|
||||
}
|
||||
|
||||
private async Task<Option<CollectionKey>> CheckForEmptyCollections(
|
||||
Map<CollectionKey, List<MediaItem>> collectionMediaItems)
|
||||
Map<CollectionKey, List<MediaItem>> collectionMediaItems,
|
||||
bool skipMissingItems)
|
||||
{
|
||||
foreach ((CollectionKey _, List<MediaItem> items) in collectionMediaItems)
|
||||
{
|
||||
var zeroItems = new List<MediaItem>();
|
||||
// var missingItems = new List<MediaItem>();
|
||||
var missingItems = new List<MediaItem>();
|
||||
|
||||
foreach (MediaItem item in items)
|
||||
{
|
||||
@@ -520,18 +528,17 @@ public class PlayoutBuilder : IPlayoutBuilder
|
||||
_ => true
|
||||
};
|
||||
|
||||
// if (item.State == MediaItemState.FileNotFound)
|
||||
// {
|
||||
// _logger.LogWarning(
|
||||
// "Skipping media item that does not exist on disk {MediaItem} - {MediaItemTitle} - {Path}",
|
||||
// item.Id,
|
||||
// DisplayTitle(item),
|
||||
// item.GetHeadVersion().MediaFiles.Head().Path);
|
||||
//
|
||||
// missingItems.Add(item);
|
||||
// }
|
||||
// else
|
||||
if (isZero)
|
||||
if (skipMissingItems && item.State is MediaItemState.FileNotFound or MediaItemState.Unavailable)
|
||||
{
|
||||
_logger.LogWarning(
|
||||
"Skipping media item that does not exist on disk {MediaItem} - {MediaItemTitle} - {Path}",
|
||||
item.Id,
|
||||
DisplayTitle(item),
|
||||
item.GetHeadVersion().MediaFiles.Head().Path);
|
||||
|
||||
missingItems.Add(item);
|
||||
}
|
||||
else if (isZero)
|
||||
{
|
||||
_logger.LogWarning(
|
||||
"Skipping media item with zero duration {MediaItem} - {MediaItemTitle}",
|
||||
@@ -542,7 +549,7 @@ public class PlayoutBuilder : IPlayoutBuilder
|
||||
}
|
||||
}
|
||||
|
||||
// items.RemoveAll(missingItems.Contains);
|
||||
items.RemoveAll(missingItems.Contains);
|
||||
items.RemoveAll(zeroItems.Contains);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
@using ErsatzTV.Application.MediaItems
|
||||
@using ErsatzTV.Application.Watermarks
|
||||
@using System.Globalization
|
||||
@using ErsatzTV.Core.Domain.Filler
|
||||
@using ErsatzTV.Application.Configuration
|
||||
@using ErsatzTV.Core.Domain.Filler
|
||||
@implements IDisposable
|
||||
@inject IMediator _mediator
|
||||
@inject ISnackbar _snackbar
|
||||
@@ -147,12 +147,19 @@
|
||||
<MudForm @bind-IsValid="@_playoutSuccess">
|
||||
<MudTextField T="int"
|
||||
Label="Days To Build"
|
||||
@bind-Value="_playoutDaysToBuild"
|
||||
@bind-Value="_playoutSettings.DaysToBuild"
|
||||
Validation="@(new Func<int, string>(ValidatePlayoutDaysToBuild))"
|
||||
Required="true"
|
||||
RequiredError="Days to build is required!"
|
||||
Adornment="Adornment.End"
|
||||
AdornmentText="Days"/>
|
||||
<MudElement HtmlTag="div" Class="mt-3">
|
||||
<MudTooltip Text="Controls whether file-not-found or unavailable items should be included in playouts">
|
||||
<MudCheckBox Label="Skip Missing Items"
|
||||
@bind-Checked="_playoutSettings.SkipMissingItems"
|
||||
For="@(() => _playoutSettings.SkipMissingItems)"/>
|
||||
</MudTooltip>
|
||||
</MudElement>
|
||||
</MudForm>
|
||||
</MudCardContent>
|
||||
<MudCardActions>
|
||||
@@ -176,7 +183,7 @@
|
||||
private List<FillerPresetViewModel> _fillerPresets;
|
||||
private int _tunerCount;
|
||||
private int _libraryRefreshInterval;
|
||||
private int _playoutDaysToBuild;
|
||||
private PlayoutSettingsViewModel _playoutSettings;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
@@ -198,8 +205,8 @@
|
||||
_hdhrSuccess = string.IsNullOrWhiteSpace(ValidateTunerCount(_tunerCount));
|
||||
_libraryRefreshInterval = await _mediator.Send(new GetLibraryRefreshInterval(), _cts.Token);
|
||||
_scannerSuccess = _libraryRefreshInterval > 0;
|
||||
_playoutDaysToBuild = await _mediator.Send(new GetPlayoutDaysToBuild(), _cts.Token);
|
||||
_playoutSuccess = _playoutDaysToBuild > 0;
|
||||
_playoutSettings = await _mediator.Send(new GetPlayoutSettings(), _cts.Token);
|
||||
_playoutSuccess = _playoutSettings.DaysToBuild > 0;
|
||||
}
|
||||
|
||||
private static string ValidatePathExists(string path) => !File.Exists(path) ? "Path does not exist" : null;
|
||||
@@ -257,7 +264,7 @@
|
||||
|
||||
private async Task SavePlayoutSettings()
|
||||
{
|
||||
Either<BaseError, Unit> result = await _mediator.Send(new UpdatePlayoutDaysToBuild(_playoutDaysToBuild), _cts.Token);
|
||||
Either<BaseError, Unit> result = await _mediator.Send(new UpdatePlayoutSettings(_playoutSettings), _cts.Token);
|
||||
result.Match(
|
||||
Left: error =>
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user