New: Add recycle bin path for deleted episodes to webhook/custom script

Closes #6114
This commit is contained in:
Mark McDowall 2024-01-20 19:22:07 -08:00 committed by Mark McDowall
parent 9ba5850fca
commit a71d40edba
17 changed files with 60 additions and 34 deletions

View File

@ -176,7 +176,7 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
public void should_return_ok_on_episode_imported_event() public void should_return_ok_on_episode_imported_event()
{ {
GivenFolderExists(_downloadRootPath); GivenFolderExists(_downloadRootPath);
var importEvent = new EpisodeImportedEvent(new LocalEpisode(), new EpisodeFile(), new List<EpisodeFile>(), true, new DownloadClientItem()); var importEvent = new EpisodeImportedEvent(new LocalEpisode(), new EpisodeFile(), new List<DeletedEpisodeFile>(), true, new DownloadClientItem());
Subject.Check(importEvent).ShouldBeOk(); Subject.Check(importEvent).ShouldBeOk();
} }

View File

@ -66,7 +66,7 @@ namespace NzbDrone.Core.Test.HistoryTests
DownloadId = "abcd" DownloadId = "abcd"
}; };
Subject.Handle(new EpisodeImportedEvent(localEpisode, episodeFile, new List<EpisodeFile>(), true, downloadClientItem)); Subject.Handle(new EpisodeImportedEvent(localEpisode, episodeFile, new List<DeletedEpisodeFile>(), true, downloadClientItem));
Mocker.GetMock<IHistoryRepository>() Mocker.GetMock<IHistoryRepository>()
.Verify(v => v.Insert(It.Is<EpisodeHistory>(h => h.SourceTitle == Path.GetFileNameWithoutExtension(localEpisode.Path)))); .Verify(v => v.Insert(It.Is<EpisodeHistory>(h => h.SourceTitle == Path.GetFileNameWithoutExtension(localEpisode.Path))));

View File

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
@ -33,16 +33,16 @@ namespace NzbDrone.Core.Test.NotificationTests
RelativePath = "file1.S01E01E02.mkv" RelativePath = "file1.S01E01E02.mkv"
}, },
OldFiles = new List<EpisodeFile> OldFiles = new List<DeletedEpisodeFile>
{ {
new EpisodeFile new DeletedEpisodeFile(new EpisodeFile
{ {
RelativePath = "file1.S01E01.mkv" RelativePath = "file1.S01E01.mkv"
}, }, null),
new EpisodeFile new DeletedEpisodeFile(new EpisodeFile
{ {
RelativePath = "file1.S01E02.mkv" RelativePath = "file1.S01E02.mkv"
} }, null)
} }
}; };

View File

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using FizzWare.NBuilder; using FizzWare.NBuilder;
using Moq; using Moq;
@ -28,7 +28,7 @@ namespace NzbDrone.Core.Test.NotificationTests.Xbmc
_downloadMessage = Builder<DownloadMessage>.CreateNew() _downloadMessage = Builder<DownloadMessage>.CreateNew()
.With(d => d.Series = series) .With(d => d.Series = series)
.With(d => d.EpisodeFile = episodeFile) .With(d => d.EpisodeFile = episodeFile)
.With(d => d.OldFiles = new List<EpisodeFile>()) .With(d => d.OldFiles = new List<DeletedEpisodeFile>())
.Build(); .Build();
Subject.Definition = new NotificationDefinition(); Subject.Definition = new NotificationDefinition();
@ -40,9 +40,12 @@ namespace NzbDrone.Core.Test.NotificationTests.Xbmc
private void GivenOldFiles() private void GivenOldFiles()
{ {
_downloadMessage.OldFiles = Builder<EpisodeFile>.CreateListOfSize(1) _downloadMessage.OldFiles = Builder<DeletedEpisodeFile>
.Build() .CreateListOfSize(1)
.ToList(); .All()
.WithFactory(() => new DeletedEpisodeFile(Builder<EpisodeFile>.CreateNew().Build(), null))
.Build()
.ToList();
Subject.Definition.Settings = new XbmcSettings Subject.Definition.Settings = new XbmcSettings
{ {

View File

@ -0,0 +1,14 @@
namespace NzbDrone.Core.MediaFiles
{
public class DeletedEpisodeFile
{
public string RecycleBinPath { get; set; }
public EpisodeFile EpisodeFile { get; set; }
public DeletedEpisodeFile(EpisodeFile episodeFile, string recycleBinPath)
{
EpisodeFile = episodeFile;
RecycleBinPath = recycleBinPath;
}
}
}

View File

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace NzbDrone.Core.MediaFiles namespace NzbDrone.Core.MediaFiles
{ {
@ -6,10 +6,10 @@ namespace NzbDrone.Core.MediaFiles
{ {
public EpisodeFileMoveResult() public EpisodeFileMoveResult()
{ {
OldFiles = new List<EpisodeFile>(); OldFiles = new List<DeletedEpisodeFile>();
} }
public EpisodeFile EpisodeFile { get; set; } public EpisodeFile EpisodeFile { get; set; }
public List<EpisodeFile> OldFiles { get; set; } public List<DeletedEpisodeFile> OldFiles { get; set; }
} }
} }

View File

@ -67,7 +67,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
.ThenByDescending(e => e.LocalEpisode.Size)) .ThenByDescending(e => e.LocalEpisode.Size))
{ {
var localEpisode = importDecision.LocalEpisode; var localEpisode = importDecision.LocalEpisode;
var oldFiles = new List<EpisodeFile>(); var oldFiles = new List<DeletedEpisodeFile>();
try try
{ {

View File

@ -9,12 +9,12 @@ namespace NzbDrone.Core.MediaFiles.Events
{ {
public LocalEpisode EpisodeInfo { get; private set; } public LocalEpisode EpisodeInfo { get; private set; }
public EpisodeFile ImportedEpisode { get; private set; } public EpisodeFile ImportedEpisode { get; private set; }
public List<EpisodeFile> OldFiles { get; private set; } public List<DeletedEpisodeFile> OldFiles { get; private set; }
public bool NewDownload { get; private set; } public bool NewDownload { get; private set; }
public DownloadClientItemClientInfo DownloadClientInfo { get; set; } public DownloadClientItemClientInfo DownloadClientInfo { get; set; }
public string DownloadId { get; private set; } public string DownloadId { get; private set; }
public EpisodeImportedEvent(LocalEpisode episodeInfo, EpisodeFile importedEpisode, List<EpisodeFile> oldFiles, bool newDownload, DownloadClientItem downloadClientItem) public EpisodeImportedEvent(LocalEpisode episodeInfo, EpisodeFile importedEpisode, List<DeletedEpisodeFile> oldFiles, bool newDownload, DownloadClientItem downloadClientItem)
{ {
EpisodeInfo = episodeInfo; EpisodeInfo = episodeInfo;
ImportedEpisode = importedEpisode; ImportedEpisode = importedEpisode;

View File

@ -14,7 +14,7 @@ namespace NzbDrone.Core.MediaFiles
public interface IRecycleBinProvider public interface IRecycleBinProvider
{ {
void DeleteFolder(string path); void DeleteFolder(string path);
void DeleteFile(string path, string subfolder = ""); string DeleteFile(string path, string subfolder = "");
void Empty(); void Empty();
void Cleanup(); void Cleanup();
} }
@ -66,7 +66,7 @@ namespace NzbDrone.Core.MediaFiles
} }
} }
public void DeleteFile(string path, string subfolder = "") public string DeleteFile(string path, string subfolder = "")
{ {
_logger.Debug("Attempting to send '{0}' to recycling bin", path); _logger.Debug("Attempting to send '{0}' to recycling bin", path);
var recyclingBin = _configService.RecycleBin; var recyclingBin = _configService.RecycleBin;
@ -82,6 +82,8 @@ namespace NzbDrone.Core.MediaFiles
_diskProvider.DeleteFile(path); _diskProvider.DeleteFile(path);
_logger.Debug("File has been permanently deleted: {0}", path); _logger.Debug("File has been permanently deleted: {0}", path);
return null;
} }
else else
{ {
@ -128,6 +130,8 @@ namespace NzbDrone.Core.MediaFiles
SetLastWriteTime(destination, DateTime.UtcNow); SetLastWriteTime(destination, DateTime.UtcNow);
_logger.Debug("File has been moved to the recycling bin: {0}", destination); _logger.Debug("File has been moved to the recycling bin: {0}", destination);
return destination;
} }
} }

View File

@ -174,9 +174,10 @@ namespace NzbDrone.Core.MediaFiles
if (oldFiles.Any()) if (oldFiles.Any())
{ {
environmentVariables.Add("Sonarr_DeletedRelativePaths", string.Join("|", oldFiles.Select(e => e.RelativePath))); environmentVariables.Add("Sonarr_DeletedRelativePaths", string.Join("|", oldFiles.Select(e => e.EpisodeFile.RelativePath)));
environmentVariables.Add("Sonarr_DeletedPaths", string.Join("|", oldFiles.Select(e => Path.Combine(series.Path, e.RelativePath)))); environmentVariables.Add("Sonarr_DeletedPaths", string.Join("|", oldFiles.Select(e => Path.Combine(series.Path, e.EpisodeFile.RelativePath))));
environmentVariables.Add("Sonarr_DeletedDateAdded", string.Join("|", oldFiles.Select(e => e.DateAdded))); environmentVariables.Add("Sonarr_DeletedDateAdded", string.Join("|", oldFiles.Select(e => e.EpisodeFile.DateAdded)));
environmentVariables.Add("Sonarr_DeletedRecycleBinPaths", string.Join("|", oldFiles.Select(e => e.RecycleBinPath ?? string.Empty)));
} }
_logger.Debug("Executing external script: {0}", _configService.ScriptImportPath); _logger.Debug("Executing external script: {0}", _configService.ScriptImportPath);

View File

@ -57,14 +57,15 @@ namespace NzbDrone.Core.MediaFiles
var file = existingFile.First(); var file = existingFile.First();
var episodeFilePath = Path.Combine(localEpisode.Series.Path, file.RelativePath); var episodeFilePath = Path.Combine(localEpisode.Series.Path, file.RelativePath);
var subfolder = rootFolder.GetRelativePath(_diskProvider.GetParentFolder(episodeFilePath)); var subfolder = rootFolder.GetRelativePath(_diskProvider.GetParentFolder(episodeFilePath));
string recycleBinPath = null;
if (_diskProvider.FileExists(episodeFilePath)) if (_diskProvider.FileExists(episodeFilePath))
{ {
_logger.Debug("Removing existing episode file: {0}", file); _logger.Debug("Removing existing episode file: {0}", file);
_recycleBinProvider.DeleteFile(episodeFilePath, subfolder); recycleBinPath = _recycleBinProvider.DeleteFile(episodeFilePath, subfolder);
} }
moveFileResult.OldFiles.Add(file); moveFileResult.OldFiles.Add(new DeletedEpisodeFile(file, recycleBinPath));
_mediaFileService.Delete(file, DeleteMediaFileReason.Upgrade); _mediaFileService.Delete(file, DeleteMediaFileReason.Upgrade);
} }

View File

@ -158,9 +158,10 @@ namespace NzbDrone.Core.Notifications.CustomScript
if (message.OldFiles.Any()) if (message.OldFiles.Any())
{ {
environmentVariables.Add("Sonarr_DeletedRelativePaths", string.Join("|", message.OldFiles.Select(e => e.RelativePath))); environmentVariables.Add("Sonarr_DeletedRelativePaths", string.Join("|", message.OldFiles.Select(e => e.EpisodeFile.RelativePath)));
environmentVariables.Add("Sonarr_DeletedPaths", string.Join("|", message.OldFiles.Select(e => Path.Combine(series.Path, e.RelativePath)))); environmentVariables.Add("Sonarr_DeletedPaths", string.Join("|", message.OldFiles.Select(e => Path.Combine(series.Path, e.EpisodeFile.RelativePath))));
environmentVariables.Add("Sonarr_DeletedDateAdded", string.Join("|", message.OldFiles.Select(e => e.DateAdded))); environmentVariables.Add("Sonarr_DeletedDateAdded", string.Join("|", message.OldFiles.Select(e => e.EpisodeFile.DateAdded)));
environmentVariables.Add("Sonarr_DeletedRecycleBinPaths", string.Join("|", message.OldFiles.Select(e => e.RecycleBinPath ?? string.Empty)));
} }
ExecuteScript(environmentVariables); ExecuteScript(environmentVariables);

View File

@ -12,7 +12,7 @@ namespace NzbDrone.Core.Notifications
public Series Series { get; set; } public Series Series { get; set; }
public LocalEpisode EpisodeInfo { get; set; } public LocalEpisode EpisodeInfo { get; set; }
public EpisodeFile EpisodeFile { get; set; } public EpisodeFile EpisodeFile { get; set; }
public List<EpisodeFile> OldFiles { get; set; } public List<DeletedEpisodeFile> OldFiles { get; set; }
public string SourcePath { get; set; } public string SourcePath { get; set; }
public DownloadClientItemClientInfo DownloadClientInfo { get; set; } public DownloadClientItemClientInfo DownloadClientInfo { get; set; }
public string DownloadId { get; set; } public string DownloadId { get; set; }

View File

@ -29,7 +29,7 @@ namespace NzbDrone.Core.Notifications.Synology
{ {
foreach (var oldFile in message.OldFiles) foreach (var oldFile in message.OldFiles)
{ {
var fullPath = Path.Combine(message.Series.Path, oldFile.RelativePath); var fullPath = Path.Combine(message.Series.Path, oldFile.EpisodeFile.RelativePath);
_indexerProxy.DeleteFile(fullPath); _indexerProxy.DeleteFile(fullPath);
} }

View File

@ -65,9 +65,10 @@ namespace NzbDrone.Core.Notifications.Webhook
if (message.OldFiles.Any()) if (message.OldFiles.Any())
{ {
payload.DeletedFiles = message.OldFiles.ConvertAll(x => new WebhookEpisodeFile(x) payload.DeletedFiles = message.OldFiles.ConvertAll(x => new WebhookEpisodeFile(x.EpisodeFile)
{ {
Path = Path.Combine(message.Series.Path, x.RelativePath) Path = Path.Combine(message.Series.Path, x.EpisodeFile.RelativePath),
RecycleBinPath = x.RecycleBinPath
}); });
} }

View File

@ -37,5 +37,6 @@ namespace NzbDrone.Core.Notifications.Webhook
public long Size { get; set; } public long Size { get; set; }
public DateTime DateAdded { get; set; } public DateTime DateAdded { get; set; }
public WebhookEpisodeFileMediaInfo MediaInfo { get; set; } public WebhookEpisodeFileMediaInfo MediaInfo { get; set; }
public string RecycleBinPath { get; set; }
} }
} }

View File

@ -28,7 +28,7 @@ namespace NzbDrone.Core.Parser.Model
public ParsedEpisodeInfo FolderEpisodeInfo { get; set; } public ParsedEpisodeInfo FolderEpisodeInfo { get; set; }
public Series Series { get; set; } public Series Series { get; set; }
public List<Episode> Episodes { get; set; } public List<Episode> Episodes { get; set; }
public List<EpisodeFile> OldFiles { get; set; } public List<DeletedEpisodeFile> OldFiles { get; set; }
public QualityModel Quality { get; set; } public QualityModel Quality { get; set; }
public List<Language> Languages { get; set; } public List<Language> Languages { get; set; }
public MediaInfoModel MediaInfo { get; set; } public MediaInfoModel MediaInfo { get; set; }