using System; using System.Collections.Generic; using System.Linq; using FluentValidation.Results; using NLog; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.Parser; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Indexers { public abstract class IndexerBase : IIndexer where TSettings : IProviderConfig, new() { protected readonly IIndexerStatusService _indexerStatusService; protected readonly IConfigService _configService; protected readonly IParsingService _parsingService; protected readonly Logger _logger; public abstract string Name { get; } public abstract DownloadProtocol Protocol { get; } public abstract bool SupportsRss { get; } public abstract bool SupportsSearch { get; } public IndexerBase(IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger) { _indexerStatusService = indexerStatusService; _configService = configService; _parsingService = parsingService; _logger = logger; } public Type ConfigContract { get { return typeof(TSettings); } } public virtual ProviderMessage Message { get { return null; } } public virtual IEnumerable DefaultDefinitions { get { var config = (IProviderConfig)new TSettings(); yield return new IndexerDefinition { Name = GetType().Name, EnableRss = config.Validate().IsValid && SupportsRss, EnableSearch = config.Validate().IsValid && SupportsSearch, Implementation = GetType().Name, Settings = config }; } } public virtual ProviderDefinition Definition { get; set; } public object ConnectData(string stage, IDictionary query) { return null; } protected TSettings Settings { get { return (TSettings)Definition.Settings; } } public abstract IList FetchRecent(); public abstract IList Fetch(SeasonSearchCriteria searchCriteria); public abstract IList Fetch(SingleEpisodeSearchCriteria searchCriteria); public abstract IList Fetch(DailyEpisodeSearchCriteria searchCriteria); public abstract IList Fetch(AnimeEpisodeSearchCriteria searchCriteria); public abstract IList Fetch(SpecialEpisodeSearchCriteria searchCriteria); protected virtual IList CleanupReleases(IEnumerable releases) { var result = releases.DistinctBy(v => v.Guid).ToList(); result.ForEach(c => { c.IndexerId = Definition.Id; c.Indexer = Definition.Name; c.DownloadProtocol = Protocol; }); return result; } public ValidationResult Test() { var failures = new List(); try { Test(failures); } catch (Exception ex) { _logger.ErrorException("Test aborted due to exception", ex); failures.Add(new ValidationFailure(string.Empty, "Test was aborted due to an error: " + ex.Message)); } if (Definition.Id != 0) { _indexerStatusService.RecordSuccess(Definition.Id); } return new ValidationResult(failures); } protected abstract void Test(List failures); public override string ToString() { return Definition.Name; } } }