From 12065948ca0b53d655e90e127800c44d6a08036a Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 22 Oct 2017 10:09:53 -0700 Subject: [PATCH] Fixed: Not deleting episode files during upgrade when root folder is missing --- .../UpgradeMediaFileServiceFixture.cs | 29 +++++++++++++++---- .../MediaFiles/UpgradeMediaFileService.cs | 16 ++++++++-- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/NzbDrone.Core.Test/MediaFiles/UpgradeMediaFileServiceFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/UpgradeMediaFileServiceFixture.cs index 615d6a418..755800253 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/UpgradeMediaFileServiceFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/UpgradeMediaFileServiceFixture.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; using System.Linq; using FizzWare.NBuilder; using FluentAssertions; @@ -7,6 +7,7 @@ using Moq; using NUnit.Framework; using NzbDrone.Common.Disk; using NzbDrone.Core.MediaFiles; +using NzbDrone.Core.MediaFiles.EpisodeImport; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Tv; @@ -33,12 +34,16 @@ namespace NzbDrone.Core.Test.MediaFiles .Build(); Mocker.GetMock() - .Setup(c => c.FileExists(It.IsAny())) - .Returns(true); + .Setup(c => c.FolderExists(Directory.GetParent(_localEpisode.Series.Path).FullName)) + .Returns(true); Mocker.GetMock() - .Setup(c => c.GetParentFolder(It.IsAny())) - .Returns(c => Path.GetDirectoryName(c)); + .Setup(c => c.FileExists(It.IsAny())) + .Returns(true); + + Mocker.GetMock() + .Setup(c => c.GetParentFolder(It.IsAny())) + .Returns(c => Path.GetDirectoryName(c)); } private void GivenSingleEpisodeWithSingleEpisodeFile() @@ -175,5 +180,19 @@ namespace NzbDrone.Core.Test.MediaFiles Subject.UpgradeEpisodeFile(_episodeFile, _localEpisode).OldFiles.Count.Should().Be(2); } + + [Test] + public void should_throw_if_there_are_existing_episode_files_and_the_root_folder_is_missing() + { + GivenSingleEpisodeWithSingleEpisodeFile(); + + Mocker.GetMock() + .Setup(c => c.FolderExists(Directory.GetParent(_localEpisode.Series.Path).FullName)) + .Returns(false); + + Assert.Throws(() => Subject.UpgradeEpisodeFile(_episodeFile, _localEpisode)); + + Mocker.GetMock().Verify(v => v.Delete(_localEpisode.Episodes.Single().EpisodeFile.Value, DeleteMediaFileReason.Upgrade), Times.Never()); + } } } diff --git a/src/NzbDrone.Core/MediaFiles/UpgradeMediaFileService.cs b/src/NzbDrone.Core/MediaFiles/UpgradeMediaFileService.cs index d6c270d2c..2bcd7b25a 100644 --- a/src/NzbDrone.Core/MediaFiles/UpgradeMediaFileService.cs +++ b/src/NzbDrone.Core/MediaFiles/UpgradeMediaFileService.cs @@ -1,8 +1,9 @@ -using System.IO; +using System.IO; using System.Linq; using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; +using NzbDrone.Core.MediaFiles.EpisodeImport; using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.MediaFiles @@ -39,13 +40,22 @@ namespace NzbDrone.Core.MediaFiles var existingFiles = localEpisode.Episodes .Where(e => e.EpisodeFileId > 0) .Select(e => e.EpisodeFile.Value) - .GroupBy(e => e.Id); + .GroupBy(e => e.Id) + .ToList(); + + var rootFolder = _diskProvider.GetParentFolder(localEpisode.Series.Path); + + // If there are existing episode files and the root folder is missing, throw, so the old file isn't left behind during the import process. + if (existingFiles.Any() && !_diskProvider.FolderExists(rootFolder)) + { + throw new RootFolderNotFoundException($"Root folder '{rootFolder}' was not found."); + } foreach (var existingFile in existingFiles) { var file = existingFile.First(); var episodeFilePath = Path.Combine(localEpisode.Series.Path, file.RelativePath); - var subfolder = _diskProvider.GetParentFolder(localEpisode.Series.Path).GetRelativePath(_diskProvider.GetParentFolder(episodeFilePath)); + var subfolder = rootFolder.GetRelativePath(_diskProvider.GetParentFolder(episodeFilePath)); if (_diskProvider.FileExists(episodeFilePath)) {