From a6496db58db2c9be16f8680f3c0c41a856e3ee92 Mon Sep 17 00:00:00 2001 From: Jason Dove Date: Mon, 5 Apr 2021 19:48:17 -0500 Subject: [PATCH] settings rework (#144) * add hdhr tuner count setting * code cleanup --- .../HDHR/Commands/UpdateHDHRTunerCount.cs | 7 + .../Commands/UpdateHDHRTunerCountHandler.cs | 45 +++++++ .../HDHR/Queries/GetHDHRTunerCount.cs | 6 + .../HDHR/Queries/GetHDHRTunerCountHandler.cs | 21 +++ .../Commands/RebuildSearchIndexHandler.cs | 2 +- ErsatzTV.Core/Domain/ConfigElementKey.cs | 1 + .../Metadata/MusicVideoFolderScanner.cs | 2 +- ErsatzTV/Controllers/HdhrController.cs | 8 +- ErsatzTV/Pages/FFmpeg.razor | 71 +---------- ErsatzTV/Pages/Movie.razor | 2 +- ErsatzTV/Pages/MovieList.razor | 5 +- ErsatzTV/Pages/MusicVideoList.razor | 5 +- ErsatzTV/Pages/Settings.razor | 120 ++++++++++++++++++ ErsatzTV/Pages/TelevisionEpisodeList.razor | 2 +- ErsatzTV/Pages/TelevisionSeasonList.razor | 2 +- ErsatzTV/Pages/TelevisionShowList.razor | 5 +- ErsatzTV/Shared/FragmentLetterAnchor.razor | 5 +- ErsatzTV/Shared/MainLayout.razor | 3 +- 18 files changed, 229 insertions(+), 83 deletions(-) create mode 100644 ErsatzTV.Application/HDHR/Commands/UpdateHDHRTunerCount.cs create mode 100644 ErsatzTV.Application/HDHR/Commands/UpdateHDHRTunerCountHandler.cs create mode 100644 ErsatzTV.Application/HDHR/Queries/GetHDHRTunerCount.cs create mode 100644 ErsatzTV.Application/HDHR/Queries/GetHDHRTunerCountHandler.cs create mode 100644 ErsatzTV/Pages/Settings.razor diff --git a/ErsatzTV.Application/HDHR/Commands/UpdateHDHRTunerCount.cs b/ErsatzTV.Application/HDHR/Commands/UpdateHDHRTunerCount.cs new file mode 100644 index 000000000..68379df93 --- /dev/null +++ b/ErsatzTV.Application/HDHR/Commands/UpdateHDHRTunerCount.cs @@ -0,0 +1,7 @@ +using ErsatzTV.Core; +using LanguageExt; + +namespace ErsatzTV.Application.HDHR.Commands +{ + public record UpdateHDHRTunerCount(int TunerCount) : MediatR.IRequest>; +} diff --git a/ErsatzTV.Application/HDHR/Commands/UpdateHDHRTunerCountHandler.cs b/ErsatzTV.Application/HDHR/Commands/UpdateHDHRTunerCountHandler.cs new file mode 100644 index 000000000..7186ffc1d --- /dev/null +++ b/ErsatzTV.Application/HDHR/Commands/UpdateHDHRTunerCountHandler.cs @@ -0,0 +1,45 @@ +using System.Threading; +using System.Threading.Tasks; +using ErsatzTV.Core; +using ErsatzTV.Core.Domain; +using ErsatzTV.Core.Interfaces.Repositories; +using LanguageExt; +using static LanguageExt.Prelude; + +namespace ErsatzTV.Application.HDHR.Commands +{ + public class UpdateHDHRTunerCountHandler : MediatR.IRequestHandler> + { + private readonly IConfigElementRepository _configElementRepository; + + public UpdateHDHRTunerCountHandler(IConfigElementRepository configElementRepository) => + _configElementRepository = configElementRepository; + + public Task> Handle( + UpdateHDHRTunerCount request, + CancellationToken cancellationToken) => + Validate(request) + .MapT(_ => Upsert(ConfigElementKey.HDHRTunerCount, request.TunerCount.ToString())) + .Bind(v => v.ToEitherAsync()); + + private Task> Validate(UpdateHDHRTunerCount request) => + Optional(request.TunerCount) + .Filter(tc => tc > 0) + .Map(_ => Unit.Default) + .ToValidation("Tuner count must be greater than zero") + .AsTask(); + + private Task Upsert(ConfigElementKey key, string value) => + _configElementRepository.Get(key).Match( + ce => + { + ce.Value = value; + return _configElementRepository.Update(ce); + }, + () => + { + var ce = new ConfigElement { Key = key.Key, Value = value }; + return _configElementRepository.Add(ce); + }).ToUnit(); + } +} diff --git a/ErsatzTV.Application/HDHR/Queries/GetHDHRTunerCount.cs b/ErsatzTV.Application/HDHR/Queries/GetHDHRTunerCount.cs new file mode 100644 index 000000000..97f242748 --- /dev/null +++ b/ErsatzTV.Application/HDHR/Queries/GetHDHRTunerCount.cs @@ -0,0 +1,6 @@ +using MediatR; + +namespace ErsatzTV.Application.HDHR.Queries +{ + public record GetHDHRTunerCount : IRequest; +} diff --git a/ErsatzTV.Application/HDHR/Queries/GetHDHRTunerCountHandler.cs b/ErsatzTV.Application/HDHR/Queries/GetHDHRTunerCountHandler.cs new file mode 100644 index 000000000..e5c3528eb --- /dev/null +++ b/ErsatzTV.Application/HDHR/Queries/GetHDHRTunerCountHandler.cs @@ -0,0 +1,21 @@ +using System.Threading; +using System.Threading.Tasks; +using ErsatzTV.Core.Domain; +using ErsatzTV.Core.Interfaces.Repositories; +using LanguageExt; +using MediatR; + +namespace ErsatzTV.Application.HDHR.Queries +{ + public class GetHDHRTunerCountHandler : IRequestHandler + { + private readonly IConfigElementRepository _configElementRepository; + + public GetHDHRTunerCountHandler(IConfigElementRepository configElementRepository) => + _configElementRepository = configElementRepository; + + public Task Handle(GetHDHRTunerCount request, CancellationToken cancellationToken) => + _configElementRepository.GetValue(ConfigElementKey.HDHRTunerCount) + .Map(result => result.IfNone(2)); + } +} diff --git a/ErsatzTV.Application/Search/Commands/RebuildSearchIndexHandler.cs b/ErsatzTV.Application/Search/Commands/RebuildSearchIndexHandler.cs index 19bcf349f..993ab1a7a 100644 --- a/ErsatzTV.Application/Search/Commands/RebuildSearchIndexHandler.cs +++ b/ErsatzTV.Application/Search/Commands/RebuildSearchIndexHandler.cs @@ -39,7 +39,7 @@ namespace ErsatzTV.Application.Search.Commands bool indexFolderExists = Directory.Exists(FileSystemLayout.SearchIndexFolder); await _searchIndex.Initialize(_localFileSystem); - + if (!indexFolderExists || await _configElementRepository.GetValue(ConfigElementKey.SearchIndexVersion) < _searchIndex.Version) diff --git a/ErsatzTV.Core/Domain/ConfigElementKey.cs b/ErsatzTV.Core/Domain/ConfigElementKey.cs index 9a3e96836..329149a92 100644 --- a/ErsatzTV.Core/Domain/ConfigElementKey.cs +++ b/ErsatzTV.Core/Domain/ConfigElementKey.cs @@ -13,5 +13,6 @@ public static ConfigElementKey FFmpegSaveReports => new("ffmpeg.save_reports"); public static ConfigElementKey FFmpegPreferredLanguageCode => new("ffmpeg.preferred_language_code"); public static ConfigElementKey SearchIndexVersion => new("search_index.version"); + public static ConfigElementKey HDHRTunerCount => new("hdhr.tuner_count"); } } diff --git a/ErsatzTV.Core/Metadata/MusicVideoFolderScanner.cs b/ErsatzTV.Core/Metadata/MusicVideoFolderScanner.cs index d1065b3ee..9246e9682 100644 --- a/ErsatzTV.Core/Metadata/MusicVideoFolderScanner.cs +++ b/ErsatzTV.Core/Metadata/MusicVideoFolderScanner.cs @@ -132,7 +132,7 @@ namespace ErsatzTV.Core.Metadata await _searchIndex.RemoveItems(ids); } } - + _searchIndex.Commit(); return Unit.Default; } diff --git a/ErsatzTV/Controllers/HdhrController.cs b/ErsatzTV/Controllers/HdhrController.cs index e294788f0..af9a30e67 100644 --- a/ErsatzTV/Controllers/HdhrController.cs +++ b/ErsatzTV/Controllers/HdhrController.cs @@ -1,7 +1,9 @@ using System.Threading.Tasks; using ErsatzTV.Application.Channels.Queries; +using ErsatzTV.Application.HDHR.Queries; using ErsatzTV.Core.Hdhr; using ErsatzTV.Extensions; +using LanguageExt; using MediatR; using Microsoft.AspNetCore.Mvc; @@ -20,8 +22,10 @@ namespace ErsatzTV.Controllers new OkObjectResult(new DeviceXml(Request.Scheme, Request.Host.ToString())); [HttpGet("discover.json")] - public IActionResult Discover() => - new OkObjectResult(new Discover(Request.Scheme, Request.Host.ToString(), 2)); + [ResponseCache(NoStore = true)] + public Task Discover() => + _mediator.Send(new GetHDHRTunerCount()).Map( + tunerCount => new OkObjectResult(new Discover(Request.Scheme, Request.Host.ToString(), tunerCount))); [HttpGet("lineup_status.json")] public IActionResult LineupStatus() => diff --git a/ErsatzTV/Pages/FFmpeg.razor b/ErsatzTV/Pages/FFmpeg.razor index e809e28a7..e0fdf9a13 100644 --- a/ErsatzTV/Pages/FFmpeg.razor +++ b/ErsatzTV/Pages/FFmpeg.razor @@ -2,55 +2,13 @@ @using ErsatzTV.Application.FFmpegProfiles @using ErsatzTV.Application.FFmpegProfiles.Commands @using ErsatzTV.Application.FFmpegProfiles.Queries -@using ErsatzTV.Application.MediaItems.Queries -@using System.Globalization -@using Unit = LanguageExt.Unit @inject IDialogService Dialog @inject IMediator Mediator @inject ILogger Logger @inject ISnackbar Snackbar - - - - FFmpeg Settings - - - - - - - - - - - @foreach (FFmpegProfileViewModel profile in _ffmpegProfiles) - { - @profile.Name - } - - - - @foreach (CultureInfo culture in _availableCultures) - { - @culture.EnglishName - } - - - - - - - - Save Settings - - - - + FFmpeg Profiles @@ -114,34 +72,9 @@ @code { - - private bool _success; - private FFmpegSettingsViewModel _ffmpegSettings; - private List _ffmpegProfiles; - private List _availableCultures; - - protected override async Task OnParametersSetAsync() - { - _ffmpegSettings = await Mediator.Send(new GetFFmpegSettings()); - _success = File.Exists(_ffmpegSettings.FFmpegPath) && File.Exists(_ffmpegSettings.FFprobePath); - await LoadFFmpegProfilesAsync(); - _availableCultures = await Mediator.Send(new GetAllLanguageCodes()); - } - - private async Task SaveSettings() - { - Either result = await Mediator.Send(new UpdateFFmpegSettings(_ffmpegSettings)); - result.Match( - Left: error => - { - Snackbar.Add(error.Value, Severity.Error); - Logger.LogError("Unexpected error saving FFmpeg settings: {Error}", error.Value); - }, - Right: _ => Snackbar.Add("Successfully saved FFmpeg settings", Severity.Success)); - } - private static string ValidatePathExists(string path) => !File.Exists(path) ? "Path does not exist" : null; + protected override async Task OnParametersSetAsync() => await LoadFFmpegProfilesAsync(); private async Task LoadFFmpegProfilesAsync() => _ffmpegProfiles = await Mediator.Send(new GetAllFFmpegProfiles()); diff --git a/ErsatzTV/Pages/Movie.razor b/ErsatzTV/Pages/Movie.razor index 4b17aa961..f24323d95 100644 --- a/ErsatzTV/Pages/Movie.razor +++ b/ErsatzTV/Pages/Movie.razor @@ -19,7 +19,7 @@ @if (!string.IsNullOrWhiteSpace(_movie.Poster)) { movie poster }
diff --git a/ErsatzTV/Pages/MovieList.razor b/ErsatzTV/Pages/MovieList.razor index 2b21c9cf1..8394befa3 100644 --- a/ErsatzTV/Pages/MovieList.razor +++ b/ErsatzTV/Pages/MovieList.razor @@ -130,7 +130,10 @@ private void SelectClicked(MediaCardViewModel card, MouseEventArgs e) { - List GetSortedItems() => _data.Cards.OrderBy(m => m.SortTitle).ToList(); + List GetSortedItems() + { + return _data.Cards.OrderBy(m => m.SortTitle).ToList(); + } SelectClicked(GetSortedItems, card, e); } diff --git a/ErsatzTV/Pages/MusicVideoList.razor b/ErsatzTV/Pages/MusicVideoList.razor index c90b0ef48..dda224e7f 100644 --- a/ErsatzTV/Pages/MusicVideoList.razor +++ b/ErsatzTV/Pages/MusicVideoList.razor @@ -131,7 +131,10 @@ private void SelectClicked(MediaCardViewModel card, MouseEventArgs e) { - List GetSortedItems() => _data.Cards.OrderBy(m => m.SortTitle).ToList(); + List GetSortedItems() + { + return _data.Cards.OrderBy(m => m.SortTitle).ToList(); + } SelectClicked(GetSortedItems, card, e); } diff --git a/ErsatzTV/Pages/Settings.razor b/ErsatzTV/Pages/Settings.razor new file mode 100644 index 000000000..a20439dda --- /dev/null +++ b/ErsatzTV/Pages/Settings.razor @@ -0,0 +1,120 @@ +@page "/settings" +@using ErsatzTV.Application.FFmpegProfiles +@using ErsatzTV.Application.FFmpegProfiles.Commands +@using ErsatzTV.Application.FFmpegProfiles.Queries +@using ErsatzTV.Application.HDHR.Commands +@using ErsatzTV.Application.HDHR.Queries +@using ErsatzTV.Application.MediaItems.Queries +@using System.Globalization +@using Unit = LanguageExt.Unit +@inject IMediator Mediator +@inject ISnackbar Snackbar +@inject ILogger Logger + + + + + + FFmpeg Settings + + + + + + + + + + + @foreach (FFmpegProfileViewModel profile in _ffmpegProfiles) + { + @profile.Name + } + + + + @foreach (CultureInfo culture in _availableCultures) + { + @culture.EnglishName + } + + + + + + + + Save Settings + + + + + + HDHomeRun Settings + + + + + + + + + Save Settings + + + + +@code { + private bool _success; + private bool _hdhrSuccess; + private List _ffmpegProfiles; + private FFmpegSettingsViewModel _ffmpegSettings; + private List _availableCultures; + private int _tunerCount; + + protected override async Task OnParametersSetAsync() + { + await LoadFFmpegProfilesAsync(); + + _ffmpegSettings = await Mediator.Send(new GetFFmpegSettings()); + _success = File.Exists(_ffmpegSettings.FFmpegPath) && File.Exists(_ffmpegSettings.FFprobePath); + _availableCultures = await Mediator.Send(new GetAllLanguageCodes()); + _tunerCount = await Mediator.Send(new GetHDHRTunerCount()); + _hdhrSuccess = string.IsNullOrWhiteSpace(ValidateTunerCount(_tunerCount)); + } + + private static string ValidatePathExists(string path) => !File.Exists(path) ? "Path does not exist" : null; + + private static string ValidateTunerCount(int tunerCount) => tunerCount <= 0 ? "Tuner count must be greater than zero" : null; + + private async Task LoadFFmpegProfilesAsync() => + _ffmpegProfiles = await Mediator.Send(new GetAllFFmpegProfiles()); + + private async Task SaveFFmpegSettings() + { + Either result = await Mediator.Send(new UpdateFFmpegSettings(_ffmpegSettings)); + result.Match( + Left: error => + { + Snackbar.Add(error.Value, Severity.Error); + Logger.LogError("Unexpected error saving FFmpeg settings: {Error}", error.Value); + }, + Right: _ => Snackbar.Add("Successfully saved FFmpeg settings", Severity.Success)); + } + + private async Task SaveHDHRSettings() + { + Either result = await Mediator.Send(new UpdateHDHRTunerCount(_tunerCount)); + result.Match( + Left: error => + { + Snackbar.Add(error.Value, Severity.Error); + Logger.LogError("Unexpected error saving HDHomeRun settings: {Error}", error.Value); + }, + Right: _ => Snackbar.Add("Successfully saved HDHomeRun settings", Severity.Success)); + } + +} \ No newline at end of file diff --git a/ErsatzTV/Pages/TelevisionEpisodeList.razor b/ErsatzTV/Pages/TelevisionEpisodeList.razor index 4959a5c5a..63385e472 100644 --- a/ErsatzTV/Pages/TelevisionEpisodeList.razor +++ b/ErsatzTV/Pages/TelevisionEpisodeList.razor @@ -29,7 +29,7 @@ @if (!string.IsNullOrWhiteSpace(_season.Poster)) { show poster }
diff --git a/ErsatzTV/Pages/TelevisionSeasonList.razor b/ErsatzTV/Pages/TelevisionSeasonList.razor index f64e6d216..650a91a77 100644 --- a/ErsatzTV/Pages/TelevisionSeasonList.razor +++ b/ErsatzTV/Pages/TelevisionSeasonList.razor @@ -27,7 +27,7 @@ @if (!string.IsNullOrWhiteSpace(_show.Poster)) { show poster }
diff --git a/ErsatzTV/Pages/TelevisionShowList.razor b/ErsatzTV/Pages/TelevisionShowList.razor index 6a6f124ea..285055352 100644 --- a/ErsatzTV/Pages/TelevisionShowList.razor +++ b/ErsatzTV/Pages/TelevisionShowList.razor @@ -130,7 +130,10 @@ private void SelectClicked(MediaCardViewModel card, MouseEventArgs e) { - List GetSortedItems() => _data.Cards.OrderBy(m => m.SortTitle).ToList(); + List GetSortedItems() + { + return _data.Cards.OrderBy(m => m.SortTitle).ToList(); + } SelectClicked(GetSortedItems, card, e); } diff --git a/ErsatzTV/Shared/FragmentLetterAnchor.razor b/ErsatzTV/Shared/FragmentLetterAnchor.razor index 7af7fcc0b..1ee3daa6c 100644 --- a/ErsatzTV/Shared/FragmentLetterAnchor.razor +++ b/ErsatzTV/Shared/FragmentLetterAnchor.razor @@ -1,5 +1,4 @@ -@using ErsatzTV.Application.MediaCards -@using LanguageExt.UnsafeValueAccess +@using LanguageExt.UnsafeValueAccess @typeparam TCard @{ var letters = new System.Collections.Generic.HashSet(); } @@ -25,4 +24,4 @@ { @ChildContent } -} +} \ No newline at end of file diff --git a/ErsatzTV/Shared/MainLayout.razor b/ErsatzTV/Shared/MainLayout.razor index dfeafe3cc..ef3285676 100644 --- a/ErsatzTV/Shared/MainLayout.razor +++ b/ErsatzTV/Shared/MainLayout.razor @@ -39,7 +39,7 @@ Channels - FFmpeg + FFmpeg Profiles Plex @@ -52,6 +52,7 @@ Schedules Playouts + Settings Logs