From 6af1ffba50a6f567ccddf966278ee00a328e7319 Mon Sep 17 00:00:00 2001 From: Qstick Date: Sat, 28 Oct 2017 17:38:57 -0400 Subject: [PATCH] New: Webhook improvements --- .../Notifications/Webhook/Webhook.cs | 92 ++++++++++++-- .../Notifications/Webhook/WebhookArtist.cs | 4 +- .../Webhook/WebhookGrabPayload.cs | 10 ++ .../Webhook/WebhookImportPayload.cs | 11 ++ .../Notifications/Webhook/WebhookMethod.cs | 10 +- .../Notifications/Webhook/WebhookPayload.cs | 3 - .../Notifications/Webhook/WebhookProxy.cs | 41 +++++++ .../Notifications/Webhook/WebhookRelease.cs | 27 ++++ .../Notifications/Webhook/WebhookService.cs | 116 ------------------ .../Notifications/Webhook/WebhookTrack.cs | 26 ++++ .../Notifications/Webhook/WebhookTrackFile.cs | 28 +++++ src/NzbDrone.Core/NzbDrone.Core.csproj | 7 +- 12 files changed, 241 insertions(+), 134 deletions(-) create mode 100644 src/NzbDrone.Core/Notifications/Webhook/WebhookGrabPayload.cs create mode 100644 src/NzbDrone.Core/Notifications/Webhook/WebhookImportPayload.cs create mode 100644 src/NzbDrone.Core/Notifications/Webhook/WebhookProxy.cs create mode 100644 src/NzbDrone.Core/Notifications/Webhook/WebhookRelease.cs delete mode 100644 src/NzbDrone.Core/Notifications/Webhook/WebhookService.cs create mode 100644 src/NzbDrone.Core/Notifications/Webhook/WebhookTrack.cs create mode 100644 src/NzbDrone.Core/Notifications/Webhook/WebhookTrackFile.cs diff --git a/src/NzbDrone.Core/Notifications/Webhook/Webhook.cs b/src/NzbDrone.Core/Notifications/Webhook/Webhook.cs index 969519bbb..252503071 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/Webhook.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/Webhook.cs @@ -1,35 +1,78 @@ - using System.Collections.Generic; +using System.Linq; using FluentValidation.Results; using NzbDrone.Core.Music; using NzbDrone.Common.Extensions; +using NzbDrone.Core.Validation; namespace NzbDrone.Core.Notifications.Webhook { public class Webhook : NotificationBase { - private readonly IWebhookService _service; + private readonly IWebhookProxy _proxy; - public Webhook(IWebhookService service) + public Webhook(IWebhookProxy proxy) { - _service = service; + _proxy = proxy; } public override string Link => "https://github.com/Lidarr/Lidarr/wiki/Webhook"; public override void OnGrab(GrabMessage message) { - _service.OnGrab(message.Artist, message.Album, message.Quality, Settings); + var remoteAlbum = message.Album; + var quality = message.Quality; + + var payload = new WebhookGrabPayload + + { + EventType = "Grab", + Artist = new WebhookArtist(message.Artist), + Albums = remoteAlbum.Albums.ConvertAll(x => new WebhookAlbum(x) + { + // TODO: Stop passing these parameters inside an album v3 + Quality = quality.Quality.Name, + QualityVersion = quality.Revision.Version, + ReleaseGroup = remoteAlbum.ParsedAlbumInfo.ReleaseGroup + }), + Release = new WebhookRelease(quality, remoteAlbum) + }; + + _proxy.SendWebhook(payload, Settings); } public override void OnDownload(DownloadMessage message) { - _service.OnDownload(message.Artist, message.TrackFile, Settings); + var trackFile = message.TrackFile; + + var payload = new WebhookImportPayload + + { + EventType = "Download", + Artist = new WebhookArtist(message.Artist), + Tracks = trackFile.Tracks.Value.ConvertAll(x => new WebhookTrack(x) + { + // TODO: Stop passing these parameters inside an episode v3 + Quality = trackFile.Quality.Quality.Name, + QualityVersion = trackFile.Quality.Revision.Version, + ReleaseGroup = trackFile.ReleaseGroup + }), + TrackFile = new WebhookTrackFile(trackFile), + IsUpgrade = message.OldFiles.Any() + }; + + _proxy.SendWebhook(payload, Settings); } public override void OnRename(Artist artist) { - _service.OnRename(artist, Settings); + var payload = new WebhookPayload + { + EventType = "Rename", + Artist = new WebhookArtist(artist) + }; + + _proxy.SendWebhook(payload, Settings); } public override string Name => "Webhook"; @@ -38,9 +81,42 @@ namespace NzbDrone.Core.Notifications.Webhook { var failures = new List(); - failures.AddIfNotNull(_service.Test(Settings)); + failures.AddIfNotNull(SendWebhookTest()); return new ValidationResult(failures); } + + private ValidationFailure SendWebhookTest() + { + try + { + var payload = new WebhookGrabPayload + { + EventType = "Test", + Artist = new WebhookArtist() + { + Id = 1, + Name = "Test Name", + Path = "C:\\testpath", + MBId = "aaaaa-aaa-aaaa-aaaaaa" + }, + Albums = new List() { + new WebhookAlbum() + { + Id = 123, + Title = "Test title" + } + } + }; + + _proxy.SendWebhook(payload, Settings); + } + catch (WebhookException ex) + { + return new NzbDroneValidationFailure("Url", ex.Message); + } + + return null; + } } } diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookArtist.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookArtist.cs index 45f92c142..5a699d26d 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookArtist.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookArtist.cs @@ -5,7 +5,7 @@ namespace NzbDrone.Core.Notifications.Webhook public class WebhookArtist { public int Id { get; set; } - public string Title { get; set; } + public string Name { get; set; } public string Path { get; set; } public string MBId { get; set; } @@ -14,7 +14,7 @@ namespace NzbDrone.Core.Notifications.Webhook public WebhookArtist(Artist artist) { Id = artist.Id; - Title = artist.Name; + Name = artist.Name; Path = artist.Path; MBId = artist.ForeignArtistId; } diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookGrabPayload.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookGrabPayload.cs new file mode 100644 index 000000000..4cb7c868b --- /dev/null +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookGrabPayload.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace NzbDrone.Core.Notifications.Webhook +{ + public class WebhookGrabPayload : WebhookPayload + { + public List Albums { get; set; } + public WebhookRelease Release { get; set; } + } +} diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookImportPayload.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookImportPayload.cs new file mode 100644 index 000000000..d3cfd0ed3 --- /dev/null +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookImportPayload.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace NzbDrone.Core.Notifications.Webhook +{ + public class WebhookImportPayload : WebhookPayload + { + public List Tracks { get; set; } + public WebhookTrackFile TrackFile { get; set; } + public bool IsUpgrade { get; set; } + } +} diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookMethod.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookMethod.cs index 42c080e00..5d6e859a6 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookMethod.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookMethod.cs @@ -1,8 +1,10 @@ -namespace NzbDrone.Core.Notifications.Webhook +using NzbDrone.Common.Http; + +namespace NzbDrone.Core.Notifications.Webhook { public enum WebhookMethod { - POST = RestSharp.Method.POST, - PUT = RestSharp.Method.PUT + POST = HttpMethod.POST, + PUT = HttpMethod.PUT } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookPayload.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookPayload.cs index f480c185d..3beff4105 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookPayload.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookPayload.cs @@ -1,11 +1,8 @@ -using System.Collections.Generic; - namespace NzbDrone.Core.Notifications.Webhook { public class WebhookPayload { public string EventType { get; set; } public WebhookArtist Artist { get; set; } - public List Albums { get; set; } } } diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookProxy.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookProxy.cs new file mode 100644 index 000000000..050c5527f --- /dev/null +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookProxy.cs @@ -0,0 +1,41 @@ +using NzbDrone.Common.Http; +using NzbDrone.Common.Serializer; +using NzbDrone.Core.Rest; + +namespace NzbDrone.Core.Notifications.Webhook +{ + public interface IWebhookProxy + { + void SendWebhook(WebhookPayload payload, WebhookSettings settings); + } + + public class WebhookProxy : IWebhookProxy + { + private readonly IHttpClient _httpClient; + + public WebhookProxy(IHttpClient httpClient) + { + _httpClient = httpClient; + } + + public void SendWebhook(WebhookPayload body, WebhookSettings settings) + { + try + { + var request = new HttpRequestBuilder(settings.Url) + .Accept(HttpAccept.Json) + .Build(); + + request.Method = (HttpMethod)settings.Method; + request.Headers.ContentType = "application/json"; + request.SetContent(body.ToJson()); + + _httpClient.Execute(request); + } + catch (RestException ex) + { + throw new WebhookException("Unable to post to webhook: {0}", ex, ex.Message); + } + } + } +} diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookRelease.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookRelease.cs new file mode 100644 index 000000000..60ff931da --- /dev/null +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookRelease.cs @@ -0,0 +1,27 @@ +using NzbDrone.Core.Parser.Model; +using NzbDrone.Core.Qualities; + +namespace NzbDrone.Core.Notifications.Webhook +{ + public class WebhookRelease + { + public WebhookRelease() { } + + public WebhookRelease(QualityModel quality, RemoteAlbum remoteAlbum) + { + Quality = quality.Quality.Name; + QualityVersion = quality.Revision.Version; + ReleaseGroup = remoteAlbum.ParsedAlbumInfo.ReleaseGroup; + ReleaseTitle = remoteAlbum.Release.Title; + Indexer = remoteAlbum.Release.Indexer; + Size = remoteAlbum.Release.Size; + } + + public string Quality { get; set; } + public int QualityVersion { get; set; } + public string ReleaseGroup { get; set; } + public string ReleaseTitle { get; set; } + public string Indexer { get; set; } + public long Size { get; set; } + } +} diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookService.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookService.cs deleted file mode 100644 index 41654297c..000000000 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookService.cs +++ /dev/null @@ -1,116 +0,0 @@ -using FluentValidation.Results; -using NzbDrone.Core.MediaFiles; -using NzbDrone.Core.Music; -using NzbDrone.Core.Validation; -using NzbDrone.Core.Rest; -using RestSharp; -using NzbDrone.Core.Qualities; -using NzbDrone.Core.Parser.Model; -using System.Collections.Generic; - -namespace NzbDrone.Core.Notifications.Webhook -{ - public interface IWebhookService - { - void OnDownload(Artist artist, TrackFile trackFile, WebhookSettings settings); - void OnRename(Artist artist, WebhookSettings settings); - void OnGrab(Artist artist, RemoteAlbum album, QualityModel quality, WebhookSettings settings); - ValidationFailure Test(WebhookSettings settings); - } - - public class WebhookService : IWebhookService - { - public void OnDownload(Artist artist, TrackFile trackFile, WebhookSettings settings) - { - var payload = new WebhookPayload - { - EventType = "Download", - Artist = new WebhookArtist(artist), - Albums = trackFile.Tracks.Value.ConvertAll(x => new WebhookAlbum(x.Album) { - Quality = trackFile.Quality.Quality.Name, - QualityVersion = trackFile.Quality.Revision.Version, - ReleaseGroup = trackFile.ReleaseGroup, - SceneName = trackFile.SceneName - }) - }; - - NotifyWebhook(payload, settings); - } - - public void OnRename(Artist artist, WebhookSettings settings) - { - var payload = new WebhookPayload - { - EventType = "Rename", - Artist = new WebhookArtist(artist) - }; - - NotifyWebhook(payload, settings); - } - - public void OnGrab(Artist artist, RemoteAlbum album, QualityModel quality, WebhookSettings settings) - { - var payload = new WebhookPayload - { - EventType = "Grab", - Artist = new WebhookArtist(artist), - Albums = album.Albums.ConvertAll(x => new WebhookAlbum(x) - { - Quality = quality.Quality.Name, - QualityVersion = quality.Revision.Version, - ReleaseGroup = album.ParsedAlbumInfo.ReleaseGroup - }) - }; - NotifyWebhook(payload, settings); - } - - public void NotifyWebhook(WebhookPayload body, WebhookSettings settings) - { - try { - var client = RestClientFactory.BuildClient(settings.Url); - var request = new RestRequest((Method) settings.Method); - request.RequestFormat = DataFormat.Json; - request.AddBody(body); - client.ExecuteAndValidate(request); - } - catch (RestException ex) - { - throw new WebhookException("Unable to post to webhook: {0}", ex, ex.Message); - } - } - - public ValidationFailure Test(WebhookSettings settings) - { - try - { - NotifyWebhook( - new WebhookPayload - { - EventType = "Test", - Artist = new WebhookArtist() - { - Id = 1, - Title = "Test Title", - Path = "C:\\testpath", - MBId = "1234" - }, - Albums = new List() { - new WebhookAlbum() - { - Id = 123, - Title = "Test title" - } - } - }, - settings - ); - } - catch (WebhookException ex) - { - return new NzbDroneValidationFailure("Url", ex.Message); - } - - return null; - } - } -} diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookTrack.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookTrack.cs new file mode 100644 index 000000000..3d03fda2c --- /dev/null +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookTrack.cs @@ -0,0 +1,26 @@ +using NzbDrone.Core.Music; +using System; + +namespace NzbDrone.Core.Notifications.Webhook +{ + public class WebhookTrack + { + public WebhookTrack() { } + + public WebhookTrack(Track track) + { + Id = track.Id; + Title = track.Title; + TrackNumber = track.TrackNumber; + + } + + public int Id { get; set; } + public string Title { get; set; } + public int TrackNumber { get; set; } + + public string Quality { get; set; } + public int QualityVersion { get; set; } + public string ReleaseGroup { get; set; } + } +} diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookTrackFile.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookTrackFile.cs new file mode 100644 index 000000000..a51bd520a --- /dev/null +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookTrackFile.cs @@ -0,0 +1,28 @@ +using NzbDrone.Core.MediaFiles; + +namespace NzbDrone.Core.Notifications.Webhook +{ + public class WebhookTrackFile + { + public WebhookTrackFile() { } + + public WebhookTrackFile(TrackFile trackFile) + { + Id = trackFile.Id; + RelativePath = trackFile.RelativePath; + Path = trackFile.Path; + Quality = trackFile.Quality.Quality.Name; + QualityVersion = trackFile.Quality.Revision.Version; + ReleaseGroup = trackFile.ReleaseGroup; + SceneName = trackFile.SceneName; + } + + public int Id { get; set; } + public string RelativePath { get; set; } + public string Path { get; set; } + public string Quality { get; set; } + public int QualityVersion { get; set; } + public string ReleaseGroup { get; set; } + public string SceneName { get; set; } + } +} diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index f1fd4c39b..1f88164de 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -816,12 +816,17 @@ + + - + + + +