mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-12-16 11:37:58 +02:00
created generic provider factory
This commit is contained in:
parent
0b179a6086
commit
9dbfc6804f
@ -36,7 +36,7 @@ public class ResourceMappingFixture : TestBase
|
|||||||
[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(Indexer), typeof(IndexerResource))]
|
[TestCase(typeof(IndexerDefinition), typeof(IndexerResource))]
|
||||||
[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))]
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using NzbDrone.Api.ClientSchema;
|
using NzbDrone.Api.ClientSchema;
|
||||||
using NzbDrone.Api.REST;
|
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
|
using NzbDrone.Core.ThingiProvider;
|
||||||
using Omu.ValueInjecter;
|
using Omu.ValueInjecter;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using NzbDrone.Api.Mapping;
|
using NzbDrone.Api.Mapping;
|
||||||
@ -62,47 +60,36 @@ private int CreateIndexer(IndexerResource indexerResource)
|
|||||||
|
|
||||||
private void UpdateIndexer(IndexerResource indexerResource)
|
private void UpdateIndexer(IndexerResource indexerResource)
|
||||||
{
|
{
|
||||||
var indexer = _indexerService.Get(indexerResource.Id);
|
var indexer = GetIndexer(indexerResource);
|
||||||
indexer.InjectFrom(indexerResource);
|
|
||||||
indexer.Settings = SchemaDeserializer.DeserializeSchema(indexer.Settings, indexerResource.Fields);
|
|
||||||
|
|
||||||
ValidateIndexer(indexer);
|
ValidateIndexer(indexer.Settings);
|
||||||
|
|
||||||
_indexerService.Update(indexer);
|
_indexerService.Update(indexer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void ValidateIndexer(Indexer indexer)
|
private static void ValidateIndexer(IProviderConfig config)
|
||||||
{
|
{
|
||||||
if (indexer.Enable)
|
var validationResult = config.Validate();
|
||||||
{
|
|
||||||
var validationResult = indexer.Settings.Validate();
|
|
||||||
|
|
||||||
if (!validationResult.IsValid)
|
if (!validationResult.IsValid)
|
||||||
{
|
{
|
||||||
throw new ValidationException(validationResult.Errors);
|
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);
|
return definition;
|
||||||
indexer.Settings = SchemaDeserializer.DeserializeSchema(indexer.Settings, indexerResource.Fields);
|
|
||||||
|
|
||||||
ValidateIndexer(indexer);
|
|
||||||
|
|
||||||
return indexer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeleteIndexer(int id)
|
private void DeleteIndexer(int id)
|
||||||
|
@ -18,20 +18,22 @@ public IndexerSchemaModule(IIndexerService indexerService)
|
|||||||
|
|
||||||
private List<IndexerResource> GetSchema()
|
private List<IndexerResource> GetSchema()
|
||||||
{
|
{
|
||||||
var indexers = _indexerService.Schema();
|
/* var indexers = _indexerService.Schema();
|
||||||
|
|
||||||
var result = new List<IndexerResource>(indexers.Count);
|
var result = new List<IndexerResource>(indexers.Count);
|
||||||
|
|
||||||
foreach (var indexer in indexers)
|
foreach (var indexer in indexers)
|
||||||
{
|
{
|
||||||
var indexerResource = new IndexerResource();
|
var indexerResource = new IndexerResource();
|
||||||
indexerResource.InjectFrom(indexer);
|
indexerResource.InjectFrom(indexer);
|
||||||
indexerResource.Fields = SchemaBuilder.GenerateSchema(indexer.Settings);
|
indexerResource.Fields = SchemaBuilder.GenerateSchema(indexer.Settings);
|
||||||
|
|
||||||
result.Add(indexerResource);
|
result.Add(indexerResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;*/
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -57,10 +57,8 @@ public void getting_list_of_indexers()
|
|||||||
var indexers = Subject.All().ToList();
|
var indexers = Subject.All().ToList();
|
||||||
indexers.Should().NotBeEmpty();
|
indexers.Should().NotBeEmpty();
|
||||||
indexers.Should().NotContain(c => c.Settings == null);
|
indexers.Should().NotContain(c => c.Settings == null);
|
||||||
indexers.Should().NotContain(c => c.Instance == null);
|
|
||||||
indexers.Should().NotContain(c => c.Name == null);
|
indexers.Should().NotContain(c => c.Name == null);
|
||||||
indexers.Select(c => c.Name).Should().OnlyHaveUniqueItems();
|
indexers.Select(c => c.Name).Should().OnlyHaveUniqueItems();
|
||||||
indexers.Select(c => c.Instance).Should().OnlyHaveUniqueItems();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,14 +48,14 @@ public void extv_rss()
|
|||||||
public void nzbsorg_rss()
|
public void nzbsorg_rss()
|
||||||
{
|
{
|
||||||
var indexer = new Newznab();
|
var indexer = new Newznab();
|
||||||
indexer.Settings = new NewznabSettings
|
|
||||||
{
|
|
||||||
ApiKey = "64d61d3cfd4b75e51d01cbc7c6a78275",
|
|
||||||
Url = "http://nzbs.org"
|
|
||||||
};
|
|
||||||
|
|
||||||
indexer.InstanceDefinition = new IndexerDefinition();
|
indexer.Definition = new IndexerDefinition();
|
||||||
indexer.InstanceDefinition.Name = "nzbs.org";
|
indexer.Definition.Name = "nzbs.org";
|
||||||
|
indexer.Definition.Settings = new NewznabSettings
|
||||||
|
{
|
||||||
|
ApiKey = "64d61d3cfd4b75e51d01cbc7c6a78275",
|
||||||
|
Url = "http://nzbs.org"
|
||||||
|
};
|
||||||
|
|
||||||
var result = Subject.FetchRss(indexer);
|
var result = Subject.FetchRss(indexer);
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
namespace NzbDrone.Core.Test.ThingiProvider
|
namespace NzbDrone.Core.Test.ThingiProvider
|
||||||
{
|
{
|
||||||
|
|
||||||
public class ProviderRepositoryFixture : DbTest<IndexerProviderRepository, IndexerDefinition>
|
public class ProviderRepositoryFixture : DbTest<ProviderRepository<IndexerDefinition>, IndexerDefinition>
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public void should_read_write_download_provider()
|
public void should_read_write_download_provider()
|
||||||
|
@ -132,7 +132,7 @@ public List<DownloadDecision> SeasonSearch(int seriesId, int seasonNumber)
|
|||||||
|
|
||||||
private List<DownloadDecision> Dispatch(Func<IIndexer, IEnumerable<ReleaseInfo>> searchAction, SearchCriteriaBase criteriaBase)
|
private List<DownloadDecision> Dispatch(Func<IIndexer, IEnumerable<ReleaseInfo>> searchAction, SearchCriteriaBase criteriaBase)
|
||||||
{
|
{
|
||||||
var indexers = _indexerService.GetAvailableIndexers().ToList();
|
var indexers = _indexerService.GetAvailableProviders().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);
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers.Eztv
|
namespace NzbDrone.Core.Indexers.Eztv
|
||||||
{
|
{
|
||||||
public class Eztv : IndexerBase
|
public class Eztv : IndexerBase<NullSetting>
|
||||||
{
|
{
|
||||||
public override string Name
|
public override string Name
|
||||||
{
|
{
|
||||||
|
@ -29,7 +29,7 @@ public List<ReleaseInfo> Fetch()
|
|||||||
{
|
{
|
||||||
var result = new List<ReleaseInfo>();
|
var result = new List<ReleaseInfo>();
|
||||||
|
|
||||||
var indexers = _indexerService.GetAvailableIndexers().ToList();
|
var indexers = _indexerService.GetAvailableProviders().ToList();
|
||||||
|
|
||||||
if (!indexers.Any())
|
if (!indexers.Any())
|
||||||
{
|
{
|
||||||
|
@ -1,23 +1,15 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers
|
namespace NzbDrone.Core.Indexers
|
||||||
{
|
{
|
||||||
public interface IIndexer
|
public interface IIndexer : IProvider
|
||||||
{
|
{
|
||||||
string Name { get; }
|
|
||||||
|
|
||||||
bool EnableByDefault { get; }
|
|
||||||
|
|
||||||
IEnumerable<IndexerDefinition> DefaultDefinitions { get; }
|
|
||||||
|
|
||||||
IndexerDefinition InstanceDefinition { get; set; }
|
|
||||||
|
|
||||||
IEnumerable<string> RecentFeed { get; }
|
|
||||||
|
|
||||||
IParseFeed Parser { get; }
|
IParseFeed Parser { get; }
|
||||||
IndexerKind Kind { get; }
|
IndexerKind Kind { get; }
|
||||||
|
|
||||||
|
IEnumerable<string> RecentFeed { get; }
|
||||||
IEnumerable<string> GetEpisodeSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int episodeNumber);
|
IEnumerable<string> GetEpisodeSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int episodeNumber);
|
||||||
IEnumerable<string> GetDailyEpisodeSearchUrls(string seriesTitle, int tvRageId, DateTime date);
|
IEnumerable<string> GetDailyEpisodeSearchUrls(string seriesTitle, int tvRageId, DateTime date);
|
||||||
IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset);
|
IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset);
|
||||||
|
@ -4,30 +4,38 @@
|
|||||||
|
|
||||||
namespace NzbDrone.Core.Indexers
|
namespace NzbDrone.Core.Indexers
|
||||||
{
|
{
|
||||||
public abstract class IndexerBase : IIndexer
|
public abstract class IndexerBase<TSettings> : IIndexer
|
||||||
{
|
{
|
||||||
public abstract string Name { get; }
|
public abstract string Name { get; }
|
||||||
|
|
||||||
public abstract IndexerKind Kind { get; }
|
public virtual IEnumerable<ProviderDefinition> DefaultDefinitions
|
||||||
|
|
||||||
public virtual bool EnableByDefault { get { return true; } }
|
|
||||||
|
|
||||||
public IndexerDefinition InstanceDefinition { get; set; }
|
|
||||||
|
|
||||||
public virtual IEnumerable<IndexerDefinition> DefaultDefinitions
|
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
yield return new IndexerDefinition
|
yield return new IndexerDefinition
|
||||||
{
|
{
|
||||||
Name = Name,
|
Name = Name,
|
||||||
Enable = EnableByDefault,
|
Enable = false,
|
||||||
Implementation = GetType().Name,
|
Implementation = GetType().Name,
|
||||||
Settings = NullSetting.Instance
|
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 virtual IParseFeed Parser { get; private set; }
|
||||||
|
|
||||||
public abstract IEnumerable<string> RecentFeed { get; }
|
public abstract IEnumerable<string> RecentFeed { get; }
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
using System;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
using NzbDrone.Core.Datastore;
|
|
||||||
using NzbDrone.Core.ThingiProvider;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers
|
namespace NzbDrone.Core.Indexers
|
||||||
{
|
{
|
||||||
public class IndexerDefinition : ProviderDefinition
|
public class IndexerDefinition : ProviderDefinition
|
||||||
{
|
{
|
||||||
public Boolean Enable { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,202 +1,19 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using NLog;
|
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 NzbDrone.Core.ThingiProvider;
|
||||||
using Omu.ValueInjecter;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers
|
namespace NzbDrone.Core.Indexers
|
||||||
{
|
{
|
||||||
public class Indexer
|
public interface IIndexerService : IProviderFactory<IIndexer, IndexerDefinition>
|
||||||
{
|
{
|
||||||
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<IIndexer, IndexerDefinition>
|
||||||
{
|
{
|
||||||
List<Indexer> All();
|
public IndexerService(IProviderRepository<IndexerDefinition> providerRepository, IEnumerable<IIndexer> providers, Logger logger)
|
||||||
List<IIndexer> GetAvailableIndexers();
|
: base(providerRepository, providers, logger)
|
||||||
Indexer Get(int id);
|
|
||||||
Indexer Get(string name);
|
|
||||||
List<Indexer> Schema();
|
|
||||||
Indexer Create(Indexer indexer);
|
|
||||||
Indexer Update(Indexer indexer);
|
|
||||||
void Delete(int id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class IndexerService : IIndexerService, IHandle<ApplicationStartedEvent>
|
|
||||||
{
|
|
||||||
private readonly IIndexerRepository _indexerRepository;
|
|
||||||
private readonly IConfigFileProvider _configFileProvider;
|
|
||||||
private readonly INewznabTestService _newznabTestService;
|
|
||||||
private readonly Logger _logger;
|
|
||||||
|
|
||||||
private readonly List<IIndexer> _indexers;
|
|
||||||
|
|
||||||
public IndexerService(IIndexerRepository indexerRepository,
|
|
||||||
IEnumerable<IIndexer> indexers,
|
|
||||||
IConfigFileProvider configFileProvider,
|
|
||||||
INewznabTestService newznabTestService,
|
|
||||||
Logger 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<Indexer> All()
|
|
||||||
{
|
|
||||||
return _indexerRepository.All().Select(ToIndexer).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<IIndexer> 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<Indexer> Schema()
|
|
||||||
{
|
|
||||||
var indexers = new List<Indexer>();
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,22 +0,0 @@
|
|||||||
using NzbDrone.Common.Serializer;
|
|
||||||
using NzbDrone.Core.ThingiProvider;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers
|
|
||||||
{
|
|
||||||
public abstract class IndexerWithSetting<TSetting> : 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<TSetting>(json) ?? new TSetting();
|
|
||||||
|
|
||||||
return Settings;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,10 +2,11 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers.Newznab
|
namespace NzbDrone.Core.Indexers.Newznab
|
||||||
{
|
{
|
||||||
public class Newznab : IndexerWithSetting<NewznabSettings>
|
public class Newznab : IndexerBase<NewznabSettings>
|
||||||
{
|
{
|
||||||
public override IParseFeed Parser
|
public override IParseFeed Parser
|
||||||
{
|
{
|
||||||
@ -15,7 +16,7 @@ public override IParseFeed Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<IndexerDefinition> DefaultDefinitions
|
public override IEnumerable<ProviderDefinition> DefaultDefinitions
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@ -118,7 +119,7 @@ public override string Name
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return InstanceDefinition.Name;
|
return Definition.Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
namespace NzbDrone.Core.Indexers.Omgwtfnzbs
|
namespace NzbDrone.Core.Indexers.Omgwtfnzbs
|
||||||
{
|
{
|
||||||
public class Omgwtfnzbs : IndexerWithSetting<OmgwtfnzbsSettings>
|
public class Omgwtfnzbs : IndexerBase<OmgwtfnzbsSettings>
|
||||||
{
|
{
|
||||||
public override string Name
|
public override string Name
|
||||||
{
|
{
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers.Wombles
|
namespace NzbDrone.Core.Indexers.Wombles
|
||||||
{
|
{
|
||||||
public class Wombles : IndexerBase
|
public class Wombles : IndexerBase<NullSetting>
|
||||||
{
|
{
|
||||||
public override string Name
|
public override string Name
|
||||||
{
|
{
|
||||||
|
@ -241,7 +241,6 @@
|
|||||||
<Compile Include="Indexers\IIndexer.cs" />
|
<Compile Include="Indexers\IIndexer.cs" />
|
||||||
<Compile Include="Indexers\IndexerSettingUpdatedEvent.cs" />
|
<Compile Include="Indexers\IndexerSettingUpdatedEvent.cs" />
|
||||||
<Compile Include="Indexers\NewznabTestService.cs" />
|
<Compile Include="Indexers\NewznabTestService.cs" />
|
||||||
<Compile Include="Indexers\IndexerWithSetting.cs" />
|
|
||||||
<Compile Include="Indexers\IParseFeed.cs" />
|
<Compile Include="Indexers\IParseFeed.cs" />
|
||||||
<Compile Include="Indexers\Newznab\NewznabException.cs" />
|
<Compile Include="Indexers\Newznab\NewznabException.cs" />
|
||||||
<Compile Include="Indexers\Newznab\NewznabPreProcessor.cs" />
|
<Compile Include="Indexers\Newznab\NewznabPreProcessor.cs" />
|
||||||
@ -413,13 +412,14 @@
|
|||||||
<Compile Include="Parser\Parser.cs" />
|
<Compile Include="Parser\Parser.cs" />
|
||||||
<Compile Include="Parser\ParsingService.cs" />
|
<Compile Include="Parser\ParsingService.cs" />
|
||||||
<Compile Include="Parser\QualityParser.cs" />
|
<Compile Include="Parser\QualityParser.cs" />
|
||||||
<Compile Include="ThingiProvider\ProviderBase.cs" />
|
<Compile Include="ThingiProvider\IProvider.cs" />
|
||||||
<Compile Include="Qualities\QualityProfileInUseException.cs" />
|
<Compile Include="Qualities\QualityProfileInUseException.cs" />
|
||||||
<Compile Include="Qualities\QualitySizeRepository.cs" />
|
<Compile Include="Qualities\QualitySizeRepository.cs" />
|
||||||
<Compile Include="Qualities\QualityProfileRepository.cs" />
|
<Compile Include="Qualities\QualityProfileRepository.cs" />
|
||||||
<Compile Include="Rest\RestSharpExtensions.cs" />
|
<Compile Include="Rest\RestSharpExtensions.cs" />
|
||||||
<Compile Include="Rest\RestException.cs" />
|
<Compile Include="Rest\RestException.cs" />
|
||||||
<Compile Include="SeriesStats\SeriesStatisticsService.cs" />
|
<Compile Include="SeriesStats\SeriesStatisticsService.cs" />
|
||||||
|
<Compile Include="ThingiProvider\ProviderService.cs" />
|
||||||
<Compile Include="Tv\EpisodeService.cs" />
|
<Compile Include="Tv\EpisodeService.cs" />
|
||||||
<Compile Include="Tv\Events\EpisodeInfoDeletedEvent.cs" />
|
<Compile Include="Tv\Events\EpisodeInfoDeletedEvent.cs" />
|
||||||
<Compile Include="Tv\Events\EpisodeInfoUpdatedEvent.cs" />
|
<Compile Include="Tv\Events\EpisodeInfoUpdatedEvent.cs" />
|
||||||
|
@ -1,38 +1,46 @@
|
|||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.Indexers;
|
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.Notifications;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.ThingiProvider
|
namespace NzbDrone.Core.ThingiProvider
|
||||||
{
|
{
|
||||||
public class NotificationProviderRepository : BasicRepository<NotificationDefinition>
|
public interface IProviderRepository<TProvider> : IBasicRepository<TProvider> where TProvider : ModelBase, new()
|
||||||
{
|
{
|
||||||
public NotificationProviderRepository(IDatabase database, IEventAggregator eventAggregator)
|
TProvider GetByName(string name);
|
||||||
: base(database, eventAggregator)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class IndexerProviderRepository : BasicRepository<IndexerDefinition>
|
public class ProviderRepository<TProviderDefinition> : BasicRepository<TProviderDefinition>, IProviderRepository<TProviderDefinition>
|
||||||
|
where TProviderDefinition : ModelBase,
|
||||||
|
new()
|
||||||
{
|
{
|
||||||
public IndexerProviderRepository(IDatabase database, IEventAggregator eventAggregator)
|
protected ProviderRepository(IDatabase database, IEventAggregator eventAggregator)
|
||||||
: base(database, 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<ProviderDefinition> DefaultDefinitions { get; }
|
||||||
|
ProviderDefinition Definition { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class ProviderDefinition : ModelBase
|
public abstract class ProviderDefinition : ModelBase
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string Implementation { get; set; }
|
public string Implementation { get; set; }
|
||||||
|
public bool Enable { get; set; }
|
||||||
|
|
||||||
public string ConfigContract
|
public string ConfigContract
|
||||||
{
|
{
|
129
NzbDrone.Core/ThingiProvider/ProviderService.cs
Normal file
129
NzbDrone.Core/ThingiProvider/ProviderService.cs
Normal file
@ -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<TProvider, TProviderDefinition>
|
||||||
|
where TProviderDefinition : ProviderDefinition, new()
|
||||||
|
where TProvider : IProvider
|
||||||
|
{
|
||||||
|
List<TProviderDefinition> All();
|
||||||
|
List<TProvider> GetAvailableProviders();
|
||||||
|
TProviderDefinition Get(int id);
|
||||||
|
//List<TProvider> Schema();
|
||||||
|
TProviderDefinition Create(TProviderDefinition indexer);
|
||||||
|
void Update(TProviderDefinition indexer);
|
||||||
|
void Delete(int id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class ProviderFactory<TProvider, TProviderDefinition> : IProviderFactory<TProvider, TProviderDefinition>, IHandle<ApplicationStartedEvent>
|
||||||
|
where TProviderDefinition : ProviderDefinition, new()
|
||||||
|
where TProvider : IProvider
|
||||||
|
{
|
||||||
|
private readonly IProviderRepository<TProviderDefinition> _providerRepository;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
private readonly List<TProvider> _providers;
|
||||||
|
|
||||||
|
protected ProviderFactory(IProviderRepository<TProviderDefinition> providerRepository, IEnumerable<TProvider> providers, Logger logger)
|
||||||
|
{
|
||||||
|
_providerRepository = providerRepository;
|
||||||
|
_providers = providers.ToList();
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TProviderDefinition> All()
|
||||||
|
{
|
||||||
|
return _providerRepository.All().ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TProvider> 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<TProvider> Schema()
|
||||||
|
{
|
||||||
|
var indexers = new List<Indexer>();
|
||||||
|
|
||||||
|
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<TProviderDefinition>().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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,7 @@
|
|||||||
<FrameworkUtilisationTypeForGallio>Disabled</FrameworkUtilisationTypeForGallio>
|
<FrameworkUtilisationTypeForGallio>Disabled</FrameworkUtilisationTypeForGallio>
|
||||||
<FrameworkUtilisationTypeForMSpec>Disabled</FrameworkUtilisationTypeForMSpec>
|
<FrameworkUtilisationTypeForMSpec>Disabled</FrameworkUtilisationTypeForMSpec>
|
||||||
<FrameworkUtilisationTypeForMSTest>Disabled</FrameworkUtilisationTypeForMSTest>
|
<FrameworkUtilisationTypeForMSTest>Disabled</FrameworkUtilisationTypeForMSTest>
|
||||||
<EngineModes>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=</EngineModes>
|
<EngineModes>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</EngineModes>
|
||||||
<MetricsExclusionList>
|
<MetricsExclusionList>
|
||||||
</MetricsExclusionList>
|
</MetricsExclusionList>
|
||||||
</SolutionConfiguration>
|
</SolutionConfiguration>
|
Loading…
Reference in New Issue
Block a user