diff --git a/src/NzbDrone.Common/Extensions/PathExtensions.cs b/src/NzbDrone.Common/Extensions/PathExtensions.cs index d8c24af8e..e10884da6 100644 --- a/src/NzbDrone.Common/Extensions/PathExtensions.cs +++ b/src/NzbDrone.Common/Extensions/PathExtensions.cs @@ -159,6 +159,11 @@ namespace NzbDrone.Common.Extensions public static bool ContainsInvalidPathChars(this string text) { + if (text.IsNullOrWhiteSpace()) + { + throw new ArgumentNullException("text"); + } + return text.IndexOfAny(Path.GetInvalidPathChars()) >= 0; } diff --git a/src/NzbDrone.Core.Test/HealthCheck/Checks/RootFolderCheckFixture.cs b/src/NzbDrone.Core.Test/HealthCheck/Checks/RootFolderCheckFixture.cs index d2eb98316..7df268485 100644 --- a/src/NzbDrone.Core.Test/HealthCheck/Checks/RootFolderCheckFixture.cs +++ b/src/NzbDrone.Core.Test/HealthCheck/Checks/RootFolderCheckFixture.cs @@ -8,7 +8,9 @@ using NzbDrone.Core.HealthCheck.Checks; using NzbDrone.Core.ImportLists; using NzbDrone.Core.Localization; using NzbDrone.Core.Music; +using NzbDrone.Core.RootFolders; using NzbDrone.Core.Test.Framework; +using NzbDrone.Test.Common; namespace NzbDrone.Core.Test.HealthCheck.Checks { @@ -23,7 +25,7 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks .Returns("Some Warning Message"); } - private void GivenMissingRootFolder() + private void GivenMissingRootFolder(string rootFolderPath) { var artist = Builder.CreateListOfSize(1) .Build() @@ -41,9 +43,9 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks .Setup(s => s.All()) .Returns(importList); - Mocker.GetMock() - .Setup(s => s.GetParentFolder(artist.First().Path)) - .Returns(@"C:\Music"); + Mocker.GetMock() + .Setup(s => s.GetBestRootFolderPath(It.IsAny())) + .Returns(rootFolderPath); Mocker.GetMock() .Setup(s => s.FolderExists(It.IsAny())) @@ -67,7 +69,25 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks [Test] public void should_return_error_if_artist_parent_is_missing() { - GivenMissingRootFolder(); + GivenMissingRootFolder(@"C:\Music".AsOsAgnostic()); + + Subject.Check().ShouldBeError(); + } + + [Test] + public void should_return_error_if_series_path_is_for_posix_os() + { + WindowsOnly(); + GivenMissingRootFolder("/mnt/music"); + + Subject.Check().ShouldBeError(); + } + + [Test] + public void should_return_error_if_series_path_is_for_windows() + { + PosixOnly(); + GivenMissingRootFolder(@"C:\Music"); Subject.Check().ShouldBeError(); } diff --git a/src/NzbDrone.Core/DiskSpace/DiskSpaceService.cs b/src/NzbDrone.Core/DiskSpace/DiskSpaceService.cs index 5721076c9..4f685c560 100644 --- a/src/NzbDrone.Core/DiskSpace/DiskSpaceService.cs +++ b/src/NzbDrone.Core/DiskSpace/DiskSpaceService.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text.RegularExpressions; using NLog; using NzbDrone.Common.Disk; +using NzbDrone.Common.Extensions; using NzbDrone.Core.RootFolders; namespace NzbDrone.Core.DiskSpace @@ -33,7 +34,7 @@ namespace NzbDrone.Core.DiskSpace public List GetFreeSpace() { - var importantRootFolders = _rootFolderService.All().Select(x => x.Path).ToList(); + var importantRootFolders = GetRootPaths().Distinct().ToList(); var optionalRootFolders = GetFixedDisksRootPaths().Except(importantRootFolders).Distinct().ToList(); @@ -42,6 +43,14 @@ namespace NzbDrone.Core.DiskSpace return diskSpace; } + private IEnumerable GetRootPaths() + { + return _rootFolderService.All() + .Select(x => x.Path) + .Where(path => path.IsPathValid(PathValidationType.CurrentOs) && _diskProvider.FolderExists(path)) + .Distinct(); + } + private IEnumerable GetFixedDisksRootPaths() { return _diskProvider.GetMounts() diff --git a/src/NzbDrone.Core/HealthCheck/Checks/RootFolderCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/RootFolderCheck.cs index a382f77af..978c839c4 100644 --- a/src/NzbDrone.Core/HealthCheck/Checks/RootFolderCheck.cs +++ b/src/NzbDrone.Core/HealthCheck/Checks/RootFolderCheck.cs @@ -1,5 +1,6 @@ using System.Linq; using NzbDrone.Common.Disk; +using NzbDrone.Common.Extensions; using NzbDrone.Core.ImportLists; using NzbDrone.Core.Localization; using NzbDrone.Core.MediaFiles.Events; @@ -35,7 +36,7 @@ namespace NzbDrone.Core.HealthCheck.Checks .Select(s => _rootFolderService.GetBestRootFolderPath(s.Value)) .Distinct(); - var missingRootFolders = rootFolders.Where(s => !_diskProvider.FolderExists(s)) + var missingRootFolders = rootFolders.Where(s => !s.IsPathValid(PathValidationType.CurrentOs) || !_diskProvider.FolderExists(s)) .ToList(); missingRootFolders.AddRange(_importListFactory.All() diff --git a/src/NzbDrone.Core/RootFolders/RootFolderService.cs b/src/NzbDrone.Core/RootFolders/RootFolderService.cs index a92020bb1..81be2b286 100644 --- a/src/NzbDrone.Core/RootFolders/RootFolderService.cs +++ b/src/NzbDrone.Core/RootFolders/RootFolderService.cs @@ -152,10 +152,12 @@ namespace NzbDrone.Core.RootFolders if (possibleRootFolder == null) { - return _diskProvider.GetParentFolder(path); + var osPath = new OsPath(path); + + return osPath.Directory.ToString(); } - return possibleRootFolder.Path; + return possibleRootFolder?.Path; } private void GetDetails(RootFolder rootFolder)