mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-29 21:39:34 +02:00
Completely overhauled how import exclusions work.
Currently new exclusions can only be added when adding new movies or deleting old ones. Not manually in the settings menu. Movies can now be hidden in the new discover feature by using the new import exclusions!
This commit is contained in:
@@ -6,6 +6,7 @@ var AddMoviesCollection = require('./AddMoviesCollection');
|
||||
var SearchResultCollectionView = require('./SearchResultCollectionView');
|
||||
var EmptyView = require('./EmptyView');
|
||||
var NotFoundView = require('./NotFoundView');
|
||||
var DiscoverEmptyView = require('./DiscoverEmptyView');
|
||||
var ErrorView = require('./ErrorView');
|
||||
var LoadingView = require('../Shared/LoadingView');
|
||||
var FullMovieCollection = require("../Movies/FullMovieCollection");
|
||||
@@ -112,14 +113,10 @@ module.exports = Marionette.Layout.extend({
|
||||
|
||||
if (this.isDiscover) {
|
||||
this.ui.searchBar.hide();
|
||||
if (FullMovieCollection.length > 0) {
|
||||
this._discoverRecos();
|
||||
} else {
|
||||
this.listenTo(FullMovieCollection, "sync", this._discover);
|
||||
}
|
||||
if (this.collection.length == 0) {
|
||||
this._discoverRecos();
|
||||
/*if (this.collection.length == 0) {
|
||||
this.searchResult.show(new LoadingView());
|
||||
}
|
||||
}*/
|
||||
}
|
||||
},
|
||||
|
||||
@@ -192,8 +189,13 @@ module.exports = Marionette.Layout.extend({
|
||||
_showResults : function() {
|
||||
if (!this.isClosed) {
|
||||
if (this.collection.length === 0) {
|
||||
this.ui.searchBar.show();
|
||||
this.searchResult.show(new NotFoundView({ term : this.collection.term }));
|
||||
if (this.isDiscover) {
|
||||
this.searchResult.show(new DiscoverEmptyView());
|
||||
} else {
|
||||
this.ui.searchBar.show();
|
||||
this.searchResult.show(new NotFoundView({ term : this.collection.term }));
|
||||
}
|
||||
|
||||
} else {
|
||||
this.searchResult.show(this.resultCollectionView);
|
||||
if (!this.showingAll) {
|
||||
@@ -224,11 +226,10 @@ module.exports = Marionette.Layout.extend({
|
||||
if (this.collection.action === action) {
|
||||
return
|
||||
}
|
||||
this.collection.reset();
|
||||
this.searchResult.show(new LoadingView());
|
||||
this.collection.action = action;
|
||||
this.collection.fetch({
|
||||
data : { action : action }
|
||||
});
|
||||
this.currentSearchPromise = this.collection.fetch();
|
||||
},
|
||||
|
||||
_discoverRecos : function() {
|
||||
|
5
src/UI/AddMovies/DiscoverEmptyView.js
Normal file
5
src/UI/AddMovies/DiscoverEmptyView.js
Normal file
@@ -0,0 +1,5 @@
|
||||
var Marionette = require('marionette');
|
||||
|
||||
module.exports = Marionette.CompositeView.extend({
|
||||
template : 'AddMovies/DiscoverEmptyViewTemplate'
|
||||
});
|
6
src/UI/AddMovies/DiscoverEmptyViewTemplate.hbs
Normal file
6
src/UI/AddMovies/DiscoverEmptyViewTemplate.hbs
Normal file
@@ -0,0 +1,6 @@
|
||||
<div class="text-center col-md-12">
|
||||
<h3>
|
||||
No movies left to discover. Come back at another time :)
|
||||
</h3>
|
||||
|
||||
</div>
|
@@ -7,6 +7,7 @@ var Profiles = require('../Profile/ProfileCollection');
|
||||
var RootFolders = require('./RootFolders/RootFolderCollection');
|
||||
var RootFolderLayout = require('./RootFolders/RootFolderLayout');
|
||||
var FullMovieCollection = require('../Movies/FullMovieCollection');
|
||||
var ImportExclusionModel = require("../Settings/NetImport/ImportExclusionModel");
|
||||
var Config = require('../Config');
|
||||
var Messenger = require('../Shared/Messenger');
|
||||
var AsValidatedView = require('../Mixins/AsValidatedView');
|
||||
@@ -33,6 +34,7 @@ var view = Marionette.ItemView.extend({
|
||||
events : {
|
||||
'click .x-add' : '_addWithoutSearch',
|
||||
'click .x-add-search' : '_addAndSearch',
|
||||
"click .x-ignore" : "_ignoreMovie",
|
||||
'change .x-profile' : '_profileChanged',
|
||||
'change .x-root-folder' : '_rootFolderChanged',
|
||||
'change .x-season-folder' : '_seasonFolderChanged',
|
||||
@@ -239,6 +241,13 @@ var view = Marionette.ItemView.extend({
|
||||
});
|
||||
},
|
||||
|
||||
_ignoreMovie : function() {
|
||||
var exclusion = new ImportExclusionModel({tmdbId : this.model.get("tmdbId"),
|
||||
movieTitle : this.model.get("title"), movieYear : this.model.get("year")});
|
||||
exclusion.save();
|
||||
this.remove();
|
||||
},
|
||||
|
||||
_rootFoldersUpdated : function() {
|
||||
this._configureTemplateHelpers();
|
||||
this.render();
|
||||
|
@@ -106,6 +106,10 @@
|
||||
<button class="btn btn-success add x-add-search" title="Add and Search for movie">
|
||||
<i class="icon-sonarr-search"></i>
|
||||
</button>
|
||||
|
||||
<button class="btn btn-warning ignore x-ignore" title="Ignore this movie, so it does not show up anymore">
|
||||
<i class="icon-sonarr-ignore"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
|
@@ -304,6 +304,10 @@
|
||||
.fa-icon-color(@brand-danger);
|
||||
}
|
||||
|
||||
.icon-sonarr-ignore {
|
||||
.fa-icon-content(@fa-var-eye-slash);
|
||||
}
|
||||
|
||||
.icon-sonarr-deleted {
|
||||
.fa-icon-content(@fa-var-trash);
|
||||
}
|
||||
|
24
src/UI/Settings/NetImport/DeleteExclusionCell.js
Normal file
24
src/UI/Settings/NetImport/DeleteExclusionCell.js
Normal file
@@ -0,0 +1,24 @@
|
||||
var vent = require('vent');
|
||||
var Backgrid = require('backgrid');
|
||||
|
||||
module.exports = Backgrid.Cell.extend({
|
||||
className : 'delete-episode-file-cell',
|
||||
|
||||
events : {
|
||||
'click' : '_onClick'
|
||||
},
|
||||
|
||||
render : function() {
|
||||
this.$el.empty();
|
||||
this.$el.html('<i class="icon-sonarr-delete" title="Delete exclusion."></i>');
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_onClick : function() {
|
||||
var self = this;
|
||||
|
||||
this.model.destroy();
|
||||
|
||||
}
|
||||
});
|
18
src/UI/Settings/NetImport/ExclusionTitleCell.js
Normal file
18
src/UI/Settings/NetImport/ExclusionTitleCell.js
Normal file
@@ -0,0 +1,18 @@
|
||||
var NzbDroneCell = require('../../Cells/NzbDroneCell');
|
||||
|
||||
module.exports = NzbDroneCell.extend({
|
||||
className : 'exclusion-title-cell',
|
||||
|
||||
render : function() {
|
||||
this.$el.empty();
|
||||
var title = this.model.get("movieTitle");
|
||||
var year = this.model.get("movieYear");
|
||||
var str = title;
|
||||
if (year > 1800) {
|
||||
str += " ("+year+")";
|
||||
}
|
||||
this.$el.html(str);
|
||||
|
||||
return this;
|
||||
}
|
||||
});
|
7
src/UI/Settings/NetImport/ImportExclusionModel.js
Normal file
7
src/UI/Settings/NetImport/ImportExclusionModel.js
Normal file
@@ -0,0 +1,7 @@
|
||||
var Backbone = require('backbone');
|
||||
var _ = require('underscore');
|
||||
|
||||
module.exports = Backbone.Model.extend({
|
||||
urlRoot : window.NzbDrone.ApiRoot + '/exclusions',
|
||||
|
||||
});
|
9
src/UI/Settings/NetImport/ImportExclusionsCollection.js
Normal file
9
src/UI/Settings/NetImport/ImportExclusionsCollection.js
Normal file
@@ -0,0 +1,9 @@
|
||||
var Backbone = require('backbone');
|
||||
var NetImportModel = require('./ImportExclusionModel');
|
||||
|
||||
var ImportExclusionsCollection = Backbone.Collection.extend({
|
||||
model : NetImportModel,
|
||||
url : window.NzbDrone.ApiRoot + '/exclusions',
|
||||
});
|
||||
|
||||
module.exports = new ImportExclusionsCollection();
|
@@ -3,6 +3,14 @@ var NetImportCollection = require('./NetImportCollection');
|
||||
var CollectionView = require('./NetImportCollectionView');
|
||||
var OptionsView = require('./Options/NetImportOptionsView');
|
||||
var RootFolderCollection = require('../../AddMovies/RootFolders/RootFolderCollection');
|
||||
var ImportExclusionsCollection = require('./ImportExclusionsCollection');
|
||||
var SelectAllCell = require('../../Cells/SelectAllCell');
|
||||
var DeleteExclusionCell = require('./DeleteExclusionCell');
|
||||
var ExclusionTitleCell = require("./ExclusionTitleCell");
|
||||
var _ = require('underscore');
|
||||
var vent = require('vent');
|
||||
var Backgrid = require('backgrid');
|
||||
var $ = require('jquery');
|
||||
|
||||
module.exports = Marionette.Layout.extend({
|
||||
template : 'Settings/NetImport/NetImportLayoutTemplate',
|
||||
@@ -10,18 +18,58 @@ module.exports = Marionette.Layout.extend({
|
||||
regions : {
|
||||
lists : '#x-lists-region',
|
||||
listOption : '#x-list-options-region',
|
||||
importExclusions : "#exclusions"
|
||||
},
|
||||
|
||||
columns: [{
|
||||
name: '',
|
||||
cell: SelectAllCell,
|
||||
headerCell: 'select-all',
|
||||
sortable: false
|
||||
}, {
|
||||
name: 'tmdbId',
|
||||
label: 'TMDBID',
|
||||
cell: Backgrid.StringCell,
|
||||
sortable: false,
|
||||
}, {
|
||||
name: 'movieTitle',
|
||||
label: 'Title',
|
||||
cell: ExclusionTitleCell,
|
||||
cellValue: 'this',
|
||||
}, {
|
||||
name: 'this',
|
||||
label: '',
|
||||
cell: DeleteExclusionCell,
|
||||
sortable: false,
|
||||
}],
|
||||
|
||||
|
||||
initialize : function() {
|
||||
this.indexersCollection = new NetImportCollection();
|
||||
this.indexersCollection.fetch();
|
||||
RootFolderCollection.fetch().done(function() {
|
||||
RootFolderCollection.synced = true;
|
||||
});
|
||||
ImportExclusionsCollection.fetch().done(function() {
|
||||
ImportExclusionsCollection.synced = true;
|
||||
});
|
||||
},
|
||||
|
||||
onShow : function() {
|
||||
this.listenTo(ImportExclusionsCollection, "sync", this._showExclusions);
|
||||
if (ImportExclusionsCollection.synced === true) {
|
||||
this._showExclusions();
|
||||
}
|
||||
this.lists.show(new CollectionView({ collection : this.indexersCollection }));
|
||||
this.listOption.show(new OptionsView({ model : this.model }));
|
||||
},
|
||||
|
||||
_showExclusions : function() {
|
||||
this.exclusionGrid = new Backgrid.Grid({
|
||||
collection: ImportExclusionsCollection,
|
||||
columns: this.columns,
|
||||
className: 'table table-hover'
|
||||
});
|
||||
this.importExclusions.show(this.exclusionGrid);
|
||||
}
|
||||
});
|
||||
|
@@ -1,4 +1,9 @@
|
||||
<div id="x-lists-region"></div>
|
||||
<div class="form-horizontal">
|
||||
<div id="x-list-options-region"></div>
|
||||
<fieldset>
|
||||
<legend>Import Exclusions</legend>
|
||||
<div id="exclusions">
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
@@ -1,6 +1,11 @@
|
||||
var Marionette = require('marionette');
|
||||
var AsModelBoundView = require('../../../Mixins/AsModelBoundView');
|
||||
var AsValidatedView = require('../../../Mixins/AsValidatedView');
|
||||
var ImportExclusionsCollection = require('./../ImportExclusionsCollection');
|
||||
var SelectAllCell = require('../../../Cells/SelectAllCell');
|
||||
var _ = require('underscore');
|
||||
var vent = require('vent');
|
||||
var Backgrid = require('backgrid');
|
||||
var $ = require('jquery');
|
||||
require('../../../Mixins/TagInput');
|
||||
require('bootstrap');
|
||||
@@ -22,10 +27,10 @@ var view = Marionette.ItemView.extend({
|
||||
'click .x-revoke-trakt-tokens' : '_revokeTraktTokens'
|
||||
},
|
||||
|
||||
initialize : function() {
|
||||
initialize : function() {
|
||||
|
||||
},
|
||||
|
||||
|
||||
onShow : function() {
|
||||
var params = new URLSearchParams(window.location.search);
|
||||
var oauth = params.get('access');
|
||||
@@ -39,78 +44,25 @@ var view = Marionette.ItemView.extend({
|
||||
//Config.setValue("traktRefreshToken", refresh);
|
||||
var tokenExpiry = Math.floor(Date.now() / 1000) + 4838400;
|
||||
this.ui.tokenExpiry.val(tokenExpiry).trigger('change'); // this means the token will expire in 8 weeks (4838400 seconds)
|
||||
//Config.setValue("traktTokenExpiry",tokenExpiry);
|
||||
//Config.setValue("traktTokenExpiry",tokenExpiry);
|
||||
//this.model.isSaved = false;
|
||||
//window.alert("Trakt Authentication Complete - Click Save to make the change take effect");
|
||||
}
|
||||
if (this.ui.authToken.val() && this.ui.refreshToken.val()){
|
||||
this.ui.resetTokensButton.hide();
|
||||
this.ui.revokeTokensButton.show();
|
||||
this.ui.resetTokensButton.hide();
|
||||
this.ui.revokeTokensButton.show();
|
||||
} else {
|
||||
this.ui.resetTokensButton.show();
|
||||
this.ui.revokeTokensButton.hide();
|
||||
this.ui.resetTokensButton.show();
|
||||
this.ui.revokeTokensButton.hide();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
},
|
||||
|
||||
onRender : function() {
|
||||
this.ui.importExclusions.tagsinput({
|
||||
trimValue : true,
|
||||
tagClass : 'label label-danger',
|
||||
/*itemText : function(item) {
|
||||
var uri;
|
||||
var text;
|
||||
if (item.startsWith('tt')) {
|
||||
uri = window.NzbDrone.ApiRoot + '/movies/lookup/imdb?imdbId='+item;
|
||||
}
|
||||
else {
|
||||
uri = window.NzbDrone.ApiRoot + '/movies/lookup/tmdb?tmdbId='+item;
|
||||
}
|
||||
var promise = $.ajax({
|
||||
url : uri,
|
||||
type : 'GET',
|
||||
async : false,
|
||||
});
|
||||
promise.success(function(response) {
|
||||
text=response['title']+' ('+response['year']+')';
|
||||
});
|
||||
|
||||
promise.error(function(request, status, error) {
|
||||
text=item;
|
||||
});
|
||||
return text;
|
||||
}*/
|
||||
});
|
||||
this.ui.importExclusions.on('beforeItemAdd', function(event) {
|
||||
var uri;
|
||||
if (event.item.startsWith('tt')) {
|
||||
uri = window.NzbDrone.ApiRoot + '/movies/lookup/imdb?imdbId='+event.item;
|
||||
}
|
||||
else {
|
||||
uri = window.NzbDrone.ApiRoot + '/movies/lookup/tmdb?tmdbId='+event.item;
|
||||
}
|
||||
var promise = $.ajax({
|
||||
url : uri,
|
||||
type : 'GET',
|
||||
async : false,
|
||||
});
|
||||
promise.success(function(response) {
|
||||
event.cancel=false;
|
||||
|
||||
//var newText = response['tmdbId']+'-';
|
||||
//if (event.item.startsWith('tt')) {
|
||||
// newText = newText+'['+event.item+']';
|
||||
//}
|
||||
event.item = response.titleSlug;//+' ('+response['year']+')-'+response['tmdbId'];
|
||||
});
|
||||
|
||||
promise.error(function(request, status, error) {
|
||||
event.cancel = true;
|
||||
window.alert(event.item+' is not a valid! Must be valid tt#### IMDB ID or #### TMDB ID');
|
||||
});
|
||||
return event;
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
ui : {
|
||||
resetTraktTokens : '.x-reset-trakt-tokens',
|
||||
@@ -118,7 +70,7 @@ var view = Marionette.ItemView.extend({
|
||||
refreshToken : '.x-trakt-refresh-token',
|
||||
resetTokensButton : '.x-reset-trakt-tokens',
|
||||
revokeTokensButton : '.x-revoke-trakt-tokens',
|
||||
tokenExpiry : '.x-trakt-token-expiry',
|
||||
tokenExpiry : '.x-trakt-token-expiry',
|
||||
importExclusions : '.x-import-exclusions'
|
||||
},
|
||||
|
||||
@@ -131,15 +83,16 @@ var view = Marionette.ItemView.extend({
|
||||
|
||||
_revokeTraktTokens : function() {
|
||||
if (window.confirm("Log out of trakt.tv?")){
|
||||
//TODO: need to implement this: http://docs.trakt.apiary.io/#reference/authentication-oauth/revoke-token/revoke-an-access_token
|
||||
//TODO: need to implement this: http://docs.trakt.apiary.io/#reference/authentication-oauth/revoke-token/revoke-an-access_token
|
||||
this.ui.authToken.val('').trigger('change');
|
||||
this.ui.refreshToken.val('').trigger('change');
|
||||
this.ui.tokenExpiry.val(0).trigger('change');
|
||||
this.ui.refreshToken.val('').trigger('change');
|
||||
this.ui.tokenExpiry.val(0).trigger('change');
|
||||
this.ui.resetTokensButton.show();
|
||||
this.ui.revokeTokensButton.hide();
|
||||
window.alert("Logged out of Trakt.tv - Click Save to make the change take effect");
|
||||
this.ui.revokeTokensButton.hide();
|
||||
window.alert("Logged out of Trakt.tv - Click Save to make the change take effect");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
@@ -30,17 +30,17 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<!--<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Import Exclusions</label>
|
||||
<div class="col-sm-1 col-sm-push-4 help-inline">
|
||||
<i class="icon-sonarr-form-warning" title="Movies in this field will not be imported even if they exist on your lists."/>
|
||||
<i class="icon-sonarr-form-info" title="Comma separated imdbid or tmdbid: tt0120915,216138,tt0121765"/>
|
||||
</div>
|
||||
<div class="col-sm-4 col-sm-pull-1">
|
||||
|
||||
|
||||
<input type="text" name="importExclusions" class="form-control x-import-exclusions"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>-->
|
||||
<legend>Trakt Authentication</legend>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-1 control-label">Auth Token</label>
|
||||
@@ -58,5 +58,6 @@
|
||||
<button class="btn btn-danger btn-icon-only x-reset-trakt-tokens" title="Reset Trakt Tokens"><i class="icon-sonarr-refresh"></i></button>
|
||||
<button class="btn btn-danger btn-icon-only x-revoke-trakt-tokens" title="Revoke Trakt Tokens"><i class="icon-sonarr-logout"></i></button>
|
||||
</div >
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
|
@@ -14,6 +14,7 @@ var IndexerCollection = require('./Indexers/IndexerCollection');
|
||||
var IndexerSettingsModel = require('./Indexers/IndexerSettingsModel');
|
||||
var NetImportSettingsModel = require("./NetImport/NetImportSettingsModel");
|
||||
var NetImportCollection = require('./NetImport/NetImportCollection');
|
||||
var ImportExclusionsCollection = require('./NetImport/ImportExclusionsCollection');
|
||||
var NetImportLayout = require('./NetImport/NetImportLayout');
|
||||
var DownloadClientLayout = require('./DownloadClient/DownloadClientLayout');
|
||||
var DownloadClientSettingsModel = require('./DownloadClient/DownloadClientSettingsModel');
|
||||
|
Reference in New Issue
Block a user