diff --git a/CHANGELOG.md b/CHANGELOG.md index d7fa77f90..16dbb77b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Fixed - Normalize smart quotes in search queries as they are unsupported by the search library - Fix incorrect watermark time calculations caused by working ahead in `HLS Segmenter` +- Fix ui crash adding empty path to local library +- Properly flag items as `File Not Found` when local library path (folder) is missing from disk ### Added - Include `Series` category tag for all episodes in XMLTV diff --git a/ErsatzTV.Core.Tests/Metadata/MovieFolderScannerTests.cs b/ErsatzTV.Core.Tests/Metadata/MovieFolderScannerTests.cs index fb3896432..d6276f02a 100644 --- a/ErsatzTV.Core.Tests/Metadata/MovieFolderScannerTests.cs +++ b/ErsatzTV.Core.Tests/Metadata/MovieFolderScannerTests.cs @@ -81,24 +81,6 @@ namespace ErsatzTV.Core.Tests.Metadata private Mock _localMetadataProvider; private Mock _imageCache; - [Test] - public async Task Missing_Folder() - { - MovieFolderScanner service = GetService( - new FakeFileEntry(Path.Combine(FakeRoot, Path.Combine("Movie (2020)", "Movie (2020).mkv"))) - ); - var libraryPath = new LibraryPath { Path = BadFakeRoot, LibraryFolders = new List() }; - - Either result = await service.ScanFolder( - libraryPath, - FFprobePath, - 0, - 1); - - result.IsLeft.Should().BeTrue(); - result.IfLeft(error => error.Should().BeOfType()); - } - [Test] public async Task NewMovie_Statistics_And_FallbackMetadata( [ValueSource(typeof(LocalFolderScanner), nameof(LocalFolderScanner.VideoFileExtensions))] diff --git a/ErsatzTV.Core/Errors/MediaSourceInaccessible.cs b/ErsatzTV.Core/Errors/MediaSourceInaccessible.cs deleted file mode 100644 index 7ce775a39..000000000 --- a/ErsatzTV.Core/Errors/MediaSourceInaccessible.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace ErsatzTV.Core.Errors -{ - public class MediaSourceInaccessible : BaseError - { - public MediaSourceInaccessible() - : base("Media source is not accessible or missing") - { - } - } -} diff --git a/ErsatzTV.Core/Metadata/LocalFileSystem.cs b/ErsatzTV.Core/Metadata/LocalFileSystem.cs index 20f6a8f24..c59467491 100644 --- a/ErsatzTV.Core/Metadata/LocalFileSystem.cs +++ b/ErsatzTV.Core/Metadata/LocalFileSystem.cs @@ -23,7 +23,7 @@ namespace ErsatzTV.Core.Metadata { try { - if (!Directory.Exists(folder)) + if (folder != null && !Directory.Exists(folder)) { Directory.CreateDirectory(folder); } @@ -42,11 +42,39 @@ namespace ErsatzTV.Core.Metadata public bool IsLibraryPathAccessible(LibraryPath libraryPath) => Directory.Exists(libraryPath.Path); - public IEnumerable ListSubdirectories(string folder) => - Try(Directory.EnumerateDirectories(folder)).IfFail(new List()); + public IEnumerable ListSubdirectories(string folder) + { + if (Directory.Exists(folder)) + { + try + { + return Directory.EnumerateDirectories(folder); + } + catch + { + // do nothing + } + } + + return new List(); + } - public IEnumerable ListFiles(string folder) => - Try(Directory.EnumerateFiles(folder, "*", SearchOption.TopDirectoryOnly)).IfFail(new List()); + public IEnumerable ListFiles(string folder) + { + if (Directory.Exists(folder)) + { + try + { + return Directory.EnumerateFiles(folder, "*", SearchOption.TopDirectoryOnly); + } + catch + { + // do nothing + } + } + + return new List(); + } public bool FileExists(string path) => File.Exists(path); diff --git a/ErsatzTV.Core/Metadata/MovieFolderScanner.cs b/ErsatzTV.Core/Metadata/MovieFolderScanner.cs index 99d33c152..2f0c8d494 100644 --- a/ErsatzTV.Core/Metadata/MovieFolderScanner.cs +++ b/ErsatzTV.Core/Metadata/MovieFolderScanner.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Threading.Tasks; using ErsatzTV.Core.Domain; -using ErsatzTV.Core.Errors; using ErsatzTV.Core.Interfaces.FFmpeg; using ErsatzTV.Core.Interfaces.Images; using ErsatzTV.Core.Interfaces.Metadata; @@ -73,11 +72,6 @@ namespace ErsatzTV.Core.Metadata { decimal progressSpread = progressMax - progressMin; - if (!_localFileSystem.IsLibraryPathAccessible(libraryPath)) - { - return new MediaSourceInaccessible(); - } - var foldersCompleted = 0; var folderQueue = new Queue(); diff --git a/ErsatzTV.Core/Metadata/MusicVideoFolderScanner.cs b/ErsatzTV.Core/Metadata/MusicVideoFolderScanner.cs index 3ed823bb9..107b07606 100644 --- a/ErsatzTV.Core/Metadata/MusicVideoFolderScanner.cs +++ b/ErsatzTV.Core/Metadata/MusicVideoFolderScanner.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Threading.Tasks; using ErsatzTV.Core.Domain; -using ErsatzTV.Core.Errors; using ErsatzTV.Core.Interfaces.FFmpeg; using ErsatzTV.Core.Interfaces.Images; using ErsatzTV.Core.Interfaces.Metadata; @@ -74,11 +73,6 @@ namespace ErsatzTV.Core.Metadata { decimal progressSpread = progressMax - progressMin; - if (!_localFileSystem.IsLibraryPathAccessible(libraryPath)) - { - return new MediaSourceInaccessible(); - } - var allArtistFolders = _localFileSystem.ListSubdirectories(libraryPath.Path) .Filter(ShouldIncludeFolder) .OrderBy(identity) diff --git a/ErsatzTV.Core/Metadata/OtherVideoFolderScanner.cs b/ErsatzTV.Core/Metadata/OtherVideoFolderScanner.cs index df2af553e..d73c16d0f 100644 --- a/ErsatzTV.Core/Metadata/OtherVideoFolderScanner.cs +++ b/ErsatzTV.Core/Metadata/OtherVideoFolderScanner.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Threading.Tasks; using ErsatzTV.Core.Domain; -using ErsatzTV.Core.Errors; using ErsatzTV.Core.Interfaces.FFmpeg; using ErsatzTV.Core.Interfaces.Images; using ErsatzTV.Core.Interfaces.Metadata; @@ -71,11 +70,6 @@ namespace ErsatzTV.Core.Metadata { decimal progressSpread = progressMax - progressMin; - if (!_localFileSystem.IsLibraryPathAccessible(libraryPath)) - { - return new MediaSourceInaccessible(); - } - var foldersCompleted = 0; var folderQueue = new Queue(); diff --git a/ErsatzTV.Core/Metadata/SongFolderScanner.cs b/ErsatzTV.Core/Metadata/SongFolderScanner.cs index 86908205b..b6b0b3168 100644 --- a/ErsatzTV.Core/Metadata/SongFolderScanner.cs +++ b/ErsatzTV.Core/Metadata/SongFolderScanner.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Threading.Tasks; using ErsatzTV.Core.Domain; -using ErsatzTV.Core.Errors; using ErsatzTV.Core.Extensions; using ErsatzTV.Core.Interfaces.FFmpeg; using ErsatzTV.Core.Interfaces.Images; @@ -73,11 +72,6 @@ namespace ErsatzTV.Core.Metadata { decimal progressSpread = progressMax - progressMin; - if (!_localFileSystem.IsLibraryPathAccessible(libraryPath)) - { - return new MediaSourceInaccessible(); - } - var foldersCompleted = 0; var folderQueue = new Queue(); diff --git a/ErsatzTV.Core/Metadata/TelevisionFolderScanner.cs b/ErsatzTV.Core/Metadata/TelevisionFolderScanner.cs index c6ceaddcc..a4629296d 100644 --- a/ErsatzTV.Core/Metadata/TelevisionFolderScanner.cs +++ b/ErsatzTV.Core/Metadata/TelevisionFolderScanner.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Threading.Tasks; using ErsatzTV.Core.Domain; -using ErsatzTV.Core.Errors; using ErsatzTV.Core.Interfaces.FFmpeg; using ErsatzTV.Core.Interfaces.Images; using ErsatzTV.Core.Interfaces.Metadata; @@ -73,11 +72,6 @@ namespace ErsatzTV.Core.Metadata { decimal progressSpread = progressMax - progressMin; - if (!_localFileSystem.IsLibraryPathAccessible(libraryPath)) - { - return new MediaSourceInaccessible(); - } - var allShowFolders = _localFileSystem.ListSubdirectories(libraryPath.Path) .Filter(ShouldIncludeFolder) .OrderBy(identity) diff --git a/ErsatzTV/Pages/LocalLibraryEditor.razor b/ErsatzTV/Pages/LocalLibraryEditor.razor index 8d94298b7..ff415d0b0 100644 --- a/ErsatzTV/Pages/LocalLibraryEditor.razor +++ b/ErsatzTV/Pages/LocalLibraryEditor.razor @@ -188,7 +188,7 @@ private void AddLibraryPath() { - if (_model.Paths.All(p => NormalizePath(p.Path) != NormalizePath(_newPath.Path))) + if (!string.IsNullOrWhiteSpace(_newPath.Path) && _model.Paths.All(p => NormalizePath(p.Path) != NormalizePath(_newPath.Path))) { _model.HasChanges = true; _model.Paths.Add(new LocalLibraryPathEditViewModel