From 2ebf89a6ab70a91727e67520eb7831af9b3888cc Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 19 Jul 2024 18:46:09 +0300 Subject: [PATCH] Fixed: Sending Manual Interaction Required notifications for unknown series For Discord/Slack/Webhooks/CustomScript --- .../CustomScript/CustomScript.cs | 29 ++-- .../Notifications/Discord/Discord.cs | 60 +++++--- .../Notifications/Slack/Slack.cs | 140 +++++++++--------- .../Notifications/Webhook/WebhookBase.cs | 14 +- 4 files changed, 135 insertions(+), 108 deletions(-) diff --git a/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs b/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs index f1b344101..c5e2e2146 100644 --- a/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs +++ b/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs @@ -406,18 +406,18 @@ namespace NzbDrone.Core.Notifications.CustomScript environmentVariables.Add("Sonarr_EventType", "ManualInteractionRequired"); environmentVariables.Add("Sonarr_InstanceName", _configFileProvider.InstanceName); environmentVariables.Add("Sonarr_ApplicationUrl", _configService.ApplicationUrl); - environmentVariables.Add("Sonarr_Series_Id", series.Id.ToString()); - environmentVariables.Add("Sonarr_Series_Title", series.Title); - environmentVariables.Add("Sonarr_Series_TitleSlug", series.TitleSlug); - environmentVariables.Add("Sonarr_Series_Path", series.Path); - environmentVariables.Add("Sonarr_Series_TvdbId", series.TvdbId.ToString()); - environmentVariables.Add("Sonarr_Series_TvMazeId", series.TvMazeId.ToString()); - environmentVariables.Add("Sonarr_Series_TmdbId", series.TmdbId.ToString()); - environmentVariables.Add("Sonarr_Series_ImdbId", series.ImdbId ?? string.Empty); - environmentVariables.Add("Sonarr_Series_Type", series.SeriesType.ToString()); - environmentVariables.Add("Sonarr_Series_Year", series.Year.ToString()); - environmentVariables.Add("Sonarr_Series_OriginalLanguage", IsoLanguages.Get(series.OriginalLanguage).ThreeLetterCode); - environmentVariables.Add("Sonarr_Series_Genres", string.Join("|", series.Genres)); + environmentVariables.Add("Sonarr_Series_Id", series?.Id.ToString()); + environmentVariables.Add("Sonarr_Series_Title", series?.Title); + environmentVariables.Add("Sonarr_Series_TitleSlug", series?.TitleSlug); + environmentVariables.Add("Sonarr_Series_Path", series?.Path); + environmentVariables.Add("Sonarr_Series_TvdbId", series?.TvdbId.ToString()); + environmentVariables.Add("Sonarr_Series_TvMazeId", series?.TvMazeId.ToString()); + environmentVariables.Add("Sonarr_Series_TmdbId", series?.TmdbId.ToString()); + environmentVariables.Add("Sonarr_Series_ImdbId", series?.ImdbId ?? string.Empty); + environmentVariables.Add("Sonarr_Series_Type", series?.SeriesType.ToString()); + environmentVariables.Add("Sonarr_Series_Year", series?.Year.ToString()); + environmentVariables.Add("Sonarr_Series_OriginalLanguage", IsoLanguages.Get(series?.OriginalLanguage)?.ThreeLetterCode); + environmentVariables.Add("Sonarr_Series_Genres", string.Join("|", series?.Genres ?? new List())); environmentVariables.Add("Sonarr_Series_Tags", string.Join("|", GetTagLabels(series))); environmentVariables.Add("Sonarr_Download_Client", message.DownloadClientInfo?.Name ?? string.Empty); environmentVariables.Add("Sonarr_Download_Client_Type", message.DownloadClientInfo?.Type ?? string.Empty); @@ -482,6 +482,11 @@ namespace NzbDrone.Core.Notifications.CustomScript private List GetTagLabels(Series series) { + if (series == null) + { + return null; + } + return _tagRepository.GetTags(series.Tags) .Select(s => s.Label) .Where(l => l.IsNotNullOrWhiteSpace()) diff --git a/src/NzbDrone.Core/Notifications/Discord/Discord.cs b/src/NzbDrone.Core/Notifications/Discord/Discord.cs index 8ef8dbf62..08d21ca0c 100644 --- a/src/NzbDrone.Core/Notifications/Discord/Discord.cs +++ b/src/NzbDrone.Core/Notifications/Discord/Discord.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using FluentValidation.Results; using NzbDrone.Common.Extensions; @@ -329,12 +330,12 @@ namespace NzbDrone.Core.Notifications.Discord public override void OnRename(Series series, List renamedFiles) { var attachments = new List - { - new Embed - { - Title = series.Title, - } - }; + { + new () + { + Title = series.Title, + } + }; var payload = CreatePayload("Renamed", attachments); @@ -361,8 +362,8 @@ namespace NzbDrone.Core.Notifications.Discord Color = (int)DiscordColors.Danger, Fields = new List { - new DiscordField { Name = "Reason", Value = reason.ToString() }, - new DiscordField { Name = "File name", Value = string.Format("```{0}```", deletedFile) } + new () { Name = "Reason", Value = reason.ToString() }, + new () { Name = "File name", Value = string.Format("```{0}```", deletedFile) } }, Timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"), }; @@ -386,7 +387,7 @@ namespace NzbDrone.Core.Notifications.Discord Title = series.Title, Description = "Series Added", Color = (int)DiscordColors.Success, - Fields = new List { new DiscordField { Name = "Links", Value = GetLinksString(series) } } + Fields = new List { new () { Name = "Links", Value = GetLinksString(series) } } }; if (Settings.ImportFields.Contains((int)DiscordImportFieldType.Poster)) @@ -425,7 +426,7 @@ namespace NzbDrone.Core.Notifications.Discord Title = series.Title, Description = deleteMessage.DeletedFilesMessage, Color = (int)DiscordColors.Danger, - Fields = new List { new DiscordField { Name = "Links", Value = GetLinksString(series) } } + Fields = new List { new () { Name = "Links", Value = GetLinksString(series) } } }; if (Settings.ImportFields.Contains((int)DiscordImportFieldType.Poster)) @@ -503,12 +504,12 @@ namespace NzbDrone.Core.Notifications.Discord Color = (int)DiscordColors.Standard, Fields = new List() { - new DiscordField() + new () { Name = "Previous Version", Value = updateMessage.PreviousVersion.ToString() }, - new DiscordField() + new () { Name = "New Version", Value = updateMessage.NewVersion.ToString() @@ -533,7 +534,7 @@ namespace NzbDrone.Core.Notifications.Discord Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author, IconUrl = "https://raw.githubusercontent.com/Sonarr/Sonarr/develop/Logo/256.png" }, - Url = $"http://thetvdb.com/?tab=series&id={series.TvdbId}", + Url = series?.TvdbId > 0 ? $"http://thetvdb.com/?tab=series&id={series.TvdbId}" : null, Description = "Manual interaction needed", Title = GetTitle(series, episodes), Color = (int)DiscordColors.Standard, @@ -545,7 +546,7 @@ namespace NzbDrone.Core.Notifications.Discord { embed.Thumbnail = new DiscordImage { - Url = series.Images.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Poster)?.Url + Url = series?.Images?.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Poster)?.Url }; } @@ -553,7 +554,7 @@ namespace NzbDrone.Core.Notifications.Discord { embed.Image = new DiscordImage { - Url = series.Images.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Fanart)?.Url + Url = series?.Images?.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Fanart)?.Url }; } @@ -564,26 +565,26 @@ namespace NzbDrone.Core.Notifications.Discord switch ((DiscordManualInteractionFieldType)field) { case DiscordManualInteractionFieldType.Overview: - var overview = episodes.First().Overview ?? ""; + var overview = episodes.FirstOrDefault()?.Overview ?? ""; discordField.Name = "Overview"; discordField.Value = overview.Length <= 300 ? overview : $"{overview.AsSpan(0, 300)}..."; break; case DiscordManualInteractionFieldType.Rating: discordField.Name = "Rating"; - discordField.Value = episodes.First().Ratings.Value.ToString(); + discordField.Value = episodes.FirstOrDefault()?.Ratings?.Value.ToString(CultureInfo.InvariantCulture); break; case DiscordManualInteractionFieldType.Genres: discordField.Name = "Genres"; - discordField.Value = series.Genres.Take(5).Join(", "); + discordField.Value = series?.Genres.Take(5).Join(", "); break; case DiscordManualInteractionFieldType.Quality: discordField.Name = "Quality"; discordField.Inline = true; - discordField.Value = message.Quality.Quality.Name; + discordField.Value = message.Quality?.Quality?.Name; break; case DiscordManualInteractionFieldType.Group: discordField.Name = "Group"; - discordField.Value = message.Episode.ParsedEpisodeInfo.ReleaseGroup; + discordField.Value = message.Episode?.ParsedEpisodeInfo?.ReleaseGroup; break; case DiscordManualInteractionFieldType.Size: discordField.Name = "Size"; @@ -592,7 +593,7 @@ namespace NzbDrone.Core.Notifications.Discord break; case DiscordManualInteractionFieldType.DownloadTitle: discordField.Name = "Download"; - discordField.Value = string.Format("```{0}```", message.TrackedDownload.DownloadItem.Title); + discordField.Value = $"```{message.TrackedDownload.DownloadItem.Title}```"; break; case DiscordManualInteractionFieldType.Links: discordField.Name = "Links"; @@ -677,10 +678,16 @@ namespace NzbDrone.Core.Notifications.Discord private string GetLinksString(Series series) { - var links = new List(); + if (series == null) + { + return null; + } - links.Add($"[The TVDB](https://thetvdb.com/?tab=series&id={series.TvdbId})"); - links.Add($"[Trakt](https://trakt.tv/search/tvdb/{series.TvdbId}?id_type=show)"); + var links = new List + { + $"[The TVDB](https://thetvdb.com/?tab=series&id={series.TvdbId})", + $"[Trakt](https://trakt.tv/search/tvdb/{series.TvdbId}?id_type=show)" + }; if (series.ImdbId.IsNotNullOrWhiteSpace()) { @@ -692,6 +699,11 @@ namespace NzbDrone.Core.Notifications.Discord private string GetTitle(Series series, List episodes) { + if (series == null) + { + return null; + } + if (series.SeriesType == SeriesTypes.Daily) { var episode = episodes.First(); diff --git a/src/NzbDrone.Core/Notifications/Slack/Slack.cs b/src/NzbDrone.Core/Notifications/Slack/Slack.cs index eb6bfb636..814b57305 100644 --- a/src/NzbDrone.Core/Notifications/Slack/Slack.cs +++ b/src/NzbDrone.Core/Notifications/Slack/Slack.cs @@ -28,15 +28,15 @@ namespace NzbDrone.Core.Notifications.Slack public override void OnGrab(GrabMessage message) { var attachments = new List - { - new Attachment - { - Fallback = message.Message, - Title = message.Series.Title, - Text = message.Message, - Color = "warning" - } - }; + { + new () + { + Fallback = message.Message, + Title = message.Series.Title, + Text = message.Message, + Color = "warning" + } + }; var payload = CreatePayload($"Grabbed: {message.Message}", attachments); _proxy.SendPayload(payload, Settings); @@ -45,15 +45,15 @@ namespace NzbDrone.Core.Notifications.Slack public override void OnDownload(DownloadMessage message) { var attachments = new List - { - new Attachment - { - Fallback = message.Message, - Title = message.Series.Title, - Text = message.Message, - Color = "good" - } - }; + { + new () + { + Fallback = message.Message, + Title = message.Series.Title, + Text = message.Message, + Color = "good" + } + }; var payload = CreatePayload($"Imported: {message.Message}", attachments); _proxy.SendPayload(payload, Settings); @@ -63,7 +63,7 @@ namespace NzbDrone.Core.Notifications.Slack { var attachments = new List { - new Attachment + new () { Fallback = message.Message, Title = message.Series.Title, @@ -79,12 +79,12 @@ namespace NzbDrone.Core.Notifications.Slack public override void OnRename(Series series, List renamedFiles) { var attachments = new List - { - new Attachment - { - Title = series.Title, - } - }; + { + new () + { + Title = series.Title, + } + }; var payload = CreatePayload("Renamed", attachments); @@ -94,12 +94,12 @@ namespace NzbDrone.Core.Notifications.Slack public override void OnEpisodeFileDelete(EpisodeDeleteMessage deleteMessage) { var attachments = new List - { - new Attachment - { - Title = GetTitle(deleteMessage.Series, deleteMessage.EpisodeFile.Episodes), - } - }; + { + new () + { + Title = GetTitle(deleteMessage.Series, deleteMessage.EpisodeFile.Episodes), + } + }; var payload = CreatePayload("Episode Deleted", attachments); @@ -109,12 +109,12 @@ namespace NzbDrone.Core.Notifications.Slack public override void OnSeriesAdd(SeriesAddMessage message) { var attachments = new List - { - new Attachment - { - Title = message.Series.Title, - } - }; + { + new () + { + Title = message.Series.Title, + } + }; var payload = CreatePayload("Series Added", attachments); @@ -124,13 +124,13 @@ namespace NzbDrone.Core.Notifications.Slack public override void OnSeriesDelete(SeriesDeleteMessage deleteMessage) { var attachments = new List - { - new Attachment - { - Title = deleteMessage.Series.Title, - Text = deleteMessage.DeletedFilesMessage - } - }; + { + new () + { + Title = deleteMessage.Series.Title, + Text = deleteMessage.DeletedFilesMessage + } + }; var payload = CreatePayload("Series Deleted", attachments); @@ -140,14 +140,14 @@ namespace NzbDrone.Core.Notifications.Slack public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { var attachments = new List - { - new Attachment - { - Title = healthCheck.Source.Name, - Text = healthCheck.Message, - Color = healthCheck.Type == HealthCheck.HealthCheckResult.Warning ? "warning" : "danger" - } - }; + { + new () + { + Title = healthCheck.Source.Name, + Text = healthCheck.Message, + Color = healthCheck.Type == HealthCheck.HealthCheckResult.Warning ? "warning" : "danger" + } + }; var payload = CreatePayload("Health Issue", attachments); @@ -157,14 +157,14 @@ namespace NzbDrone.Core.Notifications.Slack public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck) { var attachments = new List - { - new Attachment - { - Title = previousCheck.Source.Name, - Text = $"The following issue is now resolved: {previousCheck.Message}", - Color = "good" - } - }; + { + new () + { + Title = previousCheck.Source.Name, + Text = $"The following issue is now resolved: {previousCheck.Message}", + Color = "good" + } + }; var payload = CreatePayload("Health Issue Resolved", attachments); @@ -174,14 +174,14 @@ namespace NzbDrone.Core.Notifications.Slack public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage) { var attachments = new List - { - new Attachment - { - Title = Environment.MachineName, - Text = updateMessage.Message, - Color = "good" - } - }; + { + new () + { + Title = Environment.MachineName, + Text = updateMessage.Message, + Color = "good" + } + }; var payload = CreatePayload("Application Updated", attachments); @@ -192,9 +192,9 @@ namespace NzbDrone.Core.Notifications.Slack { var attachments = new List { - new Attachment + new () { - Title = Environment.MachineName, + Title = GetTitle(message.Series, message.Episode.Episodes), Text = message.Message, Color = "warning" } diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs index 558a6114f..71fe1bff0 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs @@ -229,9 +229,9 @@ namespace NzbDrone.Core.Notifications.Webhook TvdbId = 1234, Tags = new List { "test-tag" } }, - Episodes = new List() + Episodes = new List { - new WebhookEpisode() + new () { Id = 123, EpisodeNumber = 1, @@ -244,6 +244,11 @@ namespace NzbDrone.Core.Notifications.Webhook private WebhookSeries GetSeries(Series series) { + if (series == null) + { + return null; + } + _mediaCoverService.ConvertToLocalUrls(series.Id, series.Images); return new WebhookSeries(series, GetTagLabels(series)); @@ -251,6 +256,11 @@ namespace NzbDrone.Core.Notifications.Webhook private List GetTagLabels(Series series) { + if (series == null) + { + return null; + } + return _tagRepository.GetTags(series.Tags) .Select(s => s.Label) .Where(l => l.IsNotNullOrWhiteSpace())