mirror of https://github.com/Sonarr/Sonarr
created generic provider factory
This commit is contained in:
parent
0b179a6086
commit
9dbfc6804f
|
@ -36,7 +36,7 @@ namespace NzbDrone.Api.Test.MappingTests
|
|||
[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))]
|
||||
|
|
|
@ -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 @@ namespace NzbDrone.Api.Indexers
|
|||
|
||||
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)
|
||||
|
|
|
@ -18,20 +18,22 @@ namespace NzbDrone.Api.Indexers
|
|||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -57,10 +57,8 @@ namespace NzbDrone.Core.Test.IndexerTests
|
|||
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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -48,14 +48,14 @@ namespace NzbDrone.Core.Test.IndexerTests.IntegrationTests
|
|||
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);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ using NzbDrone.Core.ThingiProvider;
|
|||
namespace NzbDrone.Core.Test.ThingiProvider
|
||||
{
|
||||
|
||||
public class ProviderRepositoryFixture : DbTest<IndexerProviderRepository, IndexerDefinition>
|
||||
public class ProviderRepositoryFixture : DbTest<ProviderRepository<IndexerDefinition>, IndexerDefinition>
|
||||
{
|
||||
[Test]
|
||||
public void should_read_write_download_provider()
|
||||
|
|
|
@ -132,7 +132,7 @@ namespace NzbDrone.Core.IndexerSearch
|
|||
|
||||
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>();
|
||||
|
||||
_logger.ProgressInfo("Searching {0} indexers for {1}", indexers.Count, criteriaBase);
|
||||
|
|
|
@ -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<NullSetting>
|
||||
{
|
||||
public override string Name
|
||||
{
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace NzbDrone.Core.Indexers
|
|||
{
|
||||
var result = new List<ReleaseInfo>();
|
||||
|
||||
var indexers = _indexerService.GetAvailableIndexers().ToList();
|
||||
var indexers = _indexerService.GetAvailableProviders().ToList();
|
||||
|
||||
if (!indexers.Any())
|
||||
{
|
||||
|
|
|
@ -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<IndexerDefinition> DefaultDefinitions { get; }
|
||||
|
||||
IndexerDefinition InstanceDefinition { get; set; }
|
||||
|
||||
IEnumerable<string> RecentFeed { get; }
|
||||
|
||||
IParseFeed Parser { get; }
|
||||
IndexerKind Kind { get; }
|
||||
|
||||
IEnumerable<string> RecentFeed { get; }
|
||||
IEnumerable<string> GetEpisodeSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int episodeNumber);
|
||||
IEnumerable<string> GetDailyEpisodeSearchUrls(string seriesTitle, int tvRageId, DateTime date);
|
||||
IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset);
|
||||
|
|
|
@ -4,30 +4,38 @@ using NzbDrone.Core.ThingiProvider;
|
|||
|
||||
namespace NzbDrone.Core.Indexers
|
||||
{
|
||||
public abstract class IndexerBase : IIndexer
|
||||
public abstract class IndexerBase<TSettings> : 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<IndexerDefinition> DefaultDefinitions
|
||||
public virtual IEnumerable<ProviderDefinition> 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<string> RecentFeed { get; }
|
||||
|
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -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<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();
|
||||
List<IIndexer> GetAvailableIndexers();
|
||||
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)
|
||||
public IndexerService(IProviderRepository<IndexerDefinition> providerRepository, IEnumerable<IIndexer> 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<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.Linq;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.Newznab
|
||||
{
|
||||
public class Newznab : IndexerWithSetting<NewznabSettings>
|
||||
public class Newznab : IndexerBase<NewznabSettings>
|
||||
{
|
||||
public override IParseFeed Parser
|
||||
{
|
||||
|
@ -15,7 +16,7 @@ namespace NzbDrone.Core.Indexers.Newznab
|
|||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<IndexerDefinition> DefaultDefinitions
|
||||
public override IEnumerable<ProviderDefinition> DefaultDefinitions
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -118,7 +119,7 @@ namespace NzbDrone.Core.Indexers.Newznab
|
|||
{
|
||||
get
|
||||
{
|
||||
return InstanceDefinition.Name;
|
||||
return Definition.Name;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||
|
||||
namespace NzbDrone.Core.Indexers.Omgwtfnzbs
|
||||
{
|
||||
public class Omgwtfnzbs : IndexerWithSetting<OmgwtfnzbsSettings>
|
||||
public class Omgwtfnzbs : IndexerBase<OmgwtfnzbsSettings>
|
||||
{
|
||||
public override string Name
|
||||
{
|
||||
|
|
|
@ -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<NullSetting>
|
||||
{
|
||||
public override string Name
|
||||
{
|
||||
|
|
|
@ -241,7 +241,6 @@
|
|||
<Compile Include="Indexers\IIndexer.cs" />
|
||||
<Compile Include="Indexers\IndexerSettingUpdatedEvent.cs" />
|
||||
<Compile Include="Indexers\NewznabTestService.cs" />
|
||||
<Compile Include="Indexers\IndexerWithSetting.cs" />
|
||||
<Compile Include="Indexers\IParseFeed.cs" />
|
||||
<Compile Include="Indexers\Newznab\NewznabException.cs" />
|
||||
<Compile Include="Indexers\Newznab\NewznabPreProcessor.cs" />
|
||||
|
@ -413,13 +412,14 @@
|
|||
<Compile Include="Parser\Parser.cs" />
|
||||
<Compile Include="Parser\ParsingService.cs" />
|
||||
<Compile Include="Parser\QualityParser.cs" />
|
||||
<Compile Include="ThingiProvider\ProviderBase.cs" />
|
||||
<Compile Include="ThingiProvider\IProvider.cs" />
|
||||
<Compile Include="Qualities\QualityProfileInUseException.cs" />
|
||||
<Compile Include="Qualities\QualitySizeRepository.cs" />
|
||||
<Compile Include="Qualities\QualityProfileRepository.cs" />
|
||||
<Compile Include="Rest\RestSharpExtensions.cs" />
|
||||
<Compile Include="Rest\RestException.cs" />
|
||||
<Compile Include="SeriesStats\SeriesStatisticsService.cs" />
|
||||
<Compile Include="ThingiProvider\ProviderService.cs" />
|
||||
<Compile Include="Tv\EpisodeService.cs" />
|
||||
<Compile Include="Tv\Events\EpisodeInfoDeletedEvent.cs" />
|
||||
<Compile Include="Tv\Events\EpisodeInfoUpdatedEvent.cs" />
|
||||
|
@ -618,4 +618,4 @@
|
|||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -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<NotificationDefinition>
|
||||
public interface IProviderRepository<TProvider> : IBasicRepository<TProvider> where TProvider : ModelBase, new()
|
||||
{
|
||||
public NotificationProviderRepository(IDatabase database, IEventAggregator eventAggregator)
|
||||
: base(database, eventAggregator)
|
||||
{
|
||||
}
|
||||
TProvider GetByName(string name);
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
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 string Name { get; set; }
|
||||
public string Implementation { get; set; }
|
||||
public bool Enable { get; set; }
|
||||
|
||||
public string ConfigContract
|
||||
{
|
|
@ -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>
|
||||
<FrameworkUtilisationTypeForMSpec>Disabled</FrameworkUtilisationTypeForMSpec>
|
||||
<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>
|
||||
</SolutionConfiguration>
|
Loading…
Reference in New Issue