mirror of
https://github.com/lidarr/Lidarr
synced 2025-03-13 07:23:14 +00:00
Remove from queue improvements
New: option to blacklist a release when removing it from download client
This commit is contained in:
parent
5d41ebd322
commit
3c641cab33
9 changed files with 153 additions and 48 deletions
|
@ -1,4 +1,5 @@
|
||||||
using Nancy;
|
using System;
|
||||||
|
using Nancy;
|
||||||
using Nancy.Responses;
|
using Nancy.Responses;
|
||||||
using NzbDrone.Api.Extensions;
|
using NzbDrone.Api.Extensions;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
|
@ -14,6 +15,7 @@ namespace NzbDrone.Api.Queue
|
||||||
private readonly IQueueService _queueService;
|
private readonly IQueueService _queueService;
|
||||||
private readonly ITrackedDownloadService _trackedDownloadService;
|
private readonly ITrackedDownloadService _trackedDownloadService;
|
||||||
private readonly ICompletedDownloadService _completedDownloadService;
|
private readonly ICompletedDownloadService _completedDownloadService;
|
||||||
|
private readonly IFailedDownloadService _failedDownloadService;
|
||||||
private readonly IProvideDownloadClient _downloadClientProvider;
|
private readonly IProvideDownloadClient _downloadClientProvider;
|
||||||
private readonly IPendingReleaseService _pendingReleaseService;
|
private readonly IPendingReleaseService _pendingReleaseService;
|
||||||
private readonly IDownloadService _downloadService;
|
private readonly IDownloadService _downloadService;
|
||||||
|
@ -21,6 +23,7 @@ namespace NzbDrone.Api.Queue
|
||||||
public QueueActionModule(IQueueService queueService,
|
public QueueActionModule(IQueueService queueService,
|
||||||
ITrackedDownloadService trackedDownloadService,
|
ITrackedDownloadService trackedDownloadService,
|
||||||
ICompletedDownloadService completedDownloadService,
|
ICompletedDownloadService completedDownloadService,
|
||||||
|
IFailedDownloadService failedDownloadService,
|
||||||
IProvideDownloadClient downloadClientProvider,
|
IProvideDownloadClient downloadClientProvider,
|
||||||
IPendingReleaseService pendingReleaseService,
|
IPendingReleaseService pendingReleaseService,
|
||||||
IDownloadService downloadService)
|
IDownloadService downloadService)
|
||||||
|
@ -28,6 +31,7 @@ namespace NzbDrone.Api.Queue
|
||||||
_queueService = queueService;
|
_queueService = queueService;
|
||||||
_trackedDownloadService = trackedDownloadService;
|
_trackedDownloadService = trackedDownloadService;
|
||||||
_completedDownloadService = completedDownloadService;
|
_completedDownloadService = completedDownloadService;
|
||||||
|
_failedDownloadService = failedDownloadService;
|
||||||
_downloadClientProvider = downloadClientProvider;
|
_downloadClientProvider = downloadClientProvider;
|
||||||
_pendingReleaseService = pendingReleaseService;
|
_pendingReleaseService = pendingReleaseService;
|
||||||
_downloadService = downloadService;
|
_downloadService = downloadService;
|
||||||
|
@ -39,6 +43,14 @@ namespace NzbDrone.Api.Queue
|
||||||
|
|
||||||
private Response Remove(int id)
|
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);
|
var pendingRelease = _pendingReleaseService.FindPendingQueueItem(id);
|
||||||
|
|
||||||
if (pendingRelease != null)
|
if (pendingRelease != null)
|
||||||
|
@ -64,6 +76,11 @@ namespace NzbDrone.Api.Queue
|
||||||
|
|
||||||
downloadClient.RemoveItem(trackedDownload.DownloadItem.DownloadId, true);
|
downloadClient.RemoveItem(trackedDownload.DownloadItem.DownloadId, true);
|
||||||
|
|
||||||
|
if (blacklist)
|
||||||
|
{
|
||||||
|
_failedDownloadService.MarkAsFailed(trackedDownload.DownloadItem.DownloadId);
|
||||||
|
}
|
||||||
|
|
||||||
return new object().AsResponse();
|
return new object().AsResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace NzbDrone.Core.Download
|
||||||
public interface IFailedDownloadService
|
public interface IFailedDownloadService
|
||||||
{
|
{
|
||||||
void MarkAsFailed(int historyId);
|
void MarkAsFailed(int historyId);
|
||||||
|
void MarkAsFailed(string downloadId);
|
||||||
void Process(TrackedDownload trackedDownload);
|
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)
|
public void Process(TrackedDownload trackedDownload)
|
||||||
{
|
{
|
||||||
var grabbedItems = _historyService.Find(trackedDownload.DownloadItem.DownloadId, HistoryEventType.Grabbed)
|
var grabbedItems = _historyService.Find(trackedDownload.DownloadItem.DownloadId, HistoryEventType.Grabbed)
|
||||||
|
|
|
@ -4,10 +4,13 @@ define(
|
||||||
[
|
[
|
||||||
'jquery',
|
'jquery',
|
||||||
'marionette',
|
'marionette',
|
||||||
'Cells/NzbDroneCell'
|
'Cells/TemplatedCell',
|
||||||
], function ($, Marionette, NzbDroneCell) {
|
'Activity/Queue/RemoveFromQueueView',
|
||||||
return NzbDroneCell.extend({
|
'vent'
|
||||||
|
], function ($, Marionette, TemplatedCell, RemoveFromQueueView, vent) {
|
||||||
|
return TemplatedCell.extend({
|
||||||
|
|
||||||
|
template : 'Activity/Queue/QueueActionsCellTemplate',
|
||||||
className : 'queue-actions-cell',
|
className : 'queue-actions-cell',
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
|
@ -21,48 +24,11 @@ define(
|
||||||
grab : '.x-grab'
|
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>');
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
_remove : function () {
|
_remove : function () {
|
||||||
this.model.destroy();
|
|
||||||
|
var showBlacklist = this.model.get('status') !== 'Pending';
|
||||||
|
|
||||||
|
vent.trigger(vent.Commands.OpenModalCommand, new RemoveFromQueueView({ model: this.model, showBlacklist: showBlacklist }));
|
||||||
},
|
},
|
||||||
|
|
||||||
_import : function () {
|
_import : function () {
|
||||||
|
|
12
src/UI/Activity/Queue/QueueActionsCellTemplate.hbs
Normal file
12
src/UI/Activity/Queue/QueueActionsCellTemplate.hbs
Normal file
|
@ -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}}
|
39
src/UI/Activity/Queue/RemoveFromQueueView.js
Normal file
39
src/UI/Activity/Queue/RemoveFromQueueView.js
Normal file
|
@ -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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
49
src/UI/Activity/Queue/RemoveFromQueueViewTemplate.hbs
Normal file
49
src/UI/Activity/Queue/RemoveFromQueueViewTemplate.hbs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</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;
|
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 {
|
.queue-actions-cell {
|
||||||
width : 55px;
|
width : 70px;
|
||||||
text-align : right !important;
|
text-align : right !important;
|
||||||
|
|
||||||
i {
|
i {
|
||||||
margin-left : 3px;
|
margin-left : 1px;
|
||||||
margin-right : 3px;
|
margin-right : 1px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,11 @@
|
||||||
color : @brand-danger;
|
color : @brand-danger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-nd-blacklist:before {
|
||||||
|
.icon(@ban-circle);
|
||||||
|
color : @brand-danger;
|
||||||
|
}
|
||||||
|
|
||||||
.icon-nd-spinner:before {
|
.icon-nd-spinner:before {
|
||||||
.icon(@spinner);
|
.icon(@spinner);
|
||||||
.icon-spin;
|
.icon-spin;
|
||||||
|
|
Loading…
Add table
Reference in a new issue