From 9dbfc6804f98588c13eda5eec5e8560b93471eeb Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Sat, 21 Sep 2013 22:20:26 -0700 Subject: [PATCH] created generic provider factory --- .../MappingTests/ResourceMappingFixture.cs | 2 +- NzbDrone.Api/Indexers/IndexerModule.cs | 45 ++-- NzbDrone.Api/Indexers/IndexerSchemaModule.cs | 22 +- .../IndexerTests/IndexerServiceFixture.cs | 2 - .../IndexerIntegrationTests.cs | 14 +- .../ThingiProvider/ProviderBaseFixture.cs | 2 +- .../IndexerSearch/NzbSearchService.cs | 2 +- NzbDrone.Core/Indexers/Eztv/Eztv.cs | 3 +- .../Indexers/FetchAndParseRssService.cs | 2 +- NzbDrone.Core/Indexers/IIndexer.cs | 14 +- NzbDrone.Core/Indexers/IndexerBase.cs | 26 ++- NzbDrone.Core/Indexers/IndexerDefinition.cs | 5 +- NzbDrone.Core/Indexers/IndexerService.cs | 195 +----------------- NzbDrone.Core/Indexers/IndexerWithSetting.cs | 22 -- NzbDrone.Core/Indexers/Newznab/Newznab.cs | 7 +- .../Indexers/Omgwtfnzbs/Omgwtfnzbs.cs | 2 +- NzbDrone.Core/Indexers/Wombles/Wombles.cs | 3 +- NzbDrone.Core/NzbDrone.Core.csproj | 6 +- .../{ProviderBase.cs => IProvider.cs} | 30 ++- .../ThingiProvider/ProviderService.cs | 129 ++++++++++++ NzbDrone.ncrunchsolution | 2 +- 21 files changed, 227 insertions(+), 308 deletions(-) delete mode 100644 NzbDrone.Core/Indexers/IndexerWithSetting.cs rename NzbDrone.Core/ThingiProvider/{ProviderBase.cs => IProvider.cs} (56%) create mode 100644 NzbDrone.Core/ThingiProvider/ProviderService.cs diff --git a/NzbDrone.Api.Test/MappingTests/ResourceMappingFixture.cs b/NzbDrone.Api.Test/MappingTests/ResourceMappingFixture.cs index 82fb9425a..e03e02c35 100644 --- a/NzbDrone.Api.Test/MappingTests/ResourceMappingFixture.cs +++ b/NzbDrone.Api.Test/MappingTests/ResourceMappingFixture.cs @@ -36,7 +36,7 @@ public class ResourceMappingFixture : TestBase [TestCase(typeof(Episode), typeof(EpisodeResource))] [TestCase(typeof(RootFolder), typeof(RootFolderResource))] [TestCase(typeof(NamingConfig), typeof(NamingConfigResource))] - [TestCase(typeof(Indexer), typeof(IndexerResource))] + [TestCase(typeof(IndexerDefinition), typeof(IndexerResource))] [TestCase(typeof(ReleaseInfo), typeof(ReleaseResource))] [TestCase(typeof(ParsedEpisodeInfo), typeof(ReleaseResource))] [TestCase(typeof(DownloadDecision), typeof(ReleaseResource))] diff --git a/NzbDrone.Api/Indexers/IndexerModule.cs b/NzbDrone.Api/Indexers/IndexerModule.cs index 02215d3ed..cd5ed90c0 100644 --- a/NzbDrone.Api/Indexers/IndexerModule.cs +++ b/NzbDrone.Api/Indexers/IndexerModule.cs @@ -1,9 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Collections.Generic; using NzbDrone.Api.ClientSchema; -using NzbDrone.Api.REST; using NzbDrone.Core.Indexers; +using NzbDrone.Core.ThingiProvider; using Omu.ValueInjecter; using FluentValidation; using NzbDrone.Api.Mapping; @@ -62,47 +60,36 @@ private int CreateIndexer(IndexerResource indexerResource) private void UpdateIndexer(IndexerResource indexerResource) { - var indexer = _indexerService.Get(indexerResource.Id); - indexer.InjectFrom(indexerResource); - indexer.Settings = SchemaDeserializer.DeserializeSchema(indexer.Settings, indexerResource.Fields); + var indexer = GetIndexer(indexerResource); - ValidateIndexer(indexer); + ValidateIndexer(indexer.Settings); _indexerService.Update(indexer); } - private static void ValidateIndexer(Indexer indexer) + private static void ValidateIndexer(IProviderConfig config) { - if (indexer.Enable) - { - var validationResult = indexer.Settings.Validate(); + var validationResult = config.Validate(); - if (!validationResult.IsValid) - { - throw new ValidationException(validationResult.Errors); - } + if (!validationResult.IsValid) + { + throw new ValidationException(validationResult.Errors); } } - private Indexer GetIndexer(IndexerResource indexerResource) + private IndexerDefinition GetIndexer(IndexerResource indexerResource) { - var indexer = _indexerService.Schema() - .SingleOrDefault(i => - i.Implementation.Equals(indexerResource.Implementation, - StringComparison.InvariantCultureIgnoreCase)); - if (indexer == null) + var definition = new IndexerDefinition(); + + definition.InjectFrom(indexerResource); + if (indexerResource.Enable) { - throw new BadRequestException("Invalid Indexer Implementation"); + ValidateIndexer(definition.Settings); } - indexer.InjectFrom(indexerResource); - indexer.Settings = SchemaDeserializer.DeserializeSchema(indexer.Settings, indexerResource.Fields); - - ValidateIndexer(indexer); - - return indexer; + return definition; } private void DeleteIndexer(int id) diff --git a/NzbDrone.Api/Indexers/IndexerSchemaModule.cs b/NzbDrone.Api/Indexers/IndexerSchemaModule.cs index ad2ca7846..9fe425cf0 100644 --- a/NzbDrone.Api/Indexers/IndexerSchemaModule.cs +++ b/NzbDrone.Api/Indexers/IndexerSchemaModule.cs @@ -18,20 +18,22 @@ public IndexerSchemaModule(IIndexerService indexerService) private List GetSchema() { - var indexers = _indexerService.Schema(); + /* var indexers = _indexerService.Schema(); - var result = new List(indexers.Count); + var result = new List(indexers.Count); - foreach (var indexer in indexers) - { - var indexerResource = new IndexerResource(); - indexerResource.InjectFrom(indexer); - indexerResource.Fields = SchemaBuilder.GenerateSchema(indexer.Settings); + foreach (var indexer in indexers) + { + var indexerResource = new IndexerResource(); + indexerResource.InjectFrom(indexer); + indexerResource.Fields = SchemaBuilder.GenerateSchema(indexer.Settings); - result.Add(indexerResource); - } + result.Add(indexerResource); + } - return result; + return result;*/ + + return null; } } } \ No newline at end of file diff --git a/NzbDrone.Core.Test/IndexerTests/IndexerServiceFixture.cs b/NzbDrone.Core.Test/IndexerTests/IndexerServiceFixture.cs index 2de52fb5f..6ac94cc81 100644 --- a/NzbDrone.Core.Test/IndexerTests/IndexerServiceFixture.cs +++ b/NzbDrone.Core.Test/IndexerTests/IndexerServiceFixture.cs @@ -57,10 +57,8 @@ public void getting_list_of_indexers() var indexers = Subject.All().ToList(); indexers.Should().NotBeEmpty(); indexers.Should().NotContain(c => c.Settings == null); - indexers.Should().NotContain(c => c.Instance == null); indexers.Should().NotContain(c => c.Name == null); indexers.Select(c => c.Name).Should().OnlyHaveUniqueItems(); - indexers.Select(c => c.Instance).Should().OnlyHaveUniqueItems(); } diff --git a/NzbDrone.Core.Test/IndexerTests/IntegrationTests/IndexerIntegrationTests.cs b/NzbDrone.Core.Test/IndexerTests/IntegrationTests/IndexerIntegrationTests.cs index 1be142824..9c51cd84e 100644 --- a/NzbDrone.Core.Test/IndexerTests/IntegrationTests/IndexerIntegrationTests.cs +++ b/NzbDrone.Core.Test/IndexerTests/IntegrationTests/IndexerIntegrationTests.cs @@ -48,14 +48,14 @@ public void extv_rss() public void nzbsorg_rss() { var indexer = new Newznab(); - indexer.Settings = new NewznabSettings - { - ApiKey = "64d61d3cfd4b75e51d01cbc7c6a78275", - Url = "http://nzbs.org" - }; - indexer.InstanceDefinition = new IndexerDefinition(); - indexer.InstanceDefinition.Name = "nzbs.org"; + indexer.Definition = new IndexerDefinition(); + indexer.Definition.Name = "nzbs.org"; + indexer.Definition.Settings = new NewznabSettings + { + ApiKey = "64d61d3cfd4b75e51d01cbc7c6a78275", + Url = "http://nzbs.org" + }; var result = Subject.FetchRss(indexer); diff --git a/NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs b/NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs index 3ecfa62ac..8aa47c176 100644 --- a/NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs +++ b/NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs @@ -9,7 +9,7 @@ namespace NzbDrone.Core.Test.ThingiProvider { - public class ProviderRepositoryFixture : DbTest + public class ProviderRepositoryFixture : DbTest, IndexerDefinition> { [Test] public void should_read_write_download_provider() diff --git a/NzbDrone.Core/IndexerSearch/NzbSearchService.cs b/NzbDrone.Core/IndexerSearch/NzbSearchService.cs index 5770687b8..e79f3cedd 100644 --- a/NzbDrone.Core/IndexerSearch/NzbSearchService.cs +++ b/NzbDrone.Core/IndexerSearch/NzbSearchService.cs @@ -132,7 +132,7 @@ public List SeasonSearch(int seriesId, int seasonNumber) private List Dispatch(Func> searchAction, SearchCriteriaBase criteriaBase) { - var indexers = _indexerService.GetAvailableIndexers().ToList(); + var indexers = _indexerService.GetAvailableProviders().ToList(); var reports = new List(); _logger.ProgressInfo("Searching {0} indexers for {1}", indexers.Count, criteriaBase); diff --git a/NzbDrone.Core/Indexers/Eztv/Eztv.cs b/NzbDrone.Core/Indexers/Eztv/Eztv.cs index 541f3a078..8b514f255 100644 --- a/NzbDrone.Core/Indexers/Eztv/Eztv.cs +++ b/NzbDrone.Core/Indexers/Eztv/Eztv.cs @@ -1,9 +1,10 @@ using System; using System.Collections.Generic; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Indexers.Eztv { - public class Eztv : IndexerBase + public class Eztv : IndexerBase { public override string Name { diff --git a/NzbDrone.Core/Indexers/FetchAndParseRssService.cs b/NzbDrone.Core/Indexers/FetchAndParseRssService.cs index c9633c8d0..f153311fb 100644 --- a/NzbDrone.Core/Indexers/FetchAndParseRssService.cs +++ b/NzbDrone.Core/Indexers/FetchAndParseRssService.cs @@ -29,7 +29,7 @@ public List Fetch() { var result = new List(); - var indexers = _indexerService.GetAvailableIndexers().ToList(); + var indexers = _indexerService.GetAvailableProviders().ToList(); if (!indexers.Any()) { diff --git a/NzbDrone.Core/Indexers/IIndexer.cs b/NzbDrone.Core/Indexers/IIndexer.cs index a681ae3df..9e77b433d 100644 --- a/NzbDrone.Core/Indexers/IIndexer.cs +++ b/NzbDrone.Core/Indexers/IIndexer.cs @@ -1,23 +1,15 @@ using System; using System.Collections.Generic; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Indexers { - public interface IIndexer + public interface IIndexer : IProvider { - string Name { get; } - - bool EnableByDefault { get; } - - IEnumerable DefaultDefinitions { get; } - - IndexerDefinition InstanceDefinition { get; set; } - - IEnumerable RecentFeed { get; } - IParseFeed Parser { get; } IndexerKind Kind { get; } + IEnumerable RecentFeed { get; } IEnumerable GetEpisodeSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int episodeNumber); IEnumerable GetDailyEpisodeSearchUrls(string seriesTitle, int tvRageId, DateTime date); IEnumerable GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset); diff --git a/NzbDrone.Core/Indexers/IndexerBase.cs b/NzbDrone.Core/Indexers/IndexerBase.cs index 28a2d1d46..604f536c9 100644 --- a/NzbDrone.Core/Indexers/IndexerBase.cs +++ b/NzbDrone.Core/Indexers/IndexerBase.cs @@ -4,30 +4,38 @@ namespace NzbDrone.Core.Indexers { - public abstract class IndexerBase : IIndexer + public abstract class IndexerBase : IIndexer { public abstract string Name { get; } - public abstract IndexerKind Kind { get; } - - public virtual bool EnableByDefault { get { return true; } } - - public IndexerDefinition InstanceDefinition { get; set; } - - public virtual IEnumerable DefaultDefinitions + public virtual IEnumerable DefaultDefinitions { get { yield return new IndexerDefinition { Name = Name, - Enable = EnableByDefault, + Enable = false, Implementation = GetType().Name, Settings = NullSetting.Instance }; } } + public ProviderDefinition Definition { get; set; } + + public abstract IndexerKind Kind { get; } + + public virtual bool EnableByDefault { get { return true; } } + + protected TSettings Settings + { + get + { + return (TSettings)Definition.Settings; + } + } + public virtual IParseFeed Parser { get; private set; } public abstract IEnumerable RecentFeed { get; } diff --git a/NzbDrone.Core/Indexers/IndexerDefinition.cs b/NzbDrone.Core/Indexers/IndexerDefinition.cs index 02238e0e9..5909532b4 100644 --- a/NzbDrone.Core/Indexers/IndexerDefinition.cs +++ b/NzbDrone.Core/Indexers/IndexerDefinition.cs @@ -1,11 +1,8 @@ -using System; -using NzbDrone.Core.Datastore; -using NzbDrone.Core.ThingiProvider; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Indexers { public class IndexerDefinition : ProviderDefinition { - public Boolean Enable { get; set; } } } \ No newline at end of file diff --git a/NzbDrone.Core/Indexers/IndexerService.cs b/NzbDrone.Core/Indexers/IndexerService.cs index 5d42c2a9d..cd4a8a11e 100644 --- a/NzbDrone.Core/Indexers/IndexerService.cs +++ b/NzbDrone.Core/Indexers/IndexerService.cs @@ -1,202 +1,19 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Collections.Generic; using NLog; -using NzbDrone.Common.Serializer; -using NzbDrone.Core.Configuration; -using NzbDrone.Core.Indexers.Newznab; -using NzbDrone.Core.Lifecycle; -using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.ThingiProvider; -using Omu.ValueInjecter; namespace NzbDrone.Core.Indexers { - public class Indexer + public interface IIndexerService : IProviderFactory { - public int Id { get; set; } - public string Name { get; set; } - public bool Enable { get; set; } - public IProviderConfig Settings { get; set; } - public IIndexer Instance { get; set; } - public string Implementation { get; set; } + } - public interface IIndexerService + public class IndexerService : ProviderFactory { - List All(); - List GetAvailableIndexers(); - Indexer Get(int id); - Indexer Get(string name); - List Schema(); - Indexer Create(Indexer indexer); - Indexer Update(Indexer indexer); - void Delete(int id); - } - - public class IndexerService : IIndexerService, IHandle - { - private readonly IIndexerRepository _indexerRepository; - private readonly IConfigFileProvider _configFileProvider; - private readonly INewznabTestService _newznabTestService; - private readonly Logger _logger; - - private readonly List _indexers; - - public IndexerService(IIndexerRepository indexerRepository, - IEnumerable indexers, - IConfigFileProvider configFileProvider, - INewznabTestService newznabTestService, - Logger logger) + public IndexerService(IProviderRepository providerRepository, IEnumerable providers, Logger logger) + : base(providerRepository, providers, logger) { - _indexerRepository = indexerRepository; - _configFileProvider = configFileProvider; - _newznabTestService = newznabTestService; - _logger = logger; - - - if (!configFileProvider.Torrent) - { - _indexers = indexers.Where(c => c.Kind != IndexerKind.Torrent).ToList(); - } - else - { - _indexers = indexers.ToList(); - } - } - - public List All() - { - return _indexerRepository.All().Select(ToIndexer).ToList(); - } - - public List GetAvailableIndexers() - { - return All().Where(c => c.Enable && c.Settings.Validate().IsValid).Select(c => c.Instance).ToList(); - } - - public Indexer Get(int id) - { - return ToIndexer(_indexerRepository.Get(id)); - } - - public Indexer Get(string name) - { - return ToIndexer(_indexerRepository.Get(name)); - } - - public List Schema() - { - var indexers = new List(); - - var newznab = new Indexer(); - newznab.Instance = new Newznab.Newznab(); - newznab.Id = 1; - newznab.Name = "Newznab"; - newznab.Settings = new NewznabSettings(); - newznab.Implementation = "Newznab"; - - indexers.Add(newznab); - - return indexers; - } - - public Indexer Create(Indexer indexer) - { - var definition = new IndexerDefinition - { - Name = indexer.Name, - Enable = indexer.Enable, - Implementation = indexer.Implementation, - Settings = indexer.Settings - }; - - var instance = ToIndexer(definition).Instance; - _newznabTestService.Test(instance); - - definition = _indexerRepository.Insert(definition); - indexer.Id = definition.Id; - - return indexer; - } - - public Indexer Update(Indexer indexer) - { - var definition = _indexerRepository.Get(indexer.Id); - definition.InjectFrom(indexer); - definition.Settings = indexer.Settings; - _indexerRepository.Update(definition); - - return indexer; - } - - public void Delete(int id) - { - _indexerRepository.Delete(id); - } - - private Indexer ToIndexer(IndexerDefinition definition) - { - var indexer = new Indexer(); - indexer.Id = definition.Id; - indexer.Enable = definition.Enable; - indexer.Instance = GetInstance(definition); - indexer.Name = definition.Name; - indexer.Implementation = definition.Implementation; - - if (indexer.Instance.GetType().GetMethod("ImportSettingsFromJson") != null) - { - indexer.Settings = ((dynamic)indexer.Instance).ImportSettingsFromJson(definition.Settings); - } - else - { - indexer.Settings = NullSetting.Instance; - } - - return indexer; - } - - private IIndexer GetInstance(IndexerDefinition indexerDefinition) - { - var type = GetImplementation(indexerDefinition); - var instance = (IIndexer)Activator.CreateInstance(type); - instance.InstanceDefinition = indexerDefinition; - return instance; - } - - private Type GetImplementation(IndexerDefinition indexerDefinition) - { - return _indexers.Select(c => c.GetType()).SingleOrDefault(c => c.Name.Equals(indexerDefinition.Implementation, StringComparison.InvariantCultureIgnoreCase)); - } - - public void Handle(ApplicationStartedEvent message) - { - _logger.Debug("Initializing indexers. Count {0}", _indexers.Count); - - RemoveMissingImplementations(); - - var definitions = _indexers.SelectMany(indexer => indexer.DefaultDefinitions); - - var currentIndexer = All(); - - var newIndexers = definitions.Where(def => currentIndexer.All(c => c.Implementation != def.Implementation)).ToList(); - - - if (newIndexers.Any()) - { - _indexerRepository.InsertMany(newIndexers); - } - } - - private void RemoveMissingImplementations() - { - var storedIndexers = _indexerRepository.All(); - - foreach (var indexerDefinition in storedIndexers.Where(i => GetImplementation(i) == null)) - { - _logger.Debug("Removing Indexer {0} ", indexerDefinition.Name); - _indexerRepository.Delete(indexerDefinition); - } } } } \ No newline at end of file diff --git a/NzbDrone.Core/Indexers/IndexerWithSetting.cs b/NzbDrone.Core/Indexers/IndexerWithSetting.cs deleted file mode 100644 index ecba9f7a9..000000000 --- a/NzbDrone.Core/Indexers/IndexerWithSetting.cs +++ /dev/null @@ -1,22 +0,0 @@ -using NzbDrone.Common.Serializer; -using NzbDrone.Core.ThingiProvider; - -namespace NzbDrone.Core.Indexers -{ - public abstract class IndexerWithSetting : IndexerBase where TSetting : class, IProviderConfig, new() - { - public TSetting Settings { get; set; } - - public override bool EnableByDefault - { - get { return false; } - } - - public TSetting ImportSettingsFromJson(string json) - { - Settings = Json.Deserialize(json) ?? new TSetting(); - - return Settings; - } - } -} \ No newline at end of file diff --git a/NzbDrone.Core/Indexers/Newznab/Newznab.cs b/NzbDrone.Core/Indexers/Newznab/Newznab.cs index e2daf28d6..980513aa0 100644 --- a/NzbDrone.Core/Indexers/Newznab/Newznab.cs +++ b/NzbDrone.Core/Indexers/Newznab/Newznab.cs @@ -2,10 +2,11 @@ using System.Collections.Generic; using System.Linq; using NzbDrone.Common.Serializer; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Indexers.Newznab { - public class Newznab : IndexerWithSetting + public class Newznab : IndexerBase { public override IParseFeed Parser { @@ -15,7 +16,7 @@ public override IParseFeed Parser } } - public override IEnumerable DefaultDefinitions + public override IEnumerable DefaultDefinitions { get { @@ -118,7 +119,7 @@ public override string Name { get { - return InstanceDefinition.Name; + return Definition.Name; } } diff --git a/NzbDrone.Core/Indexers/Omgwtfnzbs/Omgwtfnzbs.cs b/NzbDrone.Core/Indexers/Omgwtfnzbs/Omgwtfnzbs.cs index 15f6dbbe5..4c281910e 100644 --- a/NzbDrone.Core/Indexers/Omgwtfnzbs/Omgwtfnzbs.cs +++ b/NzbDrone.Core/Indexers/Omgwtfnzbs/Omgwtfnzbs.cs @@ -3,7 +3,7 @@ namespace NzbDrone.Core.Indexers.Omgwtfnzbs { - public class Omgwtfnzbs : IndexerWithSetting + public class Omgwtfnzbs : IndexerBase { public override string Name { diff --git a/NzbDrone.Core/Indexers/Wombles/Wombles.cs b/NzbDrone.Core/Indexers/Wombles/Wombles.cs index 95cd559de..2f455219e 100644 --- a/NzbDrone.Core/Indexers/Wombles/Wombles.cs +++ b/NzbDrone.Core/Indexers/Wombles/Wombles.cs @@ -1,9 +1,10 @@ using System; using System.Collections.Generic; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Indexers.Wombles { - public class Wombles : IndexerBase + public class Wombles : IndexerBase { public override string Name { diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index f8d3c3b7c..8cdb8a182 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -241,7 +241,6 @@ - @@ -413,13 +412,14 @@ - + + @@ -618,4 +618,4 @@ --> - \ No newline at end of file + diff --git a/NzbDrone.Core/ThingiProvider/ProviderBase.cs b/NzbDrone.Core/ThingiProvider/IProvider.cs similarity index 56% rename from NzbDrone.Core/ThingiProvider/ProviderBase.cs rename to NzbDrone.Core/ThingiProvider/IProvider.cs index f91577aa9..4d64ea8ec 100644 --- a/NzbDrone.Core/ThingiProvider/ProviderBase.cs +++ b/NzbDrone.Core/ThingiProvider/IProvider.cs @@ -1,38 +1,46 @@  +using System; +using System.Collections.Generic; using FluentValidation.Results; using NzbDrone.Core.Datastore; -using NzbDrone.Core.Indexers; using NzbDrone.Core.Messaging.Events; -using NzbDrone.Core.Notifications; namespace NzbDrone.Core.ThingiProvider { - public class NotificationProviderRepository : BasicRepository + public interface IProviderRepository : IBasicRepository where TProvider : ModelBase, new() { - public NotificationProviderRepository(IDatabase database, IEventAggregator eventAggregator) - : base(database, eventAggregator) - { - } + TProvider GetByName(string name); } - public class IndexerProviderRepository : BasicRepository + public class ProviderRepository : BasicRepository, IProviderRepository + where TProviderDefinition : ModelBase, + new() { - public IndexerProviderRepository(IDatabase database, IEventAggregator eventAggregator) + protected ProviderRepository(IDatabase database, IEventAggregator eventAggregator) : base(database, eventAggregator) { } + + public TProviderDefinition GetByName(string name) + { + throw new NotImplementedException(); + } } - public abstract class ProviderBase + public interface IProvider { - public ProviderDefinition Definition { get; set; } + string Name { get; } + + IEnumerable DefaultDefinitions { get; } + ProviderDefinition Definition { get; set; } } public abstract class ProviderDefinition : ModelBase { public string Name { get; set; } public string Implementation { get; set; } + public bool Enable { get; set; } public string ConfigContract { diff --git a/NzbDrone.Core/ThingiProvider/ProviderService.cs b/NzbDrone.Core/ThingiProvider/ProviderService.cs new file mode 100644 index 000000000..c55529ec1 --- /dev/null +++ b/NzbDrone.Core/ThingiProvider/ProviderService.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NLog; +using NzbDrone.Core.Lifecycle; +using NzbDrone.Core.Messaging.Events; + +namespace NzbDrone.Core.ThingiProvider +{ + public interface IProviderFactory + where TProviderDefinition : ProviderDefinition, new() + where TProvider : IProvider + { + List All(); + List GetAvailableProviders(); + TProviderDefinition Get(int id); + //List Schema(); + TProviderDefinition Create(TProviderDefinition indexer); + void Update(TProviderDefinition indexer); + void Delete(int id); + } + + public abstract class ProviderFactory : IProviderFactory, IHandle + where TProviderDefinition : ProviderDefinition, new() + where TProvider : IProvider + { + private readonly IProviderRepository _providerRepository; + private readonly Logger _logger; + + private readonly List _providers; + + protected ProviderFactory(IProviderRepository providerRepository, IEnumerable providers, Logger logger) + { + _providerRepository = providerRepository; + _providers = providers.ToList(); + _logger = logger; + } + + public List All() + { + return _providerRepository.All().ToList(); + } + + public List GetAvailableProviders() + { + return All().Where(c => c.Enable && c.Settings.Validate().IsValid) + .Select(GetInstance).ToList(); + } + + public TProviderDefinition Get(int id) + { + return _providerRepository.Get(id); + } + + /* public List Schema() + { + var indexers = new List(); + + var newznab = new Indexer(); + newznab.Instance = new Newznab.Newznab(); + newznab.Id = 1; + newznab.Name = "Newznab"; + newznab.Settings = new NewznabSettings(); + newznab.Implementation = "Newznab"; + + indexers.Add(newznab); + + return indexers; + }*/ + + public TProviderDefinition Create(TProviderDefinition provider) + { + return _providerRepository.Insert(provider); + } + + public void Update(TProviderDefinition definition) + { + _providerRepository.Update(definition); + } + + public void Delete(int id) + { + _providerRepository.Delete(id); + } + + private TProvider GetInstance(TProviderDefinition definition) + { + var type = GetImplementation(definition); + var instance = (TProvider)Activator.CreateInstance(type); + instance.Definition = definition; + return instance; + } + + private Type GetImplementation(TProviderDefinition definition) + { + return _providers.Select(c => c.GetType()).SingleOrDefault(c => c.Name.Equals(definition.Implementation, StringComparison.InvariantCultureIgnoreCase)); + } + + public void Handle(ApplicationStartedEvent message) + { + _logger.Debug("Initializing Providers. Count {0}", _providers.Count); + + RemoveMissingImplementations(); + + var definitions = _providers.SelectMany(indexer => indexer.DefaultDefinitions); + + var currentProviders = All(); + + var newProviders = definitions.Where(def => currentProviders.All(c => c.Implementation != def.Implementation)).ToList(); + + + if (newProviders.Any()) + { + _providerRepository.InsertMany(newProviders.Cast().ToList()); + } + } + + private void RemoveMissingImplementations() + { + var storedProvider = _providerRepository.All(); + + foreach (var providerDefinition in storedProvider.Where(i => GetImplementation(i) == null)) + { + _logger.Debug("Removing {0} ", providerDefinition.Name); + _providerRepository.Delete(providerDefinition); + } + } + } +} \ No newline at end of file diff --git a/NzbDrone.ncrunchsolution b/NzbDrone.ncrunchsolution index 098d74afe..28e2de798 100644 --- a/NzbDrone.ncrunchsolution +++ b/NzbDrone.ncrunchsolution @@ -7,7 +7,7 @@ Disabled Disabled Disabled - Run all tests automatically:BFRydWU=;Run all tests manually:BUZhbHNl;Run impacted tests automatically, others manually (experimental!):CklzSW1wYWN0ZWQ=;Run pinned tests automatically, others manually:CElzUGlubmVk;Fast:DlN0cnVjdHVyYWxOb2RlBAAAABNEb2VzTm90SGF2ZUNhdGVnb3J5D0ludGVncmF0aW9uVGVzdBNEb2VzTm90SGF2ZUNhdGVnb3J5BkRiVGVzdApJc0ltcGFjdGVkE0RvZXNOb3RIYXZlQ2F0ZWdvcnkORGlza0FjY2Vzc1Rlc3QAAAAAAAAAAAAAAAA= + Run all tests automatically:BFRydWU=;Run all tests manually:BUZhbHNl;Run impacted tests automatically, others manually (experimental!):CklzSW1wYWN0ZWQ=;Run pinned tests automatically, others manually:CElzUGlubmVk;Fast:DlN0cnVjdHVyYWxOb2RlBQAAABNEb2VzTm90SGF2ZUNhdGVnb3J5D0ludGVncmF0aW9uVGVzdBNEb2VzTm90SGF2ZUNhdGVnb3J5BkRiVGVzdApJc0ltcGFjdGVkE0RvZXNOb3RIYXZlQ2F0ZWdvcnkORGlza0FjY2Vzc1Rlc3QISXNQaW5uZWQAAAAAAAAAAAAAAAABAAAA \ No newline at end of file