mirror of
https://github.com/Readarr/Readarr.git
synced 2026-04-22 22:14:44 -04:00
Release restrictions
New: Required terms assignable to series via tags New: Ignored terms assignable to series via tagss
This commit is contained in:
+4
-4
@@ -2,8 +2,8 @@
|
||||
<legend>Remote Path Mappings</legend>
|
||||
|
||||
<div class="col-md-12">
|
||||
<div id="remotepath-mapping-list">
|
||||
<div class="remotepath-header x-header hidden-xs">
|
||||
<div class="rule-setting-list">
|
||||
<div class="rule-setting-header x-header hidden-xs">
|
||||
<div class="row">
|
||||
<span class="col-sm-2">Host</span>
|
||||
<span class="col-sm-5">Remote Path</span>
|
||||
@@ -12,9 +12,9 @@
|
||||
</div>
|
||||
<div class="rows x-rows">
|
||||
</div>
|
||||
<div class="remotepath-footer">
|
||||
<div class="rule-setting-footer">
|
||||
<div class="pull-right">
|
||||
<span class="add-remotepath-mapping">
|
||||
<span class="add-rule-setting-mapping">
|
||||
<i class="icon-nd-add x-add" title="Add new mapping" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -31,30 +31,3 @@
|
||||
width: 33%;
|
||||
}
|
||||
}
|
||||
|
||||
.add-remotepath-mapping {
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
padding: 2px 6px;
|
||||
|
||||
i {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
#remotepath-mapping-list {
|
||||
|
||||
.remotepath-header .row {
|
||||
font-weight: bold;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.rows .row {
|
||||
line-height : 30px;
|
||||
border-top : 1px solid #ddd;
|
||||
vertical-align : middle;
|
||||
padding : 5px;
|
||||
}
|
||||
}
|
||||
@@ -4,25 +4,32 @@ define([
|
||||
'marionette',
|
||||
'Settings/Indexers/IndexerCollection',
|
||||
'Settings/Indexers/IndexerCollectionView',
|
||||
'Settings/Indexers/Options/IndexerOptionsView'
|
||||
], function (Marionette, IndexerCollection, CollectionView, OptionsView) {
|
||||
'Settings/Indexers/Options/IndexerOptionsView',
|
||||
'Settings/Indexers/Restriction/RestrictionCollection',
|
||||
'Settings/Indexers/Restriction/RestrictionCollectionView'
|
||||
], function (Marionette, IndexerCollection, CollectionView, OptionsView, RestrictionCollection, RestrictionCollectionView) {
|
||||
|
||||
return Marionette.Layout.extend({
|
||||
template: 'Settings/Indexers/IndexerLayoutTemplate',
|
||||
|
||||
regions: {
|
||||
indexers : '#x-indexers-region',
|
||||
indexerOptions : '#x-indexer-options-region'
|
||||
indexers : '#x-indexers-region',
|
||||
indexerOptions : '#x-indexer-options-region',
|
||||
restriction : '#x-restriction-region'
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
initialize: function () {
|
||||
this.indexersCollection = new IndexerCollection();
|
||||
this.indexersCollection.fetch();
|
||||
|
||||
this.restrictionCollection = new RestrictionCollection();
|
||||
this.restrictionCollection.fetch();
|
||||
},
|
||||
|
||||
onShow: function () {
|
||||
this.indexers.show(new CollectionView({ collection: this.indexersCollection }));
|
||||
this.indexerOptions.show(new OptionsView({ model: this.model }));
|
||||
this.restriction.show(new RestrictionCollectionView({ collection: this.restrictionCollection }));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<div id="x-indexers-region"></div>
|
||||
<div class="form-horizontal">
|
||||
<div id="x-indexer-options-region"></div>
|
||||
<div id="x-restriction-region"></div>
|
||||
</div>
|
||||
|
||||
@@ -21,17 +21,4 @@
|
||||
<input type="number" name="rssSyncInterval" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group advanced-setting">
|
||||
<label class="col-sm-3 control-label">Release Restrictions</label>
|
||||
|
||||
<div class="col-sm-1 col-sm-push-4 help-inline help-inline-text-area">
|
||||
<i class="icon-nd-form-info" title="Blacklist NZBs based on these words (case-insensitive)"/>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-4 col-sm-pull-1">
|
||||
<textarea rows="3" name="releaseRestrictions" class="form-control release-restrictions"></textarea>
|
||||
<div class="text-area-help">Newline-delimited set of rules</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
'use strict';
|
||||
define([
|
||||
'backbone',
|
||||
'Settings/Indexers/Restriction/RestrictionModel'
|
||||
], function (Backbone, RestrictionModel) {
|
||||
|
||||
return Backbone.Collection.extend({
|
||||
model : RestrictionModel,
|
||||
url : window.NzbDrone.ApiRoot + '/Restriction'
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
'use strict';
|
||||
define([
|
||||
'AppLayout',
|
||||
'marionette',
|
||||
'Settings/Indexers/Restriction/RestrictionItemView',
|
||||
'Settings/Indexers/Restriction/RestrictionEditView',
|
||||
'Tags/TagHelpers',
|
||||
'bootstrap'
|
||||
], function (AppLayout, Marionette, RestrictionItemView, EditView) {
|
||||
|
||||
return Marionette.CompositeView.extend({
|
||||
template : 'Settings/Indexers/Restriction/RestrictionCollectionViewTemplate',
|
||||
itemViewContainer : '.x-rows',
|
||||
itemView : RestrictionItemView,
|
||||
|
||||
events: {
|
||||
'click .x-add' : '_addMapping'
|
||||
},
|
||||
|
||||
_addMapping: function() {
|
||||
var model = this.collection.create({ tags: [] });
|
||||
|
||||
var view = new EditView({ model: model, targetCollection: this.collection});
|
||||
AppLayout.modalRegion.show(view);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
<fieldset class="advanced-setting">
|
||||
<legend>Restrictions</legend>
|
||||
|
||||
<div class="col-md-12">
|
||||
<div class="rule-setting-list">
|
||||
<div class="rule-setting-header x-header hidden-xs">
|
||||
<div class="row">
|
||||
<span class="col-sm-4">Must Contain</span>
|
||||
<span class="col-sm-4">Must Not Contain</span>
|
||||
<span class="col-sm-3">Tags</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rows x-rows">
|
||||
</div>
|
||||
<div class="rule-setting-footer">
|
||||
<div class="pull-right">
|
||||
<span class="add-rule-setting-mapping">
|
||||
<i class="icon-nd-add x-add" title="Add new restriction" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
@@ -0,0 +1,23 @@
|
||||
'use strict';
|
||||
|
||||
define([
|
||||
'vent',
|
||||
'marionette'
|
||||
], function (vent, Marionette) {
|
||||
return Marionette.ItemView.extend({
|
||||
template: 'Settings/Indexers/Restriction/RestrictionDeleteViewTemplate',
|
||||
|
||||
events: {
|
||||
'click .x-confirm-delete': '_delete'
|
||||
},
|
||||
|
||||
_delete: function () {
|
||||
this.model.destroy({
|
||||
wait : true,
|
||||
success: function () {
|
||||
vent.trigger(vent.Commands.CloseModalCommand);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3>Delete Restriction</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Are you sure you want to delete the restriction for '{{localPath}}'?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal">cancel</button>
|
||||
<button class="btn btn-danger x-confirm-delete">delete</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,61 @@
|
||||
'use strict';
|
||||
|
||||
define([
|
||||
'underscore',
|
||||
'vent',
|
||||
'AppLayout',
|
||||
'marionette',
|
||||
'Settings/Indexers/Restriction/RestrictionDeleteView',
|
||||
'Commands/CommandController',
|
||||
'Mixins/AsModelBoundView',
|
||||
'Mixins/AsValidatedView',
|
||||
'Mixins/AsEditModalView',
|
||||
'Mixins/TagInput',
|
||||
'bootstrap',
|
||||
'bootstrap.tagsinput'
|
||||
], function (_, vent, AppLayout, Marionette, DeleteView, CommandController, AsModelBoundView, AsValidatedView, AsEditModalView) {
|
||||
|
||||
var view = Marionette.ItemView.extend({
|
||||
template : 'Settings/Indexers/Restriction/RestrictionEditViewTemplate',
|
||||
|
||||
ui : {
|
||||
required : '.x-required',
|
||||
ignored : '.x-ignored',
|
||||
tags : '.x-tags'
|
||||
},
|
||||
|
||||
_deleteView: DeleteView,
|
||||
|
||||
initialize : function (options) {
|
||||
this.targetCollection = options.targetCollection;
|
||||
},
|
||||
|
||||
onRender : function () {
|
||||
this.ui.required.tagsinput({
|
||||
trimValue : true,
|
||||
tagClass : 'label label-success'
|
||||
});
|
||||
|
||||
this.ui.ignored.tagsinput({
|
||||
trimValue : true,
|
||||
tagClass : 'label label-danger'
|
||||
});
|
||||
|
||||
this.ui.tags.tagInput({
|
||||
model : this.model,
|
||||
property : 'tags'
|
||||
});
|
||||
},
|
||||
|
||||
_onAfterSave : function () {
|
||||
this.targetCollection.add(this.model, { merge : true });
|
||||
vent.trigger(vent.Commands.CloseModalCommand);
|
||||
}
|
||||
});
|
||||
|
||||
AsModelBoundView.call(view);
|
||||
AsValidatedView.call(view);
|
||||
AsEditModalView.call(view);
|
||||
|
||||
return view;
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
{{#if id}}
|
||||
<h3>Edit Restriction</h3>
|
||||
{{else}}
|
||||
<h3>Add Restriction</h3>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="modal-body remotepath-mapping-modal">
|
||||
<div class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Must contain</label>
|
||||
|
||||
<div class="col-sm-1 col-sm-push-5 help-inline">
|
||||
<i class="icon-nd-form-info" title="The release must contain at least one of these terms (case insensitive)" />
|
||||
</div>
|
||||
|
||||
<div class="col-sm-5 col-sm-pull-1">
|
||||
<input type="text" name="required" class="form-control x-required"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Must not contain</label>
|
||||
|
||||
<div class="col-sm-1 col-sm-push-5 help-inline">
|
||||
<i class="icon-nd-form-info" title="The release will be rejected if it contains one or more of terms (case insensitive)" />
|
||||
</div>
|
||||
|
||||
<div class="col-sm-5 col-sm-pull-1">
|
||||
<input type="text" name="ignored" class="form-control x-ignored"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Tags</label>
|
||||
|
||||
<div class="col-sm-1 col-sm-push-5 help-inline">
|
||||
<i class="icon-nd-form-info" title="Restrictions will apply to series with more or more matching tags. Leave blank to apply to all series" />
|
||||
</div>
|
||||
|
||||
<div class="col-sm-5 col-sm-pull-1">
|
||||
<input type="text" class="form-control x-tags">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
{{#if id}}
|
||||
<button class="btn btn-danger pull-left x-delete">delete</button>
|
||||
{{/if}}
|
||||
|
||||
<button class="btn" data-dismiss="modal">cancel</button>
|
||||
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-primary x-save">save</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,30 @@
|
||||
'use strict';
|
||||
|
||||
define([
|
||||
'AppLayout',
|
||||
'marionette',
|
||||
'Settings/Indexers/Restriction/RestrictionEditView'
|
||||
], function (AppLayout, Marionette, EditView) {
|
||||
|
||||
return Marionette.ItemView.extend({
|
||||
template : 'Settings/Indexers/Restriction/RestrictionItemViewTemplate',
|
||||
className : 'row',
|
||||
|
||||
ui: {
|
||||
tags: '.x-tags'
|
||||
},
|
||||
|
||||
events: {
|
||||
'click .x-edit' : '_edit'
|
||||
},
|
||||
|
||||
initialize: function () {
|
||||
this.listenTo(this.model, 'sync', this.render);
|
||||
},
|
||||
|
||||
_edit: function() {
|
||||
var view = new EditView({ model: this.model, targetCollection: this.model.collection});
|
||||
AppLayout.modalRegion.show(view);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
<span class="col-sm-4">
|
||||
{{genericTagDisplay required 'label label-success'}}
|
||||
</span>
|
||||
<span class="col-sm-4">
|
||||
{{genericTagDisplay ignored 'label label-danger'}}
|
||||
</span>
|
||||
<span class="col-sm-3">
|
||||
{{tagDisplay tags}}
|
||||
</span>
|
||||
<span class="col-sm-1">
|
||||
<div class="pull-right"><i class="icon-nd-edit x-edit" title="" data-original-title="Edit"></i></div>
|
||||
</span>
|
||||
@@ -0,0 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
define([
|
||||
'jquery',
|
||||
'backbone.deepmodel'
|
||||
], function ($, DeepModel) {
|
||||
return DeepModel.DeepModel.extend({
|
||||
|
||||
});
|
||||
});
|
||||
@@ -127,3 +127,34 @@ li.save-and-add:hover {
|
||||
display : none;
|
||||
padding-right : 5px;
|
||||
}
|
||||
|
||||
.add-rule-setting-mapping {
|
||||
cursor : pointer;
|
||||
font-size : 14px;
|
||||
text-align : center;
|
||||
display : inline-block;
|
||||
padding : 2px 6px;
|
||||
|
||||
i {
|
||||
cursor : pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.rule-setting-list {
|
||||
|
||||
.rule-setting-header .row {
|
||||
font-weight : bold;
|
||||
line-height : 40px;
|
||||
}
|
||||
|
||||
.rows .row {
|
||||
line-height : 30px;
|
||||
border-top : 1px solid #ddd;
|
||||
vertical-align : middle;
|
||||
padding : 5px;
|
||||
|
||||
i {
|
||||
cursor : pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user