mirror of https://github.com/Radarr/Radarr
New: Reset Quality Definitions to default
(cherry picked from commit d5fff15f32fdb49768dcadd94c760678e650c884)
This commit is contained in:
parent
850bfdcf82
commit
ae8245c3c5
|
@ -22,7 +22,7 @@ import MediaManagementConnector from 'Settings/MediaManagement/MediaManagementCo
|
||||||
import MetadataSettings from 'Settings/Metadata/MetadataSettings';
|
import MetadataSettings from 'Settings/Metadata/MetadataSettings';
|
||||||
import NotificationSettings from 'Settings/Notifications/NotificationSettings';
|
import NotificationSettings from 'Settings/Notifications/NotificationSettings';
|
||||||
import Profiles from 'Settings/Profiles/Profiles';
|
import Profiles from 'Settings/Profiles/Profiles';
|
||||||
import Quality from 'Settings/Quality/Quality';
|
import QualityConnector from 'Settings/Quality/QualityConnector';
|
||||||
import Settings from 'Settings/Settings';
|
import Settings from 'Settings/Settings';
|
||||||
import TagSettings from 'Settings/Tags/TagSettings';
|
import TagSettings from 'Settings/Tags/TagSettings';
|
||||||
import UISettingsConnector from 'Settings/UI/UISettingsConnector';
|
import UISettingsConnector from 'Settings/UI/UISettingsConnector';
|
||||||
|
@ -143,7 +143,7 @@ function AppRoutes(props) {
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path="/settings/quality"
|
path="/settings/quality"
|
||||||
component={Quality}
|
component={QualityConnector}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
|
|
|
@ -15,6 +15,7 @@ export const REFRESH_MOVIE = 'RefreshMovie';
|
||||||
export const RENAME_FILES = 'RenameFiles';
|
export const RENAME_FILES = 'RenameFiles';
|
||||||
export const RENAME_MOVIE = 'RenameMovie';
|
export const RENAME_MOVIE = 'RenameMovie';
|
||||||
export const RESET_API_KEY = 'ResetApiKey';
|
export const RESET_API_KEY = 'ResetApiKey';
|
||||||
|
export const RESET_QUALITY_DEFINITIONS = 'ResetQualityDefinitions';
|
||||||
export const RSS_SYNC = 'RssSync';
|
export const RSS_SYNC = 'RssSync';
|
||||||
export const MOVIE_SEARCH = 'MoviesSearch';
|
export const MOVIE_SEARCH = 'MoviesSearch';
|
||||||
export const IMPORT_LIST_SYNC = 'ImportListSync';
|
export const IMPORT_LIST_SYNC = 'ImportListSync';
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { fetchCommands, finishCommand, updateCommand } from 'Store/Actions/comma
|
||||||
import { fetchMovies } from 'Store/Actions/movieActions';
|
import { fetchMovies } from 'Store/Actions/movieActions';
|
||||||
import { fetchQueue, fetchQueueDetails } from 'Store/Actions/queueActions';
|
import { fetchQueue, fetchQueueDetails } from 'Store/Actions/queueActions';
|
||||||
import { fetchRootFolders } from 'Store/Actions/rootFolderActions';
|
import { fetchRootFolders } from 'Store/Actions/rootFolderActions';
|
||||||
|
import { fetchQualityDefinitions } from 'Store/Actions/settingsActions';
|
||||||
import { fetchHealth } from 'Store/Actions/systemActions';
|
import { fetchHealth } from 'Store/Actions/systemActions';
|
||||||
import { fetchTagDetails, fetchTags } from 'Store/Actions/tagActions';
|
import { fetchTagDetails, fetchTags } from 'Store/Actions/tagActions';
|
||||||
import { repopulatePage } from 'Utilities/pagePopulator';
|
import { repopulatePage } from 'Utilities/pagePopulator';
|
||||||
|
@ -46,6 +47,7 @@ const mapDispatchToProps = {
|
||||||
dispatchUpdateItem: updateItem,
|
dispatchUpdateItem: updateItem,
|
||||||
dispatchRemoveItem: removeItem,
|
dispatchRemoveItem: removeItem,
|
||||||
dispatchFetchHealth: fetchHealth,
|
dispatchFetchHealth: fetchHealth,
|
||||||
|
dispatchFetchQualityDefinitions: fetchQualityDefinitions,
|
||||||
dispatchFetchQueue: fetchQueue,
|
dispatchFetchQueue: fetchQueue,
|
||||||
dispatchFetchQueueDetails: fetchQueueDetails,
|
dispatchFetchQueueDetails: fetchQueueDetails,
|
||||||
dispatchFetchRootFolders: fetchRootFolders,
|
dispatchFetchRootFolders: fetchRootFolders,
|
||||||
|
@ -216,6 +218,10 @@ class SignalRConnector extends Component {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleQualitydefinition = () => {
|
||||||
|
this.props.dispatchFetchQualityDefinitions();
|
||||||
|
};
|
||||||
|
|
||||||
handleQueue = () => {
|
handleQueue = () => {
|
||||||
if (this.props.isQueuePopulated) {
|
if (this.props.isQueuePopulated) {
|
||||||
this.props.dispatchFetchQueue();
|
this.props.dispatchFetchQueue();
|
||||||
|
@ -335,6 +341,7 @@ SignalRConnector.propTypes = {
|
||||||
dispatchUpdateItem: PropTypes.func.isRequired,
|
dispatchUpdateItem: PropTypes.func.isRequired,
|
||||||
dispatchRemoveItem: PropTypes.func.isRequired,
|
dispatchRemoveItem: PropTypes.func.isRequired,
|
||||||
dispatchFetchHealth: PropTypes.func.isRequired,
|
dispatchFetchHealth: PropTypes.func.isRequired,
|
||||||
|
dispatchFetchQualityDefinitions: PropTypes.func.isRequired,
|
||||||
dispatchFetchQueue: PropTypes.func.isRequired,
|
dispatchFetchQueue: PropTypes.func.isRequired,
|
||||||
dispatchFetchQueueDetails: PropTypes.func.isRequired,
|
dispatchFetchQueueDetails: PropTypes.func.isRequired,
|
||||||
dispatchFetchRootFolders: PropTypes.func.isRequired,
|
dispatchFetchRootFolders: PropTypes.func.isRequired,
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
import React, { Component } from 'react';
|
import PropTypes from 'prop-types';
|
||||||
|
import React, { Component, Fragment } from 'react';
|
||||||
import PageContent from 'Components/Page/PageContent';
|
import PageContent from 'Components/Page/PageContent';
|
||||||
import PageContentBody from 'Components/Page/PageContentBody';
|
import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
|
import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
||||||
|
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
||||||
|
import { icons } from 'Helpers/Props';
|
||||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import QualityDefinitionsConnector from './Definition/QualityDefinitionsConnector';
|
import QualityDefinitionsConnector from './Definition/QualityDefinitionsConnector';
|
||||||
|
import ResetQualityDefinitionsModal from './Reset/ResetQualityDefinitionsModal';
|
||||||
|
|
||||||
class Quality extends Component {
|
class Quality extends Component {
|
||||||
|
|
||||||
|
@ -17,7 +22,8 @@ class Quality extends Component {
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
isSaving: false,
|
isSaving: false,
|
||||||
hasPendingChanges: false
|
hasPendingChanges: false,
|
||||||
|
isConfirmQualityDefinitionResetModalOpen: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +38,14 @@ class Quality extends Component {
|
||||||
this.setState(payload);
|
this.setState(payload);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onResetQualityDefinitionsPress = () => {
|
||||||
|
this.setState({ isConfirmQualityDefinitionResetModalOpen: true });
|
||||||
|
};
|
||||||
|
|
||||||
|
onCloseResetQualityDefinitionsModal = () => {
|
||||||
|
this.setState({ isConfirmQualityDefinitionResetModalOpen: false });
|
||||||
|
};
|
||||||
|
|
||||||
onSavePress = () => {
|
onSavePress = () => {
|
||||||
if (this._saveCallback) {
|
if (this._saveCallback) {
|
||||||
this._saveCallback();
|
this._saveCallback();
|
||||||
|
@ -44,6 +58,7 @@ class Quality extends Component {
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
isSaving,
|
isSaving,
|
||||||
|
isResettingQualityDefinitions,
|
||||||
hasPendingChanges
|
hasPendingChanges
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
|
@ -52,6 +67,18 @@ class Quality extends Component {
|
||||||
<SettingsToolbarConnector
|
<SettingsToolbarConnector
|
||||||
isSaving={isSaving}
|
isSaving={isSaving}
|
||||||
hasPendingChanges={hasPendingChanges}
|
hasPendingChanges={hasPendingChanges}
|
||||||
|
additionalButtons={
|
||||||
|
<Fragment>
|
||||||
|
<PageToolbarSeparator />
|
||||||
|
|
||||||
|
<PageToolbarButton
|
||||||
|
label={translate('ResetDefinitions')}
|
||||||
|
iconName={icons.REFRESH}
|
||||||
|
isSpinning={isResettingQualityDefinitions}
|
||||||
|
onPress={this.onResetQualityDefinitionsPress}
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
}
|
||||||
onSavePress={this.onSavePress}
|
onSavePress={this.onSavePress}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -61,9 +88,18 @@ class Quality extends Component {
|
||||||
onChildStateChange={this.onChildStateChange}
|
onChildStateChange={this.onChildStateChange}
|
||||||
/>
|
/>
|
||||||
</PageContentBody>
|
</PageContentBody>
|
||||||
|
|
||||||
|
<ResetQualityDefinitionsModal
|
||||||
|
isOpen={this.state.isConfirmQualityDefinitionResetModalOpen}
|
||||||
|
onModalClose={this.onCloseResetQualityDefinitionsModal}
|
||||||
|
/>
|
||||||
</PageContent>
|
</PageContent>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Quality.propTypes = {
|
||||||
|
isResettingQualityDefinitions: PropTypes.bool.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
export default Quality;
|
export default Quality;
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { createSelector } from 'reselect';
|
||||||
|
import * as commandNames from 'Commands/commandNames';
|
||||||
|
import createCommandExecutingSelector from 'Store/Selectors/createCommandExecutingSelector';
|
||||||
|
import Quality from './Quality';
|
||||||
|
|
||||||
|
function createMapStateToProps() {
|
||||||
|
return createSelector(
|
||||||
|
createCommandExecutingSelector(commandNames.RESET_QUALITY_DEFINITIONS),
|
||||||
|
(isResettingQualityDefinitions) => {
|
||||||
|
return {
|
||||||
|
isResettingQualityDefinitions
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class QualityConnector extends Component {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Render
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Quality
|
||||||
|
{...this.props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QualityConnector.propTypes = {
|
||||||
|
isResettingQualityDefinitions: PropTypes.bool.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(createMapStateToProps)(QualityConnector);
|
|
@ -0,0 +1,33 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React from 'react';
|
||||||
|
import Modal from 'Components/Modal/Modal';
|
||||||
|
import { sizes } from 'Helpers/Props';
|
||||||
|
import ResetQualityDefinitionsModalContentConnector from './ResetQualityDefinitionsModalContentConnector';
|
||||||
|
|
||||||
|
function ResetQualityDefinitionsModal(props) {
|
||||||
|
const {
|
||||||
|
isOpen,
|
||||||
|
onModalClose,
|
||||||
|
...otherProps
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
isOpen={isOpen}
|
||||||
|
size={sizes.MEDIUM}
|
||||||
|
onModalClose={onModalClose}
|
||||||
|
>
|
||||||
|
<ResetQualityDefinitionsModalContentConnector
|
||||||
|
{...otherProps}
|
||||||
|
onModalClose={onModalClose}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetQualityDefinitionsModal.propTypes = {
|
||||||
|
isOpen: PropTypes.bool.isRequired,
|
||||||
|
onModalClose: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ResetQualityDefinitionsModal;
|
|
@ -0,0 +1,3 @@
|
||||||
|
.messageContainer {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import FormGroup from 'Components/Form/FormGroup';
|
||||||
|
import FormInputGroup from 'Components/Form/FormInputGroup';
|
||||||
|
import FormLabel from 'Components/Form/FormLabel';
|
||||||
|
import Button from 'Components/Link/Button';
|
||||||
|
import ModalBody from 'Components/Modal/ModalBody';
|
||||||
|
import ModalContent from 'Components/Modal/ModalContent';
|
||||||
|
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||||
|
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||||
|
import { inputTypes, kinds } from 'Helpers/Props';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
|
import styles from './ResetQualityDefinitionsModalContent.css';
|
||||||
|
|
||||||
|
class ResetQualityDefinitionsModalContent extends Component {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Lifecycle
|
||||||
|
|
||||||
|
constructor(props, context) {
|
||||||
|
super(props, context);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
resetDefinitionTitles: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Listeners
|
||||||
|
|
||||||
|
onResetDefinitionTitlesChange = ({ value }) => {
|
||||||
|
this.setState({ resetDefinitionTitles: value });
|
||||||
|
};
|
||||||
|
|
||||||
|
onResetQualityDefinitionsConfirmed = () => {
|
||||||
|
const resetDefinitionTitles = this.state.resetDefinitionTitles;
|
||||||
|
|
||||||
|
this.setState({ resetDefinitionTitles: false });
|
||||||
|
this.props.onResetQualityDefinitions(resetDefinitionTitles);
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Render
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
onModalClose,
|
||||||
|
isResettingQualityDefinitions
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const resetDefinitionTitles = this.state.resetDefinitionTitles;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ModalContent
|
||||||
|
onModalClose={onModalClose}
|
||||||
|
>
|
||||||
|
<ModalHeader>
|
||||||
|
{translate('ResetQualityDefinitions')}
|
||||||
|
</ModalHeader>
|
||||||
|
|
||||||
|
<ModalBody>
|
||||||
|
<div className={styles.messageContainer}>
|
||||||
|
{translate('AreYouSureYouWantToResetQualityDefinitions')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('ResetTitles')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.CHECK}
|
||||||
|
name="resetDefinitionTitles"
|
||||||
|
value={resetDefinitionTitles}
|
||||||
|
helpText={translate('ResetTitlesHelpText')}
|
||||||
|
onChange={this.onResetDefinitionTitlesChange}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
</ModalBody>
|
||||||
|
|
||||||
|
<ModalFooter>
|
||||||
|
<Button onPress={onModalClose}>
|
||||||
|
{translate('Cancel')}
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
kind={kinds.DANGER}
|
||||||
|
onPress={this.onResetQualityDefinitionsConfirmed}
|
||||||
|
isDisabled={isResettingQualityDefinitions}
|
||||||
|
>
|
||||||
|
{translate('Reset')}
|
||||||
|
</Button>
|
||||||
|
</ModalFooter>
|
||||||
|
</ModalContent>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetQualityDefinitionsModalContent.propTypes = {
|
||||||
|
onResetQualityDefinitions: PropTypes.func.isRequired,
|
||||||
|
isResettingQualityDefinitions: PropTypes.bool.isRequired,
|
||||||
|
onModalClose: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ResetQualityDefinitionsModalContent;
|
|
@ -0,0 +1,54 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { createSelector } from 'reselect';
|
||||||
|
import * as commandNames from 'Commands/commandNames';
|
||||||
|
import { executeCommand } from 'Store/Actions/commandActions';
|
||||||
|
import createCommandExecutingSelector from 'Store/Selectors/createCommandExecutingSelector';
|
||||||
|
import ResetQualityDefinitionsModalContent from './ResetQualityDefinitionsModalContent';
|
||||||
|
|
||||||
|
function createMapStateToProps() {
|
||||||
|
return createSelector(
|
||||||
|
createCommandExecutingSelector(commandNames.RESET_QUALITY_DEFINITIONS),
|
||||||
|
(isResettingQualityDefinitions) => {
|
||||||
|
return {
|
||||||
|
isResettingQualityDefinitions
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapDispatchToProps = {
|
||||||
|
executeCommand
|
||||||
|
};
|
||||||
|
|
||||||
|
class ResetQualityDefinitionsModalContentConnector extends Component {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Listeners
|
||||||
|
|
||||||
|
onResetQualityDefinitions = (resetTitles) => {
|
||||||
|
this.props.executeCommand({ name: commandNames.RESET_QUALITY_DEFINITIONS, resetTitles });
|
||||||
|
this.props.onModalClose(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Render
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<ResetQualityDefinitionsModalContent
|
||||||
|
{...this.props}
|
||||||
|
onResetQualityDefinitions={this.onResetQualityDefinitions}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetQualityDefinitionsModalContentConnector.propTypes = {
|
||||||
|
onModalClose: PropTypes.func.isRequired,
|
||||||
|
isResettingQualityDefinitions: PropTypes.bool.isRequired,
|
||||||
|
executeCommand: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(createMapStateToProps, mapDispatchToProps)(ResetQualityDefinitionsModalContentConnector);
|
|
@ -66,6 +66,7 @@
|
||||||
"AreYouSureYouWantToRemoveSelectedItemFromQueue": "Are you sure you want to remove 1 item from the queue?",
|
"AreYouSureYouWantToRemoveSelectedItemFromQueue": "Are you sure you want to remove 1 item from the queue?",
|
||||||
"AreYouSureYouWantToRemoveSelectedItemsFromQueue": "Are you sure you want to remove {0} items from the queue?",
|
"AreYouSureYouWantToRemoveSelectedItemsFromQueue": "Are you sure you want to remove {0} items from the queue?",
|
||||||
"AreYouSureYouWantToRemoveTheSelectedItemsFromBlocklist": "Are you sure you want to remove the selected items from the blocklist?",
|
"AreYouSureYouWantToRemoveTheSelectedItemsFromBlocklist": "Are you sure you want to remove the selected items from the blocklist?",
|
||||||
|
"AreYouSureYouWantToResetQualityDefinitions": "Are you sure you want to reset quality definitions?",
|
||||||
"AreYouSureYouWantToResetYourAPIKey": "Are you sure you want to reset your API Key?",
|
"AreYouSureYouWantToResetYourAPIKey": "Are you sure you want to reset your API Key?",
|
||||||
"AsAllDayHelpText": "Events will appear as all-day events in your calendar",
|
"AsAllDayHelpText": "Events will appear as all-day events in your calendar",
|
||||||
"AudioInfo": "Audio Info",
|
"AudioInfo": "Audio Info",
|
||||||
|
@ -846,6 +847,10 @@
|
||||||
"RescanMovieFolderAfterRefresh": "Rescan Movie Folder after Refresh",
|
"RescanMovieFolderAfterRefresh": "Rescan Movie Folder after Refresh",
|
||||||
"Reset": "Reset",
|
"Reset": "Reset",
|
||||||
"ResetAPIKey": "Reset API Key",
|
"ResetAPIKey": "Reset API Key",
|
||||||
|
"ResetDefinitions": "Reset Definitions",
|
||||||
|
"ResetQualityDefinitions": "Reset Quality Definitions",
|
||||||
|
"ResetTitles": "Reset Titles",
|
||||||
|
"ResetTitlesHelpText": "Reset definition titles as well as values",
|
||||||
"Restart": "Restart",
|
"Restart": "Restart",
|
||||||
"RestartNow": "Restart Now",
|
"RestartNow": "Restart Now",
|
||||||
"RestartRadarr": "Restart Radarr",
|
"RestartRadarr": "Restart Radarr",
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Qualities.Commands
|
||||||
|
{
|
||||||
|
public class ResetQualityDefinitionsCommand : Command
|
||||||
|
{
|
||||||
|
public bool ResetTitles { get; set; }
|
||||||
|
|
||||||
|
public ResetQualityDefinitionsCommand(bool resetTitles = false)
|
||||||
|
{
|
||||||
|
ResetTitles = resetTitles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Cache;
|
using NzbDrone.Common.Cache;
|
||||||
using NzbDrone.Core.Lifecycle;
|
using NzbDrone.Core.Lifecycle;
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.Qualities.Commands;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Qualities
|
namespace NzbDrone.Core.Qualities
|
||||||
{
|
{
|
||||||
|
@ -17,7 +19,7 @@ namespace NzbDrone.Core.Qualities
|
||||||
QualityDefinition Get(Quality quality);
|
QualityDefinition Get(Quality quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class QualityDefinitionService : IQualityDefinitionService, IHandle<ApplicationStartedEvent>
|
public class QualityDefinitionService : IQualityDefinitionService, IExecute<ResetQualityDefinitionsCommand>, IHandle<ApplicationStartedEvent>
|
||||||
{
|
{
|
||||||
private readonly IQualityDefinitionRepository _repo;
|
private readonly IQualityDefinitionRepository _repo;
|
||||||
private readonly ICached<Dictionary<Quality, QualityDefinition>> _cache;
|
private readonly ICached<Dictionary<Quality, QualityDefinition>> _cache;
|
||||||
|
@ -105,5 +107,28 @@ namespace NzbDrone.Core.Qualities
|
||||||
|
|
||||||
InsertMissingDefinitions();
|
InsertMissingDefinitions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Execute(ResetQualityDefinitionsCommand message)
|
||||||
|
{
|
||||||
|
List<QualityDefinition> updateList = new List<QualityDefinition>();
|
||||||
|
|
||||||
|
var allDefinitions = Quality.DefaultQualityDefinitions.OrderBy(d => d.Weight).ToList();
|
||||||
|
var existingDefinitions = _repo.All().ToList();
|
||||||
|
|
||||||
|
foreach (var definition in allDefinitions)
|
||||||
|
{
|
||||||
|
var existing = existingDefinitions.SingleOrDefault(d => d.Quality == definition.Quality);
|
||||||
|
|
||||||
|
existing.MinSize = definition.MinSize;
|
||||||
|
existing.MaxSize = definition.MaxSize;
|
||||||
|
existing.Title = message.ResetTitles ? definition.Title : existing.Title;
|
||||||
|
|
||||||
|
updateList.Add(existing);
|
||||||
|
}
|
||||||
|
|
||||||
|
_repo.UpdateMany(updateList);
|
||||||
|
|
||||||
|
_cache.Clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using NzbDrone.Core.Datastore.Events;
|
||||||
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
|
using NzbDrone.SignalR;
|
||||||
using Radarr.Http;
|
using Radarr.Http;
|
||||||
using Radarr.Http.REST;
|
using Radarr.Http.REST;
|
||||||
using Radarr.Http.REST.Attributes;
|
using Radarr.Http.REST.Attributes;
|
||||||
|
@ -9,11 +12,12 @@ using Radarr.Http.REST.Attributes;
|
||||||
namespace Radarr.Api.V3.Qualities
|
namespace Radarr.Api.V3.Qualities
|
||||||
{
|
{
|
||||||
[V3ApiController]
|
[V3ApiController]
|
||||||
public class QualityDefinitionController : RestController<QualityDefinitionResource>
|
public class QualityDefinitionController : RestControllerWithSignalR<QualityDefinitionResource, QualityDefinition>, IHandle<CommandExecutedEvent>
|
||||||
{
|
{
|
||||||
private readonly IQualityDefinitionService _qualityDefinitionService;
|
private readonly IQualityDefinitionService _qualityDefinitionService;
|
||||||
|
|
||||||
public QualityDefinitionController(IQualityDefinitionService qualityDefinitionService)
|
public QualityDefinitionController(IQualityDefinitionService qualityDefinitionService, IBroadcastSignalRMessage signalRBroadcaster)
|
||||||
|
: base(signalRBroadcaster)
|
||||||
{
|
{
|
||||||
_qualityDefinitionService = qualityDefinitionService;
|
_qualityDefinitionService = qualityDefinitionService;
|
||||||
}
|
}
|
||||||
|
@ -40,7 +44,7 @@ namespace Radarr.Api.V3.Qualities
|
||||||
[HttpPut("update")]
|
[HttpPut("update")]
|
||||||
public object UpdateMany([FromBody] List<QualityDefinitionResource> resource)
|
public object UpdateMany([FromBody] List<QualityDefinitionResource> resource)
|
||||||
{
|
{
|
||||||
//Read from request
|
// Read from request
|
||||||
var qualityDefinitions = resource
|
var qualityDefinitions = resource
|
||||||
.ToModel()
|
.ToModel()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
@ -50,5 +54,14 @@ namespace Radarr.Api.V3.Qualities
|
||||||
return Accepted(_qualityDefinitionService.All()
|
return Accepted(_qualityDefinitionService.All()
|
||||||
.ToResource());
|
.ToResource());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[NonAction]
|
||||||
|
public void Handle(CommandExecutedEvent message)
|
||||||
|
{
|
||||||
|
if (message.Command.Name == "ResetQualityDefinitions")
|
||||||
|
{
|
||||||
|
BroadcastResourceChange(ModelAction.Sync);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue