You've already forked Sonarr
							
							
				mirror of
				https://github.com/Sonarr/Sonarr.git
				synced 2025-10-31 00:07:55 +02:00 
			
		
		
		
	Removed premove and instead check for source file being in use
This commit is contained in:
		| @@ -5,7 +5,7 @@ using FluentAssertions; | ||||
| using NUnit.Framework; | ||||
| using NzbDrone.Test.Common; | ||||
| 
 | ||||
| namespace NzbDrone.Common.Test | ||||
| namespace NzbDrone.Common.Test.DiskProviderTests | ||||
| { | ||||
|     [TestFixture] | ||||
|     public class DiskProviderFixture : TestBase<DiskProvider> | ||||
							
								
								
									
										32
									
								
								NzbDrone.Common.Test/DiskProviderTests/IsParentFixture.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								NzbDrone.Common.Test/DiskProviderTests/IsParentFixture.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using FluentAssertions; | ||||
| using NUnit.Framework; | ||||
| using NzbDrone.Test.Common; | ||||
|  | ||||
| namespace NzbDrone.Common.Test.DiskProviderTests | ||||
| { | ||||
|     [TestFixture] | ||||
|     public class IsParentFixture : TestBase<DiskProvider> | ||||
|     { | ||||
|         [Test] | ||||
|         public void should_return_false_when_not_a_child() | ||||
|         { | ||||
|             Subject.IsParent(@"C:\Test", @"C:\Another Folder").Should().BeFalse(); | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void should_return_true_when_folder_is_parent_of_another_folder() | ||||
|         { | ||||
|             Subject.IsParent(@"C:\Test", @"C:\Test\TV").Should().BeTrue(); | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void should_return_true_when_folder_is_parent_of_a_file() | ||||
|         { | ||||
|             Subject.IsParent(@"C:\Test", @"C:\Test\30.Rock.S01E01.Pilot.avi").Should().BeTrue(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -62,6 +62,7 @@ | ||||
|     <Compile Include="CacheTests\CachedManagerFixture.cs" /> | ||||
|     <Compile Include="CacheTests\CachedFixture.cs" /> | ||||
|     <Compile Include="ConfigFileProviderTest.cs" /> | ||||
|     <Compile Include="DiskProviderTests\IsParentFixture.cs" /> | ||||
|     <Compile Include="EnsureTest\PathExtensionFixture.cs" /> | ||||
|     <Compile Include="EnvironmentTests\StartupArgumentsFixture.cs" /> | ||||
|     <Compile Include="EnvironmentTests\EnvironmentProviderTest.cs" /> | ||||
| @@ -69,7 +70,7 @@ | ||||
|     <Compile Include="EventingTests\MessageAggregatorEventTests.cs" /> | ||||
|     <Compile Include="ReflectionExtensions.cs" /> | ||||
|     <Compile Include="PathExtensionFixture.cs" /> | ||||
|     <Compile Include="DiskProviderFixture.cs" /> | ||||
|     <Compile Include="DiskProviderTests\DiskProviderFixture.cs" /> | ||||
|     <Compile Include="EnvironmentProviderTest.cs" /> | ||||
|     <Compile Include="ProcessProviderTests.cs" /> | ||||
|     <Compile Include="ReflectionTests\ReflectionExtensionFixture.cs" /> | ||||
|   | ||||
| @@ -39,7 +39,7 @@ namespace NzbDrone.Common | ||||
|         bool IsFileLocked(FileInfo file); | ||||
|         string GetPathRoot(string path); | ||||
|         void SetPermissions(string filename, string account, FileSystemRights rights, AccessControlType controlType); | ||||
|         bool IsParent(string parentfolder, string subfolder); | ||||
|         bool IsParent(string parentPath, string childPath); | ||||
|         FileAttributes GetFileAttributes(string path);   | ||||
|     } | ||||
|  | ||||
| @@ -429,22 +429,22 @@ namespace NzbDrone.Common | ||||
|  | ||||
|         } | ||||
|  | ||||
|         public bool IsParent(string parent, string subfolder) | ||||
|         public bool IsParent(string parentPath, string childPath) | ||||
|         { | ||||
|             parent = parent.TrimEnd(Path.DirectorySeparatorChar); | ||||
|             subfolder = subfolder.TrimEnd(Path.DirectorySeparatorChar); | ||||
|             parentPath = parentPath.TrimEnd(Path.DirectorySeparatorChar); | ||||
|             childPath = childPath.TrimEnd(Path.DirectorySeparatorChar); | ||||
|  | ||||
|             var diParent = new DirectoryInfo(parent); | ||||
|             var diSubfolder = new DirectoryInfo(subfolder); | ||||
|             var parent = new DirectoryInfo(parentPath); | ||||
|             var child = new DirectoryInfo(childPath); | ||||
|  | ||||
|             while (diSubfolder.Parent != null) | ||||
|             while (child.Parent != null) | ||||
|             { | ||||
|                 if (diSubfolder.Parent.FullName == diParent.FullName) | ||||
|                 if (child.Parent.FullName == parent.FullName) | ||||
|                 { | ||||
|                     return true; | ||||
|                 } | ||||
|  | ||||
|                 diSubfolder = diSubfolder.Parent; | ||||
|                 child = child.Parent; | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|   | ||||
| @@ -0,0 +1,92 @@ | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using FizzWare.NBuilder; | ||||
| using FluentAssertions; | ||||
| using Marr.Data; | ||||
| using Moq; | ||||
| using Newtonsoft.Json.Serialization; | ||||
| using NUnit.Framework; | ||||
| using NzbDrone.Common; | ||||
| using NzbDrone.Core.MediaFiles; | ||||
| using NzbDrone.Core.MediaFiles.EpisodeImport.Specifications; | ||||
| using NzbDrone.Core.Parser.Model; | ||||
| using NzbDrone.Core.Test.Framework; | ||||
| using NzbDrone.Core.Tv; | ||||
| using NzbDrone.Test.Common; | ||||
|  | ||||
| namespace NzbDrone.Core.Test.MediaFileTests.EpisodeImportTests | ||||
| { | ||||
|     [TestFixture] | ||||
|     public class NotInUseSpecificationFixture : CoreTest<NotInUseSpecification> | ||||
|     { | ||||
|         private LocalEpisode _localEpisode; | ||||
|  | ||||
|         [SetUp] | ||||
|         public void Setup() | ||||
|         { | ||||
|             _localEpisode = new LocalEpisode | ||||
|             { | ||||
|                 Path = @"C:\Test\30 Rock\30.rock.s01e01.avi".AsOsAgnostic(), | ||||
|                 Size = 100, | ||||
|                 Series = Builder<Series>.CreateNew().Build() | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         private void GivenChildOfSeries() | ||||
|         { | ||||
|             Mocker.GetMock<IDiskProvider>() | ||||
|                 .Setup(s => s.IsParent(_localEpisode.Series.Path, _localEpisode.Path)) | ||||
|                 .Returns(true); | ||||
|         } | ||||
|  | ||||
|         private void GivenNewFile() | ||||
|         { | ||||
|             Mocker.GetMock<IDiskProvider>() | ||||
|                 .Setup(s => s.IsParent(_localEpisode.Series.Path, _localEpisode.Path)) | ||||
|                 .Returns(false); | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void should_return_true_if_file_is_under_series_folder() | ||||
|         { | ||||
|             GivenChildOfSeries(); | ||||
|  | ||||
|             Subject.IsSatisfiedBy(_localEpisode).Should().BeTrue(); | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void should_not_check_for_file_in_use_if_child_of_series_folder() | ||||
|         { | ||||
|             GivenChildOfSeries(); | ||||
|  | ||||
|             Subject.IsSatisfiedBy(_localEpisode); | ||||
|  | ||||
|             Mocker.GetMock<IDiskProvider>() | ||||
|                 .Verify(v => v.IsFileLocked(It.IsAny<FileInfo>()), Times.Never()); | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void should_return_false_if_file_is_in_use() | ||||
|         { | ||||
|             GivenNewFile(); | ||||
|  | ||||
|             Mocker.GetMock<IDiskProvider>() | ||||
|                 .Setup(s => s.IsFileLocked(It.IsAny<FileInfo>())) | ||||
|                 .Returns(true); | ||||
|  | ||||
|             Subject.IsSatisfiedBy(_localEpisode).Should().BeFalse(); | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void should_return_true_if_file_is_not_in_use() | ||||
|         { | ||||
|             GivenNewFile(); | ||||
|  | ||||
|             Mocker.GetMock<IDiskProvider>() | ||||
|                 .Setup(s => s.IsFileLocked(It.IsAny<FileInfo>())) | ||||
|                 .Returns(false); | ||||
|  | ||||
|             Subject.IsSatisfiedBy(_localEpisode).Should().BeTrue(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -150,30 +150,5 @@ namespace NzbDrone.Core.Test.MediaFileTests | ||||
|  | ||||
|             Mocker.GetMock<IRecycleBinProvider>().Verify(v => v.DeleteFile(It.IsAny<string>()), Times.Never()); | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void should_not_delete_file_if_pre_move_fails() | ||||
|         { | ||||
|             GivenSingleEpisodeWithSingleEpisodeFile(); | ||||
|  | ||||
|             Mocker.GetMock<IMoveEpisodeFiles>() | ||||
|                 .Setup(s => s.PreMoveEpisodeFile(It.IsAny<EpisodeFile>(), It.IsAny<LocalEpisode>())) | ||||
|                 .Throws<InvalidOperationException>(); | ||||
|  | ||||
|             Assert.Throws<InvalidOperationException>(() => Subject.UpgradeEpisodeFile(_episodeFile, _localEpisode)); | ||||
|  | ||||
|             Mocker.GetMock<IRecycleBinProvider>().Verify(v => v.DeleteFile(It.IsAny<string>()), Times.Never()); | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void should_move_after_premove() | ||||
|         { | ||||
|             GivenSingleEpisodeWithSingleEpisodeFile(); | ||||
|  | ||||
|             Subject.UpgradeEpisodeFile(_episodeFile, _localEpisode); | ||||
|  | ||||
|             Mocker.GetMock<IMoveEpisodeFiles>().Verify(v => v.PreMoveEpisodeFile(It.IsAny<EpisodeFile>(), It.IsAny<LocalEpisode>()), Times.Once()); | ||||
|             Mocker.GetMock<IMoveEpisodeFiles>().Verify(v => v.MoveEpisodeFile(It.IsAny<EpisodeFile>(), It.IsAny<LocalEpisode>()), Times.Once()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -129,6 +129,7 @@ | ||||
|     <Compile Include="JobTests\TestJobs.cs" /> | ||||
|     <Compile Include="MediaCoverTests\CoverExistsSpecificationFixture.cs" /> | ||||
|     <Compile Include="MediaCoverTests\MediaCoverServiceFixture.cs" /> | ||||
|     <Compile Include="MediaFileTests\EpisodeImportTests\NotInUseSpecificationFixture.cs" /> | ||||
|     <Compile Include="MediaFileTests\EpisodeImportTests\FreeSpaceSpecificationFixture.cs" /> | ||||
|     <Compile Include="MediaFileTests\RenameEpisodeFileServiceFixture.cs" /> | ||||
|     <Compile Include="MediaFileTests\UpgradeMediaFileServiceFixture.cs" /> | ||||
|   | ||||
| @@ -15,7 +15,6 @@ namespace NzbDrone.Core.MediaFiles | ||||
|     { | ||||
|         EpisodeFile MoveEpisodeFile(EpisodeFile episodeFile, Series series); | ||||
|         EpisodeFile MoveEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode); | ||||
|         EpisodeFile PreMoveEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode); | ||||
|     } | ||||
|  | ||||
|     public class MoveEpisodeFiles : IMoveEpisodeFiles | ||||
| @@ -59,15 +58,6 @@ namespace NzbDrone.Core.MediaFiles | ||||
|             return episodeFile; | ||||
|         } | ||||
|  | ||||
|         public EpisodeFile PreMoveEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode) | ||||
|         { | ||||
|             var newFileName = Path.GetFileNameWithoutExtension(episodeFile.Path); | ||||
|             var destinationFilename = _buildFileNames.BuildFilePath(localEpisode.Series, localEpisode.SeasonNumber, newFileName, Path.GetExtension(episodeFile.Path)); | ||||
|             episodeFile = MoveFile(episodeFile, destinationFilename); | ||||
|  | ||||
|             return episodeFile; | ||||
|         } | ||||
|  | ||||
|         private EpisodeFile MoveFile(EpisodeFile episodeFile, string destinationFilename) | ||||
|         { | ||||
|             if (!_diskProvider.FileExists(episodeFile.Path)) | ||||
|   | ||||
| @@ -0,0 +1,40 @@ | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using NLog; | ||||
| using NzbDrone.Common; | ||||
| using NzbDrone.Core.Parser.Model; | ||||
| using NzbDrone.Core.Tv; | ||||
|  | ||||
| namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications | ||||
| { | ||||
|     public class NotInUseSpecification : IImportDecisionEngineSpecification | ||||
|     { | ||||
|         private readonly IDiskProvider _diskProvider; | ||||
|         private readonly Logger _logger; | ||||
|  | ||||
|         public NotInUseSpecification(IDiskProvider diskProvider, Logger logger) | ||||
|         { | ||||
|             _diskProvider = diskProvider; | ||||
|             _logger = logger; | ||||
|         } | ||||
|  | ||||
|         public string RejectionReason { get { return "File is in use"; } } | ||||
|  | ||||
|         public bool IsSatisfiedBy(LocalEpisode localEpisode) | ||||
|         { | ||||
|             if (_diskProvider.IsParent(localEpisode.Series.Path, localEpisode.Path)) | ||||
|             { | ||||
|                 _logger.Trace("{0} is in series folder, skipping in use check", localEpisode.Path); | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             if (_diskProvider.IsFileLocked(new FileInfo(localEpisode.Path))) | ||||
|             { | ||||
|                 _logger.Trace("{0} is in use"); | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -38,8 +38,6 @@ namespace NzbDrone.Core.MediaFiles | ||||
|                                             .Select(e => e.EpisodeFile.Value) | ||||
|                                             .GroupBy(e => e.Id); | ||||
|  | ||||
|             episodeFile = _episodeFileMover.PreMoveEpisodeFile(episodeFile, localEpisode); | ||||
|  | ||||
|             foreach (var existingFile in existingFiles) | ||||
|             { | ||||
|                 var file = existingFile.First(); | ||||
|   | ||||
| @@ -224,6 +224,7 @@ | ||||
|     <Compile Include="MediaFiles\EpisodeImport\IImportDecisionEngineSpecification.cs" /> | ||||
|     <Compile Include="MediaFiles\EpisodeImport\ImportDecisionMaker.cs" /> | ||||
|     <Compile Include="MediaFiles\EpisodeImport\ImportApprovedEpisodes.cs" /> | ||||
|     <Compile Include="MediaFiles\EpisodeImport\Specifications\NotInUseSpecification.cs" /> | ||||
|     <Compile Include="MediaFiles\EpisodeImport\Specifications\FreeSpaceSpecification.cs" /> | ||||
|     <Compile Include="MediaFiles\EpisodeImport\Specifications\NotExistingFileSpecification.cs" /> | ||||
|     <Compile Include="MediaFiles\EpisodeImport\Specifications\UpgradeSpecification.cs" /> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user