New: OnApplicationUpdate Notifications
Closes #4810 Co-authored-by: Qstick <qstick@gmail.com>
This commit is contained in:
parent
cee17483d9
commit
71dba904a1
|
@ -1,10 +1,10 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { sizes } from 'Helpers/Props';
|
|
||||||
import Button from 'Components/Link/Button';
|
import Button from 'Components/Link/Button';
|
||||||
import Link from 'Components/Link/Link';
|
import Link from 'Components/Link/Link';
|
||||||
import Menu from 'Components/Menu/Menu';
|
import Menu from 'Components/Menu/Menu';
|
||||||
import MenuContent from 'Components/Menu/MenuContent';
|
import MenuContent from 'Components/Menu/MenuContent';
|
||||||
|
import { sizes } from 'Helpers/Props';
|
||||||
import AddNotificationPresetMenuItem from './AddNotificationPresetMenuItem';
|
import AddNotificationPresetMenuItem from './AddNotificationPresetMenuItem';
|
||||||
import styles from './AddNotificationItem.css';
|
import styles from './AddNotificationItem.css';
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ class AddNotificationItem extends Component {
|
||||||
to={infoLink}
|
to={infoLink}
|
||||||
size={sizes.SMALL}
|
size={sizes.SMALL}
|
||||||
>
|
>
|
||||||
More info
|
More Info
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -9,12 +9,3 @@
|
||||||
|
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.triggers {
|
|
||||||
margin-top: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.triggerEvents {
|
|
||||||
margin-top: 10px;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { inputTypes, kinds } from 'Helpers/Props';
|
|
||||||
import Alert from 'Components/Alert';
|
import Alert from 'Components/Alert';
|
||||||
|
import Form from 'Components/Form/Form';
|
||||||
|
import FormGroup from 'Components/Form/FormGroup';
|
||||||
|
import FormInputGroup from 'Components/Form/FormInputGroup';
|
||||||
|
import FormLabel from 'Components/Form/FormLabel';
|
||||||
|
import ProviderFieldFormGroup from 'Components/Form/ProviderFieldFormGroup';
|
||||||
import Button from 'Components/Link/Button';
|
import Button from 'Components/Link/Button';
|
||||||
import SpinnerErrorButton from 'Components/Link/SpinnerErrorButton';
|
import SpinnerErrorButton from 'Components/Link/SpinnerErrorButton';
|
||||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||||
import ModalContent from 'Components/Modal/ModalContent';
|
|
||||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
|
||||||
import ModalBody from 'Components/Modal/ModalBody';
|
import ModalBody from 'Components/Modal/ModalBody';
|
||||||
|
import ModalContent from 'Components/Modal/ModalContent';
|
||||||
import ModalFooter from 'Components/Modal/ModalFooter';
|
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||||
import Form from 'Components/Form/Form';
|
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||||
import FormGroup from 'Components/Form/FormGroup';
|
import { inputTypes, kinds } from 'Helpers/Props';
|
||||||
import FormLabel from 'Components/Form/FormLabel';
|
import NotificationEventItems from './NotificationEventItems';
|
||||||
import FormInputGroup from 'Components/Form/FormInputGroup';
|
|
||||||
import FormInputHelpText from 'Components/Form/FormInputHelpText';
|
|
||||||
import ProviderFieldFormGroup from 'Components/Form/ProviderFieldFormGroup';
|
|
||||||
import styles from './EditNotificationModalContent.css';
|
import styles from './EditNotificationModalContent.css';
|
||||||
|
|
||||||
function EditNotificationModalContent(props) {
|
function EditNotificationModalContent(props) {
|
||||||
|
@ -39,23 +39,6 @@ function EditNotificationModalContent(props) {
|
||||||
id,
|
id,
|
||||||
implementationName,
|
implementationName,
|
||||||
name,
|
name,
|
||||||
onGrab,
|
|
||||||
onDownload,
|
|
||||||
onUpgrade,
|
|
||||||
onRename,
|
|
||||||
onSeriesDelete,
|
|
||||||
onEpisodeFileDelete,
|
|
||||||
onEpisodeFileDeleteForUpgrade,
|
|
||||||
onHealthIssue,
|
|
||||||
supportsOnGrab,
|
|
||||||
supportsOnDownload,
|
|
||||||
supportsOnUpgrade,
|
|
||||||
supportsOnRename,
|
|
||||||
supportsOnSeriesDelete,
|
|
||||||
supportsOnEpisodeFileDelete,
|
|
||||||
supportsOnEpisodeFileDeleteForUpgrade,
|
|
||||||
supportsOnHealthIssue,
|
|
||||||
includeHealthWarnings,
|
|
||||||
tags,
|
tags,
|
||||||
fields,
|
fields,
|
||||||
message
|
message
|
||||||
|
@ -75,7 +58,9 @@ function EditNotificationModalContent(props) {
|
||||||
|
|
||||||
{
|
{
|
||||||
!isFetching && !!error &&
|
!isFetching && !!error &&
|
||||||
<div>Unable to add a new notification, please try again.</div>
|
<div>
|
||||||
|
Unable to add a new notification, please try again.
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -102,112 +87,11 @@ function EditNotificationModalContent(props) {
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
<FormGroup>
|
<NotificationEventItems
|
||||||
<FormLabel>Triggers</FormLabel>
|
item={item}
|
||||||
|
onInputChange={onInputChange}
|
||||||
<div className={styles.triggers}>
|
|
||||||
<FormInputHelpText
|
|
||||||
text="Select which events should trigger this conection"
|
|
||||||
link="https://wiki.servarr.com/sonarr/settings#connections"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className={styles.triggerEvents}>
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.CHECK}
|
|
||||||
name="onGrab"
|
|
||||||
helpText="On Grab"
|
|
||||||
isDisabled={!supportsOnGrab.value}
|
|
||||||
{...onGrab}
|
|
||||||
onChange={onInputChange}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.CHECK}
|
|
||||||
name="onDownload"
|
|
||||||
helpText="On Import"
|
|
||||||
isDisabled={!supportsOnDownload.value}
|
|
||||||
{...onDownload}
|
|
||||||
onChange={onInputChange}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{
|
|
||||||
onDownload.value ?
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.CHECK}
|
|
||||||
name="onUpgrade"
|
|
||||||
helpText="On Upgrade"
|
|
||||||
isDisabled={!supportsOnUpgrade.value}
|
|
||||||
{...onUpgrade}
|
|
||||||
onChange={onInputChange}
|
|
||||||
/> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.CHECK}
|
|
||||||
name="onRename"
|
|
||||||
helpText="On Rename"
|
|
||||||
isDisabled={!supportsOnRename.value}
|
|
||||||
{...onRename}
|
|
||||||
onChange={onInputChange}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.CHECK}
|
|
||||||
name="onSeriesDelete"
|
|
||||||
helpText="On Series Delete"
|
|
||||||
isDisabled={!supportsOnSeriesDelete.value}
|
|
||||||
{...onSeriesDelete}
|
|
||||||
onChange={onInputChange}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.CHECK}
|
|
||||||
name="onEpisodeFileDelete"
|
|
||||||
helpText="On Episode File Delete"
|
|
||||||
isDisabled={!supportsOnEpisodeFileDelete.value}
|
|
||||||
{...onEpisodeFileDelete}
|
|
||||||
onChange={onInputChange}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{
|
|
||||||
onEpisodeFileDelete.value ?
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.CHECK}
|
|
||||||
name="onEpisodeFileDeleteForUpgrade"
|
|
||||||
helpText="On Episode File Delete For Upgrade"
|
|
||||||
isDisabled={!supportsOnEpisodeFileDeleteForUpgrade.value}
|
|
||||||
{...onEpisodeFileDeleteForUpgrade}
|
|
||||||
onChange={onInputChange}
|
|
||||||
/> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.CHECK}
|
|
||||||
name="onHealthIssue"
|
|
||||||
helpText="On Health Issue"
|
|
||||||
isDisabled={!supportsOnHealthIssue.value}
|
|
||||||
{...onHealthIssue}
|
|
||||||
onChange={onInputChange}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{
|
|
||||||
onHealthIssue.value ?
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.CHECK}
|
|
||||||
name="includeHealthWarnings"
|
|
||||||
helpText="Include Health Warnings"
|
|
||||||
isDisabled={!supportsOnHealthIssue.value}
|
|
||||||
{...includeHealthWarnings}
|
|
||||||
onChange={onInputChange}
|
|
||||||
/> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>Tags</FormLabel>
|
<FormLabel>Tags</FormLabel>
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@ import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
|
import { saveNotification, setNotificationFieldValue, setNotificationValue, testNotification } from 'Store/Actions/settingsActions';
|
||||||
import createProviderSettingsSelector from 'Store/Selectors/createProviderSettingsSelector';
|
import createProviderSettingsSelector from 'Store/Selectors/createProviderSettingsSelector';
|
||||||
import { setNotificationValue, setNotificationFieldValue, saveNotification, testNotification } from 'Store/Actions/settingsActions';
|
|
||||||
import EditNotificationModalContent from './EditNotificationModalContent';
|
import EditNotificationModalContent from './EditNotificationModalContent';
|
||||||
|
|
||||||
function createMapStateToProps() {
|
function createMapStateToProps() {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { kinds } from 'Helpers/Props';
|
|
||||||
import Card from 'Components/Card';
|
import Card from 'Components/Card';
|
||||||
import Label from 'Components/Label';
|
import Label from 'Components/Label';
|
||||||
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||||
|
import { kinds } from 'Helpers/Props';
|
||||||
import EditNotificationModalConnector from './EditNotificationModalConnector';
|
import EditNotificationModalConnector from './EditNotificationModalConnector';
|
||||||
import styles from './Notification.css';
|
import styles from './Notification.css';
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ class Notification extends Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onDeleteNotificationModalClose= () => {
|
onDeleteNotificationModalClose = () => {
|
||||||
this.setState({ isDeleteNotificationModalOpen: false });
|
this.setState({ isDeleteNotificationModalOpen: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +62,7 @@ class Notification extends Component {
|
||||||
onEpisodeFileDelete,
|
onEpisodeFileDelete,
|
||||||
onEpisodeFileDeleteForUpgrade,
|
onEpisodeFileDeleteForUpgrade,
|
||||||
onHealthIssue,
|
onHealthIssue,
|
||||||
|
onApplicationUpdate,
|
||||||
supportsOnGrab,
|
supportsOnGrab,
|
||||||
supportsOnDownload,
|
supportsOnDownload,
|
||||||
supportsOnUpgrade,
|
supportsOnUpgrade,
|
||||||
|
@ -69,7 +70,8 @@ class Notification extends Component {
|
||||||
supportsOnSeriesDelete,
|
supportsOnSeriesDelete,
|
||||||
supportsOnEpisodeFileDelete,
|
supportsOnEpisodeFileDelete,
|
||||||
supportsOnEpisodeFileDeleteForUpgrade,
|
supportsOnEpisodeFileDeleteForUpgrade,
|
||||||
supportsOnHealthIssue
|
supportsOnHealthIssue,
|
||||||
|
supportsOnApplicationUpdate
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -122,6 +124,14 @@ class Notification extends Component {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
supportsOnApplicationUpdate && onApplicationUpdate ?
|
||||||
|
<Label kind={kinds.SUCCESS}>
|
||||||
|
On Application Update
|
||||||
|
</Label> :
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
supportsOnSeriesDelete && onSeriesDelete ?
|
supportsOnSeriesDelete && onSeriesDelete ?
|
||||||
<Label kind={kinds.SUCCESS}>
|
<Label kind={kinds.SUCCESS}>
|
||||||
|
@ -147,7 +157,7 @@ class Notification extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
!onGrab && !onDownload && !onRename && !onHealthIssue && !onSeriesDelete && !onEpisodeFileDelete ?
|
!onGrab && !onDownload && !onRename && !onHealthIssue && !onApplicationUpdate && !onSeriesDelete && !onEpisodeFileDelete ?
|
||||||
<Label
|
<Label
|
||||||
kind={kinds.DISABLED}
|
kind={kinds.DISABLED}
|
||||||
outline={true}
|
outline={true}
|
||||||
|
@ -189,6 +199,7 @@ Notification.propTypes = {
|
||||||
onEpisodeFileDelete: PropTypes.bool.isRequired,
|
onEpisodeFileDelete: PropTypes.bool.isRequired,
|
||||||
onEpisodeFileDeleteForUpgrade: PropTypes.bool.isRequired,
|
onEpisodeFileDeleteForUpgrade: PropTypes.bool.isRequired,
|
||||||
onHealthIssue: PropTypes.bool.isRequired,
|
onHealthIssue: PropTypes.bool.isRequired,
|
||||||
|
onApplicationUpdate: PropTypes.bool.isRequired,
|
||||||
supportsOnGrab: PropTypes.bool.isRequired,
|
supportsOnGrab: PropTypes.bool.isRequired,
|
||||||
supportsOnDownload: PropTypes.bool.isRequired,
|
supportsOnDownload: PropTypes.bool.isRequired,
|
||||||
supportsOnSeriesDelete: PropTypes.bool.isRequired,
|
supportsOnSeriesDelete: PropTypes.bool.isRequired,
|
||||||
|
@ -197,6 +208,7 @@ Notification.propTypes = {
|
||||||
supportsOnUpgrade: PropTypes.bool.isRequired,
|
supportsOnUpgrade: PropTypes.bool.isRequired,
|
||||||
supportsOnRename: PropTypes.bool.isRequired,
|
supportsOnRename: PropTypes.bool.isRequired,
|
||||||
supportsOnHealthIssue: PropTypes.bool.isRequired,
|
supportsOnHealthIssue: PropTypes.bool.isRequired,
|
||||||
|
supportsOnApplicationUpdate: 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,176 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React from 'react';
|
||||||
|
import FormGroup from 'Components/Form/FormGroup';
|
||||||
|
import FormInputGroup from 'Components/Form/FormInputGroup';
|
||||||
|
import FormInputHelpText from 'Components/Form/FormInputHelpText';
|
||||||
|
import FormLabel from 'Components/Form/FormLabel';
|
||||||
|
import { inputTypes } from 'Helpers/Props';
|
||||||
|
import styles from './NotificationEventItems.css';
|
||||||
|
|
||||||
|
function NotificationEventItems(props) {
|
||||||
|
const {
|
||||||
|
item,
|
||||||
|
onInputChange
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
const {
|
||||||
|
onGrab,
|
||||||
|
onDownload,
|
||||||
|
onUpgrade,
|
||||||
|
onRename,
|
||||||
|
onSeriesDelete,
|
||||||
|
onEpisodeFileDelete,
|
||||||
|
onEpisodeFileDeleteForUpgrade,
|
||||||
|
onHealthIssue,
|
||||||
|
onApplicationUpdate,
|
||||||
|
supportsOnGrab,
|
||||||
|
supportsOnDownload,
|
||||||
|
supportsOnUpgrade,
|
||||||
|
supportsOnRename,
|
||||||
|
supportsOnSeriesDelete,
|
||||||
|
supportsOnEpisodeFileDelete,
|
||||||
|
supportsOnEpisodeFileDeleteForUpgrade,
|
||||||
|
supportsOnApplicationUpdate,
|
||||||
|
supportsOnHealthIssue,
|
||||||
|
includeHealthWarnings
|
||||||
|
} = item;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>Notification Triggers</FormLabel>
|
||||||
|
<div>
|
||||||
|
<FormInputHelpText
|
||||||
|
text="Select which events should trigger this notification"
|
||||||
|
link="https://wiki.servarr.com/sonarr/settings#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="onDownload"
|
||||||
|
helpText="On Download"
|
||||||
|
isDisabled={!supportsOnDownload.value}
|
||||||
|
{...onDownload}
|
||||||
|
onChange={onInputChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{
|
||||||
|
onDownload.value &&
|
||||||
|
<div>
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.CHECK}
|
||||||
|
name="onUpgrade"
|
||||||
|
helpText="On Upgrade"
|
||||||
|
isDisabled={!supportsOnUpgrade.value}
|
||||||
|
{...onUpgrade}
|
||||||
|
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="onSeriesDelete"
|
||||||
|
helpText="On Series Delete"
|
||||||
|
isDisabled={!supportsOnSeriesDelete.value}
|
||||||
|
{...onSeriesDelete}
|
||||||
|
onChange={onInputChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.CHECK}
|
||||||
|
name="onEpisodeFileDelete"
|
||||||
|
helpText="On Episode File Delete"
|
||||||
|
isDisabled={!supportsOnEpisodeFileDelete.value}
|
||||||
|
{...onEpisodeFileDelete}
|
||||||
|
onChange={onInputChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{
|
||||||
|
onEpisodeFileDelete.value &&
|
||||||
|
<div>
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.CHECK}
|
||||||
|
name="onEpisodeFileDeleteForUpgrade"
|
||||||
|
helpText="On Episode File Delete For Upgrade"
|
||||||
|
isDisabled={!supportsOnEpisodeFileDeleteForUpgrade.value}
|
||||||
|
{...onEpisodeFileDeleteForUpgrade}
|
||||||
|
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>
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.CHECK}
|
||||||
|
name="onApplicationUpdate"
|
||||||
|
helpText="On Application Update"
|
||||||
|
isDisabled={!supportsOnApplicationUpdate.value}
|
||||||
|
{...onApplicationUpdate}
|
||||||
|
onChange={onInputChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</FormGroup>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationEventItems.propTypes = {
|
||||||
|
item: PropTypes.object.isRequired,
|
||||||
|
onInputChange: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default NotificationEventItems;
|
|
@ -1,13 +1,13 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { icons } from 'Helpers/Props';
|
|
||||||
import FieldSet from 'Components/FieldSet';
|
|
||||||
import Card from 'Components/Card';
|
import Card from 'Components/Card';
|
||||||
|
import FieldSet from 'Components/FieldSet';
|
||||||
import Icon from 'Components/Icon';
|
import Icon from 'Components/Icon';
|
||||||
import PageSectionContent from 'Components/Page/PageSectionContent';
|
import PageSectionContent from 'Components/Page/PageSectionContent';
|
||||||
import Notification from './Notification';
|
import { icons } from 'Helpers/Props';
|
||||||
import AddNotificationModal from './AddNotificationModal';
|
import AddNotificationModal from './AddNotificationModal';
|
||||||
import EditNotificationModalConnector from './EditNotificationModalConnector';
|
import EditNotificationModalConnector from './EditNotificationModalConnector';
|
||||||
|
import Notification from './Notification';
|
||||||
import styles from './Notifications.css';
|
import styles from './Notifications.css';
|
||||||
|
|
||||||
class Notifications extends Component {
|
class Notifications extends Component {
|
||||||
|
|
|
@ -2,9 +2,9 @@ import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import sortByName from 'Utilities/Array/sortByName';
|
import { deleteNotification, fetchNotifications } from 'Store/Actions/settingsActions';
|
||||||
import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector';
|
import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector';
|
||||||
import { fetchNotifications, deleteNotification } from 'Store/Actions/settingsActions';
|
import sortByName from 'Utilities/Array/sortByName';
|
||||||
import Notifications from './Notifications';
|
import Notifications from './Notifications';
|
||||||
|
|
||||||
function createMapStateToProps() {
|
function createMapStateToProps() {
|
||||||
|
|
|
@ -109,6 +109,7 @@ export default {
|
||||||
selectedSchema.onSeriesDelete = selectedSchema.supportsOnSeriesDelete;
|
selectedSchema.onSeriesDelete = selectedSchema.supportsOnSeriesDelete;
|
||||||
selectedSchema.onEpisodeFileDelete = selectedSchema.supportsOnEpisodeFileDelete;
|
selectedSchema.onEpisodeFileDelete = selectedSchema.supportsOnEpisodeFileDelete;
|
||||||
selectedSchema.onEpisodeFileDeleteForUpgrade = selectedSchema.supportsOnEpisodeFileDeleteForUpgrade;
|
selectedSchema.onEpisodeFileDeleteForUpgrade = selectedSchema.supportsOnEpisodeFileDeleteForUpgrade;
|
||||||
|
selectedSchema.onApplicationUpdate = selectedSchema.supportsOnApplicationUpdate;
|
||||||
|
|
||||||
return selectedSchema;
|
return selectedSchema;
|
||||||
});
|
});
|
||||||
|
|
|
@ -79,6 +79,11 @@ namespace NzbDrone.Core.Test.NotificationTests
|
||||||
TestLogger.Info("OnHealthIssue was called");
|
TestLogger.Info("OnHealthIssue was called");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||||
|
{
|
||||||
|
TestLogger.Info("OnApplicationUpdate was called");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestNotificationWithNoEvents : NotificationBase<TestSetting>
|
class TestNotificationWithNoEvents : NotificationBase<TestSetting>
|
||||||
|
@ -120,6 +125,7 @@ namespace NzbDrone.Core.Test.NotificationTests
|
||||||
notification.SupportsOnEpisodeFileDelete.Should().BeTrue();
|
notification.SupportsOnEpisodeFileDelete.Should().BeTrue();
|
||||||
notification.SupportsOnEpisodeFileDeleteForUpgrade.Should().BeTrue();
|
notification.SupportsOnEpisodeFileDeleteForUpgrade.Should().BeTrue();
|
||||||
notification.SupportsOnHealthIssue.Should().BeTrue();
|
notification.SupportsOnHealthIssue.Should().BeTrue();
|
||||||
|
notification.SupportsOnApplicationUpdate.Should().BeTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -136,6 +142,7 @@ namespace NzbDrone.Core.Test.NotificationTests
|
||||||
notification.SupportsOnEpisodeFileDelete.Should().BeFalse();
|
notification.SupportsOnEpisodeFileDelete.Should().BeFalse();
|
||||||
notification.SupportsOnEpisodeFileDeleteForUpgrade.Should().BeFalse();
|
notification.SupportsOnEpisodeFileDeleteForUpgrade.Should().BeFalse();
|
||||||
notification.SupportsOnHealthIssue.Should().BeFalse();
|
notification.SupportsOnHealthIssue.Should().BeFalse();
|
||||||
|
notification.SupportsOnApplicationUpdate.Should().BeFalse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(165)]
|
||||||
|
public class add_on_update_to_notifications : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Alter.Table("Notifications").AddColumn("OnApplicationUpdate").AsBoolean().WithDefaultValue(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -76,7 +76,8 @@ namespace NzbDrone.Core.Datastore
|
||||||
.Ignore(i => i.SupportsOnSeriesDelete)
|
.Ignore(i => i.SupportsOnSeriesDelete)
|
||||||
.Ignore(i => i.SupportsOnEpisodeFileDelete)
|
.Ignore(i => i.SupportsOnEpisodeFileDelete)
|
||||||
.Ignore(i => i.SupportsOnEpisodeFileDeleteForUpgrade)
|
.Ignore(i => i.SupportsOnEpisodeFileDeleteForUpgrade)
|
||||||
.Ignore(i => i.SupportsOnHealthIssue);
|
.Ignore(i => i.SupportsOnHealthIssue)
|
||||||
|
.Ignore(i => i.SupportsOnApplicationUpdate);
|
||||||
|
|
||||||
Mapper.Entity<MetadataDefinition>().RegisterDefinition("Metadata")
|
Mapper.Entity<MetadataDefinition>().RegisterDefinition("Metadata")
|
||||||
.Ignore(d => d.Tags);
|
.Ignore(d => d.Tags);
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Notifications
|
||||||
|
{
|
||||||
|
public class ApplicationUpdateMessage
|
||||||
|
{
|
||||||
|
public string Message { get; set; }
|
||||||
|
public Version PreviousVersion { get; set; }
|
||||||
|
public Version NewVersion { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return NewVersion.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,7 +23,7 @@ namespace NzbDrone.Core.Notifications.Boxcar
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
_proxy.SendNotification(EPISODE_DOWNLOADED_TITLE , message.Message, Settings);
|
_proxy.SendNotification(EPISODE_DOWNLOADED_TITLE, message.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnEpisodeFileDelete(EpisodeDeleteMessage deleteMessage)
|
public override void OnEpisodeFileDelete(EpisodeDeleteMessage deleteMessage)
|
||||||
|
@ -41,6 +41,10 @@ namespace NzbDrone.Core.Notifications.Boxcar
|
||||||
_proxy.SendNotification(HEALTH_ISSUE_TITLE, message.Message, Settings);
|
_proxy.SendNotification(HEALTH_ISSUE_TITLE, message.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnApplicationUpdate(ApplicationUpdateMessage message)
|
||||||
|
{
|
||||||
|
_proxy.SendNotification(APPLICATION_UPDATE_TITLE, message.Message, Settings);
|
||||||
|
}
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
|
@ -198,6 +198,18 @@ namespace NzbDrone.Core.Notifications.CustomScript
|
||||||
ExecuteScript(environmentVariables);
|
ExecuteScript(environmentVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||||
|
{
|
||||||
|
var environmentVariables = new StringDictionary();
|
||||||
|
|
||||||
|
environmentVariables.Add("Sonarr_EventType", "ApplicationUpdate");
|
||||||
|
environmentVariables.Add("Sonarr_Update_Message", updateMessage.Message);
|
||||||
|
environmentVariables.Add("Sonarr_Update_NewVersion", updateMessage.NewVersion.ToString());
|
||||||
|
environmentVariables.Add("Sonarr_Update_PreviousVersion", updateMessage.PreviousVersion.ToString());
|
||||||
|
|
||||||
|
ExecuteScript(environmentVariables);
|
||||||
|
}
|
||||||
|
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
|
@ -295,6 +295,40 @@ namespace NzbDrone.Core.Notifications.Discord
|
||||||
_proxy.SendPayload(payload, Settings);
|
_proxy.SendPayload(payload, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||||
|
{
|
||||||
|
var attachments = new List<Embed>
|
||||||
|
{
|
||||||
|
new Embed
|
||||||
|
{
|
||||||
|
Author = new DiscordAuthor
|
||||||
|
{
|
||||||
|
Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author,
|
||||||
|
IconUrl = "https://raw.githubusercontent.com/Sonarr/Sonarr/develop/Logo/256.png"
|
||||||
|
},
|
||||||
|
Title = APPLICATION_UPDATE_TITLE,
|
||||||
|
Timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"),
|
||||||
|
Color = (int)DiscordColors.Standard,
|
||||||
|
Fields = new List<DiscordField>()
|
||||||
|
{
|
||||||
|
new DiscordField()
|
||||||
|
{
|
||||||
|
Name = "Previous Version",
|
||||||
|
Value = updateMessage.PreviousVersion.ToString()
|
||||||
|
},
|
||||||
|
new DiscordField()
|
||||||
|
{
|
||||||
|
Name = "New Version",
|
||||||
|
Value = updateMessage.NewVersion.ToString()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var payload = CreatePayload(null, attachments);
|
||||||
|
|
||||||
|
_proxy.SendPayload(payload, Settings);
|
||||||
|
}
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
|
@ -57,6 +57,12 @@ namespace NzbDrone.Core.Notifications.Email
|
||||||
SendEmail(Settings, HEALTH_ISSUE_TITLE_BRANDED, message.Message);
|
SendEmail(Settings, HEALTH_ISSUE_TITLE_BRANDED, message.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||||
|
{
|
||||||
|
var body = $"{updateMessage.Message}";
|
||||||
|
|
||||||
|
SendEmail(Settings, APPLICATION_UPDATE_TITLE_BRANDED, body);
|
||||||
|
}
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
|
@ -44,6 +44,11 @@ namespace NzbDrone.Core.Notifications.Gotify
|
||||||
_proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings);
|
_proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||||
|
{
|
||||||
|
_proxy.SendNotification(APPLICATION_UPDATE_TITLE, updateMessage.Message, Settings);
|
||||||
|
}
|
||||||
|
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace NzbDrone.Core.Notifications
|
||||||
void OnEpisodeFileDelete(EpisodeDeleteMessage deleteMessage);
|
void OnEpisodeFileDelete(EpisodeDeleteMessage deleteMessage);
|
||||||
void OnSeriesDelete(SeriesDeleteMessage deleteMessage);
|
void OnSeriesDelete(SeriesDeleteMessage deleteMessage);
|
||||||
void OnHealthIssue(HealthCheck.HealthCheck healthCheck);
|
void OnHealthIssue(HealthCheck.HealthCheck healthCheck);
|
||||||
|
void OnApplicationUpdate(ApplicationUpdateMessage updateMessage);
|
||||||
void ProcessQueue();
|
void ProcessQueue();
|
||||||
bool SupportsOnGrab { get; }
|
bool SupportsOnGrab { get; }
|
||||||
bool SupportsOnDownload { get; }
|
bool SupportsOnDownload { get; }
|
||||||
|
@ -24,5 +25,6 @@ namespace NzbDrone.Core.Notifications
|
||||||
bool SupportsOnEpisodeFileDelete { get; }
|
bool SupportsOnEpisodeFileDelete { get; }
|
||||||
bool SupportsOnEpisodeFileDeleteForUpgrade { get; }
|
bool SupportsOnEpisodeFileDeleteForUpgrade { get; }
|
||||||
bool SupportsOnHealthIssue { get; }
|
bool SupportsOnHealthIssue { get; }
|
||||||
|
bool SupportsOnApplicationUpdate { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,11 @@ namespace NzbDrone.Core.Notifications.Join
|
||||||
_proxy.SendNotification(HEALTH_ISSUE_TITLE_BRANDED, message.Message, Settings);
|
_proxy.SendNotification(HEALTH_ISSUE_TITLE_BRANDED, message.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||||
|
{
|
||||||
|
_proxy.SendNotification(APPLICATION_UPDATE_TITLE_BRANDED, updateMessage.Message, Settings);
|
||||||
|
}
|
||||||
|
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
|
@ -48,6 +48,10 @@ namespace NzbDrone.Core.Notifications.Mailgun
|
||||||
_proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheckMessage.Message, Settings);
|
_proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheckMessage.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||||
|
{
|
||||||
|
_proxy.SendNotification(APPLICATION_UPDATE_TITLE, updateMessage.Message, Settings);
|
||||||
|
}
|
||||||
|
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
|
|
|
@ -82,6 +82,14 @@ namespace NzbDrone.Core.Notifications.Emby
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||||
|
{
|
||||||
|
if (Settings.Notify)
|
||||||
|
{
|
||||||
|
_mediaBrowserService.Notify(Settings, APPLICATION_UPDATE_TITLE_BRANDED, updateMessage.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
|
@ -15,12 +15,14 @@ namespace NzbDrone.Core.Notifications
|
||||||
protected const string EPISODE_DELETED_TITLE = "Episode Deleted";
|
protected const string EPISODE_DELETED_TITLE = "Episode Deleted";
|
||||||
protected const string SERIES_DELETED_TITLE = "Series Deleted";
|
protected const string SERIES_DELETED_TITLE = "Series Deleted";
|
||||||
protected const string HEALTH_ISSUE_TITLE = "Health Check Failure";
|
protected const string HEALTH_ISSUE_TITLE = "Health Check Failure";
|
||||||
|
protected const string APPLICATION_UPDATE_TITLE = "Application Updated";
|
||||||
|
|
||||||
protected const string EPISODE_GRABBED_TITLE_BRANDED = "Sonarr - " + EPISODE_GRABBED_TITLE;
|
protected const string EPISODE_GRABBED_TITLE_BRANDED = "Sonarr - " + EPISODE_GRABBED_TITLE;
|
||||||
protected const string EPISODE_DOWNLOADED_TITLE_BRANDED = "Sonarr - " + EPISODE_DOWNLOADED_TITLE;
|
protected const string EPISODE_DOWNLOADED_TITLE_BRANDED = "Sonarr - " + EPISODE_DOWNLOADED_TITLE;
|
||||||
protected const string EPISODE_DELETED_TITLE_BRANDED = "Sonarr - " + EPISODE_DELETED_TITLE;
|
protected const string EPISODE_DELETED_TITLE_BRANDED = "Sonarr - " + EPISODE_DELETED_TITLE;
|
||||||
protected const string SERIES_DELETED_TITLE_BRANDED = "Sonarr - " + SERIES_DELETED_TITLE;
|
protected const string SERIES_DELETED_TITLE_BRANDED = "Sonarr - " + SERIES_DELETED_TITLE;
|
||||||
protected const string HEALTH_ISSUE_TITLE_BRANDED = "Sonarr - " + HEALTH_ISSUE_TITLE;
|
protected const string HEALTH_ISSUE_TITLE_BRANDED = "Sonarr - " + HEALTH_ISSUE_TITLE;
|
||||||
|
protected const string APPLICATION_UPDATE_TITLE_BRANDED = "Sonarr - " + APPLICATION_UPDATE_TITLE;
|
||||||
|
|
||||||
public abstract string Name { get; }
|
public abstract string Name { get; }
|
||||||
|
|
||||||
|
@ -65,6 +67,10 @@ namespace NzbDrone.Core.Notifications
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void ProcessQueue()
|
public virtual void ProcessQueue()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -78,6 +84,7 @@ namespace NzbDrone.Core.Notifications
|
||||||
public bool SupportsOnEpisodeFileDelete => HasConcreteImplementation("OnEpisodeFileDelete");
|
public bool SupportsOnEpisodeFileDelete => HasConcreteImplementation("OnEpisodeFileDelete");
|
||||||
public bool SupportsOnEpisodeFileDeleteForUpgrade => SupportsOnEpisodeFileDelete;
|
public bool SupportsOnEpisodeFileDeleteForUpgrade => SupportsOnEpisodeFileDelete;
|
||||||
public bool SupportsOnHealthIssue => HasConcreteImplementation("OnHealthIssue");
|
public bool SupportsOnHealthIssue => HasConcreteImplementation("OnHealthIssue");
|
||||||
|
public bool SupportsOnApplicationUpdate => HasConcreteImplementation("OnApplicationUpdate");
|
||||||
|
|
||||||
protected TSettings Settings => (TSettings)Definition.Settings;
|
protected TSettings Settings => (TSettings)Definition.Settings;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace NzbDrone.Core.Notifications
|
||||||
public bool OnEpisodeFileDelete { get; set; }
|
public bool OnEpisodeFileDelete { get; set; }
|
||||||
public bool OnEpisodeFileDeleteForUpgrade { get; set; }
|
public bool OnEpisodeFileDeleteForUpgrade { get; set; }
|
||||||
public bool OnHealthIssue { get; set; }
|
public bool OnHealthIssue { get; set; }
|
||||||
|
public bool OnApplicationUpdate { get; set; }
|
||||||
public bool SupportsOnGrab { get; set; }
|
public bool SupportsOnGrab { get; set; }
|
||||||
public bool SupportsOnDownload { get; set; }
|
public bool SupportsOnDownload { get; set; }
|
||||||
public bool SupportsOnUpgrade { get; set; }
|
public bool SupportsOnUpgrade { get; set; }
|
||||||
|
@ -21,7 +22,8 @@ namespace NzbDrone.Core.Notifications
|
||||||
public bool SupportsOnEpisodeFileDeleteForUpgrade { get; set; }
|
public bool SupportsOnEpisodeFileDeleteForUpgrade { get; set; }
|
||||||
public bool SupportsOnHealthIssue { get; set; }
|
public bool SupportsOnHealthIssue { get; set; }
|
||||||
public bool IncludeHealthWarnings { get; set; }
|
public bool IncludeHealthWarnings { get; set; }
|
||||||
|
public bool SupportsOnApplicationUpdate { get; set; }
|
||||||
|
|
||||||
public override bool Enable => OnGrab || OnDownload || (OnDownload && OnUpgrade) || OnSeriesDelete || OnEpisodeFileDelete || OnEpisodeFileDeleteForUpgrade || OnHealthIssue;
|
public override bool Enable => OnGrab || OnDownload || (OnDownload && OnUpgrade) || OnSeriesDelete || OnEpisodeFileDelete || OnEpisodeFileDeleteForUpgrade || OnHealthIssue || OnApplicationUpdate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace NzbDrone.Core.Notifications
|
||||||
List<INotification> OnEpisodeFileDeleteEnabled();
|
List<INotification> OnEpisodeFileDeleteEnabled();
|
||||||
List<INotification> OnEpisodeFileDeleteForUpgradeEnabled();
|
List<INotification> OnEpisodeFileDeleteForUpgradeEnabled();
|
||||||
List<INotification> OnHealthIssueEnabled();
|
List<INotification> OnHealthIssueEnabled();
|
||||||
|
List<INotification> OnApplicationUpdateEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NotificationFactory : ProviderFactory<INotification, NotificationDefinition>, INotificationFactory
|
public class NotificationFactory : ProviderFactory<INotification, NotificationDefinition>, INotificationFactory
|
||||||
|
@ -65,6 +66,11 @@ namespace NzbDrone.Core.Notifications
|
||||||
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnHealthIssue).ToList();
|
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnHealthIssue).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<INotification> OnApplicationUpdateEnabled()
|
||||||
|
{
|
||||||
|
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnApplicationUpdate).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);
|
||||||
|
@ -77,6 +83,7 @@ namespace NzbDrone.Core.Notifications
|
||||||
definition.SupportsOnEpisodeFileDelete = provider.SupportsOnEpisodeFileDelete;
|
definition.SupportsOnEpisodeFileDelete = provider.SupportsOnEpisodeFileDelete;
|
||||||
definition.SupportsOnEpisodeFileDeleteForUpgrade = provider.SupportsOnEpisodeFileDeleteForUpgrade;
|
definition.SupportsOnEpisodeFileDeleteForUpgrade = provider.SupportsOnEpisodeFileDeleteForUpgrade;
|
||||||
definition.SupportsOnHealthIssue = provider.SupportsOnHealthIssue;
|
definition.SupportsOnHealthIssue = provider.SupportsOnHealthIssue;
|
||||||
|
definition.SupportsOnApplicationUpdate = provider.SupportsOnApplicationUpdate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -11,6 +11,7 @@ using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Core.Tv.Events;
|
using NzbDrone.Core.Tv.Events;
|
||||||
|
using NzbDrone.Core.Update.History.Events;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications
|
namespace NzbDrone.Core.Notifications
|
||||||
{
|
{
|
||||||
|
@ -21,6 +22,7 @@ namespace NzbDrone.Core.Notifications
|
||||||
IHandle<SeriesDeletedEvent>,
|
IHandle<SeriesDeletedEvent>,
|
||||||
IHandle<EpisodeFileDeletedEvent>,
|
IHandle<EpisodeFileDeletedEvent>,
|
||||||
IHandle<HealthCheckFailedEvent>,
|
IHandle<HealthCheckFailedEvent>,
|
||||||
|
IHandle<UpdateInstalledEvent>,
|
||||||
IHandleAsync<DeleteCompletedEvent>,
|
IHandleAsync<DeleteCompletedEvent>,
|
||||||
IHandleAsync<DownloadsProcessedEvent>,
|
IHandleAsync<DownloadsProcessedEvent>,
|
||||||
IHandleAsync<RenameCompletedEvent>,
|
IHandleAsync<RenameCompletedEvent>,
|
||||||
|
@ -193,6 +195,26 @@ namespace NzbDrone.Core.Notifications
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Handle(UpdateInstalledEvent message)
|
||||||
|
{
|
||||||
|
var updateMessage = new ApplicationUpdateMessage();
|
||||||
|
updateMessage.Message = $"Sonarr updated from {message.PreviousVerison.ToString()} to {message.NewVersion.ToString()}";
|
||||||
|
updateMessage.PreviousVersion = message.PreviousVerison;
|
||||||
|
updateMessage.NewVersion = message.NewVersion;
|
||||||
|
|
||||||
|
foreach (var notification in _notificationFactory.OnApplicationUpdateEnabled())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
notification.OnApplicationUpdate(updateMessage);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Warn(ex, "Unable to send OnApplicationUpdate notification to: " + notification.Definition.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Handle(EpisodeFileDeletedEvent message)
|
public void Handle(EpisodeFileDeletedEvent message)
|
||||||
{
|
{
|
||||||
if (message.EpisodeFile.Episodes.Value.Empty())
|
if (message.EpisodeFile.Episodes.Value.Empty())
|
||||||
|
@ -229,7 +251,7 @@ namespace NzbDrone.Core.Notifications
|
||||||
|
|
||||||
public void Handle(SeriesDeletedEvent message)
|
public void Handle(SeriesDeletedEvent message)
|
||||||
{
|
{
|
||||||
var deleteMessage = new SeriesDeleteMessage(message.Series,message.DeleteFiles);
|
var deleteMessage = new SeriesDeleteMessage(message.Series, message.DeleteFiles);
|
||||||
|
|
||||||
foreach (var notification in _notificationFactory.OnSeriesDeleteEnabled())
|
foreach (var notification in _notificationFactory.OnSeriesDeleteEnabled())
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,6 +41,11 @@ namespace NzbDrone.Core.Notifications.Prowl
|
||||||
_prowlProxy.SendNotification(HEALTH_ISSUE_TITLE, message.Message, Settings);
|
_prowlProxy.SendNotification(HEALTH_ISSUE_TITLE, message.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||||
|
{
|
||||||
|
_prowlProxy.SendNotification(APPLICATION_UPDATE_TITLE, updateMessage.Message, Settings);
|
||||||
|
}
|
||||||
|
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
|
@ -43,6 +43,11 @@ namespace NzbDrone.Core.Notifications.PushBullet
|
||||||
_proxy.SendNotification(HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message, Settings);
|
_proxy.SendNotification(HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||||
|
{
|
||||||
|
_proxy.SendNotification(APPLICATION_UPDATE_TITLE_BRANDED, updateMessage.Message, Settings);
|
||||||
|
}
|
||||||
|
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
|
@ -41,6 +41,11 @@ namespace NzbDrone.Core.Notifications.Pushover
|
||||||
_proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings);
|
_proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||||
|
{
|
||||||
|
_proxy.SendNotification(APPLICATION_UPDATE_TITLE, updateMessage.Message, Settings);
|
||||||
|
}
|
||||||
|
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
|
@ -43,6 +43,11 @@ namespace NzbDrone.Core.Notifications.SendGrid
|
||||||
_proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings);
|
_proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||||
|
{
|
||||||
|
_proxy.SendNotification(APPLICATION_UPDATE_TITLE, updateMessage.Message, Settings);
|
||||||
|
}
|
||||||
|
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
|
@ -120,6 +120,23 @@ namespace NzbDrone.Core.Notifications.Slack
|
||||||
_proxy.SendPayload(payload, Settings);
|
_proxy.SendPayload(payload, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||||
|
{
|
||||||
|
var attachments = new List<Attachment>
|
||||||
|
{
|
||||||
|
new Attachment
|
||||||
|
{
|
||||||
|
Title = Environment.MachineName,
|
||||||
|
Text = updateMessage.Message,
|
||||||
|
Color = "good"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var payload = CreatePayload("Application Updated", attachments);
|
||||||
|
|
||||||
|
_proxy.SendPayload(payload, Settings);
|
||||||
|
}
|
||||||
|
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
|
@ -41,6 +41,11 @@ namespace NzbDrone.Core.Notifications.Telegram
|
||||||
_proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings);
|
_proxy.SendNotification(HEALTH_ISSUE_TITLE, healthCheck.Message, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||||
|
{
|
||||||
|
_proxy.SendNotification(APPLICATION_UPDATE_TITLE, updateMessage.Message, Settings);
|
||||||
|
}
|
||||||
|
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var failures = new List<ValidationFailure>();
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
|
@ -44,6 +44,11 @@ namespace NzbDrone.Core.Notifications.Twitter
|
||||||
_twitterService.SendNotification($"Health Issue: {healthCheck.Message}", Settings);
|
_twitterService.SendNotification($"Health Issue: {healthCheck.Message}", Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||||
|
{
|
||||||
|
_twitterService.SendNotification($"Application Updated: {updateMessage.Message}", Settings);
|
||||||
|
}
|
||||||
|
|
||||||
public override object RequestAction(string action, IDictionary<string, string> query)
|
public override object RequestAction(string action, IDictionary<string, string> query)
|
||||||
{
|
{
|
||||||
if (action == "startOAuth")
|
if (action == "startOAuth")
|
||||||
|
|
|
@ -118,6 +118,19 @@ namespace NzbDrone.Core.Notifications.Webhook
|
||||||
_proxy.SendWebhook(payload, Settings);
|
_proxy.SendWebhook(payload, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||||
|
{
|
||||||
|
var payload = new WebhookApplicationUpdatePayload
|
||||||
|
{
|
||||||
|
EventType = WebhookEventType.ApplicationUpdate,
|
||||||
|
Message = updateMessage.Message,
|
||||||
|
PreviousVersion = updateMessage.PreviousVersion.ToString(),
|
||||||
|
NewVersion = updateMessage.NewVersion.ToString()
|
||||||
|
};
|
||||||
|
|
||||||
|
_proxy.SendWebhook(payload, Settings);
|
||||||
|
}
|
||||||
|
|
||||||
public override string Name => "Webhook";
|
public override string Name => "Webhook";
|
||||||
|
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
using NzbDrone.Core.HealthCheck;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Notifications.Webhook
|
||||||
|
{
|
||||||
|
public class WebhookApplicationUpdatePayload : WebhookPayload
|
||||||
|
{
|
||||||
|
public string Message { get; set; }
|
||||||
|
public string PreviousVersion { get; set; }
|
||||||
|
public string NewVersion { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ namespace NzbDrone.Core.Notifications.Webhook
|
||||||
Rename,
|
Rename,
|
||||||
SeriesDelete,
|
SeriesDelete,
|
||||||
EpisodeFileDelete,
|
EpisodeFileDelete,
|
||||||
Health
|
Health,
|
||||||
|
ApplicationUpdate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,11 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
Notify(Settings, HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message);
|
Notify(Settings, HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
|
||||||
|
{
|
||||||
|
Notify(Settings, APPLICATION_UPDATE_TITLE_BRANDED, updateMessage.Message);
|
||||||
|
}
|
||||||
|
|
||||||
public override string Name => "Kodi";
|
public override string Name => "Kodi";
|
||||||
|
|
||||||
public override ValidationResult Test()
|
public override ValidationResult Test()
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace Sonarr.Api.V3.Notifications
|
||||||
public bool OnEpisodeFileDelete { get; set; }
|
public bool OnEpisodeFileDelete { get; set; }
|
||||||
public bool OnEpisodeFileDeleteForUpgrade { get; set; }
|
public bool OnEpisodeFileDeleteForUpgrade { get; set; }
|
||||||
public bool OnHealthIssue { get; set; }
|
public bool OnHealthIssue { get; set; }
|
||||||
|
public bool OnApplicationUpdate { get; set; }
|
||||||
public bool SupportsOnGrab { get; set; }
|
public bool SupportsOnGrab { get; set; }
|
||||||
public bool SupportsOnDownload { get; set; }
|
public bool SupportsOnDownload { get; set; }
|
||||||
public bool SupportsOnUpgrade { get; set; }
|
public bool SupportsOnUpgrade { get; set; }
|
||||||
|
@ -21,6 +22,7 @@ namespace Sonarr.Api.V3.Notifications
|
||||||
public bool SupportsOnEpisodeFileDelete { get; set; }
|
public bool SupportsOnEpisodeFileDelete { get; set; }
|
||||||
public bool SupportsOnEpisodeFileDeleteForUpgrade { get; set; }
|
public bool SupportsOnEpisodeFileDeleteForUpgrade { get; set; }
|
||||||
public bool SupportsOnHealthIssue { get; set; }
|
public bool SupportsOnHealthIssue { get; set; }
|
||||||
|
public bool SupportsOnApplicationUpdate { get; set; }
|
||||||
public bool IncludeHealthWarnings { get; set; }
|
public bool IncludeHealthWarnings { get; set; }
|
||||||
public string TestCommand { get; set; }
|
public string TestCommand { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -41,6 +43,7 @@ namespace Sonarr.Api.V3.Notifications
|
||||||
resource.OnEpisodeFileDelete = definition.OnEpisodeFileDelete;
|
resource.OnEpisodeFileDelete = definition.OnEpisodeFileDelete;
|
||||||
resource.OnEpisodeFileDeleteForUpgrade = definition.OnEpisodeFileDeleteForUpgrade;
|
resource.OnEpisodeFileDeleteForUpgrade = definition.OnEpisodeFileDeleteForUpgrade;
|
||||||
resource.OnHealthIssue = definition.OnHealthIssue;
|
resource.OnHealthIssue = definition.OnHealthIssue;
|
||||||
|
resource.OnApplicationUpdate = definition.OnApplicationUpdate;
|
||||||
resource.SupportsOnGrab = definition.SupportsOnGrab;
|
resource.SupportsOnGrab = definition.SupportsOnGrab;
|
||||||
resource.SupportsOnDownload = definition.SupportsOnDownload;
|
resource.SupportsOnDownload = definition.SupportsOnDownload;
|
||||||
resource.SupportsOnUpgrade = definition.SupportsOnUpgrade;
|
resource.SupportsOnUpgrade = definition.SupportsOnUpgrade;
|
||||||
|
@ -50,6 +53,7 @@ namespace Sonarr.Api.V3.Notifications
|
||||||
resource.SupportsOnEpisodeFileDeleteForUpgrade = definition.SupportsOnEpisodeFileDeleteForUpgrade;
|
resource.SupportsOnEpisodeFileDeleteForUpgrade = definition.SupportsOnEpisodeFileDeleteForUpgrade;
|
||||||
resource.SupportsOnHealthIssue = definition.SupportsOnHealthIssue;
|
resource.SupportsOnHealthIssue = definition.SupportsOnHealthIssue;
|
||||||
resource.IncludeHealthWarnings = definition.IncludeHealthWarnings;
|
resource.IncludeHealthWarnings = definition.IncludeHealthWarnings;
|
||||||
|
resource.SupportsOnApplicationUpdate = definition.SupportsOnApplicationUpdate;
|
||||||
|
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
@ -68,6 +72,7 @@ namespace Sonarr.Api.V3.Notifications
|
||||||
definition.OnEpisodeFileDelete = resource.OnEpisodeFileDelete;
|
definition.OnEpisodeFileDelete = resource.OnEpisodeFileDelete;
|
||||||
definition.OnEpisodeFileDeleteForUpgrade = resource.OnEpisodeFileDeleteForUpgrade;
|
definition.OnEpisodeFileDeleteForUpgrade = resource.OnEpisodeFileDeleteForUpgrade;
|
||||||
definition.OnHealthIssue = resource.OnHealthIssue;
|
definition.OnHealthIssue = resource.OnHealthIssue;
|
||||||
|
definition.OnApplicationUpdate = resource.OnApplicationUpdate;
|
||||||
definition.SupportsOnGrab = resource.SupportsOnGrab;
|
definition.SupportsOnGrab = resource.SupportsOnGrab;
|
||||||
definition.SupportsOnDownload = resource.SupportsOnDownload;
|
definition.SupportsOnDownload = resource.SupportsOnDownload;
|
||||||
definition.SupportsOnUpgrade = resource.SupportsOnUpgrade;
|
definition.SupportsOnUpgrade = resource.SupportsOnUpgrade;
|
||||||
|
@ -77,6 +82,7 @@ namespace Sonarr.Api.V3.Notifications
|
||||||
definition.SupportsOnEpisodeFileDeleteForUpgrade = resource.SupportsOnEpisodeFileDeleteForUpgrade;
|
definition.SupportsOnEpisodeFileDeleteForUpgrade = resource.SupportsOnEpisodeFileDeleteForUpgrade;
|
||||||
definition.SupportsOnHealthIssue = resource.SupportsOnHealthIssue;
|
definition.SupportsOnHealthIssue = resource.SupportsOnHealthIssue;
|
||||||
definition.IncludeHealthWarnings = resource.IncludeHealthWarnings;
|
definition.IncludeHealthWarnings = resource.IncludeHealthWarnings;
|
||||||
|
definition.SupportsOnApplicationUpdate = resource.SupportsOnApplicationUpdate;
|
||||||
|
|
||||||
return definition;
|
return definition;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue