Changed: Remove growl and prowl

pull/993/head
ta264 5 years ago
parent 8ae66c17f8
commit 3ced1843bf

Binary file not shown.

@ -1,48 +0,0 @@
using NUnit.Framework;
using NzbDrone.Core.Notifications.Prowl;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common;
using NzbDrone.Test.Common.Categories;
namespace NzbDrone.Core.Test.NotificationTests
{
[Explicit]
[ManualTest]
[TestFixture]
public class ProwlProviderTest : CoreTest<ProwlService>
{
private const string _apiKey = "66e9f688b512152eb2688f0486ae542c76e564a2";
private const string _badApiKey = "1234567890abcdefghijklmnopqrstuvwxyz1234";
[Test]
public void Verify_should_not_throw_for_a_valid_apiKey()
{
Subject.Verify(_apiKey);
ExceptionVerification.ExpectedWarns(0);
}
[Test]
public void Verify_should_throw_for_an_invalid_apiKey()
{
Assert.Throws<InvalidApiKeyException>(() => Subject.Verify(_badApiKey));
ExceptionVerification.ExpectedWarns(1);
}
[Test]
public void SendNotification_should_not_throw_for_a_valid_apiKey()
{
Subject.SendNotification("NzbDrone Test", "This is a test message from NzbDrone", _apiKey);
ExceptionVerification.ExpectedWarns(0);
}
[Test]
public void SendNotification_should_log_a_warning_for_an_invalid_apiKey()
{
Subject.SendNotification("NzbDrone Test", "This is a test message from NzbDrone", _badApiKey);
ExceptionVerification.ExpectedWarns(1);
}
}
}

@ -0,0 +1,15 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(37)]
public class remove_growl_prowl : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Delete.FromTable("Notifications").Row(new { Implementation = "Growl" });
Delete.FromTable("Notifications").Row(new { Implementation = "Prowl" });
}
}
}

@ -9,7 +9,6 @@
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="NLog" Version="4.6.7" />
<PackageReference Include="OAuth" Version="1.0.3" />
<PackageReference Include="Prowlin" Version="0.9.4456.26422" />
<PackageReference Include="RestSharp" Version="106.6.10" />
<PackageReference Include="System.IO.Abstractions" Version="4.0.11" />
<PackageReference Include="TagLibSharp-Lidarr" Version="2.2.0.19" />
@ -24,12 +23,6 @@
<ProjectReference Include="..\NzbDrone.Common\Lidarr.Common.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="Growl.Connector, Version=2.0.0.0, Culture=neutral, PublicKeyToken=980c2339411be384, processorArchitecture=MSIL">
<HintPath>..\Libraries\Growl.Connector.dll</HintPath>
</Reference>
<Reference Include="Growl.CoreLibrary, Version=2.0.0.0, Culture=neutral, PublicKeyToken=13e59d82e007b064, processorArchitecture=MSIL">
<HintPath>..\Libraries\Growl.CoreLibrary.dll</HintPath>
</Reference>
<Reference Include="System.Data.SQLite">
<HintPath>..\Libraries\Sqlite\System.Data.SQLite.dll</HintPath>
</Reference>

@ -1,55 +0,0 @@
using System.Collections.Generic;
using FluentValidation.Results;
using NzbDrone.Common.Extensions;
namespace NzbDrone.Core.Notifications.Growl
{
public class Growl : NotificationBase<GrowlSettings>
{
private readonly IGrowlService _growlService;
public override string Name => "Growl";
public Growl(IGrowlService growlService)
{
_growlService = growlService;
}
public override string Link => "http://growl.info/";
public override void OnGrab(GrabMessage grabMessage)
{
_growlService.SendNotification(ALBUM_GRABBED_TITLE, grabMessage.Message, "GRAB", Settings.Host, Settings.Port, Settings.Password);
}
public override void OnReleaseImport(AlbumDownloadMessage message)
{
_growlService.SendNotification(ALBUM_DOWNLOADED_TITLE, message.Message, "ALBUMDOWNLOAD", Settings.Host, Settings.Port, Settings.Password);
}
public override void OnHealthIssue(HealthCheck.HealthCheck message)
{
_growlService.SendNotification(HEALTH_ISSUE_TITLE, message.Message, "HEALTHISSUE", Settings.Host, Settings.Port, Settings.Password);
}
public override void OnDownloadFailure(DownloadFailedMessage message)
{
_growlService.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, "DOWNLOADFAILURE", Settings.Host, Settings.Port, Settings.Password);
}
public override void OnImportFailure(AlbumDownloadMessage message)
{
_growlService.SendNotification(IMPORT_FAILURE_TITLE, message.Message, "IMPORTFAILURE", Settings.Host, Settings.Port, Settings.Password);
}
public override ValidationResult Test()
{
var failures = new List<ValidationFailure>();
failures.AddIfNotNull(_growlService.Test(Settings));
return new ValidationResult(failures);
}
}
}

@ -1,162 +0,0 @@
using FluentValidation.Results;
using Growl.Connector;
using Growl.CoreLibrary;
using NzbDrone.Common.Extensions;
using GrowlNotification = Growl.Connector.Notification;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
namespace NzbDrone.Core.Notifications.Growl
{
public interface IGrowlService
{
void SendNotification(string title, string message, string notificationTypeName, string hostname, int port, string password);
ValidationFailure Test(GrowlSettings settings);
}
public class GrowlService : IGrowlService
{
private readonly Logger _logger;
private readonly Application _growlApplication = new Application("Lidarr");
private readonly NotificationType[] _notificationTypes;
private class GrowlRequestState
{
private AutoResetEvent _autoEvent = new AutoResetEvent(false);
private bool _isError;
private int _code;
private string _description;
public void Wait(int timeoutMs)
{
try
{
if (!_autoEvent.WaitOne(timeoutMs))
{
throw new GrowlException(ErrorCode.TIMED_OUT, ErrorDescription.TIMED_OUT, null);
}
if (_isError)
{
throw new GrowlException(_code, _description, null);
}
}
finally
{
_autoEvent.Reset();
_isError = false;
_code = 0;
_description = null;
}
}
public void Update()
{
_autoEvent.Set();
}
public void Update(int code, string description)
{
_code = code;
_description = description;
_isError = true;
_autoEvent.Set();
}
}
public GrowlService(Logger logger)
{
_logger = logger;
_notificationTypes = GetNotificationTypes();
var logo = typeof(GrowlService).Assembly.GetManifestResourceBytes("NzbDrone.Core.Resources.Logo.64.png");
_growlApplication.Icon = new BinaryData(logo);
}
private GrowlConnector GetGrowlConnector(string hostname, int port, string password)
{
var growlConnector = new GrowlConnector(password, hostname, port);
growlConnector.OKResponse += GrowlOKResponse;
growlConnector.ErrorResponse += GrowlErrorResponse;
return growlConnector;
}
public void SendNotification(string title, string message, string notificationTypeName, string hostname, int port, string password)
{
_logger.Debug("Sending Notification to: {0}:{1}", hostname, port);
var notificationType = _notificationTypes.Single(n => n.Name == notificationTypeName);
var notification = new GrowlNotification(_growlApplication.Name, notificationType.Name, DateTime.Now.Ticks.ToString(), title, message);
var growlConnector = GetGrowlConnector(hostname, port, password);
var requestState = new GrowlRequestState();
growlConnector.Notify(notification, requestState);
requestState.Wait(5000);
}
private void Register(string host, int port, string password)
{
_logger.Debug("Registering Lidarr with Growl host: {0}:{1}", host, port);
var growlConnector = GetGrowlConnector(host, port, password);
var requestState = new GrowlRequestState();
growlConnector.Register(_growlApplication, _notificationTypes, requestState);
requestState.Wait(5000);
}
private void GrowlErrorResponse(Response response, object state)
{
var requestState = state as GrowlRequestState;
if (requestState != null)
{
requestState.Update(response.ErrorCode, response.ErrorDescription);
}
}
private void GrowlOKResponse(Response response, object state)
{
var requestState = state as GrowlRequestState;
if (requestState != null)
{
requestState.Update();
}
}
private NotificationType[] GetNotificationTypes()
{
var notificationTypes = new List<NotificationType>();
notificationTypes.Add(new NotificationType("TEST", "Test"));
notificationTypes.Add(new NotificationType("GRAB", "Album Grabbed"));
notificationTypes.Add(new NotificationType("TRACKDOWNLOAD", "Track Complete"));
notificationTypes.Add(new NotificationType("ALBUMDOWNLOAD", "Album Complete"));
return notificationTypes.ToArray();
}
public ValidationFailure Test(GrowlSettings settings)
{
try
{
Register(settings.Host, settings.Port, settings.Password);
const string title = "Test Notification";
const string body = "This is a test message from Lidarr";
SendNotification(title, body, "TEST", settings.Host, settings.Port, settings.Password);
}
catch (Exception ex)
{
_logger.Error(ex, "Unable to send test message");
return new ValidationFailure("Host", "Unable to send test message");
}
return null;
}
}
}

@ -1,42 +0,0 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Growl
{
public class GrowlSettingsValidator : AbstractValidator<GrowlSettings>
{
public GrowlSettingsValidator()
{
RuleFor(c => c.Host).ValidHost();
RuleFor(c => c.Port).InclusiveBetween(1, 65535);
}
}
public class GrowlSettings : IProviderConfig
{
private static readonly GrowlSettingsValidator Validator = new GrowlSettingsValidator();
public GrowlSettings()
{
Port = 23053;
}
[FieldDefinition(0, Label = "Host")]
public string Host { get; set; }
[FieldDefinition(1, Label = "Port")]
public int Port { get; set; }
[FieldDefinition(2, Label = "Password")]
public string Password { get; set; }
public bool IsValid => !string.IsNullOrWhiteSpace(Host) && !string.IsNullOrWhiteSpace(Password) && Port > 0;
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
}
}

@ -1,15 +0,0 @@
using System;
namespace NzbDrone.Core.Notifications.Prowl
{
public class InvalidApiKeyException : Exception
{
public InvalidApiKeyException()
{
}
public InvalidApiKeyException(string message) : base(message)
{
}
}
}

@ -1,44 +0,0 @@
using System.Collections.Generic;
using FluentValidation.Results;
using NzbDrone.Common.Extensions;
using Prowlin;
namespace NzbDrone.Core.Notifications.Prowl
{
public class Prowl : NotificationBase<ProwlSettings>
{
private readonly IProwlService _prowlService;
public Prowl(IProwlService prowlService)
{
_prowlService = prowlService;
}
public override string Link => "https://www.prowlapp.com/";
public override string Name => "Prowl";
public override void OnGrab(GrabMessage grabMessage)
{
_prowlService.SendNotification(ALBUM_GRABBED_TITLE, grabMessage.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
}
public override void OnReleaseImport(AlbumDownloadMessage message)
{
_prowlService.SendNotification(ALBUM_DOWNLOADED_TITLE, message.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
}
public override void OnHealthIssue(HealthCheck.HealthCheck message)
{
_prowlService.SendNotification(HEALTH_ISSUE_TITLE, message.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
}
public override ValidationResult Test()
{
var failures = new List<ValidationFailure>();
failures.AddIfNotNull(_prowlService.Test(Settings));
return new ValidationResult(failures);
}
}
}

@ -1,11 +0,0 @@
namespace NzbDrone.Core.Notifications.Prowl
{
public enum ProwlPriority
{
VeryLow = -2,
Low = -1,
Normal = 0,
High = 1,
Emergency = 2
}
}

@ -1,105 +0,0 @@
using System;
using FluentValidation.Results;
using NLog;
using NzbDrone.Common.EnvironmentInfo;
using Prowlin;
namespace NzbDrone.Core.Notifications.Prowl
{
public interface IProwlService
{
void SendNotification(string title, string message, string apiKey, NotificationPriority priority = NotificationPriority.Normal, string url = null);
ValidationFailure Test(ProwlSettings settings);
}
public class ProwlService : IProwlService
{
private readonly Logger _logger;
public ProwlService(Logger logger)
{
_logger = logger;
}
public void SendNotification(string title, string message, string apiKey, NotificationPriority priority = NotificationPriority.Normal, string url = null)
{
try
{
var notification = new Prowlin.Notification
{
Application = BuildInfo.AppName,
Description = message,
Event = title,
Priority = priority,
Url = url
};
notification.AddApiKey(apiKey.Trim());
var client = new ProwlClient();
_logger.Debug("Sending Prowl Notification");
var notificationResult = client.SendNotification(notification);
if (!string.IsNullOrWhiteSpace(notificationResult.ErrorMessage))
{
throw new InvalidApiKeyException("API Key: " + apiKey + " is invalid");
}
}
catch (Exception ex)
{
_logger.Debug(ex, ex.Message);
_logger.Warn("Invalid API Key: {0}", apiKey);
}
}
public void Verify(string apiKey)
{
try
{
var verificationRequest = new Verification();
verificationRequest.ApiKey = apiKey;
var client = new ProwlClient();
_logger.Debug("Verifying API Key: {0}", apiKey);
var verificationResult = client.SendVerification(verificationRequest);
if (!string.IsNullOrWhiteSpace(verificationResult.ErrorMessage) &&
verificationResult.ResultCode != "200")
{
throw new InvalidApiKeyException("API Key: " + apiKey + " is invalid");
}
}
catch (Exception ex)
{
_logger.Debug(ex, ex.Message);
_logger.Warn("Invalid API Key: {0}", apiKey);
throw new InvalidApiKeyException("API Key: " + apiKey + " is invalid");
}
}
public ValidationFailure Test(ProwlSettings settings)
{
try
{
Verify(settings.ApiKey);
const string title = "Test Notification";
string body = $"This is a test message from {BuildInfo.AppName}";
SendNotification(title, body, settings.ApiKey);
}
catch (Exception ex)
{
_logger.Error(ex, "Unable to send test message");
return new ValidationFailure("ApiKey", "Unable to send test message");
}
return null;
}
}
}

@ -1,33 +0,0 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Notifications.Prowl
{
public class ProwlSettingsValidator : AbstractValidator<ProwlSettings>
{
public ProwlSettingsValidator()
{
RuleFor(c => c.ApiKey).NotEmpty();
}
}
public class ProwlSettings : IProviderConfig
{
private static readonly ProwlSettingsValidator Validator = new ProwlSettingsValidator();
[FieldDefinition(0, Label = "API Key", HelpLink = "https://www.prowlapp.com/api_settings.php")]
public string ApiKey { get; set; }
[FieldDefinition(1, Label = "Priority", Type = FieldType.Select, SelectOptions= typeof(ProwlPriority) )]
public int Priority { get; set; }
public bool IsValid => !string.IsNullOrWhiteSpace(ApiKey) && Priority >= -2 && Priority <= 2;
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
}
}
Loading…
Cancel
Save