mirror of
https://github.com/Radarr/Radarr
synced 2025-10-06 02:13:00 +02:00
New:(Pushcut) Improved Notification Details (#10897)
This commit is contained in:
committed by
Robin Dadswell
parent
42512cbcae
commit
1f620eab22
@@ -1328,6 +1328,10 @@
|
||||
"NotificationsPushBulletSettingsDeviceIds": "Device IDs",
|
||||
"NotificationsPushBulletSettingsDeviceIdsHelpText": "List of device IDs (leave blank to send to all devices)",
|
||||
"NotificationsPushcutSettingsApiKeyHelpText": "API Keys can be managed in the Account view of the Pushcut app",
|
||||
"NotificationsPushcutSettingsIncludePoster": "Include Poster",
|
||||
"NotificationsPushcutSettingsIncludePosterHelpText": "Include poster with notification",
|
||||
"NotificationsPushcutSettingsMetadataLinks": "Metadata Links",
|
||||
"NotificationsPushcutSettingsMetadataLinksHelpText": "Add a links to series metadata when sending notifications",
|
||||
"NotificationsPushcutSettingsNotificationName": "Notification Name",
|
||||
"NotificationsPushcutSettingsNotificationNameHelpText": "Notification name from Notifications tab of the Pushcut app",
|
||||
"NotificationsPushcutSettingsTimeSensitive": "Time Sensitive",
|
||||
|
16
src/NzbDrone.Core/Notifications/NotificationMetadataLink.cs
Normal file
16
src/NzbDrone.Core/Notifications/NotificationMetadataLink.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
namespace NzbDrone.Core.Notifications
|
||||
{
|
||||
public class NotificationMetadataLink
|
||||
{
|
||||
public MetadataLinkType? Type { get; set; }
|
||||
public string Label { get; set; }
|
||||
public string Link { get; set; }
|
||||
|
||||
public NotificationMetadataLink(MetadataLinkType? type, string label, string link)
|
||||
{
|
||||
Type = type;
|
||||
Label = label;
|
||||
Link = link;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Movies;
|
||||
|
||||
namespace NzbDrone.Core.Notifications;
|
||||
|
||||
public static class NotificationMetadataLinkGenerator
|
||||
{
|
||||
public static List<NotificationMetadataLink> GenerateLinks(Movie movie, IEnumerable<int> metadataLinks)
|
||||
{
|
||||
var links = new List<NotificationMetadataLink>();
|
||||
|
||||
if (movie == null)
|
||||
{
|
||||
return links;
|
||||
}
|
||||
|
||||
foreach (var type in metadataLinks)
|
||||
{
|
||||
var linkType = (MetadataLinkType)type;
|
||||
|
||||
if (linkType == MetadataLinkType.Imdb && movie.ImdbId.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
links.Add(new NotificationMetadataLink(MetadataLinkType.Imdb, "IMDb", $"https://www.imdb.com/title/{movie.ImdbId}"));
|
||||
}
|
||||
|
||||
if (linkType == MetadataLinkType.Tmdb && movie.TmdbId > 0)
|
||||
{
|
||||
links.Add(new NotificationMetadataLink(MetadataLinkType.Tmdb, "TMDb", $"https://www.themoviedb.org/movie/{movie.TmdbId}"));
|
||||
}
|
||||
}
|
||||
|
||||
return links;
|
||||
}
|
||||
}
|
@@ -2,6 +2,7 @@ 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.Pushcut
|
||||
@@ -30,47 +31,57 @@ namespace NzbDrone.Core.Notifications.Pushcut
|
||||
|
||||
public override void OnGrab(GrabMessage grabMessage)
|
||||
{
|
||||
_proxy.SendNotification(MOVIE_GRABBED_TITLE, grabMessage?.Message, Settings);
|
||||
_proxy.SendNotification(MOVIE_GRABBED_TITLE, grabMessage?.Message, GetPosterUrl(grabMessage.Movie), GetLinks(grabMessage.Movie), Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(DownloadMessage downloadMessage)
|
||||
{
|
||||
_proxy.SendNotification(downloadMessage.OldMovieFiles.Any() ? MOVIE_UPGRADED_TITLE : MOVIE_DOWNLOADED_TITLE, downloadMessage.Message, Settings);
|
||||
_proxy.SendNotification(downloadMessage.OldMovieFiles.Any() ? MOVIE_UPGRADED_TITLE : MOVIE_DOWNLOADED_TITLE, downloadMessage.Message, GetPosterUrl(downloadMessage.Movie), GetLinks(downloadMessage.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} added to library", GetPosterUrl(movie), GetLinks(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), GetLinks(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), GetLinks(deleteMessage.Movie), Settings);
|
||||
}
|
||||
|
||||
public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
|
||||
{
|
||||
_proxy.SendNotification(HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message, Settings);
|
||||
_proxy.SendNotification(HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message, null, new List<NotificationMetadataLink>(), Settings);
|
||||
}
|
||||
|
||||
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
|
||||
{
|
||||
_proxy.SendNotification(HEALTH_RESTORED_TITLE_BRANDED, $"The following issue is now resolved: {previousCheck.Message}", Settings);
|
||||
_proxy.SendNotification(HEALTH_RESTORED_TITLE_BRANDED, $"The following issue is now resolved: {previousCheck.Message}", null, new List<NotificationMetadataLink>(), Settings);
|
||||
}
|
||||
|
||||
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||
{
|
||||
_proxy.SendNotification(APPLICATION_UPDATE_TITLE_BRANDED, updateMessage.Message, Settings);
|
||||
_proxy.SendNotification(APPLICATION_UPDATE_TITLE_BRANDED, updateMessage.Message, null, new List<NotificationMetadataLink>(), Settings);
|
||||
}
|
||||
|
||||
public override void OnManualInteractionRequired(ManualInteractionRequiredMessage manualInteractionRequiredMessage)
|
||||
{
|
||||
_proxy.SendNotification(MANUAL_INTERACTION_REQUIRED_TITLE_BRANDED, manualInteractionRequiredMessage.Message, Settings);
|
||||
_proxy.SendNotification(MANUAL_INTERACTION_REQUIRED_TITLE_BRANDED, manualInteractionRequiredMessage.Message, null, new List<NotificationMetadataLink>(), Settings);
|
||||
}
|
||||
|
||||
private string GetPosterUrl(Movie movie)
|
||||
{
|
||||
return movie.MovieMetadata.Value.Images.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Poster)?.RemoteUrl;
|
||||
}
|
||||
|
||||
private List<NotificationMetadataLink> GetLinks(Movie movie)
|
||||
{
|
||||
return NotificationMetadataLinkGenerator.GenerateLinks(movie, Settings.MetadataLinks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,3 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NzbDrone.Core.Notifications.Pushcut
|
||||
{
|
||||
public class PushcutPayload
|
||||
@@ -5,5 +7,13 @@ namespace NzbDrone.Core.Notifications.Pushcut
|
||||
public string Title { get; set; }
|
||||
public string Text { get; set; }
|
||||
public bool? IsTimeSensitive { get; set; }
|
||||
public string Image { get; set; }
|
||||
public List<PushcutAction> Actions;
|
||||
}
|
||||
|
||||
public class PushcutAction
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Url { get; set; }
|
||||
}
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@ namespace NzbDrone.Core.Notifications.Pushcut
|
||||
{
|
||||
public interface IPushcutProxy
|
||||
{
|
||||
void SendNotification(string title, string message, PushcutSettings settings);
|
||||
void SendNotification(string title, string message, string posterUrl, List<NotificationMetadataLink> links, PushcutSettings settings);
|
||||
ValidationFailure Test(PushcutSettings settings);
|
||||
}
|
||||
|
||||
@@ -29,20 +29,37 @@ namespace NzbDrone.Core.Notifications.Pushcut
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void SendNotification(string title, string message, PushcutSettings settings)
|
||||
public void SendNotification(string title, string message, string posterUrl, List<NotificationMetadataLink> links, PushcutSettings settings)
|
||||
{
|
||||
if (settings == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var request = new HttpRequestBuilder("https://api.pushcut.io/v1/notifications/{notificationName}")
|
||||
.SetSegment("notificationName", settings?.NotificationName)
|
||||
.SetHeader("API-Key", settings?.ApiKey)
|
||||
.Accept(HttpAccept.Json)
|
||||
.Build();
|
||||
|
||||
var payload = new PushcutPayload
|
||||
{
|
||||
Title = title,
|
||||
Text = message,
|
||||
IsTimeSensitive = settings?.TimeSensitive
|
||||
IsTimeSensitive = settings?.TimeSensitive,
|
||||
Image = settings.IncludePoster ? posterUrl : null,
|
||||
Actions = new List<PushcutAction>()
|
||||
};
|
||||
|
||||
foreach (var link in links)
|
||||
{
|
||||
payload.Actions.Add(new PushcutAction
|
||||
{
|
||||
Name = link.Label,
|
||||
Url = link.Link
|
||||
});
|
||||
}
|
||||
|
||||
request.Method = HttpMethod.Post;
|
||||
request.Headers.ContentType = "application/json";
|
||||
request.SetContent(payload.ToJson());
|
||||
@@ -64,7 +81,7 @@ namespace NzbDrone.Core.Notifications.Pushcut
|
||||
{
|
||||
const string title = "Radarr Test Title";
|
||||
const string message = "Success! You have properly configured your Pushcut notification settings.";
|
||||
SendNotification(title, message, settings);
|
||||
SendNotification(title, message, null, new List<NotificationMetadataLink>(), settings);
|
||||
}
|
||||
catch (PushcutException pushcutException) when (pushcutException.InnerException is HttpException httpException)
|
||||
{
|
||||
|
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Validation;
|
||||
@@ -15,7 +16,7 @@ namespace NzbDrone.Core.Notifications.Pushcut
|
||||
|
||||
public class PushcutSettings : NotificationSettingsBase<PushcutSettings>
|
||||
{
|
||||
private static readonly PushcutSettingsValidator Validator = new ();
|
||||
private static readonly PushcutSettingsValidator Validator = new PushcutSettingsValidator();
|
||||
|
||||
[FieldDefinition(0, Label = "NotificationsPushcutSettingsNotificationName", Type = FieldType.Textbox, HelpText = "NotificationsPushcutSettingsNotificationNameHelpText")]
|
||||
public string NotificationName { get; set; }
|
||||
@@ -26,6 +27,12 @@ namespace NzbDrone.Core.Notifications.Pushcut
|
||||
[FieldDefinition(2, Label = "NotificationsPushcutSettingsTimeSensitive", Type = FieldType.Checkbox, HelpText = "NotificationsPushcutSettingsTimeSensitiveHelpText")]
|
||||
public bool TimeSensitive { get; set; }
|
||||
|
||||
[FieldDefinition(3, Label = "NotificationsPushcutSettingsIncludePoster", Type = FieldType.Checkbox, HelpText = "NotificationsPushcutSettingsIncludePosterHelpText")]
|
||||
public bool IncludePoster { get; set; }
|
||||
|
||||
[FieldDefinition(4, Label = "NotificationsPushcutSettingsMetadataLinks", Type = FieldType.Select, SelectOptions = typeof(MetadataLinkType), HelpText = "NotificationsPushcutSettingsMetadataLinksHelpText")]
|
||||
public IEnumerable<int> MetadataLinks { get; set; } = new List<int>();
|
||||
|
||||
public override NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
|
Reference in New Issue
Block a user