using System.Globalization; using System.Threading.Channels; using ErsatzTV.Application.Libraries; using ErsatzTV.Core; using ErsatzTV.Core.Errors; using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.FFmpeg.Runtime; using ErsatzTV.Infrastructure.Data; using ErsatzTV.Infrastructure.Extensions; using Microsoft.EntityFrameworkCore; namespace ErsatzTV.Application.Emby; public class CallEmbyLibraryScannerHandler : CallLibraryScannerHandler, IRequestHandler>, IRequestHandler> { public CallEmbyLibraryScannerHandler( IDbContextFactory dbContextFactory, IConfigElementRepository configElementRepository, ChannelWriter channel, IMediator mediator, IRuntimeInfo runtimeInfo) : base(dbContextFactory, configElementRepository, channel, mediator, runtimeInfo) { } Task> IRequestHandler>.Handle( ForceSynchronizeEmbyLibraryById request, CancellationToken cancellationToken) => Handle(request, cancellationToken); Task> IRequestHandler>. Handle( SynchronizeEmbyLibraryByIdIfNeeded request, CancellationToken cancellationToken) => Handle(request, cancellationToken); private async Task> Handle( ISynchronizeEmbyLibraryById request, CancellationToken cancellationToken) { Validation validation = await Validate(request); return await validation.Match( scanner => PerformScan(scanner, request, cancellationToken), error => { foreach (ScanIsNotRequired scanIsNotRequired in error.OfType()) { return Task.FromResult>(scanIsNotRequired); } return Task.FromResult>(error.Join()); }); } private async Task> PerformScan( string scanner, ISynchronizeEmbyLibraryById request, CancellationToken cancellationToken) { var arguments = new List { "scan-emby", request.EmbyLibraryId.ToString(CultureInfo.InvariantCulture) }; if (request.ForceScan) { arguments.Add("--force"); } if (request.DeepScan) { arguments.Add("--deep"); } return await base.PerformScan(scanner, arguments, cancellationToken); } protected override async Task GetLastScan( TvContext dbContext, ISynchronizeEmbyLibraryById request) { DateTime minDateTime = await dbContext.EmbyLibraries .SelectOneAsync(l => l.Id, l => l.Id == request.EmbyLibraryId) .Match(l => l.LastScan ?? SystemTime.MinValueUtc, () => SystemTime.MaxValueUtc); return new DateTimeOffset(minDateTime, TimeSpan.Zero); } protected override bool ScanIsRequired( DateTimeOffset lastScan, int libraryRefreshInterval, ISynchronizeEmbyLibraryById request) { if (lastScan == SystemTime.MaxValueUtc) { return false; } DateTimeOffset nextScan = lastScan + TimeSpan.FromHours(libraryRefreshInterval); return request.ForceScan || libraryRefreshInterval > 0 && nextScan < DateTimeOffset.Now; } }