2017-09-26 01:15:10 +00:00
|
|
|
using System;
|
2012-09-04 06:49:04 +00:00
|
|
|
using System.IO;
|
|
|
|
using NLog;
|
2014-01-06 06:20:08 +00:00
|
|
|
using NzbDrone.Common.Disk;
|
2013-07-30 00:09:48 +00:00
|
|
|
using NzbDrone.Common.EnvironmentInfo;
|
2014-12-02 06:26:25 +00:00
|
|
|
using NzbDrone.Common.Extensions;
|
2013-02-24 06:48:52 +00:00
|
|
|
using NzbDrone.Core.Configuration;
|
2013-05-07 00:39:33 +00:00
|
|
|
using NzbDrone.Core.MediaFiles.Commands;
|
2013-09-14 06:42:09 +00:00
|
|
|
using NzbDrone.Core.Messaging.Commands;
|
2012-09-04 06:49:04 +00:00
|
|
|
|
2013-05-07 00:39:33 +00:00
|
|
|
namespace NzbDrone.Core.MediaFiles
|
2012-09-04 06:49:04 +00:00
|
|
|
{
|
2013-07-16 02:56:46 +00:00
|
|
|
public interface IRecycleBinProvider
|
|
|
|
{
|
|
|
|
void DeleteFolder(string path);
|
2017-03-29 13:44:50 +00:00
|
|
|
void DeleteFile(string path, string subfolder = "");
|
2013-07-16 02:56:46 +00:00
|
|
|
void Empty();
|
|
|
|
void Cleanup();
|
|
|
|
}
|
|
|
|
|
2017-10-08 04:28:57 +00:00
|
|
|
public class RecycleBinProvider : IExecute<CleanUpRecycleBinCommand>, IRecycleBinProvider
|
2012-09-04 06:49:04 +00:00
|
|
|
{
|
2014-11-15 00:42:22 +00:00
|
|
|
private readonly IDiskTransferService _diskTransferService;
|
2013-05-10 23:53:50 +00:00
|
|
|
private readonly IDiskProvider _diskProvider;
|
2013-02-24 06:48:52 +00:00
|
|
|
private readonly IConfigService _configService;
|
2014-12-17 07:12:26 +00:00
|
|
|
private readonly Logger _logger;
|
2012-09-04 06:49:04 +00:00
|
|
|
|
2014-11-15 00:42:22 +00:00
|
|
|
public RecycleBinProvider(IDiskTransferService diskTransferService,
|
|
|
|
IDiskProvider diskProvider,
|
|
|
|
IConfigService configService,
|
|
|
|
Logger logger)
|
2012-09-04 06:49:04 +00:00
|
|
|
{
|
2014-11-15 00:42:22 +00:00
|
|
|
_diskTransferService = diskTransferService;
|
2012-09-04 06:49:04 +00:00
|
|
|
_diskProvider = diskProvider;
|
2013-02-24 06:48:52 +00:00
|
|
|
_configService = configService;
|
2014-12-17 07:12:26 +00:00
|
|
|
_logger = logger;
|
2012-09-04 06:49:04 +00:00
|
|
|
}
|
|
|
|
|
2013-07-16 02:56:46 +00:00
|
|
|
public void DeleteFolder(string path)
|
2012-09-04 06:49:04 +00:00
|
|
|
{
|
2014-12-17 07:12:26 +00:00
|
|
|
_logger.Info("Attempting to send '{0}' to recycling bin", path);
|
2013-02-24 06:48:52 +00:00
|
|
|
var recyclingBin = _configService.RecycleBin;
|
2012-09-04 06:49:04 +00:00
|
|
|
|
2015-10-03 17:45:26 +00:00
|
|
|
if (string.IsNullOrWhiteSpace(recyclingBin))
|
2012-09-04 06:49:04 +00:00
|
|
|
{
|
2014-12-17 07:12:26 +00:00
|
|
|
_logger.Info("Recycling Bin has not been configured, deleting permanently. {0}", path);
|
2012-09-04 06:49:04 +00:00
|
|
|
_diskProvider.DeleteFolder(path, true);
|
2014-12-17 07:12:26 +00:00
|
|
|
_logger.Debug("Folder has been permanently deleted: {0}", path);
|
2012-09-04 06:49:04 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
var destination = Path.Combine(recyclingBin, new DirectoryInfo(path).Name);
|
|
|
|
|
2014-12-17 07:12:26 +00:00
|
|
|
_logger.Debug("Moving '{0}' to '{1}'", path, destination);
|
2014-11-15 00:42:22 +00:00
|
|
|
_diskTransferService.TransferFolder(path, destination, TransferMode.Move);
|
2012-09-04 06:49:04 +00:00
|
|
|
|
2014-12-17 07:12:26 +00:00
|
|
|
_logger.Debug("Setting last accessed: {0}", path);
|
2014-10-14 21:31:35 +00:00
|
|
|
_diskProvider.FolderSetLastWriteTime(destination, DateTime.UtcNow);
|
2013-03-05 19:49:34 +00:00
|
|
|
foreach (var file in _diskProvider.GetFiles(destination, SearchOption.AllDirectories))
|
2012-09-04 06:49:04 +00:00
|
|
|
{
|
2017-10-29 03:00:09 +00:00
|
|
|
SetLastWriteTime(file, DateTime.UtcNow);
|
2012-09-04 06:49:04 +00:00
|
|
|
}
|
|
|
|
|
2014-12-17 07:12:26 +00:00
|
|
|
_logger.Debug("Folder has been moved to the recycling bin: {0}", destination);
|
2012-09-04 06:49:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-29 13:44:50 +00:00
|
|
|
public void DeleteFile(string path, string subfolder = "")
|
2012-09-04 06:49:04 +00:00
|
|
|
{
|
2014-12-17 07:12:26 +00:00
|
|
|
_logger.Debug("Attempting to send '{0}' to recycling bin", path);
|
2013-02-24 06:48:52 +00:00
|
|
|
var recyclingBin = _configService.RecycleBin;
|
2012-09-04 06:49:04 +00:00
|
|
|
|
2015-10-03 17:45:26 +00:00
|
|
|
if (string.IsNullOrWhiteSpace(recyclingBin))
|
2012-09-04 06:49:04 +00:00
|
|
|
{
|
2014-12-17 07:12:26 +00:00
|
|
|
_logger.Info("Recycling Bin has not been configured, deleting permanently. {0}", path);
|
2013-07-30 00:09:48 +00:00
|
|
|
|
2014-08-22 02:18:28 +00:00
|
|
|
if (OsInfo.IsWindows)
|
2013-07-30 00:09:48 +00:00
|
|
|
{
|
2014-12-17 07:12:26 +00:00
|
|
|
_logger.Debug(_diskProvider.GetFileAttributes(path));
|
2013-07-30 00:09:48 +00:00
|
|
|
}
|
|
|
|
|
2012-09-04 06:49:04 +00:00
|
|
|
_diskProvider.DeleteFile(path);
|
2014-12-17 07:12:26 +00:00
|
|
|
_logger.Debug("File has been permanently deleted: {0}", path);
|
2012-09-04 06:49:04 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-07-30 22:00:55 +00:00
|
|
|
var fileInfo = new FileInfo(path);
|
2017-03-29 13:44:50 +00:00
|
|
|
var destinationFolder = Path.Combine(recyclingBin, subfolder);
|
|
|
|
var destination = Path.Combine(destinationFolder, fileInfo.Name);
|
|
|
|
|
2021-01-17 18:27:58 +00:00
|
|
|
try
|
|
|
|
{
|
|
|
|
_logger.Debug("Creating folder [0]", destinationFolder);
|
|
|
|
_diskProvider.CreateFolder(destinationFolder);
|
|
|
|
}
|
|
|
|
catch (IOException e)
|
|
|
|
{
|
|
|
|
_logger.Error(e, "Unable to create the folder '{0}' in the recycling bin for the file '{1}'", destinationFolder, fileInfo.Name);
|
|
|
|
throw;
|
|
|
|
}
|
2014-07-30 22:00:55 +00:00
|
|
|
|
|
|
|
var index = 1;
|
|
|
|
while (_diskProvider.FileExists(destination))
|
|
|
|
{
|
|
|
|
index++;
|
|
|
|
if (fileInfo.Extension.IsNullOrWhiteSpace())
|
|
|
|
{
|
2017-03-29 13:44:50 +00:00
|
|
|
destination = Path.Combine(destinationFolder, fileInfo.Name + "_" + index);
|
2014-07-30 22:00:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 13:44:50 +00:00
|
|
|
destination = Path.Combine(destinationFolder, Path.GetFileNameWithoutExtension(fileInfo.Name) + "_" + index + fileInfo.Extension);
|
2014-07-30 22:00:55 +00:00
|
|
|
}
|
|
|
|
}
|
2012-09-04 06:49:04 +00:00
|
|
|
|
2015-09-20 17:41:50 +00:00
|
|
|
try
|
|
|
|
{
|
|
|
|
_logger.Debug("Moving '{0}' to '{1}'", path, destination);
|
|
|
|
_diskTransferService.TransferFile(path, destination, TransferMode.Move);
|
|
|
|
}
|
|
|
|
catch (IOException e)
|
|
|
|
{
|
2017-01-05 23:32:17 +00:00
|
|
|
_logger.Error(e, "Unable to move '{0}' to the recycling bin: '{1}'", path, destination);
|
2015-09-20 17:41:50 +00:00
|
|
|
throw;
|
|
|
|
}
|
2017-10-29 03:00:09 +00:00
|
|
|
|
|
|
|
SetLastWriteTime(destination, DateTime.UtcNow);
|
2014-08-22 02:18:28 +00:00
|
|
|
|
2014-12-17 07:12:26 +00:00
|
|
|
_logger.Debug("File has been moved to the recycling bin: {0}", destination);
|
2012-09-04 06:49:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-16 02:56:46 +00:00
|
|
|
public void Empty()
|
2012-09-04 06:49:04 +00:00
|
|
|
{
|
2015-10-03 17:45:26 +00:00
|
|
|
if (string.IsNullOrWhiteSpace(_configService.RecycleBin))
|
2012-09-04 06:49:04 +00:00
|
|
|
{
|
2014-12-17 07:12:26 +00:00
|
|
|
_logger.Info("Recycle Bin has not been configured, cannot empty.");
|
2012-09-04 06:49:04 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-12-17 07:12:26 +00:00
|
|
|
_logger.Info("Removing all items from the recycling bin");
|
2012-09-04 06:49:04 +00:00
|
|
|
|
2013-02-24 06:48:52 +00:00
|
|
|
foreach (var folder in _diskProvider.GetDirectories(_configService.RecycleBin))
|
2012-09-04 06:49:04 +00:00
|
|
|
{
|
|
|
|
_diskProvider.DeleteFolder(folder, true);
|
|
|
|
}
|
|
|
|
|
2013-02-24 06:48:52 +00:00
|
|
|
foreach (var file in _diskProvider.GetFiles(_configService.RecycleBin, SearchOption.TopDirectoryOnly))
|
2012-09-04 06:49:04 +00:00
|
|
|
{
|
|
|
|
_diskProvider.DeleteFile(file);
|
|
|
|
}
|
|
|
|
|
2014-12-17 07:12:26 +00:00
|
|
|
_logger.Debug("Recycling Bin has been emptied.");
|
2012-09-04 06:49:04 +00:00
|
|
|
}
|
|
|
|
|
2013-07-16 02:56:46 +00:00
|
|
|
public void Cleanup()
|
2012-09-04 06:49:04 +00:00
|
|
|
{
|
2015-10-03 17:45:26 +00:00
|
|
|
if (string.IsNullOrWhiteSpace(_configService.RecycleBin))
|
2012-09-04 06:49:04 +00:00
|
|
|
{
|
2014-12-17 07:12:26 +00:00
|
|
|
_logger.Info("Recycle Bin has not been configured, cannot cleanup.");
|
2012-09-04 06:49:04 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-08-11 07:22:26 +00:00
|
|
|
var cleanupDays = _configService.RecycleBinCleanupDays;
|
|
|
|
|
|
|
|
if (cleanupDays == 0)
|
|
|
|
{
|
|
|
|
_logger.Info("Automatic cleanup of Recycle Bin is disabled");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
_logger.Info("Removing items older than {0} days from the recycling bin", cleanupDays);
|
2012-09-04 06:49:04 +00:00
|
|
|
|
2019-09-12 02:26:34 +00:00
|
|
|
foreach (var file in _diskProvider.GetFiles(_configService.RecycleBin, SearchOption.AllDirectories))
|
2012-09-04 06:49:04 +00:00
|
|
|
{
|
2019-08-11 07:22:26 +00:00
|
|
|
if (_diskProvider.FileGetLastWrite(file).AddDays(cleanupDays) > DateTime.UtcNow)
|
2012-09-04 06:49:04 +00:00
|
|
|
{
|
2014-12-17 07:12:26 +00:00
|
|
|
_logger.Debug("File hasn't expired yet, skipping: {0}", file);
|
2012-09-04 06:49:04 +00:00
|
|
|
continue;
|
|
|
|
}
|
2013-03-05 19:49:34 +00:00
|
|
|
|
2012-09-04 06:49:04 +00:00
|
|
|
_diskProvider.DeleteFile(file);
|
|
|
|
}
|
|
|
|
|
2019-09-12 02:26:34 +00:00
|
|
|
_diskProvider.RemoveEmptySubfolders(_configService.RecycleBin);
|
|
|
|
|
2014-12-17 07:12:26 +00:00
|
|
|
_logger.Debug("Recycling Bin has been cleaned up.");
|
2012-09-04 06:49:04 +00:00
|
|
|
}
|
2013-03-05 19:49:34 +00:00
|
|
|
|
2017-10-29 03:00:09 +00:00
|
|
|
private void SetLastWriteTime(string file, DateTime dateTime)
|
|
|
|
{
|
|
|
|
// Swallow any IOException that may be thrown due to "Invalid parameter"
|
|
|
|
try
|
|
|
|
{
|
|
|
|
_diskProvider.FileSetLastWriteTime(file, dateTime);
|
|
|
|
}
|
|
|
|
catch (IOException)
|
|
|
|
{
|
|
|
|
}
|
2019-08-25 05:01:11 +00:00
|
|
|
catch (UnauthorizedAccessException)
|
|
|
|
{
|
|
|
|
}
|
2017-10-29 03:00:09 +00:00
|
|
|
}
|
|
|
|
|
2013-05-07 00:39:33 +00:00
|
|
|
public void Execute(CleanUpRecycleBinCommand message)
|
|
|
|
{
|
|
|
|
Cleanup();
|
2013-03-05 19:49:34 +00:00
|
|
|
}
|
2012-09-04 06:49:04 +00:00
|
|
|
}
|
|
|
|
}
|