Added: Ability to delete multiple movies at once via the movie editor.

pull/1972/head
Leonardo Galli 7 years ago
parent 8de87bb516
commit fb53fc68a9

@ -1,7 +1,10 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Nancy; using Nancy;
using Nancy.Responses;
using NzbDrone.Api.Extensions; using NzbDrone.Api.Extensions;
using NzbDrone.Api.REST;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
namespace NzbDrone.Api.Movie namespace NzbDrone.Api.Movie
@ -15,6 +18,7 @@ namespace NzbDrone.Api.Movie
{ {
_movieService = movieService; _movieService = movieService;
Put["/"] = Movie => SaveAll(); Put["/"] = Movie => SaveAll();
Put["/delete"] = Movie => DeleteSelected();
} }
private Response SaveAll() private Response SaveAll()
@ -27,5 +31,33 @@ namespace NzbDrone.Api.Movie
.ToResource() .ToResource()
.AsResponse(HttpStatusCode.Accepted); .AsResponse(HttpStatusCode.Accepted);
} }
private Response DeleteSelected()
{
var deleteFiles = false;
var addExclusion = false;
var deleteFilesQuery = Request.Query.deleteFiles;
var addExclusionQuery = Request.Query.addExclusion;
if (deleteFilesQuery.HasValue)
{
deleteFiles = Convert.ToBoolean(deleteFilesQuery.Value);
}
if (addExclusionQuery.HasValue)
{
addExclusion = Convert.ToBoolean(addExclusionQuery.Value);
}
var ids = Request.Body.FromJson<List<int>>();
foreach (var id in ids)
{
_movieService.DeleteMovie(id, deleteFiles, addExclusion);
}
return new Response
{
StatusCode = HttpStatusCode.Accepted
};
}
} }
} }

@ -309,6 +309,10 @@
.fa-icon-color(@brand-danger); .fa-icon-color(@brand-danger);
} }
.icon-radarr-delete-white {
.fa-icon-content(@fa-var-remove);
}
.icon-sonarr-ignore { .icon-sonarr-ignore {
.fa-icon-content(@fa-var-eye-slash); .fa-icon-content(@fa-var-eye-slash);
} }

@ -0,0 +1,63 @@
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="close">&times;</button>
<h3>Delete {{removeCount}} Titles</h3>
</div>
<div class="modal-body delete-series-modal">
<div class="row">
<div class="col-sm-12">
<div class="form-horizontal">
<div class="form-group">
<label class="col-sm-4 control-label">Delete all files</label>
<div class="col-sm-8">
<div class="input-group">
<label class="checkbox toggle well">
<input type="checkbox" class="x-delete-files">
<p>
<span>Yes</span>
<span>No</span>
</p>
<div class="btn slide-button btn-danger"></div>
</label>
<span class="help-inline-checkbox">
<i class="icon-sonarr-form-info" title="Do you want to delete all files from disk?"></i>
<i class="icon-sonarr-form-warning" title="This option is irreversible, use with extreme caution!"></i>
</span>
</div>
</div>
</div>
<div class="col-md-offset-1 col-md-5 delete-files-info x-delete-files-info">
{{fileCount}} movie file(s) will be deleted
</div>
<div class="form-group">
<label class="col-sm-4 control-label">Exclude movies from auto list import?</label>
<div class="col-sm-8">
<div class="input-group">
<label class="checkbox toggle well">
<input type="checkbox" class="x-add-exclusion">
<p>
<span>Yes</span>
<span>No</span>
</p>
<div class="btn slide-button btn-danger"></div>
</label>
<span class="help-inline-checkbox">
<i class="icon-sonarr-form-info" title="Do you want to prevent these movies from being read during automatic list syncing?"></i>
<i class="icon-sonarr-form-info" title="Movies can be removed from the exclusions list via the lists tab in settings."></i>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<span class="indicator x-indicator">
<i class="icon-sonarr-spinner fa-spin" aria-hidden="true"></i>
</span>
<button class="btn" data-dismiss="modal">Cancel</button>
<button class="btn btn-danger x-confirm-delete">Delete</button>
</div>
</div>

@ -0,0 +1,60 @@
var vent = require('vent');
var Marionette = require('marionette');
var Backbone = require('backbone');
module.exports = Marionette.ItemView.extend({
template : 'Movies/Editor/Delete/DeleteSelectedTemplate',
events : {
'click .x-confirm-delete' : 'removeSeries',
'change .x-delete-files' : 'changeDeletedFiles'
},
ui : {
deleteFiles : '.x-delete-files',
deleteFilesInfo : '.x-delete-files-info',
indicator : '.x-indicator',
addExclusion : '.x-add-exclusion'
},
initialize : function(options) {
this.movies = options.movies;
this.templateHelpers = {
removeCount : this.movies.length,
fileCount : _.filter(this.movies, function(m){
return m.get("hasFile");
}).length
};
},
removeSeries : function() {
var self = this;
var deleteFiles = this.ui.deleteFiles.prop('checked');
var addExclusion = this.ui.addExclusion.prop('checked');
this.ui.indicator.show();
var proxy = _.extend(new Backbone.Model(), {
id : '',
url : window.NzbDrone.ApiRoot+'/movie/editor/delete?deleteFiles='+deleteFiles+'&addExclusion='+addExclusion,
toJSON : function() {
return _.pluck(self.movies, "id");
}
});
proxy.save().done(function() {
//vent.trigger(vent.Events.SeriesDeleted, { series : self.model });
vent.trigger(vent.Commands.CloseModalCommand);
});
},
changeDeletedFiles : function() {
var deleteFiles = this.ui.deleteFiles.prop('checked');
if (deleteFiles) {
this.ui.deleteFilesInfo.show();
} else {
this.ui.deleteFilesInfo.hide();
}
}
});

@ -13,6 +13,7 @@ var ToolbarLayout = require('../../Shared/Toolbar/ToolbarLayout');
var FooterView = require('./MovieEditorFooterView'); var FooterView = require('./MovieEditorFooterView');
var GridPager = require('../../Shared/Grid/Pager'); var GridPager = require('../../Shared/Grid/Pager');
require('../../Mixins/backbone.signalr.mixin'); require('../../Mixins/backbone.signalr.mixin');
var DeleteSelectedView = require('./Delete/DeleteSelectedView');
var Config = require('../../Config'); var Config = require('../../Config');
window.shownOnce = false; window.shownOnce = false;
@ -68,20 +69,6 @@ module.exports = Marionette.Layout.extend({
} }
], ],
leftSideButtons : {
type : 'default',
storeState : false,
items : [
{
title : 'Update Library',
icon : 'icon-sonarr-refresh',
command : 'refreshmovie',
successMessage : 'Library was updated!',
errorMessage : 'Library update failed!'
}
]
},
initialize : function() { initialize : function() {
this.movieCollection = MoviesCollection.clone(); this.movieCollection = MoviesCollection.clone();
@ -106,6 +93,26 @@ module.exports = Marionette.Layout.extend({
this.listenTo(this.movieCollection.fullCollection, 'sync', function() { this.listenTo(this.movieCollection.fullCollection, 'sync', function() {
}); });
this.leftSideButtons = {
type : 'default',
storeState : false,
items : [
{
title : 'Update Library',
icon : 'icon-sonarr-refresh',
command : 'refreshmovie',
successMessage : 'Library was updated!',
errorMessage : 'Library update failed!'
},
{
title : 'Delete Selected',
icon : 'icon-radarr-delete-white',
className: 'btn-danger',
callback : this._deleteSelected
}
]
};
//this.listenTo(FullMovieCollection, 'save', function() { //this.listenTo(FullMovieCollection, 'save', function() {
// window.alert('Done Saving'); // window.alert('Done Saving');
//}); //});
@ -230,5 +237,12 @@ module.exports = Marionette.Layout.extend({
_setFilter : function(buttonContext) { _setFilter : function(buttonContext) {
var mode = buttonContext.model.get('key'); var mode = buttonContext.model.get('key');
this.movieCollection.setFilterMode(mode); this.movieCollection.setFilterMode(mode);
},
_deleteSelected: function() {
var selected = FullMovieCollection.where({ selected : true });
var updateFilesMoviesView = new DeleteSelectedView({ movies : selected });
vent.trigger(vent.Commands.OpenModalCommand, updateFilesMoviesView);
} }
}); });

Loading…
Cancel
Save