using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Extensions; using ErsatzTV.Core.Interfaces.Jellyfin; using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Jellyfin; using ErsatzTV.Core.Metadata; using ErsatzTV.Scanner.Core.Interfaces.Metadata; using ErsatzTV.Scanner.Core.Metadata; using Microsoft.Extensions.Logging; namespace ErsatzTV.Scanner.Core.Jellyfin; public class JellyfinMovieLibraryScanner : MediaServerMovieLibraryScanner, IJellyfinMovieLibraryScanner { private readonly IJellyfinApiClient _jellyfinApiClient; private readonly IJellyfinMovieRepository _jellyfinMovieRepository; private readonly IMediaSourceRepository _mediaSourceRepository; private readonly IJellyfinPathReplacementService _pathReplacementService; public JellyfinMovieLibraryScanner( IJellyfinApiClient jellyfinApiClient, IMediator mediator, IJellyfinMovieRepository jellyfinMovieRepository, IJellyfinPathReplacementService pathReplacementService, IMediaSourceRepository mediaSourceRepository, ILocalFileSystem localFileSystem, IMetadataRepository metadataRepository, ILocalStatisticsProvider localStatisticsProvider, ILocalSubtitlesProvider localSubtitlesProvider, ILogger logger) : base( localStatisticsProvider, localSubtitlesProvider, localFileSystem, metadataRepository, mediator, logger) { _jellyfinApiClient = jellyfinApiClient; _jellyfinMovieRepository = jellyfinMovieRepository; _pathReplacementService = pathReplacementService; _mediaSourceRepository = mediaSourceRepository; } public async Task> ScanLibrary( string address, string apiKey, JellyfinLibrary library, string ffmpegPath, string ffprobePath, bool deepScan, CancellationToken cancellationToken) { List pathReplacements = await _mediaSourceRepository.GetJellyfinPathReplacements(library.MediaSourceId); string GetLocalPath(JellyfinMovie movie) { return _pathReplacementService.GetReplacementJellyfinPath( pathReplacements, movie.GetHeadVersion().MediaFiles.Head().Path, false); } return await ScanLibrary( _jellyfinMovieRepository, new JellyfinConnectionParameters(address, apiKey, library.MediaSourceId), library, GetLocalPath, ffmpegPath, ffprobePath, deepScan, cancellationToken); } protected override string MediaServerItemId(JellyfinMovie movie) => movie.ItemId; protected override string MediaServerEtag(JellyfinMovie movie) => movie.Etag; protected override Task> CountMovieLibraryItems( JellyfinConnectionParameters connectionParameters, JellyfinLibrary library) => _jellyfinApiClient.GetLibraryItemCount( connectionParameters.Address, connectionParameters.ApiKey, library, library.ItemId, JellyfinItemType.Movie, true); protected override IAsyncEnumerable GetMovieLibraryItems( JellyfinConnectionParameters connectionParameters, JellyfinLibrary library) => _jellyfinApiClient.GetMovieLibraryItems( connectionParameters.Address, connectionParameters.ApiKey, library); protected override Task> GetFullMetadata( JellyfinConnectionParameters connectionParameters, JellyfinLibrary library, MediaItemScanResult result, JellyfinMovie incoming, bool deepScan) => Task.FromResult>(None); protected override Task>> GetFullMetadataAndStatistics( JellyfinConnectionParameters connectionParameters, JellyfinLibrary library, MediaItemScanResult result, JellyfinMovie incoming) => Task.FromResult(Option>.None); protected override Task>> UpdateMetadata( MediaItemScanResult result, MovieMetadata fullMetadata) => Task.FromResult>>(result); }