From bcdef2723fe4dea43e2a40be8cd49dd538ab08f2 Mon Sep 17 00:00:00 2001 From: stephanrenggli <5135902+stephanrenggli@users.noreply.github.com> Date: Sun, 5 May 2019 06:08:32 +0200 Subject: [PATCH] New: Added support for Gotify notifications (#730) * Added support for Gotify notifications * Removed non-supported features and adjusted priorities * Use string interpolation to build url * Rename a few variables and improve Url validation * Improve building of the Url, move validation to Gotify.cs (adapting changes by markus101 over at Sonarr) * Move validation from GotifyProxy.cs to here (adapting changes by markus101 over at Sonarr) --- .../Notifications/Gotify/Gotify.cs | 67 +++++++++++++++++++ .../Notifications/Gotify/GotifyPriority.cs | 11 +++ .../Notifications/Gotify/GotifyProxy.cs | 26 +++++++ .../Notifications/Gotify/GotifySettings.cs | 40 +++++++++++ .../Gotify/InvalidResponseException.cs | 15 +++++ src/NzbDrone.Core/NzbDrone.Core.csproj | 5 ++ 6 files changed, 164 insertions(+) create mode 100644 src/NzbDrone.Core/Notifications/Gotify/Gotify.cs create mode 100644 src/NzbDrone.Core/Notifications/Gotify/GotifyPriority.cs create mode 100644 src/NzbDrone.Core/Notifications/Gotify/GotifyProxy.cs create mode 100644 src/NzbDrone.Core/Notifications/Gotify/GotifySettings.cs create mode 100644 src/NzbDrone.Core/Notifications/Gotify/InvalidResponseException.cs diff --git a/src/NzbDrone.Core/Notifications/Gotify/Gotify.cs b/src/NzbDrone.Core/Notifications/Gotify/Gotify.cs new file mode 100644 index 000000000..d5a287514 --- /dev/null +++ b/src/NzbDrone.Core/Notifications/Gotify/Gotify.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using FluentValidation.Results; +using NLog; + +namespace NzbDrone.Core.Notifications.Gotify +{ + public class Gotify : NotificationBase + { + private readonly IGotifyProxy _proxy; + private readonly Logger _logger; + + public Gotify(IGotifyProxy proxy, Logger logger) + { + _proxy = proxy; + _logger = logger; + } + + public override string Name => "Gotify"; + public override string Link => "https://gotify.net/"; + + public override void OnGrab(GrabMessage grabMessage) + { + _proxy.SendNotification(ALBUM_GRABBED_TITLE, grabMessage.Message, Settings); + } + + public override void OnReleaseImport(AlbumDownloadMessage message) + { + _proxy.SendNotification(ALBUM_DOWNLOADED_TITLE, message.Message, Settings); + } + + public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) + { + _proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings); + } + + public override void OnDownloadFailure(DownloadFailedMessage message) + { + _proxy.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, Settings); + } + + public override void OnImportFailure(AlbumDownloadMessage message) + { + _proxy.SendNotification(IMPORT_FAILURE_TITLE, message.Message, Settings); + } + + public override ValidationResult Test() + { + var failures = new List(); + + try + { + const string title = "Test Notification"; + const string body = "This is a test message from Lidarr"; + + _proxy.SendNotification(title, body, Settings); + } + catch (Exception ex) + { + _logger.Error(ex, "Unable to send test message"); + failures.Add(new ValidationFailure("", "Unable to send test message")); + } + + return new ValidationResult(failures); + } + } +} diff --git a/src/NzbDrone.Core/Notifications/Gotify/GotifyPriority.cs b/src/NzbDrone.Core/Notifications/Gotify/GotifyPriority.cs new file mode 100644 index 000000000..8782d4dcd --- /dev/null +++ b/src/NzbDrone.Core/Notifications/Gotify/GotifyPriority.cs @@ -0,0 +1,11 @@ +namespace NzbDrone.Core.Notifications.Gotify + +{ + public enum GotifyPriority + { + Min = 0, + Low = 2, + Normal = 5, + High = 8 + } +} diff --git a/src/NzbDrone.Core/Notifications/Gotify/GotifyProxy.cs b/src/NzbDrone.Core/Notifications/Gotify/GotifyProxy.cs new file mode 100644 index 000000000..b14b530d3 --- /dev/null +++ b/src/NzbDrone.Core/Notifications/Gotify/GotifyProxy.cs @@ -0,0 +1,26 @@ +using RestSharp; +using NzbDrone.Core.Rest; + +namespace NzbDrone.Core.Notifications.Gotify +{ + public interface IGotifyProxy + { + void SendNotification(string title, string message, GotifySettings settings); + } + + public class GotifyProxy : IGotifyProxy + { + public void SendNotification(string title, string message, GotifySettings settings) + { + var client = RestClientFactory.BuildClient(settings.Server); + var request = new RestRequest("message", Method.POST); + + request.AddQueryParameter("token", settings.AppToken); + request.AddParameter("title", title); + request.AddParameter("message", message); + request.AddParameter("priority", settings.Priority); + + client.ExecuteAndValidate(request); + } + } +} diff --git a/src/NzbDrone.Core/Notifications/Gotify/GotifySettings.cs b/src/NzbDrone.Core/Notifications/Gotify/GotifySettings.cs new file mode 100644 index 000000000..4e6f929c9 --- /dev/null +++ b/src/NzbDrone.Core/Notifications/Gotify/GotifySettings.cs @@ -0,0 +1,40 @@ +using FluentValidation; +using NzbDrone.Core.Annotations; +using NzbDrone.Core.ThingiProvider; +using NzbDrone.Core.Validation; + +namespace NzbDrone.Core.Notifications.Gotify +{ + public class GotifySettingsValidator : AbstractValidator + { + public GotifySettingsValidator() + { + RuleFor(c => c.Server).IsValidUrl(); + RuleFor(c => c.AppToken).NotEmpty(); + } + } + + public class GotifySettings : IProviderConfig + { + private static readonly GotifySettingsValidator Validator = new GotifySettingsValidator(); + + public GotifySettings() + { + Priority = 5; + } + + [FieldDefinition(0, Label = "Gotify Server", HelpText = "Gotify server URL, including http(s):// and port if needed")] + public string Server { get; set; } + + [FieldDefinition(1, Label = "App Token", HelpText = "The Application Token generated by Gotify")] + public string AppToken { get; set; } + + [FieldDefinition(2, Label = "Priority", Type = FieldType.Select, SelectOptions = typeof(GotifyPriority), HelpText = "Priority of the notification")] + public int Priority { get; set; } + + public NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } + } +} diff --git a/src/NzbDrone.Core/Notifications/Gotify/InvalidResponseException.cs b/src/NzbDrone.Core/Notifications/Gotify/InvalidResponseException.cs new file mode 100644 index 000000000..0a4c20b4d --- /dev/null +++ b/src/NzbDrone.Core/Notifications/Gotify/InvalidResponseException.cs @@ -0,0 +1,15 @@ +using System; + +namespace NzbDrone.Core.Notifications.Gotify +{ + public class InvalidResponseException : Exception + { + public InvalidResponseException() + { + } + + public InvalidResponseException(string message) : base(message) + { + } + } +} diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index 9fbe860ab..e0e29c99d 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -936,6 +936,11 @@ + + + + +