mirror of
https://github.com/lidarr/lidarr.git
synced 2025-07-16 10:03:51 -07:00
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
52 changed files with 1262 additions and 427 deletions
|
@ -14,6 +14,7 @@ import FormGroup from 'Components/Form/FormGroup';
|
||||||
import FormLabel from 'Components/Form/FormLabel';
|
import FormLabel from 'Components/Form/FormLabel';
|
||||||
import FormInputGroup from 'Components/Form/FormInputGroup';
|
import FormInputGroup from 'Components/Form/FormInputGroup';
|
||||||
import ProviderFieldFormGroup from 'Components/Form/ProviderFieldFormGroup';
|
import ProviderFieldFormGroup from 'Components/Form/ProviderFieldFormGroup';
|
||||||
|
import NotificationEventItems from './NotificationEventItems';
|
||||||
import styles from './EditNotificationModalContent.css';
|
import styles from './EditNotificationModalContent.css';
|
||||||
|
|
||||||
function EditNotificationModalContent(props) {
|
function EditNotificationModalContent(props) {
|
||||||
|
@ -38,16 +39,6 @@ function EditNotificationModalContent(props) {
|
||||||
id,
|
id,
|
||||||
implementationName,
|
implementationName,
|
||||||
name,
|
name,
|
||||||
onGrab,
|
|
||||||
onDownload,
|
|
||||||
onAlbumDownload,
|
|
||||||
onUpgrade,
|
|
||||||
onRename,
|
|
||||||
supportsOnGrab,
|
|
||||||
supportsOnDownload,
|
|
||||||
supportsOnAlbumDownload,
|
|
||||||
supportsOnUpgrade,
|
|
||||||
supportsOnRename,
|
|
||||||
tags,
|
tags,
|
||||||
fields,
|
fields,
|
||||||
message
|
message
|
||||||
|
@ -94,73 +85,10 @@ function EditNotificationModalContent(props) {
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
<FormGroup>
|
<NotificationEventItems
|
||||||
<FormLabel>On Grab</FormLabel>
|
item={item}
|
||||||
|
onInputChange={onInputChange}
|
||||||
<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>
|
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>Tags</FormLabel>
|
<FormLabel>Tags</FormLabel>
|
||||||
|
|
|
@ -55,15 +55,21 @@ class Notification extends Component {
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
onGrab,
|
onGrab,
|
||||||
onDownload,
|
onReleaseImport,
|
||||||
onAlbumDownload,
|
|
||||||
onUpgrade,
|
onUpgrade,
|
||||||
onRename,
|
onRename,
|
||||||
|
onHealthIssue,
|
||||||
|
onDownloadFailure,
|
||||||
|
onImportFailure,
|
||||||
|
onTrackRetag,
|
||||||
supportsOnGrab,
|
supportsOnGrab,
|
||||||
supportsOnDownload,
|
supportsOnReleaseImport,
|
||||||
supportsOnAlbumDownload,
|
|
||||||
supportsOnUpgrade,
|
supportsOnUpgrade,
|
||||||
supportsOnRename
|
supportsOnRename,
|
||||||
|
supportsOnHealthIssue,
|
||||||
|
supportsOnDownloadFailure,
|
||||||
|
supportsOnImportFailure,
|
||||||
|
supportsOnTrackRetag
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -84,21 +90,14 @@ class Notification extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
supportsOnAlbumDownload && onAlbumDownload &&
|
supportsOnReleaseImport && onReleaseImport &&
|
||||||
<Label kind={kinds.SUCCESS}>
|
<Label kind={kinds.SUCCESS}>
|
||||||
On Album Download
|
On Release Import
|
||||||
</Label>
|
</Label>
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
supportsOnDownload && onDownload &&
|
supportsOnUpgrade && onReleaseImport && onUpgrade &&
|
||||||
<Label kind={kinds.SUCCESS}>
|
|
||||||
On Download
|
|
||||||
</Label>
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
supportsOnUpgrade && onDownload && onUpgrade &&
|
|
||||||
<Label kind={kinds.SUCCESS}>
|
<Label kind={kinds.SUCCESS}>
|
||||||
On Upgrade
|
On Upgrade
|
||||||
</Label>
|
</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
|
<Label
|
||||||
kind={kinds.DISABLED}
|
kind={kinds.DISABLED}
|
||||||
outline={true}
|
outline={true}
|
||||||
|
@ -146,15 +174,21 @@ Notification.propTypes = {
|
||||||
id: PropTypes.number.isRequired,
|
id: PropTypes.number.isRequired,
|
||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
onGrab: PropTypes.bool.isRequired,
|
onGrab: PropTypes.bool.isRequired,
|
||||||
onDownload: PropTypes.bool.isRequired,
|
onReleaseImport: PropTypes.bool.isRequired,
|
||||||
onAlbumDownload: PropTypes.bool.isRequired,
|
|
||||||
onUpgrade: PropTypes.bool.isRequired,
|
onUpgrade: PropTypes.bool.isRequired,
|
||||||
onRename: 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,
|
supportsOnGrab: PropTypes.bool.isRequired,
|
||||||
supportsOnDownload: PropTypes.bool.isRequired,
|
supportsOnReleaseImport: PropTypes.bool.isRequired,
|
||||||
supportsOnAlbumDownload: PropTypes.bool.isRequired,
|
|
||||||
supportsOnUpgrade: PropTypes.bool.isRequired,
|
supportsOnUpgrade: PropTypes.bool.isRequired,
|
||||||
supportsOnRename: 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
|
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 }) => {
|
[SELECT_NOTIFICATION_SCHEMA]: (state, { payload }) => {
|
||||||
return selectProviderSchema(state, section, payload, (selectedSchema) => {
|
return selectProviderSchema(state, section, payload, (selectedSchema) => {
|
||||||
selectedSchema.onGrab = selectedSchema.supportsOnGrab;
|
selectedSchema.onGrab = selectedSchema.supportsOnGrab;
|
||||||
selectedSchema.onDownload = selectedSchema.supportsOnDownload;
|
selectedSchema.onReleaseImport = selectedSchema.supportsOnReleaseImport;
|
||||||
selectedSchema.onUpgrade = selectedSchema.supportsOnUpgrade;
|
selectedSchema.onUpgrade = selectedSchema.supportsOnUpgrade;
|
||||||
selectedSchema.onRename = selectedSchema.supportsOnRename;
|
selectedSchema.onRename = selectedSchema.supportsOnRename;
|
||||||
|
selectedSchema.onHealthIssue = selectedSchema.supportsOnHealthIssue;
|
||||||
|
selectedSchema.onDownloadFailure = selectedSchema.supportsOnDownloadFailure;
|
||||||
|
selectedSchema.onImportFailure = selectedSchema.supportsOnImportFailure;
|
||||||
|
selectedSchema.onTrackRetag = selectedSchema.supportsOnTrackRetag;
|
||||||
|
|
||||||
return selectedSchema;
|
return selectedSchema;
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Lidarr.Api.V1.Notifications
|
||||||
|
|
||||||
protected override void Validate(NotificationDefinition definition, bool includeWarnings)
|
protected override void Validate(NotificationDefinition definition, bool includeWarnings)
|
||||||
{
|
{
|
||||||
if (!definition.OnGrab && !definition.OnDownload) return;
|
if (!definition.Enable) return;
|
||||||
base.Validate(definition, includeWarnings);
|
base.Validate(definition, includeWarnings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,15 +6,22 @@ namespace Lidarr.Api.V1.Notifications
|
||||||
{
|
{
|
||||||
public string Link { get; set; }
|
public string Link { get; set; }
|
||||||
public bool OnGrab { get; set; }
|
public bool OnGrab { get; set; }
|
||||||
public bool OnDownload { get; set; }
|
public bool OnReleaseImport { get; set; }
|
||||||
public bool OnAlbumDownload { get; set; }
|
|
||||||
public bool OnUpgrade { get; set; }
|
public bool OnUpgrade { get; set; }
|
||||||
public bool OnRename { 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 SupportsOnGrab { get; set; }
|
||||||
public bool SupportsOnDownload { get; set; }
|
public bool SupportsOnReleaseImport { get; set; }
|
||||||
public bool SupportsOnAlbumDownload { get; set; }
|
|
||||||
public bool SupportsOnUpgrade { get; set; }
|
public bool SupportsOnUpgrade { get; set; }
|
||||||
public bool SupportsOnRename { 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; }
|
public string TestCommand { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,15 +34,22 @@ namespace Lidarr.Api.V1.Notifications
|
||||||
var resource = base.ToResource(definition);
|
var resource = base.ToResource(definition);
|
||||||
|
|
||||||
resource.OnGrab = definition.OnGrab;
|
resource.OnGrab = definition.OnGrab;
|
||||||
resource.OnDownload = definition.OnDownload;
|
resource.OnReleaseImport = definition.OnReleaseImport;
|
||||||
resource.OnAlbumDownload = definition.OnAlbumDownload;
|
|
||||||
resource.OnUpgrade = definition.OnUpgrade;
|
resource.OnUpgrade = definition.OnUpgrade;
|
||||||
resource.OnRename = definition.OnRename;
|
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.SupportsOnGrab = definition.SupportsOnGrab;
|
||||||
resource.SupportsOnDownload = definition.SupportsOnDownload;
|
resource.SupportsOnReleaseImport = definition.SupportsOnReleaseImport;
|
||||||
resource.SupportsOnAlbumDownload = definition.SupportsOnAlbumDownload;
|
|
||||||
resource.SupportsOnUpgrade = definition.SupportsOnUpgrade;
|
resource.SupportsOnUpgrade = definition.SupportsOnUpgrade;
|
||||||
resource.SupportsOnRename = definition.SupportsOnRename;
|
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;
|
return resource;
|
||||||
}
|
}
|
||||||
|
@ -47,15 +61,22 @@ namespace Lidarr.Api.V1.Notifications
|
||||||
var definition = base.ToModel(resource);
|
var definition = base.ToModel(resource);
|
||||||
|
|
||||||
definition.OnGrab = resource.OnGrab;
|
definition.OnGrab = resource.OnGrab;
|
||||||
definition.OnDownload = resource.OnDownload;
|
definition.OnReleaseImport = resource.OnReleaseImport;
|
||||||
definition.OnAlbumDownload = resource.OnAlbumDownload;
|
|
||||||
definition.OnUpgrade = resource.OnUpgrade;
|
definition.OnUpgrade = resource.OnUpgrade;
|
||||||
definition.OnRename = resource.OnRename;
|
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.SupportsOnGrab = resource.SupportsOnGrab;
|
||||||
definition.SupportsOnDownload = resource.SupportsOnDownload;
|
definition.SupportsOnReleaseImport = resource.SupportsOnReleaseImport;
|
||||||
definition.SupportsOnAlbumDownload = resource.SupportsOnAlbumDownload;
|
|
||||||
definition.SupportsOnUpgrade = resource.SupportsOnUpgrade;
|
definition.SupportsOnUpgrade = resource.SupportsOnUpgrade;
|
||||||
definition.SupportsOnRename = resource.SupportsOnRename;
|
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;
|
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 Name => "TestNotification";
|
||||||
public override string Link => "";
|
public override string Link => "";
|
||||||
|
@ -32,7 +32,7 @@ namespace NzbDrone.Core.Test.NotificationTests
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(TrackDownloadMessage trackDownloadMessage)
|
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||||
{
|
{
|
||||||
TestLogger.Info("OnDownload was called");
|
TestLogger.Info("OnDownload was called");
|
||||||
}
|
}
|
||||||
|
@ -55,12 +55,7 @@ namespace NzbDrone.Core.Test.NotificationTests
|
||||||
TestLogger.Info("OnGrab was called");
|
TestLogger.Info("OnGrab was called");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(TrackDownloadMessage message)
|
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||||
{
|
|
||||||
TestLogger.Info("OnDownload was called");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
|
||||||
{
|
{
|
||||||
TestLogger.Info("OnAlbumDownload was called");
|
TestLogger.Info("OnAlbumDownload was called");
|
||||||
}
|
}
|
||||||
|
@ -70,6 +65,25 @@ namespace NzbDrone.Core.Test.NotificationTests
|
||||||
TestLogger.Info("OnRename was called");
|
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>
|
class TestNotificationWithNoEvents : NotificationBase<TestSetting>
|
||||||
|
@ -87,11 +101,11 @@ namespace NzbDrone.Core.Test.NotificationTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[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.SupportsOnUpgrade.Should().BeTrue();
|
||||||
|
|
||||||
notification.SupportsOnGrab.Should().BeFalse();
|
notification.SupportsOnGrab.Should().BeFalse();
|
||||||
|
@ -104,10 +118,13 @@ namespace NzbDrone.Core.Test.NotificationTests
|
||||||
var notification = new TestNotificationWithAllEvents();
|
var notification = new TestNotificationWithAllEvents();
|
||||||
|
|
||||||
notification.SupportsOnGrab.Should().BeTrue();
|
notification.SupportsOnGrab.Should().BeTrue();
|
||||||
notification.SupportsOnDownload.Should().BeTrue();
|
notification.SupportsOnReleaseImport.Should().BeTrue();
|
||||||
notification.SupportsOnAlbumDownload.Should().BeTrue();
|
|
||||||
notification.SupportsOnUpgrade.Should().BeTrue();
|
notification.SupportsOnUpgrade.Should().BeTrue();
|
||||||
notification.SupportsOnRename.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();
|
var notification = new TestNotificationWithNoEvents();
|
||||||
|
|
||||||
notification.SupportsOnGrab.Should().BeFalse();
|
notification.SupportsOnGrab.Should().BeFalse();
|
||||||
notification.SupportsOnDownload.Should().BeFalse();
|
notification.SupportsOnReleaseImport.Should().BeFalse();
|
||||||
notification.SupportsOnAlbumDownload.Should().BeFalse();
|
|
||||||
notification.SupportsOnUpgrade.Should().BeFalse();
|
notification.SupportsOnUpgrade.Should().BeFalse();
|
||||||
notification.SupportsOnRename.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]
|
[Test]
|
||||||
public void should_remove_old_episodes_on_upgrade()
|
public void should_remove_old_episodes_on_upgrade()
|
||||||
{
|
{
|
||||||
Subject.OnAlbumDownload(_upgrade);
|
Subject.OnReleaseImport(_upgrade);
|
||||||
|
|
||||||
Mocker.GetMock<ISynologyIndexerProxy>()
|
Mocker.GetMock<ISynologyIndexerProxy>()
|
||||||
.Verify(v => v.DeleteFile(@"C:\Test\file1.S01E01.mkv".AsOsAgnostic()), Times.Once());
|
.Verify(v => v.DeleteFile(@"C:\Test\file1.S01E01.mkv".AsOsAgnostic()), Times.Once());
|
||||||
|
@ -85,7 +85,7 @@ namespace NzbDrone.Core.Test.NotificationTests
|
||||||
[Test]
|
[Test]
|
||||||
public void should_add_new_episode_on_upgrade()
|
public void should_add_new_episode_on_upgrade()
|
||||||
{
|
{
|
||||||
Subject.OnAlbumDownload(_upgrade);
|
Subject.OnReleaseImport(_upgrade);
|
||||||
|
|
||||||
Mocker.GetMock<ISynologyIndexerProxy>()
|
Mocker.GetMock<ISynologyIndexerProxy>()
|
||||||
.Verify(v => v.AddFile(@"C:\Test\file1.S01E01E02.mkv".AsOsAgnostic()), Times.Once());
|
.Verify(v => v.AddFile(@"C:\Test\file1.S01E01E02.mkv".AsOsAgnostic()), Times.Once());
|
||||||
|
|
|
@ -26,6 +26,8 @@ namespace NzbDrone.Core.Test.NotificationTests.Xbmc.Json
|
||||||
_xbmcArtist = Builder<KodiArtist>.CreateListOfSize(3)
|
_xbmcArtist = Builder<KodiArtist>.CreateListOfSize(3)
|
||||||
.TheFirst(1)
|
.TheFirst(1)
|
||||||
.With(s => s.MusicbrainzArtistId = new List<string> { MB_ID.ToString()})
|
.With(s => s.MusicbrainzArtistId = new List<string> { MB_ID.ToString()})
|
||||||
|
.TheNext(2)
|
||||||
|
.With(s => s.MusicbrainzArtistId = new List<string>())
|
||||||
.Build()
|
.Build()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,9 @@ using NzbDrone.Core.Music;
|
||||||
namespace NzbDrone.Core.Test.NotificationTests.Xbmc
|
namespace NzbDrone.Core.Test.NotificationTests.Xbmc
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class OnDownloadFixture : CoreTest<Notifications.Xbmc.Xbmc>
|
public class OnReleaseImportFixture : CoreTest<Notifications.Xbmc.Xbmc>
|
||||||
{
|
{
|
||||||
private TrackDownloadMessage _trackDownloadMessage;
|
private AlbumDownloadMessage _albumDownloadMessage;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
|
@ -25,9 +25,9 @@ namespace NzbDrone.Core.Test.NotificationTests.Xbmc
|
||||||
var trackFile = Builder<TrackFile>.CreateNew()
|
var trackFile = Builder<TrackFile>.CreateNew()
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
_trackDownloadMessage = Builder<TrackDownloadMessage>.CreateNew()
|
_albumDownloadMessage = Builder<AlbumDownloadMessage>.CreateNew()
|
||||||
.With(d => d.Artist = artist)
|
.With(d => d.Artist = artist)
|
||||||
.With(d => d.TrackFile = trackFile)
|
.With(d => d.TrackFiles = new List<TrackFile> { trackFile })
|
||||||
.With(d => d.OldFiles = new List<TrackFile>())
|
.With(d => d.OldFiles = new List<TrackFile>())
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ namespace NzbDrone.Core.Test.NotificationTests.Xbmc
|
||||||
|
|
||||||
private void GivenOldFiles()
|
private void GivenOldFiles()
|
||||||
{
|
{
|
||||||
_trackDownloadMessage.OldFiles = Builder<TrackFile>.CreateListOfSize(1)
|
_albumDownloadMessage.OldFiles = Builder<TrackFile>.CreateListOfSize(1)
|
||||||
.Build()
|
.Build()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ namespace NzbDrone.Core.Test.NotificationTests.Xbmc
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_clean_if_no_episode_was_replaced()
|
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());
|
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()
|
public void should_clean_if_episode_was_replaced()
|
||||||
{
|
{
|
||||||
GivenOldFiles();
|
GivenOldFiles();
|
||||||
Subject.OnDownload(_trackDownloadMessage);
|
Subject.OnReleaseImport(_albumDownloadMessage);
|
||||||
|
|
||||||
Mocker.GetMock<IXbmcService>().Verify(v => v.Clean(It.IsAny<XbmcSettings>()), Times.Once());
|
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\Http\UpdateFixture.cs" />
|
||||||
<Compile Include="NotificationTests\Xbmc\Json\GetArtistPathFixture.cs" />
|
<Compile Include="NotificationTests\Xbmc\Json\GetArtistPathFixture.cs" />
|
||||||
<Compile Include="NotificationTests\Xbmc\Json\UpdateFixture.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\BuildFilePathFixture.cs" />
|
||||||
<Compile Include="OrganizerTests\GetAlbumFolderFixture.cs" />
|
<Compile Include="OrganizerTests\GetAlbumFolderFixture.cs" />
|
||||||
<Compile Include="OrganizerTests\FileNameBuilderTests\FileNameBuilderFixture.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.Tags;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Serializer;
|
|
||||||
using NzbDrone.Core.Authentication;
|
using NzbDrone.Core.Authentication;
|
||||||
using NzbDrone.Core.CustomFilters;
|
using NzbDrone.Core.CustomFilters;
|
||||||
using NzbDrone.Core.Extras.Metadata;
|
using NzbDrone.Core.Extras.Metadata;
|
||||||
|
@ -73,10 +72,13 @@ namespace NzbDrone.Core.Datastore
|
||||||
|
|
||||||
Mapper.Entity<NotificationDefinition>().RegisterDefinition("Notifications")
|
Mapper.Entity<NotificationDefinition>().RegisterDefinition("Notifications")
|
||||||
.Ignore(i => i.SupportsOnGrab)
|
.Ignore(i => i.SupportsOnGrab)
|
||||||
.Ignore(i => i.SupportsOnDownload)
|
.Ignore(i => i.SupportsOnReleaseImport)
|
||||||
.Ignore(i => i.SupportsOnAlbumDownload)
|
|
||||||
.Ignore(i => i.SupportsOnUpgrade)
|
.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")
|
Mapper.Entity<MetadataDefinition>().RegisterDefinition("Metadata")
|
||||||
.Ignore(d => d.Tags);
|
.Ignore(d => d.Tags);
|
||||||
|
|
14
src/NzbDrone.Core/HealthCheck/HealthCheckFailedEvent.cs
Normal file
14
src/NzbDrone.Core/HealthCheck/HealthCheckFailedEvent.cs
Normal file
|
@ -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
|
else
|
||||||
{
|
{
|
||||||
|
if (_healthCheckResults.Find(result.Source.Name) == null)
|
||||||
|
{
|
||||||
|
_eventAggregator.PublishEvent(new HealthCheckFailedEvent(result));
|
||||||
|
}
|
||||||
|
|
||||||
_healthCheckResults.Set(result.Source.Name, result);
|
_healthCheckResults.Set(result.Source.Name, result);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,14 +21,24 @@ namespace NzbDrone.Core.Notifications.Boxcar
|
||||||
_proxy.SendNotification(ALBUM_GRABBED_TITLE, grabMessage.Message, Settings);
|
_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()
|
public override ValidationResult Test()
|
||||||
|
|
|
@ -6,6 +6,7 @@ using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Processes;
|
using NzbDrone.Common.Processes;
|
||||||
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Core.Music;
|
using NzbDrone.Core.Music;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
|
|
||||||
|
@ -55,52 +56,7 @@ namespace NzbDrone.Core.Notifications.CustomScript
|
||||||
ExecuteScript(environmentVariables);
|
ExecuteScript(environmentVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(TrackDownloadMessage message)
|
public override void OnReleaseImport(AlbumDownloadMessage 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)
|
|
||||||
{
|
{
|
||||||
var artist = message.Artist;
|
var artist = message.Artist;
|
||||||
var album = message.Album;
|
var album = message.Album;
|
||||||
|
@ -150,6 +106,53 @@ namespace NzbDrone.Core.Notifications.CustomScript
|
||||||
ExecuteScript(environmentVariables);
|
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()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
|
|
190
src/NzbDrone.Core/Notifications/Discord/Discord.cs
Normal file
190
src/NzbDrone.Core/Notifications/Discord/Discord.cs
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
src/NzbDrone.Core/Notifications/Discord/DiscordColors.cs
Normal file
9
src/NzbDrone.Core/Notifications/Discord/DiscordColors.cs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
namespace NzbDrone.Core.Notifications.Discord
|
||||||
|
{
|
||||||
|
public enum DiscordColors
|
||||||
|
{
|
||||||
|
Danger = 15749200,
|
||||||
|
Success = 2605644,
|
||||||
|
Warning = 16753920
|
||||||
|
}
|
||||||
|
}
|
16
src/NzbDrone.Core/Notifications/Discord/DiscordException.cs
Normal file
16
src/NzbDrone.Core/Notifications/Discord/DiscordException.cs
Normal file
|
@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
46
src/NzbDrone.Core/Notifications/Discord/DiscordProxy.cs
Normal file
46
src/NzbDrone.Core/Notifications/Discord/DiscordProxy.cs
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
src/NzbDrone.Core/Notifications/Discord/DiscordSettings.cs
Normal file
35
src/NzbDrone.Core/Notifications/Discord/DiscordSettings.cs
Normal file
|
@ -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; }
|
||||||
|
}
|
||||||
|
}
|
10
src/NzbDrone.Core/Notifications/Discord/Payloads/Embed.cs
Normal file
10
src/NzbDrone.Core/Notifications/Discord/Payloads/Embed.cs
Normal file
|
@ -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; }
|
||||||
|
}
|
||||||
|
}
|
22
src/NzbDrone.Core/Notifications/DownloadFailedMessage.cs
Normal file
22
src/NzbDrone.Core/Notifications/DownloadFailedMessage.cs
Normal file
|
@ -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);
|
_emailService.SendEmail(Settings, ALBUM_GRABBED_TITLE_BRANDED, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(TrackDownloadMessage message)
|
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||||
{
|
|
||||||
var body = $"{message.Message} Downloaded and sorted.";
|
|
||||||
|
|
||||||
_emailService.SendEmail(Settings, TRACK_DOWNLOADED_TITLE_BRANDED, body);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
|
||||||
{
|
{
|
||||||
var body = $"{message.Message} Downloaded and sorted.";
|
var body = $"{message.Message} Downloaded and sorted.";
|
||||||
|
|
||||||
_emailService.SendEmail(Settings, ALBUM_DOWNLOADED_TITLE_BRANDED, body);
|
_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()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
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);
|
_growlService.SendNotification(ALBUM_GRABBED_TITLE, grabMessage.Message, "GRAB", Settings.Host, Settings.Port, Settings.Password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(TrackDownloadMessage message)
|
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||||
{
|
|
||||||
_growlService.SendNotification(TRACK_DOWNLOADED_TITLE, message.Message, "TRACKDOWNLOAD", Settings.Host, Settings.Port, Settings.Password);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
|
||||||
{
|
{
|
||||||
_growlService.SendNotification(ALBUM_DOWNLOADED_TITLE, message.Message, "ALBUMDOWNLOAD", Settings.Host, Settings.Port, Settings.Password);
|
_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()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
|
@ -8,13 +8,19 @@ namespace NzbDrone.Core.Notifications
|
||||||
string Link { get; }
|
string Link { get; }
|
||||||
|
|
||||||
void OnGrab(GrabMessage grabMessage);
|
void OnGrab(GrabMessage grabMessage);
|
||||||
void OnDownload(TrackDownloadMessage message);
|
void OnReleaseImport(AlbumDownloadMessage message);
|
||||||
void OnAlbumDownload(AlbumDownloadMessage message);
|
|
||||||
void OnRename(Artist artist);
|
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 SupportsOnGrab { get; }
|
||||||
bool SupportsOnDownload { get; }
|
bool SupportsOnReleaseImport { get; }
|
||||||
bool SupportsOnAlbumDownload { get; }
|
|
||||||
bool SupportsOnUpgrade { get; }
|
bool SupportsOnUpgrade { get; }
|
||||||
bool SupportsOnRename { 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);
|
_proxy.SendNotification(ALBUM_GRABBED_TITLE_BRANDED, message.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(TrackDownloadMessage message)
|
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||||
{
|
|
||||||
_proxy.SendNotification(TRACK_DOWNLOADED_TITLE_BRANDED, message.Message, Settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
|
||||||
{
|
{
|
||||||
_proxy.SendNotification(ALBUM_DOWNLOADED_TITLE_BRANDED, message.Message, Settings);
|
_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()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
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)
|
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)
|
public override void OnRename(Artist artist)
|
||||||
{
|
{
|
||||||
if (Settings.UpdateLibrary)
|
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()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,12 +9,18 @@ namespace NzbDrone.Core.Notifications
|
||||||
public abstract class NotificationBase<TSettings> : INotification where TSettings : IProviderConfig, new()
|
public abstract class NotificationBase<TSettings> : INotification where TSettings : IProviderConfig, new()
|
||||||
{
|
{
|
||||||
protected const string ALBUM_GRABBED_TITLE = "Album Grabbed";
|
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 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 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 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; }
|
public abstract string Name { get; }
|
||||||
|
|
||||||
|
@ -34,12 +40,7 @@ namespace NzbDrone.Core.Notifications
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnDownload(TrackDownloadMessage message)
|
public virtual void OnReleaseImport(AlbumDownloadMessage message)
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void OnAlbumDownload(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 SupportsOnGrab => HasConcreteImplementation("OnGrab");
|
||||||
public bool SupportsOnRename => HasConcreteImplementation("OnRename");
|
public bool SupportsOnRename => HasConcreteImplementation("OnRename");
|
||||||
public bool SupportsOnDownload => HasConcreteImplementation("OnDownload");
|
public bool SupportsOnReleaseImport => HasConcreteImplementation("OnReleaseImport");
|
||||||
public bool SupportsOnAlbumDownload => HasConcreteImplementation("OnAlbumDownload");
|
public bool SupportsOnUpgrade => SupportsOnReleaseImport;
|
||||||
public bool SupportsOnUpgrade => SupportsOnDownload;
|
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;
|
protected TSettings Settings => (TSettings)Definition.Settings;
|
||||||
|
|
||||||
|
|
|
@ -6,16 +6,23 @@ namespace NzbDrone.Core.Notifications
|
||||||
{
|
{
|
||||||
|
|
||||||
public bool OnGrab { get; set; }
|
public bool OnGrab { get; set; }
|
||||||
public bool OnDownload { get; set; }
|
public bool OnReleaseImport { get; set; }
|
||||||
public bool OnAlbumDownload { get; set; }
|
|
||||||
public bool OnUpgrade { get; set; }
|
public bool OnUpgrade { get; set; }
|
||||||
public bool OnRename { 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 SupportsOnGrab { get; set; }
|
||||||
public bool SupportsOnDownload { get; set; }
|
public bool SupportsOnReleaseImport { get; set; }
|
||||||
public bool SupportsOnAlbumDownload { get; set; }
|
|
||||||
public bool SupportsOnUpgrade { get; set; }
|
public bool SupportsOnUpgrade { get; set; }
|
||||||
public bool SupportsOnRename { 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>
|
public interface INotificationFactory : IProviderFactory<INotification, NotificationDefinition>
|
||||||
{
|
{
|
||||||
List<INotification> OnGrabEnabled();
|
List<INotification> OnGrabEnabled();
|
||||||
List<INotification> OnDownloadEnabled();
|
List<INotification> OnReleaseImportEnabled();
|
||||||
List<INotification> OnAlbumDownloadEnabled();
|
|
||||||
List<INotification> OnUpgradeEnabled();
|
List<INotification> OnUpgradeEnabled();
|
||||||
List<INotification> OnRenameEnabled();
|
List<INotification> OnRenameEnabled();
|
||||||
|
List<INotification> OnHealthIssueEnabled();
|
||||||
|
List<INotification> OnDownloadFailureEnabled();
|
||||||
|
List<INotification> OnImportFailureEnabled();
|
||||||
|
List<INotification> OnTrackRetagEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NotificationFactory : ProviderFactory<INotification, NotificationDefinition>, INotificationFactory
|
public class NotificationFactory : ProviderFactory<INotification, NotificationDefinition>, INotificationFactory
|
||||||
|
@ -28,14 +31,9 @@ namespace NzbDrone.Core.Notifications
|
||||||
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnGrab).ToList();
|
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();
|
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnReleaseImport).ToList();
|
||||||
}
|
|
||||||
|
|
||||||
public List<INotification> OnAlbumDownloadEnabled()
|
|
||||||
{
|
|
||||||
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnAlbumDownload).ToList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<INotification> OnUpgradeEnabled()
|
public List<INotification> OnUpgradeEnabled()
|
||||||
|
@ -48,15 +46,38 @@ namespace NzbDrone.Core.Notifications
|
||||||
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnRename).ToList();
|
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)
|
public override void SetProviderCharacteristics(INotification provider, NotificationDefinition definition)
|
||||||
{
|
{
|
||||||
base.SetProviderCharacteristics(provider, definition);
|
base.SetProviderCharacteristics(provider, definition);
|
||||||
|
|
||||||
definition.SupportsOnGrab = provider.SupportsOnGrab;
|
definition.SupportsOnGrab = provider.SupportsOnGrab;
|
||||||
definition.SupportsOnDownload = provider.SupportsOnDownload;
|
definition.SupportsOnReleaseImport = provider.SupportsOnReleaseImport;
|
||||||
definition.SupportsOnAlbumDownload = provider.SupportsOnAlbumDownload;
|
|
||||||
definition.SupportsOnUpgrade = provider.SupportsOnUpgrade;
|
definition.SupportsOnUpgrade = provider.SupportsOnUpgrade;
|
||||||
definition.SupportsOnRename = provider.SupportsOnRename;
|
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.Messaging.Events;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ namespace NzbDrone.Core.Notifications
|
||||||
{
|
{
|
||||||
public interface INotificationRepository : IProviderRepository<NotificationDefinition>
|
public interface INotificationRepository : IProviderRepository<NotificationDefinition>
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NotificationRepository : ProviderRepository<NotificationDefinition>, INotificationRepository
|
public class NotificationRepository : ProviderRepository<NotificationDefinition>, INotificationRepository
|
||||||
|
|
|
@ -10,15 +10,19 @@ using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
using NzbDrone.Core.Music;
|
using NzbDrone.Core.Music;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.HealthCheck;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications
|
namespace NzbDrone.Core.Notifications
|
||||||
{
|
{
|
||||||
public class NotificationService
|
public class NotificationService
|
||||||
: IHandle<AlbumGrabbedEvent>,
|
: IHandle<AlbumGrabbedEvent>,
|
||||||
IHandle<TrackImportedEvent>,
|
|
||||||
IHandle<AlbumImportedEvent>,
|
IHandle<AlbumImportedEvent>,
|
||||||
IHandle<ArtistRenamedEvent>
|
IHandle<ArtistRenamedEvent>,
|
||||||
|
IHandle<HealthCheckFailedEvent>,
|
||||||
|
IHandle<DownloadFailedEvent>,
|
||||||
|
IHandle<AlbumImportIncompleteEvent>,
|
||||||
|
IHandle<TrackFileRetaggedEvent>
|
||||||
{
|
{
|
||||||
private readonly INotificationFactory _notificationFactory;
|
private readonly INotificationFactory _notificationFactory;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
@ -47,24 +51,6 @@ namespace NzbDrone.Core.Notifications
|
||||||
qualityString);
|
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)
|
private string GetAlbumDownloadMessage(Artist artist, Album album, List<TrackFile> tracks)
|
||||||
{
|
{
|
||||||
return string.Format("{0} - {1} ({2} Tracks Imported)",
|
return string.Format("{0} - {1} ({2} Tracks Imported)",
|
||||||
|
@ -73,6 +59,25 @@ namespace NzbDrone.Core.Notifications
|
||||||
tracks.Count);
|
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)
|
private bool ShouldHandleArtist(ProviderDefinition definition, Artist artist)
|
||||||
{
|
{
|
||||||
if (definition.Tags.Empty())
|
if (definition.Tags.Empty())
|
||||||
|
@ -92,6 +97,21 @@ namespace NzbDrone.Core.Notifications
|
||||||
return false;
|
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)
|
public void Handle(AlbumGrabbedEvent message)
|
||||||
{
|
{
|
||||||
var grabMessage = new GrabMessage
|
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)
|
public void Handle(AlbumImportedEvent message)
|
||||||
{
|
{
|
||||||
if (!message.NewDownload)
|
if (!message.NewDownload)
|
||||||
|
@ -180,19 +159,22 @@ namespace NzbDrone.Core.Notifications
|
||||||
OldFiles = message.OldFiles,
|
OldFiles = message.OldFiles,
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var notification in _notificationFactory.OnAlbumDownloadEnabled())
|
foreach (var notification in _notificationFactory.OnReleaseImportEnabled())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (ShouldHandleArtist(notification.Definition, message.Artist))
|
if (ShouldHandleArtist(notification.Definition, message.Artist))
|
||||||
{
|
{
|
||||||
notification.OnAlbumDownload(downloadMessage);
|
if (downloadMessage.OldFiles.Empty() || ((NotificationDefinition)notification.Definition).OnUpgrade)
|
||||||
|
{
|
||||||
|
notification.OnReleaseImport(downloadMessage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception ex)
|
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);
|
_plexClientService.Notify(Settings, ALBUM_GRABBED_TITLE_BRANDED, grabMessage.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(TrackDownloadMessage message)
|
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||||
{
|
|
||||||
_plexClientService.Notify(Settings, TRACK_DOWNLOADED_TITLE_BRANDED, message.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
|
||||||
{
|
{
|
||||||
_plexClientService.Notify(Settings, ALBUM_DOWNLOADED_TITLE_BRANDED, message.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()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
|
@ -26,9 +26,9 @@ namespace NzbDrone.Core.Notifications.Plex.HomeTheater
|
||||||
Notify(ALBUM_GRABBED_TITLE_BRANDED, grabMessage.Message);
|
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()
|
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 Link => "https://www.plex.tv/";
|
||||||
public override string Name => "Plex Media Server";
|
public override string Name => "Plex Media Server";
|
||||||
|
|
||||||
public override void OnDownload(TrackDownloadMessage message)
|
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||||
{
|
|
||||||
UpdateIfEnabled(message.Artist);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
|
||||||
{
|
{
|
||||||
UpdateIfEnabled(message.Artist);
|
UpdateIfEnabled(message.Artist);
|
||||||
}
|
}
|
||||||
|
@ -38,6 +33,11 @@ namespace NzbDrone.Core.Notifications.Plex.Server
|
||||||
UpdateIfEnabled(artist);
|
UpdateIfEnabled(artist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnTrackRetag(TrackRetagMessage message)
|
||||||
|
{
|
||||||
|
UpdateIfEnabled(message.Artist);
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateIfEnabled(Artist artist)
|
private void UpdateIfEnabled(Artist artist)
|
||||||
{
|
{
|
||||||
if (Settings.UpdateLibrary)
|
if (Settings.UpdateLibrary)
|
||||||
|
|
|
@ -22,16 +22,16 @@ namespace NzbDrone.Core.Notifications.Prowl
|
||||||
_prowlService.SendNotification(ALBUM_GRABBED_TITLE, grabMessage.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
_prowlService.SendNotification(ALBUM_GRABBED_TITLE, grabMessage.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(TrackDownloadMessage message)
|
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||||
{
|
|
||||||
_prowlService.SendNotification(TRACK_DOWNLOADED_TITLE, message.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
|
||||||
{
|
{
|
||||||
_prowlService.SendNotification(ALBUM_DOWNLOADED_TITLE, message.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
_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()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
|
@ -24,16 +24,26 @@ namespace NzbDrone.Core.Notifications.PushBullet
|
||||||
_proxy.SendNotification(ALBUM_GRABBED_TITLE_BRANDED, grabMessage.Message, Settings);
|
_proxy.SendNotification(ALBUM_GRABBED_TITLE_BRANDED, grabMessage.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(TrackDownloadMessage message)
|
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||||
{
|
|
||||||
_proxy.SendNotification(TRACK_DOWNLOADED_TITLE_BRANDED, message.Message, Settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
|
||||||
{
|
{
|
||||||
_proxy.SendNotification(ALBUM_DOWNLOADED_TITLE_BRANDED, message.Message, Settings);
|
_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()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
|
@ -21,16 +21,26 @@ namespace NzbDrone.Core.Notifications.Pushover
|
||||||
_proxy.SendNotification(ALBUM_GRABBED_TITLE, grabMessage.Message, Settings);
|
_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);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
|
||||||
{
|
{
|
||||||
_proxy.SendNotification(ALBUM_DOWNLOADED_TITLE, message.Message, Settings);
|
_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()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NLog;
|
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
|
||||||
using NzbDrone.Common.Serializer;
|
|
||||||
using NzbDrone.Core.Notifications.Slack.Payloads;
|
using NzbDrone.Core.Notifications.Slack.Payloads;
|
||||||
using NzbDrone.Core.Rest;
|
using NzbDrone.Core.Rest;
|
||||||
using NzbDrone.Core.Music;
|
using NzbDrone.Core.Music;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
using RestSharp;
|
|
||||||
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Slack
|
namespace NzbDrone.Core.Notifications.Slack
|
||||||
|
@ -17,12 +13,10 @@ namespace NzbDrone.Core.Notifications.Slack
|
||||||
public class Slack : NotificationBase<SlackSettings>
|
public class Slack : NotificationBase<SlackSettings>
|
||||||
{
|
{
|
||||||
private readonly ISlackProxy _proxy;
|
private readonly ISlackProxy _proxy;
|
||||||
private readonly Logger _logger;
|
|
||||||
|
|
||||||
public Slack(ISlackProxy proxy, Logger logger)
|
public Slack(ISlackProxy proxy)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
_logger = logger;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name => "Slack";
|
public override string Name => "Slack";
|
||||||
|
@ -45,24 +39,7 @@ namespace NzbDrone.Core.Notifications.Slack
|
||||||
_proxy.SendPayload(payload, Settings);
|
_proxy.SendPayload(payload, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(TrackDownloadMessage message)
|
public override void OnReleaseImport(AlbumDownloadMessage 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)
|
|
||||||
{
|
{
|
||||||
var attachments = new List<Attachment>
|
var attachments = new List<Attachment>
|
||||||
{
|
{
|
||||||
|
@ -94,6 +71,73 @@ namespace NzbDrone.Core.Notifications.Slack
|
||||||
_proxy.SendPayload(payload, Settings);
|
_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()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace NzbDrone.Core.Notifications.Subsonic
|
||||||
Notify(Settings, header, grabMessage.Message);
|
Notify(Settings, header, grabMessage.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||||
{
|
{
|
||||||
const string header = "Lidarr - Downloaded";
|
const string header = "Lidarr - Downloaded";
|
||||||
|
|
||||||
|
@ -36,19 +36,21 @@ namespace NzbDrone.Core.Notifications.Subsonic
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(TrackDownloadMessage message)
|
|
||||||
{
|
|
||||||
const string header = "Lidarr - Downloaded";
|
|
||||||
|
|
||||||
Notify(Settings, header, message.Message);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnRename(Artist artist)
|
public override void OnRename(Artist artist)
|
||||||
{
|
{
|
||||||
Update();
|
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 string Name => "Subsonic";
|
||||||
|
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
|
|
|
@ -20,8 +20,7 @@ namespace NzbDrone.Core.Notifications.Synology
|
||||||
public override string Link => "https://www.synology.com";
|
public override string Link => "https://www.synology.com";
|
||||||
public override string Name => "Synology Indexer";
|
public override string Name => "Synology Indexer";
|
||||||
|
|
||||||
|
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
|
||||||
{
|
{
|
||||||
if (Settings.UpdateLibrary)
|
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()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,14 +21,24 @@ namespace NzbDrone.Core.Notifications.Telegram
|
||||||
_proxy.SendNotification(ALBUM_GRABBED_TITLE, grabMessage.Message, Settings);
|
_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()
|
public override ValidationResult Test()
|
||||||
|
|
|
@ -1,20 +1,19 @@
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.Music;
|
using NzbDrone.Core.Music;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications
|
namespace NzbDrone.Core.Notifications
|
||||||
{
|
{
|
||||||
public class TrackDownloadMessage
|
public class TrackRetagMessage
|
||||||
{
|
{
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
public Artist Artist { get; set; }
|
public Artist Artist { get; set; }
|
||||||
public Album Album { get; set; }
|
public Album Album { get; set; }
|
||||||
public AlbumRelease Release { get; set; }
|
public AlbumRelease Release { get; set; }
|
||||||
public TrackFile TrackFile { get; set; }
|
public TrackFile TrackFile { get; set; }
|
||||||
public List<TrackFile> OldFiles { get; set; }
|
public Dictionary<string, Tuple<string, string>> Diff { get; set; }
|
||||||
public string SourcePath { get; set; }
|
public bool Scrubbed { get; set; }
|
||||||
public string DownloadClient { get; set; }
|
|
||||||
public string DownloadId { get; set; }
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
|
@ -24,14 +24,24 @@ namespace NzbDrone.Core.Notifications.Twitter
|
||||||
_twitterService.SendNotification($"Grabbed: {message.Message}", Settings);
|
_twitterService.SendNotification($"Grabbed: {message.Message}", Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(TrackDownloadMessage message)
|
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||||
{
|
{
|
||||||
_twitterService.SendNotification($"Imported: {message.Message}", Settings);
|
_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)
|
public override object RequestAction(string action, IDictionary<string, string> query)
|
||||||
|
|
|
@ -41,23 +41,23 @@ namespace NzbDrone.Core.Notifications.Webhook
|
||||||
_proxy.SendWebhook(payload, Settings);
|
_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
|
var payload = new WebhookImportPayload
|
||||||
|
|
||||||
{
|
{
|
||||||
EventType = "Download",
|
EventType = "Download",
|
||||||
Artist = new WebhookArtist(message.Artist),
|
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
|
// TODO: Stop passing these parameters inside an episode v3
|
||||||
Quality = trackFile.Quality.Quality.Name,
|
Quality = x.Quality.Quality.Name,
|
||||||
QualityVersion = trackFile.Quality.Revision.Version,
|
QualityVersion = x.Quality.Revision.Version,
|
||||||
ReleaseGroup = trackFile.ReleaseGroup
|
ReleaseGroup = x.ReleaseGroup
|
||||||
}),
|
})).ToList(),
|
||||||
TrackFile = new WebhookTrackFile(trackFile),
|
TrackFiles = trackFiles.ConvertAll(x => new WebhookTrackFile(x)),
|
||||||
IsUpgrade = message.OldFiles.Any()
|
IsUpgrade = message.OldFiles.Any()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -75,6 +75,17 @@ namespace NzbDrone.Core.Notifications.Webhook
|
||||||
_proxy.SendWebhook(payload, Settings);
|
_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 string Name => "Webhook";
|
||||||
|
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
|
|
|
@ -5,7 +5,7 @@ namespace NzbDrone.Core.Notifications.Webhook
|
||||||
public class WebhookImportPayload : WebhookPayload
|
public class WebhookImportPayload : WebhookPayload
|
||||||
{
|
{
|
||||||
public List<WebhookTrack> Tracks { get; set; }
|
public List<WebhookTrack> Tracks { get; set; }
|
||||||
public WebhookTrackFile TrackFile { get; set; }
|
public List<WebhookTrackFile> TrackFiles { get; set; }
|
||||||
public bool IsUpgrade { get; set; }
|
public bool IsUpgrade { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,14 +28,7 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
Notify(Settings, header, grabMessage.Message);
|
Notify(Settings, header, grabMessage.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnAlbumDownload(AlbumDownloadMessage message)
|
public override void OnReleaseImport(AlbumDownloadMessage message)
|
||||||
{
|
|
||||||
const string header = "Lidarr - Downloaded";
|
|
||||||
|
|
||||||
Notify(Settings, header, message.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnDownload(TrackDownloadMessage message)
|
|
||||||
{
|
{
|
||||||
const string header = "Lidarr - Downloaded";
|
const string header = "Lidarr - Downloaded";
|
||||||
|
|
||||||
|
@ -48,13 +41,23 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
UpdateAndClean(artist);
|
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 string Name => "Kodi (XBMC)";
|
||||||
|
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
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);
|
return new ValidationResult(failures);
|
||||||
}
|
}
|
||||||
|
@ -70,7 +73,7 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
}
|
}
|
||||||
catch (SocketException ex)
|
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);
|
_logger.Debug(ex, logMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +94,7 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
}
|
}
|
||||||
catch (SocketException ex)
|
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);
|
_logger.Debug(ex, logMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,6 +183,7 @@
|
||||||
<Compile Include="Datastore\Migration\003_add_medium_support.cs" />
|
<Compile Include="Datastore\Migration\003_add_medium_support.cs" />
|
||||||
<Compile Include="Datastore\Migration\006_separate_automatic_and_interactive_search.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\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\014_fix_language_metadata_profiles.cs" />
|
||||||
<Compile Include="Datastore\Migration\013_album_download_notification.cs" />
|
<Compile Include="Datastore\Migration\013_album_download_notification.cs" />
|
||||||
<Compile Include="Datastore\Migration\009_album_releases.cs" />
|
<Compile Include="Datastore\Migration\009_album_releases.cs" />
|
||||||
|
@ -508,6 +509,7 @@
|
||||||
<Compile Include="HealthCheck\EventDrivenHealthCheck.cs" />
|
<Compile Include="HealthCheck\EventDrivenHealthCheck.cs" />
|
||||||
<Compile Include="HealthCheck\HealthCheck.cs" />
|
<Compile Include="HealthCheck\HealthCheck.cs" />
|
||||||
<Compile Include="HealthCheck\HealthCheckBase.cs" />
|
<Compile Include="HealthCheck\HealthCheckBase.cs" />
|
||||||
|
<Compile Include="HealthCheck\HealthCheckFailedEvent.cs" />
|
||||||
<Compile Include="HealthCheck\HealthCheckCompleteEvent.cs" />
|
<Compile Include="HealthCheck\HealthCheckCompleteEvent.cs" />
|
||||||
<Compile Include="HealthCheck\HealthCheckService.cs" />
|
<Compile Include="HealthCheck\HealthCheckService.cs" />
|
||||||
<Compile Include="HealthCheck\IProvideHealthCheck.cs" />
|
<Compile Include="HealthCheck\IProvideHealthCheck.cs" />
|
||||||
|
@ -711,6 +713,13 @@
|
||||||
<Compile Include="Languages\Language.cs" />
|
<Compile Include="Languages\Language.cs" />
|
||||||
<Compile Include="Languages\LanguageComparer.cs" />
|
<Compile Include="Languages\LanguageComparer.cs" />
|
||||||
<Compile Include="Languages\LanguagesBelowCutoff.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\ApplicationShutdownRequested.cs" />
|
||||||
<Compile Include="Lifecycle\ApplicationStartedEvent.cs" />
|
<Compile Include="Lifecycle\ApplicationStartedEvent.cs" />
|
||||||
<Compile Include="Lifecycle\Commands\RestartCommand.cs" />
|
<Compile Include="Lifecycle\Commands\RestartCommand.cs" />
|
||||||
|
@ -922,6 +931,7 @@
|
||||||
<Compile Include="Music\TrackRepository.cs" />
|
<Compile Include="Music\TrackRepository.cs" />
|
||||||
<Compile Include="Music\TrackService.cs" />
|
<Compile Include="Music\TrackService.cs" />
|
||||||
<Compile Include="Notifications\AlbumDownloadMessage.cs" />
|
<Compile Include="Notifications\AlbumDownloadMessage.cs" />
|
||||||
|
<Compile Include="Notifications\DownloadFailedMessage.cs" />
|
||||||
<Compile Include="Notifications\Join\JoinAuthException.cs" />
|
<Compile Include="Notifications\Join\JoinAuthException.cs" />
|
||||||
<Compile Include="Notifications\Join\JoinInvalidDeviceException.cs" />
|
<Compile Include="Notifications\Join\JoinInvalidDeviceException.cs" />
|
||||||
<Compile Include="Notifications\Join\JoinPriority.cs" />
|
<Compile Include="Notifications\Join\JoinPriority.cs" />
|
||||||
|
@ -1050,7 +1060,7 @@
|
||||||
<Compile Include="RemotePathMappings\RemotePathMappingRepository.cs" />
|
<Compile Include="RemotePathMappings\RemotePathMappingRepository.cs" />
|
||||||
<Compile Include="RemotePathMappings\RemotePathMappingService.cs" />
|
<Compile Include="RemotePathMappings\RemotePathMappingService.cs" />
|
||||||
<Compile Include="MediaFiles\TorrentInfo\TorrentFileInfoReader.cs" />
|
<Compile Include="MediaFiles\TorrentInfo\TorrentFileInfoReader.cs" />
|
||||||
<Compile Include="Notifications\TrackDownloadMessage.cs" />
|
<Compile Include="Notifications\TrackRetagMessage.cs" />
|
||||||
<Compile Include="Notifications\Email\Email.cs">
|
<Compile Include="Notifications\Email\Email.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue