1
0
mirror of https://github.com/Radarr/Radarr.git synced 2026-04-18 21:35:51 -04:00

Episode file editor

New: Ability to delete all episode files in a series or season
New: Ability to change quality for all episode files in a series or season
This commit is contained in:
Mark McDowall
2015-02-19 22:14:04 -08:00
parent 47a0f55255
commit 8ab0b26773
13 changed files with 334 additions and 14 deletions

View File

@@ -0,0 +1,5 @@
var Marionette = require('marionette');
module.exports = Marionette.CompositeView.extend({
template : 'EpisodeFile/Editor/EmptyViewTemplate'
});

View File

@@ -0,0 +1,5 @@
<div class="row">
<div class="col-md-12">
No episode files
</div>
</div>

View File

@@ -0,0 +1,185 @@
var _ = require('underscore');
var reqres = require('../../reqres');
var Marionette = require('marionette');
var Backgrid = require('backgrid');
var SelectAllCell = require('../../Cells/SelectAllCell');
var EpisodeNumberCell = require('../../Series/Details/EpisodeNumberCell');
var SeasonEpisodeNumberCell = require('../../Cells/EpisodeNumberCell');
var EpisodeFilePathCell = require('../../Cells/EpisodeFilePathCell');
var EpisodeStatusCell = require('../../Cells/EpisodeStatusCell');
var RelativeDateCell = require('../../Cells/RelativeDateCell');
var EpisodeCollection = require('../../Series/EpisodeCollection');
var ProfileSchemaCollection = require('../../Settings/Profile/ProfileSchemaCollection');
var QualitySelectView = require('./QualitySelectView');
var EmptyView = require('./EmptyView');
module.exports = Marionette.Layout.extend({
className : 'modal-lg',
template : 'EpisodeFile/Editor/EpisodeFileEditorLayoutTemplate',
regions : {
episodeGrid : '.x-episode-list',
quality : '.x-quality'
},
ui : {
seasonMonitored : '.x-season-monitored'
},
events : {
'click .x-season-monitored' : '_seasonMonitored',
'click .x-delete-files' : '_deleteFiles'
},
initialize : function(options) {
if (!options.series) {
throw 'series is required';
}
if (!options.episodeCollection) {
throw 'episodeCollection is required';
}
var filtered = options.episodeCollection.filter(function(episode) {
return episode.get('episodeFileId') > 0;
});
this.series = options.series;
this.episodeCollection = options.episodeCollection;
this.filteredEpisodes = new EpisodeCollection(filtered);
this.templateHelpers = {};
this.templateHelpers.series = this.series.toJSON();
this._getColumns();
},
onRender : function() {
this._getQualities();
this._showEpisodes();
},
_getColumns : function () {
var episodeCell = {};
if (this.model) {
episodeCell.name = 'episodeNumber';
episodeCell.label = '#';
episodeCell.cell = EpisodeNumberCell;
}
else {
episodeCell.name = 'this';
episodeCell.label = 'Episode';
episodeCell.cell = SeasonEpisodeNumberCell;
}
this.columns = [
{
name : '',
cell : SelectAllCell,
headerCell : 'select-all',
sortable : false
},
episodeCell,
{
name : 'episodeNumber',
label : 'Relative Path',
cell : EpisodeFilePathCell
},
{
name : 'airDateUtc',
label : 'Air Date',
cell : RelativeDateCell
},
{
name : 'status',
label : 'Quality',
cell : EpisodeStatusCell,
sortable : false
}
];
if (!this.model) {
this.columns[1].name = 'this';
this.columns[1].cell = SeasonEpisodeNumberCell;
}
},
_showEpisodes : function() {
if (this.filteredEpisodes.length === 0) {
this.episodeGrid.show(new EmptyView());
return;
}
this.episodeGridView = new Backgrid.Grid({
columns : this.columns,
collection : this.filteredEpisodes,
className : 'table table-hover season-grid'
});
this.episodeGrid.show(this.episodeGridView);
},
_getQualities : function() {
var self = this;
var profileSchemaCollection = new ProfileSchemaCollection();
var promise = profileSchemaCollection.fetch();
promise.done(function() {
var profile = profileSchemaCollection.first();
self.qualitySelectView = new QualitySelectView({ qualities: _.map(profile.get('items'), 'quality') });
self.listenTo(self.qualitySelectView, 'seasonedit:quality', self._changeQuality);
self.quality.show(self.qualitySelectView);
});
},
_changeQuality : function(options) {
var newQuality = {
quality : options.selected,
revision : {
version : 1,
real : 0
}
};
var selected = this._getSelectedEpisodeFileIds();
_.each(selected, function(episodeFileId) {
if (reqres.hasHandler(reqres.Requests.GetEpisodeFileById)) {
var episodeFile = reqres.request(reqres.Requests.GetEpisodeFileById, episodeFileId);
episodeFile.set('quality', newQuality);
episodeFile.save();
}
});
},
_deleteFiles : function() {
if (!window.confirm('Are you sure you want to delete the episode files for the selected episodes?')) {
return;
}
var selected = this._getSelectedEpisodeFileIds();
_.each(selected, function(episodeFileId) {
if (reqres.hasHandler(reqres.Requests.GetEpisodeFileById)) {
var episodeFile = reqres.request(reqres.Requests.GetEpisodeFileById, episodeFileId);
episodeFile.destroy();
}
});
_.each(this.episodeGridView.getSelectedModels(), function(episode) {
this.episodeGridView.removeRow(episode);
}, this);
},
_getSelectedEpisodeFileIds: function () {
return _.uniq(_.map(this.episodeGridView.getSelectedModels(), function (episode) {
return episode.get('episodeFileId');
}));
}
});

View File

@@ -0,0 +1,28 @@
<div class="modal-content">
<div class="edit-season-modal">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h3>
{{#if seasonNumber}}
{{#if_eq seasonNumber compare="0"}}
{{series.title}} - Specials
{{else}}
{{series.title}} - Season {{seasonNumber}}
{{/if_eq}}
{{else}}
{{series.title}}
{{/if}}
</h3>
</div>
<div class="modal-body">
<div class="x-episode-list"></div>
<div class="x-quality"></div>
</div>
<div class="modal-footer">
<button class="btn btn-danger x-delete-files">delete files</button>
<button class="btn btn-default" data-dismiss="modal">close</button>
</div>
</div>
</div>

View File

@@ -0,0 +1,35 @@
var _ = require('underscore');
var Marionette = require('marionette');
module.exports = Marionette.ItemView.extend({
template : 'EpisodeFile/Editor/QualitySelectViewTemplate',
ui : {
select : '.x-select'
},
events : {
'change .x-select' : '_changeSelect'
},
initialize : function (options) {
this.qualities = options.qualities;
this.templateHelpers = {
qualities : this.qualities
};
},
_changeSelect : function () {
var value = this.ui.select.val();
if (value === 'choose') {
return;
}
var quality = _.find(this.qualities, { 'id': parseInt(value) });
this.trigger('seasonedit:quality', { selected : quality });
this.ui.select.val('choose');
}
});

View File

@@ -0,0 +1,10 @@
<div class="row">
<div class="form-group col-md-3 col-md-offset-9">
<select class="form-control x-select">
<option value="choose">Select quality</option>
{{#each qualities}}
<option value="{{id}}">{{name}}</option>
{{/each}}
</select>
</div>
</div>