From b01ad9dbaea107355da388ca244ee7a70edee6f0 Mon Sep 17 00:00:00 2001 From: Jason Dove <1695733+jasongdove@users.noreply.github.com> Date: Sat, 5 Jul 2025 17:40:00 +0000 Subject: [PATCH] restore incorrectly deleted file (#2114) --- .../Commands/CreateLocalLibraryHandler.cs | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 ErsatzTV.Application/Libraries/Commands/CreateLocalLibraryHandler.cs diff --git a/ErsatzTV.Application/Libraries/Commands/CreateLocalLibraryHandler.cs b/ErsatzTV.Application/Libraries/Commands/CreateLocalLibraryHandler.cs new file mode 100644 index 00000000..fbaca344 --- /dev/null +++ b/ErsatzTV.Application/Libraries/Commands/CreateLocalLibraryHandler.cs @@ -0,0 +1,76 @@ +using System.Threading.Channels; +using ErsatzTV.Application.MediaSources; +using ErsatzTV.Core; +using ErsatzTV.Core.Domain; +using ErsatzTV.Core.Interfaces.Locking; +using ErsatzTV.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; +using static ErsatzTV.Application.Libraries.Mapper; + +namespace ErsatzTV.Application.Libraries; + +public class CreateLocalLibraryHandler : LocalLibraryHandlerBase, + IRequestHandler> +{ + private readonly IDbContextFactory _dbContextFactory; + private readonly IEntityLocker _entityLocker; + private readonly ChannelWriter _scannerWorkerChannel; + + public CreateLocalLibraryHandler( + ChannelWriter scannerWorkerChannel, + IEntityLocker entityLocker, + IDbContextFactory dbContextFactory) + { + _scannerWorkerChannel = scannerWorkerChannel; + _entityLocker = entityLocker; + _dbContextFactory = dbContextFactory; + } + + public async Task> Handle( + CreateLocalLibrary request, + CancellationToken cancellationToken) + { + await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken); + Validation validation = await Validate(dbContext, request); + return await validation.Apply(localLibrary => PersistLocalLibrary(dbContext, localLibrary)); + } + + private async Task PersistLocalLibrary( + TvContext dbContext, + LocalLibrary localLibrary) + { + await dbContext.LocalLibraries.AddAsync(localLibrary); + await dbContext.SaveChangesAsync(); + + if (_entityLocker.LockLibrary(localLibrary.Id)) + { + await _scannerWorkerChannel.WriteAsync(new ForceScanLocalLibrary(localLibrary.Id)); + } + + return ProjectToViewModel(localLibrary); + } + + private static Task> Validate( + TvContext dbContext, + CreateLocalLibrary request) => + MediaSourceMustExist(dbContext, request) + .BindT(localLibrary => NameMustBeValid(request, localLibrary)) + .BindT(localLibrary => PathsMustBeValid(dbContext, localLibrary)); + + private static Task> MediaSourceMustExist( + TvContext dbContext, + CreateLocalLibrary request) => + dbContext.LocalMediaSources + .OrderBy(lms => lms.Id) + .FirstOrDefaultAsync() + .Map(Optional) + .MapT( + lms => new LocalLibrary + { + Name = request.Name, + Paths = request.Paths.Map(p => new LibraryPath { Path = p }).ToList(), + MediaKind = request.MediaKind, + MediaSourceId = lms.Id + }) + .Map(o => o.ToValidation("LocalMediaSource does not exist.")); +}