mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-10-30 07:22:35 +01:00
Option to ignore items when removing from queue instead of removing from client
New: Option to not remove item from download client when removing from queue Closes #1710
This commit is contained in:
parent
3916495329
commit
c6ea7d7e63
@ -232,6 +232,30 @@ function HistoryDetails(props) {
|
||||
);
|
||||
}
|
||||
|
||||
if (eventType === 'downloadIgnored') {
|
||||
const {
|
||||
message
|
||||
} = data;
|
||||
|
||||
return (
|
||||
<DescriptionList>
|
||||
<DescriptionListItem
|
||||
descriptionClassName={styles.description}
|
||||
title="Name"
|
||||
data={sourceTitle}
|
||||
/>
|
||||
|
||||
{
|
||||
!!message &&
|
||||
<DescriptionListItem
|
||||
title="Message"
|
||||
data={message}
|
||||
/>
|
||||
}
|
||||
</DescriptionList>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<DescriptionList>
|
||||
<DescriptionListItem
|
||||
|
@ -23,6 +23,8 @@ function getHeaderTitle(eventType) {
|
||||
return 'Episode File Deleted';
|
||||
case 'episodeFileRenamed':
|
||||
return 'Episode File Renamed';
|
||||
case 'downloadIgnored':
|
||||
return 'Download Ignored';
|
||||
default:
|
||||
return 'Unknown';
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ function getIconName(eventType) {
|
||||
return icons.DELETE;
|
||||
case 'episodeFileRenamed':
|
||||
return icons.ORGANIZE;
|
||||
case 'downloadIgnored':
|
||||
return icons.IGNORE;
|
||||
default:
|
||||
return icons.UNKNOWN;
|
||||
}
|
||||
@ -47,6 +49,8 @@ function getTooltip(eventType, data) {
|
||||
return 'Episode file deleted';
|
||||
case 'episodeFileRenamed':
|
||||
return 'Episode file renamed';
|
||||
case 'downloadIgnored':
|
||||
return 'Episode Download Ignored';
|
||||
default:
|
||||
return 'Unknown event';
|
||||
}
|
||||
|
@ -107,8 +107,8 @@ class Queue extends Component {
|
||||
this.setState({ isConfirmRemoveModalOpen: true });
|
||||
}
|
||||
|
||||
onRemoveSelectedConfirmed = (blacklist) => {
|
||||
this.props.onRemoveSelectedPress(this.getSelectedIds(), blacklist);
|
||||
onRemoveSelectedConfirmed = (payload) => {
|
||||
this.props.onRemoveSelectedPress({ ids: this.getSelectedIds(), ...payload });
|
||||
this.setState({ isConfirmRemoveModalOpen: false });
|
||||
}
|
||||
|
||||
@ -148,7 +148,8 @@ class Queue extends Component {
|
||||
const isRefreshing = isFetching || isEpisodesFetching || isRefreshMonitoredDownloadsExecuting;
|
||||
const isAllPopulated = isPopulated && (isEpisodesPopulated || !items.length || items.every((e) => !e.episodeId));
|
||||
const hasError = error || episodesError;
|
||||
const selectedCount = this.getSelectedIds().length;
|
||||
const selectedIds = this.getSelectedIds();
|
||||
const selectedCount = selectedIds.length;
|
||||
const disableSelectedActions = selectedCount === 0;
|
||||
|
||||
return (
|
||||
@ -259,6 +260,13 @@ class Queue extends Component {
|
||||
<RemoveQueueItemsModal
|
||||
isOpen={isConfirmRemoveModalOpen}
|
||||
selectedCount={selectedCount}
|
||||
canIgnore={isConfirmRemoveModalOpen && (
|
||||
selectedIds.every((id) => {
|
||||
const item = items.find((i) => i.id === id);
|
||||
|
||||
return !!(item && item.seriesId && item.episodeId);
|
||||
})
|
||||
)}
|
||||
onRemovePress={this.onRemoveSelectedConfirmed}
|
||||
onModalClose={this.onConfirmRemoveModalClose}
|
||||
/>
|
||||
|
@ -137,8 +137,8 @@ class QueueConnector extends Component {
|
||||
this.props.grabQueueItems({ ids });
|
||||
}
|
||||
|
||||
onRemoveSelectedPress = (ids, blacklist) => {
|
||||
this.props.removeQueueItems({ ids, blacklist });
|
||||
onRemoveSelectedPress = (payload) => {
|
||||
this.props.removeQueueItems(payload);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -352,6 +352,7 @@ class QueueRow extends Component {
|
||||
<RemoveQueueItemModal
|
||||
isOpen={isRemoveQueueItemModalOpen}
|
||||
sourceTitle={title}
|
||||
canIgnore={!!(series && episode)}
|
||||
onRemovePress={this.onRemoveQueueItemModalConfirmed}
|
||||
onModalClose={this.onRemoveQueueItemModalClose}
|
||||
/>
|
||||
|
@ -43,8 +43,8 @@ class QueueRowConnector extends Component {
|
||||
this.props.grabQueueItem({ id: this.props.id });
|
||||
}
|
||||
|
||||
onRemoveQueueItemPress = (blacklist) => {
|
||||
this.props.removeQueueItem({ id: this.props.id, blacklist });
|
||||
onRemoveQueueItemPress = (payload) => {
|
||||
this.props.removeQueueItem({ id: this.props.id, ...payload });
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1,4 +0,0 @@
|
||||
.messageRemove {
|
||||
margin-bottom: 30px;
|
||||
color: $dangerColor;
|
||||
}
|
@ -10,7 +10,6 @@ import ModalContent from 'Components/Modal/ModalContent';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import ModalBody from 'Components/Modal/ModalBody';
|
||||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import styles from './RemoveQueueItemModal.css';
|
||||
|
||||
class RemoveQueueItemModal extends Component {
|
||||
|
||||
@ -21,26 +20,41 @@ class RemoveQueueItemModal extends Component {
|
||||
super(props, context);
|
||||
|
||||
this.state = {
|
||||
remove: true,
|
||||
blacklist: false
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// Control
|
||||
|
||||
resetState = function() {
|
||||
this.setState({
|
||||
remove: true,
|
||||
blacklist: false
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
||||
onRemoveChange = ({ value }) => {
|
||||
this.setState({ remove: value });
|
||||
}
|
||||
|
||||
onBlacklistChange = ({ value }) => {
|
||||
this.setState({ blacklist: value });
|
||||
}
|
||||
|
||||
onRemoveQueueItemConfirmed = () => {
|
||||
const blacklist = this.state.blacklist;
|
||||
onRemoveConfirmed = () => {
|
||||
const state = this.state;
|
||||
|
||||
this.setState({ blacklist: false });
|
||||
this.props.onRemovePress(blacklist);
|
||||
this.resetState();
|
||||
this.props.onRemovePress(state);
|
||||
}
|
||||
|
||||
onModalClose = () => {
|
||||
this.setState({ blacklist: false });
|
||||
this.resetState();
|
||||
this.props.onModalClose();
|
||||
}
|
||||
|
||||
@ -50,10 +64,11 @@ class RemoveQueueItemModal extends Component {
|
||||
render() {
|
||||
const {
|
||||
isOpen,
|
||||
sourceTitle
|
||||
sourceTitle,
|
||||
canIgnore
|
||||
} = this.props;
|
||||
|
||||
const blacklist = this.state.blacklist;
|
||||
const { remove, blacklist } = this.state;
|
||||
|
||||
return (
|
||||
<Modal
|
||||
@ -73,17 +88,27 @@ class RemoveQueueItemModal extends Component {
|
||||
Are you sure you want to remove '{sourceTitle}' from the queue?
|
||||
</div>
|
||||
|
||||
<div className={styles.messageRemove}>
|
||||
Removing will remove the download and the file(s) from the download client.
|
||||
</div>
|
||||
<FormGroup>
|
||||
<FormLabel>Remove From Download Client</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="remove"
|
||||
value={remove}
|
||||
helpTextWarning="Removing will remove the download and the file(s) from the download client."
|
||||
isDisabled={!canIgnore}
|
||||
onChange={this.onRemoveChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Blacklist Release</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="blacklist"
|
||||
value={blacklist}
|
||||
helpText="Prevents Sonarr from automatically grabbing this release again"
|
||||
helpText="Starts a search for this episode again and prevents this release from being grabbed again"
|
||||
onChange={this.onBlacklistChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
@ -97,7 +122,7 @@ class RemoveQueueItemModal extends Component {
|
||||
|
||||
<Button
|
||||
kind={kinds.DANGER}
|
||||
onPress={this.onRemoveQueueItemConfirmed}
|
||||
onPress={this.onRemoveConfirmed}
|
||||
>
|
||||
Remove
|
||||
</Button>
|
||||
@ -111,6 +136,7 @@ class RemoveQueueItemModal extends Component {
|
||||
RemoveQueueItemModal.propTypes = {
|
||||
isOpen: PropTypes.bool.isRequired,
|
||||
sourceTitle: PropTypes.string.isRequired,
|
||||
canIgnore: PropTypes.bool.isRequired,
|
||||
onRemovePress: PropTypes.func.isRequired,
|
||||
onModalClose: PropTypes.func.isRequired
|
||||
};
|
||||
|
@ -21,26 +21,41 @@ class RemoveQueueItemsModal extends Component {
|
||||
super(props, context);
|
||||
|
||||
this.state = {
|
||||
remove: true,
|
||||
blacklist: false
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// Listeners
|
||||
// Control
|
||||
|
||||
resetState = function() {
|
||||
this.setState({
|
||||
remove: true,
|
||||
blacklist: false
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
||||
onRemoveChange = ({ value }) => {
|
||||
this.setState({ remove: value });
|
||||
}
|
||||
|
||||
onBlacklistChange = ({ value }) => {
|
||||
this.setState({ blacklist: value });
|
||||
}
|
||||
|
||||
onRemoveQueueItemConfirmed = () => {
|
||||
const blacklist = this.state.blacklist;
|
||||
onRemoveConfirmed = () => {
|
||||
const state = this.state;
|
||||
|
||||
this.setState({ blacklist: false });
|
||||
this.props.onRemovePress(blacklist);
|
||||
this.resetState();
|
||||
this.props.onRemovePress(state);
|
||||
}
|
||||
|
||||
onModalClose = () => {
|
||||
this.setState({ blacklist: false });
|
||||
this.resetState();
|
||||
this.props.onModalClose();
|
||||
}
|
||||
|
||||
@ -50,10 +65,11 @@ class RemoveQueueItemsModal extends Component {
|
||||
render() {
|
||||
const {
|
||||
isOpen,
|
||||
selectedCount
|
||||
selectedCount,
|
||||
canIgnore
|
||||
} = this.props;
|
||||
|
||||
const blacklist = this.state.blacklist;
|
||||
const { remove, blacklist } = this.state;
|
||||
|
||||
return (
|
||||
<Modal
|
||||
@ -74,7 +90,23 @@ class RemoveQueueItemsModal extends Component {
|
||||
</div>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Blacklist Release</FormLabel>
|
||||
<FormLabel>Remove From Download Client</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="remove"
|
||||
value={remove}
|
||||
helpTextWarning="Removing will remove the download and the file(s) from the download client."
|
||||
isDisabled={!canIgnore}
|
||||
onChange={this.onRemoveChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>
|
||||
Blacklist Release{selectedCount > 1 ? 's' : ''}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="blacklist"
|
||||
@ -93,7 +125,7 @@ class RemoveQueueItemsModal extends Component {
|
||||
|
||||
<Button
|
||||
kind={kinds.DANGER}
|
||||
onPress={this.onRemoveQueueItemConfirmed}
|
||||
onPress={this.onRemoveConfirmed}
|
||||
>
|
||||
Remove
|
||||
</Button>
|
||||
@ -107,6 +139,7 @@ class RemoveQueueItemsModal extends Component {
|
||||
RemoveQueueItemsModal.propTypes = {
|
||||
isOpen: PropTypes.bool.isRequired,
|
||||
selectedCount: PropTypes.number.isRequired,
|
||||
canIgnore: PropTypes.bool.isRequired,
|
||||
onRemovePress: PropTypes.func.isRequired,
|
||||
onModalClose: PropTypes.func.isRequired
|
||||
};
|
||||
|
@ -145,6 +145,7 @@ export const HEALTH = fasMedkit;
|
||||
export const HEART = fasHeart;
|
||||
export const HISTORY = fasHistory;
|
||||
export const HOUSEKEEPING = fasHome;
|
||||
export const IGNORE = fasTimesCircle;
|
||||
export const INFO = fasInfoCircle;
|
||||
export const INTERACTIVE = fasUser;
|
||||
export const KEYBOARD = farKeyboard;
|
||||
|
@ -150,6 +150,17 @@ export const defaultState = {
|
||||
type: filterTypes.EQUAL
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: 'ignored',
|
||||
label: 'Ignored',
|
||||
filters: [
|
||||
{
|
||||
key: 'eventType',
|
||||
value: '7',
|
||||
type: filterTypes.EQUAL
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -356,13 +356,14 @@ export const actionHandlers = handleThunks({
|
||||
[REMOVE_QUEUE_ITEM]: function(getState, payload, dispatch) {
|
||||
const {
|
||||
id,
|
||||
remove,
|
||||
blacklist
|
||||
} = payload;
|
||||
|
||||
dispatch(updateItem({ section: paged, id, isRemoving: true }));
|
||||
|
||||
const promise = createAjaxRequest({
|
||||
url: `/queue/${id}?blacklist=${blacklist}`,
|
||||
url: `/queue/${id}?removeFromClient=${remove}&blacklist=${blacklist}`,
|
||||
method: 'DELETE'
|
||||
}).request;
|
||||
|
||||
@ -378,6 +379,7 @@ export const actionHandlers = handleThunks({
|
||||
[REMOVE_QUEUE_ITEMS]: function(getState, payload, dispatch) {
|
||||
const {
|
||||
ids,
|
||||
remove,
|
||||
blacklist
|
||||
} = payload;
|
||||
|
||||
@ -394,7 +396,7 @@ export const actionHandlers = handleThunks({
|
||||
]));
|
||||
|
||||
const promise = createAjaxRequest({
|
||||
url: `/queue/bulk?blacklist=${blacklist}`,
|
||||
url: `/queue/bulk?removeFromClient=${remove}&blacklist=${blacklist}`,
|
||||
method: 'DELETE',
|
||||
dataType: 'json',
|
||||
data: JSON.stringify({ ids })
|
||||
|
19
src/NzbDrone.Core/Download/DownloadIgnoredEvent.cs
Normal file
19
src/NzbDrone.Core/Download/DownloadIgnoredEvent.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Common.Messaging;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Languages;
|
||||
|
||||
namespace NzbDrone.Core.Download
|
||||
{
|
||||
public class DownloadIgnoredEvent : IEvent
|
||||
{
|
||||
public int SeriesId { get; set; }
|
||||
public List<int> EpisodeIds { get; set; }
|
||||
public Language Language { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
public string SourceTitle { get; set; }
|
||||
public string DownloadClient { get; set; }
|
||||
public string DownloadId { get; set; }
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
53
src/NzbDrone.Core/Download/IgnoredDownloadService.cs
Normal file
53
src/NzbDrone.Core/Download/IgnoredDownloadService.cs
Normal file
@ -0,0 +1,53 @@
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Download.TrackedDownloads;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
|
||||
namespace NzbDrone.Core.Download
|
||||
{
|
||||
public interface IIgnoredDownloadService
|
||||
{
|
||||
bool IgnoreDownload(TrackedDownload trackedDownload);
|
||||
}
|
||||
|
||||
public class IgnoredDownloadService : IIgnoredDownloadService
|
||||
{
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public IgnoredDownloadService(IEventAggregator eventAggregator,
|
||||
Logger logger)
|
||||
{
|
||||
_eventAggregator = eventAggregator;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public bool IgnoreDownload(TrackedDownload trackedDownload)
|
||||
{
|
||||
var series = trackedDownload.RemoteEpisode.Series;
|
||||
var episodes = trackedDownload.RemoteEpisode.Episodes;
|
||||
|
||||
if (series == null || episodes.Empty())
|
||||
{
|
||||
_logger.Warn("Unable to ignore download for unknown series/episode");
|
||||
return false;
|
||||
}
|
||||
|
||||
var downloadIgnoredEvent = new DownloadIgnoredEvent
|
||||
{
|
||||
SeriesId = series.Id,
|
||||
EpisodeIds = episodes.Select(e => e.Id).ToList(),
|
||||
Language = trackedDownload.RemoteEpisode.ParsedEpisodeInfo.Language,
|
||||
Quality = trackedDownload.RemoteEpisode.ParsedEpisodeInfo.Quality,
|
||||
SourceTitle = trackedDownload.DownloadItem.Title,
|
||||
DownloadClient = trackedDownload.DownloadItem.DownloadClient,
|
||||
DownloadId = trackedDownload.DownloadItem.DownloadId,
|
||||
Message = "Manually ignored"
|
||||
};
|
||||
|
||||
_eventAggregator.PublishEvent(downloadIgnoredEvent);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -133,8 +133,10 @@ namespace NzbDrone.Core.Download.TrackedDownloads
|
||||
|
||||
private bool DownloadIsTrackable(TrackedDownload trackedDownload)
|
||||
{
|
||||
// If the download has already been imported or failed don't track it
|
||||
if (trackedDownload.State == TrackedDownloadState.Imported || trackedDownload.State == TrackedDownloadState.Failed)
|
||||
// If the download has already been imported, failed or the user ignored it don't track it
|
||||
if (trackedDownload.State == TrackedDownloadState.Imported ||
|
||||
trackedDownload.State == TrackedDownloadState.Failed ||
|
||||
trackedDownload.State == TrackedDownloadState.Ignored)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -40,7 +40,8 @@ namespace NzbDrone.Core.Download.TrackedDownloads
|
||||
Importing,
|
||||
Imported,
|
||||
FailedPending,
|
||||
Failed
|
||||
Failed,
|
||||
Ignored
|
||||
}
|
||||
|
||||
public enum TrackedDownloadStatus
|
||||
|
@ -201,6 +201,8 @@ namespace NzbDrone.Core.Download.TrackedDownloads
|
||||
return TrackedDownloadState.Imported;
|
||||
case HistoryEventType.DownloadFailed:
|
||||
return TrackedDownloadState.Failed;
|
||||
case HistoryEventType.DownloadIgnored:
|
||||
return TrackedDownloadState.Ignored;
|
||||
default:
|
||||
return TrackedDownloadState.Downloading;
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ namespace NzbDrone.Core.History
|
||||
DownloadFolderImported = 3,
|
||||
DownloadFailed = 4,
|
||||
EpisodeFileDeleted = 5,
|
||||
EpisodeFileRenamed = 6
|
||||
EpisodeFileRenamed = 6,
|
||||
DownloadIgnored = 7
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Marr.Data.QGen;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Datastore;
|
||||
@ -11,11 +10,7 @@ using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.MediaFiles.Events;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Tv.Events;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Profiles.Qualities;
|
||||
using NzbDrone.Core.Profiles.Languages;
|
||||
|
||||
namespace NzbDrone.Core.History
|
||||
{
|
||||
@ -39,7 +34,8 @@ namespace NzbDrone.Core.History
|
||||
IHandle<DownloadFailedEvent>,
|
||||
IHandle<EpisodeFileDeletedEvent>,
|
||||
IHandle<EpisodeFileRenamedEvent>,
|
||||
IHandle<SeriesDeletedEvent>
|
||||
IHandle<SeriesDeletedEvent>,
|
||||
IHandle<DownloadIgnoredEvent>
|
||||
{
|
||||
private readonly IHistoryRepository _historyRepository;
|
||||
private readonly Logger _logger;
|
||||
@ -307,6 +303,33 @@ namespace NzbDrone.Core.History
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(DownloadIgnoredEvent message)
|
||||
{
|
||||
var historyToAdd = new List<History>();
|
||||
|
||||
foreach (var episodeId in message.EpisodeIds)
|
||||
{
|
||||
var history = new History
|
||||
{
|
||||
EventType = HistoryEventType.DownloadIgnored,
|
||||
Date = DateTime.UtcNow,
|
||||
Quality = message.Quality,
|
||||
SourceTitle = message.SourceTitle,
|
||||
SeriesId = message.SeriesId,
|
||||
EpisodeId = episodeId,
|
||||
DownloadId = message.DownloadId,
|
||||
Language = message.Language
|
||||
};
|
||||
|
||||
history.Data.Add("DownloadClient", message.DownloadClient);
|
||||
history.Data.Add("Message", message.Message);
|
||||
|
||||
historyToAdd.Add(history);
|
||||
}
|
||||
|
||||
_historyRepository.InsertMany(historyToAdd);
|
||||
}
|
||||
|
||||
public void Handle(SeriesDeletedEvent message)
|
||||
{
|
||||
_historyRepository.DeleteForSeries(message.Series.Id);
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Nancy;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Download.Pending;
|
||||
@ -16,6 +17,7 @@ namespace Sonarr.Api.V3.Queue
|
||||
private readonly IQueueService _queueService;
|
||||
private readonly ITrackedDownloadService _trackedDownloadService;
|
||||
private readonly IFailedDownloadService _failedDownloadService;
|
||||
private readonly IIgnoredDownloadService _ignoredDownloadService;
|
||||
private readonly IProvideDownloadClient _downloadClientProvider;
|
||||
private readonly IPendingReleaseService _pendingReleaseService;
|
||||
private readonly IDownloadService _downloadService;
|
||||
@ -23,6 +25,7 @@ namespace Sonarr.Api.V3.Queue
|
||||
public QueueActionModule(IQueueService queueService,
|
||||
ITrackedDownloadService trackedDownloadService,
|
||||
IFailedDownloadService failedDownloadService,
|
||||
IIgnoredDownloadService ignoredDownloadService,
|
||||
IProvideDownloadClient downloadClientProvider,
|
||||
IPendingReleaseService pendingReleaseService,
|
||||
IDownloadService downloadService)
|
||||
@ -30,6 +33,7 @@ namespace Sonarr.Api.V3.Queue
|
||||
_queueService = queueService;
|
||||
_trackedDownloadService = trackedDownloadService;
|
||||
_failedDownloadService = failedDownloadService;
|
||||
_ignoredDownloadService = ignoredDownloadService;
|
||||
_downloadClientProvider = downloadClientProvider;
|
||||
_pendingReleaseService = pendingReleaseService;
|
||||
_downloadService = downloadService;
|
||||
@ -76,9 +80,10 @@ namespace Sonarr.Api.V3.Queue
|
||||
|
||||
private object Remove(int id)
|
||||
{
|
||||
var removeFromClient = Request.GetBooleanQueryParameter("removeFromClient", true);
|
||||
var blacklist = Request.GetBooleanQueryParameter("blacklist");
|
||||
|
||||
var trackedDownload = Remove(id, blacklist);
|
||||
var trackedDownload = Remove(id, removeFromClient, blacklist);
|
||||
|
||||
if (trackedDownload != null)
|
||||
{
|
||||
@ -90,6 +95,7 @@ namespace Sonarr.Api.V3.Queue
|
||||
|
||||
private object Remove()
|
||||
{
|
||||
var removeFromClient = Request.GetBooleanQueryParameter("removeFromClient", true);
|
||||
var blacklist = Request.GetBooleanQueryParameter("blacklist");
|
||||
|
||||
var resource = Request.Body.FromJson<QueueBulkResource>();
|
||||
@ -97,7 +103,7 @@ namespace Sonarr.Api.V3.Queue
|
||||
|
||||
foreach (var id in resource.Ids)
|
||||
{
|
||||
var trackedDownload = Remove(id, blacklist);
|
||||
var trackedDownload = Remove(id, removeFromClient, blacklist);
|
||||
|
||||
if (trackedDownload != null)
|
||||
{
|
||||
@ -110,7 +116,7 @@ namespace Sonarr.Api.V3.Queue
|
||||
return new object();
|
||||
}
|
||||
|
||||
private TrackedDownload Remove(int id, bool blacklist)
|
||||
private TrackedDownload Remove(int id, bool removeFromClient, bool blacklist)
|
||||
{
|
||||
var pendingRelease = _pendingReleaseService.FindPendingQueueItem(id);
|
||||
|
||||
@ -128,19 +134,30 @@ namespace Sonarr.Api.V3.Queue
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
var downloadClient = _downloadClientProvider.Get(trackedDownload.DownloadClient);
|
||||
|
||||
if (downloadClient == null)
|
||||
if (removeFromClient)
|
||||
{
|
||||
throw new BadRequestException();
|
||||
}
|
||||
var downloadClient = _downloadClientProvider.Get(trackedDownload.DownloadClient);
|
||||
|
||||
downloadClient.RemoveItem(trackedDownload.DownloadItem.DownloadId, true);
|
||||
if (downloadClient == null)
|
||||
{
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
downloadClient.RemoveItem(trackedDownload.DownloadItem.DownloadId, true);
|
||||
}
|
||||
|
||||
if (blacklist)
|
||||
{
|
||||
_failedDownloadService.MarkAsFailed(trackedDownload.DownloadItem.DownloadId);
|
||||
}
|
||||
|
||||
if (!removeFromClient && !blacklist)
|
||||
{
|
||||
if (!_ignoredDownloadService.IgnoreDownload(trackedDownload))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return trackedDownload;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user