diff --git a/CHANGELOG.md b/CHANGELOG.md index bbcf20583..adefc04c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Changed - Upgrade to dotnet 7 - Upgrade all docker images to ubuntu jammy and ffmpeg 5.1.2 +- Limit library scan interval between 0 and 1,000,000 + - 0 means do not automatically scan libraries + - 1 to 999,999 means scan if it has been that many hours since the last scan ## [0.7.0-beta] - 2022-12-11 ### Fixed diff --git a/ErsatzTV.Application/Configuration/Commands/UpdateLibraryRefreshIntervalHandler.cs b/ErsatzTV.Application/Configuration/Commands/UpdateLibraryRefreshIntervalHandler.cs index b2f503f71..390e2da42 100644 --- a/ErsatzTV.Application/Configuration/Commands/UpdateLibraryRefreshIntervalHandler.cs +++ b/ErsatzTV.Application/Configuration/Commands/UpdateLibraryRefreshIntervalHandler.cs @@ -24,8 +24,8 @@ public class UpdateLibraryRefreshIntervalHandler : private static Task> Validate(UpdateLibraryRefreshInterval request) => Optional(request.LibraryRefreshInterval) - .Where(lri => lri > 0) + .Where(lri => lri is >= 0 and < 1_000_000) .Map(_ => Unit.Default) - .ToValidation("Tuner count must be greater than zero") + .ToValidation("Library refresh interval must be zero or greated") .AsTask(); } diff --git a/ErsatzTV.Application/Emby/Commands/SynchronizeEmbyLibraryByIdHandler.cs b/ErsatzTV.Application/Emby/Commands/SynchronizeEmbyLibraryByIdHandler.cs index 9446542cb..a0b5931b9 100644 --- a/ErsatzTV.Application/Emby/Commands/SynchronizeEmbyLibraryByIdHandler.cs +++ b/ErsatzTV.Application/Emby/Commands/SynchronizeEmbyLibraryByIdHandler.cs @@ -72,7 +72,7 @@ public class SynchronizeEmbyLibraryByIdHandler : { var lastScan = new DateTimeOffset(parameters.Library.LastScan ?? SystemTime.MinValueUtc, TimeSpan.Zero); DateTimeOffset nextScan = lastScan + TimeSpan.FromHours(parameters.LibraryRefreshInterval); - if (parameters.ForceScan || nextScan < DateTimeOffset.Now) + if (parameters.ForceScan || (parameters.LibraryRefreshInterval > 0 && nextScan < DateTimeOffset.Now)) { Either result = parameters.Library.MediaKind switch { @@ -173,7 +173,7 @@ public class SynchronizeEmbyLibraryByIdHandler : private Task> ValidateLibraryRefreshInterval() => _configElementRepository.GetValue(ConfigElementKey.LibraryRefreshInterval) - .FilterT(lri => lri > 0) + .FilterT(lri => lri is >= 0 and < 1_000_000) .Map(lri => lri.ToValidation("Library refresh interval is invalid")); private Task> ValidateFFmpegPath() => diff --git a/ErsatzTV.Application/Jellyfin/Commands/SynchronizeJellyfinLibraryByIdHandler.cs b/ErsatzTV.Application/Jellyfin/Commands/SynchronizeJellyfinLibraryByIdHandler.cs index 52b06cd14..a3c14e9b1 100644 --- a/ErsatzTV.Application/Jellyfin/Commands/SynchronizeJellyfinLibraryByIdHandler.cs +++ b/ErsatzTV.Application/Jellyfin/Commands/SynchronizeJellyfinLibraryByIdHandler.cs @@ -72,7 +72,7 @@ public class SynchronizeJellyfinLibraryByIdHandler : { var lastScan = new DateTimeOffset(parameters.Library.LastScan ?? SystemTime.MinValueUtc, TimeSpan.Zero); DateTimeOffset nextScan = lastScan + TimeSpan.FromHours(parameters.LibraryRefreshInterval); - if (parameters.ForceScan || nextScan < DateTimeOffset.Now) + if (parameters.ForceScan || (parameters.LibraryRefreshInterval > 0 && nextScan < DateTimeOffset.Now)) { Either result = parameters.Library.MediaKind switch { @@ -173,7 +173,7 @@ public class SynchronizeJellyfinLibraryByIdHandler : private Task> ValidateLibraryRefreshInterval() => _configElementRepository.GetValue(ConfigElementKey.LibraryRefreshInterval) - .FilterT(lri => lri > 0) + .FilterT(lri => lri is >= 0 and < 1_000_000) .Map(lri => lri.ToValidation("Library refresh interval is invalid")); private Task> ValidateFFmpegPath() => diff --git a/ErsatzTV.Application/MediaSources/Commands/ScanLocalLibraryHandler.cs b/ErsatzTV.Application/MediaSources/Commands/ScanLocalLibraryHandler.cs index 75aae5eab..bce9e185d 100644 --- a/ErsatzTV.Application/MediaSources/Commands/ScanLocalLibraryHandler.cs +++ b/ErsatzTV.Application/MediaSources/Commands/ScanLocalLibraryHandler.cs @@ -82,7 +82,7 @@ public class ScanLocalLibraryHandler : IRequestHandler 0 && nextScan < DateTimeOffset.Now)) { scanned = true; @@ -220,7 +220,7 @@ public class ScanLocalLibraryHandler : IRequestHandler> ValidateLibraryRefreshInterval() => _configElementRepository.GetValue(ConfigElementKey.LibraryRefreshInterval) - .FilterT(lri => lri > 0) + .FilterT(lri => lri is >= 0 and < 1_000_000) .Map(lri => lri.ToValidation("Library refresh interval is invalid")); private record RequestParameters( diff --git a/ErsatzTV.Application/Plex/Commands/SynchronizePlexLibraryByIdHandler.cs b/ErsatzTV.Application/Plex/Commands/SynchronizePlexLibraryByIdHandler.cs index 2f18e9f94..8638e3fb1 100644 --- a/ErsatzTV.Application/Plex/Commands/SynchronizePlexLibraryByIdHandler.cs +++ b/ErsatzTV.Application/Plex/Commands/SynchronizePlexLibraryByIdHandler.cs @@ -66,7 +66,7 @@ public class { var lastScan = new DateTimeOffset(parameters.Library.LastScan ?? SystemTime.MinValueUtc, TimeSpan.Zero); DateTimeOffset nextScan = lastScan + TimeSpan.FromHours(parameters.LibraryRefreshInterval); - if (parameters.ForceScan || nextScan < DateTimeOffset.Now) + if (parameters.ForceScan || (parameters.LibraryRefreshInterval > 0 && nextScan < DateTimeOffset.Now)) { Either result = parameters.Library.MediaKind switch { @@ -167,7 +167,7 @@ public class private Task> ValidateLibraryRefreshInterval() => _configElementRepository.GetValue(ConfigElementKey.LibraryRefreshInterval) - .FilterT(lri => lri > 0) + .FilterT(lri => lri is >= 0 and < 1_000_000) .Map(lri => lri.ToValidation("Library refresh interval is invalid")); private Task> ValidateFFmpegPath() => diff --git a/ErsatzTV/Pages/Settings.razor b/ErsatzTV/Pages/Settings.razor index 17c5b890f..fd6ea7226 100644 --- a/ErsatzTV/Pages/Settings.razor +++ b/ErsatzTV/Pages/Settings.razor @@ -231,7 +231,7 @@ _tunerCount = await _mediator.Send(new GetHDHRTunerCount(), _cts.Token); _hdhrSuccess = string.IsNullOrWhiteSpace(ValidateTunerCount(_tunerCount)); _libraryRefreshInterval = await _mediator.Send(new GetLibraryRefreshInterval(), _cts.Token); - _scannerSuccess = _libraryRefreshInterval > 0; + _scannerSuccess = _libraryRefreshInterval is >= 0 and < 1_000_000; _playoutSettings = await _mediator.Send(new GetPlayoutSettings(), _cts.Token); _playoutSuccess = _playoutSettings.DaysToBuild > 0; _generalSettings = await _mediator.Send(new GetGeneralSettings(), _cts.Token); @@ -241,7 +241,11 @@ private static string ValidateTunerCount(int tunerCount) => tunerCount <= 0 ? "Tuner count must be greater than zero" : null; - private static string ValidateLibraryRefreshInterval(int libraryRefreshInterval) => libraryRefreshInterval <= 0 ? "Library refresh interval must be greater than zero" : null; + private static string ValidateLibraryRefreshInterval(int libraryRefreshInterval) => libraryRefreshInterval switch { + <= -1 => "Library refresh interval must be 0 (do not refresh) or greater than zero", + >= 1_000_000 => "Library refresh interval must be less than 1,000,000. Use 0 to disable automatic refresh", + _ => null + }; private static string ValidatePlayoutDaysToBuild(int daysToBuild) => daysToBuild <= 0 ? "Days to build must be greater than zero" : null; diff --git a/ErsatzTV/Services/SchedulerService.cs b/ErsatzTV/Services/SchedulerService.cs index a1dbf60f9..a665a930a 100644 --- a/ErsatzTV/Services/SchedulerService.cs +++ b/ErsatzTV/Services/SchedulerService.cs @@ -93,7 +93,7 @@ public class SchedulerService : BackgroundService { await DeleteOrphanedArtwork(cancellationToken); await BuildPlayouts(cancellationToken); -#if !DEBUG_NO_SYNC +#if !DEBUG_NO_SYNC await ScanLocalMediaSources(cancellationToken); await ScanPlexMediaSources(cancellationToken); await ScanJellyfinMediaSources(cancellationToken);