From fca4d2004693f7aa5df2b806da73647a2e82a5c4 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Thu, 8 Aug 2013 08:52:22 -0700 Subject: [PATCH] Do not import episodes when destination doesn't have enough disk space --- .../FreeSpaceSpecificationFixture.cs | 75 +++++++++++++++++++ NzbDrone.Core.Test/NzbDrone.Core.Test.csproj | 1 + .../Specifications/FreeSpaceSpecification.cs | 41 ++++++++++ NzbDrone.Core/NzbDrone.Core.csproj | 1 + 4 files changed, 118 insertions(+) create mode 100644 NzbDrone.Core.Test/MediaFileTests/EpisodeImportTests/FreeSpaceSpecificationFixture.cs create mode 100644 NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/FreeSpaceSpecification.cs diff --git a/NzbDrone.Core.Test/MediaFileTests/EpisodeImportTests/FreeSpaceSpecificationFixture.cs b/NzbDrone.Core.Test/MediaFileTests/EpisodeImportTests/FreeSpaceSpecificationFixture.cs new file mode 100644 index 000000000..559919214 --- /dev/null +++ b/NzbDrone.Core.Test/MediaFileTests/EpisodeImportTests/FreeSpaceSpecificationFixture.cs @@ -0,0 +1,75 @@ +using System; +using System.Linq; +using FizzWare.NBuilder; +using FluentAssertions; +using Moq; +using NUnit.Framework; +using NzbDrone.Common; +using NzbDrone.Core.MediaFiles.EpisodeImport.Specifications; +using NzbDrone.Core.Parser.Model; +using NzbDrone.Core.Providers; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Core.Tv; +using NzbDrone.Test.Common; + +namespace NzbDrone.Core.Test.MediaFileTests.EpisodeImportTests +{ + [TestFixture] + public class FreeSpaceSpecificationFixture : CoreTest + { + private Series _series; + private LocalEpisode _localEpisode; + + [SetUp] + public void Setup() + { + _series = Builder.CreateNew() + .With(s => s.SeriesType = SeriesTypes.Standard) + .Build(); + + var episodes = Builder.CreateListOfSize(1) + .All() + .With(e => e.SeasonNumber = 1) + .Build() + .ToList(); + + _localEpisode = new LocalEpisode + { + Path = @"C:\Test\30 Rock\30.rock.s01e01.avi", + Episodes = episodes, + Series = _series + }; + } + + private void GivenFileSize(long size) + { + _localEpisode.Size = size; + } + + private void GivenFreeSpace(long size) + { + Mocker.GetMock() + .Setup(s => s.GetAvilableSpace(It.IsAny())) + .Returns(size); + } + + [Test] + public void should_reject_when_there_isnt_enough_disk_space() + { + GivenFileSize(100.Megabytes()); + GivenFreeSpace(80.Megabytes()); + + Subject.IsSatisfiedBy(_localEpisode).Should().BeFalse(); + ExceptionVerification.ExpectedWarns(1); + } + + [Test] + public void should_accept_when_there_is_enough_disk_space() + { + GivenFileSize(100.Megabytes()); + GivenFreeSpace(1.Gigabytes()); + + Subject.IsSatisfiedBy(_localEpisode).Should().BeTrue(); + } + } +} diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index 569b0ec82..ec23551c0 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -129,6 +129,7 @@ + diff --git a/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/FreeSpaceSpecification.cs b/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/FreeSpaceSpecification.cs new file mode 100644 index 000000000..7fe9ded66 --- /dev/null +++ b/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/FreeSpaceSpecification.cs @@ -0,0 +1,41 @@ +using System.IO; +using System.Linq; +using NLog; +using NzbDrone.Common; +using NzbDrone.Core.Organizer; +using NzbDrone.Core.Parser.Model; + +namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications +{ + public class FreeSpaceSpecification : IImportDecisionEngineSpecification + { + private readonly IBuildFileNames _buildFileNames; + private readonly IDiskProvider _diskProvider; + private readonly Logger _logger; + + public FreeSpaceSpecification(IBuildFileNames buildFileNames, IDiskProvider diskProvider, Logger logger) + { + _buildFileNames = buildFileNames; + _diskProvider = diskProvider; + _logger = logger; + } + + public string RejectionReason { get { return "Not enough free space"; } } + + public bool IsSatisfiedBy(LocalEpisode localEpisode) + { + var newFileName = Path.GetFileNameWithoutExtension(localEpisode.Path); + var destinationFilename = _buildFileNames.BuildFilePath(localEpisode.Series, localEpisode.SeasonNumber, newFileName, Path.GetExtension(localEpisode.Path)); + + var freeSpace = _diskProvider.GetAvilableSpace(destinationFilename); + + if (freeSpace < localEpisode.Size) + { + _logger.Warn("Not enough free space to import: {0}", localEpisode); + return false; + } + + return true; + } + } +} diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index c6a7dbede..ada5b62e4 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -224,6 +224,7 @@ +