public async Task <Either <BaseError, Unit> > ScanLibrary(
        string address,
        string apiKey,
        JellyfinLibrary library,
        string ffmpegPath,
        string ffprobePath,
        CancellationToken cancellationToken)
    {
        List <JellyfinPathReplacement> 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,
                   false,
                   cancellationToken));
    }
Example #2
0
    public async Task <Either <BaseError, Unit> > ScanLibrary(
        string address,
        string apiKey,
        JellyfinLibrary library,
        string ffmpegPath,
        string ffprobePath,
        CancellationToken cancellationToken)
    {
        try
        {
            List <JellyfinItemEtag> existingShows = await _televisionRepository.GetExistingShows(library);

            // TODO: maybe get quick list of item ids and etags from api to compare first
            // TODO: paging?

            List <JellyfinPathReplacement> pathReplacements = await _mediaSourceRepository
                                                              .GetJellyfinPathReplacements(library.MediaSourceId);

            Either <BaseError, List <JellyfinShow> > maybeShows = await _jellyfinApiClient.GetShowLibraryItems(
                address,
                apiKey,
                library.MediaSourceId,
                library.ItemId);

            foreach (BaseError error in maybeShows.LeftToSeq())
            {
                _logger.LogWarning(
                    "Error synchronizing jellyfin library {Path}: {Error}",
                    library.Name,
                    error.Value);
            }

            foreach (List <JellyfinShow> shows in maybeShows.RightToSeq())
            {
                Either <BaseError, Unit> scanResult = await ProcessShows(
                    address,
                    apiKey,
                    library,
                    ffmpegPath,
                    ffprobePath,
                    pathReplacements,
                    existingShows,
                    shows,
                    cancellationToken);

                foreach (ScanCanceled error in scanResult.LeftToSeq().OfType <ScanCanceled>())
                {
                    return(error);
                }

                foreach (Unit _ in scanResult.RightToSeq())
                {
                    var incomingShowIds = shows.Map(s => s.ItemId).ToList();
                    var showIds         = existingShows
                                          .Filter(i => !incomingShowIds.Contains(i.ItemId))
                                          .Map(m => m.ItemId)
                                          .ToList();
                    List <int> missingShowIds = await _televisionRepository.RemoveMissingShows(library, showIds);

                    await _searchIndex.RemoveItems(missingShowIds);

                    await _televisionRepository.DeleteEmptySeasons(library);

                    List <int> emptyShowIds = await _televisionRepository.DeleteEmptyShows(library);

                    await _searchIndex.RemoveItems(emptyShowIds);

                    await _mediator.Publish(new LibraryScanProgress(library.Id, 0), cancellationToken);
                }
            }

            return(Unit.Default);
        }
        catch (Exception ex) when(ex is TaskCanceledException or OperationCanceledException)
        {
            return(new ScanCanceled());
        }
        finally
        {
            _searchIndex.Commit();
        }
    }