New: On Health Restored notification

(cherry picked from commit 5fdc8514da7c7ad98192f2ecb2415b3a7b5d0d05)

Closes #3631
Closes #3637
pull/3148/head
The Dark 1 year ago committed by Bogdan
parent 42ed5f4c4a
commit 5b701aafc1

@ -62,6 +62,7 @@ class Notification extends Component {
onAlbumDelete, onAlbumDelete,
onArtistDelete, onArtistDelete,
onHealthIssue, onHealthIssue,
onHealthRestored,
onDownloadFailure, onDownloadFailure,
onImportFailure, onImportFailure,
onTrackRetag, onTrackRetag,
@ -73,6 +74,7 @@ class Notification extends Component {
supportsOnAlbumDelete, supportsOnAlbumDelete,
supportsOnArtistDelete, supportsOnArtistDelete,
supportsOnHealthIssue, supportsOnHealthIssue,
supportsOnHealthRestored,
supportsOnDownloadFailure, supportsOnDownloadFailure,
supportsOnImportFailure, supportsOnImportFailure,
supportsOnTrackRetag, supportsOnTrackRetag,
@ -145,6 +147,14 @@ class Notification extends Component {
</Label> </Label>
} }
{
supportsOnHealthRestored && onHealthRestored ?
<Label kind={kinds.SUCCESS}>
{translate('OnHealthRestored')}
</Label> :
null
}
{ {
supportsOnDownloadFailure && onDownloadFailure && supportsOnDownloadFailure && onDownloadFailure &&
<Label kind={kinds.SUCCESS} > <Label kind={kinds.SUCCESS} >
@ -168,12 +178,12 @@ class Notification extends Component {
{ {
!onGrab && !onReleaseImport && !onRename && !onTrackRetag && !onAlbumDelete && !onArtistDelete && !onGrab && !onReleaseImport && !onRename && !onTrackRetag && !onAlbumDelete && !onArtistDelete &&
!onHealthIssue && !onDownloadFailure && !onImportFailure && !onApplicationUpdate && !onHealthIssue && !onHealthRestored && !onDownloadFailure && !onImportFailure && !onApplicationUpdate &&
<Label <Label
kind={kinds.DISABLED} kind={kinds.DISABLED}
outline={true} outline={true}
> >
Disabled {translate('Disabled')}
</Label> </Label>
} }
@ -208,6 +218,7 @@ Notification.propTypes = {
onAlbumDelete: PropTypes.bool.isRequired, onAlbumDelete: PropTypes.bool.isRequired,
onArtistDelete: PropTypes.bool.isRequired, onArtistDelete: PropTypes.bool.isRequired,
onHealthIssue: PropTypes.bool.isRequired, onHealthIssue: PropTypes.bool.isRequired,
onHealthRestored: PropTypes.bool.isRequired,
onDownloadFailure: PropTypes.bool.isRequired, onDownloadFailure: PropTypes.bool.isRequired,
onImportFailure: PropTypes.bool.isRequired, onImportFailure: PropTypes.bool.isRequired,
onTrackRetag: PropTypes.bool.isRequired, onTrackRetag: PropTypes.bool.isRequired,
@ -219,6 +230,7 @@ Notification.propTypes = {
supportsOnAlbumDelete: PropTypes.bool.isRequired, supportsOnAlbumDelete: PropTypes.bool.isRequired,
supportsOnArtistDelete: PropTypes.bool.isRequired, supportsOnArtistDelete: PropTypes.bool.isRequired,
supportsOnHealthIssue: PropTypes.bool.isRequired, supportsOnHealthIssue: PropTypes.bool.isRequired,
supportsOnHealthRestored: PropTypes.bool.isRequired,
supportsOnDownloadFailure: PropTypes.bool.isRequired, supportsOnDownloadFailure: PropTypes.bool.isRequired,
supportsOnImportFailure: PropTypes.bool.isRequired, supportsOnImportFailure: PropTypes.bool.isRequired,
supportsOnTrackRetag: PropTypes.bool.isRequired, supportsOnTrackRetag: PropTypes.bool.isRequired,

@ -22,6 +22,7 @@ function NotificationEventItems(props) {
onAlbumDelete, onAlbumDelete,
onArtistDelete, onArtistDelete,
onHealthIssue, onHealthIssue,
onHealthRestored,
onDownloadFailure, onDownloadFailure,
onImportFailure, onImportFailure,
onTrackRetag, onTrackRetag,
@ -33,6 +34,7 @@ function NotificationEventItems(props) {
supportsOnAlbumDelete, supportsOnAlbumDelete,
supportsOnArtistDelete, supportsOnArtistDelete,
supportsOnHealthIssue, supportsOnHealthIssue,
supportsOnHealthRestored,
includeHealthWarnings, includeHealthWarnings,
supportsOnDownloadFailure, supportsOnDownloadFailure,
supportsOnImportFailure, supportsOnImportFailure,
@ -175,8 +177,19 @@ function NotificationEventItems(props) {
/> />
</div> </div>
<div>
<FormInputGroup
type={inputTypes.CHECK}
name="onHealthRestored"
helpText={translate('OnHealthRestoredHelpText')}
isDisabled={!supportsOnHealthRestored.value}
{...onHealthRestored}
onChange={onInputChange}
/>
</div>
{ {
onHealthIssue.value && (onHealthIssue.value || onHealthRestored.value) &&
<div> <div>
<FormInputGroup <FormInputGroup
type={inputTypes.CHECK} type={inputTypes.CHECK}

@ -12,6 +12,7 @@ namespace Lidarr.Api.V1.Notifications
public bool OnAlbumDelete { get; set; } public bool OnAlbumDelete { get; set; }
public bool OnArtistDelete { get; set; } public bool OnArtistDelete { get; set; }
public bool OnHealthIssue { get; set; } public bool OnHealthIssue { get; set; }
public bool OnHealthRestored { get; set; }
public bool OnDownloadFailure { get; set; } public bool OnDownloadFailure { get; set; }
public bool OnImportFailure { get; set; } public bool OnImportFailure { get; set; }
public bool OnTrackRetag { get; set; } public bool OnTrackRetag { get; set; }
@ -23,6 +24,7 @@ namespace Lidarr.Api.V1.Notifications
public bool SupportsOnAlbumDelete { get; set; } public bool SupportsOnAlbumDelete { get; set; }
public bool SupportsOnArtistDelete { get; set; } public bool SupportsOnArtistDelete { get; set; }
public bool SupportsOnHealthIssue { get; set; } public bool SupportsOnHealthIssue { get; set; }
public bool SupportsOnHealthRestored { get; set; }
public bool IncludeHealthWarnings { get; set; } public bool IncludeHealthWarnings { get; set; }
public bool SupportsOnDownloadFailure { get; set; } public bool SupportsOnDownloadFailure { get; set; }
public bool SupportsOnImportFailure { get; set; } public bool SupportsOnImportFailure { get; set; }
@ -49,6 +51,7 @@ namespace Lidarr.Api.V1.Notifications
resource.OnAlbumDelete = definition.OnAlbumDelete; resource.OnAlbumDelete = definition.OnAlbumDelete;
resource.OnArtistDelete = definition.OnArtistDelete; resource.OnArtistDelete = definition.OnArtistDelete;
resource.OnHealthIssue = definition.OnHealthIssue; resource.OnHealthIssue = definition.OnHealthIssue;
resource.OnHealthRestored = definition.OnHealthRestored;
resource.OnDownloadFailure = definition.OnDownloadFailure; resource.OnDownloadFailure = definition.OnDownloadFailure;
resource.OnImportFailure = definition.OnImportFailure; resource.OnImportFailure = definition.OnImportFailure;
resource.OnTrackRetag = definition.OnTrackRetag; resource.OnTrackRetag = definition.OnTrackRetag;
@ -60,6 +63,7 @@ namespace Lidarr.Api.V1.Notifications
resource.SupportsOnAlbumDelete = definition.SupportsOnAlbumDelete; resource.SupportsOnAlbumDelete = definition.SupportsOnAlbumDelete;
resource.SupportsOnArtistDelete = definition.SupportsOnArtistDelete; resource.SupportsOnArtistDelete = definition.SupportsOnArtistDelete;
resource.SupportsOnHealthIssue = definition.SupportsOnHealthIssue; resource.SupportsOnHealthIssue = definition.SupportsOnHealthIssue;
resource.SupportsOnHealthRestored = definition.SupportsOnHealthRestored;
resource.IncludeHealthWarnings = definition.IncludeHealthWarnings; resource.IncludeHealthWarnings = definition.IncludeHealthWarnings;
resource.SupportsOnDownloadFailure = definition.SupportsOnDownloadFailure; resource.SupportsOnDownloadFailure = definition.SupportsOnDownloadFailure;
resource.SupportsOnImportFailure = definition.SupportsOnImportFailure; resource.SupportsOnImportFailure = definition.SupportsOnImportFailure;
@ -85,6 +89,7 @@ namespace Lidarr.Api.V1.Notifications
definition.OnAlbumDelete = resource.OnAlbumDelete; definition.OnAlbumDelete = resource.OnAlbumDelete;
definition.OnArtistDelete = resource.OnArtistDelete; definition.OnArtistDelete = resource.OnArtistDelete;
definition.OnHealthIssue = resource.OnHealthIssue; definition.OnHealthIssue = resource.OnHealthIssue;
definition.OnHealthRestored = resource.OnHealthRestored;
definition.OnDownloadFailure = resource.OnDownloadFailure; definition.OnDownloadFailure = resource.OnDownloadFailure;
definition.OnImportFailure = resource.OnImportFailure; definition.OnImportFailure = resource.OnImportFailure;
definition.OnTrackRetag = resource.OnTrackRetag; definition.OnTrackRetag = resource.OnTrackRetag;
@ -96,6 +101,7 @@ namespace Lidarr.Api.V1.Notifications
definition.SupportsOnAlbumDelete = resource.SupportsOnAlbumDelete; definition.SupportsOnAlbumDelete = resource.SupportsOnAlbumDelete;
definition.SupportsOnArtistDelete = resource.SupportsOnArtistDelete; definition.SupportsOnArtistDelete = resource.SupportsOnArtistDelete;
definition.SupportsOnHealthIssue = resource.SupportsOnHealthIssue; definition.SupportsOnHealthIssue = resource.SupportsOnHealthIssue;
definition.SupportsOnHealthRestored = resource.SupportsOnHealthRestored;
definition.IncludeHealthWarnings = resource.IncludeHealthWarnings; definition.IncludeHealthWarnings = resource.IncludeHealthWarnings;
definition.SupportsOnDownloadFailure = resource.SupportsOnDownloadFailure; definition.SupportsOnDownloadFailure = resource.SupportsOnDownloadFailure;
definition.SupportsOnImportFailure = resource.SupportsOnImportFailure; definition.SupportsOnImportFailure = resource.SupportsOnImportFailure;

@ -79,6 +79,11 @@ namespace NzbDrone.Core.Test.NotificationTests
TestLogger.Info("OnHealthIssue was called"); TestLogger.Info("OnHealthIssue was called");
} }
public override void OnHealthRestored(Core.HealthCheck.HealthCheck healthCheck)
{
TestLogger.Info("OnHealthRestored was called");
}
public override void OnDownloadFailure(DownloadFailedMessage message) public override void OnDownloadFailure(DownloadFailedMessage message)
{ {
TestLogger.Info("OnDownloadFailure was called"); TestLogger.Info("OnDownloadFailure was called");
@ -133,6 +138,7 @@ namespace NzbDrone.Core.Test.NotificationTests
notification.SupportsOnUpgrade.Should().BeTrue(); notification.SupportsOnUpgrade.Should().BeTrue();
notification.SupportsOnRename.Should().BeTrue(); notification.SupportsOnRename.Should().BeTrue();
notification.SupportsOnHealthIssue.Should().BeTrue(); notification.SupportsOnHealthIssue.Should().BeTrue();
notification.SupportsOnHealthRestored.Should().BeTrue();
notification.SupportsOnDownloadFailure.Should().BeTrue(); notification.SupportsOnDownloadFailure.Should().BeTrue();
notification.SupportsOnImportFailure.Should().BeTrue(); notification.SupportsOnImportFailure.Should().BeTrue();
notification.SupportsOnTrackRetag.Should().BeTrue(); notification.SupportsOnTrackRetag.Should().BeTrue();
@ -151,6 +157,7 @@ namespace NzbDrone.Core.Test.NotificationTests
notification.SupportsOnUpgrade.Should().BeFalse(); notification.SupportsOnUpgrade.Should().BeFalse();
notification.SupportsOnRename.Should().BeFalse(); notification.SupportsOnRename.Should().BeFalse();
notification.SupportsOnHealthIssue.Should().BeFalse(); notification.SupportsOnHealthIssue.Should().BeFalse();
notification.SupportsOnHealthRestored.Should().BeFalse();
notification.SupportsOnDownloadFailure.Should().BeFalse(); notification.SupportsOnDownloadFailure.Should().BeFalse();
notification.SupportsOnImportFailure.Should().BeFalse(); notification.SupportsOnImportFailure.Should().BeFalse();
notification.SupportsOnTrackRetag.Should().BeFalse(); notification.SupportsOnTrackRetag.Should().BeFalse();

@ -0,0 +1,14 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(065)]
public class health_restored_notification : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("Notifications").AddColumn("OnHealthRestored").AsBoolean().WithDefaultValue(false);
}
}
}

@ -87,6 +87,7 @@ namespace NzbDrone.Core.Datastore
.Ignore(i => i.SupportsOnAlbumDelete) .Ignore(i => i.SupportsOnAlbumDelete)
.Ignore(i => i.SupportsOnArtistDelete) .Ignore(i => i.SupportsOnArtistDelete)
.Ignore(i => i.SupportsOnHealthIssue) .Ignore(i => i.SupportsOnHealthIssue)
.Ignore(i => i.SupportsOnHealthRestored)
.Ignore(i => i.SupportsOnDownloadFailure) .Ignore(i => i.SupportsOnDownloadFailure)
.Ignore(i => i.SupportsOnImportFailure) .Ignore(i => i.SupportsOnImportFailure)
.Ignore(i => i.SupportsOnTrackRetag) .Ignore(i => i.SupportsOnTrackRetag)

@ -0,0 +1,16 @@
using NzbDrone.Common.Messaging;
namespace NzbDrone.Core.HealthCheck
{
public class HealthCheckRestoredEvent : IEvent
{
public HealthCheck PreviousCheck { get; private set; }
public bool IsInStartupGracePeriod { get; private set; }
public HealthCheckRestoredEvent(HealthCheck previousCheck, bool isInStartupGracePeriod)
{
PreviousCheck = previousCheck;
IsInStartupGracePeriod = isInStartupGracePeriod;
}
}
}

@ -102,6 +102,13 @@ namespace NzbDrone.Core.HealthCheck
{ {
if (result.Type == HealthCheckResult.Ok) if (result.Type == HealthCheckResult.Ok)
{ {
var previous = _healthCheckResults.Find(result.Source.Name);
if (previous != null)
{
_eventAggregator.PublishEvent(new HealthCheckRestoredEvent(previous, !_hasRunHealthChecksAfterGracePeriod));
}
_healthCheckResults.Remove(result.Source.Name); _healthCheckResults.Remove(result.Source.Name);
} }
else else

@ -230,6 +230,7 @@
"DetailedProgressBar": "Detailed Progress Bar", "DetailedProgressBar": "Detailed Progress Bar",
"DetailedProgressBarHelpText": "Show text on progess bar", "DetailedProgressBarHelpText": "Show text on progess bar",
"Details": "Details", "Details": "Details",
"Disabled": "Disabled",
"Disambiguation": "Disambiguation", "Disambiguation": "Disambiguation",
"DiscCount": "Disc Count", "DiscCount": "Disc Count",
"DiscNumber": "Disc Number", "DiscNumber": "Disc Number",
@ -568,6 +569,8 @@
"OnGrabHelpText": "On Grab", "OnGrabHelpText": "On Grab",
"OnHealthIssue": "On Health Issue", "OnHealthIssue": "On Health Issue",
"OnHealthIssueHelpText": "On Health Issue", "OnHealthIssueHelpText": "On Health Issue",
"OnHealthRestored": "On Health Restored",
"OnHealthRestoredHelpText": "On Health Restored",
"OnImportFailure": "On Import Failure", "OnImportFailure": "On Import Failure",
"OnImportFailureHelpText": "On Import Failure", "OnImportFailureHelpText": "On Import Failure",
"OnReleaseImport": "On Release Import", "OnReleaseImport": "On Release Import",

@ -42,6 +42,11 @@ namespace NzbDrone.Core.Notifications.Apprise
_proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings); _proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{
_proxy.SendNotification(HEALTH_RESTORED_TITLE, $"The following issue is now resolved: {previousCheck.Message}", Settings);
}
public override void OnDownloadFailure(DownloadFailedMessage message) public override void OnDownloadFailure(DownloadFailedMessage message)
{ {
_proxy.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, Settings); _proxy.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, Settings);

@ -41,6 +41,11 @@ namespace NzbDrone.Core.Notifications.Boxcar
_proxy.SendNotification(HEALTH_ISSUE_TITLE, message.Message, Settings); _proxy.SendNotification(HEALTH_ISSUE_TITLE, message.Message, Settings);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{
_proxy.SendNotification(HEALTH_RESTORED_TITLE, $"The following issue is now resolved: {previousCheck.Message}", Settings);
}
public override void OnDownloadFailure(DownloadFailedMessage message) public override void OnDownloadFailure(DownloadFailedMessage message)
{ {
_proxy.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, Settings); _proxy.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, Settings);

@ -229,6 +229,21 @@ namespace NzbDrone.Core.Notifications.CustomScript
ExecuteScript(environmentVariables); ExecuteScript(environmentVariables);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{
var environmentVariables = new StringDictionary();
environmentVariables.Add("Lidarr_EventType", "HealthRestored");
environmentVariables.Add("Lidarr_InstanceName", _configFileProvider.InstanceName);
environmentVariables.Add("Lidarr_ApplicationUrl", _configService.ApplicationUrl);
environmentVariables.Add("Lidarr_Health_Restored_Level", Enum.GetName(typeof(HealthCheckResult), previousCheck.Type));
environmentVariables.Add("Lidarr_Health_Restored_Message", previousCheck.Message);
environmentVariables.Add("Lidarr_Health_Restored_Type", previousCheck.Source.Name);
environmentVariables.Add("Lidarr_Health_Restored_Wiki", previousCheck.WikiUrl.ToString() ?? string.Empty);
ExecuteScript(environmentVariables);
}
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage) public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
{ {
var environmentVariables = new StringDictionary(); var environmentVariables = new StringDictionary();

@ -285,6 +285,29 @@ namespace NzbDrone.Core.Notifications.Discord
_proxy.SendPayload(payload, Settings); _proxy.SendPayload(payload, Settings);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{
var attachments = new List<Embed>
{
new Embed
{
Author = new DiscordAuthor
{
Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author,
IconUrl = "https://raw.githubusercontent.com/Lidarr/Lidarr/develop/Logo/256.png"
},
Title = "Health Issue Resolved: " + previousCheck.Source.Name,
Description = $"The following issue is now resolved: {previousCheck.Message}",
Timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"),
Color = (int)DiscordColors.Success
}
};
var payload = CreatePayload(null, attachments);
_proxy.SendPayload(payload, Settings);
}
public override void OnTrackRetag(TrackRetagMessage message) public override void OnTrackRetag(TrackRetagMessage message)
{ {
var attachments = new List<Embed> var attachments = new List<Embed>

@ -60,6 +60,11 @@ namespace NzbDrone.Core.Notifications.Email
SendEmail(Settings, HEALTH_ISSUE_TITLE_BRANDED, message.Message); SendEmail(Settings, HEALTH_ISSUE_TITLE_BRANDED, message.Message);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousMessage)
{
SendEmail(Settings, HEALTH_RESTORED_TITLE_BRANDED, $"The following issue is now resolved: {previousMessage.Message}");
}
public override void OnDownloadFailure(DownloadFailedMessage message) public override void OnDownloadFailure(DownloadFailedMessage message)
{ {
SendEmail(Settings, DOWNLOAD_FAILURE_TITLE_BRANDED, message.Message); SendEmail(Settings, DOWNLOAD_FAILURE_TITLE_BRANDED, message.Message);

@ -44,6 +44,11 @@ namespace NzbDrone.Core.Notifications.Gotify
_proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings); _proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{
_proxy.SendNotification(HEALTH_RESTORED_TITLE, $"The following issue is now resolved: {previousCheck.Message}", null);
}
public override void OnDownloadFailure(DownloadFailedMessage message) public override void OnDownloadFailure(DownloadFailedMessage message)
{ {
_proxy.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, Settings); _proxy.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, Settings);

@ -15,6 +15,7 @@ namespace NzbDrone.Core.Notifications
void OnAlbumDelete(AlbumDeleteMessage deleteMessage); void OnAlbumDelete(AlbumDeleteMessage deleteMessage);
void OnArtistDelete(ArtistDeleteMessage deleteMessage); void OnArtistDelete(ArtistDeleteMessage deleteMessage);
void OnHealthIssue(HealthCheck.HealthCheck healthCheck); void OnHealthIssue(HealthCheck.HealthCheck healthCheck);
void OnHealthRestored(HealthCheck.HealthCheck previousCheck);
void OnApplicationUpdate(ApplicationUpdateMessage updateMessage); void OnApplicationUpdate(ApplicationUpdateMessage updateMessage);
void OnDownloadFailure(DownloadFailedMessage message); void OnDownloadFailure(DownloadFailedMessage message);
void OnImportFailure(AlbumDownloadMessage message); void OnImportFailure(AlbumDownloadMessage message);
@ -27,6 +28,7 @@ namespace NzbDrone.Core.Notifications
bool SupportsOnAlbumDelete { get; } bool SupportsOnAlbumDelete { get; }
bool SupportsOnArtistDelete { get; } bool SupportsOnArtistDelete { get; }
bool SupportsOnHealthIssue { get; } bool SupportsOnHealthIssue { get; }
bool SupportsOnHealthRestored { get; }
bool SupportsOnApplicationUpdate { get; } bool SupportsOnApplicationUpdate { get; }
bool SupportsOnDownloadFailure { get; } bool SupportsOnDownloadFailure { get; }
bool SupportsOnImportFailure { get; } bool SupportsOnImportFailure { get; }

@ -42,6 +42,11 @@ namespace NzbDrone.Core.Notifications.Join
_proxy.SendNotification(HEALTH_ISSUE_TITLE_BRANDED, message.Message, Settings); _proxy.SendNotification(HEALTH_ISSUE_TITLE_BRANDED, message.Message, Settings);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousMessage)
{
_proxy.SendNotification(HEALTH_RESTORED_TITLE_BRANDED, $"The following issue is now resolved: {previousMessage.Message}", Settings);
}
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage) public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
{ {
_proxy.SendNotification(APPLICATION_UPDATE_TITLE_BRANDED, updateMessage.Message, Settings); _proxy.SendNotification(APPLICATION_UPDATE_TITLE_BRANDED, updateMessage.Message, Settings);

@ -44,6 +44,11 @@ namespace NzbDrone.Core.Notifications.Mailgun
_proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheckMessage.Message, Settings); _proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheckMessage.Message, Settings);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheckMessage)
{
_proxy.SendNotification(HEALTH_RESTORED_TITLE_BRANDED, $"The following issue is now resolved: {previousCheckMessage.Message}", Settings);
}
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage) public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
{ {
_proxy.SendNotification(APPLICATION_UPDATE_TITLE, updateMessage.Message, Settings); _proxy.SendNotification(APPLICATION_UPDATE_TITLE, updateMessage.Message, Settings);

@ -81,6 +81,14 @@ namespace NzbDrone.Core.Notifications.Emby
} }
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousMessage)
{
if (Settings.Notify)
{
_mediaBrowserService.Notify(Settings, HEALTH_RESTORED_TITLE_BRANDED, $"The following issue is now resolved: {previousMessage.Message}");
}
}
public override void OnTrackRetag(TrackRetagMessage message) public override void OnTrackRetag(TrackRetagMessage message)
{ {
if (Settings.Notify) if (Settings.Notify)

@ -67,6 +67,11 @@ namespace NzbDrone.Core.Notifications.Notifiarr
_proxy.SendNotification(BuildHealthPayload(healthCheck), Settings); _proxy.SendNotification(BuildHealthPayload(healthCheck), Settings);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{
_proxy.SendNotification(BuildHealthRestoredPayload(previousCheck), Settings);
}
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage) public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
{ {
_proxy.SendNotification(BuildApplicationUpdatePayload(updateMessage), Settings); _proxy.SendNotification(BuildApplicationUpdatePayload(updateMessage), Settings);

@ -15,6 +15,7 @@ namespace NzbDrone.Core.Notifications
protected const string ALBUM_DELETED_TITLE = "Album Deleted"; protected const string ALBUM_DELETED_TITLE = "Album Deleted";
protected const string ARTIST_DELETED_TITLE = "Artist Deleted"; protected const string ARTIST_DELETED_TITLE = "Artist Deleted";
protected const string HEALTH_ISSUE_TITLE = "Health Check Failure"; protected const string HEALTH_ISSUE_TITLE = "Health Check Failure";
protected const string HEALTH_RESTORED_TITLE = "Health Check Restored";
protected const string DOWNLOAD_FAILURE_TITLE = "Download Failed"; protected const string DOWNLOAD_FAILURE_TITLE = "Download Failed";
protected const string IMPORT_FAILURE_TITLE = "Import Failed"; protected const string IMPORT_FAILURE_TITLE = "Import Failed";
protected const string TRACK_RETAGGED_TITLE = "Track File Tags Updated"; protected const string TRACK_RETAGGED_TITLE = "Track File Tags Updated";
@ -25,6 +26,7 @@ namespace NzbDrone.Core.Notifications
protected const string ALBUM_DELETED_TITLE_BRANDED = "Lidarr - " + ALBUM_DELETED_TITLE; protected const string ALBUM_DELETED_TITLE_BRANDED = "Lidarr - " + ALBUM_DELETED_TITLE;
protected const string ARTIST_DELETED_TITLE_BRANDED = "Lidarr - " + ARTIST_DELETED_TITLE; protected const string ARTIST_DELETED_TITLE_BRANDED = "Lidarr - " + ARTIST_DELETED_TITLE;
protected const string HEALTH_ISSUE_TITLE_BRANDED = "Lidarr - " + HEALTH_ISSUE_TITLE; protected const string HEALTH_ISSUE_TITLE_BRANDED = "Lidarr - " + HEALTH_ISSUE_TITLE;
protected const string HEALTH_RESTORED_TITLE_BRANDED = "Lidarr - " + HEALTH_RESTORED_TITLE;
protected const string DOWNLOAD_FAILURE_TITLE_BRANDED = "Lidarr - " + DOWNLOAD_FAILURE_TITLE; protected const string DOWNLOAD_FAILURE_TITLE_BRANDED = "Lidarr - " + DOWNLOAD_FAILURE_TITLE;
protected const string IMPORT_FAILURE_TITLE_BRANDED = "Lidarr - " + IMPORT_FAILURE_TITLE; protected const string IMPORT_FAILURE_TITLE_BRANDED = "Lidarr - " + IMPORT_FAILURE_TITLE;
protected const string TRACK_RETAGGED_TITLE_BRANDED = "Lidarr - " + TRACK_RETAGGED_TITLE; protected const string TRACK_RETAGGED_TITLE_BRANDED = "Lidarr - " + TRACK_RETAGGED_TITLE;
@ -67,6 +69,10 @@ namespace NzbDrone.Core.Notifications
{ {
} }
public virtual void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{
}
public virtual void OnDownloadFailure(DownloadFailedMessage message) public virtual void OnDownloadFailure(DownloadFailedMessage message)
{ {
} }
@ -94,6 +100,7 @@ namespace NzbDrone.Core.Notifications
public bool SupportsOnAlbumDelete => HasConcreteImplementation("OnAlbumDelete"); public bool SupportsOnAlbumDelete => HasConcreteImplementation("OnAlbumDelete");
public bool SupportsOnArtistDelete => HasConcreteImplementation("OnArtistDelete"); public bool SupportsOnArtistDelete => HasConcreteImplementation("OnArtistDelete");
public bool SupportsOnHealthIssue => HasConcreteImplementation("OnHealthIssue"); public bool SupportsOnHealthIssue => HasConcreteImplementation("OnHealthIssue");
public bool SupportsOnHealthRestored => HasConcreteImplementation("OnHealthRestored");
public bool SupportsOnDownloadFailure => HasConcreteImplementation("OnDownloadFailure"); public bool SupportsOnDownloadFailure => HasConcreteImplementation("OnDownloadFailure");
public bool SupportsOnImportFailure => HasConcreteImplementation("OnImportFailure"); public bool SupportsOnImportFailure => HasConcreteImplementation("OnImportFailure");
public bool SupportsOnTrackRetag => HasConcreteImplementation("OnTrackRetag"); public bool SupportsOnTrackRetag => HasConcreteImplementation("OnTrackRetag");

@ -11,6 +11,7 @@ namespace NzbDrone.Core.Notifications
public bool OnAlbumDelete { get; set; } public bool OnAlbumDelete { get; set; }
public bool OnArtistDelete { get; set; } public bool OnArtistDelete { get; set; }
public bool OnHealthIssue { get; set; } public bool OnHealthIssue { get; set; }
public bool OnHealthRestored { get; set; }
public bool OnDownloadFailure { get; set; } public bool OnDownloadFailure { get; set; }
public bool OnImportFailure { get; set; } public bool OnImportFailure { get; set; }
public bool OnTrackRetag { get; set; } public bool OnTrackRetag { get; set; }
@ -22,12 +23,13 @@ namespace NzbDrone.Core.Notifications
public bool SupportsOnAlbumDelete { get; set; } public bool SupportsOnAlbumDelete { get; set; }
public bool SupportsOnArtistDelete { get; set; } public bool SupportsOnArtistDelete { get; set; }
public bool SupportsOnHealthIssue { get; set; } public bool SupportsOnHealthIssue { get; set; }
public bool SupportsOnHealthRestored { get; set; }
public bool IncludeHealthWarnings { get; set; } public bool IncludeHealthWarnings { get; set; }
public bool SupportsOnDownloadFailure { get; set; } public bool SupportsOnDownloadFailure { get; set; }
public bool SupportsOnImportFailure { get; set; } public bool SupportsOnImportFailure { get; set; }
public bool SupportsOnTrackRetag { get; set; } public bool SupportsOnTrackRetag { get; set; }
public bool SupportsOnApplicationUpdate { get; set; } public bool SupportsOnApplicationUpdate { get; set; }
public override bool Enable => OnGrab || OnReleaseImport || (OnReleaseImport && OnUpgrade) || OnAlbumDelete || OnArtistDelete || OnHealthIssue || OnDownloadFailure || OnImportFailure || OnTrackRetag || OnApplicationUpdate; public override bool Enable => OnGrab || OnReleaseImport || (OnReleaseImport && OnUpgrade) || OnAlbumDelete || OnArtistDelete || OnHealthIssue || OnHealthRestored || OnDownloadFailure || OnImportFailure || OnTrackRetag || OnApplicationUpdate;
} }
} }

@ -17,6 +17,7 @@ namespace NzbDrone.Core.Notifications
List<INotification> OnAlbumDeleteEnabled(); List<INotification> OnAlbumDeleteEnabled();
List<INotification> OnArtistDeleteEnabled(); List<INotification> OnArtistDeleteEnabled();
List<INotification> OnHealthIssueEnabled(); List<INotification> OnHealthIssueEnabled();
List<INotification> OnHealthRestoredEnabled();
List<INotification> OnDownloadFailureEnabled(); List<INotification> OnDownloadFailureEnabled();
List<INotification> OnImportFailureEnabled(); List<INotification> OnImportFailureEnabled();
List<INotification> OnTrackRetagEnabled(); List<INotification> OnTrackRetagEnabled();
@ -65,6 +66,11 @@ namespace NzbDrone.Core.Notifications
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnHealthIssue).ToList(); return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnHealthIssue).ToList();
} }
public List<INotification> OnHealthRestoredEnabled()
{
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnHealthRestored).ToList();
}
public List<INotification> OnDownloadFailureEnabled() public List<INotification> OnDownloadFailureEnabled()
{ {
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnDownloadFailure).ToList(); return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnDownloadFailure).ToList();
@ -96,6 +102,7 @@ namespace NzbDrone.Core.Notifications
definition.SupportsOnAlbumDelete = provider.SupportsOnAlbumDelete; definition.SupportsOnAlbumDelete = provider.SupportsOnAlbumDelete;
definition.SupportsOnArtistDelete = provider.SupportsOnArtistDelete; definition.SupportsOnArtistDelete = provider.SupportsOnArtistDelete;
definition.SupportsOnHealthIssue = provider.SupportsOnHealthIssue; definition.SupportsOnHealthIssue = provider.SupportsOnHealthIssue;
definition.SupportsOnHealthRestored = provider.SupportsOnHealthRestored;
definition.SupportsOnDownloadFailure = provider.SupportsOnDownloadFailure; definition.SupportsOnDownloadFailure = provider.SupportsOnDownloadFailure;
definition.SupportsOnImportFailure = provider.SupportsOnImportFailure; definition.SupportsOnImportFailure = provider.SupportsOnImportFailure;
definition.SupportsOnTrackRetag = provider.SupportsOnTrackRetag; definition.SupportsOnTrackRetag = provider.SupportsOnTrackRetag;

@ -23,6 +23,7 @@ namespace NzbDrone.Core.Notifications
IHandle<AlbumDeletedEvent>, IHandle<AlbumDeletedEvent>,
IHandle<ArtistsDeletedEvent>, IHandle<ArtistsDeletedEvent>,
IHandle<HealthCheckFailedEvent>, IHandle<HealthCheckFailedEvent>,
IHandle<HealthCheckRestoredEvent>,
IHandle<DownloadFailedEvent>, IHandle<DownloadFailedEvent>,
IHandle<AlbumImportIncompleteEvent>, IHandle<AlbumImportIncompleteEvent>,
IHandle<TrackFileRetaggedEvent>, IHandle<TrackFileRetaggedEvent>,
@ -273,6 +274,29 @@ namespace NzbDrone.Core.Notifications
} }
} }
public void Handle(HealthCheckRestoredEvent message)
{
if (message.IsInStartupGracePeriod)
{
return;
}
foreach (var notification in _notificationFactory.OnHealthRestoredEnabled())
{
try
{
if (ShouldHandleHealthFailure(message.PreviousCheck, ((NotificationDefinition)notification.Definition).IncludeHealthWarnings))
{
notification.OnHealthRestored(message.PreviousCheck);
}
}
catch (Exception ex)
{
_logger.Warn(ex, "Unable to send OnHealthRestored notification to: " + notification.Definition.Name);
}
}
}
public void Handle(DownloadFailedEvent message) public void Handle(DownloadFailedEvent message)
{ {
var downloadFailedMessage = new DownloadFailedMessage var downloadFailedMessage = new DownloadFailedMessage

@ -43,6 +43,11 @@ namespace NzbDrone.Core.Notifications.Ntfy
_proxy.SendNotification(HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message, Settings); _proxy.SendNotification(HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message, Settings);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{
_proxy.SendNotification(HEALTH_RESTORED_TITLE_BRANDED, $"The following issue is now resolved: {previousCheck.Message}", Settings);
}
public override void OnDownloadFailure(DownloadFailedMessage message) public override void OnDownloadFailure(DownloadFailedMessage message)
{ {
_proxy.SendNotification(DOWNLOAD_FAILURE_TITLE_BRANDED, message.Message, Settings); _proxy.SendNotification(DOWNLOAD_FAILURE_TITLE_BRANDED, message.Message, Settings);

@ -41,6 +41,11 @@ namespace NzbDrone.Core.Notifications.Prowl
_prowlProxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings); _prowlProxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousMessage)
{
_prowlProxy.SendNotification(HEALTH_RESTORED_TITLE, $"The following issue is now resolved: {previousMessage.Message}", Settings);
}
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage) public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
{ {
_prowlProxy.SendNotification(APPLICATION_UPDATE_TITLE, updateMessage.Message, Settings); _prowlProxy.SendNotification(APPLICATION_UPDATE_TITLE, updateMessage.Message, Settings);

@ -44,6 +44,11 @@ namespace NzbDrone.Core.Notifications.PushBullet
_proxy.SendNotification(HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message, Settings); _proxy.SendNotification(HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message, Settings);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{
_proxy.SendNotification(HEALTH_RESTORED_TITLE_BRANDED, $"The following issue is now resolved: {previousCheck.Message}", Settings);
}
public override void OnDownloadFailure(DownloadFailedMessage message) public override void OnDownloadFailure(DownloadFailedMessage message)
{ {
_proxy.SendNotification(DOWNLOAD_FAILURE_TITLE_BRANDED, message.Message, Settings); _proxy.SendNotification(DOWNLOAD_FAILURE_TITLE_BRANDED, message.Message, Settings);

@ -41,6 +41,11 @@ namespace NzbDrone.Core.Notifications.Pushover
_proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings); _proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{
_proxy.SendNotification(HEALTH_RESTORED_TITLE, $"The following issue is now resolved: {previousCheck.Message}", Settings);
}
public override void OnDownloadFailure(DownloadFailedMessage message) public override void OnDownloadFailure(DownloadFailedMessage message)
{ {
_proxy.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, Settings); _proxy.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, Settings);

@ -44,6 +44,11 @@ namespace NzbDrone.Core.Notifications.SendGrid
_proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings); _proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{
_proxy.SendNotification(HEALTH_RESTORED_TITLE, $"The following issue is now resolved: {previousCheck.Message}", Settings);
}
public override void OnDownloadFailure(DownloadFailedMessage message) public override void OnDownloadFailure(DownloadFailedMessage message)
{ {
_proxy.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, Settings); _proxy.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, Settings);

@ -41,6 +41,11 @@ namespace NzbDrone.Core.Notifications.Simplepush
_proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings); _proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{
_proxy.SendNotification(HEALTH_RESTORED_TITLE, $"The following issue is now resolved: {previousCheck.Message}", Settings);
}
public override void OnDownloadFailure(DownloadFailedMessage message) public override void OnDownloadFailure(DownloadFailedMessage message)
{ {
_proxy.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, Settings); _proxy.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, Settings);

@ -119,6 +119,23 @@ namespace NzbDrone.Core.Notifications.Slack
_proxy.SendPayload(payload, Settings); _proxy.SendPayload(payload, Settings);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{
var attachments = new List<Attachment>
{
new Attachment
{
Title = previousCheck.Source.Name,
Text = $"The following issue is now resolved: {previousCheck.Message}",
Color = "good"
}
};
var payload = CreatePayload("Health Issue Resolved", attachments);
_proxy.SendPayload(payload, Settings);
}
public override void OnTrackRetag(TrackRetagMessage message) public override void OnTrackRetag(TrackRetagMessage message)
{ {
var attachments = new List<Attachment> var attachments = new List<Attachment>

@ -41,6 +41,11 @@ namespace NzbDrone.Core.Notifications.Telegram
_proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings); _proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{
_proxy.SendNotification(HEALTH_RESTORED_TITLE, $"The following issue is now resolved: {previousCheck.Message}", Settings);
}
public override void OnDownloadFailure(DownloadFailedMessage message) public override void OnDownloadFailure(DownloadFailedMessage message)
{ {
_proxy.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, Settings); _proxy.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, Settings);

@ -43,6 +43,11 @@ namespace NzbDrone.Core.Notifications.Twitter
_twitterService.SendNotification($"Health Issue: {healthCheck.Message}", Settings); _twitterService.SendNotification($"Health Issue: {healthCheck.Message}", Settings);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{
_twitterService.SendNotification($"Health Issue Resolved: {previousCheck.Message}", Settings);
}
public override void OnDownloadFailure(DownloadFailedMessage message) public override void OnDownloadFailure(DownloadFailedMessage message)
{ {
_twitterService.SendNotification($"Download Failed: {message.Message}", Settings); _twitterService.SendNotification($"Download Failed: {message.Message}", Settings);

@ -65,6 +65,11 @@ namespace NzbDrone.Core.Notifications.Webhook
_proxy.SendWebhook(BuildHealthPayload(healthCheck), Settings); _proxy.SendWebhook(BuildHealthPayload(healthCheck), Settings);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{
_proxy.SendWebhook(BuildHealthRestoredPayload(previousCheck), Settings);
}
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage) public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
{ {
_proxy.SendWebhook(BuildApplicationUpdatePayload(updateMessage), Settings); _proxy.SendWebhook(BuildApplicationUpdatePayload(updateMessage), Settings);

@ -168,6 +168,19 @@ namespace NzbDrone.Core.Notifications.Webhook
}; };
} }
protected WebhookHealthPayload BuildHealthRestoredPayload(HealthCheck.HealthCheck healthCheck)
{
return new WebhookHealthPayload
{
EventType = WebhookEventType.HealthRestored,
InstanceName = _configFileProvider.InstanceName,
Level = healthCheck.Type,
Message = healthCheck.Message,
Type = healthCheck.Source.Name,
WikiUrl = healthCheck.WikiUrl?.ToString()
};
}
protected WebhookApplicationUpdatePayload BuildApplicationUpdatePayload(ApplicationUpdateMessage updateMessage) protected WebhookApplicationUpdatePayload BuildApplicationUpdatePayload(ApplicationUpdateMessage updateMessage)
{ {
return new WebhookApplicationUpdatePayload return new WebhookApplicationUpdatePayload

@ -19,5 +19,6 @@ namespace NzbDrone.Core.Notifications.Webhook
Health, Health,
Retag, Retag,
ApplicationUpdate, ApplicationUpdate,
HealthRestored
} }
} }

@ -47,6 +47,11 @@ namespace NzbDrone.Core.Notifications.Xbmc
Notify(Settings, HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message); Notify(Settings, HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message);
} }
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{
Notify(Settings, HEALTH_RESTORED_TITLE_BRANDED, $"The following issue is now resolved: {previousCheck.Message}");
}
public override void OnTrackRetag(TrackRetagMessage message) public override void OnTrackRetag(TrackRetagMessage message)
{ {
UpdateAndClean(message.Artist); UpdateAndClean(message.Artist);

Loading…
Cancel
Save