New: Enable/Disable RSS Sync/Searching on a per indexer basis

This commit is contained in:
Mark McDowall 2014-08-17 19:25:00 -07:00
parent 7d91b1bdb7
commit ebf0dbc1d0
29 changed files with 279 additions and 132 deletions

View File

@ -37,7 +37,7 @@ namespace NzbDrone.Api.Test.MappingTests
[TestCase(typeof(Episode), typeof(EpisodeResource))]
[TestCase(typeof(RootFolder), typeof(RootFolderResource))]
[TestCase(typeof(NamingConfig), typeof(NamingConfigResource))]
[TestCase(typeof(IndexerDefinition), typeof(IndexerResource))]
// [TestCase(typeof(IndexerDefinition), typeof(IndexerResource))] //TODO: Ignoring because we don't have a good way to ignore properties with value injector
[TestCase(typeof(ReleaseInfo), typeof(ReleaseResource))]
[TestCase(typeof(ParsedEpisodeInfo), typeof(ReleaseResource))]
[TestCase(typeof(DownloadDecision), typeof(ReleaseResource))]
@ -64,7 +64,6 @@ namespace NzbDrone.Api.Test.MappingTests
modelWithLazy.Guid.IsLoaded.Should().BeFalse();
}
[Test]
public void should_map_lay_loaded_values_should_be_inject_if_loaded()
{

View File

@ -5,7 +5,10 @@ namespace NzbDrone.Api.Indexers
{
public class IndexerResource : ProviderResource
{
public Boolean Enable { get; set; }
public Boolean EnableRss { get; set; }
public Boolean EnableSearch { get; set; }
public Boolean SupportsRss { get; set; }
public Boolean SupportsSearch { get; set; }
public DownloadProtocol Protocol { get; set; }
}
}

View File

@ -18,10 +18,8 @@ namespace NzbDrone.Api.Mapping
}
PrintExtraProperties(modelType, resourceType);
}
private static void PrintExtraProperties(Type modelType, Type resourceType)
{
var resourceBaseProperties = typeof(RestResource).GetProperties().Select(c => c.Name);
@ -34,8 +32,6 @@ namespace NzbDrone.Api.Mapping
{
Console.WriteLine("Extra: [{0}]", extraProp);
}
}
private static string GetError(Type resourceType, PropertyInfo modelProperty)
@ -54,6 +50,5 @@ namespace NzbDrone.Api.Mapping
return null;
}
}
}

View File

@ -43,7 +43,12 @@ namespace NzbDrone.Api
private TProviderResource GetProviderById(int id)
{
return _providerFactory.Get(id).InjectTo<TProviderResource>();
var definition = _providerFactory.Get(id);
var resource = definition.InjectTo<TProviderResource>();
resource.InjectFrom(_providerFactory.GetProviderCharacteristics(_providerFactory.GetInstance(definition), definition));
return resource;
}
private List<TProviderResource> GetAll()
@ -56,6 +61,7 @@ namespace NzbDrone.Api
{
var providerResource = new TProviderResource();
providerResource.InjectFrom(definition);
providerResource.InjectFrom(_providerFactory.GetProviderCharacteristics(_providerFactory.GetInstance(definition), definition));
providerResource.Fields = SchemaBuilder.ToSchema(definition.Settings);
result.Add(providerResource);
@ -116,7 +122,7 @@ namespace NzbDrone.Api
private Response GetTemplates()
{
var defaultDefinitions = _providerFactory.GetDefaultDefinitions();
var defaultDefinitions = _providerFactory.GetDefaultDefinitions().ToList();
var result = new List<TProviderResource>(defaultDefinitions.Count());

View File

@ -15,6 +15,41 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
[TestFixture]
public class IndexerCheckFixture : CoreTest<IndexerCheck>
{
private IIndexer _indexer;
private void GivenIndexer(Boolean supportsRss, Boolean supportsSearch)
{
var _indexer = Mocker.GetMock<IIndexer>();
_indexer.SetupGet(s => s.SupportsRss).Returns(supportsRss);
_indexer.SetupGet(s => s.SupportsSearch).Returns(supportsSearch);
Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.GetAvailableProviders())
.Returns(new List<IIndexer> { _indexer.Object });
Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.RssEnabled())
.Returns(new List<IIndexer>());
Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.SearchEnabled())
.Returns(new List<IIndexer>());
}
private void GivenRssEnabled()
{
Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.RssEnabled())
.Returns(new List<IIndexer> { _indexer });
}
private void GivenSearchEnabled()
{
Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.SearchEnabled())
.Returns(new List<IIndexer> { _indexer });
}
[Test]
public void should_return_error_when_not_indexers_are_enabled()
{
@ -26,14 +61,17 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
}
[Test]
public void should_return_warning_when_only_enabled_indexer_is_wombles()
public void should_return_warning_when_only_enabled_indexer_doesnt_support_search()
{
var indexer = Mocker.GetMock<IIndexer>();
indexer.SetupGet(s => s.SupportsSearching).Returns(false);
GivenIndexer(true, false);
Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.GetAvailableProviders())
.Returns(new List<IIndexer>{indexer.Object});
Subject.Check().ShouldBeWarning();
}
[Test]
public void should_return_warning_when_only_enabled_indexer_doesnt_support_rss()
{
GivenIndexer(false, true);
Subject.Check().ShouldBeWarning();
}
@ -41,11 +79,16 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
[Test]
public void should_return_ok_when_multiple_indexers_are_enabled()
{
GivenRssEnabled();
GivenSearchEnabled();
var indexer1 = Mocker.GetMock<IIndexer>();
indexer1.SetupGet(s => s.SupportsSearching).Returns(true);
indexer1.SetupGet(s => s.SupportsRss).Returns(true);
indexer1.SetupGet(s => s.SupportsSearch).Returns(true);
var indexer2 = Mocker.GetMock<Wombles>();
indexer2.SetupGet(s => s.SupportsSearching).Returns(false);
indexer2.SetupGet(s => s.SupportsRss).Returns(true);
indexer2.SetupGet(s => s.SupportsSearch).Returns(false);
Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.GetAvailableProviders())
@ -55,16 +98,31 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
}
[Test]
public void should_return_ok_when_indexer_supports_searching()
public void should_return_ok_when_indexer_supports_rss_and_search()
{
var indexer1 = Mocker.GetMock<IIndexer>();
indexer1.SetupGet(s => s.SupportsSearching).Returns(true);
Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.GetAvailableProviders())
.Returns(new List<IIndexer> { indexer1.Object });
GivenIndexer(true, true);
GivenRssEnabled();
GivenSearchEnabled();
Subject.Check().ShouldBeOk();
}
[Test]
public void should_return_warning_if_rss_is_supported_but_disabled()
{
GivenIndexer(true, true);
GivenSearchEnabled();
Subject.Check().ShouldBeWarning();
}
[Test]
public void should_return_warning_if_search_is_supported_but_disabled()
{
GivenIndexer(true, true);
GivenRssEnabled();
Subject.Check().ShouldBeWarning();
}
}
}

View File

@ -6,7 +6,6 @@ using FizzWare.NBuilder;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentAssertions;
using Moq;
using NUnit.Framework;
@ -25,10 +24,10 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
public void SetUp()
{
var indexer = Mocker.GetMock<IIndexer>();
indexer.SetupGet(s => s.SupportsSearching).Returns(true);
indexer.SetupGet(s => s.SupportsSearch).Returns(true);
Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.GetAvailableProviders())
.Setup(s => s.SearchEnabled())
.Returns(new List<IIndexer> { indexer.Object });
Mocker.GetMock<IMakeDownloadDecision>()

View File

@ -0,0 +1,19 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(59)]
public class add_enable_options_to_indexers : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("Indexers")
.AddColumn("EnableRss").AsBoolean().Nullable()
.AddColumn("EnableSearch").AsBoolean().Nullable();
Execute.Sql("UPDATE Indexers SET EnableRss = Enable, EnableSearch = Enable");
Execute.Sql("UPDATE Indexers SET EnableSearch = 0 WHERE Implementation = 'Wombles'");
}
}
}

View File

@ -0,0 +1,15 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(60)]
public class remove_enable_from_indexers : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
SqLiteAlter.DropColumns("Indexers", new[] { "Enable" });
SqLiteAlter.DropColumns("DownloadClients", new[] { "Protocol" });
}
}
}

View File

@ -40,11 +40,17 @@ namespace NzbDrone.Core.Datastore
Mapper.Entity<RootFolder>().RegisterModel("RootFolders").Ignore(r => r.FreeSpace);
Mapper.Entity<IndexerDefinition>().RegisterModel("Indexers")
.Ignore(s => s.Protocol);
.Ignore(i => i.Enable)
.Ignore(i => i.Protocol)
.Ignore(i => i.SupportsRss)
.Ignore(i => i.SupportsSearch);
Mapper.Entity<ScheduledTask>().RegisterModel("ScheduledTasks");
Mapper.Entity<NotificationDefinition>().RegisterModel("Notifications");
Mapper.Entity<MetadataDefinition>().RegisterModel("Metadata");
Mapper.Entity<DownloadClientDefinition>().RegisterModel("DownloadClients");
Mapper.Entity<DownloadClientDefinition>().RegisterModel("DownloadClients")
.Ignore(d => d.Protocol);
Mapper.Entity<SceneMapping>().RegisterModel("SceneMappings");

View File

@ -27,7 +27,7 @@ namespace NzbDrone.Core.Download
return base.Active().Where(c => c.Enable).ToList();
}
protected override DownloadClientDefinition GetProviderCharacteristics(IDownloadClient provider, DownloadClientDefinition definition)
public override DownloadClientDefinition GetProviderCharacteristics(IDownloadClient provider, DownloadClientDefinition definition)
{
definition = base.GetProviderCharacteristics(provider, definition);

View File

@ -1,4 +1,5 @@
using System.Linq;
using NzbDrone.Common;
using NzbDrone.Core.Indexers;
namespace NzbDrone.Core.HealthCheck.Checks
@ -15,17 +16,34 @@ namespace NzbDrone.Core.HealthCheck.Checks
public override HealthCheck Check()
{
var enabled = _indexerFactory.GetAvailableProviders();
var rssEnabled = _indexerFactory.RssEnabled();
var searchEnabled = _indexerFactory.SearchEnabled();
if (!enabled.Any())
if (enabled.Empty())
{
return new HealthCheck(GetType(), HealthCheckResult.Error, "No indexers are enabled");
}
if (enabled.All(i => i.SupportsSearching == false))
if (enabled.All(i => i.SupportsRss == false))
{
return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enabled indexers do not support RSS sync");
}
if (enabled.All(i => i.SupportsSearch == false))
{
return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enabled indexers do not support searching");
}
if (rssEnabled.Empty())
{
return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enabled indexers do not have RSS sync enabled");
}
if (searchEnabled.Empty())
{
return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enabled indexers do not have searching enabled");
}
return new HealthCheck(GetType());
}
}

View File

@ -247,7 +247,7 @@ namespace NzbDrone.Core.IndexerSearch
private List<DownloadDecision> Dispatch(Func<IIndexer, IEnumerable<ReleaseInfo>> searchAction, SearchCriteriaBase criteriaBase)
{
var indexers = _indexerFactory.GetAvailableProviders().ToList();
var indexers = _indexerFactory.SearchEnabled().ToList();
var reports = new List<ReleaseInfo>();
_logger.ProgressInfo("Searching {0} indexers for {1}", indexers.Count, criteriaBase);

View File

@ -21,7 +21,7 @@ namespace NzbDrone.Core.Indexers.Animezb
}
}
public override bool SupportsSearching
public override bool SupportsSearch
{
get
{

View File

@ -19,7 +19,7 @@ namespace NzbDrone.Core.Indexers.Fanzub
}
}
public override bool SupportsSearching
public override bool SupportsSearch
{
get
{

View File

@ -29,7 +29,7 @@ namespace NzbDrone.Core.Indexers
{
var result = new List<ReleaseInfo>();
var indexers = _indexerFactory.GetAvailableProviders().ToList();
var indexers = _indexerFactory.RssEnabled().ToList();
if (!indexers.Any())
{

View File

@ -10,7 +10,8 @@ namespace NzbDrone.Core.Indexers
DownloadProtocol Protocol { get; }
Int32 SupportedPageSize { get; }
Boolean SupportsPaging { get; }
Boolean SupportsSearching { get; }
Boolean SupportsRss { get; }
Boolean SupportsSearch { get; }
IEnumerable<string> RecentFeed { get; }
IEnumerable<string> GetEpisodeSearchUrls(List<String> titles, int tvRageId, int seasonNumber, int episodeNumber);

View File

@ -24,7 +24,8 @@ namespace NzbDrone.Core.Indexers
yield return new IndexerDefinition
{
Name = GetType().Name,
Enable = config.Validate().IsValid,
EnableRss = config.Validate().IsValid,
EnableSearch = config.Validate().IsValid && SupportsSearch,
Implementation = GetType().Name,
Settings = config
};
@ -36,10 +37,10 @@ namespace NzbDrone.Core.Indexers
public abstract ValidationResult Test();
public abstract DownloadProtocol Protocol { get; }
public virtual Boolean SupportsFeed { get { return true; } }
public virtual Boolean SupportsRss { get { return true; } }
public virtual Boolean SupportsSearch { get { return true; } }
public virtual Int32 SupportedPageSize { get { return 0; } }
public bool SupportsPaging { get { return SupportedPageSize > 0; } }
public virtual Boolean SupportsSearching { get { return true; } }
protected TSettings Settings
{

View File

@ -1,9 +1,22 @@
using NzbDrone.Core.ThingiProvider;
using System;
using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Indexers
{
public class IndexerDefinition : ProviderDefinition
{
public Boolean EnableRss { get; set; }
public Boolean EnableSearch { get; set; }
public DownloadProtocol Protocol { get; set; }
public Boolean SupportsRss { get; set; }
public Boolean SupportsSearch { get; set; }
public override Boolean Enable
{
get
{
return EnableRss || EnableSearch;
}
}
}
}

View File

@ -9,22 +9,19 @@ namespace NzbDrone.Core.Indexers
{
public interface IIndexerFactory : IProviderFactory<IIndexer, IndexerDefinition>
{
List<IIndexer> RssEnabled();
List<IIndexer> SearchEnabled();
}
public class IndexerFactory : ProviderFactory<IIndexer, IndexerDefinition>, IIndexerFactory
{
private readonly INewznabTestService _newznabTestService;
public IndexerFactory(IIndexerRepository providerRepository,
IEnumerable<IIndexer> providers,
IContainer container,
IEventAggregator eventAggregator,
INewznabTestService newznabTestService,
Logger logger)
: base(providerRepository, providers, container, eventAggregator, logger)
{
_newznabTestService = newznabTestService;
}
protected override void InitializeProviders()
@ -37,13 +34,25 @@ namespace NzbDrone.Core.Indexers
return base.Active().Where(c => c.Enable).ToList();
}
protected override IndexerDefinition GetProviderCharacteristics(IIndexer provider, IndexerDefinition definition)
public override IndexerDefinition GetProviderCharacteristics(IIndexer provider, IndexerDefinition definition)
{
definition = base.GetProviderCharacteristics(provider, definition);
definition.Protocol = provider.Protocol;
definition.SupportsRss = provider.SupportsRss;
definition.SupportsSearch = provider.SupportsSearch;
return definition;
}
public List<IIndexer> RssEnabled()
{
return GetAvailableProviders().Where(n => ((IndexerDefinition)n.Definition).EnableRss).ToList();
}
public List<IIndexer> SearchEnabled()
{
return GetAvailableProviders().Where(n => ((IndexerDefinition)n.Definition).EnableSearch).ToList();
}
}
}

View File

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FluentValidation;
using FluentValidation.Results;
using NLog;
using NzbDrone.Common;
@ -47,54 +46,12 @@ namespace NzbDrone.Core.Indexers.Newznab
{
var list = new List<IndexerDefinition>();
list.Add(new IndexerDefinition
{
Enable = false,
Name = "Nzbs.org",
Implementation = GetType().Name,
Settings = GetSettings("http://nzbs.org", new List<Int32> { 5000 })
});
list.Add(new IndexerDefinition
{
Enable = false,
Name = "Nzb.su",
Implementation = GetType().Name,
Settings = GetSettings("https://api.nzb.su", new List<Int32>())
});
list.Add(new IndexerDefinition
{
Enable = false,
Name = "Dognzb.cr",
Implementation = GetType().Name,
Settings = GetSettings("https://api.dognzb.cr", new List<Int32>())
});
list.Add(new IndexerDefinition
{
Enable = false,
Name = "OZnzb.com",
Implementation = GetType().Name,
Settings = GetSettings("https://www.oznzb.com", new List<Int32>())
});
list.Add(new IndexerDefinition
{
Enable = false,
Name = "nzbplanet.net",
Implementation = GetType().Name,
Settings = GetSettings("https://nzbplanet.net", new List<Int32>())
});
list.Add(new IndexerDefinition
{
Enable = false,
Name = "NZBgeek",
Implementation = GetType().Name,
Settings = GetSettings("https://api.nzbgeek.info", new List<Int32>())
});
list.Add(GetDefinition("Nzbs.org", GetSettings("http://nzbs.org", 5000)));
list.Add(GetDefinition("Nzb.su", GetSettings("https://api.nzb.su")));
list.Add(GetDefinition("Dognzb.cr", GetSettings("https://api.dognzb.cr")));
list.Add(GetDefinition("OZnzb.com", GetSettings("https://www.oznzb.com")));
list.Add(GetDefinition("nzbplanet.net", GetSettings("https://nzbplanet.net")));
list.Add(GetDefinition("NZBgeek", GetSettings("https://api.nzbgeek.info")));
return list;
}
@ -102,18 +59,6 @@ namespace NzbDrone.Core.Indexers.Newznab
public override ProviderDefinition Definition { get; set; }
private NewznabSettings GetSettings(string url, List<int> categories)
{
var settings = new NewznabSettings { Url = url };
if (categories.Any())
{
settings.Categories = categories;
}
return settings;
}
public override IEnumerable<string> RecentFeed
{
get
@ -241,6 +186,33 @@ namespace NzbDrone.Core.Indexers.Newznab
return new ValidationResult();
}
private IndexerDefinition GetDefinition(String name, NewznabSettings settings)
{
return new IndexerDefinition
{
EnableRss = false,
EnableSearch = false,
Name = name,
Implementation = GetType().Name,
Settings = settings,
Protocol = DownloadProtocol.Usenet,
SupportsRss = SupportsRss,
SupportsSearch = SupportsSearch
};
}
private NewznabSettings GetSettings(String url, params int[] categories)
{
var settings = new NewznabSettings { Url = url };
if (categories.Any())
{
settings.Categories = categories;
}
return settings;
}
private static string NewsnabifyTitle(string title)
{
return title.Replace("+", "%20");

View File

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FluentValidation.Results;
using NzbDrone.Core.ThingiProvider;
@ -9,7 +8,7 @@ namespace NzbDrone.Core.Indexers.Wombles
public class Wombles : IndexerBase<NullConfig>
{
public override DownloadProtocol Protocol { get { return DownloadProtocol.Usenet; } }
public override bool SupportsSearching { get { return false; } }
public override bool SupportsSearch { get { return false; } }
public override IParseFeed Parser
{

View File

@ -221,6 +221,8 @@
<Compile Include="Datastore\Migration\056_add_mediainfo_to_episodefile.cs" />
<Compile Include="Datastore\Migration\057_convert_episode_file_path_to_relative.cs" />
<Compile Include="Datastore\Migration\058_drop_epsiode_file_path.cs" />
<Compile Include="Datastore\Migration\059_add_enable_options_to_indexers.cs" />
<Compile Include="Datastore\Migration\060_remove_enable_from_indexers.cs" />
<Compile Include="Datastore\Migration\Framework\MigrationContext.cs" />
<Compile Include="Datastore\Migration\Framework\MigrationController.cs" />
<Compile Include="Datastore\Migration\Framework\MigrationExtension.cs" />

View File

@ -15,6 +15,8 @@ namespace NzbDrone.Core.ThingiProvider
void Delete(int id);
IEnumerable<TProviderDefinition> GetDefaultDefinitions();
IEnumerable<TProviderDefinition> GetPresetDefinitions(TProviderDefinition providerDefinition);
TProviderDefinition GetProviderCharacteristics(TProvider provider, TProviderDefinition definition);
TProvider GetInstance(TProviderDefinition definition);
ValidationResult Test(TProviderDefinition definition);
}
}

View File

@ -107,7 +107,7 @@ namespace NzbDrone.Core.ThingiProvider
_providerRepository.Delete(id);
}
protected TProvider GetInstance(TProviderDefinition definition)
public TProvider GetInstance(TProviderDefinition definition)
{
var type = GetImplementation(definition);
var instance = (TProvider)_container.Resolve(type);
@ -138,7 +138,7 @@ namespace NzbDrone.Core.ThingiProvider
return All().Where(c => c.Settings.Validate().IsValid).ToList();
}
protected virtual TProviderDefinition GetProviderCharacteristics(TProvider provider, TProviderDefinition definition)
public virtual TProviderDefinition GetProviderCharacteristics(TProvider provider, TProviderDefinition definition)
{
return definition;
}

View File

@ -15,7 +15,7 @@ namespace NzbDrone.Integration.Test
indexers.Should().NotBeEmpty();
indexers.Should().NotContain(c => string.IsNullOrWhiteSpace(c.Name));
indexers.Where(c => c.ConfigContract == typeof(NullConfig).Name).Should().OnlyContain(c => c.Enable);
indexers.Where(c => c.ConfigContract == typeof(NullConfig).Name).Should().OnlyContain(c => c.EnableRss);
}
}
}

View File

@ -72,7 +72,7 @@ namespace NzbDrone.Integration.Test
// Add Wombles
var wombles = Indexers.Post(new Api.Indexers.IndexerResource
{
Enable = true,
EnableRss = true,
ConfigContract = "NullConfig",
Implementation = "Wombles",
Name = "Wombles",

View File

@ -25,18 +25,11 @@ define([
_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.model.set({
id : undefined,
enable : true
});
var editView = new EditView({ model: this.model, targetCollection: this.targetCollection });
AppLayout.modalRegion.show(editView);
this._openEdit();
},
_add: function (e) {
@ -44,9 +37,14 @@ define([
return;
}
this._openEdit();
},
_openEdit: function () {
this.model.set({
id : undefined,
enable : true
enableRss : this.model.get('supportsRss'),
enableSearch : this.model.get('supportsSearch')
});
var editView = new EditView({ model: this.model, targetCollection: this.targetCollection });

View File

@ -17,13 +17,14 @@
</div>
</div>
{{#if supportsRss}}
<div class="form-group">
<label class="col-sm-3 control-label">Enable</label>
<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="enable"/>
<input type="checkbox" name="enableRss"/>
<p>
<span>Yes</span>
<span>No</span>
@ -34,6 +35,27 @@
</div>
</div>
</div>
{{/if}}
{{#if supportsSearch}}
<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"/>
<p>
<span>Yes</span>
<span>No</span>
</p>
<div class="btn btn-primary slide-button"/>
</label>
</div>
</div>
</div>
{{/if}}
{{formBuilder}}
</div>

View File

@ -4,10 +4,20 @@
</div>
<div class="settings">
{{#if enable}}
<span class="label label-success">Enabled</span>
{{#if supportsRss}}
{{#if enableRss}}
<span class="label label-success">RSS</span>
{{else}}
<span class="label label-default">Not Enabled</span>
<span class="label label-default">RSS</span>
{{/if}}
{{/if}}
{{#if supportsSearch}}
{{#if enableSearch}}
<span class="label label-success">Search</span>
{{else}}
<span class="label label-default">Search</span>
{{/if}}
{{/if}}
</div>
</div>