mirror of https://github.com/lidarr/Lidarr
New: Health Check Failure Notifications (#609)
* New: Health Check Failure Notifications Fixes #295 * New: OnDownloadFailure and OnImportFailure Notification * New: On Retag notifications * Fixed: XBMC notification test * New: Discord Notifications Closes #1511 * On Download to On Import on card * Remove OnDownload, Rename OnAlbumDownload -> OnReleaseImported * Fixed: Webhook OnReleaseImport notification * Respect OnUpgrade and fix missing schema items for frontend * New: Simplify Notification Modal UI * Fixed: PlexHomeTheater OnReleaseImport notification
This commit is contained in:
parent
4d8bcd12e3
commit
d4d9146599
|
@ -14,6 +14,7 @@ import FormGroup from 'Components/Form/FormGroup';
|
|||
import FormLabel from 'Components/Form/FormLabel';
|
||||
import FormInputGroup from 'Components/Form/FormInputGroup';
|
||||
import ProviderFieldFormGroup from 'Components/Form/ProviderFieldFormGroup';
|
||||
import NotificationEventItems from './NotificationEventItems';
|
||||
import styles from './EditNotificationModalContent.css';
|
||||
|
||||
function EditNotificationModalContent(props) {
|
||||
|
@ -38,16 +39,6 @@ function EditNotificationModalContent(props) {
|
|||
id,
|
||||
implementationName,
|
||||
name,
|
||||
onGrab,
|
||||
onDownload,
|
||||
onAlbumDownload,
|
||||
onUpgrade,
|
||||
onRename,
|
||||
supportsOnGrab,
|
||||
supportsOnDownload,
|
||||
supportsOnAlbumDownload,
|
||||
supportsOnUpgrade,
|
||||
supportsOnRename,
|
||||
tags,
|
||||
fields,
|
||||
message
|
||||
|
@ -94,73 +85,10 @@ function EditNotificationModalContent(props) {
|
|||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>On Grab</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="onGrab"
|
||||
helpText="Be notified when albums are available for download and has been sent to a download client"
|
||||
isDisabled={!supportsOnGrab.value}
|
||||
{...onGrab}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>On Album Import</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="onAlbumDownload"
|
||||
helpText="Be notified when complete albums are successfully imported"
|
||||
isDisabled={!supportsOnAlbumDownload.value}
|
||||
{...onAlbumDownload}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>On Track Import</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="onDownload"
|
||||
helpText="Be notified when track files are successfully imported"
|
||||
isDisabled={!supportsOnDownload.value}
|
||||
{...onDownload}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
{
|
||||
onDownload.value &&
|
||||
<FormGroup>
|
||||
<FormLabel>On Track Upgrade</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="onUpgrade"
|
||||
helpText="Be notified when tracks are upgraded to a better quality"
|
||||
isDisabled={!supportsOnUpgrade.value}
|
||||
{...onUpgrade}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
}
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>On Rename</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="onRename"
|
||||
helpText="Be notified when tracks are renamed"
|
||||
isDisabled={!supportsOnRename.value}
|
||||
{...onRename}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
<NotificationEventItems
|
||||
item={item}
|
||||
onInputChange={onInputChange}
|
||||
/>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Tags</FormLabel>
|
||||
|
|
|
@ -55,15 +55,21 @@ class Notification extends Component {
|
|||
id,
|
||||
name,
|
||||
onGrab,
|
||||
onDownload,
|
||||
onAlbumDownload,
|
||||
onReleaseImport,
|
||||
onUpgrade,
|
||||
onRename,
|
||||
onHealthIssue,
|
||||
onDownloadFailure,
|
||||
onImportFailure,
|
||||
onTrackRetag,
|
||||
supportsOnGrab,
|
||||
supportsOnDownload,
|
||||
supportsOnAlbumDownload,
|
||||
supportsOnReleaseImport,
|
||||
supportsOnUpgrade,
|
||||
supportsOnRename
|
||||
supportsOnRename,
|
||||
supportsOnHealthIssue,
|
||||
supportsOnDownloadFailure,
|
||||
supportsOnImportFailure,
|
||||
supportsOnTrackRetag
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
|
@ -84,21 +90,14 @@ class Notification extends Component {
|
|||
}
|
||||
|
||||
{
|
||||
supportsOnAlbumDownload && onAlbumDownload &&
|
||||
supportsOnReleaseImport && onReleaseImport &&
|
||||
<Label kind={kinds.SUCCESS}>
|
||||
On Album Download
|
||||
On Release Import
|
||||
</Label>
|
||||
}
|
||||
|
||||
{
|
||||
supportsOnDownload && onDownload &&
|
||||
<Label kind={kinds.SUCCESS}>
|
||||
On Download
|
||||
</Label>
|
||||
}
|
||||
|
||||
{
|
||||
supportsOnUpgrade && onDownload && onUpgrade &&
|
||||
supportsOnUpgrade && onReleaseImport && onUpgrade &&
|
||||
<Label kind={kinds.SUCCESS}>
|
||||
On Upgrade
|
||||
</Label>
|
||||
|
@ -112,7 +111,36 @@ class Notification extends Component {
|
|||
}
|
||||
|
||||
{
|
||||
!onGrab && !onAlbumDownload && !onDownload && !onRename &&
|
||||
supportsOnTrackRetag && onTrackRetag &&
|
||||
<Label kind={kinds.SUCCESS}>
|
||||
On Track Tag Update
|
||||
</Label>
|
||||
}
|
||||
|
||||
{
|
||||
supportsOnHealthIssue && onHealthIssue &&
|
||||
<Label kind={kinds.SUCCESS}>
|
||||
On Health Issue
|
||||
</Label>
|
||||
}
|
||||
|
||||
{
|
||||
supportsOnDownloadFailure && onDownloadFailure &&
|
||||
<Label kind={kinds.SUCCESS} >
|
||||
On Download Failure
|
||||
</Label>
|
||||
}
|
||||
|
||||
{
|
||||
supportsOnImportFailure && onImportFailure &&
|
||||
<Label kind={kinds.SUCCESS} >
|
||||
On Import Failure
|
||||
</Label>
|
||||
}
|
||||
|
||||
{
|
||||
!onGrab && !onReleaseImport && !onRename && !onTrackRetag &&
|
||||
!onHealthIssue && !onDownloadFailure && !onImportFailure &&
|
||||
<Label
|
||||
kind={kinds.DISABLED}
|
||||
outline={true}
|
||||
|
@ -146,15 +174,21 @@ Notification.propTypes = {
|
|||
id: PropTypes.number.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
onGrab: PropTypes.bool.isRequired,
|
||||
onDownload: PropTypes.bool.isRequired,
|
||||
onAlbumDownload: PropTypes.bool.isRequired,
|
||||
onReleaseImport: PropTypes.bool.isRequired,
|
||||
onUpgrade: PropTypes.bool.isRequired,
|
||||
onRename: PropTypes.bool.isRequired,
|
||||
onHealthIssue: PropTypes.bool.isRequired,
|
||||
onDownloadFailure: PropTypes.bool.isRequired,
|
||||
onImportFailure: PropTypes.bool.isRequired,
|
||||
onTrackRetag: PropTypes.bool.isRequired,
|
||||
supportsOnGrab: PropTypes.bool.isRequired,
|
||||
supportsOnDownload: PropTypes.bool.isRequired,
|
||||
supportsOnAlbumDownload: PropTypes.bool.isRequired,
|
||||
supportsOnReleaseImport: PropTypes.bool.isRequired,
|
||||
supportsOnUpgrade: PropTypes.bool.isRequired,
|
||||
supportsOnRename: PropTypes.bool.isRequired,
|
||||
supportsOnHealthIssue: PropTypes.bool.isRequired,
|
||||
supportsOnDownloadFailure: PropTypes.bool.isRequired,
|
||||
supportsOnImportFailure: PropTypes.bool.isRequired,
|
||||
supportsOnTrackRetag: PropTypes.bool.isRequired,
|
||||
onConfirmDeleteNotification: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
.events {
|
||||
margin-top: 10px;
|
||||
user-select: none;
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { inputTypes } from 'Helpers/Props';
|
||||
import FormGroup from 'Components/Form/FormGroup';
|
||||
import FormLabel from 'Components/Form/FormLabel';
|
||||
import FormInputHelpText from 'Components/Form/FormInputHelpText';
|
||||
import FormInputGroup from 'Components/Form/FormInputGroup';
|
||||
import styles from './NotificationEventItems.css';
|
||||
|
||||
function NotificationEventItems(props) {
|
||||
const {
|
||||
item,
|
||||
onInputChange
|
||||
} = props;
|
||||
|
||||
const {
|
||||
onGrab,
|
||||
onReleaseImport,
|
||||
onUpgrade,
|
||||
onRename,
|
||||
onHealthIssue,
|
||||
onDownloadFailure,
|
||||
onImportFailure,
|
||||
onTrackRetag,
|
||||
supportsOnGrab,
|
||||
supportsOnReleaseImport,
|
||||
supportsOnUpgrade,
|
||||
supportsOnRename,
|
||||
supportsOnHealthIssue,
|
||||
includeHealthWarnings,
|
||||
supportsOnDownloadFailure,
|
||||
supportsOnImportFailure,
|
||||
supportsOnTrackRetag
|
||||
} = item;
|
||||
|
||||
return (
|
||||
<FormGroup>
|
||||
<FormLabel>Notification Triggers</FormLabel>
|
||||
<div>
|
||||
<FormInputHelpText
|
||||
text="Select which events should trigger this notification"
|
||||
link="https://github.com/lidarr/Lidarr/wiki/Connections"
|
||||
/>
|
||||
<div className={styles.events}>
|
||||
<div>
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="onGrab"
|
||||
helpText="On Grab"
|
||||
isDisabled={!supportsOnGrab.value}
|
||||
{...onGrab}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="onReleaseImport"
|
||||
helpText="On Release Import"
|
||||
isDisabled={!supportsOnReleaseImport.value}
|
||||
{...onReleaseImport}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{
|
||||
onReleaseImport.value &&
|
||||
<div>
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="onUpgrade"
|
||||
helpText="On Upgrade"
|
||||
isDisabled={!supportsOnUpgrade.value}
|
||||
{...onUpgrade}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div>
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="onDownloadFailure"
|
||||
helpText="On Download Failure"
|
||||
isDisabled={!supportsOnDownloadFailure.value}
|
||||
{...onDownloadFailure}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="onImportFailure"
|
||||
helpText="On Import Failure"
|
||||
isDisabled={!supportsOnImportFailure.value}
|
||||
{...onImportFailure}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="onRename"
|
||||
helpText="On Rename"
|
||||
isDisabled={!supportsOnRename.value}
|
||||
{...onRename}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="onTrackRetag"
|
||||
helpText="On Track Retag"
|
||||
isDisabled={!supportsOnTrackRetag.value}
|
||||
{...onTrackRetag}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="onHealthIssue"
|
||||
helpText="On Health Issue"
|
||||
isDisabled={!supportsOnHealthIssue.value}
|
||||
{...onHealthIssue}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{
|
||||
onHealthIssue.value &&
|
||||
<div>
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="includeHealthWarnings"
|
||||
helpText="Include Health Warnings"
|
||||
isDisabled={!supportsOnHealthIssue.value}
|
||||
{...includeHealthWarnings}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</FormGroup>
|
||||
);
|
||||
}
|
||||
|
||||
NotificationEventItems.propTypes = {
|
||||
item: PropTypes.object.isRequired,
|
||||
onInputChange: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default NotificationEventItems;
|
|
@ -103,9 +103,13 @@ export default {
|
|||
[SELECT_NOTIFICATION_SCHEMA]: (state, { payload }) => {
|
||||
return selectProviderSchema(state, section, payload, (selectedSchema) => {
|
||||
selectedSchema.onGrab = selectedSchema.supportsOnGrab;
|
||||
selectedSchema.onDownload = selectedSchema.supportsOnDownload;
|
||||
selectedSchema.onReleaseImport = selectedSchema.supportsOnReleaseImport;
|
||||
selectedSchema.onUpgrade = selectedSchema.supportsOnUpgrade;
|
||||
selectedSchema.onRename = selectedSchema.supportsOnRename;
|
||||
selectedSchema.onHealthIssue = selectedSchema.supportsOnHealthIssue;
|
||||
selectedSchema.onDownloadFailure = selectedSchema.supportsOnDownloadFailure;
|
||||
selectedSchema.onImportFailure = selectedSchema.supportsOnImportFailure;
|
||||
selectedSchema.onTrackRetag = selectedSchema.supportsOnTrackRetag;
|
||||
|
||||
return selectedSchema;
|
||||
});
|
||||
|
|
|
@ -13,8 +13,8 @@ namespace Lidarr.Api.V1.Notifications
|
|||
|
||||
protected override void Validate(NotificationDefinition definition, bool includeWarnings)
|
||||
{
|
||||
if (!definition.OnGrab && !definition.OnDownload) return;
|
||||
if (!definition.Enable) return;
|
||||
base.Validate(definition, includeWarnings);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,15 +6,22 @@ namespace Lidarr.Api.V1.Notifications
|
|||
{
|
||||
public string Link { get; set; }
|
||||
public bool OnGrab { get; set; }
|
||||
public bool OnDownload { get; set; }
|
||||
public bool OnAlbumDownload { get; set; }
|
||||
public bool OnReleaseImport { get; set; }
|
||||
public bool OnUpgrade { get; set; }
|
||||
public bool OnRename { get; set; }
|
||||
public bool OnHealthIssue { get; set; }
|
||||
public bool OnDownloadFailure { get; set; }
|
||||
public bool OnImportFailure { get; set; }
|
||||
public bool OnTrackRetag { get; set; }
|
||||
public bool SupportsOnGrab { get; set; }
|
||||
public bool SupportsOnDownload { get; set; }
|
||||
public bool SupportsOnAlbumDownload { get; set; }
|
||||
public bool SupportsOnReleaseImport { get; set; }
|
||||
public bool SupportsOnUpgrade { get; set; }
|
||||
public bool SupportsOnRename { get; set; }
|
||||
public bool SupportsOnHealthIssue { get; set; }
|
||||
public bool IncludeHealthWarnings { get; set; }
|
||||
public bool SupportsOnDownloadFailure { get; set; }
|
||||
public bool SupportsOnImportFailure { get; set; }
|
||||
public bool SupportsOnTrackRetag { get; set; }
|
||||
public string TestCommand { get; set; }
|
||||
}
|
||||
|
||||
|
@ -27,15 +34,22 @@ namespace Lidarr.Api.V1.Notifications
|
|||
var resource = base.ToResource(definition);
|
||||
|
||||
resource.OnGrab = definition.OnGrab;
|
||||
resource.OnDownload = definition.OnDownload;
|
||||
resource.OnAlbumDownload = definition.OnAlbumDownload;
|
||||
resource.OnReleaseImport = definition.OnReleaseImport;
|
||||
resource.OnUpgrade = definition.OnUpgrade;
|
||||
resource.OnRename = definition.OnRename;
|
||||
resource.OnHealthIssue = definition.OnHealthIssue;
|
||||
resource.OnDownloadFailure = definition.OnDownloadFailure;
|
||||
resource.OnImportFailure = definition.OnImportFailure;
|
||||
resource.OnTrackRetag = definition.OnTrackRetag;
|
||||
resource.SupportsOnGrab = definition.SupportsOnGrab;
|
||||
resource.SupportsOnDownload = definition.SupportsOnDownload;
|
||||
resource.SupportsOnAlbumDownload = definition.SupportsOnAlbumDownload;
|
||||
resource.SupportsOnReleaseImport = definition.SupportsOnReleaseImport;
|
||||
resource.SupportsOnUpgrade = definition.SupportsOnUpgrade;
|
||||
resource.SupportsOnRename = definition.SupportsOnRename;
|
||||
resource.SupportsOnHealthIssue = definition.SupportsOnHealthIssue;
|
||||
resource.IncludeHealthWarnings = definition.IncludeHealthWarnings;
|
||||
resource.SupportsOnDownloadFailure = definition.SupportsOnDownloadFailure;
|
||||
resource.SupportsOnImportFailure = definition.SupportsOnImportFailure;
|
||||
resource.SupportsOnTrackRetag = definition.SupportsOnTrackRetag;
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
@ -47,15 +61,22 @@ namespace Lidarr.Api.V1.Notifications
|
|||
var definition = base.ToModel(resource);
|
||||
|
||||
definition.OnGrab = resource.OnGrab;
|
||||
definition.OnDownload = resource.OnDownload;
|
||||
definition.OnAlbumDownload = resource.OnAlbumDownload;
|
||||
definition.OnReleaseImport = resource.OnReleaseImport;
|
||||
definition.OnUpgrade = resource.OnUpgrade;
|
||||
definition.OnRename = resource.OnRename;
|
||||
definition.OnHealthIssue = resource.OnHealthIssue;
|
||||
definition.OnDownloadFailure = resource.OnDownloadFailure;
|
||||
definition.OnImportFailure = resource.OnImportFailure;
|
||||
definition.OnTrackRetag = resource.OnTrackRetag;
|
||||
definition.SupportsOnGrab = resource.SupportsOnGrab;
|
||||
definition.SupportsOnDownload = resource.SupportsOnDownload;
|
||||
definition.SupportsOnAlbumDownload = resource.SupportsOnAlbumDownload;
|
||||
definition.SupportsOnReleaseImport = resource.SupportsOnReleaseImport;
|
||||
definition.SupportsOnUpgrade = resource.SupportsOnUpgrade;
|
||||
definition.SupportsOnRename = resource.SupportsOnRename;
|
||||
definition.SupportsOnHealthIssue = resource.SupportsOnHealthIssue;
|
||||
definition.IncludeHealthWarnings = resource.IncludeHealthWarnings;
|
||||
definition.SupportsOnDownloadFailure = resource.SupportsOnDownloadFailure;
|
||||
definition.SupportsOnImportFailure = resource.SupportsOnImportFailure;
|
||||
definition.SupportsOnTrackRetag = resource.SupportsOnTrackRetag;
|
||||
|
||||
return definition;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace NzbDrone.Core.Test.NotificationTests
|
|||
}
|
||||
}
|
||||
|
||||
class TestNotificationWithOnDownload : NotificationBase<TestSetting>
|
||||
class TestNotificationWithOnReleaseImport : NotificationBase<TestSetting>
|
||||
{
|
||||
public override string Name => "TestNotification";
|
||||
public override string Link => "";
|
||||
|
@ -32,7 +32,7 @@ namespace NzbDrone.Core.Test.NotificationTests
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage trackDownloadMessage)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
TestLogger.Info("OnDownload was called");
|
||||
}
|
||||
|
@ -55,12 +55,7 @@ namespace NzbDrone.Core.Test.NotificationTests
|
|||
TestLogger.Info("OnGrab was called");
|
||||
}
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage message)
|
||||
{
|
||||
TestLogger.Info("OnDownload was called");
|
||||
}
|
||||
|
||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
TestLogger.Info("OnAlbumDownload was called");
|
||||
}
|
||||
|
@ -70,6 +65,25 @@ namespace NzbDrone.Core.Test.NotificationTests
|
|||
TestLogger.Info("OnRename was called");
|
||||
}
|
||||
|
||||
public override void OnHealthIssue(NzbDrone.Core.HealthCheck.HealthCheck artist)
|
||||
{
|
||||
TestLogger.Info("OnHealthIssue was called");
|
||||
}
|
||||
|
||||
public override void OnDownloadFailure(DownloadFailedMessage message)
|
||||
{
|
||||
TestLogger.Info("OnDownloadFailure was called");
|
||||
}
|
||||
|
||||
public override void OnImportFailure(AlbumDownloadMessage message)
|
||||
{
|
||||
TestLogger.Info("OnImportFailure was called");
|
||||
}
|
||||
|
||||
public override void OnTrackRetag(TrackRetagMessage message)
|
||||
{
|
||||
TestLogger.Info("OnTrackRetag was called");
|
||||
}
|
||||
}
|
||||
|
||||
class TestNotificationWithNoEvents : NotificationBase<TestSetting>
|
||||
|
@ -87,11 +101,11 @@ namespace NzbDrone.Core.Test.NotificationTests
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void should_support_OnUpgrade_should_link_to_OnDownload()
|
||||
public void should_support_OnUpgrade_should_link_to_OnReleaseImport()
|
||||
{
|
||||
var notification = new TestNotificationWithOnDownload();
|
||||
var notification = new TestNotificationWithOnReleaseImport();
|
||||
|
||||
notification.SupportsOnDownload.Should().BeTrue();
|
||||
notification.SupportsOnReleaseImport.Should().BeTrue();
|
||||
notification.SupportsOnUpgrade.Should().BeTrue();
|
||||
|
||||
notification.SupportsOnGrab.Should().BeFalse();
|
||||
|
@ -104,10 +118,13 @@ namespace NzbDrone.Core.Test.NotificationTests
|
|||
var notification = new TestNotificationWithAllEvents();
|
||||
|
||||
notification.SupportsOnGrab.Should().BeTrue();
|
||||
notification.SupportsOnDownload.Should().BeTrue();
|
||||
notification.SupportsOnAlbumDownload.Should().BeTrue();
|
||||
notification.SupportsOnReleaseImport.Should().BeTrue();
|
||||
notification.SupportsOnUpgrade.Should().BeTrue();
|
||||
notification.SupportsOnRename.Should().BeTrue();
|
||||
notification.SupportsOnHealthIssue.Should().BeTrue();
|
||||
notification.SupportsOnDownloadFailure.Should().BeTrue();
|
||||
notification.SupportsOnImportFailure.Should().BeTrue();
|
||||
notification.SupportsOnTrackRetag.Should().BeTrue();
|
||||
}
|
||||
|
||||
|
||||
|
@ -117,10 +134,13 @@ namespace NzbDrone.Core.Test.NotificationTests
|
|||
var notification = new TestNotificationWithNoEvents();
|
||||
|
||||
notification.SupportsOnGrab.Should().BeFalse();
|
||||
notification.SupportsOnDownload.Should().BeFalse();
|
||||
notification.SupportsOnAlbumDownload.Should().BeFalse();
|
||||
notification.SupportsOnReleaseImport.Should().BeFalse();
|
||||
notification.SupportsOnUpgrade.Should().BeFalse();
|
||||
notification.SupportsOnRename.Should().BeFalse();
|
||||
notification.SupportsOnHealthIssue.Should().BeFalse();
|
||||
notification.SupportsOnDownloadFailure.Should().BeFalse();
|
||||
notification.SupportsOnImportFailure.Should().BeFalse();
|
||||
notification.SupportsOnTrackRetag.Should().BeFalse();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ namespace NzbDrone.Core.Test.NotificationTests
|
|||
[Test]
|
||||
public void should_remove_old_episodes_on_upgrade()
|
||||
{
|
||||
Subject.OnAlbumDownload(_upgrade);
|
||||
Subject.OnReleaseImport(_upgrade);
|
||||
|
||||
Mocker.GetMock<ISynologyIndexerProxy>()
|
||||
.Verify(v => v.DeleteFile(@"C:\Test\file1.S01E01.mkv".AsOsAgnostic()), Times.Once());
|
||||
|
@ -85,7 +85,7 @@ namespace NzbDrone.Core.Test.NotificationTests
|
|||
[Test]
|
||||
public void should_add_new_episode_on_upgrade()
|
||||
{
|
||||
Subject.OnAlbumDownload(_upgrade);
|
||||
Subject.OnReleaseImport(_upgrade);
|
||||
|
||||
Mocker.GetMock<ISynologyIndexerProxy>()
|
||||
.Verify(v => v.AddFile(@"C:\Test\file1.S01E01E02.mkv".AsOsAgnostic()), Times.Once());
|
||||
|
|
|
@ -24,10 +24,12 @@ namespace NzbDrone.Core.Test.NotificationTests.Xbmc.Json
|
|||
.Build();
|
||||
|
||||
_xbmcArtist = Builder<KodiArtist>.CreateListOfSize(3)
|
||||
.TheFirst(1)
|
||||
.With(s => s.MusicbrainzArtistId = new List<string> { MB_ID.ToString()})
|
||||
.Build()
|
||||
.ToList();
|
||||
.TheFirst(1)
|
||||
.With(s => s.MusicbrainzArtistId = new List<string> { MB_ID.ToString()})
|
||||
.TheNext(2)
|
||||
.With(s => s.MusicbrainzArtistId = new List<string>())
|
||||
.Build()
|
||||
.ToList();
|
||||
|
||||
Mocker.GetMock<IXbmcJsonApiProxy>()
|
||||
.Setup(s => s.GetArtist(_settings))
|
||||
|
|
|
@ -12,9 +12,9 @@ using NzbDrone.Core.Music;
|
|||
namespace NzbDrone.Core.Test.NotificationTests.Xbmc
|
||||
{
|
||||
[TestFixture]
|
||||
public class OnDownloadFixture : CoreTest<Notifications.Xbmc.Xbmc>
|
||||
public class OnReleaseImportFixture : CoreTest<Notifications.Xbmc.Xbmc>
|
||||
{
|
||||
private TrackDownloadMessage _trackDownloadMessage;
|
||||
private AlbumDownloadMessage _albumDownloadMessage;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
|
@ -25,11 +25,11 @@ namespace NzbDrone.Core.Test.NotificationTests.Xbmc
|
|||
var trackFile = Builder<TrackFile>.CreateNew()
|
||||
.Build();
|
||||
|
||||
_trackDownloadMessage = Builder<TrackDownloadMessage>.CreateNew()
|
||||
.With(d => d.Artist = artist)
|
||||
.With(d => d.TrackFile = trackFile)
|
||||
.With(d => d.OldFiles = new List<TrackFile>())
|
||||
.Build();
|
||||
_albumDownloadMessage = Builder<AlbumDownloadMessage>.CreateNew()
|
||||
.With(d => d.Artist = artist)
|
||||
.With(d => d.TrackFiles = new List<TrackFile> { trackFile })
|
||||
.With(d => d.OldFiles = new List<TrackFile>())
|
||||
.Build();
|
||||
|
||||
Subject.Definition = new NotificationDefinition();
|
||||
Subject.Definition.Settings = new XbmcSettings
|
||||
|
@ -40,7 +40,7 @@ namespace NzbDrone.Core.Test.NotificationTests.Xbmc
|
|||
|
||||
private void GivenOldFiles()
|
||||
{
|
||||
_trackDownloadMessage.OldFiles = Builder<TrackFile>.CreateListOfSize(1)
|
||||
_albumDownloadMessage.OldFiles = Builder<TrackFile>.CreateListOfSize(1)
|
||||
.Build()
|
||||
.ToList();
|
||||
|
||||
|
@ -54,7 +54,7 @@ namespace NzbDrone.Core.Test.NotificationTests.Xbmc
|
|||
[Test]
|
||||
public void should_not_clean_if_no_episode_was_replaced()
|
||||
{
|
||||
Subject.OnDownload(_trackDownloadMessage);
|
||||
Subject.OnReleaseImport(_albumDownloadMessage);
|
||||
|
||||
Mocker.GetMock<IXbmcService>().Verify(v => v.Clean(It.IsAny<XbmcSettings>()), Times.Never());
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ namespace NzbDrone.Core.Test.NotificationTests.Xbmc
|
|||
public void should_clean_if_episode_was_replaced()
|
||||
{
|
||||
GivenOldFiles();
|
||||
Subject.OnDownload(_trackDownloadMessage);
|
||||
Subject.OnReleaseImport(_albumDownloadMessage);
|
||||
|
||||
Mocker.GetMock<IXbmcService>().Verify(v => v.Clean(It.IsAny<XbmcSettings>()), Times.Once());
|
||||
}
|
|
@ -357,7 +357,7 @@
|
|||
<Compile Include="NotificationTests\Xbmc\Http\UpdateFixture.cs" />
|
||||
<Compile Include="NotificationTests\Xbmc\Json\GetArtistPathFixture.cs" />
|
||||
<Compile Include="NotificationTests\Xbmc\Json\UpdateFixture.cs" />
|
||||
<Compile Include="NotificationTests\Xbmc\OnDownloadFixture.cs" />
|
||||
<Compile Include="NotificationTests\Xbmc\OnReleaseImportFixture.cs" />
|
||||
<Compile Include="OrganizerTests\BuildFilePathFixture.cs" />
|
||||
<Compile Include="OrganizerTests\GetAlbumFolderFixture.cs" />
|
||||
<Compile Include="OrganizerTests\FileNameBuilderTests\FileNameBuilderFixture.cs" />
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
using FluentMigrator;
|
||||
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(29)]
|
||||
public class health_issue_notification : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Alter.Table("Notifications").AddColumn("OnHealthIssue").AsBoolean().WithDefaultValue(0);
|
||||
Alter.Table("Notifications").AddColumn("IncludeHealthWarnings").AsBoolean().WithDefaultValue(0);
|
||||
Alter.Table("Notifications").AddColumn("OnDownloadFailure").AsBoolean().WithDefaultValue(0);
|
||||
Alter.Table("Notifications").AddColumn("OnImportFailure").AsBoolean().WithDefaultValue(0);
|
||||
Alter.Table("Notifications").AddColumn("OnTrackRetag").AsBoolean().WithDefaultValue(0);
|
||||
|
||||
Delete.Column("OnDownload").FromTable("Notifications");
|
||||
|
||||
Rename.Column("OnAlbumDownload").OnTable("Notifications").To("OnReleaseImport");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,7 +30,6 @@ using NzbDrone.Core.ArtistStats;
|
|||
using NzbDrone.Core.Tags;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Authentication;
|
||||
using NzbDrone.Core.CustomFilters;
|
||||
using NzbDrone.Core.Extras.Metadata;
|
||||
|
@ -73,10 +72,13 @@ namespace NzbDrone.Core.Datastore
|
|||
|
||||
Mapper.Entity<NotificationDefinition>().RegisterDefinition("Notifications")
|
||||
.Ignore(i => i.SupportsOnGrab)
|
||||
.Ignore(i => i.SupportsOnDownload)
|
||||
.Ignore(i => i.SupportsOnAlbumDownload)
|
||||
.Ignore(i => i.SupportsOnReleaseImport)
|
||||
.Ignore(i => i.SupportsOnUpgrade)
|
||||
.Ignore(i => i.SupportsOnRename);
|
||||
.Ignore(i => i.SupportsOnRename)
|
||||
.Ignore(i => i.SupportsOnHealthIssue)
|
||||
.Ignore(i => i.SupportsOnDownloadFailure)
|
||||
.Ignore(i => i.SupportsOnImportFailure)
|
||||
.Ignore(i => i.SupportsOnTrackRetag);
|
||||
|
||||
Mapper.Entity<MetadataDefinition>().RegisterDefinition("Metadata")
|
||||
.Ignore(d => d.Tags);
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
using NzbDrone.Common.Messaging;
|
||||
|
||||
namespace NzbDrone.Core.HealthCheck
|
||||
{
|
||||
public class HealthCheckFailedEvent : IEvent
|
||||
{
|
||||
public HealthCheck HealthCheck { get; private set; }
|
||||
|
||||
public HealthCheckFailedEvent(HealthCheck healthCheck)
|
||||
{
|
||||
HealthCheck = healthCheck;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -80,7 +80,13 @@ namespace NzbDrone.Core.HealthCheck
|
|||
|
||||
else
|
||||
{
|
||||
if (_healthCheckResults.Find(result.Source.Name) == null)
|
||||
{
|
||||
_eventAggregator.PublishEvent(new HealthCheckFailedEvent(result));
|
||||
}
|
||||
|
||||
_healthCheckResults.Set(result.Source.Name, result);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,14 +21,24 @@ namespace NzbDrone.Core.Notifications.Boxcar
|
|||
_proxy.SendNotification(ALBUM_GRABBED_TITLE, grabMessage.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
_proxy.SendNotification(TRACK_DOWNLOADED_TITLE , message.Message, Settings);
|
||||
_proxy.SendNotification(ALBUM_DOWNLOADED_TITLE, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
||||
public override void OnHealthIssue(HealthCheck.HealthCheck message)
|
||||
{
|
||||
_proxy.SendNotification(TRACK_DOWNLOADED_TITLE, message.Message, Settings);
|
||||
_proxy.SendNotification(HEALTH_ISSUE_TITLE, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownloadFailure(DownloadFailedMessage message)
|
||||
{
|
||||
_proxy.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnImportFailure(AlbumDownloadMessage message)
|
||||
{
|
||||
_proxy.SendNotification(IMPORT_FAILURE_TITLE, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override ValidationResult Test()
|
||||
|
|
|
@ -6,6 +6,7 @@ using FluentValidation.Results;
|
|||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Processes;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Music;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
|
@ -55,52 +56,7 @@ namespace NzbDrone.Core.Notifications.CustomScript
|
|||
ExecuteScript(environmentVariables);
|
||||
}
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage message)
|
||||
{
|
||||
var artist = message.Artist;
|
||||
var album = message.Album;
|
||||
var release = message.Release;
|
||||
var trackFile = message.TrackFile;
|
||||
var sourcePath = message.SourcePath;
|
||||
var environmentVariables = new StringDictionary();
|
||||
|
||||
environmentVariables.Add("Lidarr_EventType", "Download");
|
||||
environmentVariables.Add("Lidarr_IsUpgrade", message.OldFiles.Any().ToString());
|
||||
environmentVariables.Add("Lidarr_Artist_Id", artist.Id.ToString());
|
||||
environmentVariables.Add("Lidarr_Artist_Name", artist.Metadata.Value.Name);
|
||||
environmentVariables.Add("Lidarr_Artist_Path", artist.Path);
|
||||
environmentVariables.Add("Lidarr_Artist_MBId", artist.Metadata.Value.ForeignArtistId);
|
||||
environmentVariables.Add("Lidarr_Artist_Type", artist.Metadata.Value.Type);
|
||||
environmentVariables.Add("Lidarr_Album_Id", album.Id.ToString());
|
||||
environmentVariables.Add("Lidarr_Album_Title", album.Title);
|
||||
environmentVariables.Add("Lidarr_Album_MBId", album.ForeignAlbumId);
|
||||
environmentVariables.Add("Lidarr_AlbumRelease_MBId", release.ForeignReleaseId);
|
||||
environmentVariables.Add("Lidarr_Album_ReleaseDate", album.ReleaseDate.ToString());
|
||||
environmentVariables.Add("Lidarr_TrackFile_Id", trackFile.Id.ToString());
|
||||
environmentVariables.Add("Lidarr_TrackFile_TrackCount", trackFile.Tracks.Value.Count.ToString());
|
||||
environmentVariables.Add("Lidarr_TrackFile_RelativePath", trackFile.RelativePath);
|
||||
environmentVariables.Add("Lidarr_TrackFile_Path", Path.Combine(artist.Path, trackFile.RelativePath));
|
||||
environmentVariables.Add("Lidarr_TrackFile_TrackNumbers", string.Join(",", trackFile.Tracks.Value.Select(e => e.TrackNumber)));
|
||||
environmentVariables.Add("Lidarr_TrackFile_TrackTitles", string.Join("|", trackFile.Tracks.Value.Select(e => e.Title)));
|
||||
environmentVariables.Add("Lidarr_TrackFile_Quality", trackFile.Quality.Quality.Name);
|
||||
environmentVariables.Add("Lidarr_TrackFile_QualityVersion", trackFile.Quality.Revision.Version.ToString());
|
||||
environmentVariables.Add("Lidarr_TrackFile_ReleaseGroup", trackFile.ReleaseGroup ?? string.Empty);
|
||||
environmentVariables.Add("Lidarr_TrackFile_SceneName", trackFile.SceneName ?? string.Empty);
|
||||
environmentVariables.Add("Lidarr_TrackFile_SourcePath", sourcePath);
|
||||
environmentVariables.Add("Lidarr_TrackFile_SourceFolder", Path.GetDirectoryName(sourcePath));
|
||||
environmentVariables.Add("Lidarr_Download_Client", message.DownloadClient ?? string.Empty);
|
||||
environmentVariables.Add("Lidarr_Download_Id", message.DownloadId ?? string.Empty);
|
||||
|
||||
if (message.OldFiles.Any())
|
||||
{
|
||||
environmentVariables.Add("Lidarr_DeletedRelativePaths", string.Join("|", message.OldFiles.Select(e => e.RelativePath)));
|
||||
environmentVariables.Add("Lidarr_DeletedPaths", string.Join("|", message.OldFiles.Select(e => Path.Combine(artist.Path, e.RelativePath))));
|
||||
}
|
||||
|
||||
ExecuteScript(environmentVariables);
|
||||
}
|
||||
|
||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
var artist = message.Artist;
|
||||
var album = message.Album;
|
||||
|
@ -150,6 +106,53 @@ namespace NzbDrone.Core.Notifications.CustomScript
|
|||
ExecuteScript(environmentVariables);
|
||||
}
|
||||
|
||||
public override void OnTrackRetag(TrackRetagMessage message)
|
||||
{
|
||||
var artist = message.Artist;
|
||||
var album = message.Album;
|
||||
var release = message.Release;
|
||||
var trackFile = message.TrackFile;
|
||||
var environmentVariables = new StringDictionary();
|
||||
|
||||
environmentVariables.Add("Lidarr_EventType", "TrackRetag");
|
||||
environmentVariables.Add("Lidarr_Artist_Id", artist.Id.ToString());
|
||||
environmentVariables.Add("Lidarr_Artist_Name", artist.Metadata.Value.Name);
|
||||
environmentVariables.Add("Lidarr_Artist_Path", artist.Path);
|
||||
environmentVariables.Add("Lidarr_Artist_MBId", artist.Metadata.Value.ForeignArtistId);
|
||||
environmentVariables.Add("Lidarr_Artist_Type", artist.Metadata.Value.Type);
|
||||
environmentVariables.Add("Lidarr_Album_Id", album.Id.ToString());
|
||||
environmentVariables.Add("Lidarr_Album_Title", album.Title);
|
||||
environmentVariables.Add("Lidarr_Album_MBId", album.ForeignAlbumId);
|
||||
environmentVariables.Add("Lidarr_AlbumRelease_MBId", release.ForeignReleaseId);
|
||||
environmentVariables.Add("Lidarr_Album_ReleaseDate", album.ReleaseDate.ToString());
|
||||
environmentVariables.Add("Lidarr_TrackFile_Id", trackFile.Id.ToString());
|
||||
environmentVariables.Add("Lidarr_TrackFile_TrackCount", trackFile.Tracks.Value.Count.ToString());
|
||||
environmentVariables.Add("Lidarr_TrackFile_RelativePath", trackFile.RelativePath);
|
||||
environmentVariables.Add("Lidarr_TrackFile_Path", Path.Combine(artist.Path, trackFile.RelativePath));
|
||||
environmentVariables.Add("Lidarr_TrackFile_TrackNumbers", string.Join(",", trackFile.Tracks.Value.Select(e => e.TrackNumber)));
|
||||
environmentVariables.Add("Lidarr_TrackFile_TrackTitles", string.Join("|", trackFile.Tracks.Value.Select(e => e.Title)));
|
||||
environmentVariables.Add("Lidarr_TrackFile_Quality", trackFile.Quality.Quality.Name);
|
||||
environmentVariables.Add("Lidarr_TrackFile_QualityVersion", trackFile.Quality.Revision.Version.ToString());
|
||||
environmentVariables.Add("Lidarr_TrackFile_ReleaseGroup", trackFile.ReleaseGroup ?? string.Empty);
|
||||
environmentVariables.Add("Lidarr_TrackFile_SceneName", trackFile.SceneName ?? string.Empty);
|
||||
environmentVariables.Add("Lidarr_Tags_Diff", message.Diff.ToJson());
|
||||
environmentVariables.Add("Lidarr_Tags_Scrubbed", message.Scrubbed.ToString());
|
||||
|
||||
ExecuteScript(environmentVariables);
|
||||
}
|
||||
|
||||
public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
|
||||
{
|
||||
var environmentVariables = new StringDictionary();
|
||||
|
||||
environmentVariables.Add("Lidarr_EventType", "HealthIssue");
|
||||
environmentVariables.Add("Lidarr_Health_Issue_Level", nameof(healthCheck.Type));
|
||||
environmentVariables.Add("Lidarr_Health_Issue_Message", healthCheck.Message);
|
||||
environmentVariables.Add("Lidarr_Health_Issue_Type", healthCheck.Source.Name);
|
||||
environmentVariables.Add("Lidarr_Health_Issue_Wiki", healthCheck.WikiUrl.ToString() ?? string.Empty);
|
||||
|
||||
ExecuteScript(environmentVariables);
|
||||
}
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
|
|
|
@ -0,0 +1,190 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FluentValidation.Results;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Notifications.Discord.Payloads;
|
||||
using NzbDrone.Core.Music;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.Notifications.Discord
|
||||
{
|
||||
public class Discord : NotificationBase<DiscordSettings>
|
||||
{
|
||||
private readonly IDiscordProxy _proxy;
|
||||
|
||||
public Discord(IDiscordProxy proxy)
|
||||
{
|
||||
_proxy = proxy;
|
||||
}
|
||||
|
||||
public override string Name => "Discord";
|
||||
public override string Link => "https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks";
|
||||
|
||||
public override void OnGrab(GrabMessage message)
|
||||
{
|
||||
var embeds = new List<Embed>
|
||||
{
|
||||
new Embed
|
||||
{
|
||||
Description = message.Message,
|
||||
Title = message.Artist.Name,
|
||||
Text = message.Message,
|
||||
Color = (int)DiscordColors.Warning
|
||||
}
|
||||
};
|
||||
var payload = CreatePayload($"Grabbed: {message.Message}", embeds);
|
||||
|
||||
_proxy.SendPayload(payload, Settings);
|
||||
}
|
||||
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
var attachments = new List<Embed>
|
||||
{
|
||||
new Embed
|
||||
{
|
||||
Description = message.Message,
|
||||
Title = message.Artist.Name,
|
||||
Text = message.Message,
|
||||
Color = (int)DiscordColors.Success
|
||||
}
|
||||
};
|
||||
var payload = CreatePayload($"Imported: {message.Message}", attachments);
|
||||
|
||||
_proxy.SendPayload(payload, Settings);
|
||||
}
|
||||
|
||||
public override void OnRename(Artist artist)
|
||||
{
|
||||
var attachments = new List<Embed>
|
||||
{
|
||||
new Embed
|
||||
{
|
||||
Title = artist.Name,
|
||||
}
|
||||
};
|
||||
|
||||
var payload = CreatePayload("Renamed", attachments);
|
||||
|
||||
_proxy.SendPayload(payload, Settings);
|
||||
}
|
||||
|
||||
public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
|
||||
{
|
||||
var attachments = new List<Embed>
|
||||
{
|
||||
new Embed
|
||||
{
|
||||
Title = healthCheck.Source.Name,
|
||||
Text = healthCheck.Message,
|
||||
Color = healthCheck.Type == HealthCheck.HealthCheckResult.Warning ? (int)DiscordColors.Warning : (int)DiscordColors.Danger
|
||||
}
|
||||
};
|
||||
|
||||
var payload = CreatePayload("Health Issue", attachments);
|
||||
|
||||
_proxy.SendPayload(payload, Settings);
|
||||
}
|
||||
|
||||
public override void OnTrackRetag(TrackRetagMessage message)
|
||||
{
|
||||
var attachments = new List<Embed>
|
||||
{
|
||||
new Embed
|
||||
{
|
||||
Title = TRACK_RETAGGED_TITLE,
|
||||
Text = message.Message
|
||||
}
|
||||
};
|
||||
|
||||
var payload = CreatePayload($"Track file tags updated: {message.Message}", attachments);
|
||||
|
||||
_proxy.SendPayload(payload, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownloadFailure(DownloadFailedMessage message)
|
||||
{
|
||||
var attachments = new List<Embed>
|
||||
{
|
||||
new Embed
|
||||
{
|
||||
Description = message.Message,
|
||||
Title = message.SourceTitle,
|
||||
Text = message.Message,
|
||||
Color = (int)DiscordColors.Danger
|
||||
}
|
||||
};
|
||||
var payload = CreatePayload($"Download Failed: {message.Message}", attachments);
|
||||
|
||||
_proxy.SendPayload(payload, Settings);
|
||||
}
|
||||
|
||||
public override void OnImportFailure(AlbumDownloadMessage message)
|
||||
{
|
||||
var attachments = new List<Embed>
|
||||
{
|
||||
new Embed
|
||||
{
|
||||
Description = message.Message,
|
||||
Title = message.Album.Title,
|
||||
Text = message.Message,
|
||||
Color = (int)DiscordColors.Warning
|
||||
}
|
||||
};
|
||||
var payload = CreatePayload($"Import Failed: {message.Message}", attachments);
|
||||
|
||||
_proxy.SendPayload(payload, Settings);
|
||||
}
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
||||
failures.AddIfNotNull(TestMessage());
|
||||
|
||||
return new ValidationResult(failures);
|
||||
}
|
||||
|
||||
public ValidationFailure TestMessage()
|
||||
{
|
||||
try
|
||||
{
|
||||
var message = $"Test message from Lidarr posted at {DateTime.Now}";
|
||||
var payload = CreatePayload(message);
|
||||
|
||||
_proxy.SendPayload(payload, Settings);
|
||||
|
||||
}
|
||||
catch (DiscordException ex)
|
||||
{
|
||||
return new NzbDroneValidationFailure("Unable to post", ex.Message);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private DiscordPayload CreatePayload(string message, List<Embed> embeds = null)
|
||||
{
|
||||
var avatar = Settings.Avatar;
|
||||
|
||||
var payload = new DiscordPayload
|
||||
{
|
||||
Username = Settings.Username,
|
||||
Content = message,
|
||||
Embeds = embeds
|
||||
};
|
||||
|
||||
if (avatar.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
payload.AvatarUrl = avatar;
|
||||
}
|
||||
|
||||
if (Settings.Username.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
payload.Username = Settings.Username;
|
||||
}
|
||||
|
||||
return payload;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
namespace NzbDrone.Core.Notifications.Discord
|
||||
{
|
||||
public enum DiscordColors
|
||||
{
|
||||
Danger = 15749200,
|
||||
Success = 2605644,
|
||||
Warning = 16753920
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using NzbDrone.Common.Exceptions;
|
||||
|
||||
namespace NzbDrone.Core.Notifications.Discord
|
||||
{
|
||||
class DiscordException : NzbDroneException
|
||||
{
|
||||
public DiscordException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public DiscordException(string message, Exception innerException, params object[] args) : base(message, innerException, args)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
using NLog;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Notifications.Discord.Payloads;
|
||||
using NzbDrone.Core.Rest;
|
||||
|
||||
namespace NzbDrone.Core.Notifications.Discord
|
||||
{
|
||||
public interface IDiscordProxy
|
||||
{
|
||||
void SendPayload(DiscordPayload payload, DiscordSettings settings);
|
||||
}
|
||||
|
||||
public class DiscordProxy : IDiscordProxy
|
||||
{
|
||||
private readonly IHttpClient _httpClient;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public DiscordProxy(IHttpClient httpClient, Logger logger)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void SendPayload(DiscordPayload payload, DiscordSettings settings)
|
||||
{
|
||||
try
|
||||
{
|
||||
var request = new HttpRequestBuilder(settings.WebHookUrl)
|
||||
.Accept(HttpAccept.Json)
|
||||
.Build();
|
||||
|
||||
request.Method = HttpMethod.POST;
|
||||
request.Headers.ContentType = "application/json";
|
||||
request.SetContent(payload.ToJson());
|
||||
|
||||
_httpClient.Execute(request);
|
||||
}
|
||||
catch (RestException ex)
|
||||
{
|
||||
_logger.Error(ex, "Unable to post payload {0}", payload);
|
||||
throw new DiscordException("Unable to post payload", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.Notifications.Discord
|
||||
{
|
||||
public class DiscordSettingsValidator : AbstractValidator<DiscordSettings>
|
||||
{
|
||||
public DiscordSettingsValidator()
|
||||
{
|
||||
RuleFor(c => c.WebHookUrl).IsValidUrl();
|
||||
}
|
||||
}
|
||||
|
||||
public class DiscordSettings : IProviderConfig
|
||||
{
|
||||
private static readonly DiscordSettingsValidator Validator = new DiscordSettingsValidator();
|
||||
|
||||
[FieldDefinition(0, Label = "Webhook URL", HelpText = "Discord channel webhook url")]
|
||||
public string WebHookUrl { get; set; }
|
||||
|
||||
[FieldDefinition(1, Label = "Username", HelpText = "The username to post as, defaults to Discord webhook default")]
|
||||
public string Username { get; set; }
|
||||
|
||||
[FieldDefinition(2, Label = "Avatar", HelpText = "Change the avatar that is used for messages from this integration", Type = FieldType.Textbox)]
|
||||
public string Avatar { get; set; }
|
||||
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace NzbDrone.Core.Notifications.Discord.Payloads
|
||||
{
|
||||
public class DiscordPayload
|
||||
{
|
||||
public string Content { get; set; }
|
||||
|
||||
public string Username { get; set; }
|
||||
|
||||
[JsonProperty("avatar_url")]
|
||||
public string AvatarUrl { get; set; }
|
||||
|
||||
public List<Embed> Embeds { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace NzbDrone.Core.Notifications.Discord.Payloads
|
||||
{
|
||||
public class Embed
|
||||
{
|
||||
public string Description { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Text { get; set; }
|
||||
public int Color { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Music;
|
||||
using NzbDrone.Core.Languages;
|
||||
|
||||
namespace NzbDrone.Core.Notifications
|
||||
{
|
||||
public class DownloadFailedMessage
|
||||
{
|
||||
public string Message { get; set; }
|
||||
public string SourceTitle { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
public Language Language { get; set; }
|
||||
public string DownloadClient { get; set; }
|
||||
public string DownloadId { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Message;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,20 +25,28 @@ namespace NzbDrone.Core.Notifications.Email
|
|||
_emailService.SendEmail(Settings, ALBUM_GRABBED_TITLE_BRANDED, body);
|
||||
}
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage message)
|
||||
{
|
||||
var body = $"{message.Message} Downloaded and sorted.";
|
||||
|
||||
_emailService.SendEmail(Settings, TRACK_DOWNLOADED_TITLE_BRANDED, body);
|
||||
}
|
||||
|
||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
var body = $"{message.Message} Downloaded and sorted.";
|
||||
|
||||
_emailService.SendEmail(Settings, ALBUM_DOWNLOADED_TITLE_BRANDED, body);
|
||||
}
|
||||
|
||||
public override void OnHealthIssue(HealthCheck.HealthCheck message)
|
||||
{
|
||||
_emailService.SendEmail(Settings, HEALTH_ISSUE_TITLE_BRANDED, message.Message);
|
||||
}
|
||||
|
||||
public override void OnDownloadFailure(DownloadFailedMessage message)
|
||||
{
|
||||
_emailService.SendEmail(Settings, DOWNLOAD_FAILURE_TITLE_BRANDED, message.Message);
|
||||
}
|
||||
|
||||
public override void OnImportFailure(AlbumDownloadMessage message)
|
||||
{
|
||||
_emailService.SendEmail(Settings, IMPORT_FAILURE_TITLE_BRANDED, message.Message);
|
||||
}
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
|
|
@ -23,16 +23,26 @@ namespace NzbDrone.Core.Notifications.Growl
|
|||
_growlService.SendNotification(ALBUM_GRABBED_TITLE, grabMessage.Message, "GRAB", Settings.Host, Settings.Port, Settings.Password);
|
||||
}
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage message)
|
||||
{
|
||||
_growlService.SendNotification(TRACK_DOWNLOADED_TITLE, message.Message, "TRACKDOWNLOAD", Settings.Host, Settings.Port, Settings.Password);
|
||||
}
|
||||
|
||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
_growlService.SendNotification(ALBUM_DOWNLOADED_TITLE, message.Message, "ALBUMDOWNLOAD", Settings.Host, Settings.Port, Settings.Password);
|
||||
}
|
||||
|
||||
public override void OnHealthIssue(HealthCheck.HealthCheck message)
|
||||
{
|
||||
_growlService.SendNotification(HEALTH_ISSUE_TITLE, message.Message, "HEALTHISSUE", Settings.Host, Settings.Port, Settings.Password);
|
||||
}
|
||||
|
||||
public override void OnDownloadFailure(DownloadFailedMessage message)
|
||||
{
|
||||
_growlService.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, "DOWNLOADFAILURE", Settings.Host, Settings.Port, Settings.Password);
|
||||
}
|
||||
|
||||
public override void OnImportFailure(AlbumDownloadMessage message)
|
||||
{
|
||||
_growlService.SendNotification(IMPORT_FAILURE_TITLE, message.Message, "IMPORTFAILURE", Settings.Host, Settings.Port, Settings.Password);
|
||||
}
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
|
|
@ -8,13 +8,19 @@ namespace NzbDrone.Core.Notifications
|
|||
string Link { get; }
|
||||
|
||||
void OnGrab(GrabMessage grabMessage);
|
||||
void OnDownload(TrackDownloadMessage message);
|
||||
void OnAlbumDownload(AlbumDownloadMessage message);
|
||||
void OnReleaseImport(AlbumDownloadMessage message);
|
||||
void OnRename(Artist artist);
|
||||
void OnHealthIssue(HealthCheck.HealthCheck healthCheck);
|
||||
void OnDownloadFailure(DownloadFailedMessage message);
|
||||
void OnImportFailure(AlbumDownloadMessage message);
|
||||
void OnTrackRetag(TrackRetagMessage message);
|
||||
bool SupportsOnGrab { get; }
|
||||
bool SupportsOnDownload { get; }
|
||||
bool SupportsOnAlbumDownload { get; }
|
||||
bool SupportsOnReleaseImport { get; }
|
||||
bool SupportsOnUpgrade { get; }
|
||||
bool SupportsOnRename { get; }
|
||||
bool SupportsOnHealthIssue { get; }
|
||||
bool SupportsOnDownloadFailure { get; }
|
||||
bool SupportsOnImportFailure { get; }
|
||||
bool SupportsOnTrackRetag { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,16 +22,16 @@ namespace NzbDrone.Core.Notifications.Join
|
|||
_proxy.SendNotification(ALBUM_GRABBED_TITLE_BRANDED, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage message)
|
||||
{
|
||||
_proxy.SendNotification(TRACK_DOWNLOADED_TITLE_BRANDED, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
_proxy.SendNotification(ALBUM_DOWNLOADED_TITLE_BRANDED, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnHealthIssue(HealthCheck.HealthCheck message)
|
||||
{
|
||||
_proxy.SendNotification(HEALTH_ISSUE_TITLE_BRANDED, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace NzbDrone.Core.Notifications.Emby
|
|||
}
|
||||
}
|
||||
|
||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
if (Settings.Notify)
|
||||
{
|
||||
|
@ -39,14 +39,6 @@ namespace NzbDrone.Core.Notifications.Emby
|
|||
}
|
||||
}
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage message)
|
||||
{
|
||||
if (Settings.Notify)
|
||||
{
|
||||
_mediaBrowserService.Notify(Settings, TRACK_DOWNLOADED_TITLE_BRANDED, message.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnRename(Artist artist)
|
||||
{
|
||||
if (Settings.UpdateLibrary)
|
||||
|
@ -55,6 +47,21 @@ namespace NzbDrone.Core.Notifications.Emby
|
|||
}
|
||||
}
|
||||
|
||||
public override void OnHealthIssue(HealthCheck.HealthCheck message)
|
||||
{
|
||||
if (Settings.Notify)
|
||||
{
|
||||
_mediaBrowserService.Notify(Settings, HEALTH_ISSUE_TITLE_BRANDED, message.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnTrackRetag(TrackRetagMessage message)
|
||||
{
|
||||
if (Settings.Notify)
|
||||
{
|
||||
_mediaBrowserService.Notify(Settings, TRACK_RETAGGED_TITLE_BRANDED, message.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
|
|
|
@ -9,12 +9,18 @@ namespace NzbDrone.Core.Notifications
|
|||
public abstract class NotificationBase<TSettings> : INotification where TSettings : IProviderConfig, new()
|
||||
{
|
||||
protected const string ALBUM_GRABBED_TITLE = "Album Grabbed";
|
||||
protected const string TRACK_DOWNLOADED_TITLE = "Track Downloaded";
|
||||
protected const string ALBUM_DOWNLOADED_TITLE = "Album Downloaded";
|
||||
protected const string HEALTH_ISSUE_TITLE = "Health Check Failure";
|
||||
protected const string DOWNLOAD_FAILURE_TITLE = "Download Failed";
|
||||
protected const string IMPORT_FAILURE_TITLE = "Import Failed";
|
||||
protected const string TRACK_RETAGGED_TITLE = "Track File Tags Updated";
|
||||
|
||||
protected const string ALBUM_GRABBED_TITLE_BRANDED = "Lidarr - " + ALBUM_GRABBED_TITLE;
|
||||
protected const string TRACK_DOWNLOADED_TITLE_BRANDED = "Lidarr - " + TRACK_DOWNLOADED_TITLE;
|
||||
protected const string ALBUM_DOWNLOADED_TITLE_BRANDED = "Lidarr - " + ALBUM_DOWNLOADED_TITLE;
|
||||
protected const string HEALTH_ISSUE_TITLE_BRANDED = "Lidarr - " + HEALTH_ISSUE_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 TRACK_RETAGGED_TITLE_BRANDED = "Lidarr - " + TRACK_RETAGGED_TITLE;
|
||||
|
||||
public abstract string Name { get; }
|
||||
|
||||
|
@ -34,12 +40,7 @@ namespace NzbDrone.Core.Notifications
|
|||
|
||||
}
|
||||
|
||||
public virtual void OnDownload(TrackDownloadMessage message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void OnAlbumDownload(AlbumDownloadMessage message)
|
||||
public virtual void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -49,11 +50,34 @@ namespace NzbDrone.Core.Notifications
|
|||
|
||||
}
|
||||
|
||||
public virtual void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void OnDownloadFailure(DownloadFailedMessage message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void OnImportFailure(AlbumDownloadMessage message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void OnTrackRetag(TrackRetagMessage message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool SupportsOnGrab => HasConcreteImplementation("OnGrab");
|
||||
public bool SupportsOnRename => HasConcreteImplementation("OnRename");
|
||||
public bool SupportsOnDownload => HasConcreteImplementation("OnDownload");
|
||||
public bool SupportsOnAlbumDownload => HasConcreteImplementation("OnAlbumDownload");
|
||||
public bool SupportsOnUpgrade => SupportsOnDownload;
|
||||
public bool SupportsOnReleaseImport => HasConcreteImplementation("OnReleaseImport");
|
||||
public bool SupportsOnUpgrade => SupportsOnReleaseImport;
|
||||
public bool SupportsOnHealthIssue => HasConcreteImplementation("OnHealthIssue");
|
||||
public bool SupportsOnDownloadFailure => HasConcreteImplementation("OnDownloadFailure");
|
||||
public bool SupportsOnImportFailure => HasConcreteImplementation("OnImportFailure");
|
||||
public bool SupportsOnTrackRetag => HasConcreteImplementation("OnTrackRetag");
|
||||
|
||||
protected TSettings Settings => (TSettings)Definition.Settings;
|
||||
|
||||
|
|
|
@ -6,16 +6,23 @@ namespace NzbDrone.Core.Notifications
|
|||
{
|
||||
|
||||
public bool OnGrab { get; set; }
|
||||
public bool OnDownload { get; set; }
|
||||
public bool OnAlbumDownload { get; set; }
|
||||
public bool OnReleaseImport { get; set; }
|
||||
public bool OnUpgrade { get; set; }
|
||||
public bool OnRename { get; set; }
|
||||
public bool OnHealthIssue { get; set; }
|
||||
public bool OnDownloadFailure { get; set; }
|
||||
public bool OnImportFailure { get; set; }
|
||||
public bool OnTrackRetag { get; set; }
|
||||
public bool SupportsOnGrab { get; set; }
|
||||
public bool SupportsOnDownload { get; set; }
|
||||
public bool SupportsOnAlbumDownload { get; set; }
|
||||
public bool SupportsOnReleaseImport { get; set; }
|
||||
public bool SupportsOnUpgrade { get; set; }
|
||||
public bool SupportsOnRename { get; set; }
|
||||
public bool SupportsOnHealthIssue { get; set; }
|
||||
public bool IncludeHealthWarnings { get; set; }
|
||||
public bool SupportsOnDownloadFailure { get; set; }
|
||||
public bool SupportsOnImportFailure { get; set; }
|
||||
public bool SupportsOnTrackRetag { get; set; }
|
||||
|
||||
public override bool Enable => OnGrab || OnDownload || OnAlbumDownload || (OnDownload && OnUpgrade);
|
||||
public override bool Enable => OnGrab || OnReleaseImport || (OnReleaseImport && OnUpgrade) || OnHealthIssue || OnDownloadFailure || OnImportFailure || OnTrackRetag;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,10 +10,13 @@ namespace NzbDrone.Core.Notifications
|
|||
public interface INotificationFactory : IProviderFactory<INotification, NotificationDefinition>
|
||||
{
|
||||
List<INotification> OnGrabEnabled();
|
||||
List<INotification> OnDownloadEnabled();
|
||||
List<INotification> OnAlbumDownloadEnabled();
|
||||
List<INotification> OnReleaseImportEnabled();
|
||||
List<INotification> OnUpgradeEnabled();
|
||||
List<INotification> OnRenameEnabled();
|
||||
List<INotification> OnHealthIssueEnabled();
|
||||
List<INotification> OnDownloadFailureEnabled();
|
||||
List<INotification> OnImportFailureEnabled();
|
||||
List<INotification> OnTrackRetagEnabled();
|
||||
}
|
||||
|
||||
public class NotificationFactory : ProviderFactory<INotification, NotificationDefinition>, INotificationFactory
|
||||
|
@ -28,14 +31,9 @@ namespace NzbDrone.Core.Notifications
|
|||
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnGrab).ToList();
|
||||
}
|
||||
|
||||
public List<INotification> OnDownloadEnabled()
|
||||
public List<INotification> OnReleaseImportEnabled()
|
||||
{
|
||||
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnDownload).ToList();
|
||||
}
|
||||
|
||||
public List<INotification> OnAlbumDownloadEnabled()
|
||||
{
|
||||
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnAlbumDownload).ToList();
|
||||
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnReleaseImport).ToList();
|
||||
}
|
||||
|
||||
public List<INotification> OnUpgradeEnabled()
|
||||
|
@ -48,15 +46,38 @@ namespace NzbDrone.Core.Notifications
|
|||
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnRename).ToList();
|
||||
}
|
||||
|
||||
public List<INotification> OnHealthIssueEnabled()
|
||||
{
|
||||
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnHealthIssue).ToList();
|
||||
}
|
||||
|
||||
public List<INotification> OnDownloadFailureEnabled()
|
||||
{
|
||||
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnDownloadFailure).ToList();
|
||||
}
|
||||
|
||||
public List<INotification> OnImportFailureEnabled()
|
||||
{
|
||||
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnImportFailure).ToList();
|
||||
}
|
||||
|
||||
public List<INotification> OnTrackRetagEnabled()
|
||||
{
|
||||
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnTrackRetag).ToList();
|
||||
}
|
||||
|
||||
public override void SetProviderCharacteristics(INotification provider, NotificationDefinition definition)
|
||||
{
|
||||
base.SetProviderCharacteristics(provider, definition);
|
||||
|
||||
definition.SupportsOnGrab = provider.SupportsOnGrab;
|
||||
definition.SupportsOnDownload = provider.SupportsOnDownload;
|
||||
definition.SupportsOnAlbumDownload = provider.SupportsOnAlbumDownload;
|
||||
definition.SupportsOnReleaseImport = provider.SupportsOnReleaseImport;
|
||||
definition.SupportsOnUpgrade = provider.SupportsOnUpgrade;
|
||||
definition.SupportsOnRename = provider.SupportsOnRename;
|
||||
definition.SupportsOnHealthIssue = provider.SupportsOnHealthIssue;
|
||||
definition.SupportsOnDownloadFailure = provider.SupportsOnDownloadFailure;
|
||||
definition.SupportsOnImportFailure = provider.SupportsOnImportFailure;
|
||||
definition.SupportsOnTrackRetag = provider.SupportsOnTrackRetag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
|
||||
|
@ -7,7 +7,6 @@ namespace NzbDrone.Core.Notifications
|
|||
{
|
||||
public interface INotificationRepository : IProviderRepository<NotificationDefinition>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class NotificationRepository : ProviderRepository<NotificationDefinition>, INotificationRepository
|
||||
|
@ -17,4 +16,4 @@ namespace NzbDrone.Core.Notifications
|
|||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,15 +10,19 @@ using NzbDrone.Core.Messaging.Events;
|
|||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
using NzbDrone.Core.Music;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.HealthCheck;
|
||||
using System.IO;
|
||||
|
||||
namespace NzbDrone.Core.Notifications
|
||||
{
|
||||
public class NotificationService
|
||||
: IHandle<AlbumGrabbedEvent>,
|
||||
IHandle<TrackImportedEvent>,
|
||||
IHandle<AlbumImportedEvent>,
|
||||
IHandle<ArtistRenamedEvent>
|
||||
IHandle<ArtistRenamedEvent>,
|
||||
IHandle<HealthCheckFailedEvent>,
|
||||
IHandle<DownloadFailedEvent>,
|
||||
IHandle<AlbumImportIncompleteEvent>,
|
||||
IHandle<TrackFileRetaggedEvent>
|
||||
{
|
||||
private readonly INotificationFactory _notificationFactory;
|
||||
private readonly Logger _logger;
|
||||
|
@ -47,24 +51,6 @@ namespace NzbDrone.Core.Notifications
|
|||
qualityString);
|
||||
}
|
||||
|
||||
private string GetTrackMessage(Artist artist, List<Track> tracks, QualityModel quality)
|
||||
{
|
||||
var qualityString = quality.Quality.ToString();
|
||||
|
||||
if (quality.Revision.Version > 1)
|
||||
{
|
||||
qualityString += " Proper";
|
||||
}
|
||||
|
||||
|
||||
var trackTitles = string.Join(" + ", tracks.Select(e => e.Title));
|
||||
|
||||
return string.Format("{0} - {1} - [{2}]",
|
||||
artist.Name,
|
||||
trackTitles,
|
||||
qualityString);
|
||||
}
|
||||
|
||||
private string GetAlbumDownloadMessage(Artist artist, Album album, List<TrackFile> tracks)
|
||||
{
|
||||
return string.Format("{0} - {1} ({2} Tracks Imported)",
|
||||
|
@ -73,6 +59,25 @@ namespace NzbDrone.Core.Notifications
|
|||
tracks.Count);
|
||||
}
|
||||
|
||||
private string GetAlbumIncompleteImportMessage(string source)
|
||||
{
|
||||
return string.Format("Lidarr failed to Import all tracks for {0}",
|
||||
source);
|
||||
}
|
||||
|
||||
private string FormatMissing(object value)
|
||||
{
|
||||
var text = value?.ToString();
|
||||
return text.IsNullOrWhiteSpace() ? "<missing>" : text;
|
||||
}
|
||||
|
||||
private string GetTrackRetagMessage(Artist artist, TrackFile trackFile, Dictionary<string, Tuple<string, string>> diff)
|
||||
{
|
||||
return string.Format("{0}:\n{1}",
|
||||
Path.Combine(artist.Path, trackFile.RelativePath),
|
||||
string.Join("\n", diff.Select(x => $"{x.Key}: {FormatMissing(x.Value.Item1)} → {FormatMissing(x.Value.Item2)}")));
|
||||
}
|
||||
|
||||
private bool ShouldHandleArtist(ProviderDefinition definition, Artist artist)
|
||||
{
|
||||
if (definition.Tags.Empty())
|
||||
|
@ -92,6 +97,21 @@ namespace NzbDrone.Core.Notifications
|
|||
return false;
|
||||
}
|
||||
|
||||
private bool ShouldHandleHealthFailure(HealthCheck.HealthCheck healthCheck, bool includeWarnings)
|
||||
{
|
||||
if (healthCheck.Type == HealthCheckResult.Error)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (healthCheck.Type == HealthCheckResult.Warning && includeWarnings)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Handle(AlbumGrabbedEvent message)
|
||||
{
|
||||
var grabMessage = new GrabMessage
|
||||
|
@ -119,47 +139,6 @@ namespace NzbDrone.Core.Notifications
|
|||
}
|
||||
}
|
||||
|
||||
public void Handle(TrackImportedEvent message)
|
||||
{
|
||||
if (!message.NewDownload)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var downloadMessage = new TrackDownloadMessage
|
||||
|
||||
{
|
||||
Message = GetTrackMessage(message.TrackInfo.Artist, message.TrackInfo.Tracks, message.TrackInfo.Quality),
|
||||
Artist = message.TrackInfo.Artist,
|
||||
Album = message.TrackInfo.Album,
|
||||
Release = message.TrackInfo.Release,
|
||||
TrackFile = message.ImportedTrack,
|
||||
OldFiles = message.OldFiles,
|
||||
SourcePath = message.TrackInfo.Path,
|
||||
DownloadClient = message.DownloadClient,
|
||||
DownloadId = message.DownloadId
|
||||
};
|
||||
|
||||
foreach (var notification in _notificationFactory.OnDownloadEnabled())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ShouldHandleArtist(notification.Definition, message.TrackInfo.Artist))
|
||||
{
|
||||
if (downloadMessage.OldFiles.Empty() || ((NotificationDefinition)notification.Definition).OnUpgrade)
|
||||
{
|
||||
notification.OnDownload(downloadMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warn(ex, "Unable to send OnDownload notification to: " + notification.Definition.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(AlbumImportedEvent message)
|
||||
{
|
||||
if (!message.NewDownload)
|
||||
|
@ -180,19 +159,22 @@ namespace NzbDrone.Core.Notifications
|
|||
OldFiles = message.OldFiles,
|
||||
};
|
||||
|
||||
foreach (var notification in _notificationFactory.OnAlbumDownloadEnabled())
|
||||
foreach (var notification in _notificationFactory.OnReleaseImportEnabled())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ShouldHandleArtist(notification.Definition, message.Artist))
|
||||
{
|
||||
notification.OnAlbumDownload(downloadMessage);
|
||||
if (downloadMessage.OldFiles.Empty() || ((NotificationDefinition)notification.Definition).OnUpgrade)
|
||||
{
|
||||
notification.OnReleaseImport(downloadMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warn(ex, "Unable to send OnDownload notification to: " + notification.Definition.Name);
|
||||
_logger.Warn(ex, "Unable to send OnReleaseImport notification to: " + notification.Definition.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -215,5 +197,85 @@ namespace NzbDrone.Core.Notifications
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(HealthCheckFailedEvent message)
|
||||
{
|
||||
foreach (var notification in _notificationFactory.OnHealthIssueEnabled())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ShouldHandleHealthFailure(message.HealthCheck, ((NotificationDefinition)notification.Definition).IncludeHealthWarnings))
|
||||
{
|
||||
notification.OnHealthIssue(message.HealthCheck);
|
||||
}
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warn(ex, "Unable to send OnHealthIssue notification to: " + notification.Definition.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(DownloadFailedEvent message)
|
||||
{
|
||||
var downloadFailedMessage = new DownloadFailedMessage
|
||||
{
|
||||
DownloadId = message.DownloadId,
|
||||
DownloadClient = message.DownloadClient,
|
||||
Quality = message.Quality,
|
||||
Language = message.Language,
|
||||
SourceTitle = message.SourceTitle,
|
||||
Message = message.Message
|
||||
|
||||
};
|
||||
|
||||
foreach (var notification in _notificationFactory.OnDownloadFailureEnabled())
|
||||
{
|
||||
if (ShouldHandleArtist(notification.Definition, message.TrackedDownload.RemoteAlbum.Artist))
|
||||
{
|
||||
notification.OnDownloadFailure(downloadFailedMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(AlbumImportIncompleteEvent message)
|
||||
{
|
||||
// TODO: Build out this message so that we can pass on what failed and what was successful
|
||||
var downloadMessage = new AlbumDownloadMessage
|
||||
{
|
||||
Message = GetAlbumIncompleteImportMessage(message.TrackedDownload.RemoteAlbum.Release.Title),
|
||||
};
|
||||
|
||||
foreach (var notification in _notificationFactory.OnDownloadFailureEnabled())
|
||||
{
|
||||
if (ShouldHandleArtist(notification.Definition, message.TrackedDownload.RemoteAlbum.Artist))
|
||||
{
|
||||
notification.OnImportFailure(downloadMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(TrackFileRetaggedEvent message)
|
||||
{
|
||||
var retagMessage = new TrackRetagMessage
|
||||
{
|
||||
Message = GetTrackRetagMessage(message.Artist, message.TrackFile, message.Diff),
|
||||
Artist = message.Artist,
|
||||
Album = message.TrackFile.Album,
|
||||
Release = message.TrackFile.Tracks.Value.First().AlbumRelease.Value,
|
||||
TrackFile = message.TrackFile,
|
||||
Diff = message.Diff,
|
||||
Scrubbed = message.Scrubbed
|
||||
};
|
||||
|
||||
foreach (var notification in _notificationFactory.OnTrackRetagEnabled())
|
||||
{
|
||||
if (ShouldHandleArtist(notification.Definition, message.Artist))
|
||||
{
|
||||
notification.OnTrackRetag(retagMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,16 +21,16 @@ namespace NzbDrone.Core.Notifications.Plex.HomeTheater
|
|||
_plexClientService.Notify(Settings, ALBUM_GRABBED_TITLE_BRANDED, grabMessage.Message);
|
||||
}
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage message)
|
||||
{
|
||||
_plexClientService.Notify(Settings, TRACK_DOWNLOADED_TITLE_BRANDED, message.Message);
|
||||
}
|
||||
|
||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
_plexClientService.Notify(Settings, ALBUM_DOWNLOADED_TITLE_BRANDED, message.Message);
|
||||
}
|
||||
|
||||
public override void OnHealthIssue(HealthCheck.HealthCheck message)
|
||||
{
|
||||
_plexClientService.Notify(Settings, HEALTH_ISSUE_TITLE_BRANDED, message.Message);
|
||||
}
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
|
|
@ -26,9 +26,9 @@ namespace NzbDrone.Core.Notifications.Plex.HomeTheater
|
|||
Notify(ALBUM_GRABBED_TITLE_BRANDED, grabMessage.Message);
|
||||
}
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
Notify(TRACK_DOWNLOADED_TITLE_BRANDED, message.Message);
|
||||
Notify(ALBUM_DOWNLOADED_TITLE_BRANDED, message.Message);
|
||||
}
|
||||
|
||||
public override ValidationResult Test()
|
||||
|
|
|
@ -23,12 +23,7 @@ namespace NzbDrone.Core.Notifications.Plex.Server
|
|||
public override string Link => "https://www.plex.tv/";
|
||||
public override string Name => "Plex Media Server";
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage message)
|
||||
{
|
||||
UpdateIfEnabled(message.Artist);
|
||||
}
|
||||
|
||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
UpdateIfEnabled(message.Artist);
|
||||
}
|
||||
|
@ -38,6 +33,11 @@ namespace NzbDrone.Core.Notifications.Plex.Server
|
|||
UpdateIfEnabled(artist);
|
||||
}
|
||||
|
||||
public override void OnTrackRetag(TrackRetagMessage message)
|
||||
{
|
||||
UpdateIfEnabled(message.Artist);
|
||||
}
|
||||
|
||||
private void UpdateIfEnabled(Artist artist)
|
||||
{
|
||||
if (Settings.UpdateLibrary)
|
||||
|
|
|
@ -22,16 +22,16 @@ namespace NzbDrone.Core.Notifications.Prowl
|
|||
_prowlService.SendNotification(ALBUM_GRABBED_TITLE, grabMessage.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
||||
}
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage message)
|
||||
{
|
||||
_prowlService.SendNotification(TRACK_DOWNLOADED_TITLE, message.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
||||
}
|
||||
|
||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
_prowlService.SendNotification(ALBUM_DOWNLOADED_TITLE, message.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
||||
}
|
||||
|
||||
public override void OnHealthIssue(HealthCheck.HealthCheck message)
|
||||
{
|
||||
_prowlService.SendNotification(HEALTH_ISSUE_TITLE, message.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
||||
}
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
|
|
@ -24,16 +24,26 @@ namespace NzbDrone.Core.Notifications.PushBullet
|
|||
_proxy.SendNotification(ALBUM_GRABBED_TITLE_BRANDED, grabMessage.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage message)
|
||||
{
|
||||
_proxy.SendNotification(TRACK_DOWNLOADED_TITLE_BRANDED, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
_proxy.SendNotification(ALBUM_DOWNLOADED_TITLE_BRANDED, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
|
||||
{
|
||||
_proxy.SendNotification(HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownloadFailure(DownloadFailedMessage message)
|
||||
{
|
||||
_proxy.SendNotification(DOWNLOAD_FAILURE_TITLE_BRANDED, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnImportFailure(AlbumDownloadMessage message)
|
||||
{
|
||||
_proxy.SendNotification(IMPORT_FAILURE_TITLE_BRANDED, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
|
|
@ -21,16 +21,26 @@ namespace NzbDrone.Core.Notifications.Pushover
|
|||
_proxy.SendNotification(ALBUM_GRABBED_TITLE, grabMessage.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage message)
|
||||
{
|
||||
_proxy.SendNotification(TRACK_DOWNLOADED_TITLE, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
_proxy.SendNotification(ALBUM_DOWNLOADED_TITLE, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
|
||||
{
|
||||
_proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownloadFailure(DownloadFailedMessage message)
|
||||
{
|
||||
_proxy.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnImportFailure(AlbumDownloadMessage message)
|
||||
{
|
||||
_proxy.SendNotification(IMPORT_FAILURE_TITLE, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Notifications.Slack.Payloads;
|
||||
using NzbDrone.Core.Rest;
|
||||
using NzbDrone.Core.Music;
|
||||
using NzbDrone.Core.Validation;
|
||||
using RestSharp;
|
||||
|
||||
|
||||
namespace NzbDrone.Core.Notifications.Slack
|
||||
|
@ -17,12 +13,10 @@ namespace NzbDrone.Core.Notifications.Slack
|
|||
public class Slack : NotificationBase<SlackSettings>
|
||||
{
|
||||
private readonly ISlackProxy _proxy;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public Slack(ISlackProxy proxy, Logger logger)
|
||||
public Slack(ISlackProxy proxy)
|
||||
{
|
||||
_proxy = proxy;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public override string Name => "Slack";
|
||||
|
@ -45,24 +39,7 @@ namespace NzbDrone.Core.Notifications.Slack
|
|||
_proxy.SendPayload(payload, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage message)
|
||||
{
|
||||
var attachments = new List<Attachment>
|
||||
{
|
||||
new Attachment
|
||||
{
|
||||
Fallback = message.Message,
|
||||
Title = message.Artist.Name,
|
||||
Text = message.Message,
|
||||
Color = "good"
|
||||
}
|
||||
};
|
||||
var payload = CreatePayload($"Imported: {message.Message}", attachments);
|
||||
|
||||
_proxy.SendPayload(payload, Settings);
|
||||
}
|
||||
|
||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
var attachments = new List<Attachment>
|
||||
{
|
||||
|
@ -94,6 +71,73 @@ namespace NzbDrone.Core.Notifications.Slack
|
|||
_proxy.SendPayload(payload, Settings);
|
||||
}
|
||||
|
||||
public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
|
||||
{
|
||||
var attachments = new List<Attachment>
|
||||
{
|
||||
new Attachment
|
||||
{
|
||||
Title = healthCheck.Source.Name,
|
||||
Text = healthCheck.Message,
|
||||
Color = healthCheck.Type == HealthCheck.HealthCheckResult.Warning ? "warning" : "danger"
|
||||
}
|
||||
};
|
||||
|
||||
var payload = CreatePayload("Health Issue", attachments);
|
||||
|
||||
_proxy.SendPayload(payload, Settings);
|
||||
}
|
||||
|
||||
public override void OnTrackRetag(TrackRetagMessage message)
|
||||
{
|
||||
var attachments = new List<Attachment>
|
||||
{
|
||||
new Attachment
|
||||
{
|
||||
Title = TRACK_RETAGGED_TITLE,
|
||||
Text = message.Message
|
||||
}
|
||||
};
|
||||
|
||||
var payload = CreatePayload(TRACK_RETAGGED_TITLE, attachments);
|
||||
|
||||
_proxy.SendPayload(payload, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownloadFailure(DownloadFailedMessage message)
|
||||
{
|
||||
var attachments = new List<Attachment>
|
||||
{
|
||||
new Attachment
|
||||
{
|
||||
Fallback = message.Message,
|
||||
Title = message.SourceTitle,
|
||||
Text = message.Message,
|
||||
Color = "danger"
|
||||
}
|
||||
};
|
||||
var payload = CreatePayload($"Download Failed: {message.Message}", attachments);
|
||||
|
||||
_proxy.SendPayload(payload, Settings);
|
||||
}
|
||||
|
||||
public override void OnImportFailure(AlbumDownloadMessage message)
|
||||
{
|
||||
var attachments = new List<Attachment>
|
||||
{
|
||||
new Attachment
|
||||
{
|
||||
Fallback = message.Message,
|
||||
Title = message.Album.Title,
|
||||
Text = message.Message,
|
||||
Color = "warning"
|
||||
}
|
||||
};
|
||||
var payload = CreatePayload($"Import Failed: {message.Message}", attachments);
|
||||
|
||||
_proxy.SendPayload(payload, Settings);
|
||||
}
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace NzbDrone.Core.Notifications.Subsonic
|
|||
Notify(Settings, header, grabMessage.Message);
|
||||
}
|
||||
|
||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
const string header = "Lidarr - Downloaded";
|
||||
|
||||
|
@ -36,19 +36,21 @@ namespace NzbDrone.Core.Notifications.Subsonic
|
|||
Update();
|
||||
}
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage message)
|
||||
{
|
||||
const string header = "Lidarr - Downloaded";
|
||||
|
||||
Notify(Settings, header, message.Message);
|
||||
|
||||
}
|
||||
|
||||
public override void OnRename(Artist artist)
|
||||
{
|
||||
Update();
|
||||
}
|
||||
|
||||
public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
|
||||
{
|
||||
Notify(Settings, HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message);
|
||||
}
|
||||
|
||||
public override void OnTrackRetag(TrackRetagMessage message)
|
||||
{
|
||||
Notify(Settings, TRACK_RETAGGED_TITLE_BRANDED, message.Message);
|
||||
}
|
||||
|
||||
public override string Name => "Subsonic";
|
||||
|
||||
public override ValidationResult Test()
|
||||
|
|
|
@ -20,8 +20,7 @@ namespace NzbDrone.Core.Notifications.Synology
|
|||
public override string Link => "https://www.synology.com";
|
||||
public override string Name => "Synology Indexer";
|
||||
|
||||
|
||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
if (Settings.UpdateLibrary)
|
||||
{
|
||||
|
@ -49,6 +48,13 @@ namespace NzbDrone.Core.Notifications.Synology
|
|||
}
|
||||
}
|
||||
|
||||
public override void OnTrackRetag(TrackRetagMessage message)
|
||||
{
|
||||
if (Settings.UpdateLibrary)
|
||||
{
|
||||
_indexerProxy.UpdateFolder(message.Artist.Path);
|
||||
}
|
||||
}
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
|
|
|
@ -21,14 +21,24 @@ namespace NzbDrone.Core.Notifications.Telegram
|
|||
_proxy.SendNotification(ALBUM_GRABBED_TITLE, grabMessage.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
_proxy.SendNotification(TRACK_DOWNLOADED_TITLE, message.Message, Settings);
|
||||
_proxy.SendNotification(ALBUM_DOWNLOADED_TITLE, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
||||
public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
|
||||
{
|
||||
_proxy.SendNotification(TRACK_DOWNLOADED_TITLE, message.Message, Settings);
|
||||
_proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownloadFailure(DownloadFailedMessage message)
|
||||
{
|
||||
_proxy.SendNotification(DOWNLOAD_FAILURE_TITLE, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override void OnImportFailure(AlbumDownloadMessage message)
|
||||
{
|
||||
_proxy.SendNotification(IMPORT_FAILURE_TITLE, message.Message, Settings);
|
||||
}
|
||||
|
||||
public override ValidationResult Test()
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Music;
|
||||
|
||||
namespace NzbDrone.Core.Notifications
|
||||
{
|
||||
public class TrackDownloadMessage
|
||||
public class TrackRetagMessage
|
||||
{
|
||||
public string Message { get; set; }
|
||||
public Artist Artist { get; set; }
|
||||
public Album Album { get; set; }
|
||||
public AlbumRelease Release { get; set; }
|
||||
public TrackFile TrackFile { get; set; }
|
||||
public List<TrackFile> OldFiles { get; set; }
|
||||
public string SourcePath { get; set; }
|
||||
public string DownloadClient { get; set; }
|
||||
public string DownloadId { get; set; }
|
||||
public Dictionary<string, Tuple<string, string>> Diff { get; set; }
|
||||
public bool Scrubbed { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
|
@ -24,14 +24,24 @@ namespace NzbDrone.Core.Notifications.Twitter
|
|||
_twitterService.SendNotification($"Grabbed: {message.Message}", Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
_twitterService.SendNotification($"Imported: {message.Message}", Settings);
|
||||
}
|
||||
|
||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
||||
public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
|
||||
{
|
||||
_twitterService.SendNotification($"Imported: {message.Message}", Settings);
|
||||
_twitterService.SendNotification($"Health Issue: {healthCheck.Message}", Settings);
|
||||
}
|
||||
|
||||
public override void OnDownloadFailure(DownloadFailedMessage message)
|
||||
{
|
||||
_twitterService.SendNotification($"Download Failed: {message.Message}", Settings);
|
||||
}
|
||||
|
||||
public override void OnImportFailure(AlbumDownloadMessage message)
|
||||
{
|
||||
_twitterService.SendNotification($"Import Failed: {message.Message}", Settings);
|
||||
}
|
||||
|
||||
public override object RequestAction(string action, IDictionary<string, string> query)
|
||||
|
|
|
@ -41,23 +41,23 @@ namespace NzbDrone.Core.Notifications.Webhook
|
|||
_proxy.SendWebhook(payload, Settings);
|
||||
}
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
var trackFile = message.TrackFile;
|
||||
var trackFiles = message.TrackFiles;
|
||||
|
||||
var payload = new WebhookImportPayload
|
||||
|
||||
{
|
||||
EventType = "Download",
|
||||
Artist = new WebhookArtist(message.Artist),
|
||||
Tracks = trackFile.Tracks.Value.ConvertAll(x => new WebhookTrack(x)
|
||||
Tracks = trackFiles.SelectMany(x => x.Tracks.Value.Select(y => new WebhookTrack(y)
|
||||
{
|
||||
// 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),
|
||||
Quality = x.Quality.Quality.Name,
|
||||
QualityVersion = x.Quality.Revision.Version,
|
||||
ReleaseGroup = x.ReleaseGroup
|
||||
})).ToList(),
|
||||
TrackFiles = trackFiles.ConvertAll(x => new WebhookTrackFile(x)),
|
||||
IsUpgrade = message.OldFiles.Any()
|
||||
};
|
||||
|
||||
|
@ -75,6 +75,17 @@ namespace NzbDrone.Core.Notifications.Webhook
|
|||
_proxy.SendWebhook(payload, Settings);
|
||||
}
|
||||
|
||||
public override void OnTrackRetag(TrackRetagMessage message)
|
||||
{
|
||||
var payload = new WebhookPayload
|
||||
{
|
||||
EventType = "Retag",
|
||||
Artist = new WebhookArtist(message.Artist)
|
||||
};
|
||||
|
||||
_proxy.SendWebhook(payload, Settings);
|
||||
}
|
||||
|
||||
public override string Name => "Webhook";
|
||||
|
||||
public override ValidationResult Test()
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace NzbDrone.Core.Notifications.Webhook
|
|||
public class WebhookImportPayload : WebhookPayload
|
||||
{
|
||||
public List<WebhookTrack> Tracks { get; set; }
|
||||
public WebhookTrackFile TrackFile { get; set; }
|
||||
public List<WebhookTrackFile> TrackFiles { get; set; }
|
||||
public bool IsUpgrade { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,14 +28,7 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
|||
Notify(Settings, header, grabMessage.Message);
|
||||
}
|
||||
|
||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
||||
{
|
||||
const string header = "Lidarr - Downloaded";
|
||||
|
||||
Notify(Settings, header, message.Message);
|
||||
}
|
||||
|
||||
public override void OnDownload(TrackDownloadMessage message)
|
||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||
{
|
||||
const string header = "Lidarr - Downloaded";
|
||||
|
||||
|
@ -48,13 +41,23 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
|||
UpdateAndClean(artist);
|
||||
}
|
||||
|
||||
public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
|
||||
{
|
||||
Notify(Settings, HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message);
|
||||
}
|
||||
|
||||
public override void OnTrackRetag(TrackRetagMessage message)
|
||||
{
|
||||
UpdateAndClean(message.Artist);
|
||||
}
|
||||
|
||||
public override string Name => "Kodi (XBMC)";
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
||||
failures.AddIfNotNull(_xbmcService.Test(Settings, "Success! XBMC has been successfully configured!"));
|
||||
failures.AddIfNotNull(_xbmcService.Test(Settings, "Success! Kodi has been successfully configured!"));
|
||||
|
||||
return new ValidationResult(failures);
|
||||
}
|
||||
|
@ -70,7 +73,7 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
|||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
var logMessage = string.Format("Unable to connect to XBMC Host: {0}:{1}", Settings.Host, Settings.Port);
|
||||
var logMessage = string.Format("Unable to connect to Kodi Host: {0}:{1}", Settings.Host, Settings.Port);
|
||||
_logger.Debug(ex, logMessage);
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +94,7 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
|||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
var logMessage = string.Format("Unable to connect to XBMC Host: {0}:{1}", Settings.Host, Settings.Port);
|
||||
var logMessage = string.Format("Unable to connect to Kodi Host: {0}:{1}", Settings.Host, Settings.Port);
|
||||
_logger.Debug(ex, logMessage);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -183,6 +183,7 @@
|
|||
<Compile Include="Datastore\Migration\003_add_medium_support.cs" />
|
||||
<Compile Include="Datastore\Migration\006_separate_automatic_and_interactive_search.cs" />
|
||||
<Compile Include="Datastore\Migration\007_change_album_path_to_relative.cs" />
|
||||
<Compile Include="Datastore\Migration\029_health_issue_notification.cs" />
|
||||
<Compile Include="Datastore\Migration\014_fix_language_metadata_profiles.cs" />
|
||||
<Compile Include="Datastore\Migration\013_album_download_notification.cs" />
|
||||
<Compile Include="Datastore\Migration\009_album_releases.cs" />
|
||||
|
@ -508,6 +509,7 @@
|
|||
<Compile Include="HealthCheck\EventDrivenHealthCheck.cs" />
|
||||
<Compile Include="HealthCheck\HealthCheck.cs" />
|
||||
<Compile Include="HealthCheck\HealthCheckBase.cs" />
|
||||
<Compile Include="HealthCheck\HealthCheckFailedEvent.cs" />
|
||||
<Compile Include="HealthCheck\HealthCheckCompleteEvent.cs" />
|
||||
<Compile Include="HealthCheck\HealthCheckService.cs" />
|
||||
<Compile Include="HealthCheck\IProvideHealthCheck.cs" />
|
||||
|
@ -711,6 +713,13 @@
|
|||
<Compile Include="Languages\Language.cs" />
|
||||
<Compile Include="Languages\LanguageComparer.cs" />
|
||||
<Compile Include="Languages\LanguagesBelowCutoff.cs" />
|
||||
<Compile Include="Notifications\Discord\Discord.cs" />
|
||||
<Compile Include="Notifications\Discord\DiscordColors.cs" />
|
||||
<Compile Include="Notifications\Discord\DiscordException.cs" />
|
||||
<Compile Include="Notifications\Discord\DiscordProxy.cs" />
|
||||
<Compile Include="Notifications\Discord\DiscordSettings.cs" />
|
||||
<Compile Include="Notifications\Discord\Payloads\Embed.cs" />
|
||||
<Compile Include="Notifications\Discord\Payloads\DiscordPayload.cs" />
|
||||
<Compile Include="Lifecycle\ApplicationShutdownRequested.cs" />
|
||||
<Compile Include="Lifecycle\ApplicationStartedEvent.cs" />
|
||||
<Compile Include="Lifecycle\Commands\RestartCommand.cs" />
|
||||
|
@ -922,6 +931,7 @@
|
|||
<Compile Include="Music\TrackRepository.cs" />
|
||||
<Compile Include="Music\TrackService.cs" />
|
||||
<Compile Include="Notifications\AlbumDownloadMessage.cs" />
|
||||
<Compile Include="Notifications\DownloadFailedMessage.cs" />
|
||||
<Compile Include="Notifications\Join\JoinAuthException.cs" />
|
||||
<Compile Include="Notifications\Join\JoinInvalidDeviceException.cs" />
|
||||
<Compile Include="Notifications\Join\JoinPriority.cs" />
|
||||
|
@ -1050,7 +1060,7 @@
|
|||
<Compile Include="RemotePathMappings\RemotePathMappingRepository.cs" />
|
||||
<Compile Include="RemotePathMappings\RemotePathMappingService.cs" />
|
||||
<Compile Include="MediaFiles\TorrentInfo\TorrentFileInfoReader.cs" />
|
||||
<Compile Include="Notifications\TrackDownloadMessage.cs" />
|
||||
<Compile Include="Notifications\TrackRetagMessage.cs" />
|
||||
<Compile Include="Notifications\Email\Email.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
|
|
Loading…
Reference in New Issue