public async Task <Either <BaseError, Unit> > ScanFolder(LibraryPath libraryPath, string ffprobePath)
        {
            if (!_localFileSystem.IsLibraryPathAccessible(libraryPath))
            {
                return(new MediaSourceInaccessible());
            }

            var allShowFolders = _localFileSystem.ListSubdirectories(libraryPath.Path)
                                 .Filter(ShouldIncludeFolder)
                                 .OrderBy(identity)
                                 .ToList();

            foreach (string showFolder in allShowFolders)
            {
                Either <BaseError, MediaItemScanResult <Show> > maybeShow =
                    await FindOrCreateShow(libraryPath.Id, showFolder)
                    .BindT(show => UpdateMetadataForShow(show, showFolder))
                    .BindT(show => UpdateArtworkForShow(show, showFolder, ArtworkKind.Poster))
                    .BindT(show => UpdateArtworkForShow(show, showFolder, ArtworkKind.FanArt));

                await maybeShow.Match(
                    async result =>
                {
                    if (result.IsAdded)
                    {
                        await _searchIndex.AddItems(new List <MediaItem> {
                            result.Item
                        });
                    }
                    else if (result.IsUpdated)
                    {
                        await _searchIndex.UpdateItems(new List <MediaItem> {
                            result.Item
                        });
                    }

                    await ScanSeasons(libraryPath, ffprobePath, result.Item, showFolder);
                },
                    _ => Task.FromResult(Unit.Default));
            }

            foreach (string path in await _televisionRepository.FindEpisodePaths(libraryPath))
            {
                if (!_localFileSystem.FileExists(path))
                {
                    _logger.LogInformation("Removing missing episode at {Path}", path);
                    await _televisionRepository.DeleteByPath(libraryPath, path);
                }
            }

            await _televisionRepository.DeleteEmptySeasons(libraryPath);

            List <int> ids = await _televisionRepository.DeleteEmptyShows(libraryPath);

            await _searchIndex.RemoveItems(ids);

            return(Unit.Default);
        }
Exemplo n.º 2
0
        public async Task <Either <BaseError, Unit> > ScanFolder(LibraryPath libraryPath, string ffprobePath)
        {
            if (!_localFileSystem.IsLibraryPathAccessible(libraryPath))
            {
                return(new MediaSourceInaccessible());
            }

            var folderQueue = new Queue <string>();

            foreach (string folder in _localFileSystem.ListSubdirectories(libraryPath.Path).OrderBy(identity))
            {
                folderQueue.Enqueue(folder);
            }

            while (folderQueue.Count > 0)
            {
                string movieFolder = folderQueue.Dequeue();

                var allFiles = _localFileSystem.ListFiles(movieFolder)
                               .Filter(f => VideoFileExtensions.Contains(Path.GetExtension(f)))
                               .Filter(
                    f => !ExtraFiles.Any(
                        e => Path.GetFileNameWithoutExtension(f).EndsWith(e, StringComparison.OrdinalIgnoreCase)))
                               .ToList();

                if (allFiles.Count == 0)
                {
                    foreach (string subdirectory in _localFileSystem.ListSubdirectories(movieFolder).OrderBy(identity))
                    {
                        folderQueue.Enqueue(subdirectory);
                    }

                    continue;
                }

                foreach (string file in allFiles.OrderBy(identity))
                {
                    // TODO: figure out how to rebuild playlists
                    Either <BaseError, MediaItemScanResult <Movie> > maybeMovie = await _movieRepository
                                                                                  .GetOrAdd(libraryPath, file)
                                                                                  .BindT(movie => UpdateStatistics(movie, ffprobePath))
                                                                                  .BindT(UpdateMetadata)
                                                                                  .BindT(movie => UpdateArtwork(movie, ArtworkKind.Poster))
                                                                                  .BindT(movie => UpdateArtwork(movie, ArtworkKind.FanArt));

                    await maybeMovie.Match(
                        async result =>
                    {
                        if (result.IsAdded)
                        {
                            await _searchIndex.AddItems(new List <MediaItem> {
                                result.Item
                            });
                        }
                        else if (result.IsUpdated)
                        {
                            await _searchIndex.UpdateItems(new List <MediaItem> {
                                result.Item
                            });
                        }
                    },
                        error =>
                    {
                        _logger.LogWarning("Error processing movie at {Path}: {Error}", file, error.Value);
                        return(Task.CompletedTask);
                    });
                }
            }

            foreach (string path in await _movieRepository.FindMoviePaths(libraryPath))
            {
                if (!_localFileSystem.FileExists(path))
                {
                    _logger.LogInformation("Removing missing movie at {Path}", path);
                    List <int> ids = await _movieRepository.DeleteByPath(libraryPath, path);

                    await _searchIndex.RemoveItems(ids);
                }
            }

            return(Unit.Default);
        }