using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Locking; using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Repositories.Caching; using ErsatzTV.Core.Interfaces.Search; using ErsatzTV.Core.Interfaces.Trakt; using ErsatzTV.Infrastructure.Data; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; namespace ErsatzTV.Application.MediaCollections; public class MatchTraktListItemsHandler : TraktCommandBase, IRequestHandler> { private readonly IDbContextFactory _dbContextFactory; private readonly IEntityLocker _entityLocker; public MatchTraktListItemsHandler( ITraktApiClient traktApiClient, ICachingSearchRepository searchRepository, ISearchIndex searchIndex, IFallbackMetadataProvider fallbackMetadataProvider, IDbContextFactory dbContextFactory, ILogger logger, IEntityLocker entityLocker) : base( traktApiClient, searchRepository, searchIndex, fallbackMetadataProvider, logger) { _dbContextFactory = dbContextFactory; _entityLocker = entityLocker; } public async Task> Handle( MatchTraktListItems request, CancellationToken cancellationToken) { try { await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken); Validation validation = await TraktListMustExist(dbContext, request.TraktListId); return await validation.Match( async l => await MatchListItems(dbContext, l).MapT(_ => Unit.Default), error => Task.FromResult>(error.Join())); } finally { if (request.Unlock) { _entityLocker.UnlockTrakt(); } } } }