From 31b44d2c2e6dd5ee48897b0c1ad896cfb6908fde Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 11 May 2025 13:32:16 +0300 Subject: [PATCH] New: Include movie poster for Apprise --- src/NzbDrone.Core/Localization/Core/en.json | 2 ++ .../Notifications/Apprise/Apprise.cs | 25 ++++++++++++------- .../Notifications/Apprise/ApprisePayload.cs | 2 ++ .../Notifications/Apprise/AppriseProxy.cs | 12 ++++++--- .../Notifications/Apprise/AppriseSettings.cs | 7 ++++-- 5 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 3630a9f4e3..8484570c50 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -1221,6 +1221,8 @@ "NotificationTriggersHelpText": "Select which events should trigger this notification", "NotificationsAppriseSettingsConfigurationKey": "Apprise Configuration Key", "NotificationsAppriseSettingsConfigurationKeyHelpText": "Configuration Key for the Persistent Storage Solution. Leave empty if Stateless URLs is used.", + "NotificationsAppriseSettingsIncludePoster": "Include Poster", + "NotificationsAppriseSettingsIncludePosterHelpText": "Include poster in message", "NotificationsAppriseSettingsNotificationType": "Apprise Notification Type", "NotificationsAppriseSettingsPasswordHelpText": "HTTP Basic Auth Password", "NotificationsAppriseSettingsServerUrl": "Apprise Server URL", diff --git a/src/NzbDrone.Core/Notifications/Apprise/Apprise.cs b/src/NzbDrone.Core/Notifications/Apprise/Apprise.cs index ab48e77b65..be2ac0c6ce 100644 --- a/src/NzbDrone.Core/Notifications/Apprise/Apprise.cs +++ b/src/NzbDrone.Core/Notifications/Apprise/Apprise.cs @@ -1,6 +1,8 @@ using System.Collections.Generic; +using System.Linq; using FluentValidation.Results; using NzbDrone.Common.Extensions; +using NzbDrone.Core.MediaCover; using NzbDrone.Core.Movies; namespace NzbDrone.Core.Notifications.Apprise @@ -20,47 +22,47 @@ public Apprise(IAppriseProxy proxy) public override void OnGrab(GrabMessage grabMessage) { - _proxy.SendNotification(MOVIE_GRABBED_TITLE, grabMessage.Message, Settings); + _proxy.SendNotification(MOVIE_GRABBED_TITLE, grabMessage.Message, GetPosterUrl(grabMessage.Movie), Settings); } public override void OnDownload(DownloadMessage message) { - _proxy.SendNotification(MOVIE_DOWNLOADED_TITLE, message.Message, Settings); + _proxy.SendNotification(MOVIE_DOWNLOADED_TITLE, message.Message, GetPosterUrl(message.Movie), Settings); } public override void OnMovieAdded(Movie movie) { - _proxy.SendNotification(MOVIE_ADDED_TITLE, $"{movie.Title} added to library", Settings); + _proxy.SendNotification(MOVIE_ADDED_TITLE, $"{movie.Title} ({movie.Year}) added to library", GetPosterUrl(movie), Settings); } public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) { - _proxy.SendNotification(MOVIE_FILE_DELETED_TITLE, deleteMessage.Message, Settings); + _proxy.SendNotification(MOVIE_FILE_DELETED_TITLE, deleteMessage.Message, GetPosterUrl(deleteMessage.Movie), Settings); } public override void OnMovieDelete(MovieDeleteMessage deleteMessage) { - _proxy.SendNotification(MOVIE_DELETED_TITLE, deleteMessage.Message, Settings); + _proxy.SendNotification(MOVIE_DELETED_TITLE, deleteMessage.Message, GetPosterUrl(deleteMessage.Movie), Settings); } public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { - _proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings); + _proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, null, Settings); } public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck) { - _proxy.SendNotification(HEALTH_RESTORED_TITLE, $"The following issue is now resolved: {previousCheck.Message}", Settings); + _proxy.SendNotification(HEALTH_RESTORED_TITLE, $"The following issue is now resolved: {previousCheck.Message}", null, Settings); } public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage) { - _proxy.SendNotification(APPLICATION_UPDATE_TITLE, updateMessage.Message, Settings); + _proxy.SendNotification(APPLICATION_UPDATE_TITLE, updateMessage.Message, null, Settings); } public override void OnManualInteractionRequired(ManualInteractionRequiredMessage message) { - _proxy.SendNotification(MANUAL_INTERACTION_REQUIRED_TITLE, message.Message, Settings); + _proxy.SendNotification(MANUAL_INTERACTION_REQUIRED_TITLE, message.Message, GetPosterUrl(message.Movie), Settings); } public override ValidationResult Test() @@ -71,5 +73,10 @@ public override ValidationResult Test() return new ValidationResult(failures); } + + private static string GetPosterUrl(Movie movie) + { + return movie?.MovieMetadata?.Value?.Images?.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Poster)?.RemoteUrl; + } } } diff --git a/src/NzbDrone.Core/Notifications/Apprise/ApprisePayload.cs b/src/NzbDrone.Core/Notifications/Apprise/ApprisePayload.cs index 71ab0ea61b..4d044a53ae 100644 --- a/src/NzbDrone.Core/Notifications/Apprise/ApprisePayload.cs +++ b/src/NzbDrone.Core/Notifications/Apprise/ApprisePayload.cs @@ -8,6 +8,8 @@ public class ApprisePayload public string Body { get; set; } + public string Attachment { get; set; } + public AppriseNotificationType Type { get; set; } public string Tag { get; set; } diff --git a/src/NzbDrone.Core/Notifications/Apprise/AppriseProxy.cs b/src/NzbDrone.Core/Notifications/Apprise/AppriseProxy.cs index b30b60058a..ba9c42bd07 100644 --- a/src/NzbDrone.Core/Notifications/Apprise/AppriseProxy.cs +++ b/src/NzbDrone.Core/Notifications/Apprise/AppriseProxy.cs @@ -13,7 +13,7 @@ namespace NzbDrone.Core.Notifications.Apprise { public interface IAppriseProxy { - void SendNotification(string title, string message, AppriseSettings settings); + void SendNotification(string title, string message, string posterUrl, AppriseSettings settings); ValidationFailure Test(AppriseSettings settings); } @@ -30,7 +30,7 @@ public AppriseProxy(IHttpClient httpClient, ILocalizationService localizationSer _logger = logger; } - public void SendNotification(string title, string message, AppriseSettings settings) + public void SendNotification(string title, string message, string posterUrl, AppriseSettings settings) { var payload = new ApprisePayload { @@ -61,6 +61,11 @@ public void SendNotification(string title, string message, AppriseSettings setti payload.Tag = settings.Tags.Join(","); } + if (settings.IncludePoster && posterUrl.IsNotNullOrWhiteSpace()) + { + payload.Attachment = posterUrl; + } + if (settings.AuthUsername.IsNotNullOrWhiteSpace() || settings.AuthPassword.IsNotNullOrWhiteSpace()) { requestBuilder.NetworkCredential = new BasicNetworkCredential(settings.AuthUsername, settings.AuthPassword); @@ -86,10 +91,11 @@ public ValidationFailure Test(AppriseSettings settings) { const string title = "Radarr - Test Notification"; const string body = "Success! You have properly configured your apprise notification settings."; + const string posterUrl = "https://raw.githubusercontent.com/Radarr/Radarr/develop/Logo/128.png"; try { - SendNotification(title, body, settings); + SendNotification(title, body, posterUrl, settings); } catch (AppriseException ex) when (ex.InnerException is HttpException httpException) { diff --git a/src/NzbDrone.Core/Notifications/Apprise/AppriseSettings.cs b/src/NzbDrone.Core/Notifications/Apprise/AppriseSettings.cs index 978305318b..c9a0636118 100644 --- a/src/NzbDrone.Core/Notifications/Apprise/AppriseSettings.cs +++ b/src/NzbDrone.Core/Notifications/Apprise/AppriseSettings.cs @@ -59,10 +59,13 @@ public AppriseSettings() [FieldDefinition(5, Label = "NotificationsAppriseSettingsTags", Type = FieldType.Tag, HelpText = "NotificationsAppriseSettingsTagsHelpText")] public IEnumerable Tags { get; set; } - [FieldDefinition(6, Label = "Username", Type = FieldType.Textbox, HelpText = "NotificationsAppriseSettingsUsernameHelpText", Privacy = PrivacyLevel.UserName)] + [FieldDefinition(6, Label = "NotificationsAppriseSettingsIncludePoster", Type = FieldType.Checkbox, HelpText = "NotificationsAppriseSettingsIncludePosterHelpText")] + public bool IncludePoster { get; set; } + + [FieldDefinition(7, Label = "Username", Type = FieldType.Textbox, HelpText = "NotificationsAppriseSettingsUsernameHelpText", Privacy = PrivacyLevel.UserName)] public string AuthUsername { get; set; } - [FieldDefinition(7, Label = "Password", Type = FieldType.Password, HelpText = "NotificationsAppriseSettingsPasswordHelpText", Privacy = PrivacyLevel.Password)] + [FieldDefinition(8, Label = "Password", Type = FieldType.Password, HelpText = "NotificationsAppriseSettingsPasswordHelpText", Privacy = PrivacyLevel.Password)] public string AuthPassword { get; set; } public override NzbDroneValidationResult Validate()