New: Episode files sent to Recycling Bin are put into subfolders
Closes #401
This commit is contained in:
parent
c20b152c28
commit
83370ddbbb
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue