diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/ScanWatchFolderFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/ScanWatchFolderFixture.cs index b20dbec7a..51006ba3e 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/ScanWatchFolderFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/ScanWatchFolderFixture.cs @@ -36,7 +36,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole .Setup(c => c.GetFileSize(It.IsAny())) .Returns(1000000); - Mocker.GetMock().Setup(c => c.FilterPaths(It.IsAny(), It.IsAny>())) + Mocker.GetMock().Setup(c => c.FilterPaths(It.IsAny(), It.IsAny>(), It.IsAny())) .Returns>((b, s) => s.ToList()); } diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/TorrentBlackholeFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/TorrentBlackholeFixture.cs index 6b63737e8..1c11414b4 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/TorrentBlackholeFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/TorrentBlackholeFixture.cs @@ -58,7 +58,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole .Setup(c => c.GetHashFromTorrentFile(It.IsAny())) .Returns("myhash"); - Mocker.GetMock().Setup(c => c.FilterPaths(It.IsAny(), It.IsAny>())) + Mocker.GetMock().Setup(c => c.FilterPaths(It.IsAny(), It.IsAny>(), It.IsAny())) .Returns>((b, s) => s.ToList()); } diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/UsenetBlackholeFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/UsenetBlackholeFixture.cs index 6638e338d..220e95c61 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/UsenetBlackholeFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/UsenetBlackholeFixture.cs @@ -52,7 +52,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole .Setup(c => c.OpenWriteStream(It.IsAny())) .Returns(() => new FileStream(GetTempFilePath(), FileMode.Create)); - Mocker.GetMock().Setup(c => c.FilterPaths(It.IsAny(), It.IsAny>())) + Mocker.GetMock().Setup(c => c.FilterPaths(It.IsAny(), It.IsAny>(), It.IsAny())) .Returns>((b, s) => s.ToList()); } diff --git a/src/NzbDrone.Core.Test/MediaFiles/DiskScanServiceTests/ScanFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/DiskScanServiceTests/ScanFixture.cs index 66fe909af..c03c1a117 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/DiskScanServiceTests/ScanFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/DiskScanServiceTests/ScanFixture.cs @@ -171,6 +171,50 @@ namespace NzbDrone.Core.Test.MediaFiles.DiskScanServiceTests .Verify(v => v.GetImportDecisions(It.IsAny>(), _series, false), Times.Never()); } + [Test] + public void should_not_scan_various_extras_subfolders() + { + GivenSeriesFolder(); + + GivenFiles(new List + { + Path.Combine(_series.Path, "Behind the Scenes", "file1.mkv").AsOsAgnostic(), + Path.Combine(_series.Path, "Deleted Scenes", "file2.mkv").AsOsAgnostic(), + Path.Combine(_series.Path, "Featurettes", "file3.mkv").AsOsAgnostic(), + Path.Combine(_series.Path, "Interviews", "file4.mkv").AsOsAgnostic(), + Path.Combine(_series.Path, "Samples", "file5.mkv").AsOsAgnostic(), + Path.Combine(_series.Path, "Scenes", "file6.mkv").AsOsAgnostic(), + Path.Combine(_series.Path, "Shorts", "file7.mkv").AsOsAgnostic(), + Path.Combine(_series.Path, "Trailers", "file8.mkv").AsOsAgnostic(), + Path.Combine(_series.Path, "Series Title S01E01 (1080p BluRay x265 10bit Tigole).mkv").AsOsAgnostic(), + }); + + Subject.Scan(_series); + + Mocker.GetMock() + .Verify(v => v.GetImportDecisions(It.Is>(l => l.Count == 1), _series), Times.Once()); + } + + [Test] + public void should_not_scan_featurettes_subfolders() + { + GivenSeriesFolder(); + + GivenFiles(new List + { + Path.Combine(_series.Path, "Featurettes", "An Epic Reborn.mkv").AsOsAgnostic(), + Path.Combine(_series.Path, "Featurettes", "Deleted & Alternate Scenes.mkv").AsOsAgnostic(), + Path.Combine(_series.Path, "Featurettes", "En Garde - Multi-Angle Dailies.mkv").AsOsAgnostic(), + Path.Combine(_series.Path, "Featurettes", "Layer-By-Layer - Sound Design - Multiple Audio.mkv").AsOsAgnostic(), + Path.Combine(_series.Path, "Series Title S01E01 (1080p BluRay x265 10bit Tigole).mkv").AsOsAgnostic(), + }); + + Subject.Scan(_series); + + Mocker.GetMock() + .Verify(v => v.GetImportDecisions(It.Is>(l => l.Count == 1), _series), Times.Once()); + } + [Test] public void should_clean_but_not_import_if_series_folder_does_not_exist_and_create_folder_enabled() { diff --git a/src/NzbDrone.Core.Test/MediaFiles/DownloadedEpisodesImportServiceFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/DownloadedEpisodesImportServiceFixture.cs index 884c46dd8..5482e9ee5 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/DownloadedEpisodesImportServiceFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/DownloadedEpisodesImportServiceFixture.cs @@ -34,8 +34,8 @@ namespace NzbDrone.Core.Test.MediaFiles Mocker.GetMock().Setup(c => c.GetVideoFiles(It.IsAny(), It.IsAny())) .Returns(_videoFiles); - Mocker.GetMock().Setup(c => c.FilterPaths(It.IsAny(), It.IsAny>())) - .Returns>((b,s) => s.ToList()); + Mocker.GetMock().Setup(c => c.FilterPaths(It.IsAny(), It.IsAny>(), It.IsAny())) + .Returns>((b, s) => s.ToList()); Mocker.GetMock().Setup(c => c.GetDirectories(It.IsAny())) .Returns(_subFolders); diff --git a/src/NzbDrone.Core/Extras/ExistingExtraFileService.cs b/src/NzbDrone.Core/Extras/ExistingExtraFileService.cs index 321ac2b1a..70b4b4cfe 100644 --- a/src/NzbDrone.Core/Extras/ExistingExtraFileService.cs +++ b/src/NzbDrone.Core/Extras/ExistingExtraFileService.cs @@ -41,7 +41,7 @@ namespace NzbDrone.Core.Extras _logger.Debug("Looking for existing extra files in {0}", series.Path); var filesOnDisk = _diskScanService.GetNonVideoFiles(series.Path); - var possibleExtraFiles = _diskScanService.FilterPaths(series.Path, filesOnDisk); + var possibleExtraFiles = _diskScanService.FilterPaths(series.Path, filesOnDisk, false); var filteredFiles = possibleExtraFiles; var importedFiles = new List(); diff --git a/src/NzbDrone.Core/MediaFiles/DiskScanService.cs b/src/NzbDrone.Core/MediaFiles/DiskScanService.cs index 9a7712a2d..2b862ad05 100644 --- a/src/NzbDrone.Core/MediaFiles/DiskScanService.cs +++ b/src/NzbDrone.Core/MediaFiles/DiskScanService.cs @@ -25,7 +25,7 @@ namespace NzbDrone.Core.MediaFiles void Scan(Series series); string[] GetVideoFiles(string path, bool allDirectories = true); string[] GetNonVideoFiles(string path, bool allDirectories = true); - List FilterPaths(string basePath, IEnumerable files); + List FilterPaths(string basePath, IEnumerable files, bool filterExtras = true); } public class DiskScanService : @@ -69,7 +69,8 @@ namespace NzbDrone.Core.MediaFiles _logger = logger; } - private static readonly Regex ExcludedSubFoldersRegex = new Regex(@"(?:\\|\/|^)(?:extras|@eadir|\.@__thumb|extrafanart|plex versions|\.[^\\/]+)(?:\\|\/)", RegexOptions.Compiled | RegexOptions.IgnoreCase); + private static readonly Regex ExcludedExtrasSubFolderRegex = new Regex(@"(?:\\|\/|^)(?:extras|extrafanart|behind the scenes|deleted scenes|featurettes|interviews|scenes|samples|shorts|trailers)(?:\\|\/)", RegexOptions.Compiled | RegexOptions.IgnoreCase); + private static readonly Regex ExcludedSubFoldersRegex = new Regex(@"(?:\\|\/|^)(?:@eadir|\.@__thumb|plex versions|\.[^\\/]+)(?:\\|\/)", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Regex ExcludedFilesRegex = new Regex(@"^\._|^Thumbs\.db$", RegexOptions.Compiled | RegexOptions.IgnoreCase); public void Scan(Series series) @@ -217,11 +218,18 @@ namespace NzbDrone.Core.MediaFiles return mediaFileList.ToArray(); } - public List FilterPaths(string basePath, IEnumerable paths) + public List FilterPaths(string basePath, IEnumerable paths, bool filterExtras = true) { - return paths.Where(path => !ExcludedSubFoldersRegex.IsMatch(basePath.GetRelativePath(path))) + var filteredPaths = paths.Where(path => !ExcludedSubFoldersRegex.IsMatch(basePath.GetRelativePath(path))) .Where(path => !ExcludedFilesRegex.IsMatch(Path.GetFileName(path))) .ToList(); + + if (filterExtras) + { + filteredPaths = filteredPaths.Where(path => !ExcludedExtrasSubFolderRegex.IsMatch(basePath.GetRelativePath(path))).ToList(); + } + + return filteredPaths; } private void SetPermissions(string path)