parent
2c52795822
commit
463d85e479
@ -0,0 +1,9 @@
|
|||||||
|
var ThingyAddCollectionView = require('../../ThingyAddCollectionView');
|
||||||
|
var ThingyHeaderGroupView = require('../../ThingyHeaderGroupView');
|
||||||
|
var AddItemView = require('./IndexerAddItemView');
|
||||||
|
|
||||||
|
module.exports = ThingyAddCollectionView.extend({
|
||||||
|
itemView : ThingyHeaderGroupView.extend({ itemView : AddItemView }),
|
||||||
|
itemViewContainer : '.add-indexer .items',
|
||||||
|
template : 'Settings/Indexers/Add/IndexerAddCollectionViewTemplate'
|
||||||
|
});
|
@ -0,0 +1,18 @@
|
|||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
|
<h3>Add Indexer</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="alert alert-info">
|
||||||
|
Radarr supports any indexer that uses the Newznab standard, as well as other indexers listed below.<br/>
|
||||||
|
For more information on the individual indexers, click on the info buttons.
|
||||||
|
</div>
|
||||||
|
<div class="add-indexer add-thingies">
|
||||||
|
<ul class="items"></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn" data-dismiss="modal">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,52 @@
|
|||||||
|
var _ = require('underscore');
|
||||||
|
var $ = require('jquery');
|
||||||
|
var AppLayout = require('../../../AppLayout');
|
||||||
|
var Marionette = require('marionette');
|
||||||
|
var EditView = require('../Edit/IndexerEditView');
|
||||||
|
|
||||||
|
module.exports = Marionette.ItemView.extend({
|
||||||
|
template : 'Settings/Indexers/Add/IndexerAddItemViewTemplate',
|
||||||
|
tagName : 'li',
|
||||||
|
className : 'add-thingy-item',
|
||||||
|
|
||||||
|
events : {
|
||||||
|
'click .x-preset' : '_addPreset',
|
||||||
|
'click' : '_add'
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize : function(options) {
|
||||||
|
this.targetCollection = options.targetCollection;
|
||||||
|
},
|
||||||
|
|
||||||
|
_addPreset : function(e) {
|
||||||
|
var presetName = $(e.target).closest('.x-preset').attr('data-id');
|
||||||
|
var presetData = _.where(this.model.get('presets'), { name : presetName })[0];
|
||||||
|
|
||||||
|
this.model.set(presetData);
|
||||||
|
|
||||||
|
this._openEdit();
|
||||||
|
},
|
||||||
|
|
||||||
|
_add : function(e) {
|
||||||
|
if ($(e.target).closest('.btn,.btn-group').length !== 0 && $(e.target).closest('.x-custom').length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._openEdit();
|
||||||
|
},
|
||||||
|
|
||||||
|
_openEdit : function() {
|
||||||
|
this.model.set({
|
||||||
|
id : undefined,
|
||||||
|
enableRss : this.model.get('supportsRss'),
|
||||||
|
enableSearch : this.model.get('supportsSearch')
|
||||||
|
});
|
||||||
|
|
||||||
|
var editView = new EditView({
|
||||||
|
model : this.model,
|
||||||
|
targetCollection : this.targetCollection
|
||||||
|
});
|
||||||
|
|
||||||
|
AppLayout.modalRegion.show(editView);
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,30 @@
|
|||||||
|
<div class="add-thingy">
|
||||||
|
<div>
|
||||||
|
{{implementationName}}
|
||||||
|
</div>
|
||||||
|
<div class="pull-right">
|
||||||
|
{{#if_gt presets.length compare=0}}
|
||||||
|
<button class="btn btn-xs btn-default x-custom">
|
||||||
|
Custom
|
||||||
|
</button>
|
||||||
|
<div class="btn-group">
|
||||||
|
<button class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
|
||||||
|
Presets
|
||||||
|
<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
{{#each presets}}
|
||||||
|
<li class="x-preset" data-id="{{name}}">
|
||||||
|
<a>{{name}}</a>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{/if_gt}}
|
||||||
|
{{#if infoLink}}
|
||||||
|
<a class="btn btn-xs btn-default x-info" href="{{infoLink}}">
|
||||||
|
<i class="icon-sonarr-form-info"/>
|
||||||
|
</a>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,39 @@
|
|||||||
|
var _ = require('underscore');
|
||||||
|
var AppLayout = require('../../../AppLayout');
|
||||||
|
var Backbone = require('backbone');
|
||||||
|
var SchemaCollection = require('../IndexerCollection');
|
||||||
|
var AddCollectionView = require('./IndexerAddCollectionView');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
open : function(collection) {
|
||||||
|
var schemaCollection = new SchemaCollection();
|
||||||
|
var originalUrl = schemaCollection.url;
|
||||||
|
schemaCollection.url = schemaCollection.url + '/schema';
|
||||||
|
schemaCollection.fetch();
|
||||||
|
schemaCollection.url = originalUrl;
|
||||||
|
|
||||||
|
var groupedSchemaCollection = new Backbone.Collection();
|
||||||
|
|
||||||
|
schemaCollection.on('sync', function() {
|
||||||
|
|
||||||
|
var groups = schemaCollection.groupBy(function(model, iterator) {
|
||||||
|
return model.get('protocol');
|
||||||
|
});
|
||||||
|
var modelCollection = _.map(groups, function(values, key, list) {
|
||||||
|
return {
|
||||||
|
"header" : key,
|
||||||
|
collection : values
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
groupedSchemaCollection.reset(modelCollection);
|
||||||
|
});
|
||||||
|
|
||||||
|
var view = new AddCollectionView({
|
||||||
|
collection : groupedSchemaCollection,
|
||||||
|
targetCollection : collection
|
||||||
|
});
|
||||||
|
|
||||||
|
AppLayout.modalRegion.show(view);
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,19 @@
|
|||||||
|
var vent = require('vent');
|
||||||
|
var Marionette = require('marionette');
|
||||||
|
|
||||||
|
module.exports = Marionette.ItemView.extend({
|
||||||
|
template : 'Settings/Indexers/Delete/IndexerDeleteViewTemplate',
|
||||||
|
|
||||||
|
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 Indexer</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p>Are you sure you want to delete '{{name}}'?</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,122 @@
|
|||||||
|
var _ = require('underscore');
|
||||||
|
var $ = require('jquery');
|
||||||
|
var vent = require('vent');
|
||||||
|
var Marionette = require('marionette');
|
||||||
|
var DeleteView = require('../Delete/IndexerDeleteView');
|
||||||
|
var AsModelBoundView = require('../../../Mixins/AsModelBoundView');
|
||||||
|
var AsValidatedView = require('../../../Mixins/AsValidatedView');
|
||||||
|
var AsEditModalView = require('../../../Mixins/AsEditModalView');
|
||||||
|
require('../../../Form/FormBuilder');
|
||||||
|
require('../../../Mixins/AutoComplete');
|
||||||
|
require('bootstrap');
|
||||||
|
|
||||||
|
var view = Marionette.ItemView.extend({
|
||||||
|
template : 'Settings/Indexers/Edit/IndexerEditViewTemplate',
|
||||||
|
|
||||||
|
events : {
|
||||||
|
'click .x-back' : '_back',
|
||||||
|
'click .x-captcha-refresh' : '_onRefreshCaptcha'
|
||||||
|
},
|
||||||
|
|
||||||
|
_deleteView : DeleteView,
|
||||||
|
|
||||||
|
initialize : function(options) {
|
||||||
|
this.targetCollection = options.targetCollection;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onAfterSave : function() {
|
||||||
|
this.targetCollection.add(this.model, { merge : true });
|
||||||
|
vent.trigger(vent.Commands.CloseModalCommand);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onAfterSaveAndAdd : function() {
|
||||||
|
this.targetCollection.add(this.model, { merge : true });
|
||||||
|
|
||||||
|
require('../Add/IndexerSchemaModal').open(this.targetCollection);
|
||||||
|
},
|
||||||
|
|
||||||
|
_back : function() {
|
||||||
|
if (this.model.isNew()) {
|
||||||
|
this.model.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
require('../Add/IndexerSchemaModal').open(this.targetCollection);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onRefreshCaptcha : function(event) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var target = $(event.target).parents('.input-group');
|
||||||
|
|
||||||
|
this.ui.indicator.show();
|
||||||
|
|
||||||
|
this.model.requestAction("checkCaptcha")
|
||||||
|
.then(function(result) {
|
||||||
|
if (!result.captchaRequest) {
|
||||||
|
self.model.setFieldValue('CaptchaToken', '');
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self._showCaptcha(target, result.captchaRequest);
|
||||||
|
})
|
||||||
|
.always(function() {
|
||||||
|
self.ui.indicator.hide();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_showCaptcha : function(target, captchaRequest) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var widget = $('<div class="g-recaptcha"></div>').insertAfter(target);
|
||||||
|
|
||||||
|
return this._loadRecaptchaWidget(widget[0], captchaRequest.siteKey, captchaRequest.secretToken)
|
||||||
|
.then(function(captchaResponse) {
|
||||||
|
target.parents('.form-group').removeAllErrors();
|
||||||
|
widget.remove();
|
||||||
|
|
||||||
|
var queryParams = {
|
||||||
|
responseUrl : captchaRequest.responseUrl,
|
||||||
|
ray : captchaRequest.ray,
|
||||||
|
captchaResponse: captchaResponse
|
||||||
|
};
|
||||||
|
|
||||||
|
return self.model.requestAction("getCaptchaCookie", queryParams);
|
||||||
|
})
|
||||||
|
.then(function(response) {
|
||||||
|
self.model.setFieldValue('CaptchaToken', response.captchaToken);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_loadRecaptchaWidget : function(widget, sitekey, stoken) {
|
||||||
|
var promise = $.Deferred();
|
||||||
|
|
||||||
|
var renderWidget = function() {
|
||||||
|
window.grecaptcha.render(widget, {
|
||||||
|
'sitekey' : sitekey,
|
||||||
|
'stoken' : stoken,
|
||||||
|
'callback' : promise.resolve
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (window.grecaptcha) {
|
||||||
|
renderWidget();
|
||||||
|
} else {
|
||||||
|
window.grecaptchaLoadCallback = function() {
|
||||||
|
delete window.grecaptchaLoadCallback;
|
||||||
|
renderWidget();
|
||||||
|
};
|
||||||
|
|
||||||
|
$.getScript('https://www.google.com/recaptcha/api.js?onload=grecaptchaLoadCallback&render=explicit')
|
||||||
|
.fail(function() { promise.reject(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AsModelBoundView.call(view);
|
||||||
|
AsValidatedView.call(view);
|
||||||
|
AsEditModalView.call(view);
|
||||||
|
|
||||||
|
module.exports = view;
|
@ -0,0 +1,92 @@
|
|||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" aria-hidden="true" data-dismiss="modal">×</button>
|
||||||
|
{{#if id}}
|
||||||
|
<h3>Edit - {{implementationName}}</h3>
|
||||||
|
{{else}}
|
||||||
|
<h3>Add - {{implementationName}}</h3>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
<div class="modal-body indexer-modal">
|
||||||
|
<div class="form-horizontal">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">Name</label>
|
||||||
|
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<input type="text" name="name" class="form-control"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">Enable RSS Sync</label>
|
||||||
|
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<div class="input-group">
|
||||||
|
<label class="checkbox toggle well">
|
||||||
|
<input type="checkbox" name="enableRss" {{#unless supportsRss}}disabled="disabled"{{/unless}}/>
|
||||||
|
<p>
|
||||||
|
<span>Yes</span>
|
||||||
|
<span>No</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="btn btn-primary slide-button"/>
|
||||||
|
</label>
|
||||||
|
{{#unless supportsRss}}
|
||||||
|
<span class="help-inline-checkbox">
|
||||||
|
<i class="icon-sonarr-form-warning" title="" data-original-title="RSS is not supported with this indexer"></i>
|
||||||
|
</span>
|
||||||
|
{{/unless}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">Enable Search</label>
|
||||||
|
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<div class="input-group">
|
||||||
|
<label class="checkbox toggle well">
|
||||||
|
|
||||||
|
<input type="checkbox" name="enableSearch" {{#unless supportsSearch}}disabled="disabled"{{/unless}}/>
|
||||||
|
<p>
|
||||||
|
<span>Yes</span>
|
||||||
|
<span>No</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="btn btn-primary slide-button"/>
|
||||||
|
</label>
|
||||||
|
{{#unless supportsSearch}}
|
||||||
|
<span class="help-inline-checkbox">
|
||||||
|
<i class="icon-sonarr-form-warning" title="" data-original-title="Search is not supported with this indexer"></i>
|
||||||
|
</span>
|
||||||
|
{{/unless}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{formBuilder}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
{{#if id}}
|
||||||
|
<button class="btn btn-danger pull-left x-delete">Delete</button>
|
||||||
|
{{else}}
|
||||||
|
<button class="btn pull-left x-back">Back</button>
|
||||||
|
{{/if}}
|
||||||
|
<span class="indicator x-indicator"><i class="icon-sonarr-spinner fa-spin"></i></span>
|
||||||
|
<button class="btn x-test">test <i class="x-test-icon icon-sonarr-test"/></button>
|
||||||
|
<button class="btn" data-dismiss="modal">Cancel</button>
|
||||||
|
|
||||||
|
<div class="btn-group">
|
||||||
|
<button class="btn btn-primary x-save">Save</button>
|
||||||
|
<button class="btn btn-icon-only btn-primary dropdown-toggle" data-toggle="dropdown">
|
||||||
|
<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li class="save-and-add x-save-and-add">
|
||||||
|
save and add
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,25 @@
|
|||||||
|
var Marionette = require('marionette');
|
||||||
|
var ItemView = require('./IndexerItemView');
|
||||||
|
var SchemaModal = require('./Add/IndexerSchemaModal');
|
||||||
|
|
||||||
|
module.exports = Marionette.CompositeView.extend({
|
||||||
|
itemView : ItemView,
|
||||||
|
itemViewContainer : '.indexer-list',
|
||||||
|
template : 'Settings/Indexers/IndexerCollectionViewTemplate',
|
||||||
|
|
||||||
|
ui : {
|
||||||
|
'addCard' : '.x-add-card'
|
||||||
|
},
|
||||||
|
|
||||||
|
events : {
|
||||||
|
'click .x-add-card' : '_openSchemaModal'
|
||||||
|
},
|
||||||
|
|
||||||
|
appendHtml : function(collectionView, itemView, index) {
|
||||||
|
collectionView.ui.addCard.parent('li').before(itemView.el);
|
||||||
|
},
|
||||||
|
|
||||||
|
_openSchemaModal : function() {
|
||||||
|
SchemaModal.open(this.collection);
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,16 @@
|
|||||||
|
<fieldset>
|
||||||
|
<legend>Indexers</legend>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<ul class="indexer-list thingies">
|
||||||
|
<li>
|
||||||
|
<div class="indexer-item thingy add-card x-add-card">
|
||||||
|
<span class="center well">
|
||||||
|
<i class="icon-sonarr-add"/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
@ -0,0 +1,24 @@
|
|||||||
|
var AppLayout = require('../../AppLayout');
|
||||||
|
var Marionette = require('marionette');
|
||||||
|
var EditView = require('./Edit/IndexerEditView');
|
||||||
|
|
||||||
|
module.exports = Marionette.ItemView.extend({
|
||||||
|
template : 'Settings/Indexers/IndexerItemViewTemplate',
|
||||||
|
tagName : 'li',
|
||||||
|
|
||||||
|
events : {
|
||||||
|
'click' : '_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,27 @@
|
|||||||
|
<div class="indexer-item thingy">
|
||||||
|
<div>
|
||||||
|
<h3>{{name}}</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="settings">
|
||||||
|
{{#if supportsRss}}
|
||||||
|
{{#if enableRss}}
|
||||||
|
<span class="label label-success">RSS</span>
|
||||||
|
{{else}}
|
||||||
|
<span class="label label-default">RSS</span>
|
||||||
|
{{/if}}
|
||||||
|
{{else}}
|
||||||
|
<span class="label label-default label-disabled">RSS</span>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if supportsSearch}}
|
||||||
|
{{#if enableSearch}}
|
||||||
|
<span class="label label-success">Search</span>
|
||||||
|
{{else}}
|
||||||
|
<span class="label label-default">Search</span>
|
||||||
|
{{/if}}
|
||||||
|
{{else}}
|
||||||
|
<span class="label label-default label-disabled">Search</span>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,30 @@
|
|||||||
|
var Marionette = require('marionette');
|
||||||
|
var IndexerCollection = require('./IndexerCollection');
|
||||||
|
var CollectionView = require('./IndexerCollectionView');
|
||||||
|
var OptionsView = require('./Options/IndexerOptionsView');
|
||||||
|
var RestrictionCollection = require('./Restriction/RestrictionCollection');
|
||||||
|
var RestrictionCollectionView = require('./Restriction/RestrictionCollectionView');
|
||||||
|
|
||||||
|
module.exports = Marionette.Layout.extend({
|
||||||
|
template : 'Settings/Indexers/IndexerLayoutTemplate',
|
||||||
|
|
||||||
|
regions : {
|
||||||
|
indexers : '#x-indexers-region',
|
||||||
|
indexerOptions : '#x-indexer-options-region',
|
||||||
|
restriction : '#x-restriction-region'
|
||||||
|
},
|
||||||
|
|
||||||
|
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 }));
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +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>
|
@ -0,0 +1,13 @@
|
|||||||
|
var Backbone = require('backbone');
|
||||||
|
var NetImportModel = require('./NetImportModel');
|
||||||
|
|
||||||
|
module.exports = Backbone.Collection.extend({
|
||||||
|
model : NetImportModel,
|
||||||
|
url : window.NzbDrone.ApiRoot + '/netimport',
|
||||||
|
|
||||||
|
comparator : function(left, right, collection) {
|
||||||
|
var result = 0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,3 @@
|
|||||||
|
var ProviderSettingsModelBase = require('../ProviderSettingsModelBase');
|
||||||
|
|
||||||
|
module.exports = ProviderSettingsModelBase.extend({});
|
@ -0,0 +1,7 @@
|
|||||||
|
var SettingsModelBase = require('../SettingsModelBase');
|
||||||
|
|
||||||
|
module.exports = SettingsModelBase.extend({
|
||||||
|
url : window.NzbDrone.ApiRoot + '/config/netimport',
|
||||||
|
successMessage : 'Net Import settings saved',
|
||||||
|
errorMessage : 'Failed to save net import settings'
|
||||||
|
});
|
@ -0,0 +1,12 @@
|
|||||||
|
var Marionette = require('marionette');
|
||||||
|
var AsModelBoundView = require('../../../Mixins/AsModelBoundView');
|
||||||
|
var AsValidatedView = require('../../../Mixins/AsValidatedView');
|
||||||
|
|
||||||
|
var view = Marionette.ItemView.extend({
|
||||||
|
template : 'Settings/Indexers/Options/IndexerOptionsViewTemplate'
|
||||||
|
});
|
||||||
|
|
||||||
|
AsModelBoundView.call(view);
|
||||||
|
AsValidatedView.call(view);
|
||||||
|
|
||||||
|
module.exports = view;
|
@ -0,0 +1,40 @@
|
|||||||
|
<fieldset>
|
||||||
|
<legend>Options</legend>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">Minimum Age</label>
|
||||||
|
|
||||||
|
<div class="col-sm-1 col-sm-push-2 help-inline">
|
||||||
|
<i class="icon-sonarr-form-info" title="Usenet only: Minimum age in minutes of NZBs before they are grabbed. Use this to give new releases time to propagate to your usenet provider."/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-2 col-sm-pull-1">
|
||||||
|
<input type="number" min="0" name="minimumAge" class="form-control"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">Retention</label>
|
||||||
|
|
||||||
|
<div class="col-sm-1 col-sm-push-2 help-inline">
|
||||||
|
<i class="icon-sonarr-form-info" title="Usenet only: Set to zero to set to unlimited"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-2 col-sm-pull-1">
|
||||||
|
<input type="number" min="0" name="retention" class="form-control"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group advanced-setting">
|
||||||
|
<label class="col-sm-3 control-label">RSS Sync Interval</label>
|
||||||
|
|
||||||
|
<div class="col-sm-1 col-sm-push-2 help-inline">
|
||||||
|
<i class="icon-sonarr-form-warning" title="This will apply to all indexers, please follow the rules set forth by them"/>
|
||||||
|
<i class="icon-sonarr-form-info" title="Interval in minutes. Set to zero to disable (this will stop all automatic release grabbing)"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-2 col-sm-pull-1">
|
||||||
|
<input type="number" name="rssSyncInterval" class="form-control" min="0" max="120"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
@ -0,0 +1,7 @@
|
|||||||
|
var Backbone = require('backbone');
|
||||||
|
var RestrictionModel = require('./RestrictionModel');
|
||||||
|
|
||||||
|
module.exports = Backbone.Collection.extend({
|
||||||
|
model : RestrictionModel,
|
||||||
|
url : window.NzbDrone.ApiRoot + '/Restriction'
|
||||||
|
});
|
@ -0,0 +1,26 @@
|
|||||||
|
var AppLayout = require('../../../AppLayout');
|
||||||
|
var Marionette = require('marionette');
|
||||||
|
var RestrictionItemView = require('./RestrictionItemView');
|
||||||
|
var EditView = require('./RestrictionEditView');
|
||||||
|
require('../../../Tags/TagHelpers');
|
||||||
|
require('bootstrap');
|
||||||
|
|
||||||
|
module.exports = 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-sonarr-add x-add" title="Add new restriction" />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
@ -0,0 +1,19 @@
|
|||||||
|
var vent = require('vent');
|
||||||
|
var Marionette = require('marionette');
|
||||||
|
|
||||||
|
module.exports = 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 this restriction?</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,55 @@
|
|||||||
|
var _ = require('underscore');
|
||||||
|
var vent = require('vent');
|
||||||
|
var AppLayout = require('../../../AppLayout');
|
||||||
|
var Marionette = require('marionette');
|
||||||
|
var DeleteView = require('./RestrictionDeleteView');
|
||||||
|
var CommandController = require('../../../Commands/CommandController');
|
||||||
|
var AsModelBoundView = require('../../../Mixins/AsModelBoundView');
|
||||||
|
var AsValidatedView = require('../../../Mixins/AsValidatedView');
|
||||||
|
var AsEditModalView = require('../../../Mixins/AsEditModalView');
|
||||||
|
require('../../../Mixins/TagInput');
|
||||||
|
require('bootstrap');
|
||||||
|
require('bootstrap.tagsinput');
|
||||||
|
|
||||||
|
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);
|
||||||
|
module.exports = 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-sonarr-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-sonarr-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-sonarr-form-info" title="Restrictions will apply to series with one 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,28 @@
|
|||||||
|
var AppLayout = require('../../../AppLayout');
|
||||||
|
var Marionette = require('marionette');
|
||||||
|
var EditView = require('./RestrictionEditView');
|
||||||
|
|
||||||
|
module.exports = 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 @@
|
|||||||
|
<div class="col-sm-4">
|
||||||
|
{{genericTagDisplay required 'label label-success'}}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
{{genericTagDisplay ignored 'label label-danger'}}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-3">
|
||||||
|
{{tagDisplay tags}}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-1">
|
||||||
|
<div class="pull-right"><i class="icon-sonarr-edit x-edit" title="" data-original-title="Edit"></i></div>
|
||||||
|
</div>
|
@ -0,0 +1,4 @@
|
|||||||
|
var $ = require('jquery');
|
||||||
|
var DeepModel = require('backbone.deepmodel');
|
||||||
|
|
||||||
|
module.exports = DeepModel.extend({});
|
@ -0,0 +1,33 @@
|
|||||||
|
@import "../../Shared/Styles/clickable.less";
|
||||||
|
|
||||||
|
.indexer-list {
|
||||||
|
li {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.indexer-item {
|
||||||
|
|
||||||
|
.clickable;
|
||||||
|
|
||||||
|
width: 290px;
|
||||||
|
height: 90px;
|
||||||
|
padding: 10px 15px;
|
||||||
|
|
||||||
|
&.add-card {
|
||||||
|
.center {
|
||||||
|
margin-top: -3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-overflow {
|
||||||
|
overflow-y: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-indexer {
|
||||||
|
li.add-thingy-item {
|
||||||
|
width: 33%;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue