Convert Notifications from RestSharp to HttpClient

pull/4304/head
Qstick 5 years ago
parent 39250abf7d
commit 4abf44617c

@ -1,10 +1,9 @@
using System; using System;
using System.Net; 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://raw.githubusercontent.com/Radarr/Radarr/develop/Logo/64.png"); .AddFormParameter("notification[icon_url]", "https://raw.githubusercontent.com/Radarr/Radarr/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);

@ -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/Radarr/Radarr/develop/Logo/256.png"); // Use the Radarr logo. .AddQueryParam("icon", "https://cdn.rawgit.com/Radarr/Radarr/develop/Logo/256.png") // Use the Radarr logo.
request.AddParameter("smallicon", "https://cdn.rawgit.com/Radarr/Radarr/develop/Logo/96-Outline-White.png"); // 96x96px with outline at 88x88px on a transparent background. .AddQueryParam("smallicon", "https://cdn.rawgit.com/Radarr/Radarr/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)

@ -2,8 +2,8 @@ using System;
using System.Net; using System.Net;
using FluentValidation.Results; using FluentValidation.Results;
using NLog; using NLog;
using NzbDrone.Common.Http;
using NzbDrone.Core.Movies; using NzbDrone.Core.Movies;
using NzbDrone.Core.Rest;
namespace NzbDrone.Core.Notifications.Emby namespace NzbDrone.Core.Notifications.Emby
{ {
@ -43,7 +43,7 @@ namespace NzbDrone.Core.Notifications.Emby
Notify(settings, "Test from Radarr", "Success! MediaBrowser has been successfully configured!"); Notify(settings, "Test from Radarr", "Success! MediaBrowser has been successfully configured!");
} }
catch (RestException ex) catch (HttpException ex)
{ {
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized) if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
{ {

@ -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.Prowl namespace NzbDrone.Core.Notifications.Prowl
{ {
@ -17,12 +16,12 @@ namespace NzbDrone.Core.Notifications.Prowl
public class ProwlProxy : IProwlProxy public class ProwlProxy : IProwlProxy
{ {
private const string PUSH_URL = "https://api.prowlapp.com/publicapi/add"; private const string PUSH_URL = "https://api.prowlapp.com/publicapi/add";
private readonly IRestClientFactory _restClientFactory; private readonly IHttpClient _httpClient;
private readonly Logger _logger; private readonly Logger _logger;
public ProwlProxy(IRestClientFactory restClientFactory, Logger logger) public ProwlProxy(IHttpClient httpClient, Logger logger)
{ {
_restClientFactory = restClientFactory; _httpClient = httpClient;
_logger = logger; _logger = logger;
} }
@ -30,19 +29,20 @@ namespace NzbDrone.Core.Notifications.Prowl
{ {
try try
{ {
var client = _restClientFactory.BuildClient(PUSH_URL); var requestBuilder = new HttpRequestBuilder(PUSH_URL);
var request = new RestRequest(Method.POST);
request.AddParameter("apikey", apiKey); var request = requestBuilder.Post()
request.AddParameter("application", BuildInfo.AppName); .AddFormParameter("apikey", apiKey)
request.AddParameter("event", title); .AddFormParameter("application", BuildInfo.AppName)
request.AddParameter("description", message); .AddFormParameter("event", title)
request.AddParameter("priority", priority); .AddFormParameter("description", message)
request.AddParameter("url", url); .AddFormParameter("priority", priority)
.AddFormParameter("url", url)
.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)
{ {
@ -52,6 +52,10 @@ namespace NzbDrone.Core.Notifications.Prowl
throw new ProwlException("Unable to send text message: " + ex.Message, 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) public ValidationFailure Test(ProwlSettings settings)

@ -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)

@ -1,8 +1,7 @@
using NLog; 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);

@ -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,16 +31,16 @@ 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)
.Build();
client.ExecuteAndValidate(request); _httpClient.Post(request);
} }
public ValidationFailure Test(TelegramSettings settings) public ValidationFailure Test(TelegramSettings settings)
@ -61,7 +60,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,108 +19,74 @@ 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/Radarr/Radarr/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/Radarr/Radarr/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, "VideoLibrary.Scan", path);
var parameters = new Dictionary<string, object>();
parameters.Add("directory", path);
if (path.IsNullOrWhiteSpace())
{
parameters = null;
}
var response = ProcessRequest(request, settings, "VideoLibrary.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, "VideoLibrary.Clean");
ProcessRequest(request, settings, "VideoLibrary.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<XbmcMovie> GetMovies(XbmcSettings settings) public List<XbmcMovie> GetMovies(XbmcSettings settings)
{ {
var request = new RestRequest(); var response = ProcessRequest(settings, "VideoLibrary.GetMovies", new[] { "file", "imdbnumber" });
var parameters = new Dictionary<string, object>();
parameters.Add("properties", new[] { "file", "imdbnumber" });
var response = ProcessRequest(request, settings, "VideoLibrary.GetMovies", parameters);
return Json.Deserialize<MovieResponse>(response).Result.Movies; return Json.Deserialize<MovieResponse>(response).Result.Movies;
} }
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;
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);
_logger.Trace("Response: {0}", response.Content);
CheckForError(response);
return response.Content; requestBuilder.LogResponseContent = true;
}
private IRestClient BuildClient(XbmcSettings settings) var request = requestBuilder.Build();
{
var url = string.Format(@"http://{0}/jsonrpc", settings.Address);
var client = _restClientFactory.BuildClient(url);
if (!settings.Username.IsNullOrWhiteSpace()) if (!settings.Username.IsNullOrWhiteSpace())
{ {
client.Authenticator = new HttpBasicAuthenticator(settings.Username, settings.Password); request.AddBasicAuthentication(settings.Username, settings.Password);
} }
return client; var response = _httpClient.Execute(request);
_logger.Trace("Response: {0}", response.Content);
CheckForError(response);
return response.Content;
} }
private void CheckForError(IRestResponse response) private void CheckForError(HttpResponse response)
{ {
if (string.IsNullOrWhiteSpace(response.Content)) if (string.IsNullOrWhiteSpace(response.Content))
{ {

@ -13,7 +13,6 @@
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-beta0007" /> <PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-beta0007" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NLog" Version="4.7.0" /> <PackageReference Include="NLog" Version="4.7.0" />
<PackageReference Include="RestSharp" Version="106.10.1" />
<PackageReference Include="TinyTwitter" Version="1.1.2" /> <PackageReference Include="TinyTwitter" Version="1.1.2" />
<PackageReference Include="Kveer.XmlRPC" Version="1.1.1" /> <PackageReference Include="Kveer.XmlRPC" Version="1.1.1" />
<PackageReference Include="System.Data.SQLite.Core.Lidarr" Version="1.0.111.0-5" /> <PackageReference Include="System.Data.SQLite.Core.Lidarr" Version="1.0.111.0-5" />

@ -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…
Cancel
Save