From d1a4c7c942420b0541bae7e1d5ef6a7ff4222d34 Mon Sep 17 00:00:00 2001 From: Keivan Beigi Date: Fri, 20 Sep 2013 17:18:11 -0700 Subject: [PATCH 01/16] something! --- NzbDrone.Core.Test/NzbDrone.Core.Test.csproj | 1 + .../ThingiProvider/ProviderBaseFixture.cs | 23 +++++++++ NzbDrone.Core/NzbDrone.Core.csproj | 1 + NzbDrone.Core/ThingiProvider/ProviderBase.cs | 49 +++++++++++++++++++ 4 files changed, 74 insertions(+) create mode 100644 NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs create mode 100644 NzbDrone.Core/ThingiProvider/ProviderBase.cs diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index 58b09e81e..430b4d934 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -181,6 +181,7 @@ + diff --git a/NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs b/NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs new file mode 100644 index 000000000..11006aa42 --- /dev/null +++ b/NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs @@ -0,0 +1,23 @@ +using NUnit.Framework; +using NzbDrone.Core.Test.Datastore; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Core.ThingiProvider; + +namespace NzbDrone.Core.Test.ThingiProvider +{ + + public class ProviderRepositoryFixture : DbTest + { + [Test] + public void should_read_write_download_provider() + { + var model = new DownloadProviderModel(); + + model.Config = new DownloadProviderConfig(); + + //Subject.Insert(new ) + } + + + } +} \ No newline at end of file diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 23d3657e3..2ab111e2a 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -416,6 +416,7 @@ + diff --git a/NzbDrone.Core/ThingiProvider/ProviderBase.cs b/NzbDrone.Core/ThingiProvider/ProviderBase.cs new file mode 100644 index 000000000..61035d7de --- /dev/null +++ b/NzbDrone.Core/ThingiProvider/ProviderBase.cs @@ -0,0 +1,49 @@ + +using NzbDrone.Core.Datastore; +using NzbDrone.Core.Messaging.Events; + +namespace NzbDrone.Core.ThingiProvider +{ + + + public class DownloadProviderRepository : BasicRepository + { + public DownloadProviderRepository(IDatabase database, IEventAggregator eventAggregator) + : base(database, eventAggregator) + { + } + } + + public class DownloadProviderModel : Provider + { + + } + + public class DownloadProviderConfig : ProviderSetting + { + + } + + + public abstract class Provider : ModelBase + where TSettings : ProviderSetting + { + public string Implementation { get; set; } + public TSettings Config { get; set; } + } + + public abstract class ProviderSetting : IEmbeddedDocument + { + + } + + public abstract class ProviderBase where TSettings : ProviderSetting + { + public TSettings Settings { get; private set; } + + public void LoadSettings(TSettings setting) + { + Settings = setting; + } + } +} \ No newline at end of file From 08e2d60f20936344b25301d5e128e7d54bfbe591 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Fri, 20 Sep 2013 23:38:27 -0700 Subject: [PATCH 02/16] added ConverterContext to marr Converters. --- Marr.Data/Converters/BooleanIntConverter.cs | 13 ++++-- Marr.Data/Converters/BooleanYNConverter.cs | 13 ++++-- Marr.Data/Converters/CastConverter.cs | 9 +++- Marr.Data/Converters/ConverterContext.cs | 13 ++++++ Marr.Data/Converters/EnumIntConverter.cs | 11 +++-- Marr.Data/Converters/EnumStringConverter.cs | 11 +++-- Marr.Data/Converters/IConverter.cs | 3 ++ Marr.Data/Mapping/MappingHelper.cs | 11 ++++- Marr.Data/Marr.Data.csproj | 1 + .../Converters/BooleanIntConverter.cs | 13 ++++-- .../Converters/EmbeddedDocumentConverter.cs | 45 ++++++++++++++++--- .../Datastore/Converters/EnumIntConverter.cs | 11 +++-- .../Datastore/Converters/Int32Converter.cs | 15 +++++++ .../Converters/QualityIntConverter.cs | 11 +++-- .../Datastore/Converters/UtcConverter.cs | 7 ++- 15 files changed, 153 insertions(+), 34 deletions(-) create mode 100644 Marr.Data/Converters/ConverterContext.cs diff --git a/Marr.Data/Converters/BooleanIntConverter.cs b/Marr.Data/Converters/BooleanIntConverter.cs index 9dc9b41d3..18c964d15 100644 --- a/Marr.Data/Converters/BooleanIntConverter.cs +++ b/Marr.Data/Converters/BooleanIntConverter.cs @@ -20,14 +20,14 @@ namespace Marr.Data.Converters { public class BooleanIntConverter : IConverter { - public object FromDB(ColumnMap map, object dbValue) + public object FromDB(ConverterContext context) { - if (dbValue == DBNull.Value) + if (context.DbValue == DBNull.Value) { return DBNull.Value; } - int val = (int)dbValue; + int val = (int)context.DbValue; if (val == 1) { @@ -40,7 +40,12 @@ namespace Marr.Data.Converters throw new ConversionException( string.Format( "The BooleanCharConverter could not convert the value '{0}' to a boolean.", - dbValue)); + context.DbValue)); + } + + public object FromDB(ColumnMap map, object dbValue) + { + return FromDB(new ConverterContext { ColumnMap = map, DbValue = dbValue }); } public object ToDB(object clrValue) diff --git a/Marr.Data/Converters/BooleanYNConverter.cs b/Marr.Data/Converters/BooleanYNConverter.cs index b116bdeaf..38003939c 100644 --- a/Marr.Data/Converters/BooleanYNConverter.cs +++ b/Marr.Data/Converters/BooleanYNConverter.cs @@ -20,14 +20,14 @@ namespace Marr.Data.Converters { public class BooleanYNConverter : IConverter { - public object FromDB(ColumnMap map, object dbValue) + public object FromDB(ConverterContext context) { - if (dbValue == DBNull.Value) + if (context.DbValue == DBNull.Value) { return DBNull.Value; } - string val = dbValue.ToString(); + string val = context.DbValue.ToString(); if (val == "Y") { @@ -40,7 +40,12 @@ namespace Marr.Data.Converters throw new ConversionException( string.Format( "The BooleanYNConverter could not convert the value '{0}' to a boolean.", - dbValue)); + context.DbValue)); + } + + public object FromDB(ColumnMap map, object dbValue) + { + return FromDB(new ConverterContext {ColumnMap = map, DbValue = dbValue}); } public object ToDB(object clrValue) diff --git a/Marr.Data/Converters/CastConverter.cs b/Marr.Data/Converters/CastConverter.cs index 4253357ed..2fa3b8eca 100644 --- a/Marr.Data/Converters/CastConverter.cs +++ b/Marr.Data/Converters/CastConverter.cs @@ -30,10 +30,15 @@ namespace Marr.Data.Converters get { return typeof(TDb); } } + public object FromDB(ConverterContext context) + { + TDb val = (TDb)context.DbValue; + return val.ToType(typeof(TClr), CultureInfo.InvariantCulture); + } + public object FromDB(ColumnMap map, object dbValue) { - TDb val = (TDb)dbValue; - return val.ToType(typeof(TClr), CultureInfo.InvariantCulture); + return FromDB(new ConverterContext { ColumnMap = map, DbValue = dbValue }); } public object ToDB(object clrValue) diff --git a/Marr.Data/Converters/ConverterContext.cs b/Marr.Data/Converters/ConverterContext.cs new file mode 100644 index 000000000..341925077 --- /dev/null +++ b/Marr.Data/Converters/ConverterContext.cs @@ -0,0 +1,13 @@ +using System.Data; +using Marr.Data.Mapping; + +namespace Marr.Data.Converters +{ + public class ConverterContext + { + public ColumnMap ColumnMap { get; set; } + public object DbValue { get; set; } + public ColumnMapCollection MapCollection { get; set; } + public IDataRecord DataRecord { get; set; } + } +} \ No newline at end of file diff --git a/Marr.Data/Converters/EnumIntConverter.cs b/Marr.Data/Converters/EnumIntConverter.cs index a7d528d16..5fe88a411 100644 --- a/Marr.Data/Converters/EnumIntConverter.cs +++ b/Marr.Data/Converters/EnumIntConverter.cs @@ -20,11 +20,16 @@ namespace Marr.Data.Converters { public class EnumIntConverter : IConverter { + public object FromDB(ConverterContext context) + { + if (context.DbValue == null || context.DbValue == DBNull.Value) + return null; + return Enum.ToObject(context.ColumnMap.FieldType, (int)context.DbValue); + } + public object FromDB(ColumnMap map, object dbValue) { - if (dbValue == null || dbValue == DBNull.Value) - return null; - return Enum.ToObject(map.FieldType, (int)dbValue); + return FromDB(new ConverterContext { ColumnMap = map, DbValue = dbValue }); } public object ToDB(object clrValue) diff --git a/Marr.Data/Converters/EnumStringConverter.cs b/Marr.Data/Converters/EnumStringConverter.cs index 4e304fc10..eb4f8b01a 100644 --- a/Marr.Data/Converters/EnumStringConverter.cs +++ b/Marr.Data/Converters/EnumStringConverter.cs @@ -20,11 +20,16 @@ namespace Marr.Data.Converters { public class EnumStringConverter : IConverter { + public object FromDB(ConverterContext context) + { + if (context.DbValue == null || context.DbValue == DBNull.Value) + return null; + return Enum.Parse(context.ColumnMap.FieldType, (string)context.DbValue); + } + public object FromDB(ColumnMap map, object dbValue) { - if (dbValue == null || dbValue == DBNull.Value) - return null; - return Enum.Parse(map.FieldType, (string)dbValue); + return FromDB(new ConverterContext { ColumnMap = map, DbValue = dbValue }); } public object ToDB(object clrValue) diff --git a/Marr.Data/Converters/IConverter.cs b/Marr.Data/Converters/IConverter.cs index 318f26957..f2e9685a9 100644 --- a/Marr.Data/Converters/IConverter.cs +++ b/Marr.Data/Converters/IConverter.cs @@ -20,6 +20,9 @@ namespace Marr.Data.Converters { public interface IConverter { + object FromDB(ConverterContext context); + + [Obsolete("use FromDB(ConverterContext context) instead")] object FromDB(ColumnMap map, object dbValue); object ToDB(object clrValue); Type DbType { get; } diff --git a/Marr.Data/Mapping/MappingHelper.cs b/Marr.Data/Mapping/MappingHelper.cs index f025528be..0b4c73681 100644 --- a/Marr.Data/Mapping/MappingHelper.cs +++ b/Marr.Data/Mapping/MappingHelper.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Data.Common; +using Marr.Data.Converters; namespace Marr.Data.Mapping { @@ -53,7 +54,15 @@ namespace Marr.Data.Mapping // Handle conversions if (dataMap.Converter != null) { - dbValue = dataMap.Converter.FromDB(dataMap, dbValue); + var convertContext = new ConverterContext + { + DbValue = dbValue, + ColumnMap = dataMap, + MapCollection = mappings, + DataRecord = reader + }; + + dbValue = dataMap.Converter.FromDB(convertContext); } if (dbValue != DBNull.Value && dbValue != null) diff --git a/Marr.Data/Marr.Data.csproj b/Marr.Data/Marr.Data.csproj index f7e58cb01..9ae7c2082 100644 --- a/Marr.Data/Marr.Data.csproj +++ b/Marr.Data/Marr.Data.csproj @@ -52,6 +52,7 @@ + diff --git a/NzbDrone.Core/Datastore/Converters/BooleanIntConverter.cs b/NzbDrone.Core/Datastore/Converters/BooleanIntConverter.cs index 88d06c669..7ec60e201 100644 --- a/NzbDrone.Core/Datastore/Converters/BooleanIntConverter.cs +++ b/NzbDrone.Core/Datastore/Converters/BooleanIntConverter.cs @@ -6,14 +6,14 @@ namespace NzbDrone.Core.Datastore.Converters { public class BooleanIntConverter : IConverter { - public object FromDB(ColumnMap map, object dbValue) + public object FromDB(ConverterContext context) { - if (dbValue == DBNull.Value) + if (context.DbValue == DBNull.Value) { return DBNull.Value; } - var val = (Int64)dbValue; + var val = (Int64)context.DbValue; switch (val) { @@ -22,10 +22,15 @@ namespace NzbDrone.Core.Datastore.Converters case 0: return false; default: - throw new ConversionException(string.Format("The BooleanCharConverter could not convert the value '{0}' to a Boolean.", dbValue)); + throw new ConversionException(string.Format("The BooleanCharConverter could not convert the value '{0}' to a Boolean.", context.DbValue)); } } + public object FromDB(ColumnMap map, object dbValue) + { + return FromDB(new ConverterContext { ColumnMap = map, DbValue = dbValue }); + } + public object ToDB(object clrValue) { var val = (Nullable)clrValue; diff --git a/NzbDrone.Core/Datastore/Converters/EmbeddedDocumentConverter.cs b/NzbDrone.Core/Datastore/Converters/EmbeddedDocumentConverter.cs index b222eb320..cde1c116d 100644 --- a/NzbDrone.Core/Datastore/Converters/EmbeddedDocumentConverter.cs +++ b/NzbDrone.Core/Datastore/Converters/EmbeddedDocumentConverter.cs @@ -5,24 +5,57 @@ using NzbDrone.Common.Serializer; namespace NzbDrone.Core.Datastore.Converters { - public class EmbeddedDocumentConverter : IConverter - { - public object FromDB(ColumnMap map, object dbValue) + public class ProviderSettingConverter : EmbeddedDocumentConverter + { + public override object FromDB(ConverterContext context) { - if (dbValue == DBNull.Value) + if (context.DbValue == DBNull.Value) { return DBNull.Value; } - var stringValue = (string)dbValue; + var stringValue = (string)context.DbValue; if (string.IsNullOrWhiteSpace(stringValue)) { return null; } - return Json.Deserialize(stringValue, map.FieldType); + var ordinal = context.DataRecord.GetOrdinal("ConfigContract"); + + var implementation = context.DataRecord.GetString(ordinal); + + var impType = Type.GetType(implementation, true, true); + + return Json.Deserialize(stringValue, impType); + } + + } + + + public class EmbeddedDocumentConverter : IConverter + { + public virtual object FromDB(ConverterContext context) + { + if (context.DbValue == DBNull.Value) + { + return DBNull.Value; + } + + var stringValue = (string)context.DbValue; + + if (string.IsNullOrWhiteSpace(stringValue)) + { + return null; + } + + return Json.Deserialize(stringValue, context.ColumnMap.FieldType); + } + + public object FromDB(ColumnMap map, object dbValue) + { + return FromDB(new ConverterContext { ColumnMap = map, DbValue = dbValue }); } public object ToDB(object clrValue) diff --git a/NzbDrone.Core/Datastore/Converters/EnumIntConverter.cs b/NzbDrone.Core/Datastore/Converters/EnumIntConverter.cs index f79c736c2..40c2727bc 100644 --- a/NzbDrone.Core/Datastore/Converters/EnumIntConverter.cs +++ b/NzbDrone.Core/Datastore/Converters/EnumIntConverter.cs @@ -14,16 +14,21 @@ namespace NzbDrone.Core.Datastore.Converters } } - public object FromDB(ColumnMap map, object dbValue) + public object FromDB(ConverterContext context) { - if (dbValue != null && dbValue != DBNull.Value) + if (context.DbValue != null && context.DbValue != DBNull.Value) { - return Enum.ToObject(map.FieldType, (Int64)dbValue); + return Enum.ToObject(context.ColumnMap.FieldType, (Int64)context.DbValue); } return null; } + public object FromDB(ColumnMap map, object dbValue) + { + return FromDB(new ConverterContext { ColumnMap = map, DbValue = dbValue }); + } + public object ToDB(object clrValue) { if (clrValue != null) diff --git a/NzbDrone.Core/Datastore/Converters/Int32Converter.cs b/NzbDrone.Core/Datastore/Converters/Int32Converter.cs index fcf66a045..c69bfb9a5 100644 --- a/NzbDrone.Core/Datastore/Converters/Int32Converter.cs +++ b/NzbDrone.Core/Datastore/Converters/Int32Converter.cs @@ -6,6 +6,21 @@ namespace NzbDrone.Core.Datastore.Converters { public class Int32Converter : IConverter { + public object FromDB(ConverterContext context) + { + if (context.DbValue == DBNull.Value) + { + return DBNull.Value; + } + + if (context.DbValue is Int32) + { + return context.DbValue; + } + + return Convert.ToInt32(context.DbValue); + } + public object FromDB(ColumnMap map, object dbValue) { if (dbValue == DBNull.Value) diff --git a/NzbDrone.Core/Datastore/Converters/QualityIntConverter.cs b/NzbDrone.Core/Datastore/Converters/QualityIntConverter.cs index 839ef85be..6dc9d6c24 100644 --- a/NzbDrone.Core/Datastore/Converters/QualityIntConverter.cs +++ b/NzbDrone.Core/Datastore/Converters/QualityIntConverter.cs @@ -7,18 +7,23 @@ namespace NzbDrone.Core.Datastore.Converters { public class QualityIntConverter : IConverter { - public object FromDB(ColumnMap map, object dbValue) + public object FromDB(ConverterContext context) { - if (dbValue == DBNull.Value) + if (context.DbValue == DBNull.Value) { return Quality.Unknown; } - var val = Convert.ToInt32(dbValue); + var val = Convert.ToInt32(context.DbValue); return (Quality)val; } + public object FromDB(ColumnMap map, object dbValue) + { + return FromDB(new ConverterContext { ColumnMap = map, DbValue = dbValue }); + } + public object ToDB(object clrValue) { if(clrValue == null) return 0; diff --git a/NzbDrone.Core/Datastore/Converters/UtcConverter.cs b/NzbDrone.Core/Datastore/Converters/UtcConverter.cs index 0bdc802dc..25d313a6c 100644 --- a/NzbDrone.Core/Datastore/Converters/UtcConverter.cs +++ b/NzbDrone.Core/Datastore/Converters/UtcConverter.cs @@ -6,9 +6,14 @@ namespace NzbDrone.Core.Datastore.Converters { public class UtcConverter : IConverter { + public object FromDB(ConverterContext context) + { + return context.DbValue; + } + public object FromDB(ColumnMap map, object dbValue) { - return dbValue; + return FromDB(new ConverterContext { ColumnMap = map, DbValue = dbValue }); } public object ToDB(object clrValue) From 4046d356047c981f5c446f614e8e2723dba1b6fc Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Fri, 20 Sep 2013 23:39:26 -0700 Subject: [PATCH 03/16] can now read/write provider config to db. --- .../ThingiProvider/ProviderBaseFixture.cs | 24 ++++--- .../Converters/EmbeddedDocumentConverter.cs | 5 +- ...2_move_notification_to_generic_provider.cs | 68 +++++++++++++++++++ NzbDrone.Core/Datastore/TableMapping.cs | 18 ++++- .../Notifications/Email/EmailSettings.cs | 3 +- .../Notifications/Growl/GrowlSettings.cs | 3 +- .../Notifications/INotifcationSettings.cs | 7 -- NzbDrone.Core/Notifications/Notification.cs | 6 +- .../Notifications/NotificationBase.cs | 3 +- .../Notifications/NotificationDefinition.cs | 8 +++ .../Notifications/NotificationService.cs | 3 +- .../NotificationSettingsProvider.cs | 5 +- .../NotifyMyAndroidSettings.cs | 3 +- .../Notifications/Plex/PlexClientSettings.cs | 3 +- .../Notifications/Plex/PlexServerSettings.cs | 3 +- .../Notifications/Prowl/ProwlSettings.cs | 3 +- .../PushBullet/PushBulletSettings.cs | 3 +- .../Pushover/PushoverSettings.cs | 3 +- .../Notifications/Xbmc/XbmcSettings.cs | 3 +- NzbDrone.Core/NzbDrone.Core.csproj | 2 +- NzbDrone.Core/ThingiProvider/ProviderBase.cs | 65 ++++++++++-------- 21 files changed, 179 insertions(+), 62 deletions(-) create mode 100644 NzbDrone.Core/Datastore/Migration/022_move_notification_to_generic_provider.cs delete mode 100644 NzbDrone.Core/Notifications/INotifcationSettings.cs diff --git a/NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs b/NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs index 11006aa42..2d9cb0f9e 100644 --- a/NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs +++ b/NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs @@ -1,23 +1,31 @@ -using NUnit.Framework; -using NzbDrone.Core.Test.Datastore; +using FizzWare.NBuilder; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Notifications; +using NzbDrone.Core.Notifications.Email; using NzbDrone.Core.Test.Framework; using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Test.ThingiProvider { - public class ProviderRepositoryFixture : DbTest + public class ProviderRepositoryFixture : DbTest { [Test] public void should_read_write_download_provider() { - var model = new DownloadProviderModel(); + var model = Builder.CreateNew().BuildNew(); + var emailSettings = Builder.CreateNew().Build(); + model.Settings = emailSettings; + Subject.Insert(model); - model.Config = new DownloadProviderConfig(); + var storedProvider = Subject.Single(); + + storedProvider.Settings.Should().BeOfType(); - //Subject.Insert(new ) + var storedSetting = (EmailSettings) storedProvider.Settings; + + storedSetting.ShouldHave().AllProperties().EqualTo(emailSettings); } - - } } \ No newline at end of file diff --git a/NzbDrone.Core/Datastore/Converters/EmbeddedDocumentConverter.cs b/NzbDrone.Core/Datastore/Converters/EmbeddedDocumentConverter.cs index cde1c116d..89b2ecea1 100644 --- a/NzbDrone.Core/Datastore/Converters/EmbeddedDocumentConverter.cs +++ b/NzbDrone.Core/Datastore/Converters/EmbeddedDocumentConverter.cs @@ -1,7 +1,9 @@ using System; +using System.Linq; using Marr.Data.Converters; using Marr.Data.Mapping; using NzbDrone.Common.Serializer; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Datastore.Converters { @@ -26,7 +28,8 @@ namespace NzbDrone.Core.Datastore.Converters var implementation = context.DataRecord.GetString(ordinal); - var impType = Type.GetType(implementation, true, true); + + var impType = typeof(IProviderConfig).Assembly.GetTypes().Single(c => c.Name == implementation); return Json.Deserialize(stringValue, impType); } diff --git a/NzbDrone.Core/Datastore/Migration/022_move_notification_to_generic_provider.cs b/NzbDrone.Core/Datastore/Migration/022_move_notification_to_generic_provider.cs new file mode 100644 index 000000000..d0210438f --- /dev/null +++ b/NzbDrone.Core/Datastore/Migration/022_move_notification_to_generic_provider.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Data; +using FluentMigrator; +using NzbDrone.Common.Serializer; +using NzbDrone.Core.Datastore.Migration.Framework; + +namespace NzbDrone.Core.Datastore.Migration +{ + [Migration(22)] + public class move_notification_to_generic_provider : NzbDroneMigrationBase + { + protected override void MainDbUpgrade() + { + Alter.Table("Notifications").AddColumn("ConfigContract").AsString().Nullable(); + + //Execute.WithConnection(ConvertSeasons); + } + + private void ConvertSeasons(IDbConnection conn, IDbTransaction tran) + { + using (IDbCommand allSeriesCmd = conn.CreateCommand()) + { + allSeriesCmd.Transaction = tran; + allSeriesCmd.CommandText = @"SELECT Id FROM Series"; + using (IDataReader allSeriesReader = allSeriesCmd.ExecuteReader()) + { + while (allSeriesReader.Read()) + { + int seriesId = allSeriesReader.GetInt32(0); + var seasons = new List(); + + using (IDbCommand seasonsCmd = conn.CreateCommand()) + { + seasonsCmd.Transaction = tran; + seasonsCmd.CommandText = String.Format(@"SELECT SeasonNumber, Monitored FROM Seasons WHERE SeriesId = {0}", seriesId); + + using (IDataReader seasonReader = seasonsCmd.ExecuteReader()) + { + while (seasonReader.Read()) + { + int seasonNumber = seasonReader.GetInt32(0); + bool monitored = seasonReader.GetBoolean(1); + + if (seasonNumber == 0) + { + monitored = false; + } + + seasons.Add(new { seasonNumber, monitored }); + } + } + } + + using (IDbCommand updateCmd = conn.CreateCommand()) + { + var text = String.Format("UPDATE Series SET Seasons = '{0}' WHERE Id = {1}", seasons.ToJson() , seriesId); + + updateCmd.Transaction = tran; + updateCmd.CommandText = text; + updateCmd.ExecuteNonQuery(); + } + } + } + } + } + } +} diff --git a/NzbDrone.Core/Datastore/TableMapping.cs b/NzbDrone.Core/Datastore/TableMapping.cs index 533b3ab70..3feda3e13 100644 --- a/NzbDrone.Core/Datastore/TableMapping.cs +++ b/NzbDrone.Core/Datastore/TableMapping.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using Marr.Data; using Marr.Data.Mapping; +using NzbDrone.Common.Reflection; using NzbDrone.Core.Configuration; using NzbDrone.Core.DataAugmentation.Scene; using NzbDrone.Core.Datastore.Converters; @@ -15,6 +16,7 @@ using NzbDrone.Core.Organizer; using NzbDrone.Core.Qualities; using NzbDrone.Core.RootFolders; using NzbDrone.Core.SeriesStats; +using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Tv; namespace NzbDrone.Core.Datastore @@ -34,6 +36,7 @@ namespace NzbDrone.Core.Datastore Mapper.Entity().RegisterModel("Indexers"); Mapper.Entity().RegisterModel("ScheduledTasks"); Mapper.Entity().RegisterModel("Notifications"); + Mapper.Entity().RegisterModel("Notifications"); Mapper.Entity().RegisterModel("SceneMappings"); @@ -69,6 +72,7 @@ namespace NzbDrone.Core.Datastore private static void RegisterMappers() { RegisterEmbeddedConverter(); + RegisterProviderSettingConverter(); MapRepository.Instance.RegisterTypeConverter(typeof(Int32), new Int32Converter()); MapRepository.Instance.RegisterTypeConverter(typeof(DateTime), new UtcConverter()); @@ -78,10 +82,20 @@ namespace NzbDrone.Core.Datastore MapRepository.Instance.RegisterTypeConverter(typeof(Dictionary), new EmbeddedDocumentConverter()); } + private static void RegisterProviderSettingConverter() + { + var settingTypes = typeof(IProviderConfig).Assembly.ImplementationsOf(); + + var providerSettingConverter = new ProviderSettingConverter(); + foreach (var embeddedType in settingTypes) + { + MapRepository.Instance.RegisterTypeConverter(embeddedType, providerSettingConverter); + } + } + private static void RegisterEmbeddedConverter() { - var embeddedTypes = typeof(IEmbeddedDocument).Assembly.GetTypes() - .Where(c => c.GetInterfaces().Any(i => i == typeof(IEmbeddedDocument))); + var embeddedTypes = typeof(IEmbeddedDocument).Assembly.ImplementationsOf(); var embeddedConvertor = new EmbeddedDocumentConverter(); diff --git a/NzbDrone.Core/Notifications/Email/EmailSettings.cs b/NzbDrone.Core/Notifications/Email/EmailSettings.cs index 6ee61b6a2..1d678dae9 100644 --- a/NzbDrone.Core/Notifications/Email/EmailSettings.cs +++ b/NzbDrone.Core/Notifications/Email/EmailSettings.cs @@ -1,9 +1,10 @@ using System; using NzbDrone.Core.Annotations; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Notifications.Email { - public class EmailSettings : INotifcationSettings + public class EmailSettings : IProviderConfig { public EmailSettings() { diff --git a/NzbDrone.Core/Notifications/Growl/GrowlSettings.cs b/NzbDrone.Core/Notifications/Growl/GrowlSettings.cs index c66060a94..75c3de74a 100644 --- a/NzbDrone.Core/Notifications/Growl/GrowlSettings.cs +++ b/NzbDrone.Core/Notifications/Growl/GrowlSettings.cs @@ -1,9 +1,10 @@ using System; using NzbDrone.Core.Annotations; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Notifications.Growl { - public class GrowlSettings : INotifcationSettings + public class GrowlSettings : IProviderConfig { public GrowlSettings() { diff --git a/NzbDrone.Core/Notifications/INotifcationSettings.cs b/NzbDrone.Core/Notifications/INotifcationSettings.cs deleted file mode 100644 index 49e113de4..000000000 --- a/NzbDrone.Core/Notifications/INotifcationSettings.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace NzbDrone.Core.Notifications -{ - public interface INotifcationSettings - { - bool IsValid { get; } - } -} diff --git a/NzbDrone.Core/Notifications/Notification.cs b/NzbDrone.Core/Notifications/Notification.cs index 09919c958..40275ecf9 100644 --- a/NzbDrone.Core/Notifications/Notification.cs +++ b/NzbDrone.Core/Notifications/Notification.cs @@ -1,4 +1,6 @@ -namespace NzbDrone.Core.Notifications +using NzbDrone.Core.ThingiProvider; + +namespace NzbDrone.Core.Notifications { public class Notification { @@ -8,7 +10,7 @@ public string Link { get; set; } public bool OnGrab { get; set; } public bool OnDownload { get; set; } - public INotifcationSettings Settings { get; set; } + public IProviderConfig Settings { get; set; } public INotification Instance { get; set; } public string Implementation { get; set; } } diff --git a/NzbDrone.Core/Notifications/NotificationBase.cs b/NzbDrone.Core/Notifications/NotificationBase.cs index e8577c978..d121bd44b 100644 --- a/NzbDrone.Core/Notifications/NotificationBase.cs +++ b/NzbDrone.Core/Notifications/NotificationBase.cs @@ -1,9 +1,10 @@ using NzbDrone.Common.Serializer; +using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Tv; namespace NzbDrone.Core.Notifications { - public abstract class NotificationBase : INotification where TSetting : class, INotifcationSettings, new() + public abstract class NotificationBase : INotification where TSetting : class, IProviderConfig, new() { public abstract string Name { get; } public abstract string ImplementationName { get; } diff --git a/NzbDrone.Core/Notifications/NotificationDefinition.cs b/NzbDrone.Core/Notifications/NotificationDefinition.cs index 7456c7783..15f274dfc 100644 --- a/NzbDrone.Core/Notifications/NotificationDefinition.cs +++ b/NzbDrone.Core/Notifications/NotificationDefinition.cs @@ -1,5 +1,6 @@ using System; using NzbDrone.Core.Datastore; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Notifications { @@ -11,4 +12,11 @@ namespace NzbDrone.Core.Notifications public String Settings { get; set; } public String Implementation { get; set; } } + + + public class NotificationProviderModel : Provider + { + public Boolean OnGrab { get; set; } + public Boolean OnDownload { get; set; } + } } \ No newline at end of file diff --git a/NzbDrone.Core/Notifications/NotificationService.cs b/NzbDrone.Core/Notifications/NotificationService.cs index 0553f4669..3febb84e0 100644 --- a/NzbDrone.Core/Notifications/NotificationService.cs +++ b/NzbDrone.Core/Notifications/NotificationService.cs @@ -7,6 +7,7 @@ using NzbDrone.Common.Serializer; using NzbDrone.Core.Download; using NzbDrone.Core.MediaFiles.Events; using NzbDrone.Core.Messaging.Events; +using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Tv; using Omu.ValueInjecter; @@ -71,7 +72,7 @@ namespace NzbDrone.Core.Notifications var instanceType = newNotification.Instance.GetType(); var baseGenArgs = instanceType.BaseType.GetGenericArguments(); - newNotification.Settings = (INotifcationSettings)Activator.CreateInstance(baseGenArgs[0]); + newNotification.Settings = (IProviderConfig)Activator.CreateInstance(baseGenArgs[0]); newNotification.Implementation = type.Name; notifications.Add(newNotification); diff --git a/NzbDrone.Core/Notifications/NotificationSettingsProvider.cs b/NzbDrone.Core/Notifications/NotificationSettingsProvider.cs index 53f4d8a58..b26afa1fd 100644 --- a/NzbDrone.Core/Notifications/NotificationSettingsProvider.cs +++ b/NzbDrone.Core/Notifications/NotificationSettingsProvider.cs @@ -1,10 +1,11 @@ using NzbDrone.Common.Serializer; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Notifications { public interface INotificationSettingsProvider { - TSetting Get(INotification indexer) where TSetting : INotifcationSettings, new(); + TSetting Get(INotification indexer) where TSetting : IProviderConfig, new(); } public class NotificationSettingsProvider : INotificationSettingsProvider @@ -16,7 +17,7 @@ namespace NzbDrone.Core.Notifications _notificationRepository = notificationRepository; } - public TSetting Get(INotification indexer) where TSetting : INotifcationSettings, new() + public TSetting Get(INotification indexer) where TSetting : IProviderConfig, new() { var indexerDef = _notificationRepository.Find(indexer.Name); diff --git a/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroidSettings.cs b/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroidSettings.cs index c8c941239..f9a4da283 100644 --- a/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroidSettings.cs +++ b/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroidSettings.cs @@ -1,9 +1,10 @@ using System; using NzbDrone.Core.Annotations; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Notifications.NotifyMyAndroid { - public class NotifyMyAndroidSettings : INotifcationSettings + public class NotifyMyAndroidSettings : IProviderConfig { [FieldDefinition(0, Label = "API Key", HelpLink = "http://www.notifymyandroid.com/")] public String ApiKey { get; set; } diff --git a/NzbDrone.Core/Notifications/Plex/PlexClientSettings.cs b/NzbDrone.Core/Notifications/Plex/PlexClientSettings.cs index 130552e52..95c9a3291 100644 --- a/NzbDrone.Core/Notifications/Plex/PlexClientSettings.cs +++ b/NzbDrone.Core/Notifications/Plex/PlexClientSettings.cs @@ -1,9 +1,10 @@ using System; using NzbDrone.Core.Annotations; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Notifications.Plex { - public class PlexClientSettings : INotifcationSettings + public class PlexClientSettings : IProviderConfig { public PlexClientSettings() { diff --git a/NzbDrone.Core/Notifications/Plex/PlexServerSettings.cs b/NzbDrone.Core/Notifications/Plex/PlexServerSettings.cs index 40b05a2c0..9f4e3cc5f 100644 --- a/NzbDrone.Core/Notifications/Plex/PlexServerSettings.cs +++ b/NzbDrone.Core/Notifications/Plex/PlexServerSettings.cs @@ -1,9 +1,10 @@ using System; using NzbDrone.Core.Annotations; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Notifications.Plex { - public class PlexServerSettings : INotifcationSettings + public class PlexServerSettings : IProviderConfig { public PlexServerSettings() { diff --git a/NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs b/NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs index f6b9a7603..1b6db74cc 100644 --- a/NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs +++ b/NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs @@ -1,9 +1,10 @@ using System; using NzbDrone.Core.Annotations; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Notifications.Prowl { - public class ProwlSettings : INotifcationSettings + public class ProwlSettings : IProviderConfig { [FieldDefinition(0, Label = "API Key", HelpLink = "https://www.prowlapp.com/api_settings.php")] public String ApiKey { get; set; } diff --git a/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs b/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs index f7a492622..cf34b3718 100644 --- a/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs +++ b/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs @@ -1,9 +1,10 @@ using System; using NzbDrone.Core.Annotations; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Notifications.PushBullet { - public class PushBulletSettings : INotifcationSettings + public class PushBulletSettings : IProviderConfig { [FieldDefinition(0, Label = "API Key", HelpLink = "https://www.pushbullet.com/")] public String ApiKey { get; set; } diff --git a/NzbDrone.Core/Notifications/Pushover/PushoverSettings.cs b/NzbDrone.Core/Notifications/Pushover/PushoverSettings.cs index 43c7937b6..4a42baac9 100644 --- a/NzbDrone.Core/Notifications/Pushover/PushoverSettings.cs +++ b/NzbDrone.Core/Notifications/Pushover/PushoverSettings.cs @@ -1,9 +1,10 @@ using System; using NzbDrone.Core.Annotations; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Notifications.Pushover { - public class PushoverSettings : INotifcationSettings + public class PushoverSettings : IProviderConfig { [FieldDefinition(0, Label = "User Key", HelpLink = "https://pushover.net/")] public String UserKey { get; set; } diff --git a/NzbDrone.Core/Notifications/Xbmc/XbmcSettings.cs b/NzbDrone.Core/Notifications/Xbmc/XbmcSettings.cs index 0a09d9d57..26e114d30 100644 --- a/NzbDrone.Core/Notifications/Xbmc/XbmcSettings.cs +++ b/NzbDrone.Core/Notifications/Xbmc/XbmcSettings.cs @@ -2,10 +2,11 @@ using System.ComponentModel; using Newtonsoft.Json; using NzbDrone.Core.Annotations; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Notifications.Xbmc { - public class XbmcSettings : INotifcationSettings + public class XbmcSettings : IProviderConfig { public XbmcSettings() { diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 2ab111e2a..049d2cb4c 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -171,6 +171,7 @@ + @@ -370,7 +371,6 @@ - diff --git a/NzbDrone.Core/ThingiProvider/ProviderBase.cs b/NzbDrone.Core/ThingiProvider/ProviderBase.cs index 61035d7de..bf24434d2 100644 --- a/NzbDrone.Core/ThingiProvider/ProviderBase.cs +++ b/NzbDrone.Core/ThingiProvider/ProviderBase.cs @@ -1,6 +1,7 @@  using NzbDrone.Core.Datastore; using NzbDrone.Core.Messaging.Events; +using NzbDrone.Core.Notifications; namespace NzbDrone.Core.ThingiProvider { @@ -14,36 +15,44 @@ namespace NzbDrone.Core.ThingiProvider } } - public class DownloadProviderModel : Provider + + public class NotificationProviderRepository : BasicRepository { - - } - - public class DownloadProviderConfig : ProviderSetting - { - - } - - - public abstract class Provider : ModelBase - where TSettings : ProviderSetting - { - public string Implementation { get; set; } - public TSettings Config { get; set; } - } - - public abstract class ProviderSetting : IEmbeddedDocument - { - - } - - public abstract class ProviderBase where TSettings : ProviderSetting - { - public TSettings Settings { get; private set; } - - public void LoadSettings(TSettings setting) + public NotificationProviderRepository(IDatabase database, IEventAggregator eventAggregator) + : base(database, eventAggregator) { - Settings = setting; } } + + public class DownloadProviderModel : Provider + { + + } + + + public abstract class Provider : ModelBase + { + public string Name { get; set; } + public string Implementation { get; set; } + + public string ConfigContract + { + get + { + if (Settings == null) return null; + return Settings.GetType().Name; + } + set + { + + } + } + + public IProviderConfig Settings { get; set; } + } + + public interface IProviderConfig + { + bool IsValid { get; } + } } \ No newline at end of file From 0b179a608661780b91174b52fcc4b582c4d5a452 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Sat, 21 Sep 2013 00:09:26 -0700 Subject: [PATCH 04/16] starting to move indexers to generic provider. --- .../ThingiProvider/ProviderBaseFixture.cs | 22 +++++----- ...2_move_notification_to_generic_provider.cs | 6 +-- NzbDrone.Core/Datastore/TableMapping.cs | 1 - NzbDrone.Core/Indexers/IIndexerSetting.cs | 9 ---- NzbDrone.Core/Indexers/IndexerBase.cs | 3 +- NzbDrone.Core/Indexers/IndexerDefinition.cs | 6 +-- NzbDrone.Core/Indexers/IndexerService.cs | 7 +-- .../Indexers/IndexerSettingProvider.cs | 31 ------------- .../Indexers/IndexerSettingUpdatedEvent.cs | 5 ++- NzbDrone.Core/Indexers/IndexerWithSetting.cs | 3 +- NzbDrone.Core/Indexers/Newznab/Newznab.cs | 4 +- .../Indexers/Newznab/NewznabSettings.cs | 3 +- NzbDrone.Core/Indexers/NullSetting.cs | 14 ------ .../Indexers/Omgwtfnzbs/OmgwtfnzbsSettings.cs | 3 +- .../Notifications/Email/EmailSettings.cs | 6 +++ .../Notifications/Growl/GrowlSettings.cs | 6 +++ .../Notifications/NotificationDefinition.cs | 2 +- .../Notifications/NotificationService.cs | 6 +-- .../NotifyMyAndroidSettings.cs | 6 +++ .../Notifications/Plex/PlexClientSettings.cs | 6 +++ .../Notifications/Plex/PlexServerSettings.cs | 6 +++ .../Notifications/Prowl/ProwlSettings.cs | 6 +++ .../PushBullet/PushBulletSettings.cs | 6 +++ .../Pushover/PushoverSettings.cs | 6 +++ .../Notifications/Xbmc/XbmcSettings.cs | 6 +++ NzbDrone.Core/NzbDrone.Core.csproj | 3 -- NzbDrone.Core/ThingiProvider/ProviderBase.cs | 43 +++++++++++-------- 27 files changed, 116 insertions(+), 109 deletions(-) delete mode 100644 NzbDrone.Core/Indexers/IIndexerSetting.cs delete mode 100644 NzbDrone.Core/Indexers/IndexerSettingProvider.cs delete mode 100644 NzbDrone.Core/Indexers/NullSetting.cs diff --git a/NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs b/NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs index 2d9cb0f9e..3ecfa62ac 100644 --- a/NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs +++ b/NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs @@ -1,31 +1,31 @@ using FizzWare.NBuilder; using FluentAssertions; using NUnit.Framework; -using NzbDrone.Core.Notifications; -using NzbDrone.Core.Notifications.Email; +using NzbDrone.Core.Indexers; +using NzbDrone.Core.Indexers.Newznab; using NzbDrone.Core.Test.Framework; using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Test.ThingiProvider { - public class ProviderRepositoryFixture : DbTest + public class ProviderRepositoryFixture : DbTest { [Test] public void should_read_write_download_provider() { - var model = Builder.CreateNew().BuildNew(); - var emailSettings = Builder.CreateNew().Build(); - model.Settings = emailSettings; + var model = Builder.CreateNew().BuildNew(); + var newznabSettings = Builder.CreateNew().Build(); + model.Settings = newznabSettings; Subject.Insert(model); var storedProvider = Subject.Single(); - - storedProvider.Settings.Should().BeOfType(); - var storedSetting = (EmailSettings) storedProvider.Settings; - - storedSetting.ShouldHave().AllProperties().EqualTo(emailSettings); + storedProvider.Settings.Should().BeOfType(); + + var storedSetting = (NewznabSettings)storedProvider.Settings; + + storedSetting.ShouldHave().AllProperties().EqualTo(newznabSettings); } } } \ No newline at end of file diff --git a/NzbDrone.Core/Datastore/Migration/022_move_notification_to_generic_provider.cs b/NzbDrone.Core/Datastore/Migration/022_move_notification_to_generic_provider.cs index d0210438f..2b5182419 100644 --- a/NzbDrone.Core/Datastore/Migration/022_move_notification_to_generic_provider.cs +++ b/NzbDrone.Core/Datastore/Migration/022_move_notification_to_generic_provider.cs @@ -8,11 +8,11 @@ using NzbDrone.Core.Datastore.Migration.Framework; namespace NzbDrone.Core.Datastore.Migration { [Migration(22)] - public class move_notification_to_generic_provider : NzbDroneMigrationBase + public class move_indexer_to_generic_provider : NzbDroneMigrationBase { protected override void MainDbUpgrade() { - Alter.Table("Notifications").AddColumn("ConfigContract").AsString().Nullable(); + Alter.Table("Indexers").AddColumn("ConfigContract").AsString().Nullable(); //Execute.WithConnection(ConvertSeasons); } @@ -54,7 +54,7 @@ namespace NzbDrone.Core.Datastore.Migration using (IDbCommand updateCmd = conn.CreateCommand()) { - var text = String.Format("UPDATE Series SET Seasons = '{0}' WHERE Id = {1}", seasons.ToJson() , seriesId); + var text = String.Format("UPDATE Series SET Seasons = '{0}' WHERE Id = {1}", seasons.ToJson(), seriesId); updateCmd.Transaction = tran; updateCmd.CommandText = text; diff --git a/NzbDrone.Core/Datastore/TableMapping.cs b/NzbDrone.Core/Datastore/TableMapping.cs index 3feda3e13..bade3c2d6 100644 --- a/NzbDrone.Core/Datastore/TableMapping.cs +++ b/NzbDrone.Core/Datastore/TableMapping.cs @@ -36,7 +36,6 @@ namespace NzbDrone.Core.Datastore Mapper.Entity().RegisterModel("Indexers"); Mapper.Entity().RegisterModel("ScheduledTasks"); Mapper.Entity().RegisterModel("Notifications"); - Mapper.Entity().RegisterModel("Notifications"); Mapper.Entity().RegisterModel("SceneMappings"); diff --git a/NzbDrone.Core/Indexers/IIndexerSetting.cs b/NzbDrone.Core/Indexers/IIndexerSetting.cs deleted file mode 100644 index 4f9cf16de..000000000 --- a/NzbDrone.Core/Indexers/IIndexerSetting.cs +++ /dev/null @@ -1,9 +0,0 @@ -using FluentValidation.Results; - -namespace NzbDrone.Core.Indexers -{ - public interface IIndexerSetting - { - ValidationResult Validate(); - } -} diff --git a/NzbDrone.Core/Indexers/IndexerBase.cs b/NzbDrone.Core/Indexers/IndexerBase.cs index 6f544a2be..28a2d1d46 100644 --- a/NzbDrone.Core/Indexers/IndexerBase.cs +++ b/NzbDrone.Core/Indexers/IndexerBase.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Indexers { @@ -22,7 +23,7 @@ namespace NzbDrone.Core.Indexers Name = Name, Enable = EnableByDefault, Implementation = GetType().Name, - Settings = String.Empty + Settings = NullSetting.Instance }; } } diff --git a/NzbDrone.Core/Indexers/IndexerDefinition.cs b/NzbDrone.Core/Indexers/IndexerDefinition.cs index a061052e7..02238e0e9 100644 --- a/NzbDrone.Core/Indexers/IndexerDefinition.cs +++ b/NzbDrone.Core/Indexers/IndexerDefinition.cs @@ -1,13 +1,11 @@ using System; using NzbDrone.Core.Datastore; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Indexers { - public class IndexerDefinition : ModelBase + public class IndexerDefinition : ProviderDefinition { public Boolean Enable { get; set; } - public String Name { get; set; } - public String Settings { get; set; } - public String Implementation { get; set; } } } \ No newline at end of file diff --git a/NzbDrone.Core/Indexers/IndexerService.cs b/NzbDrone.Core/Indexers/IndexerService.cs index e1b49c2dd..5d42c2a9d 100644 --- a/NzbDrone.Core/Indexers/IndexerService.cs +++ b/NzbDrone.Core/Indexers/IndexerService.cs @@ -7,6 +7,7 @@ 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 @@ -16,7 +17,7 @@ namespace NzbDrone.Core.Indexers public int Id { get; set; } public string Name { get; set; } public bool Enable { get; set; } - public IIndexerSetting Settings { get; set; } + public IProviderConfig Settings { get; set; } public IIndexer Instance { get; set; } public string Implementation { get; set; } } @@ -107,7 +108,7 @@ namespace NzbDrone.Core.Indexers Name = indexer.Name, Enable = indexer.Enable, Implementation = indexer.Implementation, - Settings = indexer.Settings.ToJson() + Settings = indexer.Settings }; var instance = ToIndexer(definition).Instance; @@ -123,7 +124,7 @@ namespace NzbDrone.Core.Indexers { var definition = _indexerRepository.Get(indexer.Id); definition.InjectFrom(indexer); - definition.Settings = indexer.Settings.ToJson(); + definition.Settings = indexer.Settings; _indexerRepository.Update(definition); return indexer; diff --git a/NzbDrone.Core/Indexers/IndexerSettingProvider.cs b/NzbDrone.Core/Indexers/IndexerSettingProvider.cs deleted file mode 100644 index ab7da9e58..000000000 --- a/NzbDrone.Core/Indexers/IndexerSettingProvider.cs +++ /dev/null @@ -1,31 +0,0 @@ -using NzbDrone.Common.Serializer; - -namespace NzbDrone.Core.Indexers -{ - public interface IProviderIndexerSetting - { - TSetting Get(IIndexer indexer) where TSetting : IIndexerSetting, new(); - } - - public class IndexerSettingProvider : IProviderIndexerSetting - { - private readonly IIndexerRepository _indexerRepository; - - public IndexerSettingProvider(IIndexerRepository indexerRepository) - { - _indexerRepository = indexerRepository; - } - - public TSetting Get(IIndexer indexer) where TSetting : IIndexerSetting, new() - { - var indexerDef = _indexerRepository.Find(indexer.Name); - - if (indexerDef == null || string.IsNullOrWhiteSpace(indexerDef.Settings)) - { - return new TSetting(); - } - - return Json.Deserialize(indexerDef.Settings); - } - } -} \ No newline at end of file diff --git a/NzbDrone.Core/Indexers/IndexerSettingUpdatedEvent.cs b/NzbDrone.Core/Indexers/IndexerSettingUpdatedEvent.cs index 8b3edc513..783948b2e 100644 --- a/NzbDrone.Core/Indexers/IndexerSettingUpdatedEvent.cs +++ b/NzbDrone.Core/Indexers/IndexerSettingUpdatedEvent.cs @@ -1,13 +1,14 @@ using NzbDrone.Common.Messaging; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Indexers { public class IndexerSettingUpdatedEvent : IEvent { public string IndexerName { get; private set; } - public IIndexerSetting IndexerSetting { get; private set; } + public IProviderConfig IndexerSetting { get; private set; } - public IndexerSettingUpdatedEvent(string indexerName, IIndexerSetting indexerSetting) + public IndexerSettingUpdatedEvent(string indexerName, IProviderConfig indexerSetting) { IndexerName = indexerName; IndexerSetting = indexerSetting; diff --git a/NzbDrone.Core/Indexers/IndexerWithSetting.cs b/NzbDrone.Core/Indexers/IndexerWithSetting.cs index 78db54932..ecba9f7a9 100644 --- a/NzbDrone.Core/Indexers/IndexerWithSetting.cs +++ b/NzbDrone.Core/Indexers/IndexerWithSetting.cs @@ -1,8 +1,9 @@ using NzbDrone.Common.Serializer; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Indexers { - public abstract class IndexerWithSetting : IndexerBase where TSetting : class, IIndexerSetting, new() + public abstract class IndexerWithSetting : IndexerBase where TSetting : class, IProviderConfig, new() { public TSetting Settings { get; set; } diff --git a/NzbDrone.Core/Indexers/Newznab/Newznab.cs b/NzbDrone.Core/Indexers/Newznab/Newznab.cs index 8a13d2282..e2daf28d6 100644 --- a/NzbDrone.Core/Indexers/Newznab/Newznab.cs +++ b/NzbDrone.Core/Indexers/Newznab/Newznab.cs @@ -51,7 +51,7 @@ namespace NzbDrone.Core.Indexers.Newznab } } - private string GetSettings(string url, List categories) + private NewznabSettings GetSettings(string url, List categories) { var settings = new NewznabSettings { Url = url }; @@ -60,7 +60,7 @@ namespace NzbDrone.Core.Indexers.Newznab settings.Categories = categories; } - return settings.ToJson(); + return settings; } public override IEnumerable RecentFeed diff --git a/NzbDrone.Core/Indexers/Newznab/NewznabSettings.cs b/NzbDrone.Core/Indexers/Newznab/NewznabSettings.cs index c83623ace..5f05ba96d 100644 --- a/NzbDrone.Core/Indexers/Newznab/NewznabSettings.cs +++ b/NzbDrone.Core/Indexers/Newznab/NewznabSettings.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using FluentValidation; using FluentValidation.Results; using NzbDrone.Core.Annotations; +using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Indexers.Newznab @@ -16,7 +17,7 @@ namespace NzbDrone.Core.Indexers.Newznab } - public class NewznabSettings : IIndexerSetting + public class NewznabSettings : IProviderConfig { private static readonly NewznabSettingsValidator Validator = new NewznabSettingsValidator(); diff --git a/NzbDrone.Core/Indexers/NullSetting.cs b/NzbDrone.Core/Indexers/NullSetting.cs deleted file mode 100644 index a7013335a..000000000 --- a/NzbDrone.Core/Indexers/NullSetting.cs +++ /dev/null @@ -1,14 +0,0 @@ -using FluentValidation.Results; - -namespace NzbDrone.Core.Indexers -{ - public class NullSetting : IIndexerSetting - { - public static readonly NullSetting Instance = new NullSetting(); - - public ValidationResult Validate() - { - return new ValidationResult(); - } - } -} \ No newline at end of file diff --git a/NzbDrone.Core/Indexers/Omgwtfnzbs/OmgwtfnzbsSettings.cs b/NzbDrone.Core/Indexers/Omgwtfnzbs/OmgwtfnzbsSettings.cs index 778b3a48e..900055608 100644 --- a/NzbDrone.Core/Indexers/Omgwtfnzbs/OmgwtfnzbsSettings.cs +++ b/NzbDrone.Core/Indexers/Omgwtfnzbs/OmgwtfnzbsSettings.cs @@ -2,6 +2,7 @@ using FluentValidation; using FluentValidation.Results; using NzbDrone.Core.Annotations; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Indexers.Omgwtfnzbs { @@ -14,7 +15,7 @@ namespace NzbDrone.Core.Indexers.Omgwtfnzbs } } - public class OmgwtfnzbsSettings : IIndexerSetting + public class OmgwtfnzbsSettings : IProviderConfig { private static readonly OmgwtfnzbsSettingsValidator Validator = new OmgwtfnzbsSettingsValidator(); diff --git a/NzbDrone.Core/Notifications/Email/EmailSettings.cs b/NzbDrone.Core/Notifications/Email/EmailSettings.cs index 1d678dae9..42aa725cd 100644 --- a/NzbDrone.Core/Notifications/Email/EmailSettings.cs +++ b/NzbDrone.Core/Notifications/Email/EmailSettings.cs @@ -1,4 +1,5 @@ using System; +using FluentValidation.Results; using NzbDrone.Core.Annotations; using NzbDrone.Core.ThingiProvider; @@ -39,5 +40,10 @@ namespace NzbDrone.Core.Notifications.Email return !string.IsNullOrWhiteSpace(Server) && Port > 0 && !string.IsNullOrWhiteSpace(From) && !string.IsNullOrWhiteSpace(To); } } + + public ValidationResult Validate() + { + throw new NotImplementedException(); + } } } diff --git a/NzbDrone.Core/Notifications/Growl/GrowlSettings.cs b/NzbDrone.Core/Notifications/Growl/GrowlSettings.cs index 75c3de74a..dd049268d 100644 --- a/NzbDrone.Core/Notifications/Growl/GrowlSettings.cs +++ b/NzbDrone.Core/Notifications/Growl/GrowlSettings.cs @@ -1,4 +1,5 @@ using System; +using FluentValidation.Results; using NzbDrone.Core.Annotations; using NzbDrone.Core.ThingiProvider; @@ -27,5 +28,10 @@ namespace NzbDrone.Core.Notifications.Growl return !string.IsNullOrWhiteSpace(Host) && !string.IsNullOrWhiteSpace(Password) && Port > 0; } } + + public ValidationResult Validate() + { + throw new NotImplementedException(); + } } } diff --git a/NzbDrone.Core/Notifications/NotificationDefinition.cs b/NzbDrone.Core/Notifications/NotificationDefinition.cs index 15f274dfc..41fc64509 100644 --- a/NzbDrone.Core/Notifications/NotificationDefinition.cs +++ b/NzbDrone.Core/Notifications/NotificationDefinition.cs @@ -14,7 +14,7 @@ namespace NzbDrone.Core.Notifications } - public class NotificationProviderModel : Provider + public class NotificationProviderModel : ProviderDefinition { public Boolean OnGrab { get; set; } public Boolean OnDownload { get; set; } diff --git a/NzbDrone.Core/Notifications/NotificationService.cs b/NzbDrone.Core/Notifications/NotificationService.cs index 3febb84e0..458c80d65 100644 --- a/NzbDrone.Core/Notifications/NotificationService.cs +++ b/NzbDrone.Core/Notifications/NotificationService.cs @@ -19,7 +19,7 @@ namespace NzbDrone.Core.Notifications Notification Get(int id); List Schema(); Notification Create(Notification notification); - Notification Update(Notification notification); + void Update(Notification notification); void Delete(int id); } @@ -94,15 +94,13 @@ namespace NzbDrone.Core.Notifications return notification; } - public Notification Update(Notification notification) + public void Update(Notification notification) { var definition = _notificationRepository.Get(notification.Id); definition.InjectFrom(notification); definition.Settings = notification.Settings.ToJson(); _notificationRepository.Update(definition); - - return notification; } public void Delete(int id) diff --git a/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroidSettings.cs b/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroidSettings.cs index f9a4da283..48c8c6fc6 100644 --- a/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroidSettings.cs +++ b/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroidSettings.cs @@ -1,4 +1,5 @@ using System; +using FluentValidation.Results; using NzbDrone.Core.Annotations; using NzbDrone.Core.ThingiProvider; @@ -19,5 +20,10 @@ namespace NzbDrone.Core.Notifications.NotifyMyAndroid return !String.IsNullOrWhiteSpace(ApiKey) && Priority != null & Priority >= -1 && Priority <= 2; } } + + public ValidationResult Validate() + { + throw new NotImplementedException(); + } } } diff --git a/NzbDrone.Core/Notifications/Plex/PlexClientSettings.cs b/NzbDrone.Core/Notifications/Plex/PlexClientSettings.cs index 95c9a3291..a0d762406 100644 --- a/NzbDrone.Core/Notifications/Plex/PlexClientSettings.cs +++ b/NzbDrone.Core/Notifications/Plex/PlexClientSettings.cs @@ -1,4 +1,5 @@ using System; +using FluentValidation.Results; using NzbDrone.Core.Annotations; using NzbDrone.Core.ThingiProvider; @@ -30,5 +31,10 @@ namespace NzbDrone.Core.Notifications.Plex return !string.IsNullOrWhiteSpace(Host); } } + + public ValidationResult Validate() + { + throw new NotImplementedException(); + } } } diff --git a/NzbDrone.Core/Notifications/Plex/PlexServerSettings.cs b/NzbDrone.Core/Notifications/Plex/PlexServerSettings.cs index 9f4e3cc5f..ed410767b 100644 --- a/NzbDrone.Core/Notifications/Plex/PlexServerSettings.cs +++ b/NzbDrone.Core/Notifications/Plex/PlexServerSettings.cs @@ -1,4 +1,5 @@ using System; +using FluentValidation.Results; using NzbDrone.Core.Annotations; using NzbDrone.Core.ThingiProvider; @@ -27,5 +28,10 @@ namespace NzbDrone.Core.Notifications.Plex return !string.IsNullOrWhiteSpace(Host); } } + + public ValidationResult Validate() + { + throw new NotImplementedException(); + } } } diff --git a/NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs b/NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs index 1b6db74cc..66b574179 100644 --- a/NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs +++ b/NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs @@ -1,4 +1,5 @@ using System; +using FluentValidation.Results; using NzbDrone.Core.Annotations; using NzbDrone.Core.ThingiProvider; @@ -19,5 +20,10 @@ namespace NzbDrone.Core.Notifications.Prowl return !string.IsNullOrWhiteSpace(ApiKey) && Priority != null & Priority >= -2 && Priority <= 2; } } + + public ValidationResult Validate() + { + throw new NotImplementedException(); + } } } diff --git a/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs b/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs index cf34b3718..1886991d8 100644 --- a/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs +++ b/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs @@ -1,4 +1,5 @@ using System; +using FluentValidation.Results; using NzbDrone.Core.Annotations; using NzbDrone.Core.ThingiProvider; @@ -19,5 +20,10 @@ namespace NzbDrone.Core.Notifications.PushBullet return !String.IsNullOrWhiteSpace(ApiKey) && DeviceId > 0; } } + + public ValidationResult Validate() + { + throw new NotImplementedException(); + } } } diff --git a/NzbDrone.Core/Notifications/Pushover/PushoverSettings.cs b/NzbDrone.Core/Notifications/Pushover/PushoverSettings.cs index 4a42baac9..ca4c332c7 100644 --- a/NzbDrone.Core/Notifications/Pushover/PushoverSettings.cs +++ b/NzbDrone.Core/Notifications/Pushover/PushoverSettings.cs @@ -1,4 +1,5 @@ using System; +using FluentValidation.Results; using NzbDrone.Core.Annotations; using NzbDrone.Core.ThingiProvider; @@ -19,5 +20,10 @@ namespace NzbDrone.Core.Notifications.Pushover return !string.IsNullOrWhiteSpace(UserKey) && Priority != null & Priority >= -1 && Priority <= 2; } } + + public ValidationResult Validate() + { + throw new NotImplementedException(); + } } } diff --git a/NzbDrone.Core/Notifications/Xbmc/XbmcSettings.cs b/NzbDrone.Core/Notifications/Xbmc/XbmcSettings.cs index 26e114d30..2c0569c89 100644 --- a/NzbDrone.Core/Notifications/Xbmc/XbmcSettings.cs +++ b/NzbDrone.Core/Notifications/Xbmc/XbmcSettings.cs @@ -1,5 +1,6 @@ using System; using System.ComponentModel; +using FluentValidation.Results; using Newtonsoft.Json; using NzbDrone.Core.Annotations; using NzbDrone.Core.ThingiProvider; @@ -52,5 +53,10 @@ namespace NzbDrone.Core.Notifications.Xbmc return !string.IsNullOrWhiteSpace(Host) && Port > 0; } } + + public ValidationResult Validate() + { + throw new NotImplementedException(); + } } } diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 049d2cb4c..f8d3c3b7c 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -246,7 +246,6 @@ - @@ -343,13 +342,11 @@ - - diff --git a/NzbDrone.Core/ThingiProvider/ProviderBase.cs b/NzbDrone.Core/ThingiProvider/ProviderBase.cs index bf24434d2..f91577aa9 100644 --- a/NzbDrone.Core/ThingiProvider/ProviderBase.cs +++ b/NzbDrone.Core/ThingiProvider/ProviderBase.cs @@ -1,22 +1,13 @@  +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 DownloadProviderRepository : BasicRepository - { - public DownloadProviderRepository(IDatabase database, IEventAggregator eventAggregator) - : base(database, eventAggregator) - { - } - } - - - public class NotificationProviderRepository : BasicRepository + public class NotificationProviderRepository : BasicRepository { public NotificationProviderRepository(IDatabase database, IEventAggregator eventAggregator) : base(database, eventAggregator) @@ -24,13 +15,21 @@ namespace NzbDrone.Core.ThingiProvider } } - public class DownloadProviderModel : Provider - { + public class IndexerProviderRepository : BasicRepository + { + public IndexerProviderRepository(IDatabase database, IEventAggregator eventAggregator) + : base(database, eventAggregator) + { + } } + public abstract class ProviderBase + { + public ProviderDefinition Definition { get; set; } + } - public abstract class Provider : ModelBase + public abstract class ProviderDefinition : ModelBase { public string Name { get; set; } public string Implementation { get; set; } @@ -44,7 +43,7 @@ namespace NzbDrone.Core.ThingiProvider } set { - + } } @@ -53,6 +52,16 @@ namespace NzbDrone.Core.ThingiProvider public interface IProviderConfig { - bool IsValid { get; } + ValidationResult Validate(); + } + + public class NullSetting : IProviderConfig + { + public static readonly NullSetting Instance = new NullSetting(); + + public ValidationResult Validate() + { + return new ValidationResult(); + } } } \ No newline at end of file From 9dbfc6804f98588c13eda5eec5e8560b93471eeb Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Sat, 21 Sep 2013 22:20:26 -0700 Subject: [PATCH 05/16] 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 @@ 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))] 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 @@ 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) 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 @@ namespace NzbDrone.Api.Indexers 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 @@ 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(); } 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 @@ 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); 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 @@ using NzbDrone.Core.ThingiProvider; 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 @@ namespace NzbDrone.Core.IndexerSearch 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 @@ namespace NzbDrone.Core.Indexers { 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 @@ using NzbDrone.Core.ThingiProvider; 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 @@ namespace NzbDrone.Core.Indexers.Newznab } } - public override IEnumerable DefaultDefinitions + public override IEnumerable DefaultDefinitions { get { @@ -118,7 +119,7 @@ namespace NzbDrone.Core.Indexers.Newznab { 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 @@ using System.Collections.Generic; 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 From 3e9a6ed0ef1a256508c6d58acb7fca4f49e55b40 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Sun, 22 Sep 2013 13:00:29 -0700 Subject: [PATCH 06/16] indexer cleanup. --- NzbDrone.Core/Indexers/Eztv/Eztv.cs | 23 +++-------- NzbDrone.Core/Indexers/IIndexer.cs | 2 +- NzbDrone.Core/Indexers/IndexerBase.cs | 24 ++++++++---- NzbDrone.Core/Indexers/IndexerFetchService.cs | 19 +++++----- NzbDrone.Core/Indexers/IndexerService.cs | 21 ++++++++++ NzbDrone.Core/Indexers/Newznab/Newznab.cs | 16 ++------ .../Indexers/Omgwtfnzbs/Omgwtfnzbs.cs | 9 +---- NzbDrone.Core/Indexers/Wombles/Wombles.cs | 11 ++---- NzbDrone.Core/ThingiProvider/IProvider.cs | 7 ++-- .../ThingiProvider/ProviderService.cs | 38 ++++++++----------- 10 files changed, 81 insertions(+), 89 deletions(-) diff --git a/NzbDrone.Core/Indexers/Eztv/Eztv.cs b/NzbDrone.Core/Indexers/Eztv/Eztv.cs index 8b514f255..52c55df60 100644 --- a/NzbDrone.Core/Indexers/Eztv/Eztv.cs +++ b/NzbDrone.Core/Indexers/Eztv/Eztv.cs @@ -4,26 +4,16 @@ using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Indexers.Eztv { - public class Eztv : IndexerBase + public class Eztv : IndexerBase { - public override string Name - { - get { return "Eztv"; } - } - - public override IndexerKind Kind + public override DownloadProtocol Protocol { get { - return IndexerKind.Torrent; + return DownloadProtocol.Torrent; } } - public override bool EnableByDefault - { - get { return false; } - } - public override IParseFeed Parser { get @@ -36,10 +26,7 @@ namespace NzbDrone.Core.Indexers.Eztv { get { - return new[] - { - "http://www.ezrss.it/feed/" - }; + yield return "http://www.ezrss.it/feed/"; } } @@ -56,7 +43,7 @@ namespace NzbDrone.Core.Indexers.Eztv public override IEnumerable GetDailyEpisodeSearchUrls(string seriesTitle, int tvRageId, DateTime date) { - //EZTV doesn't support searching based on actual epidose airdate. they only support release date. + //EZTV doesn't support searching based on actual episode airdate. they only support release date. return new string[0]; } } diff --git a/NzbDrone.Core/Indexers/IIndexer.cs b/NzbDrone.Core/Indexers/IIndexer.cs index 9e77b433d..34daa6a26 100644 --- a/NzbDrone.Core/Indexers/IIndexer.cs +++ b/NzbDrone.Core/Indexers/IIndexer.cs @@ -7,7 +7,7 @@ namespace NzbDrone.Core.Indexers public interface IIndexer : IProvider { IParseFeed Parser { get; } - IndexerKind Kind { get; } + DownloadProtocol Protocol { get; } IEnumerable RecentFeed { get; } IEnumerable GetEpisodeSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int episodeNumber); diff --git a/NzbDrone.Core/Indexers/IndexerBase.cs b/NzbDrone.Core/Indexers/IndexerBase.cs index 604f536c9..ddedc098c 100644 --- a/NzbDrone.Core/Indexers/IndexerBase.cs +++ b/NzbDrone.Core/Indexers/IndexerBase.cs @@ -6,7 +6,13 @@ namespace NzbDrone.Core.Indexers { public abstract class IndexerBase : IIndexer { - public abstract string Name { get; } + public Type ConfigContract + { + get + { + return typeof(TSettings); + } + } public virtual IEnumerable DefaultDefinitions { @@ -14,19 +20,17 @@ namespace NzbDrone.Core.Indexers { yield return new IndexerDefinition { - Name = Name, + Name = this.GetType().Name, Enable = false, Implementation = GetType().Name, - Settings = NullSetting.Instance + Settings = NullConfig.Instance }; } } public ProviderDefinition Definition { get; set; } - public abstract IndexerKind Kind { get; } - - public virtual bool EnableByDefault { get { return true; } } + public abstract DownloadProtocol Protocol { get; } protected TSettings Settings { @@ -42,9 +46,15 @@ namespace NzbDrone.Core.Indexers public abstract IEnumerable GetEpisodeSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int episodeNumber); public abstract IEnumerable GetDailyEpisodeSearchUrls(string seriesTitle, int tvRageId, DateTime date); public abstract IEnumerable GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset); + + + public override string ToString() + { + return GetType().Name; + } } - public enum IndexerKind + public enum DownloadProtocol { Usenet, Torrent diff --git a/NzbDrone.Core/Indexers/IndexerFetchService.cs b/NzbDrone.Core/Indexers/IndexerFetchService.cs index ba284c8b7..d9457f58b 100644 --- a/NzbDrone.Core/Indexers/IndexerFetchService.cs +++ b/NzbDrone.Core/Indexers/IndexerFetchService.cs @@ -33,11 +33,11 @@ namespace NzbDrone.Core.Indexers public virtual IList FetchRss(IIndexer indexer) { - _logger.Debug("Fetching feeds from " + indexer.Name); + _logger.Debug("Fetching feeds from " + indexer); var result = Fetch(indexer, indexer.RecentFeed); - _logger.Debug("Finished processing feeds from " + indexer.Name); + _logger.Debug("Finished processing feeds from " + indexer); return result; } @@ -48,7 +48,7 @@ namespace NzbDrone.Core.Indexers var result = Fetch(indexer, searchCriteria, 0).DistinctBy(c => c.DownloadUrl).ToList(); - _logger.Info("Finished searching {0} for {1}. Found {2}", indexer.Name, searchCriteria, result.Count); + _logger.Info("Finished searching {0} for {1}. Found {2}", indexer, searchCriteria, result.Count); return result; } @@ -61,7 +61,7 @@ namespace NzbDrone.Core.Indexers var result = Fetch(indexer, searchUrls); - _logger.Info("{0} offset {1}. Found {2}", indexer.Name, searchCriteria, result.Count); + _logger.Info("{0} offset {1}. Found {2}", indexer, searchCriteria, result.Count); if (result.Count > 90) { @@ -79,7 +79,7 @@ namespace NzbDrone.Core.Indexers var result = Fetch(indexer, searchUrls); - _logger.Info("Finished searching {0} for {1}. Found {2}", indexer.Name, searchCriteria, result.Count); + _logger.Info("Finished searching {0} for {1}. Found {2}", indexer, searchCriteria, result.Count); return result; } @@ -90,7 +90,7 @@ namespace NzbDrone.Core.Indexers var searchUrls = indexer.GetDailyEpisodeSearchUrls(searchCriteria.QueryTitle, searchCriteria.Series.TvRageId, searchCriteria.Airtime); var result = Fetch(indexer, searchUrls); - _logger.Info("Finished searching {0} for {1}. Found {2}", indexer.Name, searchCriteria, result.Count); + _logger.Info("Finished searching {0} for {1}. Found {2}", indexer, searchCriteria, result.Count); return result; } @@ -119,12 +119,11 @@ namespace NzbDrone.Core.Indexers if (webException.Message.Contains("502") || webException.Message.Contains("503") || webException.Message.Contains("timed out")) { - _logger.Warn("{0} server is currently unavailable. {1} {2}", indexer.Name, url, - webException.Message); + _logger.Warn("{0} server is currently unavailable. {1} {2}", indexer, url, webException.Message); } else { - _logger.Warn("{0} {1} {2}", indexer.Name, url, webException.Message); + _logger.Warn("{0} {1} {2}", indexer, url, webException.Message); } } catch (ApiKeyException) @@ -138,7 +137,7 @@ namespace NzbDrone.Core.Indexers } } - result.ForEach(c => c.Indexer = indexer.Name); + result.ForEach(c => c.Indexer = indexer.Definition.Name); return result; } diff --git a/NzbDrone.Core/Indexers/IndexerService.cs b/NzbDrone.Core/Indexers/IndexerService.cs index cd4a8a11e..e56531438 100644 --- a/NzbDrone.Core/Indexers/IndexerService.cs +++ b/NzbDrone.Core/Indexers/IndexerService.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using NLog; using NzbDrone.Core.ThingiProvider; @@ -11,9 +12,29 @@ namespace NzbDrone.Core.Indexers public class IndexerService : ProviderFactory { + private readonly IProviderRepository _providerRepository; + private readonly IEnumerable _providers; + public IndexerService(IProviderRepository providerRepository, IEnumerable providers, Logger logger) : base(providerRepository, providers, logger) { + _providerRepository = providerRepository; + _providers = providers; + } + + protected override void InitializeProviders() + { + 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()); + } } } } \ No newline at end of file diff --git a/NzbDrone.Core/Indexers/Newznab/Newznab.cs b/NzbDrone.Core/Indexers/Newznab/Newznab.cs index 980513aa0..a4c106846 100644 --- a/NzbDrone.Core/Indexers/Newznab/Newznab.cs +++ b/NzbDrone.Core/Indexers/Newznab/Newznab.cs @@ -69,7 +69,7 @@ namespace NzbDrone.Core.Indexers.Newznab get { //Todo: We should be able to update settings on start - if (Name.Equals("nzbs.org", StringComparison.InvariantCultureIgnoreCase)) + if (Settings.Url.Contains("nzbs.org")) { Settings.Categories = new List { 5000 }; } @@ -115,19 +115,11 @@ namespace NzbDrone.Core.Indexers.Newznab return RecentFeed.Select(url => String.Format("{0}&limit=100&q={1}&season={2}&offset={3}", url, NewsnabifyTitle(seriesTitle), seasonNumber, offset)); } - public override string Name + public override DownloadProtocol Protocol { get { - return Definition.Name; - } - } - - public override IndexerKind Kind - { - get - { - return IndexerKind.Usenet; + return DownloadProtocol.Usenet; } } @@ -136,4 +128,4 @@ namespace NzbDrone.Core.Indexers.Newznab return title.Replace("+", "%20"); } } -} \ No newline at end of file +} diff --git a/NzbDrone.Core/Indexers/Omgwtfnzbs/Omgwtfnzbs.cs b/NzbDrone.Core/Indexers/Omgwtfnzbs/Omgwtfnzbs.cs index 4c281910e..c4daeab66 100644 --- a/NzbDrone.Core/Indexers/Omgwtfnzbs/Omgwtfnzbs.cs +++ b/NzbDrone.Core/Indexers/Omgwtfnzbs/Omgwtfnzbs.cs @@ -5,16 +5,11 @@ namespace NzbDrone.Core.Indexers.Omgwtfnzbs { public class Omgwtfnzbs : IndexerBase { - public override string Name - { - get { return "omgwtfnzbs"; } - } - - public override IndexerKind Kind + public override DownloadProtocol Protocol { get { - return IndexerKind.Usenet; + return DownloadProtocol.Usenet; } } diff --git a/NzbDrone.Core/Indexers/Wombles/Wombles.cs b/NzbDrone.Core/Indexers/Wombles/Wombles.cs index 2f455219e..5355d853d 100644 --- a/NzbDrone.Core/Indexers/Wombles/Wombles.cs +++ b/NzbDrone.Core/Indexers/Wombles/Wombles.cs @@ -4,18 +4,13 @@ using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Indexers.Wombles { - public class Wombles : IndexerBase + public class Wombles : IndexerBase { - public override string Name - { - get { return "WomblesIndex"; } - } - - public override IndexerKind Kind + public override DownloadProtocol Protocol { get { - return IndexerKind.Usenet; + return DownloadProtocol.Usenet; } } diff --git a/NzbDrone.Core/ThingiProvider/IProvider.cs b/NzbDrone.Core/ThingiProvider/IProvider.cs index 4d64ea8ec..7baeb4bc7 100644 --- a/NzbDrone.Core/ThingiProvider/IProvider.cs +++ b/NzbDrone.Core/ThingiProvider/IProvider.cs @@ -30,7 +30,7 @@ namespace NzbDrone.Core.ThingiProvider public interface IProvider { - string Name { get; } + Type ConfigContract { get; } IEnumerable DefaultDefinitions { get; } ProviderDefinition Definition { get; set; } @@ -51,7 +51,6 @@ namespace NzbDrone.Core.ThingiProvider } set { - } } @@ -63,9 +62,9 @@ namespace NzbDrone.Core.ThingiProvider ValidationResult Validate(); } - public class NullSetting : IProviderConfig + public class NullConfig : IProviderConfig { - public static readonly NullSetting Instance = new NullSetting(); + public static readonly NullConfig Instance = new NullConfig(); public ValidationResult Validate() { diff --git a/NzbDrone.Core/ThingiProvider/ProviderService.cs b/NzbDrone.Core/ThingiProvider/ProviderService.cs index c55529ec1..c09a1d79c 100644 --- a/NzbDrone.Core/ThingiProvider/ProviderService.cs +++ b/NzbDrone.Core/ThingiProvider/ProviderService.cs @@ -52,21 +52,21 @@ namespace NzbDrone.Core.ThingiProvider return _providerRepository.Get(id); } - /* public List Schema() - { - var indexers = new List(); + /* 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"; + 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); + indexers.Add(newznab); - return indexers; - }*/ + return indexers; + }*/ public TProviderDefinition Create(TProviderDefinition provider) { @@ -102,17 +102,11 @@ namespace NzbDrone.Core.ThingiProvider RemoveMissingImplementations(); - var definitions = _providers.SelectMany(indexer => indexer.DefaultDefinitions); + InitializeProviders(); + } - var currentProviders = All(); - - var newProviders = definitions.Where(def => currentProviders.All(c => c.Implementation != def.Implementation)).ToList(); - - - if (newProviders.Any()) - { - _providerRepository.InsertMany(newProviders.Cast().ToList()); - } + protected virtual void InitializeProviders() + { } private void RemoveMissingImplementations() From 1e88d2b7c3c7e9916d4be45309e0472f974eab62 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Sun, 22 Sep 2013 13:06:11 -0700 Subject: [PATCH 07/16] fixed broken tests. --- NzbDrone.Api/Indexers/IndexerResource.cs | 1 + .../ThingiProvider/ProviderBaseFixture.cs | 2 +- NzbDrone.Core/Indexers/IndexerRepository.cs | 23 ++++--------------- NzbDrone.Core/Indexers/IndexerService.cs | 4 ++-- 4 files changed, 9 insertions(+), 21 deletions(-) diff --git a/NzbDrone.Api/Indexers/IndexerResource.cs b/NzbDrone.Api/Indexers/IndexerResource.cs index 34a31551a..a613526fe 100644 --- a/NzbDrone.Api/Indexers/IndexerResource.cs +++ b/NzbDrone.Api/Indexers/IndexerResource.cs @@ -11,5 +11,6 @@ namespace NzbDrone.Api.Indexers public String Name { get; set; } public List Fields { get; set; } public String Implementation { get; set; } + public String ConfigContract { get; set; } } } \ No newline at end of file diff --git a/NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs b/NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs index 8aa47c176..641e62dca 100644 --- a/NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs +++ b/NzbDrone.Core.Test/ThingiProvider/ProviderBaseFixture.cs @@ -9,7 +9,7 @@ using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Test.ThingiProvider { - public class ProviderRepositoryFixture : DbTest, IndexerDefinition> + public class ProviderRepositoryFixture : DbTest { [Test] public void should_read_write_download_provider() diff --git a/NzbDrone.Core/Indexers/IndexerRepository.cs b/NzbDrone.Core/Indexers/IndexerRepository.cs index b4c6446a1..269bb5507 100644 --- a/NzbDrone.Core/Indexers/IndexerRepository.cs +++ b/NzbDrone.Core/Indexers/IndexerRepository.cs @@ -1,33 +1,20 @@ -using System; -using System.Linq; -using NzbDrone.Core.Datastore; +using NzbDrone.Core.Datastore; using NzbDrone.Core.Messaging.Events; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Indexers { - public interface IIndexerRepository : IBasicRepository + public interface IIndexerRepository : IProviderRepository { - IndexerDefinition Get(string name); - IndexerDefinition Find(string name); + } - public class IndexerRepository : BasicRepository, IIndexerRepository + public class IndexerRepository : ProviderRepository, IIndexerRepository { public IndexerRepository(IDatabase database, IEventAggregator eventAggregator) : base(database, eventAggregator) { } - - public IndexerDefinition Get(string name) - { - return Query.Single(i => i.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)); - } - - public IndexerDefinition Find(string name) - { - return Query.SingleOrDefault(i => i.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)); - } - } } diff --git a/NzbDrone.Core/Indexers/IndexerService.cs b/NzbDrone.Core/Indexers/IndexerService.cs index e56531438..dd1b9aca9 100644 --- a/NzbDrone.Core/Indexers/IndexerService.cs +++ b/NzbDrone.Core/Indexers/IndexerService.cs @@ -12,10 +12,10 @@ namespace NzbDrone.Core.Indexers public class IndexerService : ProviderFactory { - private readonly IProviderRepository _providerRepository; + private readonly IIndexerRepository _providerRepository; private readonly IEnumerable _providers; - public IndexerService(IProviderRepository providerRepository, IEnumerable providers, Logger logger) + public IndexerService(IIndexerRepository providerRepository, IEnumerable providers, Logger logger) : base(providerRepository, providers, logger) { _providerRepository = providerRepository; From 0eec2cd5f79d4b22a43503c551262a5b5c8aa4a2 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Sun, 22 Sep 2013 16:40:36 -0700 Subject: [PATCH 08/16] schema updates --- .../ClientSchemaTests/SchemaBuilderFixture.cs | 4 +- NzbDrone.Api/ClientSchema/SchemaBuilder.cs | 51 ++++++++++++++++++- .../ClientSchema/SchemaDeserializer.cs | 34 +------------ NzbDrone.Api/Indexers/IndexerModule.cs | 21 +++++--- NzbDrone.Api/Indexers/IndexerSchemaModule.cs | 6 ++- .../Notifications/NotificationModule.cs | 8 ++- .../Notifications/NotificationSchemaModule.cs | 2 +- .../Reflection/ReflectionExtensions.cs | 7 +++ .../ProviderSettingConverterFixture.cs | 39 ++++++++++++++ NzbDrone.Core.Test/NzbDrone.Core.Test.csproj | 1 + .../Converters/EmbeddedDocumentConverter.cs | 32 ------------ .../Converters/ProviderSettingConverter.cs | 36 +++++++++++++ .../023_add_config_contract_to_indexers.cs | 23 +++++++++ NzbDrone.Core/Indexers/IndexerService.cs | 2 +- NzbDrone.Core/NzbDrone.Core.csproj | 2 + NzbDrone.Core/ThingiProvider/IProvider.cs | 15 ++++-- .../ThingiProvider/ProviderService.cs | 23 ++------- 17 files changed, 199 insertions(+), 107 deletions(-) create mode 100644 NzbDrone.Core.Test/Datastore/Converters/ProviderSettingConverterFixture.cs create mode 100644 NzbDrone.Core/Datastore/Converters/ProviderSettingConverter.cs create mode 100644 NzbDrone.Core/Datastore/Migration/023_add_config_contract_to_indexers.cs diff --git a/NzbDrone.Api.Test/ClientSchemaTests/SchemaBuilderFixture.cs b/NzbDrone.Api.Test/ClientSchemaTests/SchemaBuilderFixture.cs index bf3d72d11..385a9b989 100644 --- a/NzbDrone.Api.Test/ClientSchemaTests/SchemaBuilderFixture.cs +++ b/NzbDrone.Api.Test/ClientSchemaTests/SchemaBuilderFixture.cs @@ -12,7 +12,7 @@ namespace NzbDrone.Api.Test.ClientSchemaTests [Test] public void should_return_field_for_every_property() { - var schema = SchemaBuilder.GenerateSchema(new TestModel()); + var schema = SchemaBuilder.ToSchema(new TestModel()); schema.Should().HaveCount(2); } @@ -26,7 +26,7 @@ namespace NzbDrone.Api.Test.ClientSchemaTests LastName = "Poop" }; - var schema = SchemaBuilder.GenerateSchema(model); + var schema = SchemaBuilder.ToSchema(model); schema.Should().Contain(c => c.Order == 1 && c.Name == "LastName" && c.Label == "Last Name" && c.HelpText == "Your Last Name" && (string) c.Value == "Poop"); schema.Should().Contain(c => c.Order == 0 && c.Name == "FirstName" && c.Label == "First Name" && c.HelpText == "Your First Name" && (string) c.Value == "Bob"); diff --git a/NzbDrone.Api/ClientSchema/SchemaBuilder.cs b/NzbDrone.Api/ClientSchema/SchemaBuilder.cs index 99b2c6d15..1393387bc 100644 --- a/NzbDrone.Api/ClientSchema/SchemaBuilder.cs +++ b/NzbDrone.Api/ClientSchema/SchemaBuilder.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Linq; +using NzbDrone.Common; +using NzbDrone.Common.EnsureThat; using NzbDrone.Common.Reflection; using NzbDrone.Core.Annotations; @@ -8,8 +10,10 @@ namespace NzbDrone.Api.ClientSchema { public static class SchemaBuilder { - public static List GenerateSchema(object model) + public static List ToSchema(object model) { + Ensure.That(() => model).IsNotNull(); + var properties = model.GetType().GetSimpleProperties(); var result = new List(properties.Count); @@ -50,10 +54,53 @@ namespace NzbDrone.Api.ClientSchema } + + public static object ReadFormSchema(List fields, Type targetType) + { + var properties = targetType.GetSimpleProperties(); + + var target = Activator.CreateInstance(targetType); + + foreach (var propertyInfo in properties) + { + var fieldAttribute = propertyInfo.GetAttribute(false); + + if (fieldAttribute != null) + { + var field = fields.Find(f => f.Name == propertyInfo.Name); + + if (propertyInfo.PropertyType == typeof(Int32)) + { + var intValue = Convert.ToInt32(field.Value); + propertyInfo.SetValue(target, intValue, null); + } + + else if (propertyInfo.PropertyType == typeof(Nullable)) + { + var intValue = field.Value.ToString().ParseInt32(); + propertyInfo.SetValue(target, intValue, null); + } + + else + { + propertyInfo.SetValue(target, field.Value, null); + } + } + } + + return target; + + } + + public static T ReadFormSchema(List fields) + { + return (T)ReadFormSchema(fields, typeof (T)); + } + private static List GetSelectOptions(Type selectOptions) { var options = from Enum e in Enum.GetValues(selectOptions) - select new SelectOption { Value = Convert.ToInt32(e), Name = e.ToString() }; + select new SelectOption { Value = Convert.ToInt32(e), Name = e.ToString() }; return options.OrderBy(o => o.Value).ToList(); } diff --git a/NzbDrone.Api/ClientSchema/SchemaDeserializer.cs b/NzbDrone.Api/ClientSchema/SchemaDeserializer.cs index 9985ffb49..36d2a68e8 100644 --- a/NzbDrone.Api/ClientSchema/SchemaDeserializer.cs +++ b/NzbDrone.Api/ClientSchema/SchemaDeserializer.cs @@ -8,38 +8,6 @@ namespace NzbDrone.Api.ClientSchema { public static class SchemaDeserializer { - public static T DeserializeSchema(T model, List fields) - { - var properties = model.GetType().GetSimpleProperties(); - - foreach (var propertyInfo in properties) - { - var fieldAttribute = propertyInfo.GetAttribute(false); - - if (fieldAttribute != null) - { - var field = fields.Find(f => f.Name == propertyInfo.Name); - - if (propertyInfo.PropertyType == typeof (Int32)) - { - var intValue = Convert.ToInt32(field.Value); - propertyInfo.SetValue(model, intValue, null); - } - - else if (propertyInfo.PropertyType == typeof(Nullable)) - { - var intValue = field.Value.ToString().ParseInt32(); - propertyInfo.SetValue(model, intValue, null); - } - - else - { - propertyInfo.SetValue(model, field.Value, null); - } - } - } - - return model; - } + } } \ No newline at end of file diff --git a/NzbDrone.Api/Indexers/IndexerModule.cs b/NzbDrone.Api/Indexers/IndexerModule.cs index cd5ed90c0..531a7dee8 100644 --- a/NzbDrone.Api/Indexers/IndexerModule.cs +++ b/NzbDrone.Api/Indexers/IndexerModule.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using NzbDrone.Api.ClientSchema; +using NzbDrone.Common.Reflection; using NzbDrone.Core.Indexers; using NzbDrone.Core.ThingiProvider; using Omu.ValueInjecter; @@ -35,15 +36,15 @@ namespace NzbDrone.Api.Indexers private List GetAll() { - var indexers = _indexerService.All(); + var indexerDefinitions = _indexerService.All(); - var result = new List(indexers.Count); + var result = new List(indexerDefinitions.Count); - foreach (var indexer in indexers) + foreach (var definition in indexerDefinitions) { var indexerResource = new IndexerResource(); - indexerResource.InjectFrom(indexer); - indexerResource.Fields = SchemaBuilder.GenerateSchema(indexer.Settings); + indexerResource.InjectFrom(definition); + indexerResource.Fields = SchemaBuilder.ToSchema(definition.Settings); result.Add(indexerResource); } @@ -53,14 +54,14 @@ namespace NzbDrone.Api.Indexers private int CreateIndexer(IndexerResource indexerResource) { - var indexer = GetIndexer(indexerResource); + var indexer = GetDefinition(indexerResource); indexer = _indexerService.Create(indexer); return indexer.Id; } private void UpdateIndexer(IndexerResource indexerResource) { - var indexer = GetIndexer(indexerResource); + var indexer = GetDefinition(indexerResource); ValidateIndexer(indexer.Settings); @@ -78,12 +79,16 @@ namespace NzbDrone.Api.Indexers } } - private IndexerDefinition GetIndexer(IndexerResource indexerResource) + private IndexerDefinition GetDefinition(IndexerResource indexerResource) { var definition = new IndexerDefinition(); definition.InjectFrom(indexerResource); + + var configContract = ReflectionExtensions.CoreAssembly.FindTypeByName(definition.ConfigContract); + definition.Settings = (IProviderConfig)SchemaBuilder.ReadFormSchema(indexerResource.Fields, configContract); + if (indexerResource.Enable) { ValidateIndexer(definition.Settings); diff --git a/NzbDrone.Api/Indexers/IndexerSchemaModule.cs b/NzbDrone.Api/Indexers/IndexerSchemaModule.cs index 9fe425cf0..8d9b09f2a 100644 --- a/NzbDrone.Api/Indexers/IndexerSchemaModule.cs +++ b/NzbDrone.Api/Indexers/IndexerSchemaModule.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using NzbDrone.Api.ClientSchema; +using NzbDrone.Api.Mapping; using NzbDrone.Core.Indexers; using Omu.ValueInjecter; @@ -18,6 +19,9 @@ namespace NzbDrone.Api.Indexers private List GetSchema() { + + var indexers = _indexerService.All().InjectTo>(); + /* var indexers = _indexerService.Schema(); var result = new List(indexers.Count); @@ -33,7 +37,7 @@ namespace NzbDrone.Api.Indexers return result;*/ - return null; + return indexers; } } } \ No newline at end of file diff --git a/NzbDrone.Api/Notifications/NotificationModule.cs b/NzbDrone.Api/Notifications/NotificationModule.cs index bc7ca8aac..c8be13f67 100644 --- a/NzbDrone.Api/Notifications/NotificationModule.cs +++ b/NzbDrone.Api/Notifications/NotificationModule.cs @@ -4,6 +4,7 @@ using System.Linq; using NzbDrone.Api.ClientSchema; using NzbDrone.Api.Mapping; using NzbDrone.Api.REST; +using NzbDrone.Common.Reflection; using NzbDrone.Core.Notifications; using Omu.ValueInjecter; @@ -39,7 +40,7 @@ namespace NzbDrone.Api.Notifications { var notificationResource = new NotificationResource(); notificationResource.InjectFrom(notification); - notificationResource.Fields = SchemaBuilder.GenerateSchema(notification.Settings); + notificationResource.Fields = SchemaBuilder.ToSchema(notification.Settings); notificationResource.TestCommand = String.Format("test{0}", notification.Implementation.ToLowerInvariant()); result.Add(notificationResource); @@ -79,7 +80,10 @@ namespace NzbDrone.Api.Notifications } notification.InjectFrom(notificationResource); - notification.Settings = SchemaDeserializer.DeserializeSchema(notification.Settings, notificationResource.Fields); + + //var configType = ReflectionExtensions.CoreAssembly.FindTypeByName(notification) + + //notification.Settings = SchemaBuilder.ReadFormSchema(notification.Settings, notificationResource.Fields); return notification; } diff --git a/NzbDrone.Api/Notifications/NotificationSchemaModule.cs b/NzbDrone.Api/Notifications/NotificationSchemaModule.cs index d347e343c..68a5bd594 100644 --- a/NzbDrone.Api/Notifications/NotificationSchemaModule.cs +++ b/NzbDrone.Api/Notifications/NotificationSchemaModule.cs @@ -28,7 +28,7 @@ namespace NzbDrone.Api.Notifications { var notificationResource = new NotificationResource(); notificationResource.InjectFrom(notification); - notificationResource.Fields = SchemaBuilder.GenerateSchema(notification.Settings); + notificationResource.Fields = SchemaBuilder.ToSchema(notification.Settings); notificationResource.TestCommand = String.Format("test{0}", notification.Implementation.ToLowerInvariant()); result.Add(notificationResource); diff --git a/NzbDrone.Common/Reflection/ReflectionExtensions.cs b/NzbDrone.Common/Reflection/ReflectionExtensions.cs index 98ff9ff12..0c70d0c42 100644 --- a/NzbDrone.Common/Reflection/ReflectionExtensions.cs +++ b/NzbDrone.Common/Reflection/ReflectionExtensions.cs @@ -7,6 +7,8 @@ namespace NzbDrone.Common.Reflection { public static class ReflectionExtensions { + public static readonly Assembly CoreAssembly = Assembly.Load("NzbDrone.Core"); + public static List GetSimpleProperties(this Type type) { var properties = type.GetProperties(); @@ -58,6 +60,11 @@ namespace NzbDrone.Common.Reflection return (T)attribute; } + public static Type FindTypeByName(this Assembly assembly, string name) + { + return assembly.GetTypes().Single(c => c.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)); + } + public static bool HasAttribute(this Type type) { return type.GetCustomAttributes(typeof(TAttribute), true).Any(); diff --git a/NzbDrone.Core.Test/Datastore/Converters/ProviderSettingConverterFixture.cs b/NzbDrone.Core.Test/Datastore/Converters/ProviderSettingConverterFixture.cs new file mode 100644 index 000000000..9aafbee73 --- /dev/null +++ b/NzbDrone.Core.Test/Datastore/Converters/ProviderSettingConverterFixture.cs @@ -0,0 +1,39 @@ +using System; +using FluentAssertions; +using Marr.Data.Converters; +using NUnit.Framework; +using NzbDrone.Core.Datastore.Converters; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Core.ThingiProvider; + +namespace NzbDrone.Core.Test.Datastore.Converters +{ + [TestFixture] + public class ProviderSettingConverterFixture : CoreTest + { + [Test] + public void should_return_null_config_if_config_is_null() + { + var result = Subject.FromDB(new ConverterContext() + { + DbValue = DBNull.Value + }); + + + result.Should().Be(NullConfig.Instance); + } + + [TestCase(null)] + [TestCase("")] + public void should_return_null_config_if_config_is_empty(object dbValue) + { + var result = Subject.FromDB(new ConverterContext() + { + DbValue = dbValue + }); + + + result.Should().Be(NullConfig.Instance); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index 430b4d934..39bda7be4 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -102,6 +102,7 @@ + diff --git a/NzbDrone.Core/Datastore/Converters/EmbeddedDocumentConverter.cs b/NzbDrone.Core/Datastore/Converters/EmbeddedDocumentConverter.cs index 89b2ecea1..e144d4cf4 100644 --- a/NzbDrone.Core/Datastore/Converters/EmbeddedDocumentConverter.cs +++ b/NzbDrone.Core/Datastore/Converters/EmbeddedDocumentConverter.cs @@ -1,42 +1,10 @@ using System; -using System.Linq; using Marr.Data.Converters; using Marr.Data.Mapping; using NzbDrone.Common.Serializer; -using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Datastore.Converters { - - public class ProviderSettingConverter : EmbeddedDocumentConverter - { - public override object FromDB(ConverterContext context) - { - if (context.DbValue == DBNull.Value) - { - return DBNull.Value; - } - - var stringValue = (string)context.DbValue; - - if (string.IsNullOrWhiteSpace(stringValue)) - { - return null; - } - - var ordinal = context.DataRecord.GetOrdinal("ConfigContract"); - - var implementation = context.DataRecord.GetString(ordinal); - - - var impType = typeof(IProviderConfig).Assembly.GetTypes().Single(c => c.Name == implementation); - - return Json.Deserialize(stringValue, impType); - } - - } - - public class EmbeddedDocumentConverter : IConverter { public virtual object FromDB(ConverterContext context) diff --git a/NzbDrone.Core/Datastore/Converters/ProviderSettingConverter.cs b/NzbDrone.Core/Datastore/Converters/ProviderSettingConverter.cs new file mode 100644 index 000000000..8e83938a9 --- /dev/null +++ b/NzbDrone.Core/Datastore/Converters/ProviderSettingConverter.cs @@ -0,0 +1,36 @@ +using System; +using Marr.Data.Converters; +using NzbDrone.Common.Reflection; +using NzbDrone.Common.Serializer; +using NzbDrone.Core.ThingiProvider; + +namespace NzbDrone.Core.Datastore.Converters +{ + public class ProviderSettingConverter : EmbeddedDocumentConverter + { + public override object FromDB(ConverterContext context) + { + if (context.DbValue == DBNull.Value) + { + return NullConfig.Instance; + } + + var stringValue = (string)context.DbValue; + + if (string.IsNullOrWhiteSpace(stringValue)) + { + return NullConfig.Instance; + } + + var ordinal = context.DataRecord.GetOrdinal("ConfigContract"); + + var implementation = context.DataRecord.GetString(ordinal); + + + var impType = typeof (IProviderConfig).Assembly.FindTypeByName(implementation); + + return Json.Deserialize(stringValue, impType); + } + + } +} \ No newline at end of file diff --git a/NzbDrone.Core/Datastore/Migration/023_add_config_contract_to_indexers.cs b/NzbDrone.Core/Datastore/Migration/023_add_config_contract_to_indexers.cs new file mode 100644 index 000000000..cf2153605 --- /dev/null +++ b/NzbDrone.Core/Datastore/Migration/023_add_config_contract_to_indexers.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Data; +using FluentMigrator; +using NzbDrone.Common.Serializer; +using NzbDrone.Core.Datastore.Migration.Framework; + +namespace NzbDrone.Core.Datastore.Migration +{ + [Migration(23)] + public class add_config_contract_to_indexers : NzbDroneMigrationBase + { + protected override void MainDbUpgrade() + { + Update.Table("Indexers").Set(new { ConfigContract = "NewznabSettings" }).Where(new { Implementation = "Newznab" }); + Update.Table("Indexers").Set(new { ConfigContract = "OmgwtfnzbsSettings" }).Where(new { Implementation = "Omgwtfnzbs" }); + Update.Table("Indexers").Set(new { ConfigContract = "NullConfig" }).Where(new { Implementation = "Wombles" }); + Update.Table("Indexers").Set(new { ConfigContract = "NullConfig" }).Where(new { Implementation = "Eztv" }); + + Delete.FromTable("Indexers").IsNull("ConfigContract"); + } + } +} diff --git a/NzbDrone.Core/Indexers/IndexerService.cs b/NzbDrone.Core/Indexers/IndexerService.cs index dd1b9aca9..70e845747 100644 --- a/NzbDrone.Core/Indexers/IndexerService.cs +++ b/NzbDrone.Core/Indexers/IndexerService.cs @@ -10,7 +10,7 @@ namespace NzbDrone.Core.Indexers } - public class IndexerService : ProviderFactory + public class IndexerService : ProviderFactory, IIndexerService { private readonly IIndexerRepository _providerRepository; private readonly IEnumerable _providers; diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 8cdb8a182..5956274e0 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -140,6 +140,7 @@ + @@ -172,6 +173,7 @@ + diff --git a/NzbDrone.Core/ThingiProvider/IProvider.cs b/NzbDrone.Core/ThingiProvider/IProvider.cs index 7baeb4bc7..c3308316e 100644 --- a/NzbDrone.Core/ThingiProvider/IProvider.cs +++ b/NzbDrone.Core/ThingiProvider/IProvider.cs @@ -38,23 +38,28 @@ namespace NzbDrone.Core.ThingiProvider public abstract class ProviderDefinition : ModelBase { + private IProviderConfig _settings; public string Name { get; set; } public string Implementation { get; set; } public bool Enable { get; set; } - public string ConfigContract + public string ConfigContract { get; set; } + + public IProviderConfig Settings { get { - if (Settings == null) return null; - return Settings.GetType().Name; + return _settings; } set { + _settings = value; + if (value != null) + { + ConfigContract = value.GetType().Name; + } } } - - public IProviderConfig Settings { get; set; } } public interface IProviderConfig diff --git a/NzbDrone.Core/ThingiProvider/ProviderService.cs b/NzbDrone.Core/ThingiProvider/ProviderService.cs index c09a1d79c..b56f6cac3 100644 --- a/NzbDrone.Core/ThingiProvider/ProviderService.cs +++ b/NzbDrone.Core/ThingiProvider/ProviderService.cs @@ -14,7 +14,6 @@ namespace NzbDrone.Core.ThingiProvider List All(); List GetAvailableProviders(); TProviderDefinition Get(int id); - //List Schema(); TProviderDefinition Create(TProviderDefinition indexer); void Update(TProviderDefinition indexer); void Delete(int id); @@ -52,22 +51,6 @@ namespace NzbDrone.Core.ThingiProvider 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); @@ -113,10 +96,10 @@ namespace NzbDrone.Core.ThingiProvider { var storedProvider = _providerRepository.All(); - foreach (var providerDefinition in storedProvider.Where(i => GetImplementation(i) == null)) + foreach (var invalidDefinition in storedProvider.Where(def => GetImplementation(def) == null)) { - _logger.Debug("Removing {0} ", providerDefinition.Name); - _providerRepository.Delete(providerDefinition); + _logger.Debug("Removing {0} ", invalidDefinition.Name); + _providerRepository.Delete(invalidDefinition); } } } From 4f9b745e7021d404e12f4e65cf479d149f63a43f Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Sun, 22 Sep 2013 17:27:00 -0700 Subject: [PATCH 09/16] fixed schema support for indexers --- NzbDrone.Api/Indexers/IndexerModule.cs | 13 +++++----- NzbDrone.Api/Indexers/IndexerSchemaModule.cs | 25 ++++++++----------- .../ThingiProvider/ProviderService.cs | 12 +++++++++ 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/NzbDrone.Api/Indexers/IndexerModule.cs b/NzbDrone.Api/Indexers/IndexerModule.cs index 531a7dee8..5776a14b0 100644 --- a/NzbDrone.Api/Indexers/IndexerModule.cs +++ b/NzbDrone.Api/Indexers/IndexerModule.cs @@ -63,15 +63,17 @@ namespace NzbDrone.Api.Indexers { var indexer = GetDefinition(indexerResource); - ValidateIndexer(indexer.Settings); + ValidateIndexer(indexer); _indexerService.Update(indexer); } - private static void ValidateIndexer(IProviderConfig config) + private static void ValidateIndexer(ProviderDefinition definition) { - var validationResult = config.Validate(); + if (!definition.Enable) return; + + var validationResult = definition.Settings.Validate(); if (!validationResult.IsValid) { @@ -89,10 +91,7 @@ namespace NzbDrone.Api.Indexers var configContract = ReflectionExtensions.CoreAssembly.FindTypeByName(definition.ConfigContract); definition.Settings = (IProviderConfig)SchemaBuilder.ReadFormSchema(indexerResource.Fields, configContract); - if (indexerResource.Enable) - { - ValidateIndexer(definition.Settings); - } + ValidateIndexer(definition); return definition; } diff --git a/NzbDrone.Api/Indexers/IndexerSchemaModule.cs b/NzbDrone.Api/Indexers/IndexerSchemaModule.cs index 8d9b09f2a..368af9383 100644 --- a/NzbDrone.Api/Indexers/IndexerSchemaModule.cs +++ b/NzbDrone.Api/Indexers/IndexerSchemaModule.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; +using System.Linq; using NzbDrone.Api.ClientSchema; -using NzbDrone.Api.Mapping; using NzbDrone.Core.Indexers; using Omu.ValueInjecter; @@ -20,24 +20,21 @@ namespace NzbDrone.Api.Indexers private List GetSchema() { - var indexers = _indexerService.All().InjectTo>(); + var indexers = _indexerService.Templates().Where(c => c.Implementation =="Newznab"); - /* 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.ToSchema(indexer.Settings); - result.Add(indexerResource); - } + result.Add(indexerResource); + } - return result;*/ - - return indexers; + return result; } } } \ No newline at end of file diff --git a/NzbDrone.Core/ThingiProvider/ProviderService.cs b/NzbDrone.Core/ThingiProvider/ProviderService.cs index b56f6cac3..9869f9679 100644 --- a/NzbDrone.Core/ThingiProvider/ProviderService.cs +++ b/NzbDrone.Core/ThingiProvider/ProviderService.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using NLog; +using NzbDrone.Common.Reflection; using NzbDrone.Core.Lifecycle; using NzbDrone.Core.Messaging.Events; @@ -17,6 +18,7 @@ namespace NzbDrone.Core.ThingiProvider TProviderDefinition Create(TProviderDefinition indexer); void Update(TProviderDefinition indexer); void Delete(int id); + List Templates(); } public abstract class ProviderFactory : IProviderFactory, IHandle @@ -40,6 +42,16 @@ namespace NzbDrone.Core.ThingiProvider return _providerRepository.All().ToList(); } + public List Templates() + { + return _providers.Select(p => new TProviderDefinition() + { + ConfigContract = p.ConfigContract.Name, + Implementation = p.GetType().Name, + Settings = (IProviderConfig)Activator.CreateInstance(ReflectionExtensions.CoreAssembly.FindTypeByName(p.ConfigContract.Name)) + }).ToList(); + } + public List GetAvailableProviders() { return All().Where(c => c.Enable && c.Settings.Validate().IsValid) From eaed756655adc11fdd0c44af0e351c5299803c49 Mon Sep 17 00:00:00 2001 From: kayone Date: Tue, 24 Sep 2013 16:42:55 -0700 Subject: [PATCH 10/16] created ProviderModuleBase --- NzbDrone.Api/IndexerResource.cs | 16 +++ NzbDrone.Api/Indexers/IndexerModule.cs | 100 +------------ NzbDrone.Api/Indexers/IndexerSchemaModule.cs | 8 +- NzbDrone.Api/NzbDrone.Api.csproj | 2 + NzbDrone.Api/ProviderModuleBase.cs | 133 ++++++++++++++++++ NzbDrone.App.Test/ContainerFixture.cs | 2 +- .../IndexerTests/IndexerServiceFixture.cs | 2 +- .../IndexerSearch/NzbSearchService.cs | 8 +- .../Indexers/FetchAndParseRssService.cs | 8 +- .../{IndexerService.cs => IndexerFactory.cs} | 6 +- NzbDrone.Core/NzbDrone.Core.csproj | 2 +- 11 files changed, 173 insertions(+), 114 deletions(-) create mode 100644 NzbDrone.Api/IndexerResource.cs create mode 100644 NzbDrone.Api/ProviderModuleBase.cs rename NzbDrone.Core/Indexers/{IndexerService.cs => IndexerFactory.cs} (82%) diff --git a/NzbDrone.Api/IndexerResource.cs b/NzbDrone.Api/IndexerResource.cs new file mode 100644 index 000000000..65c5bad64 --- /dev/null +++ b/NzbDrone.Api/IndexerResource.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using NzbDrone.Api.ClientSchema; +using NzbDrone.Api.REST; + +namespace NzbDrone.Api +{ + public class ProviderResource : RestResource + { + public Boolean Enable { get; set; } + public String Name { get; set; } + public List Fields { get; set; } + public String Implementation { get; set; } + public String ConfigContract { get; set; } + } +} \ No newline at end of file diff --git a/NzbDrone.Api/Indexers/IndexerModule.cs b/NzbDrone.Api/Indexers/IndexerModule.cs index 5776a14b0..52b38fe7d 100644 --- a/NzbDrone.Api/Indexers/IndexerModule.cs +++ b/NzbDrone.Api/Indexers/IndexerModule.cs @@ -1,104 +1,12 @@ -using System.Collections.Generic; -using NzbDrone.Api.ClientSchema; -using NzbDrone.Common.Reflection; -using NzbDrone.Core.Indexers; -using NzbDrone.Core.ThingiProvider; -using Omu.ValueInjecter; -using FluentValidation; -using NzbDrone.Api.Mapping; +using NzbDrone.Core.Indexers; namespace NzbDrone.Api.Indexers { - public class IndexerModule : NzbDroneRestModule + public class IndexerModule : ProviderModuleBase { - private readonly IIndexerService _indexerService; - - public IndexerModule(IIndexerService indexerService) + public IndexerModule(IndexerFactory indexerFactory) + : base(indexerFactory) { - _indexerService = indexerService; - GetResourceAll = GetAll; - GetResourceById = GetIndexer; - CreateResource = CreateIndexer; - UpdateResource = UpdateIndexer; - DeleteResource = DeleteIndexer; - - - SharedValidator.RuleFor(c => c.Name).NotEmpty(); - SharedValidator.RuleFor(c => c.Implementation).NotEmpty(); - - PostValidator.RuleFor(c => c.Fields).NotEmpty(); - } - - private IndexerResource GetIndexer(int id) - { - return _indexerService.Get(id).InjectTo(); - } - - private List GetAll() - { - var indexerDefinitions = _indexerService.All(); - - var result = new List(indexerDefinitions.Count); - - foreach (var definition in indexerDefinitions) - { - var indexerResource = new IndexerResource(); - indexerResource.InjectFrom(definition); - indexerResource.Fields = SchemaBuilder.ToSchema(definition.Settings); - - result.Add(indexerResource); - } - - return result; - } - - private int CreateIndexer(IndexerResource indexerResource) - { - var indexer = GetDefinition(indexerResource); - indexer = _indexerService.Create(indexer); - return indexer.Id; - } - - private void UpdateIndexer(IndexerResource indexerResource) - { - var indexer = GetDefinition(indexerResource); - - ValidateIndexer(indexer); - - _indexerService.Update(indexer); - } - - - private static void ValidateIndexer(ProviderDefinition definition) - { - if (!definition.Enable) return; - - var validationResult = definition.Settings.Validate(); - - if (!validationResult.IsValid) - { - throw new ValidationException(validationResult.Errors); - } - } - - private IndexerDefinition GetDefinition(IndexerResource indexerResource) - { - - var definition = new IndexerDefinition(); - - definition.InjectFrom(indexerResource); - - var configContract = ReflectionExtensions.CoreAssembly.FindTypeByName(definition.ConfigContract); - definition.Settings = (IProviderConfig)SchemaBuilder.ReadFormSchema(indexerResource.Fields, configContract); - - ValidateIndexer(definition); - - return definition; - } - - private void DeleteIndexer(int id) - { - _indexerService.Delete(id); } } } \ No newline at end of file diff --git a/NzbDrone.Api/Indexers/IndexerSchemaModule.cs b/NzbDrone.Api/Indexers/IndexerSchemaModule.cs index 368af9383..a0312bdc4 100644 --- a/NzbDrone.Api/Indexers/IndexerSchemaModule.cs +++ b/NzbDrone.Api/Indexers/IndexerSchemaModule.cs @@ -8,19 +8,19 @@ namespace NzbDrone.Api.Indexers { public class IndexerSchemaModule : NzbDroneRestModule { - private readonly IIndexerService _indexerService; + private readonly IIndexerFactory _indexerFactory; - public IndexerSchemaModule(IIndexerService indexerService) + public IndexerSchemaModule(IIndexerFactory indexerFactory) : base("indexer/schema") { - _indexerService = indexerService; + _indexerFactory = indexerFactory; GetResourceAll = GetSchema; } private List GetSchema() { - var indexers = _indexerService.Templates().Where(c => c.Implementation =="Newznab"); + var indexers = _indexerFactory.Templates().Where(c => c.Implementation =="Newznab"); var result = new List(indexers.Count()); diff --git a/NzbDrone.Api/NzbDrone.Api.csproj b/NzbDrone.Api/NzbDrone.Api.csproj index b88c2277d..8c8493ad3 100644 --- a/NzbDrone.Api/NzbDrone.Api.csproj +++ b/NzbDrone.Api/NzbDrone.Api.csproj @@ -109,6 +109,8 @@ + + diff --git a/NzbDrone.Api/ProviderModuleBase.cs b/NzbDrone.Api/ProviderModuleBase.cs new file mode 100644 index 000000000..a56891a68 --- /dev/null +++ b/NzbDrone.Api/ProviderModuleBase.cs @@ -0,0 +1,133 @@ +using System.Collections.Generic; +using System.Linq; +using FluentValidation; +using Nancy; +using NzbDrone.Api.ClientSchema; +using NzbDrone.Api.Extensions; +using NzbDrone.Api.Indexers; +using NzbDrone.Api.Mapping; +using NzbDrone.Common.Reflection; +using NzbDrone.Core.ThingiProvider; +using Omu.ValueInjecter; + +namespace NzbDrone.Api +{ + public abstract class ProviderModuleBase : NzbDroneRestModule + where TProviderDefinition : ProviderDefinition, new() + where TProvider : IProvider + where TProviderResource : ProviderResource, new() + { + private readonly IProviderFactory _providerFactory; + + protected ProviderModuleBase(IProviderFactory providerFactory) + { + _providerFactory = providerFactory; + Get["templates"] = x => GetTemplates(); + GetResourceAll = GetAll; + GetResourceById = GetProviderById; + CreateResource = CreateProvider; + UpdateResource = UpdateProvider; + DeleteResource = DeleteProvider; + + + + SharedValidator.RuleFor(c => c.Name).NotEmpty(); + SharedValidator.RuleFor(c => c.Implementation).NotEmpty(); + SharedValidator.RuleFor(c => c.ConfigContract).NotEmpty(); + + PostValidator.RuleFor(c => c.Fields).NotEmpty(); + } + + private TProviderResource GetProviderById(int id) + { + return _providerFactory.Get(id).InjectTo(); + } + + private List GetAll() + { + var indexerDefinitions = _providerFactory.All(); + + var result = new List(indexerDefinitions.Count); + + foreach (var definition in indexerDefinitions) + { + var indexerResource = new TProviderResource(); + indexerResource.InjectFrom(definition); + indexerResource.Fields = SchemaBuilder.ToSchema(definition.Settings); + + result.Add(indexerResource); + } + + return result; + } + + private int CreateProvider(TProviderResource indexerResource) + { + var indexer = GetDefinition(indexerResource); + indexer = _providerFactory.Create(indexer); + return indexer.Id; + } + + private void UpdateProvider(TProviderResource indexerResource) + { + var indexer = GetDefinition(indexerResource); + + ValidateIndexer(indexer); + + _providerFactory.Update(indexer); + } + + + private static void ValidateIndexer(ProviderDefinition definition) + { + if (!definition.Enable) return; + + var validationResult = definition.Settings.Validate(); + + if (!validationResult.IsValid) + { + throw new ValidationException(validationResult.Errors); + } + } + + private TProviderDefinition GetDefinition(TProviderResource indexerResource) + { + + var definition = new TProviderDefinition(); + + definition.InjectFrom(indexerResource); + + var configContract = ReflectionExtensions.CoreAssembly.FindTypeByName(definition.ConfigContract); + definition.Settings = (IProviderConfig)SchemaBuilder.ReadFormSchema(indexerResource.Fields, configContract); + + ValidateIndexer(definition); + + return definition; + } + + private void DeleteProvider(int id) + { + _providerFactory.Delete(id); + } + + private Response GetTemplates() + { + + var indexers = _providerFactory.Templates(); + + + var result = new List(indexers.Count()); + + foreach (var indexer in indexers) + { + var indexerResource = new IndexerResource(); + indexerResource.InjectFrom(indexer); + indexerResource.Fields = SchemaBuilder.ToSchema(indexer.Settings); + + result.Add(indexerResource); + } + + return result.AsResponse(); + } + } +} \ No newline at end of file diff --git a/NzbDrone.App.Test/ContainerFixture.cs b/NzbDrone.App.Test/ContainerFixture.cs index 14a35688d..a165f9348 100644 --- a/NzbDrone.App.Test/ContainerFixture.cs +++ b/NzbDrone.App.Test/ContainerFixture.cs @@ -37,7 +37,7 @@ namespace NzbDrone.App.Test { var factory = MainAppContainerBuilder.BuildContainer(args).Resolve(); - factory.Build().Should().NotBeNull(); + factory.Build().Should().NotBeNull(); } [Test] diff --git a/NzbDrone.Core.Test/IndexerTests/IndexerServiceFixture.cs b/NzbDrone.Core.Test/IndexerTests/IndexerServiceFixture.cs index 6ac94cc81..2012921f0 100644 --- a/NzbDrone.Core.Test/IndexerTests/IndexerServiceFixture.cs +++ b/NzbDrone.Core.Test/IndexerTests/IndexerServiceFixture.cs @@ -13,7 +13,7 @@ using NzbDrone.Core.Test.Framework; namespace NzbDrone.Core.Test.IndexerTests { - public class IndexerServiceFixture : DbTest + public class IndexerServiceFixture : DbTest { private List _indexers; diff --git a/NzbDrone.Core/IndexerSearch/NzbSearchService.cs b/NzbDrone.Core/IndexerSearch/NzbSearchService.cs index e79f3cedd..96b52e8cf 100644 --- a/NzbDrone.Core/IndexerSearch/NzbSearchService.cs +++ b/NzbDrone.Core/IndexerSearch/NzbSearchService.cs @@ -24,7 +24,7 @@ namespace NzbDrone.Core.IndexerSearch public class NzbSearchService : ISearchForNzb { - private readonly IIndexerService _indexerService; + private readonly IIndexerFactory _indexerFactory; private readonly IFetchFeedFromIndexers _feedFetcher; private readonly ISceneMappingService _sceneMapping; private readonly ISeriesService _seriesService; @@ -32,7 +32,7 @@ namespace NzbDrone.Core.IndexerSearch private readonly IMakeDownloadDecision _makeDownloadDecision; private readonly Logger _logger; - public NzbSearchService(IIndexerService indexerService, + public NzbSearchService(IIndexerFactory indexerFactory, IFetchFeedFromIndexers feedFetcher, ISceneMappingService sceneMapping, ISeriesService seriesService, @@ -40,7 +40,7 @@ namespace NzbDrone.Core.IndexerSearch IMakeDownloadDecision makeDownloadDecision, Logger logger) { - _indexerService = indexerService; + _indexerFactory = indexerFactory; _feedFetcher = feedFetcher; _sceneMapping = sceneMapping; _seriesService = seriesService; @@ -132,7 +132,7 @@ namespace NzbDrone.Core.IndexerSearch private List Dispatch(Func> searchAction, SearchCriteriaBase criteriaBase) { - var indexers = _indexerService.GetAvailableProviders().ToList(); + var indexers = _indexerFactory.GetAvailableProviders().ToList(); var reports = new List(); _logger.ProgressInfo("Searching {0} indexers for {1}", indexers.Count, criteriaBase); diff --git a/NzbDrone.Core/Indexers/FetchAndParseRssService.cs b/NzbDrone.Core/Indexers/FetchAndParseRssService.cs index f153311fb..534668b6b 100644 --- a/NzbDrone.Core/Indexers/FetchAndParseRssService.cs +++ b/NzbDrone.Core/Indexers/FetchAndParseRssService.cs @@ -14,13 +14,13 @@ namespace NzbDrone.Core.Indexers public class FetchAndParseRssService : IFetchAndParseRss { - private readonly IIndexerService _indexerService; + private readonly IIndexerFactory _indexerFactory; private readonly IFetchFeedFromIndexers _feedFetcher; private readonly Logger _logger; - public FetchAndParseRssService(IIndexerService indexerService, IFetchFeedFromIndexers feedFetcher, Logger logger) + public FetchAndParseRssService(IIndexerFactory indexerFactory, IFetchFeedFromIndexers feedFetcher, Logger logger) { - _indexerService = indexerService; + _indexerFactory = indexerFactory; _feedFetcher = feedFetcher; _logger = logger; } @@ -29,7 +29,7 @@ namespace NzbDrone.Core.Indexers { var result = new List(); - var indexers = _indexerService.GetAvailableProviders().ToList(); + var indexers = _indexerFactory.GetAvailableProviders().ToList(); if (!indexers.Any()) { diff --git a/NzbDrone.Core/Indexers/IndexerService.cs b/NzbDrone.Core/Indexers/IndexerFactory.cs similarity index 82% rename from NzbDrone.Core/Indexers/IndexerService.cs rename to NzbDrone.Core/Indexers/IndexerFactory.cs index 70e845747..a8796fc28 100644 --- a/NzbDrone.Core/Indexers/IndexerService.cs +++ b/NzbDrone.Core/Indexers/IndexerFactory.cs @@ -5,17 +5,17 @@ using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Indexers { - public interface IIndexerService : IProviderFactory + public interface IIndexerFactory : IProviderFactory { } - public class IndexerService : ProviderFactory, IIndexerService + public class IndexerFactory : ProviderFactory, IIndexerFactory { private readonly IIndexerRepository _providerRepository; private readonly IEnumerable _providers; - public IndexerService(IIndexerRepository providerRepository, IEnumerable providers, Logger logger) + public IndexerFactory(IIndexerRepository providerRepository, IEnumerable providers, Logger logger) : base(providerRepository, providers, logger) { _providerRepository = providerRepository; diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 5956274e0..e5058b047 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -500,7 +500,7 @@ Code - + Code From e8b2d1fda0e679a4d2b875897438cc722014cd2d Mon Sep 17 00:00:00 2001 From: kayone Date: Tue, 24 Sep 2013 17:01:03 -0700 Subject: [PATCH 11/16] fixed broken test, cleaned up some code around config contracts. --- NzbDrone.Api/ClientSchema/SchemaBuilder.cs | 2 ++ NzbDrone.Common/Reflection/ReflectionExtensions.cs | 2 +- .../IndexerTests/IndexerServiceFixture.cs | 1 + .../Converters/ProviderSettingConverter.cs | 10 +++++++--- NzbDrone.Core/NzbDrone.Core.csproj | 1 + .../ConfigContractNotFoundException.cs | 13 +++++++++++++ NzbDrone.Core/ThingiProvider/ProviderService.cs | 2 +- 7 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 NzbDrone.Core/ThingiProvider/ConfigContractNotFoundException.cs diff --git a/NzbDrone.Api/ClientSchema/SchemaBuilder.cs b/NzbDrone.Api/ClientSchema/SchemaBuilder.cs index 1393387bc..c5c96c302 100644 --- a/NzbDrone.Api/ClientSchema/SchemaBuilder.cs +++ b/NzbDrone.Api/ClientSchema/SchemaBuilder.cs @@ -57,6 +57,8 @@ namespace NzbDrone.Api.ClientSchema public static object ReadFormSchema(List fields, Type targetType) { + Ensure.That(() => targetType).IsNotNull(); + var properties = targetType.GetSimpleProperties(); var target = Activator.CreateInstance(targetType); diff --git a/NzbDrone.Common/Reflection/ReflectionExtensions.cs b/NzbDrone.Common/Reflection/ReflectionExtensions.cs index 0c70d0c42..898d45119 100644 --- a/NzbDrone.Common/Reflection/ReflectionExtensions.cs +++ b/NzbDrone.Common/Reflection/ReflectionExtensions.cs @@ -62,7 +62,7 @@ namespace NzbDrone.Common.Reflection public static Type FindTypeByName(this Assembly assembly, string name) { - return assembly.GetTypes().Single(c => c.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)); + return assembly.GetTypes().SingleOrDefault(c => c.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)); } public static bool HasAttribute(this Type type) diff --git a/NzbDrone.Core.Test/IndexerTests/IndexerServiceFixture.cs b/NzbDrone.Core.Test/IndexerTests/IndexerServiceFixture.cs index 2012921f0..bbfb8404a 100644 --- a/NzbDrone.Core.Test/IndexerTests/IndexerServiceFixture.cs +++ b/NzbDrone.Core.Test/IndexerTests/IndexerServiceFixture.cs @@ -71,6 +71,7 @@ namespace NzbDrone.Core.Test.IndexerTests var existingIndexers = Builder.CreateNew().BuildNew(); + existingIndexers.ConfigContract = typeof (NewznabSettings).Name; repo.Insert(existingIndexers); diff --git a/NzbDrone.Core/Datastore/Converters/ProviderSettingConverter.cs b/NzbDrone.Core/Datastore/Converters/ProviderSettingConverter.cs index 8e83938a9..ace64d6af 100644 --- a/NzbDrone.Core/Datastore/Converters/ProviderSettingConverter.cs +++ b/NzbDrone.Core/Datastore/Converters/ProviderSettingConverter.cs @@ -23,11 +23,15 @@ namespace NzbDrone.Core.Datastore.Converters } var ordinal = context.DataRecord.GetOrdinal("ConfigContract"); - - var implementation = context.DataRecord.GetString(ordinal); + var contract = context.DataRecord.GetString(ordinal); - var impType = typeof (IProviderConfig).Assembly.FindTypeByName(implementation); + var impType = typeof (IProviderConfig).Assembly.FindTypeByName(contract); + + if (impType == null) + { + throw new ConfigContractNotFoundException(contract); + } return Json.Deserialize(stringValue, impType); } diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index e5058b047..582096964 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -414,6 +414,7 @@ + diff --git a/NzbDrone.Core/ThingiProvider/ConfigContractNotFoundException.cs b/NzbDrone.Core/ThingiProvider/ConfigContractNotFoundException.cs new file mode 100644 index 000000000..47d6ecdf3 --- /dev/null +++ b/NzbDrone.Core/ThingiProvider/ConfigContractNotFoundException.cs @@ -0,0 +1,13 @@ +using NzbDrone.Common.Exceptions; + +namespace NzbDrone.Core.ThingiProvider +{ + public class ConfigContractNotFoundException : NzbDroneException + { + public ConfigContractNotFoundException(string contract) + : base("Couldn't find config contract " + contract) + { + } + + } +} diff --git a/NzbDrone.Core/ThingiProvider/ProviderService.cs b/NzbDrone.Core/ThingiProvider/ProviderService.cs index 9869f9679..4765de4bc 100644 --- a/NzbDrone.Core/ThingiProvider/ProviderService.cs +++ b/NzbDrone.Core/ThingiProvider/ProviderService.cs @@ -48,7 +48,7 @@ namespace NzbDrone.Core.ThingiProvider { ConfigContract = p.ConfigContract.Name, Implementation = p.GetType().Name, - Settings = (IProviderConfig)Activator.CreateInstance(ReflectionExtensions.CoreAssembly.FindTypeByName(p.ConfigContract.Name)) + Settings = (IProviderConfig)Activator.CreateInstance(p.ConfigContract) }).ToList(); } From 7b14d09976839f87b141431762bc2e5a2de8cb8a Mon Sep 17 00:00:00 2001 From: kayone Date: Tue, 24 Sep 2013 17:12:45 -0700 Subject: [PATCH 12/16] fixed indexer integration tests. --- .../IntegrationTests/IndexerIntegrationTests.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/NzbDrone.Core.Test/IndexerTests/IntegrationTests/IndexerIntegrationTests.cs b/NzbDrone.Core.Test/IndexerTests/IntegrationTests/IndexerIntegrationTests.cs index 9c51cd84e..28dc053e4 100644 --- a/NzbDrone.Core.Test/IndexerTests/IntegrationTests/IndexerIntegrationTests.cs +++ b/NzbDrone.Core.Test/IndexerTests/IntegrationTests/IndexerIntegrationTests.cs @@ -7,6 +7,7 @@ using NzbDrone.Core.Indexers.Wombles; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Test.Framework; using NUnit.Framework; +using NzbDrone.Core.ThingiProvider; using NzbDrone.Test.Common.Categories; using System.Linq; @@ -27,6 +28,12 @@ namespace NzbDrone.Core.Test.IndexerTests.IntegrationTests { var indexer = new Wombles(); + indexer.Definition = new IndexerDefinition + { + Name = "Wombles", + Settings = NullConfig.Instance + }; + var result = Subject.FetchRss(indexer); ValidateResult(result, skipSize: true, skipInfo: true); @@ -37,6 +44,11 @@ namespace NzbDrone.Core.Test.IndexerTests.IntegrationTests public void extv_rss() { var indexer = new Eztv(); + indexer.Definition = new IndexerDefinition + { + Name = "Eztv", + Settings = NullConfig.Instance + }; var result = Subject.FetchRss(indexer); From c9f5cb02570e7d4fdad6966ec4cefa957c147471 Mon Sep 17 00:00:00 2001 From: kayone Date: Tue, 1 Oct 2013 10:13:40 -0700 Subject: [PATCH 13/16] cleaned up ThingiProvider --- NzbDrone.Core/Indexers/IndexerFetchService.cs | 2 +- NzbDrone.Core/NzbDrone.Core.csproj | 10 ++- NzbDrone.Core/NzbDrone.Core.ncrunchproject | 2 +- NzbDrone.Core/ThingiProvider/IProvider.cs | 65 ------------------- .../ThingiProvider/IProviderConfig.cs | 9 +++ .../ThingiProvider/IProviderFactory.cs | 17 +++++ .../ThingiProvider/IProviderRepository.cs | 8 +++ NzbDrone.Core/ThingiProvider/NullConfig.cs | 14 ++++ .../ThingiProvider/ProviderDefinition.cs | 30 +++++++++ ...{ProviderService.cs => ProviderFactory.cs} | 14 ---- .../ThingiProvider/ProviderRepository.cs | 16 +++++ 11 files changed, 104 insertions(+), 83 deletions(-) create mode 100644 NzbDrone.Core/ThingiProvider/IProviderConfig.cs create mode 100644 NzbDrone.Core/ThingiProvider/IProviderFactory.cs create mode 100644 NzbDrone.Core/ThingiProvider/IProviderRepository.cs create mode 100644 NzbDrone.Core/ThingiProvider/NullConfig.cs create mode 100644 NzbDrone.Core/ThingiProvider/ProviderDefinition.cs rename NzbDrone.Core/ThingiProvider/{ProviderService.cs => ProviderFactory.cs} (86%) create mode 100644 NzbDrone.Core/ThingiProvider/ProviderRepository.cs diff --git a/NzbDrone.Core/Indexers/IndexerFetchService.cs b/NzbDrone.Core/Indexers/IndexerFetchService.cs index d9457f58b..b571f6466 100644 --- a/NzbDrone.Core/Indexers/IndexerFetchService.cs +++ b/NzbDrone.Core/Indexers/IndexerFetchService.cs @@ -128,7 +128,7 @@ namespace NzbDrone.Core.Indexers } catch (ApiKeyException) { - _logger.Warn("Invalid API Key for {0} {1}", indexer.Name, url); + _logger.Warn("Invalid API Key for {0} {1}", indexer, url); } catch (Exception feedEx) { diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 582096964..c19c6e319 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -422,7 +422,13 @@ - + + + + + + + @@ -621,4 +627,4 @@ --> - + \ No newline at end of file diff --git a/NzbDrone.Core/NzbDrone.Core.ncrunchproject b/NzbDrone.Core/NzbDrone.Core.ncrunchproject index b2eed192e..b36cf9e27 100644 --- a/NzbDrone.Core/NzbDrone.Core.ncrunchproject +++ b/NzbDrone.Core/NzbDrone.Core.ncrunchproject @@ -13,7 +13,7 @@ true true 5000 - Debug + RELEASE x86 x86 diff --git a/NzbDrone.Core/ThingiProvider/IProvider.cs b/NzbDrone.Core/ThingiProvider/IProvider.cs index c3308316e..4947c3d8b 100644 --- a/NzbDrone.Core/ThingiProvider/IProvider.cs +++ b/NzbDrone.Core/ThingiProvider/IProvider.cs @@ -1,33 +1,9 @@  using System; using System.Collections.Generic; -using FluentValidation.Results; -using NzbDrone.Core.Datastore; -using NzbDrone.Core.Messaging.Events; namespace NzbDrone.Core.ThingiProvider { - public interface IProviderRepository : IBasicRepository where TProvider : ModelBase, new() - { - TProvider GetByName(string name); - } - - - public class ProviderRepository : BasicRepository, IProviderRepository - where TProviderDefinition : ModelBase, - new() - { - protected ProviderRepository(IDatabase database, IEventAggregator eventAggregator) - : base(database, eventAggregator) - { - } - - public TProviderDefinition GetByName(string name) - { - throw new NotImplementedException(); - } - } - public interface IProvider { Type ConfigContract { get; } @@ -35,45 +11,4 @@ namespace NzbDrone.Core.ThingiProvider IEnumerable DefaultDefinitions { get; } ProviderDefinition Definition { get; set; } } - - public abstract class ProviderDefinition : ModelBase - { - private IProviderConfig _settings; - public string Name { get; set; } - public string Implementation { get; set; } - public bool Enable { get; set; } - - public string ConfigContract { get; set; } - - public IProviderConfig Settings - { - get - { - return _settings; - } - set - { - _settings = value; - if (value != null) - { - ConfigContract = value.GetType().Name; - } - } - } - } - - public interface IProviderConfig - { - ValidationResult Validate(); - } - - public class NullConfig : IProviderConfig - { - public static readonly NullConfig Instance = new NullConfig(); - - public ValidationResult Validate() - { - return new ValidationResult(); - } - } } \ No newline at end of file diff --git a/NzbDrone.Core/ThingiProvider/IProviderConfig.cs b/NzbDrone.Core/ThingiProvider/IProviderConfig.cs new file mode 100644 index 000000000..46501fb34 --- /dev/null +++ b/NzbDrone.Core/ThingiProvider/IProviderConfig.cs @@ -0,0 +1,9 @@ +using FluentValidation.Results; + +namespace NzbDrone.Core.ThingiProvider +{ + public interface IProviderConfig + { + ValidationResult Validate(); + } +} \ No newline at end of file diff --git a/NzbDrone.Core/ThingiProvider/IProviderFactory.cs b/NzbDrone.Core/ThingiProvider/IProviderFactory.cs new file mode 100644 index 000000000..54e8315a6 --- /dev/null +++ b/NzbDrone.Core/ThingiProvider/IProviderFactory.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; + +namespace NzbDrone.Core.ThingiProvider +{ + public interface IProviderFactory + where TProviderDefinition : ProviderDefinition, new() + where TProvider : IProvider + { + List All(); + List GetAvailableProviders(); + TProviderDefinition Get(int id); + TProviderDefinition Create(TProviderDefinition indexer); + void Update(TProviderDefinition indexer); + void Delete(int id); + List Templates(); + } +} \ No newline at end of file diff --git a/NzbDrone.Core/ThingiProvider/IProviderRepository.cs b/NzbDrone.Core/ThingiProvider/IProviderRepository.cs new file mode 100644 index 000000000..13043b64d --- /dev/null +++ b/NzbDrone.Core/ThingiProvider/IProviderRepository.cs @@ -0,0 +1,8 @@ +using NzbDrone.Core.Datastore; + +namespace NzbDrone.Core.ThingiProvider +{ + public interface IProviderRepository : IBasicRepository where TProvider : ModelBase, new() + { + } +} \ No newline at end of file diff --git a/NzbDrone.Core/ThingiProvider/NullConfig.cs b/NzbDrone.Core/ThingiProvider/NullConfig.cs new file mode 100644 index 000000000..6eea2e66c --- /dev/null +++ b/NzbDrone.Core/ThingiProvider/NullConfig.cs @@ -0,0 +1,14 @@ +using FluentValidation.Results; + +namespace NzbDrone.Core.ThingiProvider +{ + public class NullConfig : IProviderConfig + { + public static readonly NullConfig Instance = new NullConfig(); + + public ValidationResult Validate() + { + return new ValidationResult(); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core/ThingiProvider/ProviderDefinition.cs b/NzbDrone.Core/ThingiProvider/ProviderDefinition.cs new file mode 100644 index 000000000..ef21d3206 --- /dev/null +++ b/NzbDrone.Core/ThingiProvider/ProviderDefinition.cs @@ -0,0 +1,30 @@ +using NzbDrone.Core.Datastore; + +namespace NzbDrone.Core.ThingiProvider +{ + public abstract class ProviderDefinition : ModelBase + { + private IProviderConfig _settings; + public string Name { get; set; } + public string Implementation { get; set; } + public bool Enable { get; set; } + + public string ConfigContract { get; set; } + + public IProviderConfig Settings + { + get + { + return _settings; + } + set + { + _settings = value; + if (value != null) + { + ConfigContract = value.GetType().Name; + } + } + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core/ThingiProvider/ProviderService.cs b/NzbDrone.Core/ThingiProvider/ProviderFactory.cs similarity index 86% rename from NzbDrone.Core/ThingiProvider/ProviderService.cs rename to NzbDrone.Core/ThingiProvider/ProviderFactory.cs index 4765de4bc..bbd909bb3 100644 --- a/NzbDrone.Core/ThingiProvider/ProviderService.cs +++ b/NzbDrone.Core/ThingiProvider/ProviderFactory.cs @@ -2,25 +2,11 @@ using System.Collections.Generic; using System.Linq; using NLog; -using NzbDrone.Common.Reflection; 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); - TProviderDefinition Create(TProviderDefinition indexer); - void Update(TProviderDefinition indexer); - void Delete(int id); - List Templates(); - } - public abstract class ProviderFactory : IProviderFactory, IHandle where TProviderDefinition : ProviderDefinition, new() where TProvider : IProvider diff --git a/NzbDrone.Core/ThingiProvider/ProviderRepository.cs b/NzbDrone.Core/ThingiProvider/ProviderRepository.cs new file mode 100644 index 000000000..cceaaefcb --- /dev/null +++ b/NzbDrone.Core/ThingiProvider/ProviderRepository.cs @@ -0,0 +1,16 @@ +using System; +using NzbDrone.Core.Datastore; +using NzbDrone.Core.Messaging.Events; + +namespace NzbDrone.Core.ThingiProvider +{ + public class ProviderRepository : BasicRepository, IProviderRepository + where TProviderDefinition : ModelBase, + new() + { + protected ProviderRepository(IDatabase database, IEventAggregator eventAggregator) + : base(database, eventAggregator) + { + } + } +} \ No newline at end of file From 1b234f40df010ea86e0f49f1d084395e6684dc6a Mon Sep 17 00:00:00 2001 From: kayone Date: Tue, 1 Oct 2013 10:27:22 -0700 Subject: [PATCH 14/16] fixed indexer endpoint. --- NzbDrone.Api/Indexers/IndexerModule.cs | 2 +- NzbDrone.Api/ProviderModuleBase.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/NzbDrone.Api/Indexers/IndexerModule.cs b/NzbDrone.Api/Indexers/IndexerModule.cs index 52b38fe7d..33c56a108 100644 --- a/NzbDrone.Api/Indexers/IndexerModule.cs +++ b/NzbDrone.Api/Indexers/IndexerModule.cs @@ -5,7 +5,7 @@ namespace NzbDrone.Api.Indexers public class IndexerModule : ProviderModuleBase { public IndexerModule(IndexerFactory indexerFactory) - : base(indexerFactory) + : base(indexerFactory, "indexer") { } } diff --git a/NzbDrone.Api/ProviderModuleBase.cs b/NzbDrone.Api/ProviderModuleBase.cs index a56891a68..f379f598a 100644 --- a/NzbDrone.Api/ProviderModuleBase.cs +++ b/NzbDrone.Api/ProviderModuleBase.cs @@ -19,7 +19,8 @@ namespace NzbDrone.Api { private readonly IProviderFactory _providerFactory; - protected ProviderModuleBase(IProviderFactory providerFactory) + protected ProviderModuleBase(IProviderFactory providerFactory, string resource) + : base(resource) { _providerFactory = providerFactory; Get["templates"] = x => GetTemplates(); From 27bd59268d21ed38285c2a14bea981431bbd242c Mon Sep 17 00:00:00 2001 From: kayone Date: Tue, 1 Oct 2013 12:32:08 -0700 Subject: [PATCH 15/16] nullconfig indexers are enabled by default. --- NzbDrone.Core.Test/NzbDrone.Core.Test.csproj | 1 + .../ThingiProviderTests/NullConfigFixture.cs | 17 +++++++++++++++++ NzbDrone.Core/Indexers/IndexerBase.cs | 10 ++++++---- .../IndexerIntegrationFixture.cs | 5 ++++- .../ReleaseIntegrationTest.cs | 8 ++++++-- 5 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 NzbDrone.Core.Test/ThingiProviderTests/NullConfigFixture.cs diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index 39bda7be4..8a79c19af 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -182,6 +182,7 @@ + diff --git a/NzbDrone.Core.Test/ThingiProviderTests/NullConfigFixture.cs b/NzbDrone.Core.Test/ThingiProviderTests/NullConfigFixture.cs new file mode 100644 index 000000000..0f47d9a91 --- /dev/null +++ b/NzbDrone.Core.Test/ThingiProviderTests/NullConfigFixture.cs @@ -0,0 +1,17 @@ +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Core.ThingiProvider; + +namespace NzbDrone.Core.Test.ThingiProviderTests +{ + [TestFixture] + public class NullConfigFixture : CoreTest + { + [Test] + public void should_be_valid() + { + Subject.Validate().IsValid.Should().BeTrue(); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core/Indexers/IndexerBase.cs b/NzbDrone.Core/Indexers/IndexerBase.cs index ddedc098c..41942d35b 100644 --- a/NzbDrone.Core/Indexers/IndexerBase.cs +++ b/NzbDrone.Core/Indexers/IndexerBase.cs @@ -4,7 +4,7 @@ using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Indexers { - public abstract class IndexerBase : IIndexer + public abstract class IndexerBase : IIndexer where TSettings : IProviderConfig, new() { public Type ConfigContract { @@ -18,12 +18,14 @@ namespace NzbDrone.Core.Indexers { get { + var config = (IProviderConfig)new TSettings(); + yield return new IndexerDefinition { - Name = this.GetType().Name, - Enable = false, + Name = GetType().Name, + Enable = config.Validate().IsValid, Implementation = GetType().Name, - Settings = NullConfig.Instance + Settings = config }; } } diff --git a/NzbDrone.Integration.Test/IndexerIntegrationFixture.cs b/NzbDrone.Integration.Test/IndexerIntegrationFixture.cs index 33fb6e0ab..96003762b 100644 --- a/NzbDrone.Integration.Test/IndexerIntegrationFixture.cs +++ b/NzbDrone.Integration.Test/IndexerIntegrationFixture.cs @@ -1,5 +1,7 @@ -using FluentAssertions; +using System.Linq; +using FluentAssertions; using NUnit.Framework; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Integration.Test { @@ -13,6 +15,7 @@ namespace NzbDrone.Integration.Test indexers.Should().NotBeEmpty(); indexers.Should().NotContain(c => string.IsNullOrWhiteSpace(c.Name)); + indexers.Where(c => c.ConfigContract == typeof(NullConfig).Name).Should().OnlyContain(c => c.Enable); } } } \ No newline at end of file diff --git a/NzbDrone.Integration.Test/ReleaseIntegrationTest.cs b/NzbDrone.Integration.Test/ReleaseIntegrationTest.cs index b9a86674e..eb76f1255 100644 --- a/NzbDrone.Integration.Test/ReleaseIntegrationTest.cs +++ b/NzbDrone.Integration.Test/ReleaseIntegrationTest.cs @@ -1,4 +1,5 @@ -using FluentAssertions; +using System.Threading; +using FluentAssertions; using NUnit.Framework; using NzbDrone.Api.Indexers; @@ -10,10 +11,13 @@ namespace NzbDrone.Integration.Test [Test] public void should_only_have_unknown_series_releases() { + var releases = Releases.All(); + var indexers = Indexers.All(); + releases.Should().OnlyContain(c => c.Rejections.Contains("Unknown Series")); - releases.Should().OnlyContain(c=>BeValidRelease(c)); + releases.Should().OnlyContain(c => BeValidRelease(c)); } From c7660891881a09ae029ed0e71b35b5f617c2fd0f Mon Sep 17 00:00:00 2001 From: kayone Date: Tue, 1 Oct 2013 12:33:48 -0700 Subject: [PATCH 16/16] hide torrent indexers. --- NzbDrone.Core/Indexers/IndexerFactory.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NzbDrone.Core/Indexers/IndexerFactory.cs b/NzbDrone.Core/Indexers/IndexerFactory.cs index a8796fc28..b89f0d539 100644 --- a/NzbDrone.Core/Indexers/IndexerFactory.cs +++ b/NzbDrone.Core/Indexers/IndexerFactory.cs @@ -24,7 +24,8 @@ namespace NzbDrone.Core.Indexers protected override void InitializeProviders() { - var definitions = _providers.SelectMany(indexer => indexer.DefaultDefinitions); + var definitions = _providers.Where(c => c.Protocol == DownloadProtocol.Usenet) + .SelectMany(indexer => indexer.DefaultDefinitions); var currentProviders = All();