diff --git a/src/NzbDrone.Api/ClientSchema/SchemaBuilder.cs b/src/NzbDrone.Api/ClientSchema/SchemaBuilder.cs index 86ca9cc1a..966492a44 100644 --- a/src/NzbDrone.Api/ClientSchema/SchemaBuilder.cs +++ b/src/NzbDrone.Api/ClientSchema/SchemaBuilder.cs @@ -28,15 +28,15 @@ namespace NzbDrone.Api.ClientSchema { var field = new Field - { - Name = propertyInfo.Name, - Label = fieldAttribute.Label, - HelpText = fieldAttribute.HelpText, - HelpLink = fieldAttribute.HelpLink, - Order = fieldAttribute.Order, - Advanced = fieldAttribute.Advanced, - Type = fieldAttribute.Type.ToString().ToLowerInvariant() - }; + { + Name = propertyInfo.Name, + Label = fieldAttribute.Label, + HelpText = fieldAttribute.HelpText, + HelpLink = fieldAttribute.HelpLink, + Order = fieldAttribute.Order, + Advanced = fieldAttribute.Advanced, + Type = fieldAttribute.Type.ToString().ToLowerInvariant() + }; var value = propertyInfo.GetValue(model, null); if (value != null) @@ -101,20 +101,37 @@ namespace NzbDrone.Api.ClientSchema propertyInfo.SetValue(target, value, null); } - else if (propertyInfo.PropertyType == typeof (IEnumerable)) + else if (propertyInfo.PropertyType == typeof(IEnumerable)) { IEnumerable value; - if (field.Value.GetType() == typeof (JArray)) + if (field.Value.GetType() == typeof(JArray)) { - value = ((JArray) field.Value).Select(s => s.Value()); + value = ((JArray)field.Value).Select(s => s.Value()); } else { - value = field.Value.ToString().Split(new []{','}, StringSplitOptions.RemoveEmptyEntries).Select(s => Convert.ToInt32(s)); + value = field.Value.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => Convert.ToInt32(s)); } - + + propertyInfo.SetValue(target, value, null); + } + + else if (propertyInfo.PropertyType == typeof(IEnumerable)) + { + IEnumerable value; + + if (field.Value.GetType() == typeof(JArray)) + { + value = ((JArray)field.Value).Select(s => s.Value()); + } + + else + { + value = field.Value.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + } + propertyInfo.SetValue(target, value, null); } @@ -142,4 +159,4 @@ namespace NzbDrone.Api.ClientSchema return options.OrderBy(o => o.Value).ToList(); } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core.Test/Datastore/Migration/086_pushbullet_device_idsFixture.cs b/src/NzbDrone.Core.Test/Datastore/Migration/086_pushbullet_device_idsFixture.cs index a97eb3e2b..846889c6f 100644 --- a/src/NzbDrone.Core.Test/Datastore/Migration/086_pushbullet_device_idsFixture.cs +++ b/src/NzbDrone.Core.Test/Datastore/Migration/086_pushbullet_device_idsFixture.cs @@ -84,7 +84,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration var items = Mocker.Resolve().All(); items.Should().HaveCount(1); - items.First().Settings.As().DeviceIds.Should().Be(deviceId); + items.First().Settings.As().DeviceIds.First().Should().Be(deviceId); } } } diff --git a/src/NzbDrone.Core.Test/Datastore/Migration/087_pushbullet_devices_channels.cs b/src/NzbDrone.Core.Test/Datastore/Migration/087_pushbullet_devices_channels.cs new file mode 100644 index 000000000..11d7bb227 --- /dev/null +++ b/src/NzbDrone.Core.Test/Datastore/Migration/087_pushbullet_devices_channels.cs @@ -0,0 +1,44 @@ +using System.Linq; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Common.Serializer; +using NzbDrone.Core.Notifications; +using NzbDrone.Core.Notifications.PushBullet; +using NzbDrone.Core.Notifications.Pushover; +using NzbDrone.Core.Test.Framework; +namespace NzbDrone.Core.Test.Datastore.Migration +{ + [TestFixture] + public class pushbullet_devices_channels : MigrationTest + { + [Test] + public void should_convert_comma_separted_string_to_list() + { + var deviceId = "device_id"; + + WithTestDb(c => + { + c.Insert.IntoTable("Notifications").Row(new + { + OnGrab = false, + OnDownload = false, + OnUpgrade = false, + Name = "PushBullet", + Implementation = "PushBullet", + Settings = new + { + ApiKey = "my_api_key", + ChannelTags = "channel1,channel2" + }.ToJson(), + ConfigContract = "PushBulletSettings" + }); + }); + + var items = Mocker.Resolve().All(); + + items.Should().HaveCount(1); + var settings = items.First().Settings.As(); + settings.ChannelTags.Should().HaveCount(2); + } + } +} diff --git a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index fe956a2c2..59051d732 100644 --- a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -120,6 +120,7 @@ + diff --git a/src/NzbDrone.Core/Datastore/Migration/087_pushbullet_devices_channels_list.cs b/src/NzbDrone.Core/Datastore/Migration/087_pushbullet_devices_channels_list.cs new file mode 100644 index 000000000..7b251f563 --- /dev/null +++ b/src/NzbDrone.Core/Datastore/Migration/087_pushbullet_devices_channels_list.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Data; +using FluentMigrator; +using NzbDrone.Common.Extensions; +using NzbDrone.Common.Serializer; +using NzbDrone.Core.Datastore.Migration.Framework; + +namespace NzbDrone.Core.Datastore.Migration +{ + [Migration(87)] + public class pushbullet_devices_channels_list : NzbDroneMigrationBase + { + protected override void MainDbUpgrade() + { + Execute.WithConnection(UpdateTransmissionSettings); + } + + private void UpdateTransmissionSettings(IDbConnection conn, IDbTransaction tran) + { + using (var cmd = conn.CreateCommand()) + { + cmd.Transaction = tran; + cmd.CommandText = "SELECT Id, Settings FROM Notifications WHERE Implementation = 'PushBullet'"; + + using (var reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + var id = reader.GetInt32(0); + var settingsJson = reader.GetString(1); + var settings = Json.Deserialize>(settingsJson); + + if (settings.ContainsKey("deviceIds")) + { + var deviceIdsString = settings.GetValueOrDefault("deviceIds", "") as string; + var deviceIds = deviceIdsString.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries); + + settings["deviceIds"] = deviceIds; + } + + if (settings.ContainsKey("channelTags")) + { + var channelTagsString = settings.GetValueOrDefault("channelTags", "") as string; + var channelTags = channelTagsString.Split(new[] {","}, StringSplitOptions.RemoveEmptyEntries); + + settings["channelTags"] = channelTags; + } + + using (var updateCmd = conn.CreateCommand()) + { + updateCmd.Transaction = tran; + updateCmd.CommandText = "UPDATE Notifications SET Settings = ? WHERE Id = ?"; + updateCmd.AddParameter(settings.ToJson()); + updateCmd.AddParameter(id); + + updateCmd.ExecuteNonQuery(); + } + } + } + } + } + } +} diff --git a/src/NzbDrone.Core/Notifications/PushBullet/PushBulletProxy.cs b/src/NzbDrone.Core/Notifications/PushBullet/PushBulletProxy.cs index 993651c68..1bb07efd9 100644 --- a/src/NzbDrone.Core/Notifications/PushBullet/PushBulletProxy.cs +++ b/src/NzbDrone.Core/Notifications/PushBullet/PushBulletProxy.cs @@ -1,10 +1,8 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Net; using FluentValidation.Results; using NLog; -using NzbDrone.Common.Extensions; using RestSharp; using NzbDrone.Core.Rest; @@ -28,13 +26,11 @@ namespace NzbDrone.Core.Notifications.PushBullet public void SendNotification(string title, string message, PushBulletSettings settings) { - var channelTags = GetIds(settings.ChannelTags); - var deviceIds = GetIds(settings.DeviceIds); var error = false; - if (channelTags.Any()) + if (settings.ChannelTags.Any()) { - foreach (var channelTag in channelTags) + foreach (var channelTag in settings.ChannelTags) { var request = BuildChannelRequest(channelTag); @@ -51,9 +47,9 @@ namespace NzbDrone.Core.Notifications.PushBullet } else { - if (deviceIds.Any()) + if (settings.DeviceIds.Any()) { - foreach (var deviceId in deviceIds) + foreach (var deviceId in settings.DeviceIds) { var request = BuildDeviceRequest(deviceId); @@ -169,12 +165,5 @@ namespace NzbDrone.Core.Notifications.PushBullet throw new PushBulletException("Unable to send text message: {0}", ex, ex.Message); } } - - private List GetIds(string input) - { - if (input.IsNullOrWhiteSpace()) return new List(); - - return input.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).ToList(); - } } } diff --git a/src/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs b/src/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs index 83dcfd7c4..9872a922a 100644 --- a/src/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs +++ b/src/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs @@ -1,4 +1,4 @@ -using System; +using System.Collections.Generic; using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.ThingiProvider; @@ -18,14 +18,20 @@ namespace NzbDrone.Core.Notifications.PushBullet { private static readonly PushBulletSettingsValidator Validator = new PushBulletSettingsValidator(); + public PushBulletSettings() + { + DeviceIds = new string[]{}; + ChannelTags = new string[]{}; + } + [FieldDefinition(0, Label = "API Key", HelpLink = "https://www.pushbullet.com/")] - public String ApiKey { get; set; } + public string ApiKey { get; set; } [FieldDefinition(1, Label = "Device IDs", HelpText = "List of device IDs, use device_iden in the device's URL on pushbullet.com (leave blank to send to all devices)", Type = FieldType.Tag)] - public String DeviceIds { get; set; } + public IEnumerable DeviceIds { get; set; } [FieldDefinition(2, Label = "Channel Tags", HelpText = "List of Channel Tags to send notifications to", Type = FieldType.Tag)] - public String ChannelTags { get; set; } + public IEnumerable ChannelTags { get; set; } public NzbDroneValidationResult Validate() { diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index d2aafd02f..7224e19c0 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -262,6 +262,7 @@ +