Remove from queue improvements

New: option to blacklist a release when removing it from download client
pull/4/head
Mark McDowall 10 years ago
parent 5d41ebd322
commit 3c641cab33

@ -1,4 +1,5 @@
using Nancy;
using System;
using Nancy;
using Nancy.Responses;
using NzbDrone.Api.Extensions;
using NzbDrone.Api.REST;
@ -14,6 +15,7 @@ namespace NzbDrone.Api.Queue
private readonly IQueueService _queueService;
private readonly ITrackedDownloadService _trackedDownloadService;
private readonly ICompletedDownloadService _completedDownloadService;
private readonly IFailedDownloadService _failedDownloadService;
private readonly IProvideDownloadClient _downloadClientProvider;
private readonly IPendingReleaseService _pendingReleaseService;
private readonly IDownloadService _downloadService;
@ -21,6 +23,7 @@ namespace NzbDrone.Api.Queue
public QueueActionModule(IQueueService queueService,
ITrackedDownloadService trackedDownloadService,
ICompletedDownloadService completedDownloadService,
IFailedDownloadService failedDownloadService,
IProvideDownloadClient downloadClientProvider,
IPendingReleaseService pendingReleaseService,
IDownloadService downloadService)
@ -28,6 +31,7 @@ namespace NzbDrone.Api.Queue
_queueService = queueService;
_trackedDownloadService = trackedDownloadService;
_completedDownloadService = completedDownloadService;
_failedDownloadService = failedDownloadService;
_downloadClientProvider = downloadClientProvider;
_pendingReleaseService = pendingReleaseService;
_downloadService = downloadService;
@ -39,6 +43,14 @@ namespace NzbDrone.Api.Queue
private Response Remove(int id)
{
var blacklist = false;
var blacklistQuery = Request.Query.blacklist;
if (blacklistQuery.HasValue)
{
blacklist = Convert.ToBoolean(blacklistQuery.Value);
}
var pendingRelease = _pendingReleaseService.FindPendingQueueItem(id);
if (pendingRelease != null)
@ -64,6 +76,11 @@ namespace NzbDrone.Api.Queue
downloadClient.RemoveItem(trackedDownload.DownloadItem.DownloadId, true);
if (blacklist)
{
_failedDownloadService.MarkAsFailed(trackedDownload.DownloadItem.DownloadId);
}
return new object().AsResponse();
}

@ -10,6 +10,7 @@ namespace NzbDrone.Core.Download
public interface IFailedDownloadService
{
void MarkAsFailed(int historyId);
void MarkAsFailed(string downloadId);
void Process(TrackedDownload trackedDownload);
}
@ -41,6 +42,16 @@ namespace NzbDrone.Core.Download
}
}
public void MarkAsFailed(string downloadId)
{
var history = _historyService.Find(downloadId, HistoryEventType.Grabbed);
if (history.Any())
{
PublishDownloadFailedEvent(history, "Manually marked as failed");
}
}
public void Process(TrackedDownload trackedDownload)
{
var grabbedItems = _historyService.Find(trackedDownload.DownloadItem.DownloadId, HistoryEventType.Grabbed)

@ -4,10 +4,13 @@ define(
[
'jquery',
'marionette',
'Cells/NzbDroneCell'
], function ($, Marionette, NzbDroneCell) {
return NzbDroneCell.extend({
'Cells/TemplatedCell',
'Activity/Queue/RemoveFromQueueView',
'vent'
], function ($, Marionette, TemplatedCell, RemoveFromQueueView, vent) {
return TemplatedCell.extend({
template : 'Activity/Queue/QueueActionsCellTemplate',
className : 'queue-actions-cell',
events: {
@ -21,48 +24,11 @@ define(
grab : '.x-grab'
},
render: function () {
this.$el.empty();
if (this.cellValue) {
var status = this.cellValue.get('status').toLowerCase();
var trackedDownloadStatus = this.cellValue.has('trackedDownloadStatus') ? this.cellValue.get('trackedDownloadStatus').toLowerCase() : 'ok';
var icon = '';
var title = '';
if (status === 'completed' && trackedDownloadStatus === 'warning') {
icon = 'icon-inbox x-import';
title = 'Force import';
}
if (status === 'pending') {
icon = 'icon-download-alt x-grab';
title = 'Add to download queue (Override Delay Profile)';
}
//TODO: Show manual import if its completed or option to blacklist
//if (trackedDownloadStatus === 'error') {
// if (status === 'completed') {
// icon = 'icon-nd-import-failed';
// title = 'Import failed: ' + itemTitle;
// }
//TODO: What do we show when waiting for retry to take place?
// else {
// icon = 'icon-nd-download-failed';
// title = 'Download failed';
// }
//}
this.$el.html('<i class="{0}" title="{1}"></i>'.format(icon, title) +
'<i class="icon-nd-delete x-remove" title="Remove from Download Client"></i>');
}
_remove : function () {
return this;
},
var showBlacklist = this.model.get('status') !== 'Pending';
_remove : function () {
this.model.destroy();
vent.trigger(vent.Commands.OpenModalCommand, new RemoveFromQueueView({ model: this.model, showBlacklist: showBlacklist }));
},
_import : function () {

@ -0,0 +1,12 @@
{{#if_eq status compare="Completed"}}
{{#if_eq trackedDownloadStatus compare="Warning"}}
<i class="icon-inbox x-import" title="Force import"></i>
{{/if_eq}}
{{/if_eq}}
{{#if_eq status compare="Pending"}}
<i class="icon-download-alt x-grab" title="Add to download queue (Override Delay Profile)"></i>
<i class="icon-nd-delete x-remove" title="Remove pending release"></i>
{{else}}
<i class="icon-nd-delete x-remove" title="Remove from download client"></i>
{{/if_eq}}

@ -0,0 +1,39 @@
'use strict';
define(
[
'vent',
'marionette'
], function (vent, Marionette) {
return Marionette.ItemView.extend({
template: 'Activity/Queue/RemoveFromQueueViewTemplate',
events: {
'click .x-confirm-remove' : 'removeItem'
},
ui: {
blacklist : '.x-blacklist',
indicator : '.x-indicator'
},
initialize: function (options) {
this.templateHelpers = {
showBlacklist: options.showBlacklist
};
},
removeItem: function () {
var blacklist = this.ui.blacklist.prop('checked');
this.ui.indicator.show();
this.model.destroy({
data: { 'blacklist': blacklist },
wait: true
}).done(function () {
vent.trigger(vent.Commands.CloseModalCommand);
});
}
});
});

@ -0,0 +1,49 @@
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h3>{{title}}</h3>
</div>
<div class="modal-body remove-from-queue-modal">
<div class="row">
<div class="col-sm-12">
Are you sure you want to remove '{{title}}'?
</div>
</div>
{{#if showBlacklist}}
<div class="row">
<div class="col-sm-12">
<div class="form-horizontal">
<div class="form-group">
<label class="col-sm-4 control-label">Blacklist release</label>
<div class="col-sm-8">
<div class="input-group">
<label class="checkbox toggle well">
<input type="checkbox" class="x-blacklist"/>
<p>
<span>Yes</span>
<span>No</span>
</p>
<div class="btn slide-button btn-danger"/>
</label>
<span class="help-inline-checkbox">
<i class="icon-nd-form-info" title="Do you want to blacklist this release?"/>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
{{/if}}
</div>
<div class="modal-footer">
<span class="indicator x-indicator"><i class="icon-spinner icon-spin"></i></span>
<button class="btn" data-dismiss="modal">cancel</button>
<button class="btn btn-danger x-confirm-remove">remove</button>
</div>
</div>

@ -9,3 +9,9 @@
width : 80px;
}
}
.remove-from-queue-modal {
.form-horizontal {
margin-top : 20px;
}
}

@ -156,12 +156,12 @@ td.episode-status-cell, td.quality-cell, td.history-quality-cell, td.progress-ce
}
.queue-actions-cell {
width : 55px;
width : 70px;
text-align : right !important;
i {
margin-left : 3px;
margin-right : 3px;
margin-left : 1px;
margin-right : 1px;
}
}

@ -60,6 +60,11 @@
color : @brand-danger;
}
.icon-nd-blacklist:before {
.icon(@ban-circle);
color : @brand-danger;
}
.icon-nd-spinner:before {
.icon(@spinner);
.icon-spin;

Loading…
Cancel
Save