Browse Source

properly flag local missing folders (#615)

pull/616/head
Jason Dove 5 years ago committed by GitHub
parent
commit
a9dff5eff7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      CHANGELOG.md
  2. 18
      ErsatzTV.Core.Tests/Metadata/MovieFolderScannerTests.cs
  3. 10
      ErsatzTV.Core/Errors/MediaSourceInaccessible.cs
  4. 38
      ErsatzTV.Core/Metadata/LocalFileSystem.cs
  5. 6
      ErsatzTV.Core/Metadata/MovieFolderScanner.cs
  6. 6
      ErsatzTV.Core/Metadata/MusicVideoFolderScanner.cs
  7. 6
      ErsatzTV.Core/Metadata/OtherVideoFolderScanner.cs
  8. 6
      ErsatzTV.Core/Metadata/SongFolderScanner.cs
  9. 6
      ErsatzTV.Core/Metadata/TelevisionFolderScanner.cs
  10. 2
      ErsatzTV/Pages/LocalLibraryEditor.razor

2
CHANGELOG.md

@ -7,6 +7,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Fixed ### Fixed
- Normalize smart quotes in search queries as they are unsupported by the search library - 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 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 ### Added
- Include `Series` category tag for all episodes in XMLTV - Include `Series` category tag for all episodes in XMLTV

18
ErsatzTV.Core.Tests/Metadata/MovieFolderScannerTests.cs

@ -81,24 +81,6 @@ namespace ErsatzTV.Core.Tests.Metadata
private Mock<ILocalMetadataProvider> _localMetadataProvider; private Mock<ILocalMetadataProvider> _localMetadataProvider;
private Mock<IImageCache> _imageCache; private Mock<IImageCache> _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<LibraryFolder>() };
Either<BaseError, Unit> result = await service.ScanFolder(
libraryPath,
FFprobePath,
0,
1);
result.IsLeft.Should().BeTrue();
result.IfLeft(error => error.Should().BeOfType<MediaSourceInaccessible>());
}
[Test] [Test]
public async Task NewMovie_Statistics_And_FallbackMetadata( public async Task NewMovie_Statistics_And_FallbackMetadata(
[ValueSource(typeof(LocalFolderScanner), nameof(LocalFolderScanner.VideoFileExtensions))] [ValueSource(typeof(LocalFolderScanner), nameof(LocalFolderScanner.VideoFileExtensions))]

10
ErsatzTV.Core/Errors/MediaSourceInaccessible.cs

@ -1,10 +0,0 @@
namespace ErsatzTV.Core.Errors
{
public class MediaSourceInaccessible : BaseError
{
public MediaSourceInaccessible()
: base("Media source is not accessible or missing")
{
}
}
}

38
ErsatzTV.Core/Metadata/LocalFileSystem.cs

@ -23,7 +23,7 @@ namespace ErsatzTV.Core.Metadata
{ {
try try
{ {
if (!Directory.Exists(folder)) if (folder != null && !Directory.Exists(folder))
{ {
Directory.CreateDirectory(folder); Directory.CreateDirectory(folder);
} }
@ -42,11 +42,39 @@ namespace ErsatzTV.Core.Metadata
public bool IsLibraryPathAccessible(LibraryPath libraryPath) => public bool IsLibraryPathAccessible(LibraryPath libraryPath) =>
Directory.Exists(libraryPath.Path); Directory.Exists(libraryPath.Path);
public IEnumerable<string> ListSubdirectories(string folder) => public IEnumerable<string> ListSubdirectories(string folder)
Try(Directory.EnumerateDirectories(folder)).IfFail(new List<string>()); {
if (Directory.Exists(folder))
{
try
{
return Directory.EnumerateDirectories(folder);
}
catch
{
// do nothing
}
}
return new List<string>();
}
public IEnumerable<string> ListFiles(string folder) => public IEnumerable<string> ListFiles(string folder)
Try(Directory.EnumerateFiles(folder, "*", SearchOption.TopDirectoryOnly)).IfFail(new List<string>()); {
if (Directory.Exists(folder))
{
try
{
return Directory.EnumerateFiles(folder, "*", SearchOption.TopDirectoryOnly);
}
catch
{
// do nothing
}
}
return new List<string>();
}
public bool FileExists(string path) => File.Exists(path); public bool FileExists(string path) => File.Exists(path);

6
ErsatzTV.Core/Metadata/MovieFolderScanner.cs

@ -4,7 +4,6 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Errors;
using ErsatzTV.Core.Interfaces.FFmpeg; using ErsatzTV.Core.Interfaces.FFmpeg;
using ErsatzTV.Core.Interfaces.Images; using ErsatzTV.Core.Interfaces.Images;
using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Metadata;
@ -73,11 +72,6 @@ namespace ErsatzTV.Core.Metadata
{ {
decimal progressSpread = progressMax - progressMin; decimal progressSpread = progressMax - progressMin;
if (!_localFileSystem.IsLibraryPathAccessible(libraryPath))
{
return new MediaSourceInaccessible();
}
var foldersCompleted = 0; var foldersCompleted = 0;
var folderQueue = new Queue<string>(); var folderQueue = new Queue<string>();

6
ErsatzTV.Core/Metadata/MusicVideoFolderScanner.cs

@ -4,7 +4,6 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Errors;
using ErsatzTV.Core.Interfaces.FFmpeg; using ErsatzTV.Core.Interfaces.FFmpeg;
using ErsatzTV.Core.Interfaces.Images; using ErsatzTV.Core.Interfaces.Images;
using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Metadata;
@ -74,11 +73,6 @@ namespace ErsatzTV.Core.Metadata
{ {
decimal progressSpread = progressMax - progressMin; decimal progressSpread = progressMax - progressMin;
if (!_localFileSystem.IsLibraryPathAccessible(libraryPath))
{
return new MediaSourceInaccessible();
}
var allArtistFolders = _localFileSystem.ListSubdirectories(libraryPath.Path) var allArtistFolders = _localFileSystem.ListSubdirectories(libraryPath.Path)
.Filter(ShouldIncludeFolder) .Filter(ShouldIncludeFolder)
.OrderBy(identity) .OrderBy(identity)

6
ErsatzTV.Core/Metadata/OtherVideoFolderScanner.cs

@ -4,7 +4,6 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Errors;
using ErsatzTV.Core.Interfaces.FFmpeg; using ErsatzTV.Core.Interfaces.FFmpeg;
using ErsatzTV.Core.Interfaces.Images; using ErsatzTV.Core.Interfaces.Images;
using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Metadata;
@ -71,11 +70,6 @@ namespace ErsatzTV.Core.Metadata
{ {
decimal progressSpread = progressMax - progressMin; decimal progressSpread = progressMax - progressMin;
if (!_localFileSystem.IsLibraryPathAccessible(libraryPath))
{
return new MediaSourceInaccessible();
}
var foldersCompleted = 0; var foldersCompleted = 0;
var folderQueue = new Queue<string>(); var folderQueue = new Queue<string>();

6
ErsatzTV.Core/Metadata/SongFolderScanner.cs

@ -4,7 +4,6 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Errors;
using ErsatzTV.Core.Extensions; using ErsatzTV.Core.Extensions;
using ErsatzTV.Core.Interfaces.FFmpeg; using ErsatzTV.Core.Interfaces.FFmpeg;
using ErsatzTV.Core.Interfaces.Images; using ErsatzTV.Core.Interfaces.Images;
@ -73,11 +72,6 @@ namespace ErsatzTV.Core.Metadata
{ {
decimal progressSpread = progressMax - progressMin; decimal progressSpread = progressMax - progressMin;
if (!_localFileSystem.IsLibraryPathAccessible(libraryPath))
{
return new MediaSourceInaccessible();
}
var foldersCompleted = 0; var foldersCompleted = 0;
var folderQueue = new Queue<string>(); var folderQueue = new Queue<string>();

6
ErsatzTV.Core/Metadata/TelevisionFolderScanner.cs

@ -4,7 +4,6 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Errors;
using ErsatzTV.Core.Interfaces.FFmpeg; using ErsatzTV.Core.Interfaces.FFmpeg;
using ErsatzTV.Core.Interfaces.Images; using ErsatzTV.Core.Interfaces.Images;
using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Metadata;
@ -73,11 +72,6 @@ namespace ErsatzTV.Core.Metadata
{ {
decimal progressSpread = progressMax - progressMin; decimal progressSpread = progressMax - progressMin;
if (!_localFileSystem.IsLibraryPathAccessible(libraryPath))
{
return new MediaSourceInaccessible();
}
var allShowFolders = _localFileSystem.ListSubdirectories(libraryPath.Path) var allShowFolders = _localFileSystem.ListSubdirectories(libraryPath.Path)
.Filter(ShouldIncludeFolder) .Filter(ShouldIncludeFolder)
.OrderBy(identity) .OrderBy(identity)

2
ErsatzTV/Pages/LocalLibraryEditor.razor

@ -188,7 +188,7 @@
private void AddLibraryPath() 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.HasChanges = true;
_model.Paths.Add(new LocalLibraryPathEditViewModel _model.Paths.Add(new LocalLibraryPathEditViewModel

Loading…
Cancel
Save