diff --git a/src/NzbDrone.Core.Test/NotificationTests/NotificationBaseFixture.cs b/src/NzbDrone.Core.Test/NotificationTests/NotificationBaseFixture.cs index 5dc996c2e..d4cb95ee6 100644 --- a/src/NzbDrone.Core.Test/NotificationTests/NotificationBaseFixture.cs +++ b/src/NzbDrone.Core.Test/NotificationTests/NotificationBaseFixture.cs @@ -1,8 +1,10 @@ using System; +using System.Collections.Generic; using FluentAssertions; using FluentValidation.Results; using NUnit.Framework; using NzbDrone.Core.Books; +using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Notifications; using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; @@ -57,7 +59,7 @@ namespace NzbDrone.Core.Test.NotificationTests TestLogger.Info("OnDownload was called"); } - public override void OnRename(Author author) + public override void OnRename(Author author, List<RenamedBookFile> renamedFiles) { TestLogger.Info("OnRename was called"); } diff --git a/src/NzbDrone.Core.Test/NotificationTests/SynologyIndexerFixture.cs b/src/NzbDrone.Core.Test/NotificationTests/SynologyIndexerFixture.cs index ce5569a75..d0c4803c1 100644 --- a/src/NzbDrone.Core.Test/NotificationTests/SynologyIndexerFixture.cs +++ b/src/NzbDrone.Core.Test/NotificationTests/SynologyIndexerFixture.cs @@ -65,7 +65,7 @@ namespace NzbDrone.Core.Test.NotificationTests { (Subject.Definition.Settings as SynologyIndexerSettings).UpdateLibrary = false; - Subject.OnRename(_author); + Subject.OnRename(_author, new List<RenamedBookFile>()); Mocker.GetMock<ISynologyIndexerProxy>() .Verify(v => v.UpdateFolder(_author.Path), Times.Never()); @@ -95,7 +95,7 @@ namespace NzbDrone.Core.Test.NotificationTests [Test] public void should_update_entire_series_folder_on_rename() { - Subject.OnRename(_author); + Subject.OnRename(_author, new List<RenamedBookFile>()); Mocker.GetMock<ISynologyIndexerProxy>() .Verify(v => v.UpdateFolder(@"C:\Test\".AsOsAgnostic()), Times.Once()); diff --git a/src/NzbDrone.Core/MediaFiles/Events/AuthorRenamedEvent.cs b/src/NzbDrone.Core/MediaFiles/Events/AuthorRenamedEvent.cs index 5d95e1982..3dae8fc97 100644 --- a/src/NzbDrone.Core/MediaFiles/Events/AuthorRenamedEvent.cs +++ b/src/NzbDrone.Core/MediaFiles/Events/AuthorRenamedEvent.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using NzbDrone.Common.Messaging; using NzbDrone.Core.Books; @@ -6,10 +7,12 @@ namespace NzbDrone.Core.MediaFiles.Events public class AuthorRenamedEvent : IEvent { public Author Author { get; private set; } + public List<RenamedBookFile> RenamedFiles { get; private set; } - public AuthorRenamedEvent(Author author) + public AuthorRenamedEvent(Author author, List<RenamedBookFile> renamedFiles) { Author = author; + RenamedFiles = renamedFiles; } } } diff --git a/src/NzbDrone.Core/MediaFiles/RenameBookFileService.cs b/src/NzbDrone.Core/MediaFiles/RenameBookFileService.cs index 94df44e46..79c4dc0e7 100644 --- a/src/NzbDrone.Core/MediaFiles/RenameBookFileService.cs +++ b/src/NzbDrone.Core/MediaFiles/RenameBookFileService.cs @@ -115,12 +115,12 @@ namespace NzbDrone.Core.MediaFiles { var allFiles = _mediaFileService.GetFilesByAuthor(author.Id); var counts = allFiles.GroupBy(x => x.EditionId).ToDictionary(g => g.Key, g => g.Count()); - var renamed = new List<BookFile>(); + var renamed = new List<RenamedBookFile>(); // Don't rename Calibre files foreach (var bookFile in bookFiles.Where(x => x.CalibreId == 0)) { - var bookFilePath = bookFile.Path; + var previousPath = bookFile.Path; bookFile.PartCount = counts[bookFile.EditionId]; try @@ -129,11 +129,16 @@ namespace NzbDrone.Core.MediaFiles _bookFileMover.MoveBookFile(bookFile, author); _mediaFileService.Update(bookFile); - renamed.Add(bookFile); + + renamed.Add(new RenamedBookFile + { + BookFile = bookFile, + PreviousPath = previousPath + }); _logger.Debug("Renamed book file: {0}", bookFile); - _eventAggregator.PublishEvent(new BookFileRenamedEvent(author, bookFile, bookFilePath)); + _eventAggregator.PublishEvent(new BookFileRenamedEvent(author, bookFile, previousPath)); } catch (FileAlreadyExistsException ex) { @@ -145,13 +150,13 @@ namespace NzbDrone.Core.MediaFiles } catch (Exception ex) { - _logger.Error(ex, "Failed to rename file {0}", bookFilePath); + _logger.Error(ex, "Failed to rename file {0}", previousPath); } } if (renamed.Any()) { - _eventAggregator.PublishEvent(new AuthorRenamedEvent(author)); + _eventAggregator.PublishEvent(new AuthorRenamedEvent(author, renamed)); _logger.Debug("Removing Empty Subfolders from: {0}", author.Path); _diskProvider.RemoveEmptySubfolders(author.Path); diff --git a/src/NzbDrone.Core/MediaFiles/RenamedBookFile.cs b/src/NzbDrone.Core/MediaFiles/RenamedBookFile.cs new file mode 100644 index 000000000..1392bd749 --- /dev/null +++ b/src/NzbDrone.Core/MediaFiles/RenamedBookFile.cs @@ -0,0 +1,8 @@ +namespace NzbDrone.Core.MediaFiles +{ + public class RenamedBookFile + { + public BookFile BookFile { get; set; } + public string PreviousPath { get; set; } + } +} diff --git a/src/NzbDrone.Core/Notifications/BookDownloadMessage.cs b/src/NzbDrone.Core/Notifications/BookDownloadMessage.cs index a3c036bf2..3f1d4403e 100644 --- a/src/NzbDrone.Core/Notifications/BookDownloadMessage.cs +++ b/src/NzbDrone.Core/Notifications/BookDownloadMessage.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using NzbDrone.Core.Books; +using NzbDrone.Core.Download; using NzbDrone.Core.MediaFiles; namespace NzbDrone.Core.Notifications @@ -11,7 +12,7 @@ namespace NzbDrone.Core.Notifications public Book Book { get; set; } public List<BookFile> BookFiles { get; set; } public List<BookFile> OldFiles { get; set; } - public string DownloadClient { get; set; } + public DownloadClientItemClientInfo DownloadClientInfo { get; set; } public string DownloadId { get; set; } public override string ToString() diff --git a/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs b/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs index 89b52a223..9126936db 100644 --- a/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs +++ b/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs @@ -10,6 +10,7 @@ using NzbDrone.Common.Processes; using NzbDrone.Common.Serializer; using NzbDrone.Core.Books; using NzbDrone.Core.HealthCheck; +using NzbDrone.Core.MediaFiles; using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; @@ -37,7 +38,7 @@ namespace NzbDrone.Core.Notifications.CustomScript public override void OnGrab(GrabMessage message) { var author = message.Author; - var remoteBook = message.Book; + var remoteBook = message.RemoteBook; var releaseGroup = remoteBook.ParsedBookInfo.ReleaseGroup; var environmentVariables = new StringDictionary(); @@ -56,7 +57,8 @@ namespace NzbDrone.Core.Notifications.CustomScript environmentVariables.Add("Readarr_Release_Quality", remoteBook.ParsedBookInfo.Quality.Quality.Name); environmentVariables.Add("Readarr_Release_QualityVersion", remoteBook.ParsedBookInfo.Quality.Revision.Version.ToString()); environmentVariables.Add("Readarr_Release_ReleaseGroup", releaseGroup ?? string.Empty); - environmentVariables.Add("Readarr_Download_Client", message.DownloadClient ?? string.Empty); + environmentVariables.Add("Readarr_Download_Client", message.DownloadClientName ?? string.Empty); + environmentVariables.Add("Readarr_Download_Client_Type", message.DownloadClientType ?? string.Empty); environmentVariables.Add("Readarr_Download_Id", message.DownloadId ?? string.Empty); ExecuteScript(environmentVariables); @@ -77,7 +79,8 @@ namespace NzbDrone.Core.Notifications.CustomScript environmentVariables.Add("Readarr_Book_Title", book.Title); environmentVariables.Add("Readarr_Book_GRId", book.Editions.Value.Single(e => e.Monitored).ForeignEditionId.ToString()); environmentVariables.Add("Readarr_Book_ReleaseDate", book.ReleaseDate.ToString()); - environmentVariables.Add("Readarr_Download_Client", message.DownloadClient ?? string.Empty); + environmentVariables.Add("Readarr_Download_Client", message.DownloadClientInfo?.Name ?? string.Empty); + environmentVariables.Add("Readarr_Download_Client_Type", message.DownloadClientInfo?.Type ?? string.Empty); environmentVariables.Add("Readarr_Download_Id", message.DownloadId ?? string.Empty); if (message.BookFiles.Any()) @@ -94,7 +97,7 @@ namespace NzbDrone.Core.Notifications.CustomScript ExecuteScript(environmentVariables); } - public override void OnRename(Author author) + public override void OnRename(Author author, List<RenamedBookFile> renamedFiles) { var environmentVariables = new StringDictionary(); diff --git a/src/NzbDrone.Core/Notifications/Discord/Discord.cs b/src/NzbDrone.Core/Notifications/Discord/Discord.cs index 31cbd69a6..55b29f97e 100644 --- a/src/NzbDrone.Core/Notifications/Discord/Discord.cs +++ b/src/NzbDrone.Core/Notifications/Discord/Discord.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using FluentValidation.Results; using NzbDrone.Common.Extensions; using NzbDrone.Core.Books; +using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Notifications.Discord.Payloads; using NzbDrone.Core.Validation; @@ -54,7 +55,7 @@ namespace NzbDrone.Core.Notifications.Discord _proxy.SendPayload(payload, Settings); } - public override void OnRename(Author author) + public override void OnRename(Author author, List<RenamedBookFile> renamedFiles) { var attachments = new List<Embed> { diff --git a/src/NzbDrone.Core/Notifications/GrabMessage.cs b/src/NzbDrone.Core/Notifications/GrabMessage.cs index 16f738b90..fce697c70 100644 --- a/src/NzbDrone.Core/Notifications/GrabMessage.cs +++ b/src/NzbDrone.Core/Notifications/GrabMessage.cs @@ -8,9 +8,10 @@ namespace NzbDrone.Core.Notifications { public string Message { get; set; } public Author Author { get; set; } - public RemoteBook Book { get; set; } + public RemoteBook RemoteBook { get; set; } public QualityModel Quality { get; set; } - public string DownloadClient { get; set; } + public string DownloadClientType { get; set; } + public string DownloadClientName { get; set; } public string DownloadId { get; set; } public override string ToString() diff --git a/src/NzbDrone.Core/Notifications/INotification.cs b/src/NzbDrone.Core/Notifications/INotification.cs index 6cef6ae02..f6505d98d 100644 --- a/src/NzbDrone.Core/Notifications/INotification.cs +++ b/src/NzbDrone.Core/Notifications/INotification.cs @@ -1,4 +1,6 @@ +using System.Collections.Generic; using NzbDrone.Core.Books; +using NzbDrone.Core.MediaFiles; using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Notifications @@ -9,7 +11,7 @@ namespace NzbDrone.Core.Notifications void OnGrab(GrabMessage grabMessage); void OnReleaseImport(BookDownloadMessage message); - void OnRename(Author author); + void OnRename(Author author, List<RenamedBookFile> renamedFiles); void OnAuthorDelete(AuthorDeleteMessage deleteMessage); void OnBookDelete(BookDeleteMessage deleteMessage); void OnBookFileDelete(BookFileDeleteMessage deleteMessage); diff --git a/src/NzbDrone.Core/Notifications/Notifiarr/Notifiarr.cs b/src/NzbDrone.Core/Notifications/Notifiarr/Notifiarr.cs index 9fefdc86b..0816ab7eb 100644 --- a/src/NzbDrone.Core/Notifications/Notifiarr/Notifiarr.cs +++ b/src/NzbDrone.Core/Notifications/Notifiarr/Notifiarr.cs @@ -1,18 +1,18 @@ -using System; using System.Collections.Generic; -using System.Collections.Specialized; -using System.Linq; using FluentValidation.Results; using NzbDrone.Common.Extensions; -using NzbDrone.Core.HealthCheck; +using NzbDrone.Core.Configuration; +using NzbDrone.Core.Notifications.Webhook; +using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Notifiarr { - public class Notifiarr : NotificationBase<NotifiarrSettings> + public class Notifiarr : WebhookBase<NotifiarrSettings> { private readonly INotifiarrProxy _proxy; - public Notifiarr(INotifiarrProxy proxy) + public Notifiarr(INotifiarrProxy proxy, IConfigFileProvider configFileProvider) + : base(configFileProvider) { _proxy = proxy; } @@ -22,162 +22,60 @@ namespace NzbDrone.Core.Notifications.Notifiarr public override void OnGrab(GrabMessage message) { - var author = message.Author; - var remoteBook = message.Book; - var releaseGroup = remoteBook.ParsedBookInfo.ReleaseGroup; - var variables = new StringDictionary(); - - variables.Add("Readarr_EventType", "Grab"); - variables.Add("Readarr_Author_Id", author.Id.ToString()); - variables.Add("Readarr_Author_Name", author.Metadata.Value.Name); - variables.Add("Readarr_Author_GRId", author.Metadata.Value.ForeignAuthorId); - variables.Add("Readarr_Release_BookCount", remoteBook.Books.Count.ToString()); - variables.Add("Readarr_Release_BookReleaseDates", string.Join(",", remoteBook.Books.Select(e => e.ReleaseDate))); - variables.Add("Readarr_Release_BookTitles", string.Join("|", remoteBook.Books.Select(e => e.Title))); - variables.Add("Readarr_Release_BookIds", string.Join("|", remoteBook.Books.Select(e => e.Id.ToString()))); - variables.Add("Readarr_Release_GRIds", remoteBook.Books.Select(x => x.Editions.Value.Single(e => e.Monitored).ForeignEditionId).ConcatToString("|")); - variables.Add("Readarr_Release_Title", remoteBook.Release.Title); - variables.Add("Readarr_Release_Indexer", remoteBook.Release.Indexer ?? string.Empty); - variables.Add("Readarr_Release_Size", remoteBook.Release.Size.ToString()); - variables.Add("Readarr_Release_Quality", remoteBook.ParsedBookInfo.Quality.Quality.Name); - variables.Add("Readarr_Release_QualityVersion", remoteBook.ParsedBookInfo.Quality.Revision.Version.ToString()); - variables.Add("Readarr_Release_ReleaseGroup", releaseGroup ?? string.Empty); - variables.Add("Readarr_Download_Client", message.DownloadClient ?? string.Empty); - variables.Add("Readarr_Download_Id", message.DownloadId ?? string.Empty); - - _proxy.SendNotification(variables, Settings); + _proxy.SendNotification(BuildOnGrabPayload(message), Settings); } public override void OnReleaseImport(BookDownloadMessage message) { - var author = message.Author; - var book = message.Book; - var variables = new StringDictionary(); - - variables.Add("Readarr_EventType", "Download"); - variables.Add("Readarr_Author_Id", author.Id.ToString()); - variables.Add("Readarr_Author_Name", author.Metadata.Value.Name); - variables.Add("Readarr_Author_Path", author.Path); - variables.Add("Readarr_Author_GRId", author.Metadata.Value.ForeignAuthorId); - variables.Add("Readarr_Book_Id", book.Id.ToString()); - variables.Add("Readarr_Book_Title", book.Title); - variables.Add("Readarr_Book_GRId", book.Editions.Value.Single(e => e.Monitored).ForeignEditionId.ToString()); - variables.Add("Readarr_Book_ReleaseDate", book.ReleaseDate.ToString()); - variables.Add("Readarr_Download_Client", message.DownloadClient ?? string.Empty); - variables.Add("Readarr_Download_Id", message.DownloadId ?? string.Empty); - - if (message.BookFiles.Any()) - { - variables.Add("Readarr_AddedBookPaths", string.Join("|", message.BookFiles.Select(e => e.Path))); - } - - if (message.OldFiles.Any()) - { - variables.Add("Readarr_DeletedPaths", string.Join("|", message.OldFiles.Select(e => e.Path))); - } - - _proxy.SendNotification(variables, Settings); + _proxy.SendNotification(BuildOnReleaseImportPayload(message), Settings); } public override void OnAuthorDelete(AuthorDeleteMessage deleteMessage) { - var author = deleteMessage.Author; - var variables = new StringDictionary(); - - variables.Add("Readarr_EventType", "AuthorDelete"); - variables.Add("Readarr_Author_Id", author.Id.ToString()); - variables.Add("Readarr_Author_Name", author.Name); - variables.Add("Readarr_Author_Path", author.Path); - variables.Add("Readarr_Author_GoodreadsId", author.ForeignAuthorId); - variables.Add("Readarr_Author_DeletedFiles", deleteMessage.DeletedFiles.ToString()); - - _proxy.SendNotification(variables, Settings); + _proxy.SendNotification(BuildOnAuthorDelete(deleteMessage), Settings); } public override void OnBookDelete(BookDeleteMessage deleteMessage) { - var author = deleteMessage.Book.Author.Value; - var book = deleteMessage.Book; - - var variables = new StringDictionary(); - - variables.Add("Readarr_EventType", "BookDelete"); - variables.Add("Readarr_Author_Id", author.Id.ToString()); - variables.Add("Readarr_Author_Name", author.Name); - variables.Add("Readarr_Author_Path", author.Path); - variables.Add("Readarr_Author_GoodreadsId", author.ForeignAuthorId); - variables.Add("Readarr_Book_Id", book.Id.ToString()); - variables.Add("Readarr_Book_Title", book.Title); - variables.Add("Readarr_Book_GoodreadsId", book.ForeignBookId); - variables.Add("Readarr_Book_DeletedFiles", deleteMessage.DeletedFiles.ToString()); - - _proxy.SendNotification(variables, Settings); + _proxy.SendNotification(BuildOnBookDelete(deleteMessage), Settings); } public override void OnBookFileDelete(BookFileDeleteMessage deleteMessage) { - var author = deleteMessage.Book.Author.Value; - var book = deleteMessage.Book; - var bookFile = deleteMessage.BookFile; - var edition = bookFile.Edition.Value; - - var variables = new StringDictionary(); - - variables.Add("Readarr_EventType", "BookFileDelete"); - variables.Add("Readarr_Delete_Reason", deleteMessage.Reason.ToString()); - variables.Add("Readarr_Author_Id", author.Id.ToString()); - variables.Add("Readarr_Author_Name", author.Name); - variables.Add("Readarr_Author_GoodreadsId", author.ForeignAuthorId); - variables.Add("Readarr_Book_Id", book.Id.ToString()); - variables.Add("Readarr_Book_Title", book.Title); - variables.Add("Readarr_Book_GoodreadsId", book.ForeignBookId); - variables.Add("Readarr_BookFile_Id", bookFile.Id.ToString()); - variables.Add("Readarr_BookFile_Path", bookFile.Path); - variables.Add("Readarr_BookFile_Quality", bookFile.Quality.Quality.Name); - variables.Add("Readarr_BookFile_QualityVersion", bookFile.Quality.Revision.Version.ToString()); - variables.Add("Readarr_BookFile_ReleaseGroup", bookFile.ReleaseGroup ?? string.Empty); - variables.Add("Readarr_BookFile_SceneName", bookFile.SceneName ?? string.Empty); - variables.Add("Readarr_BookFile_Edition_Id", edition.Id.ToString()); - variables.Add("Readarr_BookFile_Edition_Name", edition.Title); - variables.Add("Readarr_BookFile_Edition_GoodreadsId", edition.ForeignEditionId); - variables.Add("Readarr_BookFile_Edition_Isbn13", edition.Isbn13); - variables.Add("Readarr_BookFile_Edition_Asin", edition.Asin); - - _proxy.SendNotification(variables, Settings); + _proxy.SendNotification(BuildOnBookFileDelete(deleteMessage), Settings); } public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { - var variables = new StringDictionary(); - - variables.Add("Readarr_EventType", "HealthIssue"); - variables.Add("Readarr_Health_Issue_Level", Enum.GetName(typeof(HealthCheckResult), healthCheck.Type)); - variables.Add("Readarr_Health_Issue_Message", healthCheck.Message); - variables.Add("Readarr_Health_Issue_Type", healthCheck.Source.Name); - variables.Add("Readarr_Health_Issue_Wiki", healthCheck.WikiUrl.ToString() ?? string.Empty); - - _proxy.SendNotification(variables, Settings); + _proxy.SendNotification(BuildHealthPayload(healthCheck), Settings); } public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage) { - var variables = new StringDictionary(); - - variables.Add("Readarr_EventType", "ApplicationUpdate"); - variables.Add("Readarr_Update_Message", updateMessage.Message); - variables.Add("Readarr_Update_NewVersion", updateMessage.NewVersion.ToString()); - variables.Add("Readarr_Update_PreviousVersion", updateMessage.PreviousVersion.ToString()); - - _proxy.SendNotification(variables, Settings); + _proxy.SendNotification(BuildApplicationUpdatePayload(updateMessage), Settings); } public override ValidationResult Test() { var failures = new List<ValidationFailure>(); - failures.AddIfNotNull(_proxy.Test(Settings)); + failures.AddIfNotNull(SendWebhookTest()); return new ValidationResult(failures); } + + private ValidationFailure SendWebhookTest() + { + try + { + _proxy.SendNotification(BuildTestPayload(), Settings); + } + catch (NotifiarrException ex) + { + return new NzbDroneValidationFailure("APIKey", ex.Message); + } + + return null; + } } } diff --git a/src/NzbDrone.Core/Notifications/Notifiarr/NotifiarrProxy.cs b/src/NzbDrone.Core/Notifications/Notifiarr/NotifiarrProxy.cs index 6038dc8bf..704ffee7e 100644 --- a/src/NzbDrone.Core/Notifications/Notifiarr/NotifiarrProxy.cs +++ b/src/NzbDrone.Core/Notifications/Notifiarr/NotifiarrProxy.cs @@ -1,98 +1,68 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Net; -using FluentValidation.Results; -using NLog; -using NzbDrone.Common.EnvironmentInfo; +using System.Net.Http; using NzbDrone.Common.Http; +using NzbDrone.Common.Serializer; +using NzbDrone.Core.Notifications.Webhook; namespace NzbDrone.Core.Notifications.Notifiarr { public interface INotifiarrProxy { - void SendNotification(StringDictionary message, NotifiarrSettings settings); - ValidationFailure Test(NotifiarrSettings settings); + void SendNotification(WebhookPayload payload, NotifiarrSettings settings); } public class NotifiarrProxy : INotifiarrProxy { - private const string URL = "https://notifiarr.com/notifier.php"; + private const string URL = "https://notifiarr.com"; private readonly IHttpClient _httpClient; - private readonly Logger _logger; - public NotifiarrProxy(IHttpClient httpClient, Logger logger) + public NotifiarrProxy(IHttpClient httpClient) { _httpClient = httpClient; - _logger = logger; } - public void SendNotification(StringDictionary message, NotifiarrSettings settings) + public void SendNotification(WebhookPayload payload, NotifiarrSettings settings) { - try - { - ProcessNotification(message, settings); - } - catch (NotifiarrException ex) - { - _logger.Error(ex, "Unable to send notification"); - throw new NotifiarrException("Unable to send notification"); - } + ProcessNotification(payload, settings); } - public ValidationFailure Test(NotifiarrSettings settings) + private void ProcessNotification(WebhookPayload payload, NotifiarrSettings settings) { try { - var variables = new StringDictionary(); - variables.Add("Readarr_EventType", "Test"); + var request = new HttpRequestBuilder(URL + "/api/v1/notification/readarr") + .Accept(HttpAccept.Json) + .SetHeader("X-API-Key", settings.APIKey) + .Build(); - SendNotification(variables, settings); - return null; - } - catch (HttpException ex) - { - if (ex.Response.StatusCode == HttpStatusCode.Unauthorized) - { - _logger.Error(ex, "API key is invalid: " + ex.Message); - return new ValidationFailure("APIKey", "API key is invalid"); - } + request.Method = HttpMethod.Post; - _logger.Error(ex, "Unable to send test message: " + ex.Message); - return new ValidationFailure("APIKey", "Unable to send test notification"); - } - catch (Exception ex) - { - _logger.Error(ex, "Unable to send test notification: " + ex.Message); - return new ValidationFailure("", "Unable to send test notification"); - } - } - - private void ProcessNotification(StringDictionary message, NotifiarrSettings settings) - { - try - { - var requestBuilder = new HttpRequestBuilder(URL).Post(); - requestBuilder.AddFormParameter("api", settings.APIKey).Build(); - - foreach (string key in message.Keys) - { - requestBuilder.AddFormParameter(key, message[key]); - } - - var request = requestBuilder.Build(); + request.Headers.ContentType = "application/json"; + request.SetContent(payload.ToJson()); _httpClient.Post(request); } catch (HttpException ex) { - if (ex.Response.StatusCode == HttpStatusCode.BadRequest) + var responseCode = ex.Response.StatusCode; + switch ((int)responseCode) { - _logger.Error(ex, "API key is invalid"); - throw; + case 401: + throw new NotifiarrException("API key is invalid"); + case 400: + throw new NotifiarrException("Unable to send notification. Ensure Readarr Integration is enabled & assigned a channel on Notifiarr"); + case 502: + case 503: + case 504: + throw new NotifiarrException("Unable to send notification. Service Unavailable", ex); + case 520: + case 521: + case 522: + case 523: + case 524: + throw new NotifiarrException("Cloudflare Related HTTP Error - Unable to send notification", ex); + default: + throw new NotifiarrException("Unknown HTTP Error - Unable to send notification", ex); } - - throw new NotifiarrException("Unable to send notification", ex); } } } diff --git a/src/NzbDrone.Core/Notifications/NotificationBase.cs b/src/NzbDrone.Core/Notifications/NotificationBase.cs index cb733bdf2..ce8c57613 100644 --- a/src/NzbDrone.Core/Notifications/NotificationBase.cs +++ b/src/NzbDrone.Core/Notifications/NotificationBase.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using FluentValidation.Results; using NzbDrone.Core.Books; +using NzbDrone.Core.MediaFiles; using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Notifications @@ -52,7 +53,7 @@ namespace NzbDrone.Core.Notifications { } - public virtual void OnRename(Author author) + public virtual void OnRename(Author author, List<RenamedBookFile> renamedFiles) { } diff --git a/src/NzbDrone.Core/Notifications/NotificationService.cs b/src/NzbDrone.Core/Notifications/NotificationService.cs index d4a1f6ceb..a16a7e738 100644 --- a/src/NzbDrone.Core/Notifications/NotificationService.cs +++ b/src/NzbDrone.Core/Notifications/NotificationService.cs @@ -124,8 +124,9 @@ namespace NzbDrone.Core.Notifications Message = GetMessage(message.Book.Author, message.Book.Books, message.Book.ParsedBookInfo.Quality), Author = message.Book.Author, Quality = message.Book.ParsedBookInfo.Quality, - Book = message.Book, - DownloadClient = message.DownloadClient, + RemoteBook = message.Book, + DownloadClientName = message.DownloadClientName, + DownloadClientType = message.DownloadClient, DownloadId = message.DownloadId }; @@ -159,7 +160,7 @@ namespace NzbDrone.Core.Notifications Message = GetBookDownloadMessage(message.Author, message.Book, message.ImportedBooks), Author = message.Author, Book = message.Book, - DownloadClient = message.DownloadClientInfo?.Name, + DownloadClientInfo = message.DownloadClientInfo, DownloadId = message.DownloadId, BookFiles = message.ImportedBooks, OldFiles = message.OldFiles, @@ -192,7 +193,7 @@ namespace NzbDrone.Core.Notifications { if (ShouldHandleAuthor(notification.Definition, message.Author)) { - notification.OnRename(message.Author); + notification.OnRename(message.Author, message.RenamedFiles); } } catch (Exception ex) diff --git a/src/NzbDrone.Core/Notifications/Slack/Slack.cs b/src/NzbDrone.Core/Notifications/Slack/Slack.cs index 126f021aa..0e73d0a4a 100644 --- a/src/NzbDrone.Core/Notifications/Slack/Slack.cs +++ b/src/NzbDrone.Core/Notifications/Slack/Slack.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using FluentValidation.Results; using NzbDrone.Common.Extensions; using NzbDrone.Core.Books; +using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Notifications.Slack.Payloads; using NzbDrone.Core.Validation; @@ -54,7 +55,7 @@ namespace NzbDrone.Core.Notifications.Slack _proxy.SendPayload(payload, Settings); } - public override void OnRename(Author author) + public override void OnRename(Author author, List<RenamedBookFile> renamedFiles) { var attachments = new List<Attachment> { diff --git a/src/NzbDrone.Core/Notifications/Subsonic/Subsonic.cs b/src/NzbDrone.Core/Notifications/Subsonic/Subsonic.cs index fc92ab20b..bebf424de 100644 --- a/src/NzbDrone.Core/Notifications/Subsonic/Subsonic.cs +++ b/src/NzbDrone.Core/Notifications/Subsonic/Subsonic.cs @@ -4,6 +4,7 @@ using FluentValidation.Results; using NLog; using NzbDrone.Common.Extensions; using NzbDrone.Core.Books; +using NzbDrone.Core.MediaFiles; namespace NzbDrone.Core.Notifications.Subsonic { @@ -35,7 +36,7 @@ namespace NzbDrone.Core.Notifications.Subsonic Update(); } - public override void OnRename(Author author) + public override void OnRename(Author author, List<RenamedBookFile> renamedFiles) { Update(); } diff --git a/src/NzbDrone.Core/Notifications/Synology/SynologyIndexer.cs b/src/NzbDrone.Core/Notifications/Synology/SynologyIndexer.cs index bd58073e1..94bd62400 100644 --- a/src/NzbDrone.Core/Notifications/Synology/SynologyIndexer.cs +++ b/src/NzbDrone.Core/Notifications/Synology/SynologyIndexer.cs @@ -3,6 +3,7 @@ using FluentValidation.Results; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.Extensions; using NzbDrone.Core.Books; +using NzbDrone.Core.MediaFiles; namespace NzbDrone.Core.Notifications.Synology { @@ -38,7 +39,7 @@ namespace NzbDrone.Core.Notifications.Synology } } - public override void OnRename(Author author) + public override void OnRename(Author author, List<RenamedBookFile> renamedFiles) { if (Settings.UpdateLibrary) { diff --git a/src/NzbDrone.Core/Notifications/Webhook/Webhook.cs b/src/NzbDrone.Core/Notifications/Webhook/Webhook.cs index aef9671b4..04b5b8e34 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/Webhook.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/Webhook.cs @@ -3,147 +3,67 @@ using System.Linq; using FluentValidation.Results; using NzbDrone.Common.Extensions; using NzbDrone.Core.Books; +using NzbDrone.Core.Configuration; +using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Webhook { - public class Webhook : NotificationBase<WebhookSettings> + public class Webhook : WebhookBase<WebhookSettings> { private readonly IWebhookProxy _proxy; - public Webhook(IWebhookProxy proxy) + public Webhook(IWebhookProxy proxy, IConfigFileProvider configFileProvider) + : base(configFileProvider) { _proxy = proxy; } - public override string Link => "https://wiki.servarr.com/readarr/settings#connect"; + public override string Link => "https://wiki.servarr.com/readarr/settings#connections"; public override void OnGrab(GrabMessage message) { - var remoteBook = message.Book; - var quality = message.Quality; - - var payload = new WebhookGrabPayload - { - EventType = WebhookEventType.Grab, - Author = new WebhookAuthor(message.Author), - Books = remoteBook.Books.ConvertAll(x => new WebhookBook(x) - { - // TODO: Stop passing these parameters inside an book v3 - Quality = quality.Quality.Name, - QualityVersion = quality.Revision.Version, - ReleaseGroup = remoteBook.ParsedBookInfo.ReleaseGroup - }), - Release = new WebhookRelease(quality, remoteBook), - DownloadClient = message.DownloadClient, - DownloadId = message.DownloadId - }; - - _proxy.SendWebhook(payload, Settings); + _proxy.SendWebhook(BuildOnGrabPayload(message), Settings); } public override void OnReleaseImport(BookDownloadMessage message) { - var bookFiles = message.BookFiles; - - var payload = new WebhookImportPayload - { - EventType = WebhookEventType.Download, - Author = new WebhookAuthor(message.Author), - Book = new WebhookBook(message.Book), - BookFiles = bookFiles.ConvertAll(x => new WebhookBookFile(x)), - IsUpgrade = message.OldFiles.Any(), - DownloadClient = message.DownloadClient, - DownloadId = message.DownloadId - }; - - _proxy.SendWebhook(payload, Settings); + _proxy.SendWebhook(BuildOnReleaseImportPayload(message), Settings); } - public override void OnRename(Author author) + public override void OnRename(Author author, List<RenamedBookFile> renamedFiles) { - var payload = new WebhookRenamePayload - { - EventType = WebhookEventType.Rename, - Author = new WebhookAuthor(author) - }; - - _proxy.SendWebhook(payload, Settings); + _proxy.SendWebhook(BuildOnRenamePayload(author, renamedFiles), Settings); } public override void OnAuthorDelete(AuthorDeleteMessage deleteMessage) { - var payload = new WebhookAuthorDeletePayload - { - EventType = WebhookEventType.Delete, - Author = new WebhookAuthor(deleteMessage.Author), - DeletedFiles = deleteMessage.DeletedFiles - }; - - _proxy.SendWebhook(payload, Settings); + _proxy.SendWebhook(BuildOnAuthorDelete(deleteMessage), Settings); } public override void OnBookDelete(BookDeleteMessage deleteMessage) { - var payload = new WebhookBookDeletePayload - { - EventType = WebhookEventType.Delete, - Author = new WebhookAuthor(deleteMessage.Book.Author), - Book = new WebhookBook(deleteMessage.Book) - }; - - _proxy.SendWebhook(payload, Settings); + _proxy.SendWebhook(BuildOnBookDelete(deleteMessage), Settings); } public override void OnBookFileDelete(BookFileDeleteMessage deleteMessage) { - var payload = new WebhookBookFileDeletePayload - { - EventType = WebhookEventType.Delete, - Author = new WebhookAuthor(deleteMessage.Book.Author), - Book = new WebhookBook(deleteMessage.Book), - BookFile = new WebhookBookFile(deleteMessage.BookFile) - }; - - _proxy.SendWebhook(payload, Settings); + _proxy.SendWebhook(BuildOnBookFileDelete(deleteMessage), Settings); } public override void OnBookRetag(BookRetagMessage message) { - var payload = new WebhookRetagPayload - { - EventType = WebhookEventType.Retag, - Author = new WebhookAuthor(message.Author) - }; - - _proxy.SendWebhook(payload, Settings); + _proxy.SendWebhook(BuildOnBookRetagPayload(message), Settings); } public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { - var payload = new WebhookHealthPayload - { - EventType = WebhookEventType.Health, - Level = healthCheck.Type, - Message = healthCheck.Message, - Type = healthCheck.Source.Name, - WikiUrl = healthCheck.WikiUrl?.ToString() - }; - - _proxy.SendWebhook(payload, Settings); + _proxy.SendWebhook(BuildHealthPayload(healthCheck), Settings); } public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage) { - var payload = new WebhookApplicationUpdatePayload - { - EventType = WebhookEventType.ApplicationUpdate, - Message = updateMessage.Message, - PreviousVersion = updateMessage.PreviousVersion.ToString(), - NewVersion = updateMessage.NewVersion.ToString() - }; - - _proxy.SendWebhook(payload, Settings); + _proxy.SendWebhook(BuildApplicationUpdatePayload(updateMessage), Settings); } public override string Name => "Webhook"; @@ -161,27 +81,7 @@ namespace NzbDrone.Core.Notifications.Webhook { try { - var payload = new WebhookGrabPayload - { - EventType = WebhookEventType.Test, - Author = new WebhookAuthor() - { - Id = 1, - Name = "Test Name", - Path = "C:\\testpath", - MBId = "aaaaa-aaa-aaaa-aaaaaa" - }, - Books = new List<WebhookBook>() - { - new WebhookBook() - { - Id = 123, - Title = "Test title" - } - } - }; - - _proxy.SendWebhook(payload, Settings); + _proxy.SendWebhook(BuildTestPayload(), Settings); } catch (WebhookException ex) { diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookApplicationUpdatePayload.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookApplicationUpdatePayload.cs index e05be69bc..66a6ff382 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookApplicationUpdatePayload.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookApplicationUpdatePayload.cs @@ -1,5 +1,3 @@ -using NzbDrone.Core.HealthCheck; - namespace NzbDrone.Core.Notifications.Webhook { public class WebhookApplicationUpdatePayload : WebhookPayload diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookAuthor.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookAuthor.cs index f099f8943..1f84c8ebf 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookAuthor.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookAuthor.cs @@ -7,7 +7,7 @@ namespace NzbDrone.Core.Notifications.Webhook public int Id { get; set; } public string Name { get; set; } public string Path { get; set; } - public string MBId { get; set; } + public string GoodreadsId { get; set; } public WebhookAuthor() { @@ -18,7 +18,7 @@ namespace NzbDrone.Core.Notifications.Webhook Id = author.Id; Name = author.Name; Path = author.Path; - MBId = author.Metadata.Value.ForeignAuthorId; + GoodreadsId = author.Metadata.Value.ForeignAuthorId; } } } diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs new file mode 100644 index 000000000..369fbe3b0 --- /dev/null +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs @@ -0,0 +1,176 @@ +using System.Collections.Generic; +using System.Linq; +using NzbDrone.Core.Books; +using NzbDrone.Core.Configuration; +using NzbDrone.Core.MediaFiles; +using NzbDrone.Core.ThingiProvider; + +namespace NzbDrone.Core.Notifications.Webhook +{ + public abstract class WebhookBase<TSettings> : NotificationBase<TSettings> + where TSettings : IProviderConfig, new() + { + private readonly IConfigFileProvider _configFileProvider; + + protected WebhookBase(IConfigFileProvider configFileProvider) + : base() + { + _configFileProvider = configFileProvider; + } + + public WebhookGrabPayload BuildOnGrabPayload(GrabMessage message) + { + var remoteBook = message.RemoteBook; + var quality = message.Quality; + + return new WebhookGrabPayload + { + EventType = WebhookEventType.Grab, + InstanceName = _configFileProvider.InstanceName, + Author = new WebhookAuthor(message.Author), + Books = remoteBook.Books.ConvertAll(x => new WebhookBook(x) + { + // TODO: Stop passing these parameters inside an book v3 + Quality = quality.Quality.Name, + QualityVersion = quality.Revision.Version, + ReleaseGroup = remoteBook.ParsedBookInfo.ReleaseGroup + }), + Release = new WebhookRelease(quality, remoteBook), + DownloadClient = message.DownloadClientName, + DownloadClientType = message.DownloadClientType, + DownloadId = message.DownloadId + }; + } + + public WebhookImportPayload BuildOnReleaseImportPayload(BookDownloadMessage message) + { + var trackFiles = message.BookFiles; + + var payload = new WebhookImportPayload + { + EventType = WebhookEventType.Download, + InstanceName = _configFileProvider.InstanceName, + Author = new WebhookAuthor(message.Author), + Book = new WebhookBook(message.Book), + BookFiles = trackFiles.ConvertAll(x => new WebhookBookFile(x)), + IsUpgrade = message.OldFiles.Any(), + DownloadClient = message.DownloadClientInfo?.Name, + DownloadClientType = message.DownloadClientInfo?.Type, + DownloadId = message.DownloadId + }; + + if (message.OldFiles.Any()) + { + payload.DeletedFiles = message.OldFiles.ConvertAll(x => new WebhookBookFile(x)); + } + + return payload; + } + + public WebhookRenamePayload BuildOnRenamePayload(Author author, List<RenamedBookFile> renamedFiles) + { + return new WebhookRenamePayload + { + EventType = WebhookEventType.Rename, + InstanceName = _configFileProvider.InstanceName, + Author = new WebhookAuthor(author), + RenamedBookFiles = renamedFiles.ConvertAll(x => new WebhookRenamedBookFile(x)) + }; + } + + public WebhookRetagPayload BuildOnBookRetagPayload(BookRetagMessage message) + { + return new WebhookRetagPayload + { + EventType = WebhookEventType.Retag, + InstanceName = _configFileProvider.InstanceName, + Author = new WebhookAuthor(message.Author), + BookFile = new WebhookBookFile(message.BookFile) + }; + } + + public WebhookBookDeletePayload BuildOnBookDelete(BookDeleteMessage deleteMessage) + { + return new WebhookBookDeletePayload + { + EventType = WebhookEventType.Delete, + InstanceName = _configFileProvider.InstanceName, + Author = new WebhookAuthor(deleteMessage.Book.Author), + Book = new WebhookBook(deleteMessage.Book), + DeletedFiles = deleteMessage.DeletedFiles + }; + } + + public WebhookBookFileDeletePayload BuildOnBookFileDelete(BookFileDeleteMessage deleteMessage) + { + return new WebhookBookFileDeletePayload + { + EventType = WebhookEventType.Delete, + InstanceName = _configFileProvider.InstanceName, + Author = new WebhookAuthor(deleteMessage.Book.Author), + Book = new WebhookBook(deleteMessage.Book), + BookFile = new WebhookBookFile(deleteMessage.BookFile) + }; + } + + public WebhookAuthorDeletePayload BuildOnAuthorDelete(AuthorDeleteMessage deleteMessage) + { + return new WebhookAuthorDeletePayload + { + EventType = WebhookEventType.Delete, + InstanceName = _configFileProvider.InstanceName, + Author = new WebhookAuthor(deleteMessage.Author), + DeletedFiles = deleteMessage.DeletedFiles + }; + } + + protected WebhookHealthPayload BuildHealthPayload(HealthCheck.HealthCheck healthCheck) + { + return new WebhookHealthPayload + { + EventType = WebhookEventType.Health, + InstanceName = _configFileProvider.InstanceName, + Level = healthCheck.Type, + Message = healthCheck.Message, + Type = healthCheck.Source.Name, + WikiUrl = healthCheck.WikiUrl?.ToString() + }; + } + + protected WebhookApplicationUpdatePayload BuildApplicationUpdatePayload(ApplicationUpdateMessage updateMessage) + { + return new WebhookApplicationUpdatePayload + { + EventType = WebhookEventType.ApplicationUpdate, + InstanceName = _configFileProvider.InstanceName, + Message = updateMessage.Message, + PreviousVersion = updateMessage.PreviousVersion.ToString(), + NewVersion = updateMessage.NewVersion.ToString() + }; + } + + protected WebhookPayload BuildTestPayload() + { + return new WebhookGrabPayload + { + EventType = WebhookEventType.Test, + InstanceName = _configFileProvider.InstanceName, + Author = new WebhookAuthor() + { + Id = 1, + Name = "Test Name", + Path = "C:\\testpath", + GoodreadsId = "aaaaa-aaa-aaaa-aaaaaa" + }, + Books = new List<WebhookBook>() + { + new WebhookBook() + { + Id = 123, + Title = "Test title" + } + } + }; + } + } +} diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookBookDeletePayload.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookBookDeletePayload.cs index 804ddf77b..3f0d6b1ef 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookBookDeletePayload.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookBookDeletePayload.cs @@ -4,5 +4,6 @@ namespace NzbDrone.Core.Notifications.Webhook { public WebhookAuthor Author { get; set; } public WebhookBook Book { get; set; } + public bool DeletedFiles { get; set; } } } diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookGrabPayload.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookGrabPayload.cs index 5990afce7..f6bc7b1df 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookGrabPayload.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookGrabPayload.cs @@ -8,6 +8,7 @@ namespace NzbDrone.Core.Notifications.Webhook public List<WebhookBook> Books { get; set; } public WebhookRelease Release { get; set; } public string DownloadClient { get; set; } + public string DownloadClientType { get; set; } public string DownloadId { get; set; } } } diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookImportPayload.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookImportPayload.cs index aaf779e73..cc8cdeb13 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookImportPayload.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookImportPayload.cs @@ -7,8 +7,10 @@ namespace NzbDrone.Core.Notifications.Webhook public WebhookAuthor Author { get; set; } public WebhookBook Book { get; set; } public List<WebhookBookFile> BookFiles { get; set; } + public List<WebhookBookFile> DeletedFiles { get; set; } public bool IsUpgrade { get; set; } public string DownloadClient { get; set; } + public string DownloadClientType { get; set; } public string DownloadId { get; set; } } } diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookPayload.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookPayload.cs index 4b63a748e..05d51c7c1 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookPayload.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookPayload.cs @@ -3,5 +3,6 @@ namespace NzbDrone.Core.Notifications.Webhook public class WebhookPayload { public WebhookEventType EventType { get; set; } + public string InstanceName { get; set; } } } diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookRenamePayload.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookRenamePayload.cs index bb9a3e56b..d2a7bf7b7 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookRenamePayload.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookRenamePayload.cs @@ -1,7 +1,10 @@ +using System.Collections.Generic; + namespace NzbDrone.Core.Notifications.Webhook { public class WebhookRenamePayload : WebhookPayload { public WebhookAuthor Author { get; set; } + public List<WebhookRenamedBookFile> RenamedBookFiles { get; set; } } } diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookRenamedBookFile.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookRenamedBookFile.cs new file mode 100644 index 000000000..4dbeddec2 --- /dev/null +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookRenamedBookFile.cs @@ -0,0 +1,15 @@ +using NzbDrone.Core.MediaFiles; + +namespace NzbDrone.Core.Notifications.Webhook +{ + public class WebhookRenamedBookFile : WebhookBookFile + { + public WebhookRenamedBookFile(RenamedBookFile renamedMovie) + : base(renamedMovie.BookFile) + { + PreviousPath = renamedMovie.PreviousPath; + } + + public string PreviousPath { get; set; } + } +} diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookRetagPayload.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookRetagPayload.cs index 67e3ec729..877097dc6 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookRetagPayload.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookRetagPayload.cs @@ -3,5 +3,6 @@ namespace NzbDrone.Core.Notifications.Webhook public class WebhookRetagPayload : WebhookPayload { public WebhookAuthor Author { get; set; } + public WebhookBookFile BookFile { get; set; } } }