New: Episode files sent to Recycling Bin are put into subfolders

Closes #401
This commit is contained in:
Mark McDowall 2017-03-29 06:44:50 -07:00
parent c20b152c28
commit 83370ddbbb
6 changed files with 37 additions and 12 deletions

View File

@ -2,6 +2,8 @@
using System.IO;
using NLog;
using NzbDrone.Api.REST;
using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.MediaFiles.Events;
@ -16,6 +18,7 @@ namespace NzbDrone.Api.EpisodeFiles
IHandle<EpisodeFileAddedEvent>
{
private readonly IMediaFileService _mediaFileService;
private readonly IDiskProvider _diskProvider;
private readonly IRecycleBinProvider _recycleBinProvider;
private readonly ISeriesService _seriesService;
private readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
@ -23,6 +26,7 @@ namespace NzbDrone.Api.EpisodeFiles
public EpisodeFileModule(IBroadcastSignalRMessage signalRBroadcaster,
IMediaFileService mediaFileService,
IDiskProvider diskProvider,
IRecycleBinProvider recycleBinProvider,
ISeriesService seriesService,
IQualityUpgradableSpecification qualityUpgradableSpecification,
@ -30,6 +34,7 @@ namespace NzbDrone.Api.EpisodeFiles
: base(signalRBroadcaster)
{
_mediaFileService = mediaFileService;
_diskProvider = diskProvider;
_recycleBinProvider = recycleBinProvider;
_seriesService = seriesService;
_qualityUpgradableSpecification = qualityUpgradableSpecification;
@ -74,9 +79,10 @@ namespace NzbDrone.Api.EpisodeFiles
var episodeFile = _mediaFileService.Get(id);
var series = _seriesService.GetSeries(episodeFile.SeriesId);
var fullPath = Path.Combine(series.Path, episodeFile.RelativePath);
var subfolder = _diskProvider.GetParentFolder(series.Path).GetRelativePath(_diskProvider.GetParentFolder(fullPath));
_logger.Info("Deleting episode file: {0}", fullPath);
_recycleBinProvider.DeleteFile(fullPath);
_recycleBinProvider.DeleteFile(fullPath, subfolder);
_mediaFileService.Delete(episodeFile, DeleteMediaFileReason.Manual);
}

View File

@ -95,7 +95,7 @@ namespace NzbDrone.Core.Test.MediaFiles
Subject.UpgradeEpisodeFile(_episodeFile, _localEpisode);
Mocker.GetMock<IRecycleBinProvider>().Verify(v => v.DeleteFile(It.IsAny<string>()), Times.Once());
Mocker.GetMock<IRecycleBinProvider>().Verify(v => v.DeleteFile(It.IsAny<string>(), It.IsAny<string>()), Times.Once());
}
[Test]
@ -105,7 +105,7 @@ namespace NzbDrone.Core.Test.MediaFiles
Subject.UpgradeEpisodeFile(_episodeFile, _localEpisode);
Mocker.GetMock<IRecycleBinProvider>().Verify(v => v.DeleteFile(It.IsAny<string>()), Times.Once());
Mocker.GetMock<IRecycleBinProvider>().Verify(v => v.DeleteFile(It.IsAny<string>(), It.IsAny<string>()), Times.Once());
}
[Test]
@ -115,7 +115,7 @@ namespace NzbDrone.Core.Test.MediaFiles
Subject.UpgradeEpisodeFile(_episodeFile, _localEpisode);
Mocker.GetMock<IRecycleBinProvider>().Verify(v => v.DeleteFile(It.IsAny<string>()), Times.Exactly(2));
Mocker.GetMock<IRecycleBinProvider>().Verify(v => v.DeleteFile(It.IsAny<string>(), It.IsAny<string>()), Times.Exactly(2));
}
[Test]
@ -153,7 +153,7 @@ namespace NzbDrone.Core.Test.MediaFiles
Subject.UpgradeEpisodeFile(_episodeFile, _localEpisode);
Mocker.GetMock<IRecycleBinProvider>().Verify(v => v.DeleteFile(It.IsAny<string>()), Times.Never());
Mocker.GetMock<IRecycleBinProvider>().Verify(v => v.DeleteFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
}
[Test]

View File

@ -75,5 +75,17 @@ namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests
Mocker.GetMock<IDiskProvider>().Verify(v => v.FileSetLastWriteTime(@"C:\Test\Recycle Bin\S01E01.avi".AsOsAgnostic(), It.IsAny<DateTime>()), Times.Once());
}
[Test]
public void should_use_subfolder_when_passed_in()
{
WithRecycleBin();
var path = @"C:\Test\TV\30 Rock\S01E01.avi".AsOsAgnostic();
Mocker.Resolve<RecycleBinProvider>().DeleteFile(path, "30 Rock");
Mocker.GetMock<IDiskTransferService>().Verify(v => v.TransferFile(path, @"C:\Test\Recycle Bin\30 Rock\S01E01.avi".AsOsAgnostic(), TransferMode.Move, false, true), Times.Once());
}
}
}

View File

@ -4,6 +4,7 @@ using System.IO;
using System.Linq;
using NLog;
using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Messaging.Events;
@ -129,7 +130,8 @@ namespace NzbDrone.Core.Extras.Files
else
{
// Send extra files to the recycling bin so they can be recovered if necessary
_recycleBinProvider.DeleteFile(path);
var subfolder = _diskProvider.GetParentFolder(series.Path).GetRelativePath(_diskProvider.GetParentFolder(path));
_recycleBinProvider.DeleteFile(path, subfolder);
}
}
}

View File

@ -15,7 +15,7 @@ namespace NzbDrone.Core.MediaFiles
public interface IRecycleBinProvider
{
void DeleteFolder(string path);
void DeleteFile(string path);
void DeleteFile(string path, string subfolder = "");
void Empty();
void Cleanup();
}
@ -73,7 +73,7 @@ namespace NzbDrone.Core.MediaFiles
}
}
public void DeleteFile(string path)
public void DeleteFile(string path, string subfolder = "")
{
_logger.Debug("Attempting to send '{0}' to recycling bin", path);
var recyclingBin = _configService.RecycleBin;
@ -94,7 +94,10 @@ namespace NzbDrone.Core.MediaFiles
else
{
var fileInfo = new FileInfo(path);
var destination = Path.Combine(recyclingBin, fileInfo.Name);
var destinationFolder = Path.Combine(recyclingBin, subfolder);
var destination = Path.Combine(destinationFolder, fileInfo.Name);
_diskProvider.CreateFolder(destinationFolder);
var index = 1;
while (_diskProvider.FileExists(destination))
@ -102,11 +105,11 @@ namespace NzbDrone.Core.MediaFiles
index++;
if (fileInfo.Extension.IsNullOrWhiteSpace())
{
destination = Path.Combine(recyclingBin, fileInfo.Name + "_" + index);
destination = Path.Combine(destinationFolder, fileInfo.Name + "_" + index);
}
else
{
destination = Path.Combine(recyclingBin, Path.GetFileNameWithoutExtension(fileInfo.Name) + "_" + index + fileInfo.Extension);
destination = Path.Combine(destinationFolder, Path.GetFileNameWithoutExtension(fileInfo.Name) + "_" + index + fileInfo.Extension);
}
}

View File

@ -2,6 +2,7 @@
using System.Linq;
using NLog;
using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.MediaFiles
@ -44,11 +45,12 @@ namespace NzbDrone.Core.MediaFiles
{
var file = existingFile.First();
var episodeFilePath = Path.Combine(localEpisode.Series.Path, file.RelativePath);
var subfolder = _diskProvider.GetParentFolder(localEpisode.Series.Path).GetRelativePath(_diskProvider.GetParentFolder(episodeFilePath));
if (_diskProvider.FileExists(episodeFilePath))
{
_logger.Debug("Removing existing episode file: {0}", file);
_recycleBinProvider.DeleteFile(episodeFilePath);
_recycleBinProvider.DeleteFile(episodeFilePath, subfolder);
}
moveFileResult.OldFiles.Add(file);