1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2024-12-16 11:37:58 +02:00

Fixed: Add tag when text box loses focus

This commit is contained in:
Mark McDowall 2014-12-02 17:18:17 -08:00
parent be81bf322a
commit cd1d34a0f2
17 changed files with 373 additions and 49 deletions

View File

@ -100,6 +100,7 @@
<Compile Include="Extensions\Pipelines\CorsPipeline.cs" /> <Compile Include="Extensions\Pipelines\CorsPipeline.cs" />
<Compile Include="Profiles\Delay\DelayProfileModule.cs" /> <Compile Include="Profiles\Delay\DelayProfileModule.cs" />
<Compile Include="Profiles\Delay\DelayProfileResource.cs" /> <Compile Include="Profiles\Delay\DelayProfileResource.cs" />
<Compile Include="Profiles\Delay\DelayProfileValidator.cs" />
<Compile Include="RemotePathMappings\RemotePathMappingModule.cs" /> <Compile Include="RemotePathMappings\RemotePathMappingModule.cs" />
<Compile Include="RemotePathMappings\RemotePathMappingResource.cs" /> <Compile Include="RemotePathMappings\RemotePathMappingResource.cs" />
<Compile Include="Config\UiConfigModule.cs" /> <Compile Include="Config\UiConfigModule.cs" />

View File

@ -24,6 +24,9 @@ public DelayProfileModule(IDelayProfileService delayProfileService, DelayProfile
SharedValidator.RuleFor(d => d.Tags).NotEmpty().When(d => d.Id != 1); SharedValidator.RuleFor(d => d.Tags).NotEmpty().When(d => d.Id != 1);
SharedValidator.RuleFor(d => d.Tags).EmptyCollection().When(d => d.Id == 1); SharedValidator.RuleFor(d => d.Tags).EmptyCollection().When(d => d.Id == 1);
SharedValidator.RuleFor(d => d.Tags).SetValidator(tagInUseValidator); SharedValidator.RuleFor(d => d.Tags).SetValidator(tagInUseValidator);
SharedValidator.RuleFor(d => d.UsenetDelay).GreaterThanOrEqualTo(0);
SharedValidator.RuleFor(d => d.TorrentDelay).GreaterThanOrEqualTo(0);
SharedValidator.RuleFor(d => d.Id).SetValidator(new DelayProfileValidator());
} }
private int Create(DelayProfileResource resource) private int Create(DelayProfileResource resource)

View File

@ -6,6 +6,8 @@ namespace NzbDrone.Api.Profiles.Delay
{ {
public class DelayProfileResource : RestResource public class DelayProfileResource : RestResource
{ {
public bool EnableUsenet { get; set; }
public bool EnableTorrent { get; set; }
public DownloadProtocol PreferredProtocol { get; set; } public DownloadProtocol PreferredProtocol { get; set; }
public int UsenetDelay { get; set; } public int UsenetDelay { get; set; }
public int TorrentDelay { get; set; } public int TorrentDelay { get; set; }

View File

@ -0,0 +1,27 @@
using FluentValidation.Validators;
using NzbDrone.Core.Profiles.Delay;
using Omu.ValueInjecter;
namespace NzbDrone.Api.Profiles.Delay
{
public class DelayProfileValidator : PropertyValidator
{
public DelayProfileValidator()
: base("Usenet or Torrent must be enabled")
{
}
protected override bool IsValid(PropertyValidatorContext context)
{
var delayProfile = new DelayProfile();
delayProfile.InjectFrom(context.ParentContext.InstanceToValidate);
if (!delayProfile.EnableUsenet && !delayProfile.EnableTorrent)
{
return false;
}
return true;
}
}
}

View File

@ -1,21 +1,20 @@
using System; using System.Collections.Generic;
using System.Linq; using System.Linq;
using FluentAssertions; using FluentAssertions;
using FluentMigrator;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Datastore.Migration; using NzbDrone.Core.Datastore.Migration;
using NzbDrone.Core.Datastore.Migration.Framework;
using NzbDrone.Core.Indexers; using NzbDrone.Core.Indexers;
using NzbDrone.Core.Profiles.Delay; using NzbDrone.Core.Profiles.Delay;
using NzbDrone.Core.Tags;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Test.Datastore.Migration namespace NzbDrone.Core.Test.Datastore.Migration
{ {
[TestFixture] [TestFixture]
public class delay_profileFixture : MigrationTest<delay_profile> public class delay_profileFixture : MigrationTest<delay_profile>
{ {
[TestCase] [Test]
public void should_migrate_old_delays() public void should_migrate_old_delays()
{ {
WithTestDb(c => WithTestDb(c =>
@ -27,6 +26,7 @@ public void should_migrate_old_delays()
Cutoff = "{}", Cutoff = "{}",
Items = "{}" Items = "{}"
}); });
c.Insert.IntoTable("Profiles").Row(new c.Insert.IntoTable("Profiles").Row(new
{ {
GrabDelay = 2, GrabDelay = 2,
@ -36,17 +36,72 @@ public void should_migrate_old_delays()
}); });
}); });
var allProfiles = Mocker.Resolve<DelayProfileRepository>().All().ToList(); var allProfiles = Mocker.Resolve<DelayProfileRepository>().All().ToList();
allProfiles.Should().HaveCount(3); allProfiles.Should().HaveCount(3);
allProfiles.Should().OnlyContain(c => c.PreferredProtocol == DownloadProtocol.Usenet); allProfiles.Should().OnlyContain(c => c.PreferredProtocol == DownloadProtocol.Usenet);
allProfiles.Should().OnlyContain(c => c.TorrentDelay == 0); allProfiles.Should().OnlyContain(c => c.TorrentDelay == 0);
allProfiles.Should().Contain(c => c.UsenetDelay == 60); allProfiles.Should().Contain(c => c.UsenetDelay == 60);
allProfiles.Should().Contain(c => c.UsenetDelay == 120); allProfiles.Should().Contain(c => c.UsenetDelay == 120);
}
[Test]
public void should_create_tag_for_delay_profile()
{
WithTestDb(c =>
c.Insert.IntoTable("Profiles").Row(new
{
GrabDelay = 1,
Name = "OneHour",
Cutoff = "{}",
Items = "{}"
})
);
var tags = Mocker.Resolve<TagRepository>().All().ToList();
tags.Should().HaveCount(1);
tags.First().Label.Should().Be("delay-60");
}
[Test]
public void should_add_tag_to_series_that_had_a_profile_with_delay_attached()
{
WithTestDb(c =>
{
c.Insert.IntoTable("Profiles").Row(new
{
GrabDelay = 1,
Name = "OneHour",
Cutoff = "{}",
Items = "{}"
});
c.Insert.IntoTable("Series").Row(new
{
TvdbId = 0,
TvRageId = 0,
Title = "Series",
TitleSlug = "series",
CleanTitle = "series",
Status = 0,
Images = "[]",
Path = @"C:\Test\Series",
Monitored = 1,
SeasonFolder = 1,
RunTime = 0,
SeriesType = 0,
UseSceneNumbering = 0,
Tags = "[1]"
});
});
var tag = Mocker.Resolve<TagRepository>().All().ToList().First();
var series = Mocker.Resolve<SeriesRepository>().All().ToList();
series.Should().HaveCount(1);
series.First().Tags.Should().HaveCount(1);
series.First().Tags.First().Should().Be(tag.Id);
} }
} }
} }

View File

@ -0,0 +1,75 @@
using System.Collections.Generic;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Profiles.Delay;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Test.DecisionEngineTests
{
[TestFixture]
public class ProtocolSpecificationFixture : CoreTest<ProtocolSpecification>
{
private RemoteEpisode _remoteEpisode;
private DelayProfile _delayProfile;
[SetUp]
public void Setup()
{
_remoteEpisode = new RemoteEpisode();
_remoteEpisode.Release = new ReleaseInfo();
_remoteEpisode.Series = new Series();
_delayProfile = new DelayProfile();
Mocker.GetMock<IDelayProfileService>()
.Setup(s => s.BestForTags(It.IsAny<HashSet<int>>()))
.Returns(_delayProfile);
}
private void GivenProtocol(DownloadProtocol downloadProtocol)
{
_remoteEpisode.Release.DownloadProtocol = downloadProtocol;
}
[Test]
public void should_be_true_if_usenet_and_usenet_is_enabled()
{
GivenProtocol(DownloadProtocol.Usenet);
_delayProfile.EnableUsenet = true;
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().Be(true);
}
[Test]
public void should_be_true_if_torrent_and_torrent_is_enabled()
{
GivenProtocol(DownloadProtocol.Torrent);
_delayProfile.EnableTorrent = true;
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().Be(true);
}
[Test]
public void should_be_false_if_usenet_and_usenet_is_disabled()
{
GivenProtocol(DownloadProtocol.Usenet);
_delayProfile.EnableUsenet = false;
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().Be(false);
}
[Test]
public void should_be_false_if_torrent_and_torrent_is_disabled()
{
GivenProtocol(DownloadProtocol.Torrent);
_delayProfile.EnableTorrent = false;
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().Be(false);
}
}
}

View File

@ -124,6 +124,7 @@
<Compile Include="Datastore\SqliteSchemaDumperTests\SqliteSchemaDumperFixture.cs" /> <Compile Include="Datastore\SqliteSchemaDumperTests\SqliteSchemaDumperFixture.cs" />
<Compile Include="DecisionEngineTests\AcceptableSizeSpecificationFixture.cs" /> <Compile Include="DecisionEngineTests\AcceptableSizeSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\AnimeVersionUpgradeSpecificationFixture.cs" /> <Compile Include="DecisionEngineTests\AnimeVersionUpgradeSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\ProtocolSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\CutoffSpecificationFixture.cs" /> <Compile Include="DecisionEngineTests\CutoffSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\DownloadDecisionMakerFixture.cs" /> <Compile Include="DecisionEngineTests\DownloadDecisionMakerFixture.cs" />
<Compile Include="DecisionEngineTests\HistorySpecificationFixture.cs" /> <Compile Include="DecisionEngineTests\HistorySpecificationFixture.cs" />

View File

@ -3,7 +3,6 @@
using System.Data; using System.Data;
using System.Linq; using System.Linq;
using FluentMigrator; using FluentMigrator;
using NzbDrone.Common;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Common.Serializer; using NzbDrone.Common.Serializer;
using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.Datastore.Migration.Framework;
@ -16,15 +15,18 @@ public class delay_profile : NzbDroneMigrationBase
protected override void MainDbUpgrade() protected override void MainDbUpgrade()
{ {
Create.TableForModel("DelayProfiles") Create.TableForModel("DelayProfiles")
.WithColumn("EnableUsenet").AsBoolean().NotNullable()
.WithColumn("EnableTorrent").AsBoolean().NotNullable()
.WithColumn("PreferredProtocol").AsInt32().NotNullable() .WithColumn("PreferredProtocol").AsInt32().NotNullable()
.WithColumn("UsenetDelay").AsInt32().NotNullable() .WithColumn("UsenetDelay").AsInt32().NotNullable()
.WithColumn("TorrentDelay").AsInt32().NotNullable() .WithColumn("TorrentDelay").AsInt32().NotNullable()
.WithColumn("Order").AsInt32().NotNullable() .WithColumn("Order").AsInt32().NotNullable()
.WithColumn("Tags").AsString().NotNullable(); .WithColumn("Tags").AsString().NotNullable();
Insert.IntoTable("DelayProfiles").Row(new Insert.IntoTable("DelayProfiles").Row(new
{ {
EnableUsenet = 1,
EnableTorrent = 1,
PreferredProtocol = 1, PreferredProtocol = 1,
UsenetDelay = 0, UsenetDelay = 0,
TorrentDelay = 0, TorrentDelay = 0,
@ -55,7 +57,7 @@ private void ConvertProfile(IDbConnection conn, IDbTransaction tran)
using (IDbCommand insertDelayProfileCmd = conn.CreateCommand()) using (IDbCommand insertDelayProfileCmd = conn.CreateCommand())
{ {
insertDelayProfileCmd.Transaction = tran; insertDelayProfileCmd.Transaction = tran;
insertDelayProfileCmd.CommandText = "INSERT INTO DelayProfiles (PreferredProtocol, TorrentDelay, UsenetDelay, [Order], Tags) VALUES (1, 0, ?, ?, ?)"; insertDelayProfileCmd.CommandText = "INSERT INTO DelayProfiles (EnableUsenet, EnableTorrent, PreferredProtocol, TorrentDelay, UsenetDelay, [Order], Tags) VALUES (1, 1, 1, 0, ?, ?, ?)";
insertDelayProfileCmd.AddParameter(profile.GrabDelay); insertDelayProfileCmd.AddParameter(profile.GrabDelay);
insertDelayProfileCmd.AddParameter(order); insertDelayProfileCmd.AddParameter(order);
insertDelayProfileCmd.AddParameter(tags); insertDelayProfileCmd.AddParameter(tags);

View File

@ -0,0 +1,45 @@
using NLog;
using NzbDrone.Core.Download.Pending;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Profiles.Delay;
namespace NzbDrone.Core.DecisionEngine.Specifications
{
public class ProtocolSpecification : IDecisionEngineSpecification
{
private readonly IPendingReleaseService _pendingReleaseService;
private readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
private readonly IDelayProfileService _delayProfileService;
private readonly Logger _logger;
public ProtocolSpecification(IDelayProfileService delayProfileService,
Logger logger)
{
_delayProfileService = delayProfileService;
_logger = logger;
}
public RejectionType Type { get { return RejectionType.Temporary; } }
public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
{
var delayProfile = _delayProfileService.BestForTags(subject.Series.Tags);
if (subject.Release.DownloadProtocol == DownloadProtocol.Usenet && !delayProfile.EnableUsenet)
{
_logger.Debug("[{0}] Usenet is not enabled for this series", subject.Release.Title);
return Decision.Reject("Usenet is not enabled for this series");
}
if (subject.Release.DownloadProtocol == DownloadProtocol.Torrent && !delayProfile.EnableTorrent)
{
_logger.Debug("[{0}] Torrent is not enabled for this series", subject.Release.Title);
return Decision.Reject("Torrent is not enabled for this series");
}
return Decision.Accept();
}
}
}

View File

@ -261,6 +261,7 @@
<Compile Include="DecisionEngine\Specifications\BlacklistSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\BlacklistSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\AnimeVersionUpgradeSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\AnimeVersionUpgradeSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\CutoffSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\CutoffSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\ProtocolSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\LanguageSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\LanguageSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\NotInQueueSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\NotInQueueSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\ReleaseRestrictionsSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\ReleaseRestrictionsSpecification.cs" />

View File

@ -6,6 +6,8 @@ namespace NzbDrone.Core.Profiles.Delay
{ {
public class DelayProfile : ModelBase public class DelayProfile : ModelBase
{ {
public bool EnableUsenet { get; set; }
public bool EnableTorrent { get; set; }
public DownloadProtocol PreferredProtocol { get; set; } public DownloadProtocol PreferredProtocol { get; set; }
public int UsenetDelay { get; set; } public int UsenetDelay { get; set; }
public int TorrentDelay { get; set; } public int TorrentDelay { get; set; }

View File

@ -1,7 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using FluentValidation.Validators; using FluentValidation.Validators;
using NzbDrone.Common;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using Omu.ValueInjecter; using Omu.ValueInjecter;

View File

@ -26,22 +26,27 @@ define(
if (existing) { if (existing) {
originalAdd.call(this, existing, dontPushVal); originalAdd.call(this, existing, dontPushVal);
return;
} }
var newTag = new TagModel(); else {
newTag.set({ label: item.toLowerCase() }); var newTag = new TagModel();
TagCollection.add(newTag); newTag.set({ label: item.toLowerCase() });
TagCollection.add(newTag);
newTag.save().done(function () { newTag.save().done(function () {
item = newTag.toJSON(); item = newTag.toJSON();
originalAdd.call(self, item, dontPushVal); originalAdd.call(self, item, dontPushVal);
}); });
}
} }
else { else {
originalAdd.call(this, item, dontPushVal); originalAdd.call(this, item, dontPushVal);
} }
if (this.options.tag) {
self.$input.typeahead('val', '');
}
}; };
$.fn.tagsinput.Constructor.prototype.remove = function (item, dontPushVal) { $.fn.tagsinput.Constructor.prototype.remove = function (item, dontPushVal) {
@ -69,6 +74,11 @@ define(
} }
}); });
self.$input.on('focusout', function () {
self.add(self.$input.val());
self.$input.val('');
});
originalBuild.call(this, options); originalBuild.call(this, options);
}; };

View File

@ -1,29 +1,47 @@
 <div class="col-sm-2">  <div class="col-sm-2">
{{TitleCase preferredProtocol}} {{#if enableUsenet}}
{{#if enableTorrent}}
{{#if_eq preferredProtocol compare="usenet"}}
Prefer Usenet
{{else}}
Prefer Torrent
{{/if_eq}}
{{else}}
Only Usenet
{{/if}}
{{else}}
Only Torrent
{{/if}}
</div> </div>
<div class="col-sm-2"> <div class="col-sm-2">
{{#if enableUsenet}}
{{#if_eq usenetDelay compare="0"}} {{#if_eq usenetDelay compare="0"}}
No delay No delay
{{else}}
{{#if_eq usenetDelay compare="1"}}
1 minute
{{else}} {{else}}
{{usenetDelay}} minutes {{#if_eq usenetDelay compare="1"}}
1 minute
{{else}}
{{usenetDelay}} minutes
{{/if_eq}}
{{/if_eq}} {{/if_eq}}
{{/if_eq}} {{else}}
-
{{/if}}
</div> </div>
<div class="col-sm-2"> <div class="col-sm-2">
{{#if_eq torrentDelay compare="0"}} {{#if enableTorrent}}
No delay {{#if_eq torrentDelay compare="0"}}
{{else}} No delay
{{#if_eq torrentDelay compare="1"}}
1 minute
{{else}} {{else}}
{{torrentDelay}} minutes {{#if_eq torrentDelay compare="1"}}
1 minute
{{else}}
{{torrentDelay}} minutes
{{/if_eq}}
{{/if_eq}} {{/if_eq}}
{{/if_eq}} {{else}}
-
{{/if}}
</div> </div>
<div class="col-sm-5"> <div class="col-sm-5">
{{tagDisplay tags}} {{tagDisplay tags}}

View File

@ -5,7 +5,7 @@
<div class="rule-setting-list"> <div class="rule-setting-list">
<div class="rule-setting-header x-header hidden-xs"> <div class="rule-setting-header x-header hidden-xs">
<div class="row"> <div class="row">
<span class="col-sm-2">Preferred Protocol</span> <span class="col-sm-2">Protocol</span>
<span class="col-sm-2">Usenet Delay</span> <span class="col-sm-2">Usenet Delay</span>
<span class="col-sm-2">Torrent Delay</span> <span class="col-sm-2">Torrent Delay</span>
<span class="col-sm-5">Tags</span> <span class="col-sm-5">Tags</span>

View File

@ -18,7 +18,14 @@ define([
_deleteView: DeleteView, _deleteView: DeleteView,
ui: { ui: {
tags : '.x-tags' tags : '.x-tags',
usenetDelay : '.x-usenet-delay',
torrentDelay : '.x-torrent-delay',
protocol : '.x-protocol'
},
events: {
'change .x-protocol' : '_updateModel'
}, },
initialize: function (options) { initialize: function (options) {
@ -32,11 +39,83 @@ define([
property : 'tags' property : 'tags'
}); });
} }
this._toggleControls();
}, },
_onAfterSave: function () { _onAfterSave: function () {
this.targetCollection.add(this.model, { merge: true }); this.targetCollection.add(this.model, { merge: true });
vent.trigger(vent.Commands.CloseModalCommand); vent.trigger(vent.Commands.CloseModalCommand);
},
_updateModel: function () {
var protocol = this.ui.protocol.val();
if (protocol === 'preferUsenet') {
this.model.set({
enableUsenet : true,
enableTorrent : true,
preferredProtocol : 'usenet'
});
}
if (protocol === 'preferTorrent') {
this.model.set({
enableUsenet : true,
enableTorrent : true,
preferredProtocol : 'torrent'
});
}
if (protocol === 'onlyUsenet') {
this.model.set({
enableUsenet : true,
enableTorrent : false,
preferredProtocol : 'usenet'
});
}
if (protocol === 'onlyTorrent') {
this.model.set({
enableUsenet : false,
enableTorrent : true,
preferredProtocol : 'torrent'
});
}
this._toggleControls();
},
_toggleControls: function () {
var enableUsenet = this.model.get('enableUsenet');
var enableTorrent = this.model.get('enableTorrent');
var preferred = this.model.get('preferredProtocol');
if (preferred === 'usenet') {
this.ui.protocol.val('preferUsenet');
}
else {
this.ui.protocol.val('preferTorrent');
}
if (enableUsenet) {
this.ui.usenetDelay.show();
}
else {
this.ui.protocol.val('onlyTorrent');
this.ui.usenetDelay.hide();
}
if (enableTorrent) {
this.ui.torrentDelay.show();
}
else {
this.ui.protocol.val('onlyUsenet');
this.ui.torrentDelay.hide();
}
} }
}); });

View File

@ -10,21 +10,23 @@
<div class="modal-body indexer-modal"> <div class="modal-body indexer-modal">
<div class="form-horizontal"> <div class="form-horizontal">
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">Preferred Protocol</label> <label class="col-sm-3 control-label">Protocol</label>
<div class="col-sm-1 col-sm-push-5 help-inline"> <div class="col-sm-1 col-sm-push-5 help-inline">
<i class="icon-nd-form-info" title="Choose which protocol to use when choosing between otherwise equal releases" /> <i class="icon-nd-form-info" title="Choose which protocol(s) to use and which one is preferred when choosing between otherwise equal releases" />
</div> </div>
<div class="col-sm-5 col-sm-pull-1"> <div class="col-sm-5 col-sm-pull-1">
<select class="form-control" name="preferredProtocol"> <select class="form-control x-protocol">
<option value="1">Usenet</option> <option value="preferUsenet">Prefer Usenet</option>
<option value="2">Torrents</option> <option value="preferTorrent">Prefer Torrent</option>
<option value="onlyUsenet">Only Usenet</option>
<option value="onlyTorrent">Only Torrent</option>
</select> </select>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group x-usenet-delay">
<label class="col-sm-3 control-label">Usenet Delay</label> <label class="col-sm-3 control-label">Usenet Delay</label>
<div class="col-sm-1 col-sm-push-5 help-inline"> <div class="col-sm-1 col-sm-push-5 help-inline">
@ -36,7 +38,7 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group x-torrent-delay">
<label class="col-sm-3 control-label">Torrent Delay</label> <label class="col-sm-3 control-label">Torrent Delay</label>
<div class="col-sm-1 col-sm-push-5 help-inline"> <div class="col-sm-1 col-sm-push-5 help-inline">
@ -49,7 +51,7 @@
</div> </div>
{{#if_eq id compare="1"}} {{#if_eq id compare="1"}}
<div class="alert alert-info" role="alert">The default Delay Profile applies to all series unless overridden by a Delay Profile attached to a matching tag</div> <div class="alert alert-info" role="alert">This is the default profile. It applies to all series that don't have an explicit profile.</div>
{{else}} {{else}}
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">Tags</label> <label class="col-sm-3 control-label">Tags</label>
@ -67,7 +69,9 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
{{#if id}} {{#if id}}
<button class="btn btn-danger pull-left x-delete">delete</button> {{#if_gt id compare="1"}}
<button class="btn btn-danger pull-left x-delete">delete</button>
{{/if_gt}}
{{/if}} {{/if}}
<span class="indicator x-indicator"><i class="icon-spinner icon-spin"></i></span> <span class="indicator x-indicator"><i class="icon-spinner icon-spin"></i></span>
<button class="btn" data-dismiss="modal">cancel</button> <button class="btn" data-dismiss="modal">cancel</button>