mirror of
https://github.com/lidarr/lidarr.git
synced 2025-07-30 03:38:26 -07:00
Convert Notifications from RestSharp to HttpClient
This commit is contained in:
parent
7566f68fea
commit
12f5f8e437
24 changed files with 385 additions and 415 deletions
|
@ -3,8 +3,7 @@ using System.Net;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
using NzbDrone.Core.Rest;
|
using NzbDrone.Common.Http;
|
||||||
using RestSharp;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Boxcar
|
namespace NzbDrone.Core.Notifications.Boxcar
|
||||||
{
|
{
|
||||||
|
@ -17,22 +16,20 @@ namespace NzbDrone.Core.Notifications.Boxcar
|
||||||
public class BoxcarProxy : IBoxcarProxy
|
public class BoxcarProxy : IBoxcarProxy
|
||||||
{
|
{
|
||||||
private const string URL = "https://new.boxcar.io/api/notifications";
|
private const string URL = "https://new.boxcar.io/api/notifications";
|
||||||
private readonly IRestClientFactory _restClientFactory;
|
private readonly IHttpClient _httpClient;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public BoxcarProxy(IRestClientFactory restClientFactory, Logger logger)
|
public BoxcarProxy(IHttpClient httpClient, Logger logger)
|
||||||
{
|
{
|
||||||
_restClientFactory = restClientFactory;
|
_httpClient = httpClient;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendNotification(string title, string message, BoxcarSettings settings)
|
public void SendNotification(string title, string message, BoxcarSettings settings)
|
||||||
{
|
{
|
||||||
var request = new RestRequest(Method.POST);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
SendNotification(title, message, request, settings);
|
ProcessNotification(title, message, settings);
|
||||||
}
|
}
|
||||||
catch (BoxcarException ex)
|
catch (BoxcarException ex)
|
||||||
{
|
{
|
||||||
|
@ -51,7 +48,7 @@ namespace NzbDrone.Core.Notifications.Boxcar
|
||||||
SendNotification(title, body, settings);
|
SendNotification(title, body, settings);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
catch (RestException ex)
|
catch (HttpException ex)
|
||||||
{
|
{
|
||||||
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
|
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
|
||||||
{
|
{
|
||||||
|
@ -69,21 +66,22 @@ namespace NzbDrone.Core.Notifications.Boxcar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendNotification(string title, string message, RestRequest request, BoxcarSettings settings)
|
private void ProcessNotification(string title, string message, BoxcarSettings settings)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var client = _restClientFactory.BuildClient(URL);
|
var requestBuilder = new HttpRequestBuilder(URL).Post();
|
||||||
|
|
||||||
request.AddParameter("user_credentials", settings.Token);
|
var request = requestBuilder.AddFormParameter("user_credentials", settings.Token)
|
||||||
request.AddParameter("notification[title]", title);
|
.AddFormParameter("notification[title]", title)
|
||||||
request.AddParameter("notification[long_message]", message);
|
.AddFormParameter("notification[long_message]", message)
|
||||||
request.AddParameter("notification[source_name]", BuildInfo.AppName);
|
.AddFormParameter("notification[source_name]", BuildInfo.AppName)
|
||||||
request.AddParameter("notification[icon_url]", "https://github.com/lidarr/Lidarr/raw/develop/Logo/64.png");
|
.AddFormParameter("notification[icon_url]", "https://raw.githubusercontent.com/Lidarr/Lidarr/develop/Logo/64.png")
|
||||||
|
.Build();
|
||||||
|
|
||||||
client.ExecuteAndValidate(request);
|
_httpClient.Post(request);
|
||||||
}
|
}
|
||||||
catch (RestException ex)
|
catch (HttpException ex)
|
||||||
{
|
{
|
||||||
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
|
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,6 @@ using NLog;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Core.Notifications.Discord.Payloads;
|
using NzbDrone.Core.Notifications.Discord.Payloads;
|
||||||
using NzbDrone.Core.Rest;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Discord
|
namespace NzbDrone.Core.Notifications.Discord
|
||||||
{
|
{
|
||||||
|
@ -36,7 +35,7 @@ namespace NzbDrone.Core.Notifications.Discord
|
||||||
|
|
||||||
_httpClient.Execute(request);
|
_httpClient.Execute(request);
|
||||||
}
|
}
|
||||||
catch (RestException ex)
|
catch (HttpException ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Unable to post payload {0}", payload);
|
_logger.Error(ex, "Unable to post payload {0}", payload);
|
||||||
throw new DiscordException("Unable to post payload", ex);
|
throw new DiscordException("Unable to post payload", ex);
|
||||||
|
|
18
src/NzbDrone.Core/Notifications/Gotify/GotifyException.cs
Normal file
18
src/NzbDrone.Core/Notifications/Gotify/GotifyException.cs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
using NzbDrone.Common.Exceptions;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Notifications.Gotify
|
||||||
|
{
|
||||||
|
public class GotifyException : NzbDroneException
|
||||||
|
{
|
||||||
|
public GotifyException(string message)
|
||||||
|
: base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public GotifyException(string message, Exception innerException, params object[] args)
|
||||||
|
: base(message, innerException, args)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
using NzbDrone.Core.Rest;
|
using System.Net;
|
||||||
using RestSharp;
|
using NzbDrone.Common.Http;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Gotify
|
namespace NzbDrone.Core.Notifications.Gotify
|
||||||
{
|
{
|
||||||
|
@ -10,24 +10,35 @@ namespace NzbDrone.Core.Notifications.Gotify
|
||||||
|
|
||||||
public class GotifyProxy : IGotifyProxy
|
public class GotifyProxy : IGotifyProxy
|
||||||
{
|
{
|
||||||
private readonly IRestClientFactory _restClientFactory;
|
private readonly IHttpClient _httpClient;
|
||||||
|
|
||||||
public GotifyProxy(IRestClientFactory restClientFactory)
|
public GotifyProxy(IHttpClient httpClient)
|
||||||
{
|
{
|
||||||
_restClientFactory = restClientFactory;
|
_httpClient = httpClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendNotification(string title, string message, GotifySettings settings)
|
public void SendNotification(string title, string message, GotifySettings settings)
|
||||||
{
|
{
|
||||||
var client = _restClientFactory.BuildClient(settings.Server);
|
try
|
||||||
var request = new RestRequest("message", Method.POST);
|
{
|
||||||
|
var request = new HttpRequestBuilder(settings.Server).Post()
|
||||||
|
.AddFormParameter("token", settings.AppToken)
|
||||||
|
.AddFormParameter("title", title)
|
||||||
|
.AddFormParameter("message", message)
|
||||||
|
.AddFormParameter("priority", settings.Priority)
|
||||||
|
.Build();
|
||||||
|
|
||||||
request.AddQueryParameter("token", settings.AppToken);
|
_httpClient.Post(request);
|
||||||
request.AddParameter("title", title);
|
}
|
||||||
request.AddParameter("message", message);
|
catch (HttpException ex)
|
||||||
request.AddParameter("priority", settings.Priority);
|
{
|
||||||
|
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
|
||||||
|
{
|
||||||
|
throw new GotifyException("Unauthorized - AuthToken is invalid");
|
||||||
|
}
|
||||||
|
|
||||||
client.ExecuteAndValidate(request);
|
throw new GotifyException("Unable to connect to Gotify. Status Code: {0}", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Gotify
|
|
||||||
{
|
|
||||||
public class InvalidResponseException : Exception
|
|
||||||
{
|
|
||||||
public InvalidResponseException()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public InvalidResponseException(string message)
|
|
||||||
: base(message)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,9 +2,8 @@ using System;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Core.Rest;
|
|
||||||
using RestSharp;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Join
|
namespace NzbDrone.Core.Notifications.Join
|
||||||
{
|
{
|
||||||
|
@ -17,22 +16,22 @@ namespace NzbDrone.Core.Notifications.Join
|
||||||
public class JoinProxy : IJoinProxy
|
public class JoinProxy : IJoinProxy
|
||||||
{
|
{
|
||||||
private const string URL = "https://joinjoaomgcd.appspot.com/_ah/api/messaging/v1/sendPush?";
|
private const string URL = "https://joinjoaomgcd.appspot.com/_ah/api/messaging/v1/sendPush?";
|
||||||
private readonly IRestClientFactory _restClientFactory;
|
private readonly IHttpClient _httpClient;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public JoinProxy(IRestClientFactory restClientFactory, Logger logger)
|
public JoinProxy(IHttpClient httpClient, Logger logger)
|
||||||
{
|
{
|
||||||
_restClientFactory = restClientFactory;
|
_httpClient = httpClient;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendNotification(string title, string message, JoinSettings settings)
|
public void SendNotification(string title, string message, JoinSettings settings)
|
||||||
{
|
{
|
||||||
var request = new RestRequest(Method.GET);
|
var method = HttpMethod.GET;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
SendNotification(title, message, request, settings);
|
SendNotification(title, message, method, settings);
|
||||||
}
|
}
|
||||||
catch (JoinException ex)
|
catch (JoinException ex)
|
||||||
{
|
{
|
||||||
|
@ -61,7 +60,7 @@ namespace NzbDrone.Core.Notifications.Join
|
||||||
_logger.Error(ex, "Unable to send test Join message.");
|
_logger.Error(ex, "Unable to send test Join message.");
|
||||||
return new ValidationFailure("ApiKey", ex.Message);
|
return new ValidationFailure("ApiKey", ex.Message);
|
||||||
}
|
}
|
||||||
catch (RestException ex)
|
catch (HttpException ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Unable to send test Join message. Server connection failed.");
|
_logger.Error(ex, "Unable to send test Join message. Server connection failed.");
|
||||||
return new ValidationFailure("ApiKey", "Unable to connect to Join API. Please try again later.");
|
return new ValidationFailure("ApiKey", "Unable to connect to Join API. Please try again later.");
|
||||||
|
@ -73,31 +72,34 @@ namespace NzbDrone.Core.Notifications.Join
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendNotification(string title, string message, RestRequest request, JoinSettings settings)
|
private void SendNotification(string title, string message, HttpMethod method, JoinSettings settings)
|
||||||
{
|
{
|
||||||
var client = _restClientFactory.BuildClient(URL);
|
var requestBuilder = new HttpRequestBuilder(URL);
|
||||||
|
|
||||||
if (settings.DeviceNames.IsNotNullOrWhiteSpace())
|
if (settings.DeviceNames.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
request.AddParameter("deviceNames", settings.DeviceNames);
|
requestBuilder.AddQueryParam("deviceNames", settings.DeviceNames);
|
||||||
}
|
}
|
||||||
else if (settings.DeviceIds.IsNotNullOrWhiteSpace())
|
else if (settings.DeviceIds.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
request.AddParameter("deviceIds", settings.DeviceIds);
|
requestBuilder.AddQueryParam("deviceIds", settings.DeviceIds);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
request.AddParameter("deviceId", "group.all");
|
requestBuilder.AddQueryParam("deviceId", "group.all");
|
||||||
}
|
}
|
||||||
|
|
||||||
request.AddParameter("apikey", settings.ApiKey);
|
var request = requestBuilder.AddQueryParam("apikey", settings.ApiKey)
|
||||||
request.AddParameter("title", title);
|
.AddQueryParam("title", title)
|
||||||
request.AddParameter("text", message);
|
.AddQueryParam("text", message)
|
||||||
request.AddParameter("icon", "https://cdn.rawgit.com/Lidarr/Lidarr/develop/Logo/256.png"); // Use the Lidarr logo.
|
.AddQueryParam("icon", "https://cdn.rawgit.com/Lidarr/Lidarr/develop/Logo/256.png") // Use the Lidarr logo.
|
||||||
request.AddParameter("smallicon", "https://cdn.rawgit.com/Lidarr/Lidarr/develop/Logo/96-Outline-White.png"); // 96x96px with outline at 88x88px on a transparent background.
|
.AddQueryParam("smallicon", "https://cdn.rawgit.com/Lidarr/Lidarr/develop/Logo/96-Outline-White.png") // 96x96px with outline at 88x88px on a transparent background.
|
||||||
request.AddParameter("priority", settings.Priority);
|
.AddQueryParam("priority", settings.Priority)
|
||||||
|
.Build();
|
||||||
|
|
||||||
var response = client.ExecuteAndValidate(request);
|
request.Method = method;
|
||||||
|
|
||||||
|
var response = _httpClient.Execute(request);
|
||||||
var res = Json.Deserialize<JoinResponseModel>(response.Content);
|
var res = Json.Deserialize<JoinResponseModel>(response.Content);
|
||||||
|
|
||||||
if (res.success)
|
if (res.success)
|
||||||
|
|
|
@ -3,8 +3,8 @@ using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Music;
|
using NzbDrone.Core.Music;
|
||||||
using NzbDrone.Core.Rest;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Emby
|
namespace NzbDrone.Core.Notifications.Emby
|
||||||
{
|
{
|
||||||
|
@ -48,7 +48,7 @@ namespace NzbDrone.Core.Notifications.Emby
|
||||||
|
|
||||||
Notify(settings, "Test from Lidarr", "Success! MediaBrowser has been successfully configured!");
|
Notify(settings, "Test from Lidarr", "Success! MediaBrowser has been successfully configured!");
|
||||||
}
|
}
|
||||||
catch (RestException ex)
|
catch (HttpException ex)
|
||||||
{
|
{
|
||||||
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
|
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
|
||||||
{
|
{
|
||||||
|
|
43
src/NzbDrone.Core/Notifications/Prowl/Prowl.cs
Normal file
43
src/NzbDrone.Core/Notifications/Prowl/Prowl.cs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Notifications.Prowl
|
||||||
|
{
|
||||||
|
public class Prowl : NotificationBase<ProwlSettings>
|
||||||
|
{
|
||||||
|
private readonly IProwlProxy _prowlProxy;
|
||||||
|
|
||||||
|
public Prowl(IProwlProxy prowlProxy)
|
||||||
|
{
|
||||||
|
_prowlProxy = prowlProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Link => "https://www.prowlapp.com/";
|
||||||
|
public override string Name => "Prowl";
|
||||||
|
|
||||||
|
public override void OnGrab(GrabMessage message)
|
||||||
|
{
|
||||||
|
_prowlProxy.SendNotification(ALBUM_GRABBED_TITLE, message.Message, Settings.ApiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||||
|
{
|
||||||
|
_prowlProxy.SendNotification(ALBUM_DOWNLOADED_TITLE, message.Message, Settings.ApiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
|
||||||
|
{
|
||||||
|
_prowlProxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings.ApiKey, (ProwlPriority)Settings.Priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ValidationResult Test()
|
||||||
|
{
|
||||||
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
||||||
|
failures.AddIfNotNull(_prowlProxy.Test(Settings));
|
||||||
|
|
||||||
|
return new ValidationResult(failures);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
src/NzbDrone.Core/Notifications/Prowl/ProwlException.cs
Normal file
18
src/NzbDrone.Core/Notifications/Prowl/ProwlException.cs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
using NzbDrone.Common.Exceptions;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Notifications.Prowl
|
||||||
|
{
|
||||||
|
public class ProwlException : NzbDroneException
|
||||||
|
{
|
||||||
|
public ProwlException(string message)
|
||||||
|
: base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProwlException(string message, Exception innerException, params object[] args)
|
||||||
|
: base(message, innerException, args)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
src/NzbDrone.Core/Notifications/Prowl/ProwlPriority.cs
Normal file
11
src/NzbDrone.Core/Notifications/Prowl/ProwlPriority.cs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
namespace NzbDrone.Core.Notifications.Prowl
|
||||||
|
{
|
||||||
|
public enum ProwlPriority
|
||||||
|
{
|
||||||
|
VeryLow = -2,
|
||||||
|
Low = -1,
|
||||||
|
Normal = 0,
|
||||||
|
High = 1,
|
||||||
|
Emergency = 2
|
||||||
|
}
|
||||||
|
}
|
78
src/NzbDrone.Core/Notifications/Prowl/ProwlProxy.cs
Normal file
78
src/NzbDrone.Core/Notifications/Prowl/ProwlProxy.cs
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Notifications.Prowl
|
||||||
|
{
|
||||||
|
public interface IProwlProxy
|
||||||
|
{
|
||||||
|
void SendNotification(string title, string message, string apiKey, ProwlPriority priority = ProwlPriority.Normal, string url = null);
|
||||||
|
ValidationFailure Test(ProwlSettings settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ProwlProxy : IProwlProxy
|
||||||
|
{
|
||||||
|
private const string PUSH_URL = "https://api.prowlapp.com/publicapi/add";
|
||||||
|
private readonly IHttpClient _httpClient;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public ProwlProxy(IHttpClient httpClient, Logger logger)
|
||||||
|
{
|
||||||
|
_httpClient = httpClient;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendNotification(string title, string message, string apiKey, ProwlPriority priority = ProwlPriority.Normal, string url = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var requestBuilder = new HttpRequestBuilder(PUSH_URL);
|
||||||
|
|
||||||
|
var request = requestBuilder.Post()
|
||||||
|
.AddFormParameter("apikey", apiKey)
|
||||||
|
.AddFormParameter("application", BuildInfo.AppName)
|
||||||
|
.AddFormParameter("event", title)
|
||||||
|
.AddFormParameter("description", message)
|
||||||
|
.AddFormParameter("priority", priority)
|
||||||
|
.AddFormParameter("url", url)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_httpClient.Post(request);
|
||||||
|
}
|
||||||
|
catch (HttpException ex)
|
||||||
|
{
|
||||||
|
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
|
||||||
|
{
|
||||||
|
_logger.Error(ex, "Apikey is invalid: {0}", apiKey);
|
||||||
|
throw new ProwlException("Apikey is invalid", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ProwlException("Unable to send text message: " + ex.Message, ex);
|
||||||
|
}
|
||||||
|
catch (WebException ex)
|
||||||
|
{
|
||||||
|
throw new ProwlException("Failed to connect to prowl, please check your settings.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValidationFailure Test(ProwlSettings settings)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const string title = "Test Notification";
|
||||||
|
const string body = "This is a test message from Lidarr";
|
||||||
|
|
||||||
|
SendNotification(title, body, settings.ApiKey);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return new ValidationFailure("ApiKey", ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
33
src/NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs
Normal file
33
src/NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
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", Privacy = PrivacyLevel.ApiKey, 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,10 +5,8 @@ using System.Net;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Core.Rest;
|
|
||||||
using RestSharp;
|
|
||||||
using RestSharp.Authenticators;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.PushBullet
|
namespace NzbDrone.Core.Notifications.PushBullet
|
||||||
{
|
{
|
||||||
|
@ -23,12 +21,12 @@ namespace NzbDrone.Core.Notifications.PushBullet
|
||||||
{
|
{
|
||||||
private const string PUSH_URL = "https://api.pushbullet.com/v2/pushes";
|
private const string PUSH_URL = "https://api.pushbullet.com/v2/pushes";
|
||||||
private const string DEVICE_URL = "https://api.pushbullet.com/v2/devices";
|
private const string DEVICE_URL = "https://api.pushbullet.com/v2/devices";
|
||||||
private readonly IRestClientFactory _restClientFactory;
|
private readonly IHttpClient _httpClient;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public PushBulletProxy(IRestClientFactory restClientFactory, Logger logger)
|
public PushBulletProxy(IHttpClient httpClient, Logger logger)
|
||||||
{
|
{
|
||||||
_restClientFactory = restClientFactory;
|
_httpClient = httpClient;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,15 +96,18 @@ namespace NzbDrone.Core.Notifications.PushBullet
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var client = _restClientFactory.BuildClient(DEVICE_URL);
|
var requestBuilder = new HttpRequestBuilder(DEVICE_URL);
|
||||||
var request = new RestRequest(Method.GET);
|
|
||||||
|
|
||||||
client.Authenticator = new HttpBasicAuthenticator(settings.ApiKey, string.Empty);
|
var request = requestBuilder.Build();
|
||||||
var response = client.ExecuteAndValidate(request);
|
|
||||||
|
request.Method = HttpMethod.GET;
|
||||||
|
request.AddBasicAuthentication(settings.ApiKey, string.Empty);
|
||||||
|
|
||||||
|
var response = _httpClient.Execute(request);
|
||||||
|
|
||||||
return Json.Deserialize<PushBulletDevicesResponse>(response.Content).Devices;
|
return Json.Deserialize<PushBulletDevicesResponse>(response.Content).Devices;
|
||||||
}
|
}
|
||||||
catch (RestException ex)
|
catch (HttpException ex)
|
||||||
{
|
{
|
||||||
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
|
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
|
||||||
{
|
{
|
||||||
|
@ -127,7 +128,7 @@ namespace NzbDrone.Core.Notifications.PushBullet
|
||||||
|
|
||||||
SendNotification(title, body, settings);
|
SendNotification(title, body, settings);
|
||||||
}
|
}
|
||||||
catch (RestException ex)
|
catch (HttpException ex)
|
||||||
{
|
{
|
||||||
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
|
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
|
||||||
{
|
{
|
||||||
|
@ -147,50 +148,60 @@ namespace NzbDrone.Core.Notifications.PushBullet
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private RestRequest BuildDeviceRequest(string deviceId)
|
private HttpRequestBuilder BuildDeviceRequest(string deviceId)
|
||||||
{
|
{
|
||||||
var request = new RestRequest(Method.POST);
|
var requestBuilder = new HttpRequestBuilder(PUSH_URL).Post();
|
||||||
long integerId;
|
long integerId;
|
||||||
|
|
||||||
|
if (deviceId.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
return requestBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
if (long.TryParse(deviceId, out integerId))
|
if (long.TryParse(deviceId, out integerId))
|
||||||
{
|
{
|
||||||
request.AddParameter("device_id", integerId);
|
requestBuilder.AddFormParameter("device_id", integerId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
request.AddParameter("device_iden", deviceId);
|
requestBuilder.AddFormParameter("device_iden", deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return request;
|
return requestBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private RestRequest BuildChannelRequest(string channelTag)
|
private HttpRequestBuilder BuildChannelRequest(string channelTag)
|
||||||
{
|
{
|
||||||
var request = new RestRequest(Method.POST);
|
var requestBuilder = new HttpRequestBuilder(PUSH_URL).Post();
|
||||||
request.AddParameter("channel_tag", channelTag);
|
|
||||||
|
|
||||||
return request;
|
if (channelTag.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
requestBuilder.AddFormParameter("channel_tag", channelTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
return requestBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendNotification(string title, string message, RestRequest request, PushBulletSettings settings)
|
private void SendNotification(string title, string message, HttpRequestBuilder requestBuilder, PushBulletSettings settings)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var client = _restClientFactory.BuildClient(PUSH_URL);
|
requestBuilder.AddFormParameter("type", "note")
|
||||||
|
.AddFormParameter("title", title)
|
||||||
request.AddParameter("type", "note");
|
.AddFormParameter("body", message);
|
||||||
request.AddParameter("title", title);
|
|
||||||
request.AddParameter("body", message);
|
|
||||||
|
|
||||||
if (settings.SenderId.IsNotNullOrWhiteSpace())
|
if (settings.SenderId.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
request.AddParameter("source_device_iden", settings.SenderId);
|
requestBuilder.AddFormParameter("source_device_iden", settings.SenderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Authenticator = new HttpBasicAuthenticator(settings.ApiKey, string.Empty);
|
var request = requestBuilder.Build();
|
||||||
client.ExecuteAndValidate(request);
|
|
||||||
|
request.AddBasicAuthentication(settings.ApiKey, string.Empty);
|
||||||
|
|
||||||
|
_httpClient.Execute(request);
|
||||||
}
|
}
|
||||||
catch (RestException ex)
|
catch (HttpException ex)
|
||||||
{
|
{
|
||||||
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
|
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,8 +2,7 @@ using System;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Core.Rest;
|
using NzbDrone.Common.Http;
|
||||||
using RestSharp;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Pushover
|
namespace NzbDrone.Core.Notifications.Pushover
|
||||||
{
|
{
|
||||||
|
@ -16,38 +15,40 @@ namespace NzbDrone.Core.Notifications.Pushover
|
||||||
public class PushoverProxy : IPushoverProxy
|
public class PushoverProxy : IPushoverProxy
|
||||||
{
|
{
|
||||||
private const string URL = "https://api.pushover.net/1/messages.json";
|
private const string URL = "https://api.pushover.net/1/messages.json";
|
||||||
private readonly IRestClientFactory _restClientFactory;
|
private readonly IHttpClient _httpClient;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public PushoverProxy(IRestClientFactory restClientFactory, Logger logger)
|
public PushoverProxy(IHttpClient httpClient, Logger logger)
|
||||||
{
|
{
|
||||||
_restClientFactory = restClientFactory;
|
_httpClient = httpClient;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendNotification(string title, string message, PushoverSettings settings)
|
public void SendNotification(string title, string message, PushoverSettings settings)
|
||||||
{
|
{
|
||||||
var client = _restClientFactory.BuildClient(URL);
|
var requestBuilder = new HttpRequestBuilder(URL).Post();
|
||||||
var request = new RestRequest(Method.POST);
|
|
||||||
request.AddParameter("token", settings.ApiKey);
|
requestBuilder.AddFormParameter("token", settings.ApiKey)
|
||||||
request.AddParameter("user", settings.UserKey);
|
.AddFormParameter("user", settings.UserKey)
|
||||||
request.AddParameter("device", string.Join(",", settings.Devices));
|
.AddFormParameter("device", string.Join(",", settings.Devices))
|
||||||
request.AddParameter("title", title);
|
.AddFormParameter("title", title)
|
||||||
request.AddParameter("message", message);
|
.AddFormParameter("message", message)
|
||||||
request.AddParameter("priority", settings.Priority);
|
.AddFormParameter("priority", settings.Priority);
|
||||||
|
|
||||||
if ((PushoverPriority)settings.Priority == PushoverPriority.Emergency)
|
if ((PushoverPriority)settings.Priority == PushoverPriority.Emergency)
|
||||||
{
|
{
|
||||||
request.AddParameter("retry", settings.Retry);
|
requestBuilder.AddFormParameter("retry", settings.Retry);
|
||||||
request.AddParameter("expire", settings.Expire);
|
requestBuilder.AddFormParameter("expire", settings.Expire);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!settings.Sound.IsNullOrWhiteSpace())
|
if (!settings.Sound.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
request.AddParameter("sound", settings.Sound);
|
requestBuilder.AddFormParameter("sound", settings.Sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
client.ExecuteAndValidate(request);
|
var request = requestBuilder.Build();
|
||||||
|
|
||||||
|
_httpClient.Post(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValidationFailure Test(PushoverSettings settings)
|
public ValidationFailure Test(PushoverSettings settings)
|
||||||
|
|
|
@ -2,7 +2,6 @@ using NLog;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Core.Notifications.Slack.Payloads;
|
using NzbDrone.Core.Notifications.Slack.Payloads;
|
||||||
using NzbDrone.Core.Rest;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Slack
|
namespace NzbDrone.Core.Notifications.Slack
|
||||||
{
|
{
|
||||||
|
@ -36,7 +35,7 @@ namespace NzbDrone.Core.Notifications.Slack
|
||||||
|
|
||||||
_httpClient.Execute(request);
|
_httpClient.Execute(request);
|
||||||
}
|
}
|
||||||
catch (RestException ex)
|
catch (HttpException ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Unable to post payload {0}", payload);
|
_logger.Error(ex, "Unable to post payload {0}", payload);
|
||||||
throw new SlackExeption("Unable to post payload", ex);
|
throw new SlackExeption("Unable to post payload", ex);
|
||||||
|
|
|
@ -3,8 +3,6 @@ using System.Xml.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Rest;
|
|
||||||
using RestSharp;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Subsonic
|
namespace NzbDrone.Core.Notifications.Subsonic
|
||||||
{
|
{
|
||||||
|
@ -18,12 +16,12 @@ namespace NzbDrone.Core.Notifications.Subsonic
|
||||||
|
|
||||||
public class SubsonicServerProxy : ISubsonicServerProxy
|
public class SubsonicServerProxy : ISubsonicServerProxy
|
||||||
{
|
{
|
||||||
private readonly IRestClientFactory _restClientFactory;
|
private readonly IHttpClient _httpClient;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public SubsonicServerProxy(IRestClientFactory restClientFactory, Logger logger)
|
public SubsonicServerProxy(IHttpClient httpClient, Logger logger)
|
||||||
{
|
{
|
||||||
_restClientFactory = restClientFactory;
|
_httpClient = httpClient;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,10 +36,10 @@ namespace NzbDrone.Core.Notifications.Subsonic
|
||||||
public void Notify(SubsonicSettings settings, string message)
|
public void Notify(SubsonicSettings settings, string message)
|
||||||
{
|
{
|
||||||
var resource = "addChatMessage";
|
var resource = "addChatMessage";
|
||||||
var request = GetSubsonicServerRequest(resource, Method.GET, settings);
|
var request = GetSubsonicServerRequest(resource, HttpMethod.GET, settings);
|
||||||
request.AddParameter("message", message);
|
request.AddQueryParam("message", message);
|
||||||
var client = GetSubsonicServerClient(settings);
|
|
||||||
var response = client.Execute(request);
|
var response = _httpClient.Execute(request.Build());
|
||||||
|
|
||||||
_logger.Trace("Update response: {0}", response.Content);
|
_logger.Trace("Update response: {0}", response.Content);
|
||||||
CheckForError(response, settings);
|
CheckForError(response, settings);
|
||||||
|
@ -50,9 +48,8 @@ namespace NzbDrone.Core.Notifications.Subsonic
|
||||||
public void Update(SubsonicSettings settings)
|
public void Update(SubsonicSettings settings)
|
||||||
{
|
{
|
||||||
var resource = "startScan";
|
var resource = "startScan";
|
||||||
var request = GetSubsonicServerRequest(resource, Method.GET, settings);
|
var request = GetSubsonicServerRequest(resource, HttpMethod.GET, settings);
|
||||||
var client = GetSubsonicServerClient(settings);
|
var response = _httpClient.Execute(request.Build());
|
||||||
var response = client.Execute(request);
|
|
||||||
|
|
||||||
_logger.Trace("Update response: {0}", response.Content);
|
_logger.Trace("Update response: {0}", response.Content);
|
||||||
CheckForError(response, settings);
|
CheckForError(response, settings);
|
||||||
|
@ -60,9 +57,8 @@ namespace NzbDrone.Core.Notifications.Subsonic
|
||||||
|
|
||||||
public string Version(SubsonicSettings settings)
|
public string Version(SubsonicSettings settings)
|
||||||
{
|
{
|
||||||
var request = GetSubsonicServerRequest("ping", Method.GET, settings);
|
var request = GetSubsonicServerRequest("ping", HttpMethod.GET, settings);
|
||||||
var client = GetSubsonicServerClient(settings);
|
var response = _httpClient.Execute(request.Build());
|
||||||
var response = client.Execute(request);
|
|
||||||
|
|
||||||
_logger.Trace("Version response: {0}", response.Content);
|
_logger.Trace("Version response: {0}", response.Content);
|
||||||
CheckForError(response, settings);
|
CheckForError(response, settings);
|
||||||
|
@ -78,27 +74,26 @@ namespace NzbDrone.Core.Notifications.Subsonic
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
private RestClient GetSubsonicServerClient(SubsonicSettings settings)
|
private HttpRequestBuilder GetSubsonicServerRequest(string resource, HttpMethod method, SubsonicSettings settings)
|
||||||
{
|
{
|
||||||
return _restClientFactory.BuildClient(GetBaseUrl(settings, "rest"));
|
var client = new HttpRequestBuilder(GetBaseUrl(settings, "rest"));
|
||||||
}
|
|
||||||
|
|
||||||
private RestRequest GetSubsonicServerRequest(string resource, Method method, SubsonicSettings settings)
|
client.Resource(resource);
|
||||||
{
|
|
||||||
var request = new RestRequest(resource, method);
|
|
||||||
|
|
||||||
if (settings.Username.IsNotNullOrWhiteSpace())
|
if (settings.Username.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
request.AddParameter("u", settings.Username);
|
client.AddQueryParam("u", settings.Username)
|
||||||
request.AddParameter("p", settings.Password);
|
.AddQueryParam("p", settings.Password)
|
||||||
request.AddParameter("c", "Lidarr");
|
.AddQueryParam("c", "Lidarr")
|
||||||
request.AddParameter("v", "1.15.0");
|
.AddQueryParam("v", "1.15.0");
|
||||||
}
|
}
|
||||||
|
|
||||||
return request;
|
client.Method = method;
|
||||||
|
|
||||||
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckForError(IRestResponse response, SubsonicSettings settings)
|
private void CheckForError(HttpResponse response, SubsonicSettings settings)
|
||||||
{
|
{
|
||||||
_logger.Trace("Checking for error");
|
_logger.Trace("Checking for error");
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,8 @@ using System.Web;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Core.Rest;
|
|
||||||
using RestSharp;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Telegram
|
namespace NzbDrone.Core.Notifications.Telegram
|
||||||
{
|
{
|
||||||
|
@ -19,12 +18,12 @@ namespace NzbDrone.Core.Notifications.Telegram
|
||||||
public class TelegramProxy : ITelegramProxy
|
public class TelegramProxy : ITelegramProxy
|
||||||
{
|
{
|
||||||
private const string URL = "https://api.telegram.org";
|
private const string URL = "https://api.telegram.org";
|
||||||
private readonly IRestClientFactory _restClientFactory;
|
private readonly IHttpClient _httpClient;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public TelegramProxy(IRestClientFactory restClientFactory, Logger logger)
|
public TelegramProxy(IHttpClient httpClient, Logger logger)
|
||||||
{
|
{
|
||||||
_restClientFactory = restClientFactory;
|
_httpClient = httpClient;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,17 +31,17 @@ namespace NzbDrone.Core.Notifications.Telegram
|
||||||
{
|
{
|
||||||
//Format text to add the title before and bold using markdown
|
//Format text to add the title before and bold using markdown
|
||||||
var text = $"<b>{HttpUtility.HtmlEncode(title)}</b>\n{HttpUtility.HtmlEncode(message)}";
|
var text = $"<b>{HttpUtility.HtmlEncode(title)}</b>\n{HttpUtility.HtmlEncode(message)}";
|
||||||
var client = _restClientFactory.BuildClient(URL);
|
|
||||||
|
|
||||||
var request = new RestRequest("bot{token}/sendmessage", Method.POST);
|
var requestBuilder = new HttpRequestBuilder(URL).Resource("bot{token}/sendmessage").Post();
|
||||||
|
|
||||||
request.AddUrlSegment("token", settings.BotToken);
|
var request = requestBuilder.SetSegment("token", settings.BotToken)
|
||||||
request.AddParameter("chat_id", settings.ChatId);
|
.AddFormParameter("chat_id", settings.ChatId)
|
||||||
request.AddParameter("parse_mode", "HTML");
|
.AddFormParameter("parse_mode", "HTML")
|
||||||
request.AddParameter("text", text);
|
.AddFormParameter("text", text)
|
||||||
request.AddParameter("disable_notification", settings.SendSilently);
|
.AddFormParameter("disable_notification", settings.SendSilently)
|
||||||
|
.Build();
|
||||||
|
|
||||||
client.ExecuteAndValidate(request);
|
_httpClient.Post(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValidationFailure Test(TelegramSettings settings)
|
public ValidationFailure Test(TelegramSettings settings)
|
||||||
|
@ -62,7 +61,7 @@ namespace NzbDrone.Core.Notifications.Telegram
|
||||||
{
|
{
|
||||||
return new ValidationFailure("Connection", $"{webException.Status.ToString()}: {webException.Message}");
|
return new ValidationFailure("Connection", $"{webException.Status.ToString()}: {webException.Message}");
|
||||||
}
|
}
|
||||||
else if (ex is RestException restException && restException.Response.StatusCode == HttpStatusCode.BadRequest)
|
else if (ex is Common.Http.HttpException restException && restException.Response.StatusCode == HttpStatusCode.BadRequest)
|
||||||
{
|
{
|
||||||
var error = Json.Deserialize<TelegramError>(restException.Response.Content);
|
var error = Json.Deserialize<TelegramError>(restException.Response.Content);
|
||||||
var property = error.Description.ContainsIgnoreCase("chat not found") ? "ChatId" : "BotToken";
|
var property = error.Description.ContainsIgnoreCase("chat not found") ? "ChatId" : "BotToken";
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Core.Rest;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Webhook
|
namespace NzbDrone.Core.Notifications.Webhook
|
||||||
{
|
{
|
||||||
|
@ -38,7 +37,7 @@ namespace NzbDrone.Core.Notifications.Webhook
|
||||||
|
|
||||||
_httpClient.Execute(request);
|
_httpClient.Execute(request);
|
||||||
}
|
}
|
||||||
catch (RestException ex)
|
catch (HttpException ex)
|
||||||
{
|
{
|
||||||
throw new WebhookException("Unable to post to webhook: {0}", ex, ex.Message);
|
throw new WebhookException("Unable to post to webhook: {0}", ex, ex.Message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Core.Notifications.Xbmc.Model;
|
using NzbDrone.Core.Notifications.Xbmc.Model;
|
||||||
using NzbDrone.Core.Rest;
|
|
||||||
using RestSharp;
|
|
||||||
using RestSharp.Authenticators;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Xbmc
|
namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
{
|
{
|
||||||
|
@ -21,87 +19,66 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
|
|
||||||
public class XbmcJsonApiProxy : IXbmcJsonApiProxy
|
public class XbmcJsonApiProxy : IXbmcJsonApiProxy
|
||||||
{
|
{
|
||||||
private readonly IRestClientFactory _restClientFactory;
|
private readonly IHttpClient _httpClient;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public XbmcJsonApiProxy(IRestClientFactory restClientFactory, Logger logger)
|
public XbmcJsonApiProxy(IHttpClient httpClient, Logger logger)
|
||||||
{
|
{
|
||||||
_restClientFactory = restClientFactory;
|
_httpClient = httpClient;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetJsonVersion(XbmcSettings settings)
|
public string GetJsonVersion(XbmcSettings settings)
|
||||||
{
|
{
|
||||||
var request = new RestRequest();
|
return ProcessRequest(settings, "JSONRPC.Version");
|
||||||
return ProcessRequest(request, settings, "JSONRPC.Version");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Notify(XbmcSettings settings, string title, string message)
|
public void Notify(XbmcSettings settings, string title, string message)
|
||||||
{
|
{
|
||||||
var request = new RestRequest();
|
ProcessRequest(settings, "GUI.ShowNotification", title, message, "https://raw.github.com/Lidarr/Lidarr/develop/Logo/64.png", settings.DisplayTime * 1000);
|
||||||
|
|
||||||
var parameters = new Dictionary<string, object>();
|
|
||||||
parameters.Add("title", title);
|
|
||||||
parameters.Add("message", message);
|
|
||||||
parameters.Add("image", "https://raw.github.com/Lidarr/Lidarr/develop/Logo/64.png");
|
|
||||||
parameters.Add("displaytime", settings.DisplayTime * 1000);
|
|
||||||
|
|
||||||
ProcessRequest(request, settings, "GUI.ShowNotification", parameters);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string UpdateLibrary(XbmcSettings settings, string path)
|
public string UpdateLibrary(XbmcSettings settings, string path)
|
||||||
{
|
{
|
||||||
var request = new RestRequest();
|
var response = ProcessRequest(settings, "AudioLibrary.Scan", path);
|
||||||
var parameters = new Dictionary<string, object>();
|
|
||||||
parameters.Add("directory", path);
|
|
||||||
|
|
||||||
if (path.IsNullOrWhiteSpace())
|
|
||||||
{
|
|
||||||
parameters = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var response = ProcessRequest(request, settings, "AudioLibrary.Scan", parameters);
|
|
||||||
|
|
||||||
return Json.Deserialize<XbmcJsonResult<string>>(response).Result;
|
return Json.Deserialize<XbmcJsonResult<string>>(response).Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CleanLibrary(XbmcSettings settings)
|
public void CleanLibrary(XbmcSettings settings)
|
||||||
{
|
{
|
||||||
var request = new RestRequest();
|
ProcessRequest(settings, "AudioLibrary.Clean");
|
||||||
|
|
||||||
ProcessRequest(request, settings, "AudioLibrary.Clean");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ActivePlayer> GetActivePlayers(XbmcSettings settings)
|
public List<ActivePlayer> GetActivePlayers(XbmcSettings settings)
|
||||||
{
|
{
|
||||||
var request = new RestRequest();
|
var response = ProcessRequest(settings, "Player.GetActivePlayers");
|
||||||
|
|
||||||
var response = ProcessRequest(request, settings, "Player.GetActivePlayers");
|
|
||||||
|
|
||||||
return Json.Deserialize<ActivePlayersResult>(response).Result;
|
return Json.Deserialize<ActivePlayersResult>(response).Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<KodiArtist> GetArtist(XbmcSettings settings)
|
public List<KodiArtist> GetArtist(XbmcSettings settings)
|
||||||
{
|
{
|
||||||
var request = new RestRequest();
|
var response = ProcessRequest(settings, "AudioLibrary.GetArtists", new[] { "properties", "musicbrainzartistid" });
|
||||||
var parameters = new Dictionary<string, object>();
|
|
||||||
parameters.Add("properties", new[] { "musicbrainzartistid" }); //TODO: Figure out why AudioLibrary doesnt list file location like videoLibray
|
|
||||||
|
|
||||||
var response = ProcessRequest(request, settings, "AudioLibrary.GetArtists", parameters);
|
|
||||||
|
|
||||||
return Json.Deserialize<ArtistResponse>(response).Result.Artists;
|
return Json.Deserialize<ArtistResponse>(response).Result.Artists;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ProcessRequest(IRestRequest request, XbmcSettings settings, string method, Dictionary<string, object> parameters = null)
|
private string ProcessRequest(XbmcSettings settings, string method, params object[] parameters)
|
||||||
{
|
{
|
||||||
var client = BuildClient(settings);
|
var url = string.Format(@"http://{0}/jsonrpc", settings.Address);
|
||||||
|
var requestBuilder = new JsonRpcRequestBuilder(url, method, parameters);
|
||||||
|
|
||||||
request.Method = Method.POST;
|
requestBuilder.LogResponseContent = true;
|
||||||
request.RequestFormat = DataFormat.Json;
|
|
||||||
request.JsonSerializer = new JsonNetSerializer();
|
|
||||||
request.AddBody(new { jsonrpc = "2.0", method = method, id = 10, @params = parameters });
|
|
||||||
|
|
||||||
var response = client.ExecuteAndValidate(request);
|
var request = requestBuilder.Build();
|
||||||
|
|
||||||
|
if (!settings.Username.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
request.AddBasicAuthentication(settings.Username, settings.Password);
|
||||||
|
}
|
||||||
|
|
||||||
|
var response = _httpClient.Execute(request);
|
||||||
_logger.Trace("Response: {0}", response.Content);
|
_logger.Trace("Response: {0}", response.Content);
|
||||||
|
|
||||||
CheckForError(response);
|
CheckForError(response);
|
||||||
|
@ -109,20 +86,7 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
return response.Content;
|
return response.Content;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IRestClient BuildClient(XbmcSettings settings)
|
private void CheckForError(HttpResponse response)
|
||||||
{
|
|
||||||
var url = string.Format(@"http://{0}/jsonrpc", settings.Address);
|
|
||||||
var client = _restClientFactory.BuildClient(url);
|
|
||||||
|
|
||||||
if (!settings.Username.IsNullOrWhiteSpace())
|
|
||||||
{
|
|
||||||
client.Authenticator = new HttpBasicAuthenticator(settings.Username, settings.Password);
|
|
||||||
}
|
|
||||||
|
|
||||||
return client;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CheckForError(IRestResponse response)
|
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(response.Content))
|
if (string.IsNullOrWhiteSpace(response.Content))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
using RestSharp;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Rest
|
|
||||||
{
|
|
||||||
public interface IRestClientFactory
|
|
||||||
{
|
|
||||||
RestClient BuildClient(string baseUrl);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
using NzbDrone.Common.Serializer;
|
|
||||||
using RestSharp.Serializers;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Rest
|
|
||||||
{
|
|
||||||
public class JsonNetSerializer : ISerializer
|
|
||||||
{
|
|
||||||
public JsonNetSerializer()
|
|
||||||
{
|
|
||||||
ContentType = "application/json";
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Serialize(object obj)
|
|
||||||
{
|
|
||||||
return obj.ToJson();
|
|
||||||
}
|
|
||||||
|
|
||||||
public string RootElement { get; set; }
|
|
||||||
public string Namespace { get; set; }
|
|
||||||
public string DateFormat { get; set; }
|
|
||||||
public string ContentType { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
|
||||||
using NzbDrone.Common.Http.Proxy;
|
|
||||||
using RestSharp;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Rest
|
|
||||||
{
|
|
||||||
public class RestClientFactory : IRestClientFactory
|
|
||||||
{
|
|
||||||
private readonly IHttpProxySettingsProvider _httpProxySettingsProvider;
|
|
||||||
private readonly ICreateManagedWebProxy _createManagedWebProxy;
|
|
||||||
|
|
||||||
public RestClientFactory(IHttpProxySettingsProvider httpProxySettingsProvider, ICreateManagedWebProxy createManagedWebProxy)
|
|
||||||
{
|
|
||||||
_httpProxySettingsProvider = httpProxySettingsProvider;
|
|
||||||
_createManagedWebProxy = createManagedWebProxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RestClient BuildClient(string baseUrl)
|
|
||||||
{
|
|
||||||
var restClient = new RestClient(baseUrl)
|
|
||||||
{
|
|
||||||
UserAgent = $"{BuildInfo.AppName}/{BuildInfo.Version} ({OsInfo.Os})"
|
|
||||||
};
|
|
||||||
|
|
||||||
var proxySettings = _httpProxySettingsProvider.GetProxySettings();
|
|
||||||
if (proxySettings != null)
|
|
||||||
{
|
|
||||||
restClient.Proxy = _createManagedWebProxy.GetWebProxy(proxySettings);
|
|
||||||
}
|
|
||||||
|
|
||||||
return restClient;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
using System;
|
|
||||||
using RestSharp;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Rest
|
|
||||||
{
|
|
||||||
public class RestException : Exception
|
|
||||||
{
|
|
||||||
public IRestResponse Response { get; private set; }
|
|
||||||
|
|
||||||
public RestException(IRestResponse response, IRestClient restClient)
|
|
||||||
: base(string.Format("REST request failed: [{0}] [{1}] at [{2}]", (int)response.StatusCode, response.Request.Method, restClient.BuildUri(response.Request)))
|
|
||||||
{
|
|
||||||
Response = response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
if (Response != null)
|
|
||||||
{
|
|
||||||
return base.ToString() + Environment.NewLine + Response.Content;
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,101 +0,0 @@
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using NLog;
|
|
||||||
using NzbDrone.Common.EnsureThat;
|
|
||||||
using NzbDrone.Common.Instrumentation;
|
|
||||||
using NzbDrone.Common.Serializer;
|
|
||||||
using RestSharp;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Rest
|
|
||||||
{
|
|
||||||
public static class RestSharpExtensions
|
|
||||||
{
|
|
||||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(RestSharpExtensions));
|
|
||||||
|
|
||||||
public static IRestResponse ValidateResponse(this IRestResponse response, IRestClient restClient)
|
|
||||||
{
|
|
||||||
Ensure.That(response, () => response).IsNotNull();
|
|
||||||
|
|
||||||
if (response.Request == null && response.ErrorException != null)
|
|
||||||
{
|
|
||||||
throw response.ErrorException;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ensure.That(response.Request, () => response.Request).IsNotNull();
|
|
||||||
Ensure.That(restClient, () => restClient).IsNotNull();
|
|
||||||
|
|
||||||
Logger.Debug("Validating Responses from [{0}] [{1}] status: [{2}]", response.Request.Method, restClient.BuildUri(response.Request), response.StatusCode);
|
|
||||||
|
|
||||||
if (response.ResponseUri == null)
|
|
||||||
{
|
|
||||||
Logger.Error(response.ErrorException, "Error communicating with server");
|
|
||||||
throw response.ErrorException;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (response.StatusCode)
|
|
||||||
{
|
|
||||||
case HttpStatusCode.OK:
|
|
||||||
{
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
case HttpStatusCode.NoContent:
|
|
||||||
{
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
case HttpStatusCode.Created:
|
|
||||||
{
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
Logger.Warn("[{0}] [{1}] Failed. [{2}]", response.Request.Method, response.ResponseUri.ToString(), response.StatusCode);
|
|
||||||
throw new RestException(response, restClient);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static T Read<T>(this IRestResponse restResponse, IRestClient restClient)
|
|
||||||
where T : class, new()
|
|
||||||
{
|
|
||||||
restResponse.ValidateResponse(restClient);
|
|
||||||
|
|
||||||
if (restResponse.Content != null)
|
|
||||||
{
|
|
||||||
Logger.Trace("Response: " + restResponse.Content);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Json.Deserialize<T>(restResponse.Content);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static T ExecuteAndValidate<T>(this IRestClient client, IRestRequest request)
|
|
||||||
where T : class, new()
|
|
||||||
{
|
|
||||||
return client.Execute(request).Read<T>(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IRestResponse ExecuteAndValidate(this IRestClient client, IRestRequest request)
|
|
||||||
{
|
|
||||||
return client.Execute(request).ValidateResponse(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void AddQueryString(this IRestRequest request, string name, object value)
|
|
||||||
{
|
|
||||||
request.AddParameter(name, value.ToString(), ParameterType.GetOrPost);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static object GetHeaderValue(this IRestResponse response, string key)
|
|
||||||
{
|
|
||||||
var header = response.Headers.FirstOrDefault(v => v.Name == key);
|
|
||||||
|
|
||||||
if (header == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return header.Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue