From 5926ca5d8a78ed3b907a18b0b5a2bba3703e330e Mon Sep 17 00:00:00 2001 From: Robin Dadswell <19610103+RobinDadswell@users.noreply.github.com> Date: Fri, 5 Mar 2021 23:30:08 +0000 Subject: [PATCH] New: On Movie Delete and On Movie File Delete Notifications --- .../Notifications/Notification.js | 77 +++++++++++++------ .../Notifications/NotificationEventItems.js | 41 ++++++++-- .../Store/Actions/Settings/notifications.js | 3 + .../Notifications/NotificationModule.cs | 18 +++-- .../Notifications/NotificationResource.cs | 10 ++- .../NotificationBaseFixture.cs | 19 +++-- .../192_add_on_delete_to_notifications.cs | 16 ++++ src/NzbDrone.Core/Datastore/TableMapping.cs | 4 +- src/NzbDrone.Core/Localization/Core/en.json | 9 ++- .../MediaFiles/Events/DeleteCompletedEvent.cs | 8 ++ .../MediaFiles/MediaFileDeletionService.cs | 7 ++ .../Notifications/Boxcar/Boxcar.cs | 10 +++ .../CustomScript/CustomScript.cs | 49 ++++++++++++ .../Notifications/Discord/Discord.cs | 38 +++++++++ .../DiscordNotifier/DiscordNotifier.cs | 48 ++++++++++++ .../Notifications/Email/Email.cs | 14 ++++ .../Notifications/Gotify/Gotify.cs | 10 +++ .../Notifications/INotification.cs | 7 +- src/NzbDrone.Core/Notifications/Join/Join.cs | 10 +++ .../Notifications/MovieDeleteMessage.cs | 28 +++++++ .../Notifications/MovieFileDeleteMessage.cs | 19 +++++ .../Notifications/NotificationBase.cs | 17 +++- .../Notifications/NotificationDefinition.cs | 10 ++- .../Notifications/NotificationFactory.cs | 27 +++++-- .../Notifications/NotificationService.cs | 66 ++++++++++++---- .../Notifications/Plex/Server/PlexServer.cs | 13 ++++ .../Notifications/Prowl/Prowl.cs | 14 +++- .../Notifications/PushBullet/PushBullet.cs | 10 +++ .../Notifications/Pushover/Pushover.cs | 10 +++ .../Notifications/SendGrid/SendGrid.cs | 10 +++ .../Notifications/Slack/Slack.cs | 34 ++++++++ .../Notifications/Synology/SynologyIndexer.cs | 20 +++++ .../Notifications/Telegram/Telegram.cs | 10 +++ .../Notifications/Trakt/Trakt.cs | 11 ++- .../Notifications/Trakt/TraktService.cs | 4 +- .../Notifications/Twitter/Twitter.cs | 10 +++ .../Notifications/Webhook/Webhook.cs | 25 ++++++ .../Notifications/Webhook/WebhookEventType.cs | 2 + .../Webhook/WebhookMovieDeletePayload.cs | 10 +++ .../Webhook/WebhookMovieFileDeletePayload.cs | 12 +++ src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs | 19 +++++ .../Notifications/NotificationResource.cs | 24 ++++-- 42 files changed, 714 insertions(+), 89 deletions(-) create mode 100644 src/NzbDrone.Core/Datastore/Migration/192_add_on_delete_to_notifications.cs create mode 100644 src/NzbDrone.Core/MediaFiles/Events/DeleteCompletedEvent.cs create mode 100644 src/NzbDrone.Core/Notifications/MovieDeleteMessage.cs create mode 100644 src/NzbDrone.Core/Notifications/MovieFileDeleteMessage.cs create mode 100644 src/NzbDrone.Core/Notifications/Webhook/WebhookMovieDeletePayload.cs create mode 100644 src/NzbDrone.Core/Notifications/Webhook/WebhookMovieFileDeletePayload.cs diff --git a/frontend/src/Settings/Notifications/Notifications/Notification.js b/frontend/src/Settings/Notifications/Notifications/Notification.js index b30b19716..d571545f0 100644 --- a/frontend/src/Settings/Notifications/Notifications/Notification.js +++ b/frontend/src/Settings/Notifications/Notifications/Notification.js @@ -59,13 +59,17 @@ class Notification extends Component { onDownload, onUpgrade, onRename, - onDelete, + onMovieDelete, + onMovieFileDelete, + onMovieFileDeleteForUpgrade, onHealthIssue, supportsOnGrab, supportsOnDownload, supportsOnUpgrade, supportsOnRename, - supportsOnDelete, + supportsOnMovieDelete, + supportsOnMovieFileDelete, + supportsOnMovieFileDeleteForUpgrade, supportsOnHealthIssue } = this.props; @@ -80,55 +84,78 @@ class Notification extends Component { { - supportsOnGrab && onGrab && + supportsOnGrab && onGrab ? + : + null } { - supportsOnDelete && onDelete && - - } - - { - supportsOnDownload && onDownload && + supportsOnDownload && onDownload ? + : + null } { - supportsOnUpgrade && onDownload && onUpgrade && + supportsOnUpgrade && onDownload && onUpgrade ? + : + null } { - supportsOnRename && onRename && + supportsOnRename && onRename ? + : + null } { - supportsOnHealthIssue && onHealthIssue && + supportsOnHealthIssue && onHealthIssue ? + : + null + } + + { + supportsOnMovieDelete && onMovieDelete ? + : + null + } + + { + supportsOnMovieFileDelete && onMovieFileDelete ? + : + null + } + + { + supportsOnMovieFileDeleteForUpgrade && onMovieFileDelete && onMovieFileDeleteForUpgrade ? + : + null } { - !onGrab && !onDownload && !onRename && !onHealthIssue && !onDelete && + !onGrab && !onDownload && !onRename && !onHealthIssue && !onMovieDelete && !onMovieFileDelete ? + : + null } +
+ +
+ + { + onMovieFileDelete.value && +
+ +
+ } +
Tags { get; set; } } } diff --git a/src/NzbDrone.Core.Test/NotificationTests/NotificationBaseFixture.cs b/src/NzbDrone.Core.Test/NotificationTests/NotificationBaseFixture.cs index 7ed370e84..e8ba8551a 100644 --- a/src/NzbDrone.Core.Test/NotificationTests/NotificationBaseFixture.cs +++ b/src/NzbDrone.Core.Test/NotificationTests/NotificationBaseFixture.cs @@ -1,4 +1,4 @@ -using System; +using System; using FluentAssertions; using FluentValidation.Results; using NUnit.Framework; @@ -62,9 +62,14 @@ namespace NzbDrone.Core.Test.NotificationTests TestLogger.Info("OnRename was called"); } - public override void OnDelete(DeleteMessage message) + public override void OnMovieFileDelete(MovieFileDeleteMessage message) { - TestLogger.Info("OnDelete was called"); + TestLogger.Info("OnMovieFileDelete was called"); + } + + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + TestLogger.Info("OnMovieDelete was called"); } public override void OnHealthIssue(NzbDrone.Core.HealthCheck.HealthCheck artist) @@ -105,7 +110,9 @@ namespace NzbDrone.Core.Test.NotificationTests notification.SupportsOnDownload.Should().BeTrue(); notification.SupportsOnUpgrade.Should().BeTrue(); notification.SupportsOnRename.Should().BeTrue(); - notification.SupportsOnDelete.Should().BeTrue(); + notification.SupportsOnMovieDelete.Should().BeTrue(); + notification.SupportsOnMovieFileDelete.Should().BeTrue(); + notification.SupportsOnMovieFileDeleteForUpgrade.Should().BeTrue(); notification.SupportsOnHealthIssue.Should().BeTrue(); } @@ -118,7 +125,9 @@ namespace NzbDrone.Core.Test.NotificationTests notification.SupportsOnDownload.Should().BeFalse(); notification.SupportsOnUpgrade.Should().BeFalse(); notification.SupportsOnRename.Should().BeFalse(); - notification.SupportsOnDelete.Should().BeFalse(); + notification.SupportsOnMovieDelete.Should().BeFalse(); + notification.SupportsOnMovieFileDelete.Should().BeFalse(); + notification.SupportsOnMovieFileDeleteForUpgrade.Should().BeFalse(); notification.SupportsOnHealthIssue.Should().BeFalse(); } } diff --git a/src/NzbDrone.Core/Datastore/Migration/192_add_on_delete_to_notifications.cs b/src/NzbDrone.Core/Datastore/Migration/192_add_on_delete_to_notifications.cs new file mode 100644 index 000000000..3c1f0a252 --- /dev/null +++ b/src/NzbDrone.Core/Datastore/Migration/192_add_on_delete_to_notifications.cs @@ -0,0 +1,16 @@ +using FluentMigrator; +using NzbDrone.Core.Datastore.Migration.Framework; + +namespace NzbDrone.Core.Datastore.Migration +{ + [Migration(192)] + public class add_on_delete_to_notifications : NzbDroneMigrationBase + { + protected override void MainDbUpgrade() + { + Rename.Column("OnDelete").OnTable("Notifications").To("OnMovieDelete"); + Alter.Table("Notifications").AddColumn("OnMovieFileDelete").AsBoolean().WithDefaultValue(0); + Alter.Table("Notifications").AddColumn("OnMovieFileDeleteForUpgrade").AsBoolean().WithDefaultValue(0); + } + } +} diff --git a/src/NzbDrone.Core/Datastore/TableMapping.cs b/src/NzbDrone.Core/Datastore/TableMapping.cs index 1014d4bae..833e739fc 100644 --- a/src/NzbDrone.Core/Datastore/TableMapping.cs +++ b/src/NzbDrone.Core/Datastore/TableMapping.cs @@ -87,7 +87,9 @@ namespace NzbDrone.Core.Datastore .Ignore(i => i.SupportsOnDownload) .Ignore(i => i.SupportsOnUpgrade) .Ignore(i => i.SupportsOnRename) - .Ignore(i => i.SupportsOnDelete) + .Ignore(i => i.SupportsOnMovieDelete) + .Ignore(i => i.SupportsOnMovieFileDelete) + .Ignore(i => i.SupportsOnMovieFileDeleteForUpgrade) .Ignore(i => i.SupportsOnHealthIssue); Mapper.Entity("Metadata").RegisterModel() diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 9acbc06d7..6b83bf55c 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -612,8 +612,6 @@ "NoVideoFilesFoundSelectedFolder": "No video files were found in the selected folder", "OAuthPopupMessage": "Pop-ups are being blocked by your browser", "Ok": "Ok", - "OnDelete": "On Delete", - "OnDeleteHelpText": "On Delete", "OnDownloadHelpText": "On Import", "OnGrab": "On Grab", "OnGrabHelpText": "On Grab", @@ -623,8 +621,15 @@ "OnLatestVersion": "The latest version of Radarr is already installed", "OnlyTorrent": "Only Torrent", "OnlyUsenet": "Only Usenet", + "OnMovieDelete": "On Movie Delete", + "OnMovieDeleteHelpText": "On Movie Delete", + "OnMovieFileDelete": "On Movie File Delete", + "OnMovieFileDeleteHelpText": "On Movie File Delete", + "OnMovieFileDeleteForUpgrade": "On Movie File Delete For Upgrade", + "OnMovieFileDeleteForUpgradeHelpText": "On Movie File Delete For Upgrade", "OnRename": "On Rename", "OnRenameHelpText": "On Rename", + "OnUpgrade": "On Upgrade", "OnUpgradeHelpText": "On Upgrade", "OpenBrowserOnStart": "Open browser on start", "OpenThisModal": "Open This Modal", diff --git a/src/NzbDrone.Core/MediaFiles/Events/DeleteCompletedEvent.cs b/src/NzbDrone.Core/MediaFiles/Events/DeleteCompletedEvent.cs new file mode 100644 index 000000000..f987bc1c2 --- /dev/null +++ b/src/NzbDrone.Core/MediaFiles/Events/DeleteCompletedEvent.cs @@ -0,0 +1,8 @@ +using NzbDrone.Common.Messaging; + +namespace NzbDrone.Core.MediaFiles.Events +{ + public class DeleteCompletedEvent : IEvent + { + } +} diff --git a/src/NzbDrone.Core/MediaFiles/MediaFileDeletionService.cs b/src/NzbDrone.Core/MediaFiles/MediaFileDeletionService.cs index c23ef9f91..32f5cdd77 100644 --- a/src/NzbDrone.Core/MediaFiles/MediaFileDeletionService.cs +++ b/src/NzbDrone.Core/MediaFiles/MediaFileDeletionService.cs @@ -28,6 +28,7 @@ namespace NzbDrone.Core.MediaFiles private readonly IMediaFileService _mediaFileService; private readonly IMovieService _movieService; private readonly IConfigService _configService; + private readonly IEventAggregator _eventAggregator; private readonly Logger _logger; public MediaFileDeletionService(IDiskProvider diskProvider, @@ -35,6 +36,7 @@ namespace NzbDrone.Core.MediaFiles IMediaFileService mediaFileService, IMovieService movieService, IConfigService configService, + IEventAggregator eventAggregator, Logger logger) { _diskProvider = diskProvider; @@ -42,6 +44,7 @@ namespace NzbDrone.Core.MediaFiles _mediaFileService = mediaFileService; _movieService = movieService; _configService = configService; + _eventAggregator = eventAggregator; _logger = logger; } @@ -81,6 +84,8 @@ namespace NzbDrone.Core.MediaFiles // Delete the movie file from the database to clean it up even if the file was already deleted _mediaFileService.Delete(movieFile, DeleteMediaFileReason.Manual); + + _eventAggregator.PublishEvent(new DeleteCompletedEvent()); } public void HandleAsync(MoviesDeletedEvent message) @@ -116,6 +121,8 @@ namespace NzbDrone.Core.MediaFiles _recycleBinProvider.DeleteFolder(movie.Path); } } + + _eventAggregator.PublishEvent(new DeleteCompletedEvent()); } } diff --git a/src/NzbDrone.Core/Notifications/Boxcar/Boxcar.cs b/src/NzbDrone.Core/Notifications/Boxcar/Boxcar.cs index b2fc8ec1c..5bed87b59 100644 --- a/src/NzbDrone.Core/Notifications/Boxcar/Boxcar.cs +++ b/src/NzbDrone.Core/Notifications/Boxcar/Boxcar.cs @@ -26,6 +26,16 @@ namespace NzbDrone.Core.Notifications.Boxcar _proxy.SendNotification(MOVIE_DOWNLOADED_TITLE, message.Message, Settings); } + public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) + { + _proxy.SendNotification(MOVIE_FILE_DELETED_TITLE, deleteMessage.Message, Settings); + } + + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + _proxy.SendNotification(MOVIE_DELETED_TITLE, deleteMessage.Message, Settings); + } + public override void OnHealthIssue(HealthCheck.HealthCheck message) { _proxy.SendNotification(HEALTH_ISSUE_TITLE, message.Message, Settings); diff --git a/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs b/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs index a34601e21..5731b1f0f 100755 --- a/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs +++ b/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs @@ -117,6 +117,55 @@ namespace NzbDrone.Core.Notifications.CustomScript ExecuteScript(environmentVariables); } + public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) + { + var movie = deleteMessage.Movie; + var movieFile = deleteMessage.MovieFile; + + var environmentVariables = new StringDictionary(); + + environmentVariables.Add("Radarr_EventType", "MovieFileDelete"); + environmentVariables.Add("Radarr_MovieFile_DeleteReason", deleteMessage.Reason.ToString()); + environmentVariables.Add("Radarr_Movie_Id", movie.Id.ToString()); + environmentVariables.Add("Radarr_Movie_Title", movie.Title); + environmentVariables.Add("Radarr_Movie_Year", movie.Year.ToString()); + environmentVariables.Add("Radarr_Movie_Path", movie.Path); + environmentVariables.Add("Radarr_Movie_ImdbId", movie.ImdbId ?? string.Empty); + environmentVariables.Add("Radarr_Movie_TmdbId", movie.TmdbId.ToString()); + environmentVariables.Add("Radarr_MovieFile_Id", movieFile.Id.ToString()); + environmentVariables.Add("Radarr_MovieFile_RelativePath", movieFile.RelativePath); + environmentVariables.Add("Radarr_MovieFile_Path", Path.Combine(movie.Path, movieFile.RelativePath)); + environmentVariables.Add("Radarr_MovieFile_Size", movieFile.Size.ToString()); + environmentVariables.Add("Radarr_MovieFile_Quality", movieFile.Quality.Quality.Name); + environmentVariables.Add("Radarr_MovieFile_QualityVersion", movieFile.Quality.Revision.Version.ToString()); + environmentVariables.Add("Radarr_MovieFile_ReleaseGroup", movieFile.ReleaseGroup ?? string.Empty); + environmentVariables.Add("Radarr_MovieFile_SceneName", movieFile.SceneName ?? string.Empty); + + ExecuteScript(environmentVariables); + } + + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + var movie = deleteMessage.Movie; + var environmentVariables = new StringDictionary(); + + environmentVariables.Add("Radarr_EventType", "MovieDelete"); + environmentVariables.Add("Radarr_Movie_Id", movie.Id.ToString()); + environmentVariables.Add("Radarr_Movie_Title", movie.Title); + environmentVariables.Add("Radarr_Movie_Year", movie.Year.ToString()); + environmentVariables.Add("Radarr_Movie_Path", movie.Path); + environmentVariables.Add("Radarr_Movie_ImdbId", movie.ImdbId ?? string.Empty); + environmentVariables.Add("Radarr_Movie_TmdbId", movie.TmdbId.ToString()); + environmentVariables.Add("Radarr_Movie_DeletedFiles", deleteMessage.DeletedFiles.ToString()); + + if (deleteMessage.DeletedFiles && movie.MovieFile != null) + { + environmentVariables.Add("Radarr_Movie_Folder_Size", movie.MovieFile.Size.ToString()); + } + + ExecuteScript(environmentVariables); + } + public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { var environmentVariables = new StringDictionary(); diff --git a/src/NzbDrone.Core/Notifications/Discord/Discord.cs b/src/NzbDrone.Core/Notifications/Discord/Discord.cs index 56780c274..458859e1d 100644 --- a/src/NzbDrone.Core/Notifications/Discord/Discord.cs +++ b/src/NzbDrone.Core/Notifications/Discord/Discord.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using FluentValidation.Results; using NzbDrone.Common.Extensions; @@ -212,6 +213,43 @@ namespace NzbDrone.Core.Notifications.Discord _proxy.SendPayload(payload, Settings); } + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + var movie = deleteMessage.Movie; + + var attachments = new List + { + new Embed + { + Title = movie.Title, + Description = deleteMessage.DeletedFilesMessage + } + }; + + var payload = CreatePayload("Movie Deleted", attachments); + + _proxy.SendPayload(payload, Settings); + } + + public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) + { + var movie = deleteMessage.Movie; + + var fullPath = Path.Combine(deleteMessage.Movie.Path, deleteMessage.MovieFile.RelativePath); + var attachments = new List + { + new Embed + { + Title = movie.Title, + Description = deleteMessage.MovieFile.Path + } + }; + + var payload = CreatePayload("Movie File Deleted", attachments); + + _proxy.SendPayload(payload, Settings); + } + public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { var attachments = new List diff --git a/src/NzbDrone.Core/Notifications/DiscordNotifier/DiscordNotifier.cs b/src/NzbDrone.Core/Notifications/DiscordNotifier/DiscordNotifier.cs index 1ee534d4c..b9a18f860 100644 --- a/src/NzbDrone.Core/Notifications/DiscordNotifier/DiscordNotifier.cs +++ b/src/NzbDrone.Core/Notifications/DiscordNotifier/DiscordNotifier.cs @@ -86,6 +86,54 @@ namespace NzbDrone.Core.Notifications.DiscordNotifier _proxy.SendNotification(variables, Settings); } + public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) + { + var movie = deleteMessage.Movie; + var movieFile = deleteMessage.MovieFile; + + var variables = new StringDictionary(); + + variables.Add("Radarr_EventType", "MovieFileDelete"); + variables.Add("Radarr_MovieFile_DeleteReason", deleteMessage.Reason.ToString()); + variables.Add("Radarr_Movie_Id", movie.Id.ToString()); + variables.Add("Radarr_Movie_Title", movie.Title); + variables.Add("Radarr_Movie_Year", movie.Year.ToString()); + variables.Add("Radarr_Movie_Path", movie.Path); + variables.Add("Radarr_Movie_ImdbId", movie.ImdbId ?? string.Empty); + variables.Add("Radarr_Movie_TmdbId", movie.TmdbId.ToString()); + variables.Add("Radarr_MovieFile_Id", movieFile.Id.ToString()); + variables.Add("Radarr_MovieFile_RelativePath", movieFile.RelativePath); + variables.Add("Radarr_MovieFile_Path", Path.Combine(movie.Path, movieFile.RelativePath)); + variables.Add("Radarr_MovieFile_Size", movieFile.Size.ToString()); + variables.Add("Radarr_MovieFile_Quality", movieFile.Quality.Quality.Name); + variables.Add("Radarr_MovieFile_QualityVersion", movieFile.Quality.Revision.Version.ToString()); + variables.Add("Radarr_MovieFile_ReleaseGroup", movieFile.ReleaseGroup ?? string.Empty); + variables.Add("Radarr_MovieFile_SceneName", movieFile.SceneName ?? string.Empty); + + _proxy.SendNotification(variables, Settings); + } + + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + var movie = deleteMessage.Movie; + var variables = new StringDictionary(); + + variables.Add("Radarr_EventType", "MovieDelete"); + variables.Add("Radarr_Movie_Id", movie.Id.ToString()); + variables.Add("Radarr_Movie_Title", movie.Title); + variables.Add("Radarr_Movie_Year", movie.Year.ToString()); + variables.Add("Radarr_Movie_Path", movie.Path); + variables.Add("Radarr_Movie_ImdbId", movie.ImdbId ?? string.Empty); + variables.Add("Radarr_Movie_TmdbId", movie.TmdbId.ToString()); + variables.Add("Radarr_Movie_DeletedFiles", deleteMessage.DeletedFiles.ToString()); + if (deleteMessage.DeletedFiles && movie.MovieFile != null) + { + variables.Add("Radarr_Movie_Folder_Size", movie.MovieFile.Size.ToString()); + } + + _proxy.SendNotification(variables, Settings); + } + public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { var variables = new StringDictionary(); diff --git a/src/NzbDrone.Core/Notifications/Email/Email.cs b/src/NzbDrone.Core/Notifications/Email/Email.cs index 1dd7623c4..69add44d9 100644 --- a/src/NzbDrone.Core/Notifications/Email/Email.cs +++ b/src/NzbDrone.Core/Notifications/Email/Email.cs @@ -31,6 +31,20 @@ namespace NzbDrone.Core.Notifications.Email _emailService.SendEmail(Settings, MOVIE_DOWNLOADED_TITLE_BRANDED, body); } + public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) + { + var body = $"{deleteMessage.Message} deleted."; + + _emailService.SendEmail(Settings, MOVIE_FILE_DELETED_TITLE_BRANDED, body); + } + + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + var body = $"{deleteMessage.Message}"; + + _emailService.SendEmail(Settings, MOVIE_DELETED_TITLE_BRANDED, body); + } + public override void OnHealthIssue(HealthCheck.HealthCheck message) { _emailService.SendEmail(Settings, HEALTH_ISSUE_TITLE_BRANDED, message.Message); diff --git a/src/NzbDrone.Core/Notifications/Gotify/Gotify.cs b/src/NzbDrone.Core/Notifications/Gotify/Gotify.cs index 94e3380e2..349606c49 100644 --- a/src/NzbDrone.Core/Notifications/Gotify/Gotify.cs +++ b/src/NzbDrone.Core/Notifications/Gotify/Gotify.cs @@ -29,6 +29,16 @@ namespace NzbDrone.Core.Notifications.Gotify _proxy.SendNotification(MOVIE_DOWNLOADED_TITLE, message.Message, Settings); } + public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) + { + _proxy.SendNotification(MOVIE_FILE_DELETED_TITLE, deleteMessage.Message, Settings); + } + + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + _proxy.SendNotification(MOVIE_DELETED_TITLE, deleteMessage.Message, Settings); + } + public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { _proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings); diff --git a/src/NzbDrone.Core/Notifications/INotification.cs b/src/NzbDrone.Core/Notifications/INotification.cs index 7b955950f..63e897ca9 100644 --- a/src/NzbDrone.Core/Notifications/INotification.cs +++ b/src/NzbDrone.Core/Notifications/INotification.cs @@ -10,14 +10,17 @@ namespace NzbDrone.Core.Notifications void OnGrab(GrabMessage grabMessage); void OnDownload(DownloadMessage message); void OnMovieRename(Movie movie); + void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage); + void OnMovieDelete(MovieDeleteMessage deleteMessage); void OnHealthIssue(HealthCheck.HealthCheck healthCheck); - void OnDelete(DeleteMessage deleteMessage); void ProcessQueue(); bool SupportsOnGrab { get; } bool SupportsOnDownload { get; } bool SupportsOnUpgrade { get; } bool SupportsOnRename { get; } + bool SupportsOnMovieDelete { get; } + bool SupportsOnMovieFileDelete { get; } + bool SupportsOnMovieFileDeleteForUpgrade { get; } bool SupportsOnHealthIssue { get; } - bool SupportsOnDelete { get; } } } diff --git a/src/NzbDrone.Core/Notifications/Join/Join.cs b/src/NzbDrone.Core/Notifications/Join/Join.cs index 7b1c6b05f..a9da69308 100644 --- a/src/NzbDrone.Core/Notifications/Join/Join.cs +++ b/src/NzbDrone.Core/Notifications/Join/Join.cs @@ -27,6 +27,16 @@ namespace NzbDrone.Core.Notifications.Join _proxy.SendNotification(MOVIE_DOWNLOADED_TITLE_BRANDED, message.Message, Settings); } + public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) + { + _proxy.SendNotification(MOVIE_FILE_DELETED_TITLE_BRANDED, deleteMessage.Message, Settings); + } + + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + _proxy.SendNotification(MOVIE_DELETED_TITLE_BRANDED, deleteMessage.Message, Settings); + } + public override void OnHealthIssue(HealthCheck.HealthCheck message) { _proxy.SendNotification(HEALTH_ISSUE_TITLE_BRANDED, message.Message, Settings); diff --git a/src/NzbDrone.Core/Notifications/MovieDeleteMessage.cs b/src/NzbDrone.Core/Notifications/MovieDeleteMessage.cs new file mode 100644 index 000000000..8c89d0165 --- /dev/null +++ b/src/NzbDrone.Core/Notifications/MovieDeleteMessage.cs @@ -0,0 +1,28 @@ +using NzbDrone.Core.MediaFiles; +using NzbDrone.Core.Movies; + +namespace NzbDrone.Core.Notifications +{ + public class MovieDeleteMessage + { + public string Message { get; set; } + public Movie Movie { get; set; } + public bool DeletedFiles { get; set; } + public string DeletedFilesMessage { get; set; } + + public override string ToString() + { + return Message; + } + + public MovieDeleteMessage(Movie movie, bool deleteFiles) + { + Movie = movie; + DeletedFiles = deleteFiles; + DeletedFilesMessage = DeletedFiles ? + "Movie removed and all files were deleted" : + "Movie removed, files were not deleted"; + Message = movie.Title + " - " + DeletedFilesMessage; + } + } +} diff --git a/src/NzbDrone.Core/Notifications/MovieFileDeleteMessage.cs b/src/NzbDrone.Core/Notifications/MovieFileDeleteMessage.cs new file mode 100644 index 000000000..5c17c9765 --- /dev/null +++ b/src/NzbDrone.Core/Notifications/MovieFileDeleteMessage.cs @@ -0,0 +1,19 @@ +using NzbDrone.Core.MediaFiles; +using NzbDrone.Core.Movies; + +namespace NzbDrone.Core.Notifications +{ + public class MovieFileDeleteMessage + { + public string Message { get; set; } + public Movie Movie { get; set; } + public MovieFile MovieFile { get; set; } + + public DeleteMediaFileReason Reason { get; set; } + + public override string ToString() + { + return Message; + } + } +} diff --git a/src/NzbDrone.Core/Notifications/NotificationBase.cs b/src/NzbDrone.Core/Notifications/NotificationBase.cs index bcc98bf01..505bc5681 100644 --- a/src/NzbDrone.Core/Notifications/NotificationBase.cs +++ b/src/NzbDrone.Core/Notifications/NotificationBase.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using FluentValidation.Results; using NzbDrone.Core.Movies; using NzbDrone.Core.ThingiProvider; @@ -11,10 +12,14 @@ namespace NzbDrone.Core.Notifications { protected const string MOVIE_GRABBED_TITLE = "Movie Grabbed"; protected const string MOVIE_DOWNLOADED_TITLE = "Movie Downloaded"; + protected const string MOVIE_DELETED_TITLE = "Movie Deleted"; + protected const string MOVIE_FILE_DELETED_TITLE = "Movie File Deleted"; protected const string HEALTH_ISSUE_TITLE = "Health Check Failure"; protected const string MOVIE_GRABBED_TITLE_BRANDED = "Radarr - " + MOVIE_GRABBED_TITLE; protected const string MOVIE_DOWNLOADED_TITLE_BRANDED = "Radarr - " + MOVIE_DOWNLOADED_TITLE; + protected const string MOVIE_DELETED_TITLE_BRANDED = "Radarr - " + MOVIE_DELETED_TITLE; + protected const string MOVIE_FILE_DELETED_TITLE_BRANDED = "Radarr - " + MOVIE_FILE_DELETED_TITLE; protected const string HEALTH_ISSUE_TITLE_BRANDED = "Radarr - " + HEALTH_ISSUE_TITLE; public abstract string Name { get; } @@ -42,11 +47,15 @@ namespace NzbDrone.Core.Notifications { } - public virtual void OnHealthIssue(HealthCheck.HealthCheck healthCheck) + public virtual void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) { } - public virtual void OnDelete(DeleteMessage deleteMessage) + public virtual void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + } + + public virtual void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { } @@ -58,8 +67,10 @@ namespace NzbDrone.Core.Notifications public bool SupportsOnRename => HasConcreteImplementation("OnMovieRename"); public bool SupportsOnDownload => HasConcreteImplementation("OnDownload"); public bool SupportsOnUpgrade => SupportsOnDownload; + public bool SupportsOnMovieDelete => HasConcreteImplementation("OnMovieDelete"); + public bool SupportsOnMovieFileDelete => HasConcreteImplementation("OnMovieFileDelete"); + public bool SupportsOnMovieFileDeleteForUpgrade => SupportsOnMovieFileDelete; public bool SupportsOnHealthIssue => HasConcreteImplementation("OnHealthIssue"); - public bool SupportsOnDelete => HasConcreteImplementation("OnDelete"); protected TSettings Settings => (TSettings)Definition.Settings; diff --git a/src/NzbDrone.Core/Notifications/NotificationDefinition.cs b/src/NzbDrone.Core/Notifications/NotificationDefinition.cs index 77e978e1e..aa078e2f9 100644 --- a/src/NzbDrone.Core/Notifications/NotificationDefinition.cs +++ b/src/NzbDrone.Core/Notifications/NotificationDefinition.cs @@ -8,16 +8,20 @@ namespace NzbDrone.Core.Notifications public bool OnDownload { get; set; } public bool OnUpgrade { get; set; } public bool OnRename { get; set; } + public bool OnMovieDelete { get; set; } + public bool OnMovieFileDelete { get; set; } + public bool OnMovieFileDeleteForUpgrade { get; set; } public bool OnHealthIssue { get; set; } - public bool OnDelete { get; set; } public bool SupportsOnGrab { get; set; } public bool SupportsOnDownload { get; set; } public bool SupportsOnUpgrade { get; set; } public bool SupportsOnRename { get; set; } + public bool SupportsOnMovieDelete { get; set; } + public bool SupportsOnMovieFileDelete { get; set; } + public bool SupportsOnMovieFileDeleteForUpgrade { get; set; } public bool SupportsOnHealthIssue { get; set; } - public bool SupportsOnDelete { get; set; } public bool IncludeHealthWarnings { get; set; } - public override bool Enable => OnGrab || OnDownload || (OnDownload && OnUpgrade) || OnHealthIssue || OnDelete; + public override bool Enable => OnGrab || OnDownload || (OnDownload && OnUpgrade) || OnMovieDelete || OnMovieFileDelete || OnMovieFileDeleteForUpgrade || OnHealthIssue; } } diff --git a/src/NzbDrone.Core/Notifications/NotificationFactory.cs b/src/NzbDrone.Core/Notifications/NotificationFactory.cs index 1fe06c1f3..1226c5be7 100644 --- a/src/NzbDrone.Core/Notifications/NotificationFactory.cs +++ b/src/NzbDrone.Core/Notifications/NotificationFactory.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using NLog; using NzbDrone.Common.Composition; @@ -13,8 +13,9 @@ namespace NzbDrone.Core.Notifications List OnDownloadEnabled(); List OnUpgradeEnabled(); List OnRenameEnabled(); + List OnMovieDeleteEnabled(); + List OnMovieFileDeleteEnabled(); List OnHealthIssueEnabled(); - List OnDeleteEnabled(); } public class NotificationFactory : ProviderFactory, INotificationFactory @@ -44,14 +45,24 @@ namespace NzbDrone.Core.Notifications return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnRename).ToList(); } - public List OnHealthIssueEnabled() + public List OnMovieDeleteEnabled() { - return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnHealthIssue).ToList(); + return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnMovieDelete).ToList(); + } + + public List OnMovieFileDeleteEnabled() + { + return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnMovieFileDelete).ToList(); } - public List OnDeleteEnabled() + public List OnMovieFileDeleteForUpgradeEnabled() { - return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnDelete).ToList(); + return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnMovieFileDeleteForUpgrade).ToList(); + } + + public List OnHealthIssueEnabled() + { + return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnHealthIssue).ToList(); } public override void SetProviderCharacteristics(INotification provider, NotificationDefinition definition) @@ -62,8 +73,10 @@ namespace NzbDrone.Core.Notifications definition.SupportsOnDownload = provider.SupportsOnDownload; definition.SupportsOnUpgrade = provider.SupportsOnUpgrade; definition.SupportsOnRename = provider.SupportsOnRename; + definition.SupportsOnMovieDelete = provider.SupportsOnMovieDelete; + definition.SupportsOnMovieFileDelete = provider.SupportsOnMovieFileDelete; + definition.SupportsOnMovieFileDeleteForUpgrade = provider.SupportsOnMovieFileDeleteForUpgrade; definition.SupportsOnHealthIssue = provider.SupportsOnHealthIssue; - definition.SupportsOnDelete = provider.SupportsOnDelete; } } } diff --git a/src/NzbDrone.Core/Notifications/NotificationService.cs b/src/NzbDrone.Core/Notifications/NotificationService.cs index a6662872a..df7fdd3aa 100644 --- a/src/NzbDrone.Core/Notifications/NotificationService.cs +++ b/src/NzbDrone.Core/Notifications/NotificationService.cs @@ -7,6 +7,7 @@ using NzbDrone.Core.HealthCheck; using NzbDrone.Core.MediaFiles.Events; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Movies; +using NzbDrone.Core.Movies.Events; using NzbDrone.Core.Qualities; using NzbDrone.Core.ThingiProvider; @@ -16,8 +17,10 @@ namespace NzbDrone.Core.Notifications : IHandle, IHandle, IHandle, - IHandle, + IHandle, IHandle, + IHandle, + IHandleAsync, IHandleAsync, IHandleAsync, IHandleAsync @@ -159,48 +162,79 @@ namespace NzbDrone.Core.Notifications } } - public void Handle(HealthCheckFailedEvent message) + public void Handle(MovieFileDeletedEvent message) { - foreach (var notification in _notificationFactory.OnHealthIssueEnabled()) + var deleteMessage = new MovieFileDeleteMessage(); + deleteMessage.Message = GetMessage(message.MovieFile.Movie, message.MovieFile.Quality); + deleteMessage.MovieFile = message.MovieFile; + deleteMessage.Movie = message.MovieFile.Movie; + deleteMessage.Reason = message.Reason; + + foreach (var notification in _notificationFactory.OnMovieFileDeleteEnabled()) { try { - if (ShouldHandleHealthFailure(message.HealthCheck, ((NotificationDefinition)notification.Definition).IncludeHealthWarnings)) + if (message.Reason != MediaFiles.DeleteMediaFileReason.Upgrade || ((NotificationDefinition)notification.Definition).OnMovieFileDeleteForUpgrade) { - notification.OnHealthIssue(message.HealthCheck); + if (ShouldHandleMovie(notification.Definition, message.MovieFile.Movie)) + { + notification.OnMovieFileDelete(deleteMessage); + } } } catch (Exception ex) { - _logger.Warn(ex, "Unable to send OnHealthIssue notification to: " + notification.Definition.Name); + _logger.Warn(ex, "Unable to send OnMovieFileDelete notification to: " + notification.Definition.Name); } } } - public void Handle(MovieFileDeletedEvent message) + public void Handle(MoviesDeletedEvent message) { - var deleteMessage = new DeleteMessage(); - deleteMessage.Message = GetMessage(message.MovieFile.Movie, message.MovieFile.Quality); - deleteMessage.MovieFile = message.MovieFile; - deleteMessage.Movie = message.MovieFile.Movie; - deleteMessage.Reason = message.Reason; + foreach (Movie movie in message.Movies) + { + var deleteMessage = new MovieDeleteMessage(movie, message.DeleteFiles); - foreach (var notification in _notificationFactory.OnDeleteEnabled()) + foreach (var notification in _notificationFactory.OnMovieDeleteEnabled()) + { + try + { + if (ShouldHandleMovie(notification.Definition, deleteMessage.Movie)) + { + notification.OnMovieDelete(deleteMessage); + } + } + catch (Exception ex) + { + _logger.Warn(ex, "Unable to send OnMovieDelete notification to: " + notification.Definition.Name); + } + } + } + } + + public void Handle(HealthCheckFailedEvent message) + { + foreach (var notification in _notificationFactory.OnHealthIssueEnabled()) { try { - if (ShouldHandleMovie(notification.Definition, message.MovieFile.Movie)) + if (ShouldHandleHealthFailure(message.HealthCheck, ((NotificationDefinition)notification.Definition).IncludeHealthWarnings)) { - notification.OnDelete(deleteMessage); + notification.OnHealthIssue(message.HealthCheck); } } catch (Exception ex) { - _logger.Warn(ex, "Unable to send OnDelete notification to: " + notification.Definition.Name); + _logger.Warn(ex, "Unable to send OnHealthIssue notification to: " + notification.Definition.Name); } } } + public void HandleAsync(DeleteCompletedEvent message) + { + ProcessQueue(); + } + public void HandleAsync(DownloadsProcessedEvent message) { ProcessQueue(); diff --git a/src/NzbDrone.Core/Notifications/Plex/Server/PlexServer.cs b/src/NzbDrone.Core/Notifications/Plex/Server/PlexServer.cs index a3b3ceafc..7ccbff05d 100644 --- a/src/NzbDrone.Core/Notifications/Plex/Server/PlexServer.cs +++ b/src/NzbDrone.Core/Notifications/Plex/Server/PlexServer.cs @@ -48,6 +48,19 @@ namespace NzbDrone.Core.Notifications.Plex.Server UpdateIfEnabled(movie); } + public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) + { + UpdateIfEnabled(deleteMessage.Movie); + } + + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + if (deleteMessage.DeletedFiles) + { + UpdateIfEnabled(deleteMessage.Movie); + } + } + private void UpdateIfEnabled(Movie movie) { if (Settings.UpdateLibrary) diff --git a/src/NzbDrone.Core/Notifications/Prowl/Prowl.cs b/src/NzbDrone.Core/Notifications/Prowl/Prowl.cs index 279db9770..43a6b2ae6 100644 --- a/src/NzbDrone.Core/Notifications/Prowl/Prowl.cs +++ b/src/NzbDrone.Core/Notifications/Prowl/Prowl.cs @@ -26,9 +26,19 @@ namespace NzbDrone.Core.Notifications.Prowl _prowlProxy.SendNotification(MOVIE_DOWNLOADED_TITLE, message.Message, Settings.ApiKey, (ProwlPriority)Settings.Priority); } - public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) + public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) { - _prowlProxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings.ApiKey, (ProwlPriority)Settings.Priority); + _prowlProxy.SendNotification(MOVIE_FILE_DELETED_TITLE, deleteMessage.Message, Settings.ApiKey, (ProwlPriority)Settings.Priority); + } + + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + _prowlProxy.SendNotification(MOVIE_DELETED_TITLE, deleteMessage.Message, Settings.ApiKey, (ProwlPriority)Settings.Priority); + } + + public override void OnHealthIssue(HealthCheck.HealthCheck message) + { + _prowlProxy.SendNotification(HEALTH_ISSUE_TITLE, message.Message, Settings.ApiKey, (ProwlPriority)Settings.Priority); } public override ValidationResult Test() diff --git a/src/NzbDrone.Core/Notifications/PushBullet/PushBullet.cs b/src/NzbDrone.Core/Notifications/PushBullet/PushBullet.cs index 024244a0d..0b1c07b19 100644 --- a/src/NzbDrone.Core/Notifications/PushBullet/PushBullet.cs +++ b/src/NzbDrone.Core/Notifications/PushBullet/PushBullet.cs @@ -29,6 +29,16 @@ namespace NzbDrone.Core.Notifications.PushBullet _proxy.SendNotification(MOVIE_DOWNLOADED_TITLE_BRANDED, message.Message, Settings); } + public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) + { + _proxy.SendNotification(MOVIE_FILE_DELETED_TITLE, deleteMessage.Message, Settings); + } + + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + _proxy.SendNotification(MOVIE_DELETED_TITLE, deleteMessage.Message, Settings); + } + public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { _proxy.SendNotification(HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message, Settings); diff --git a/src/NzbDrone.Core/Notifications/Pushover/Pushover.cs b/src/NzbDrone.Core/Notifications/Pushover/Pushover.cs index e87e1321e..11c698817 100644 --- a/src/NzbDrone.Core/Notifications/Pushover/Pushover.cs +++ b/src/NzbDrone.Core/Notifications/Pushover/Pushover.cs @@ -26,6 +26,16 @@ namespace NzbDrone.Core.Notifications.Pushover _proxy.SendNotification(MOVIE_DOWNLOADED_TITLE, message.Message, Settings); } + public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) + { + _proxy.SendNotification(MOVIE_FILE_DELETED_TITLE, deleteMessage.Message, Settings); + } + + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + _proxy.SendNotification(MOVIE_DELETED_TITLE, deleteMessage.Message, Settings); + } + public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { _proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings); diff --git a/src/NzbDrone.Core/Notifications/SendGrid/SendGrid.cs b/src/NzbDrone.Core/Notifications/SendGrid/SendGrid.cs index 02ba76af8..f7d898f5a 100644 --- a/src/NzbDrone.Core/Notifications/SendGrid/SendGrid.cs +++ b/src/NzbDrone.Core/Notifications/SendGrid/SendGrid.cs @@ -29,6 +29,16 @@ namespace NzbDrone.Core.Notifications.SendGrid _proxy.SendNotification(MOVIE_DOWNLOADED_TITLE, message.Message, Settings); } + public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) + { + _proxy.SendNotification(MOVIE_FILE_DELETED_TITLE, deleteMessage.Message, Settings); + } + + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + _proxy.SendNotification(MOVIE_DELETED_TITLE, deleteMessage.Message, Settings); + } + public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { _proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings); diff --git a/src/NzbDrone.Core/Notifications/Slack/Slack.cs b/src/NzbDrone.Core/Notifications/Slack/Slack.cs index b570d6aef..3bc2e7163 100644 --- a/src/NzbDrone.Core/Notifications/Slack/Slack.cs +++ b/src/NzbDrone.Core/Notifications/Slack/Slack.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using System.IO; +using System.Linq; using FluentValidation.Results; using NzbDrone.Common.Extensions; using NzbDrone.Core.Movies; @@ -69,6 +71,38 @@ namespace NzbDrone.Core.Notifications.Slack _proxy.SendPayload(payload, Settings); } + public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) + { + var attachments = new List + { + new Attachment + { + Title = deleteMessage.Movie.Title, + Text = Path.Combine(deleteMessage.Movie.Path, deleteMessage.MovieFile.RelativePath) + } + }; + + var payload = CreatePayload("Movie File Deleted", attachments); + + _proxy.SendPayload(payload, Settings); + } + + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + var attachments = new List + { + new Attachment + { + Title = deleteMessage.Movie.Title, + Text = deleteMessage.DeletedFilesMessage + } + }; + + var payload = CreatePayload("Movie Deleted", attachments); + + _proxy.SendPayload(payload, Settings); + } + public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { var attachments = new List diff --git a/src/NzbDrone.Core/Notifications/Synology/SynologyIndexer.cs b/src/NzbDrone.Core/Notifications/Synology/SynologyIndexer.cs index 828b5044e..c8fb4c121 100644 --- a/src/NzbDrone.Core/Notifications/Synology/SynologyIndexer.cs +++ b/src/NzbDrone.Core/Notifications/Synology/SynologyIndexer.cs @@ -46,6 +46,26 @@ namespace NzbDrone.Core.Notifications.Synology } } + public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) + { + if (Settings.UpdateLibrary) + { + var fullPath = Path.Combine(deleteMessage.Movie.Path, deleteMessage.MovieFile.RelativePath); + _indexerProxy.DeleteFile(fullPath); + } + } + + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + if (deleteMessage.DeletedFiles) + { + if (Settings.UpdateLibrary) + { + _indexerProxy.DeleteFolder(deleteMessage.Movie.Path); + } + } + } + public override ValidationResult Test() { var failures = new List(); diff --git a/src/NzbDrone.Core/Notifications/Telegram/Telegram.cs b/src/NzbDrone.Core/Notifications/Telegram/Telegram.cs index 95d640207..c91c8077f 100644 --- a/src/NzbDrone.Core/Notifications/Telegram/Telegram.cs +++ b/src/NzbDrone.Core/Notifications/Telegram/Telegram.cs @@ -26,6 +26,16 @@ namespace NzbDrone.Core.Notifications.Telegram _proxy.SendNotification(MOVIE_DOWNLOADED_TITLE, message.Message, Settings); } + public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) + { + _proxy.SendNotification(MOVIE_FILE_DELETED_TITLE, deleteMessage.Message, Settings); + } + + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + _proxy.SendNotification(MOVIE_DELETED_TITLE, deleteMessage.Message, Settings); + } + public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { _proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings); diff --git a/src/NzbDrone.Core/Notifications/Trakt/Trakt.cs b/src/NzbDrone.Core/Notifications/Trakt/Trakt.cs index 36ca30a31..f68d6cec2 100644 --- a/src/NzbDrone.Core/Notifications/Trakt/Trakt.cs +++ b/src/NzbDrone.Core/Notifications/Trakt/Trakt.cs @@ -29,11 +29,16 @@ namespace NzbDrone.Core.Notifications.Trakt _traktService.AddMovieToCollection(Settings, message.Movie, message.MovieFile); } - public override void OnDelete(DeleteMessage message) + public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) { - if (message.Reason != MediaFiles.DeleteMediaFileReason.Upgrade) + _traktService.RemoveMovieFromCollection(Settings, deleteMessage.Movie); + } + + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + if (deleteMessage.DeletedFiles) { - _traktService.RemoveMovieFromCollection(Settings, message.Movie, message.MovieFile); + _traktService.RemoveMovieFromCollection(Settings, deleteMessage.Movie); } } diff --git a/src/NzbDrone.Core/Notifications/Trakt/TraktService.cs b/src/NzbDrone.Core/Notifications/Trakt/TraktService.cs index edd68a584..15a8f8765 100644 --- a/src/NzbDrone.Core/Notifications/Trakt/TraktService.cs +++ b/src/NzbDrone.Core/Notifications/Trakt/TraktService.cs @@ -19,7 +19,7 @@ namespace NzbDrone.Core.Notifications.Trakt HttpRequest GetOAuthRequest(string callbackUrl); TraktAuthRefreshResource RefreshAuthToken(string refreshToken); void AddMovieToCollection(TraktSettings settings, Movie movie, MovieFile movieFile); - void RemoveMovieFromCollection(TraktSettings settings, Movie movie, MovieFile movieFile); + void RemoveMovieFromCollection(TraktSettings settings, Movie movie); string GetUserName(string accessToken); ValidationFailure Test(TraktSettings settings); } @@ -76,7 +76,7 @@ namespace NzbDrone.Core.Notifications.Trakt } } - public void RemoveMovieFromCollection(TraktSettings settings, Movie movie, MovieFile movieFile) + public void RemoveMovieFromCollection(TraktSettings settings, Movie movie) { var payload = new TraktCollectMoviesResource { diff --git a/src/NzbDrone.Core/Notifications/Twitter/Twitter.cs b/src/NzbDrone.Core/Notifications/Twitter/Twitter.cs index 38fd9ebb7..c9d329b8a 100644 --- a/src/NzbDrone.Core/Notifications/Twitter/Twitter.cs +++ b/src/NzbDrone.Core/Notifications/Twitter/Twitter.cs @@ -28,6 +28,16 @@ namespace NzbDrone.Core.Notifications.Twitter _twitterService.SendNotification($"[Radarr] Imported: {message.Message}", Settings); } + public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) + { + _twitterService.SendNotification($"Movie File Deleted: {deleteMessage.Message}", Settings); + } + + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + _twitterService.SendNotification($"Movie Deleted: {deleteMessage.Message}", Settings); + } + public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { _twitterService.SendNotification($"Health Issue: {healthCheck.Message}", Settings); diff --git a/src/NzbDrone.Core/Notifications/Webhook/Webhook.cs b/src/NzbDrone.Core/Notifications/Webhook/Webhook.cs index adc6cf925..b22e588cf 100755 --- a/src/NzbDrone.Core/Notifications/Webhook/Webhook.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/Webhook.cs @@ -75,6 +75,31 @@ namespace NzbDrone.Core.Notifications.Webhook _proxy.SendWebhook(payload, Settings); } + public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) + { + var payload = new WebhookMovieFileDeletePayload + { + EventType = WebhookEventType.MovieFileDelete, + Movie = new WebhookMovie(deleteMessage.Movie), + MovieFile = new WebhookMovieFile(deleteMessage.MovieFile), + DeleteReason = deleteMessage.Reason + }; + + _proxy.SendWebhook(payload, Settings); + } + + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + var payload = new WebhookMovieDeletePayload + { + EventType = WebhookEventType.MovieDelete, + Movie = new WebhookMovie(deleteMessage.Movie), + DeletedFiles = deleteMessage.DeletedFiles + }; + + _proxy.SendWebhook(payload, Settings); + } + public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { var payload = new WebhookHealthPayload diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookEventType.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookEventType.cs index 8c7036d92..091f59a0f 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookEventType.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookEventType.cs @@ -12,6 +12,8 @@ namespace NzbDrone.Core.Notifications.Webhook Grab, Download, Rename, + MovieDelete, + MovieFileDelete, Health } } diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieDeletePayload.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieDeletePayload.cs new file mode 100644 index 000000000..8540110f5 --- /dev/null +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieDeletePayload.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace NzbDrone.Core.Notifications.Webhook +{ + public class WebhookMovieDeletePayload : WebhookPayload + { + public WebhookMovie Movie { get; set; } + public bool DeletedFiles { get; set; } + } +} diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieFileDeletePayload.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieFileDeletePayload.cs new file mode 100644 index 000000000..851fa285c --- /dev/null +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieFileDeletePayload.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using NzbDrone.Core.MediaFiles; + +namespace NzbDrone.Core.Notifications.Webhook +{ + public class WebhookMovieFileDeletePayload : WebhookPayload + { + public WebhookMovie Movie { get; set; } + public WebhookMovieFile MovieFile { get; set; } + public DeleteMediaFileReason DeleteReason { get; set; } + } +} diff --git a/src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs b/src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs index 9f42d57c6..5421a3ada 100644 --- a/src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs +++ b/src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs @@ -41,6 +41,25 @@ namespace NzbDrone.Core.Notifications.Xbmc UpdateAndCleanMovie(movie); } + public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) + { + const string header = "Radarr - Deleted"; + + Notify(Settings, header, deleteMessage.Message); + UpdateAndCleanMovie(deleteMessage.Movie, true); + } + + public override void OnMovieDelete(MovieDeleteMessage deleteMessage) + { + if (deleteMessage.DeletedFiles) + { + const string header = "Radarr - Deleted"; + + Notify(Settings, header, deleteMessage.Message); + UpdateAndCleanMovie(deleteMessage.Movie, true); + } + } + public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { Notify(Settings, HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message); diff --git a/src/Radarr.Api.V3/Notifications/NotificationResource.cs b/src/Radarr.Api.V3/Notifications/NotificationResource.cs index ce2851297..d69988ae7 100644 --- a/src/Radarr.Api.V3/Notifications/NotificationResource.cs +++ b/src/Radarr.Api.V3/Notifications/NotificationResource.cs @@ -9,13 +9,17 @@ namespace Radarr.Api.V3.Notifications public bool OnDownload { get; set; } public bool OnUpgrade { get; set; } public bool OnRename { get; set; } - public bool OnDelete { get; set; } + public bool OnMovieDelete { get; set; } + public bool OnMovieFileDelete { get; set; } + public bool OnMovieFileDeleteForUpgrade { get; set; } public bool OnHealthIssue { get; set; } public bool SupportsOnGrab { get; set; } public bool SupportsOnDownload { get; set; } public bool SupportsOnUpgrade { get; set; } public bool SupportsOnRename { get; set; } - public bool SupportsOnDelete { get; set; } + public bool SupportsOnMovieDelete { get; set; } + public bool SupportsOnMovieFileDelete { get; set; } + public bool SupportsOnMovieFileDeleteForUpgrade { get; set; } public bool SupportsOnHealthIssue { get; set; } public bool IncludeHealthWarnings { get; set; } public string TestCommand { get; set; } @@ -36,13 +40,17 @@ namespace Radarr.Api.V3.Notifications resource.OnDownload = definition.OnDownload; resource.OnUpgrade = definition.OnUpgrade; resource.OnRename = definition.OnRename; - resource.OnDelete = definition.OnDelete; + resource.OnMovieDelete = definition.OnMovieDelete; + resource.OnMovieFileDelete = definition.OnMovieFileDelete; + resource.OnMovieFileDeleteForUpgrade = definition.OnMovieFileDeleteForUpgrade; resource.OnHealthIssue = definition.OnHealthIssue; resource.SupportsOnGrab = definition.SupportsOnGrab; resource.SupportsOnDownload = definition.SupportsOnDownload; resource.SupportsOnUpgrade = definition.SupportsOnUpgrade; resource.SupportsOnRename = definition.SupportsOnRename; - resource.SupportsOnDelete = definition.SupportsOnDelete; + resource.SupportsOnMovieDelete = definition.SupportsOnMovieDelete; + resource.SupportsOnMovieFileDelete = definition.SupportsOnMovieFileDelete; + resource.SupportsOnMovieFileDeleteForUpgrade = definition.SupportsOnMovieFileDeleteForUpgrade; resource.SupportsOnHealthIssue = definition.SupportsOnHealthIssue; resource.IncludeHealthWarnings = definition.IncludeHealthWarnings; @@ -62,13 +70,17 @@ namespace Radarr.Api.V3.Notifications definition.OnDownload = resource.OnDownload; definition.OnUpgrade = resource.OnUpgrade; definition.OnRename = resource.OnRename; - definition.OnDelete = resource.OnDelete; + definition.OnMovieDelete = resource.OnMovieDelete; + definition.OnMovieFileDelete = resource.OnMovieFileDelete; + definition.OnMovieFileDeleteForUpgrade = resource.OnMovieFileDeleteForUpgrade; definition.OnHealthIssue = resource.OnHealthIssue; definition.SupportsOnGrab = resource.SupportsOnGrab; definition.SupportsOnDownload = resource.SupportsOnDownload; definition.SupportsOnUpgrade = resource.SupportsOnUpgrade; definition.SupportsOnRename = resource.SupportsOnRename; - definition.SupportsOnDelete = resource.SupportsOnDelete; + definition.SupportsOnMovieDelete = resource.SupportsOnMovieDelete; + definition.SupportsOnMovieFileDelete = resource.SupportsOnMovieFileDelete; + definition.SupportsOnMovieFileDeleteForUpgrade = resource.SupportsOnMovieFileDeleteForUpgrade; definition.SupportsOnHealthIssue = resource.SupportsOnHealthIssue; definition.IncludeHealthWarnings = resource.IncludeHealthWarnings;