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(Episode), typeof(EpisodeResource))]
[TestCase(typeof(RootFolder), typeof(RootFolderResource))] [TestCase(typeof(RootFolder), typeof(RootFolderResource))]
[TestCase(typeof(NamingConfig), typeof(NamingConfigResource))] [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(ReleaseInfo), typeof(ReleaseResource))]
[TestCase(typeof(ParsedEpisodeInfo), typeof(ReleaseResource))] [TestCase(typeof(ParsedEpisodeInfo), typeof(ReleaseResource))]
[TestCase(typeof(DownloadDecision), typeof(ReleaseResource))] [TestCase(typeof(DownloadDecision), typeof(ReleaseResource))]
@ -64,7 +64,6 @@ namespace NzbDrone.Api.Test.MappingTests
modelWithLazy.Guid.IsLoaded.Should().BeFalse(); modelWithLazy.Guid.IsLoaded.Should().BeFalse();
} }
[Test] [Test]
public void should_map_lay_loaded_values_should_be_inject_if_loaded() 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 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; } public DownloadProtocol Protocol { get; set; }
} }
} }

View File

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

View File

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

View File

@ -15,6 +15,41 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
[TestFixture] [TestFixture]
public class IndexerCheckFixture : CoreTest<IndexerCheck> 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] [Test]
public void should_return_error_when_not_indexers_are_enabled() public void should_return_error_when_not_indexers_are_enabled()
{ {
@ -26,14 +61,17 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
} }
[Test] [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>(); GivenIndexer(true, false);
indexer.SetupGet(s => s.SupportsSearching).Returns(false);
Mocker.GetMock<IIndexerFactory>() Subject.Check().ShouldBeWarning();
.Setup(s => s.GetAvailableProviders()) }
.Returns(new List<IIndexer>{indexer.Object});
[Test]
public void should_return_warning_when_only_enabled_indexer_doesnt_support_rss()
{
GivenIndexer(false, true);
Subject.Check().ShouldBeWarning(); Subject.Check().ShouldBeWarning();
} }
@ -41,11 +79,16 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
[Test] [Test]
public void should_return_ok_when_multiple_indexers_are_enabled() public void should_return_ok_when_multiple_indexers_are_enabled()
{ {
GivenRssEnabled();
GivenSearchEnabled();
var indexer1 = Mocker.GetMock<IIndexer>(); 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>(); 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>() Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.GetAvailableProviders()) .Setup(s => s.GetAvailableProviders())
@ -55,16 +98,31 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
} }
[Test] [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>(); GivenIndexer(true, true);
indexer1.SetupGet(s => s.SupportsSearching).Returns(true); GivenRssEnabled();
GivenSearchEnabled();
Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.GetAvailableProviders())
.Returns(new List<IIndexer> { indexer1.Object });
Subject.Check().ShouldBeOk(); 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;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using FluentAssertions; using FluentAssertions;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
@ -25,10 +24,10 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
public void SetUp() public void SetUp()
{ {
var indexer = Mocker.GetMock<IIndexer>(); var indexer = Mocker.GetMock<IIndexer>();
indexer.SetupGet(s => s.SupportsSearching).Returns(true); indexer.SetupGet(s => s.SupportsSearch).Returns(true);
Mocker.GetMock<IIndexerFactory>() Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.GetAvailableProviders()) .Setup(s => s.SearchEnabled())
.Returns(new List<IIndexer> { indexer.Object }); .Returns(new List<IIndexer> { indexer.Object });
Mocker.GetMock<IMakeDownloadDecision>() 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<RootFolder>().RegisterModel("RootFolders").Ignore(r => r.FreeSpace);
Mapper.Entity<IndexerDefinition>().RegisterModel("Indexers") 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<ScheduledTask>().RegisterModel("ScheduledTasks");
Mapper.Entity<NotificationDefinition>().RegisterModel("Notifications"); Mapper.Entity<NotificationDefinition>().RegisterModel("Notifications");
Mapper.Entity<MetadataDefinition>().RegisterModel("Metadata"); Mapper.Entity<MetadataDefinition>().RegisterModel("Metadata");
Mapper.Entity<DownloadClientDefinition>().RegisterModel("DownloadClients");
Mapper.Entity<DownloadClientDefinition>().RegisterModel("DownloadClients")
.Ignore(d => d.Protocol);
Mapper.Entity<SceneMapping>().RegisterModel("SceneMappings"); Mapper.Entity<SceneMapping>().RegisterModel("SceneMappings");

View File

@ -27,7 +27,7 @@ namespace NzbDrone.Core.Download
return base.Active().Where(c => c.Enable).ToList(); 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); definition = base.GetProviderCharacteristics(provider, definition);

View File

@ -1,4 +1,5 @@
using System.Linq; using System.Linq;
using NzbDrone.Common;
using NzbDrone.Core.Indexers; using NzbDrone.Core.Indexers;
namespace NzbDrone.Core.HealthCheck.Checks namespace NzbDrone.Core.HealthCheck.Checks
@ -15,17 +16,34 @@ namespace NzbDrone.Core.HealthCheck.Checks
public override HealthCheck Check() public override HealthCheck Check()
{ {
var enabled = _indexerFactory.GetAvailableProviders(); 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"); 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"); 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()); 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) 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>(); var reports = new List<ReleaseInfo>();
_logger.ProgressInfo("Searching {0} indexers for {1}", indexers.Count, criteriaBase); _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 get
{ {

View File

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

View File

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

View File

@ -10,7 +10,8 @@ namespace NzbDrone.Core.Indexers
DownloadProtocol Protocol { get; } DownloadProtocol Protocol { get; }
Int32 SupportedPageSize { get; } Int32 SupportedPageSize { get; }
Boolean SupportsPaging { get; } Boolean SupportsPaging { get; }
Boolean SupportsSearching { get; } Boolean SupportsRss { get; }
Boolean SupportsSearch { get; }
IEnumerable<string> RecentFeed { get; } IEnumerable<string> RecentFeed { get; }
IEnumerable<string> GetEpisodeSearchUrls(List<String> titles, int tvRageId, int seasonNumber, int episodeNumber); 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 yield return new IndexerDefinition
{ {
Name = GetType().Name, Name = GetType().Name,
Enable = config.Validate().IsValid, EnableRss = config.Validate().IsValid,
EnableSearch = config.Validate().IsValid && SupportsSearch,
Implementation = GetType().Name, Implementation = GetType().Name,
Settings = config Settings = config
}; };
@ -36,10 +37,10 @@ namespace NzbDrone.Core.Indexers
public abstract ValidationResult Test(); public abstract ValidationResult Test();
public abstract DownloadProtocol Protocol { get; } 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 virtual Int32 SupportedPageSize { get { return 0; } }
public bool SupportsPaging { get { return SupportedPageSize > 0; } } public bool SupportsPaging { get { return SupportedPageSize > 0; } }
public virtual Boolean SupportsSearching { get { return true; } }
protected TSettings Settings protected TSettings Settings
{ {

View File

@ -1,9 +1,22 @@
using NzbDrone.Core.ThingiProvider; using System;
using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Indexers namespace NzbDrone.Core.Indexers
{ {
public class IndexerDefinition : ProviderDefinition public class IndexerDefinition : ProviderDefinition
{ {
public Boolean EnableRss { get; set; }
public Boolean EnableSearch { get; set; }
public DownloadProtocol Protocol { 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> public interface IIndexerFactory : IProviderFactory<IIndexer, IndexerDefinition>
{ {
List<IIndexer> RssEnabled();
List<IIndexer> SearchEnabled();
} }
public class IndexerFactory : ProviderFactory<IIndexer, IndexerDefinition>, IIndexerFactory public class IndexerFactory : ProviderFactory<IIndexer, IndexerDefinition>, IIndexerFactory
{ {
private readonly INewznabTestService _newznabTestService;
public IndexerFactory(IIndexerRepository providerRepository, public IndexerFactory(IIndexerRepository providerRepository,
IEnumerable<IIndexer> providers, IEnumerable<IIndexer> providers,
IContainer container, IContainer container,
IEventAggregator eventAggregator, IEventAggregator eventAggregator,
INewznabTestService newznabTestService,
Logger logger) Logger logger)
: base(providerRepository, providers, container, eventAggregator, logger) : base(providerRepository, providers, container, eventAggregator, logger)
{ {
_newznabTestService = newznabTestService;
} }
protected override void InitializeProviders() protected override void InitializeProviders()
@ -37,13 +34,25 @@ namespace NzbDrone.Core.Indexers
return base.Active().Where(c => c.Enable).ToList(); 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 = base.GetProviderCharacteristics(provider, definition);
definition.Protocol = provider.Protocol; definition.Protocol = provider.Protocol;
definition.SupportsRss = provider.SupportsRss;
definition.SupportsSearch = provider.SupportsSearch;
return definition; 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;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using FluentValidation;
using FluentValidation.Results; using FluentValidation.Results;
using NLog; using NLog;
using NzbDrone.Common; using NzbDrone.Common;
@ -47,54 +46,12 @@ namespace NzbDrone.Core.Indexers.Newznab
{ {
var list = new List<IndexerDefinition>(); var list = new List<IndexerDefinition>();
list.Add(new IndexerDefinition list.Add(GetDefinition("Nzbs.org", GetSettings("http://nzbs.org", 5000)));
{ list.Add(GetDefinition("Nzb.su", GetSettings("https://api.nzb.su")));
Enable = false, list.Add(GetDefinition("Dognzb.cr", GetSettings("https://api.dognzb.cr")));
Name = "Nzbs.org", list.Add(GetDefinition("OZnzb.com", GetSettings("https://www.oznzb.com")));
Implementation = GetType().Name, list.Add(GetDefinition("nzbplanet.net", GetSettings("https://nzbplanet.net")));
Settings = GetSettings("http://nzbs.org", new List<Int32> { 5000 }) list.Add(GetDefinition("NZBgeek", GetSettings("https://api.nzbgeek.info")));
});
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>())
});
return list; return list;
} }
@ -102,18 +59,6 @@ namespace NzbDrone.Core.Indexers.Newznab
public override ProviderDefinition Definition { get; set; } 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 public override IEnumerable<string> RecentFeed
{ {
get get
@ -241,6 +186,33 @@ namespace NzbDrone.Core.Indexers.Newznab
return new ValidationResult(); 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) private static string NewsnabifyTitle(string title)
{ {
return title.Replace("+", "%20"); return title.Replace("+", "%20");

View File

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

View File

@ -221,6 +221,8 @@
<Compile Include="Datastore\Migration\056_add_mediainfo_to_episodefile.cs" /> <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\057_convert_episode_file_path_to_relative.cs" />
<Compile Include="Datastore\Migration\058_drop_epsiode_file_path.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\MigrationContext.cs" />
<Compile Include="Datastore\Migration\Framework\MigrationController.cs" /> <Compile Include="Datastore\Migration\Framework\MigrationController.cs" />
<Compile Include="Datastore\Migration\Framework\MigrationExtension.cs" /> <Compile Include="Datastore\Migration\Framework\MigrationExtension.cs" />

View File

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

View File

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

View File

@ -15,7 +15,7 @@ namespace NzbDrone.Integration.Test
indexers.Should().NotBeEmpty(); indexers.Should().NotBeEmpty();
indexers.Should().NotContain(c => string.IsNullOrWhiteSpace(c.Name)); 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 // Add Wombles
var wombles = Indexers.Post(new Api.Indexers.IndexerResource var wombles = Indexers.Post(new Api.Indexers.IndexerResource
{ {
Enable = true, EnableRss = true,
ConfigContract = "NullConfig", ConfigContract = "NullConfig",
Implementation = "Wombles", Implementation = "Wombles",
Name = "Wombles", Name = "Wombles",

View File

@ -25,18 +25,11 @@ define([
_addPreset: function (e) { _addPreset: function (e) {
var presetName = $(e.target).closest('.x-preset').attr('data-id'); var presetName = $(e.target).closest('.x-preset').attr('data-id');
var presetData = _.where(this.model.get('presets'), {name: presetName})[0]; var presetData = _.where(this.model.get('presets'), {name: presetName})[0];
this.model.set(presetData); this.model.set(presetData);
this.model.set({ this._openEdit();
id : undefined,
enable : true
});
var editView = new EditView({ model: this.model, targetCollection: this.targetCollection });
AppLayout.modalRegion.show(editView);
}, },
_add: function (e) { _add: function (e) {
@ -44,9 +37,14 @@ define([
return; return;
} }
this._openEdit();
},
_openEdit: function () {
this.model.set({ this.model.set({
id : undefined, id : undefined,
enable : true enableRss : this.model.get('supportsRss'),
enableSearch : this.model.get('supportsSearch')
}); });
var editView = new EditView({ model: this.model, targetCollection: this.targetCollection }); var editView = new EditView({ model: this.model, targetCollection: this.targetCollection });

View File

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

View File

@ -4,10 +4,20 @@
</div> </div>
<div class="settings"> <div class="settings">
{{#if enable}} {{#if supportsRss}}
<span class="label label-success">Enabled</span> {{#if enableRss}}
<span class="label label-success">RSS</span>
{{else}} {{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}} {{/if}}
</div> </div>
</div> </div>