You've already forked Sonarr
							
							
				mirror of
				https://github.com/Sonarr/Sonarr.git
				synced 2025-10-31 00:07:55 +02:00 
			
		
		
		
	Notifications wired up server sided
This commit is contained in:
		| @@ -4,6 +4,8 @@ using System.Linq; | ||||
| using NzbDrone.Api.Extensions; | ||||
| using NzbDrone.Common.Composition; | ||||
| using NzbDrone.Common.Messaging; | ||||
| using NzbDrone.Core.Download; | ||||
| using NzbDrone.Core.Parser.Model; | ||||
|  | ||||
| namespace NzbDrone.Api.Commands | ||||
| { | ||||
|   | ||||
| @@ -5,7 +5,7 @@ using Moq; | ||||
| using NUnit.Framework; | ||||
| using NzbDrone.Common; | ||||
| using NzbDrone.Core.Model.Xbmc; | ||||
| using NzbDrone.Core.Providers.Xbmc; | ||||
| using NzbDrone.Core.Notifications.Xbmc; | ||||
| using NzbDrone.Core.Test.Framework; | ||||
| using NzbDrone.Test.Common.AutoMoq; | ||||
|  | ||||
|   | ||||
| @@ -4,8 +4,9 @@ using FizzWare.NBuilder; | ||||
| using FluentAssertions; | ||||
| using Moq; | ||||
| using NUnit.Framework; | ||||
| using NzbDrone.Core.ExternalNotification; | ||||
| using NzbDrone.Core.Model; | ||||
| using NzbDrone.Core.Notifications; | ||||
| using NzbDrone.Core.Notifications.Growl; | ||||
| using NzbDrone.Core.Providers; | ||||
|  | ||||
| using NzbDrone.Core.Test.Framework; | ||||
|   | ||||
| @@ -1,6 +1,4 @@ | ||||
|  | ||||
|  | ||||
| using System; | ||||
| using System; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Net; | ||||
| @@ -10,14 +8,8 @@ using FluentAssertions; | ||||
| using Moq; | ||||
| using NUnit.Framework; | ||||
| using NzbDrone.Common; | ||||
| using NzbDrone.Core.Configuration; | ||||
| using NzbDrone.Core.ExternalNotification; | ||||
| using NzbDrone.Core.Model.Xbmc; | ||||
| using NzbDrone.Core.Providers; | ||||
| using NzbDrone.Core.Providers.Xbmc; | ||||
|  | ||||
| using NzbDrone.Core.Notifications.Plex; | ||||
| using NzbDrone.Core.Test.Framework; | ||||
| using NzbDrone.Test.Common.AutoMoq; | ||||
|  | ||||
| namespace NzbDrone.Core.Test.ProviderTests | ||||
| { | ||||
| @@ -25,32 +17,27 @@ namespace NzbDrone.Core.Test.ProviderTests | ||||
|      | ||||
|     public class PlexProviderTest : CoreTest | ||||
|     { | ||||
|         private void WithSingleClient() | ||||
|         { | ||||
|             Mocker.GetMock<IConfigService>().SetupGet(s => s.PlexClientHosts) | ||||
|                     .Returns("localhost:3000"); | ||||
|         } | ||||
|  | ||||
|         private void WithMultipleClients() | ||||
|         { | ||||
|             Mocker.GetMock<IConfigService>().SetupGet(s => s.PlexClientHosts) | ||||
|                     .Returns("localhost:3000, 192.168.0.10:3000"); | ||||
|         } | ||||
|         private PlexClientSettings _clientSettings; | ||||
|  | ||||
|         public void WithClientCredentials() | ||||
|         { | ||||
|             Mocker.GetMock<IConfigService>().SetupGet(s => s.PlexUsername) | ||||
|                     .Returns("plex"); | ||||
|             _clientSettings.Username = "plex"; | ||||
|             _clientSettings.Password = "plex"; | ||||
|         } | ||||
|  | ||||
|             Mocker.GetMock<IConfigService>().SetupGet(s => s.PlexPassword) | ||||
|                     .Returns("plex"); | ||||
|         [SetUp] | ||||
|         public void Setup() | ||||
|         { | ||||
|             _clientSettings = new PlexClientSettings | ||||
|                                   { | ||||
|                                       Host = "localhost", | ||||
|                                       Port = 3000 | ||||
|                                   }; | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void GetSectionKeys_should_return_single_section_key_when_only_one_show_section() | ||||
|         { | ||||
|              | ||||
|              | ||||
|         {            | ||||
|             var response = "<MediaContainer size=\"1\" mediaTagPrefix=\"/system/bundle/media/flags/\" mediaTagVersion=\"1329809559\" title1=\"Plex Library\" identifier=\"com.plexapp.plugins.library\"><Directory refreshing=\"0\" key=\"5\" type=\"show\" title=\"TV Shows\" art=\"/:/resources/show-fanart.jpg\" agent=\"com.plexapp.agents.thetvdb\" scanner=\"Plex Series Scanner\" language=\"en\" updatedAt=\"1329810350\"><Location path=\"C:/Test/TV\"/></Directory></MediaContainer>"; | ||||
|             Stream stream = new MemoryStream(ASCIIEncoding.Default.GetBytes(response)); | ||||
|  | ||||
| @@ -123,10 +110,8 @@ namespace NzbDrone.Core.Test.ProviderTests | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void Notify_should_send_notification_for_single_client_when_only_one_is_configured() | ||||
|         public void Notify_should_send_notification() | ||||
|         { | ||||
|              | ||||
|             WithSingleClient(); | ||||
|  | ||||
|             const string header = "Test Header"; | ||||
|             const string message = "Test Message"; | ||||
| @@ -138,37 +123,15 @@ namespace NzbDrone.Core.Test.ProviderTests | ||||
|                     .Returns("ok"); | ||||
|  | ||||
|              | ||||
|             Mocker.Resolve<PlexProvider>().Notify(header, message); | ||||
|             Mocker.Resolve<PlexProvider>().Notify(_clientSettings, header, message); | ||||
|  | ||||
|              | ||||
|             fakeHttp.Verify(v => v.DownloadString(expectedUrl), Times.Once()); | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void Notify_should_send_notifcation_to_all_configured_clients() | ||||
|         { | ||||
|              | ||||
|             WithMultipleClients(); | ||||
|  | ||||
|             const string header = "Test Header"; | ||||
|             const string message = "Test Message"; | ||||
|  | ||||
|             var fakeHttp = Mocker.GetMock<IHttpProvider>(); | ||||
|             fakeHttp.Setup(s => s.DownloadString(It.IsAny<string>())) | ||||
|                     .Returns("ok"); | ||||
|  | ||||
|              | ||||
|             Mocker.Resolve<PlexProvider>().Notify(header, message); | ||||
|  | ||||
|              | ||||
|             fakeHttp.Verify(v => v.DownloadString(It.IsAny<string>()), Times.Exactly(2)); | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void Notify_should_send_notification_with_credentials_when_configured() | ||||
|         { | ||||
|              | ||||
|             WithSingleClient(); | ||||
|             WithClientCredentials(); | ||||
|  | ||||
|             const string header = "Test Header"; | ||||
| @@ -181,31 +144,10 @@ namespace NzbDrone.Core.Test.ProviderTests | ||||
|                     .Returns("ok"); | ||||
|  | ||||
|              | ||||
|             Mocker.Resolve<PlexProvider>().Notify(header, message); | ||||
|             Mocker.Resolve<PlexProvider>().Notify(_clientSettings, header, message); | ||||
|  | ||||
|              | ||||
|             fakeHttp.Verify(v => v.DownloadString(expectedUrl, "plex", "plex"), Times.Once()); | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void Notify_should_send_notification_with_credentials_when_configured_for_all_clients() | ||||
|         { | ||||
|              | ||||
|             WithMultipleClients(); | ||||
|             WithClientCredentials(); | ||||
|  | ||||
|             const string header = "Test Header"; | ||||
|             const string message = "Test Message"; | ||||
|  | ||||
|             var fakeHttp = Mocker.GetMock<IHttpProvider>(); | ||||
|             fakeHttp.Setup(s => s.DownloadString(It.IsAny<string>(), "plex", "plex")) | ||||
|                     .Returns("ok"); | ||||
|  | ||||
|              | ||||
|             Mocker.Resolve<PlexProvider>().Notify(header, message); | ||||
|  | ||||
|              | ||||
|             fakeHttp.Verify(v => v.DownloadString(It.IsAny<string>(), "plex", "plex"), Times.Exactly(2)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -5,6 +5,7 @@ using FluentAssertions; | ||||
| using Moq; | ||||
| using NUnit.Framework; | ||||
| using NzbDrone.Core.Model; | ||||
| using NzbDrone.Core.Notifications.Prowl; | ||||
| using NzbDrone.Core.Providers; | ||||
|  | ||||
| using NzbDrone.Core.Test.Framework; | ||||
|   | ||||
| @@ -8,11 +8,10 @@ using Moq; | ||||
| using NUnit.Framework; | ||||
| using NzbDrone.Common; | ||||
| using NzbDrone.Core.Configuration; | ||||
| using NzbDrone.Core.Notifications.Xbmc; | ||||
| using NzbDrone.Core.Tv; | ||||
| using NzbDrone.Core.Model.Xbmc; | ||||
| using NzbDrone.Core.Providers; | ||||
| using NzbDrone.Core.Providers.Xbmc; | ||||
|  | ||||
| using NzbDrone.Core.Test.Framework; | ||||
| using NzbDrone.Test.Common.AutoMoq; | ||||
|  | ||||
| @@ -22,6 +21,7 @@ namespace NzbDrone.Core.Test.ProviderTests | ||||
|      | ||||
|     public class XbmcProviderTest : CoreTest | ||||
|     { | ||||
|         private XbmcSettings _settings; | ||||
|         private string EdenActivePlayers; | ||||
|  | ||||
|         private void WithNoActivePlayers() | ||||
| @@ -49,6 +49,19 @@ namespace NzbDrone.Core.Test.ProviderTests | ||||
|             EdenActivePlayers = "{\"id\":10,\"jsonrpc\":\"2.0\",\"result\":[{\"playerid\":1,\"type\":\"audio\"},{\"playerid\":2,\"type\":\"picture\"},{\"playerid\":3,\"type\":\"video\"}]}"; | ||||
|         } | ||||
|  | ||||
|         [SetUp] | ||||
|         public void Setup() | ||||
|         { | ||||
|             _settings = new XbmcSettings | ||||
|                             { | ||||
|                                 Host = "localhost", | ||||
|                                 Port = 8080, | ||||
|                                 AlwaysUpdate = false, | ||||
|                                 CleanLibrary = false, | ||||
|                                 UpdateLibrary = true | ||||
|                             }; | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void JsonError_true() | ||||
|         { | ||||
| @@ -290,21 +303,13 @@ namespace NzbDrone.Core.Test.ProviderTests | ||||
|         [Test] | ||||
|         public void Notify_true() | ||||
|         { | ||||
|              | ||||
|              | ||||
|  | ||||
|             var header = "NzbDrone Test"; | ||||
|             var message = "Test Message!"; | ||||
|  | ||||
|             var fakeConfig = Mocker.GetMock<IConfigService>(); | ||||
|             fakeConfig.SetupGet(s => s.XbmcHosts).Returns("localhost:8080"); | ||||
|  | ||||
|             //var fakeUdpProvider = Mocker.GetMock<EventClient>(); | ||||
|             var fakeEventClient = Mocker.GetMock<EventClientProvider>(); | ||||
|             fakeEventClient.Setup(s => s.SendNotification(header, message, IconType.Jpeg, "NzbDrone.jpg", "localhost")).Returns(true); | ||||
|  | ||||
|              | ||||
|             Mocker.Resolve<XbmcProvider>().Notify(header, message); | ||||
|             Mocker.Resolve<XbmcProvider>().Notify(_settings, header, message); | ||||
|  | ||||
|              | ||||
|             Mocker.VerifyAllMocks(); | ||||
| @@ -437,19 +442,10 @@ namespace NzbDrone.Core.Test.ProviderTests | ||||
|         [Test] | ||||
|         public void Clean() | ||||
|         { | ||||
|              | ||||
|              | ||||
|  | ||||
|             var fakeConfig = Mocker.GetMock<IConfigService>(); | ||||
|             fakeConfig.SetupGet(s => s.XbmcHosts).Returns("localhost:8080"); | ||||
|  | ||||
|             var fakeEventClient = Mocker.GetMock<EventClientProvider>(); | ||||
|             fakeEventClient.Setup(s => s.SendAction("localhost", ActionType.ExecBuiltin, "ExecBuiltIn(CleanLibrary(video))")).Returns(true); | ||||
|  | ||||
|              | ||||
|             Mocker.Resolve<XbmcProvider>().Clean(); | ||||
|  | ||||
|              | ||||
|             Mocker.Resolve<XbmcProvider>().Clean(_settings); | ||||
|             Mocker.VerifyAllMocks(); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -126,94 +126,12 @@ namespace NzbDrone.Core.Configuration | ||||
|             set { SetValue("DefaultQualityProfile", value); } | ||||
|         } | ||||
|  | ||||
|         public Boolean XbmcUpdateLibrary | ||||
|         { | ||||
|             get { return GetValueBoolean("XbmcUpdateLibrary"); } | ||||
|  | ||||
|             set { SetValue("XbmcUpdateLibrary", value); } | ||||
|         } | ||||
|  | ||||
|         public Boolean XbmcCleanLibrary | ||||
|         { | ||||
|             get { return GetValueBoolean("XbmcCleanLibrary"); } | ||||
|  | ||||
|             set { SetValue("XbmcCleanLibrary", value); } | ||||
|         } | ||||
|  | ||||
|         public Boolean XbmcUpdateWhenPlaying | ||||
|         { | ||||
|             get { return GetValueBoolean("XbmcUpdateWhenPlaying"); } | ||||
|  | ||||
|             set { SetValue("XbmcUpdateWhenPlaying", value); } | ||||
|         } | ||||
|  | ||||
|         public string XbmcHosts | ||||
|         { | ||||
|             get { return GetValue("XbmcHosts", "localhost:8080"); } | ||||
|             set { SetValue("XbmcHosts", value); } | ||||
|         } | ||||
|  | ||||
|         public string XbmcUsername | ||||
|         { | ||||
|             get { return GetValue("XbmcUsername", "xbmc"); } | ||||
|             set { SetValue("XbmcUsername", value); } | ||||
|         } | ||||
|  | ||||
|         public string XbmcPassword | ||||
|         { | ||||
|             get { return GetValue("XbmcPassword", String.Empty); } | ||||
|             set { SetValue("XbmcPassword", value); } | ||||
|         } | ||||
|  | ||||
|         public string UpdateUrl | ||||
|         { | ||||
|             get { return GetValue("UpdateUrl", "http://update.nzbdrone.com/vnext/"); } | ||||
|             set { SetValue("UpdateUrl", value); } | ||||
|         } | ||||
|  | ||||
|         public string SmtpServer | ||||
|         { | ||||
|             get { return GetValue("SmtpServer", String.Empty); } | ||||
|             set { SetValue("SmtpServer", value); } | ||||
|         } | ||||
|  | ||||
|         public int SmtpPort | ||||
|         { | ||||
|             get { return GetValueInt("SmtpPort", 25); } | ||||
|             set { SetValue("SmtpPort", value); } | ||||
|         } | ||||
|  | ||||
|         public Boolean SmtpUseSsl | ||||
|         { | ||||
|             get { return GetValueBoolean("SmtpUseSsl"); } | ||||
|  | ||||
|             set { SetValue("SmtpUseSsl", value); } | ||||
|         } | ||||
|  | ||||
|         public string SmtpUsername | ||||
|         { | ||||
|             get { return GetValue("SmtpUsername", String.Empty); } | ||||
|             set { SetValue("SmtpUsername", value); } | ||||
|         } | ||||
|  | ||||
|         public string SmtpPassword | ||||
|         { | ||||
|             get { return GetValue("SmtpPassword", String.Empty); } | ||||
|             set { SetValue("SmtpPassword", value); } | ||||
|         } | ||||
|  | ||||
|         public string SmtpFromAddress | ||||
|         { | ||||
|             get { return GetValue("SmtpFromAddress", String.Empty); } | ||||
|             set { SetValue("SmtpFromAddress", value); } | ||||
|         } | ||||
|  | ||||
|         public string SmtpToAddresses | ||||
|         { | ||||
|             get { return GetValue("SmtpToAddresses", String.Empty); } | ||||
|             set { SetValue("SmtpToAddresses", value); } | ||||
|         } | ||||
|  | ||||
|         public string TwitterAccessToken | ||||
|         { | ||||
|             get { return GetValue("TwitterAccessToken", String.Empty); } | ||||
| @@ -226,30 +144,6 @@ namespace NzbDrone.Core.Configuration | ||||
|             set { SetValue("TwitterAccessTokenSecret", value); } | ||||
|         } | ||||
|  | ||||
|         public string GrowlHost | ||||
|         { | ||||
|             get { return GetValue("GrowlHost", "localhost:23053"); } | ||||
|             set { SetValue("GrowlHost", value); } | ||||
|         } | ||||
|  | ||||
|         public string GrowlPassword | ||||
|         { | ||||
|             get { return GetValue("GrowlPassword", String.Empty); } | ||||
|             set { SetValue("GrowlPassword", value); } | ||||
|         } | ||||
|  | ||||
|         public string ProwlApiKeys | ||||
|         { | ||||
|             get { return GetValue("ProwlApiKeys", String.Empty); } | ||||
|             set { SetValue("ProwlApiKeys", value); } | ||||
|         } | ||||
|  | ||||
|         public int ProwlPriority | ||||
|         { | ||||
|             get { return GetValueInt("ProwlPriority", 0); } | ||||
|             set { SetValue("ProwlPriority", value); } | ||||
|         } | ||||
|  | ||||
|         public bool EnableBacklogSearching | ||||
|         { | ||||
|             get { return GetValueBoolean("EnableBacklogSearching"); } | ||||
| @@ -291,37 +185,6 @@ namespace NzbDrone.Core.Configuration | ||||
|             get { return "http://services.nzbdrone.com"; } | ||||
|         } | ||||
|  | ||||
|         public Boolean PlexUpdateLibrary | ||||
|         { | ||||
|             get { return GetValueBoolean("PlexUpdateLibrary"); } | ||||
|  | ||||
|             set { SetValue("PlexUpdateLibrary", value); } | ||||
|         } | ||||
|  | ||||
|         public string PlexServerHost | ||||
|         { | ||||
|             get { return GetValue("PlexServerHost", "localhost:32400"); } | ||||
|             set { SetValue("PlexServerHost", value); } | ||||
|         } | ||||
|  | ||||
|         public string PlexClientHosts | ||||
|         { | ||||
|             get { return GetValue("PlexClientHosts", "localhost:3000"); } | ||||
|             set { SetValue("PlexClientHosts", value); } | ||||
|         } | ||||
|  | ||||
|         public string PlexUsername | ||||
|         { | ||||
|             get { return GetValue("PlexUsername"); } | ||||
|             set { SetValue("PlexUsername", value); } | ||||
|         } | ||||
|  | ||||
|         public string PlexPassword | ||||
|         { | ||||
|             get { return GetValue("PlexPassword"); } | ||||
|             set { SetValue("PlexPassword", value); } | ||||
|         } | ||||
|  | ||||
|         public Boolean MetadataUseBanners | ||||
|         { | ||||
|             get { return GetValueBoolean("MetadataUseBanners"); } | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using NzbDrone.Core.Download; | ||||
| using NzbDrone.Core.Model; | ||||
| using NzbDrone.Core.Download.Clients.Nzbget; | ||||
| using NzbDrone.Core.Download.Clients.Sabnzbd; | ||||
|  | ||||
| @@ -11,6 +10,7 @@ namespace NzbDrone.Core.Configuration | ||||
|     { | ||||
|         IEnumerable<Config> All(); | ||||
|         Dictionary<String, Object> AllWithDefaults(); | ||||
|         string UpdateUrl { get; set; } | ||||
|         String SabHost { get; set; } | ||||
|         int SabPort { get; set; } | ||||
|         String SabApiKey { get; set; } | ||||
| @@ -23,26 +23,8 @@ namespace NzbDrone.Core.Configuration | ||||
|         bool UseSeasonFolder { get; set; } | ||||
|         string SortingSeasonFolderFormat { get; set; } | ||||
|         int DefaultQualityProfile { get; set; } | ||||
|         Boolean XbmcUpdateLibrary { get; set; } | ||||
|         Boolean XbmcCleanLibrary { get; set; } | ||||
|         Boolean XbmcUpdateWhenPlaying { get; set; } | ||||
|         string XbmcHosts { get; set; } | ||||
|         string XbmcUsername { get; set; } | ||||
|         string XbmcPassword { get; set; } | ||||
|         string UpdateUrl { get; set; } | ||||
|         string SmtpServer { get; set; } | ||||
|         int SmtpPort { get; set; } | ||||
|         Boolean SmtpUseSsl { get; set; } | ||||
|         string SmtpUsername { get; set; } | ||||
|         string SmtpPassword { get; set; } | ||||
|         string SmtpFromAddress { get; set; } | ||||
|         string SmtpToAddresses { get; set; } | ||||
|         string TwitterAccessToken { get; set; } | ||||
|         string TwitterAccessTokenSecret { get; set; } | ||||
|         string GrowlHost { get; set; } | ||||
|         string GrowlPassword { get; set; } | ||||
|         string ProwlApiKeys { get; set; } | ||||
|         int ProwlPriority { get; set; } | ||||
|         bool EnableBacklogSearching { get; set; } | ||||
|         bool AutoIgnorePreviouslyDownloadedEpisodes { get; set; } | ||||
|         int Retention { get; set; } | ||||
| @@ -50,11 +32,6 @@ namespace NzbDrone.Core.Configuration | ||||
|         DownloadClientType DownloadClient { get; set; } | ||||
|         string BlackholeDirectory { get; set; } | ||||
|         string ServiceRootUrl { get; } | ||||
|         Boolean PlexUpdateLibrary { get; set; } | ||||
|         string PlexServerHost { get; set; } | ||||
|         string PlexClientHosts { get; set; } | ||||
|         string PlexUsername { get; set; } | ||||
|         string PlexPassword { get; set; } | ||||
|         Boolean MetadataUseBanners { get; set; } | ||||
|         string PneumaticDirectory { get; set; } | ||||
|         string RecycleBin { get; set; } | ||||
|   | ||||
| @@ -83,10 +83,12 @@ namespace NzbDrone.Core.Datastore.Migration | ||||
|                   .WithColumn("NzbInfoUrl").AsString().Nullable() | ||||
|                   .WithColumn("ReleaseGroup").AsString().Nullable(); | ||||
|  | ||||
|             Create.TableForModel("ExternalNotificationDefinitions") | ||||
|                   .WithColumn("Enable").AsBoolean() | ||||
|                   .WithColumn("Type").AsString().Unique() | ||||
|                   .WithColumn("Name").AsString().Unique(); | ||||
|             Create.TableForModel("NotificationDefinitions") | ||||
|                   .WithColumn("Name").AsString() | ||||
|                   .WithColumn("OnGrab").AsBoolean() | ||||
|                   .WithColumn("OnDownload").AsBoolean() | ||||
|                   .WithColumn("Settings").AsString() | ||||
|                   .WithColumn("Implementation").AsString(); | ||||
|  | ||||
|             Create.TableForModel("ScheduledTasks") | ||||
|                   .WithColumn("TypeName").AsString().Unique() | ||||
|   | ||||
| @@ -8,11 +8,11 @@ using NzbDrone.Common.Serializer; | ||||
| using NzbDrone.Core.Configuration; | ||||
| using NzbDrone.Core.DataAugmentation.Scene; | ||||
| using NzbDrone.Core.Datastore.Converters; | ||||
| using NzbDrone.Core.ExternalNotification; | ||||
| using NzbDrone.Core.Indexers; | ||||
| using NzbDrone.Core.Instrumentation; | ||||
| using NzbDrone.Core.Jobs; | ||||
| using NzbDrone.Core.MediaFiles; | ||||
| using NzbDrone.Core.Notifications; | ||||
| using NzbDrone.Core.Organizer; | ||||
| using NzbDrone.Core.Qualities; | ||||
| using NzbDrone.Core.RootFolders; | ||||
| @@ -35,7 +35,7 @@ namespace NzbDrone.Core.Datastore | ||||
|  | ||||
|             Mapper.Entity<IndexerDefinition>().RegisterModel("IndexerDefinitions"); | ||||
|             Mapper.Entity<ScheduledTask>().RegisterModel("ScheduledTasks"); | ||||
|             Mapper.Entity<ExternalNotificationDefinition>().RegisterModel("ExternalNotificationDefinitions"); | ||||
|             Mapper.Entity<NotificationDefinition>().RegisterModel("NotificationDefinitions"); | ||||
|  | ||||
|             Mapper.Entity<SceneMapping>().RegisterModel("SceneMappings"); | ||||
|  | ||||
|   | ||||
| @@ -4,11 +4,7 @@ using System.Linq; | ||||
| using NLog; | ||||
| using NzbDrone.Common.Messaging; | ||||
| using NzbDrone.Core.Configuration; | ||||
| using NzbDrone.Core.DecisionEngine; | ||||
| using NzbDrone.Core.Model; | ||||
| using NzbDrone.Core.Parser; | ||||
| using NzbDrone.Core.Parser.Model; | ||||
| using NzbDrone.Core.Tv; | ||||
|  | ||||
| namespace NzbDrone.Core.Download | ||||
| { | ||||
| @@ -20,16 +16,14 @@ namespace NzbDrone.Core.Download | ||||
|     public class DownloadService : IDownloadService | ||||
|     { | ||||
|         private readonly IProvideDownloadClient _downloadClientProvider; | ||||
|         private readonly IConfigService _configService; | ||||
|         private readonly IMessageAggregator _messageAggregator; | ||||
|         private readonly Logger _logger; | ||||
|  | ||||
|  | ||||
|         public DownloadService(IProvideDownloadClient downloadClientProvider, IConfigService configService, | ||||
|         public DownloadService(IProvideDownloadClient downloadClientProvider, | ||||
|             IMessageAggregator messageAggregator, Logger logger) | ||||
|         { | ||||
|             _downloadClientProvider = downloadClientProvider; | ||||
|             _configService = configService; | ||||
|             _messageAggregator = messageAggregator; | ||||
|             _logger = logger; | ||||
|         } | ||||
|   | ||||
| @@ -1,148 +0,0 @@ | ||||
| using System; | ||||
| using NLog; | ||||
| using NzbDrone.Common.Messaging; | ||||
| using NzbDrone.Core.Download; | ||||
| using NzbDrone.Core.MediaFiles.Events; | ||||
| using NzbDrone.Core.Tv; | ||||
|  | ||||
| namespace NzbDrone.Core.ExternalNotification | ||||
| { | ||||
|     public abstract class ExternalNotificationBase | ||||
|         : IHandle<EpisodeGrabbedEvent>, | ||||
|           IHandle<EpisodeDownloadedEvent>, | ||||
|           IHandle<SeriesRenamedEvent> | ||||
|     { | ||||
|         private readonly IExternalNotificationRepository _externalNotificationRepository; | ||||
|         private readonly Logger _logger; | ||||
|  | ||||
|         protected ExternalNotificationBase(IExternalNotificationRepository externalNotificationRepository, Logger logger) | ||||
|         { | ||||
|             _externalNotificationRepository = externalNotificationRepository; | ||||
|             _logger = logger; | ||||
|         } | ||||
|  | ||||
|         public abstract string Name { get; } | ||||
|  | ||||
|         public bool NotifyOnGrab | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 return GetEnableStatus(c => c.OnGrab); | ||||
|             } | ||||
|             set | ||||
|             { | ||||
|                 SetEnableStatus(c => c.OnGrab = value); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public bool NotifyOnDownload | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 return GetEnableStatus(c => c.OnDownload); | ||||
|             } | ||||
|             set | ||||
|             { | ||||
|                 SetEnableStatus(c => c.OnDownload = value); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public bool NotifyOnRename | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 return GetEnableStatus(c => c.OnRename); | ||||
|             } | ||||
|             set | ||||
|             { | ||||
|                 SetEnableStatus(c => c.OnRename = value); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private void SetEnableStatus(Action<ExternalNotificationDefinition> updateAction) | ||||
|         { | ||||
|             var def = _externalNotificationRepository.Get(Name) ?? | ||||
|                       new ExternalNotificationDefinition { Name = Name }; | ||||
|  | ||||
|             updateAction(def); | ||||
|             _externalNotificationRepository.Upsert(def); | ||||
|         } | ||||
|  | ||||
|         private bool GetEnableStatus(Func<ExternalNotificationDefinition, bool> readFunction) | ||||
|         { | ||||
|             var def = _externalNotificationRepository.Get(Name) ?? | ||||
|                       new ExternalNotificationDefinition { Name = Name }; | ||||
|  | ||||
|             return readFunction(def); | ||||
|         } | ||||
|  | ||||
|         public void Handle(EpisodeGrabbedEvent message) | ||||
|         { | ||||
|             if (NotifyOnGrab) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     _logger.Trace("Sending grab notification to {0}", Name); | ||||
|                     //todo: pass all the info to grab event and let the handlers deal with it. | ||||
|                     OnGrab(message.Episode.ToString()); | ||||
|  | ||||
|                 } | ||||
|                 catch (Exception e) | ||||
|                 { | ||||
|                     _logger.WarnException("Couldn't send grab notification to " + Name, e); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void Handle(EpisodeDownloadedEvent message) | ||||
|         { | ||||
|             if (NotifyOnDownload) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     _logger.Trace("Sending download notification to {0}", Name); | ||||
|                     OnDownload(message.ParsedEpisodeInfo.ToString(), message.Series); | ||||
|                 } | ||||
|                 catch (Exception e) | ||||
|                 { | ||||
|                     _logger.WarnException("Couldn't send download notification to " + Name, e); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void Handle(SeriesRenamedEvent message) | ||||
|         { | ||||
|             if (NotifyOnRename) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     _logger.Trace("Sending rename notification to {0}", Name); | ||||
|                     AfterRename(message.Series); | ||||
|  | ||||
|                 } | ||||
|                 catch (Exception e) | ||||
|                 { | ||||
|                     _logger.WarnException("Couldn't send rename notification to " + Name, e); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|         protected virtual void OnGrab(string message) | ||||
|         { | ||||
|  | ||||
|         } | ||||
|  | ||||
|         protected virtual void OnDownload(string message, Series series) | ||||
|         { | ||||
|  | ||||
|         } | ||||
|  | ||||
|         protected virtual void AfterRename(Series series) | ||||
|         { | ||||
|  | ||||
|         } | ||||
|  | ||||
|  | ||||
|     } | ||||
| } | ||||
| @@ -1,13 +0,0 @@ | ||||
| using System.Linq; | ||||
| using NzbDrone.Core.Datastore; | ||||
|  | ||||
| namespace NzbDrone.Core.ExternalNotification | ||||
| { | ||||
|     public class ExternalNotificationDefinition : ModelBase | ||||
|     { | ||||
|         public string Name { get; set; } | ||||
|         public bool OnGrab { get; set; } | ||||
|         public bool OnDownload { get; set; } | ||||
|         public bool OnRename { get; set; } | ||||
|     } | ||||
| } | ||||
| @@ -1,25 +0,0 @@ | ||||
| using System.Data; | ||||
| using System.Linq; | ||||
| using NzbDrone.Common.Messaging; | ||||
| using NzbDrone.Core.Datastore; | ||||
|  | ||||
| namespace NzbDrone.Core.ExternalNotification | ||||
| { | ||||
|     public interface IExternalNotificationRepository : IBasicRepository<ExternalNotificationDefinition> | ||||
|     { | ||||
|         ExternalNotificationDefinition Get(string name); | ||||
|     } | ||||
|  | ||||
|     public class ExternalNotificationRepository : BasicRepository<ExternalNotificationDefinition>, IExternalNotificationRepository | ||||
|     { | ||||
|         public ExternalNotificationRepository(IDatabase database, IMessageAggregator messageAggregator) | ||||
|             : base(database, messageAggregator) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         public ExternalNotificationDefinition Get(string name) | ||||
|         { | ||||
|             return Query.SingleOrDefault(c => c.Name.ToLower() == name.ToLower()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,48 +0,0 @@ | ||||
| using System.Linq; | ||||
| using System; | ||||
| using NLog; | ||||
| using NzbDrone.Core.Configuration; | ||||
| using NzbDrone.Core.Tv; | ||||
|  | ||||
| namespace NzbDrone.Core.ExternalNotification | ||||
| { | ||||
|     public class Growl : ExternalNotificationBase | ||||
|     { | ||||
|         private readonly IConfigService _configService; | ||||
|         private readonly GrowlProvider _growlProvider; | ||||
|  | ||||
|         public Growl(IExternalNotificationRepository repository, IConfigService configService, GrowlProvider growlProvider, Logger logger) | ||||
|             : base(repository, logger) | ||||
|         { | ||||
|             _configService = configService; | ||||
|             _growlProvider = growlProvider; | ||||
|         } | ||||
|  | ||||
|         public override string Name | ||||
|         { | ||||
|             get { return "Growl"; } | ||||
|         } | ||||
|  | ||||
|         protected override void OnGrab(string message) | ||||
|         { | ||||
|             const string title = "Episode Grabbed"; | ||||
|  | ||||
|             var growlHost = _configService.GrowlHost.Split(':'); | ||||
|             var host = growlHost[0]; | ||||
|             var port = Convert.ToInt32(growlHost[1]); | ||||
|  | ||||
|             _growlProvider.SendNotification(title, message, "GRAB", host, port, _configService.GrowlPassword); | ||||
|         } | ||||
|  | ||||
|         protected override void OnDownload(string message, Series series) | ||||
|         { | ||||
|             const string title = "Episode Downloaded"; | ||||
|  | ||||
|             var growlHost = _configService.GrowlHost.Split(':'); | ||||
|             var host = growlHost[0]; | ||||
|             var port = Convert.ToInt32(growlHost[1]); | ||||
|  | ||||
|             _growlProvider.SendNotification(title, message, "DOWNLOAD", host, port, _configService.GrowlPassword); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,51 +0,0 @@ | ||||
| using System.Linq; | ||||
| using NLog; | ||||
| using NzbDrone.Core.Configuration; | ||||
| using NzbDrone.Core.Tv; | ||||
|  | ||||
| namespace NzbDrone.Core.ExternalNotification | ||||
| { | ||||
|     public class Plex : ExternalNotificationBase | ||||
|     { | ||||
|         private readonly IConfigService _configService; | ||||
|         private readonly PlexProvider _plexProvider; | ||||
|  | ||||
|         public Plex(IConfigService configService, IExternalNotificationRepository repository, PlexProvider plexProvider, Logger logger) | ||||
|             : base(repository, logger) | ||||
|         { | ||||
|             _configService = configService; | ||||
|             _plexProvider = plexProvider; | ||||
|         } | ||||
|  | ||||
|         public override string Name | ||||
|         { | ||||
|             get { return "Plex"; } | ||||
|         } | ||||
|  | ||||
|         protected override void OnGrab(string message) | ||||
|         { | ||||
|             const string header = "NzbDrone [TV] - Grabbed"; | ||||
|             _plexProvider.Notify(header, message); | ||||
|         } | ||||
|  | ||||
|         protected override void OnDownload(string message, Series series) | ||||
|         { | ||||
|             const string header = "NzbDrone [TV] - Downloaded"; | ||||
|             _plexProvider.Notify(header, message); | ||||
|             UpdateIfEnabled(); | ||||
|         } | ||||
|  | ||||
|         protected override void AfterRename( Series series) | ||||
|         { | ||||
|             UpdateIfEnabled(); | ||||
|         } | ||||
|  | ||||
|         private void UpdateIfEnabled() | ||||
|         { | ||||
|             if (_configService.PlexUpdateLibrary) | ||||
|             { | ||||
|                 _plexProvider.UpdateLibrary(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,48 +0,0 @@ | ||||
| using System.Linq; | ||||
| using System; | ||||
| using NLog; | ||||
| using NzbDrone.Core.Configuration; | ||||
| using NzbDrone.Core.Providers; | ||||
| using NzbDrone.Core.Tv; | ||||
| using Prowlin; | ||||
|  | ||||
| namespace NzbDrone.Core.ExternalNotification | ||||
| { | ||||
|     public class Prowl : ExternalNotificationBase | ||||
|     { | ||||
|         private readonly IConfigService _configService; | ||||
|         private readonly ProwlProvider _prowlProvider; | ||||
|  | ||||
|         public Prowl(IConfigService configService, IExternalNotificationRepository repository, ProwlProvider prowlProvider, Logger logger) | ||||
|             : base(repository, logger) | ||||
|         { | ||||
|             _configService = configService; | ||||
|             _prowlProvider = prowlProvider; | ||||
|         } | ||||
|  | ||||
|         public override string Name | ||||
|         { | ||||
|             get { return "Prowl"; } | ||||
|         } | ||||
|  | ||||
|         protected override void OnGrab(string message) | ||||
|         { | ||||
|             const string title = "Episode Grabbed"; | ||||
|  | ||||
|             var apiKeys = _configService.ProwlApiKeys; | ||||
|             var priority = _configService.ProwlPriority; | ||||
|  | ||||
|             _prowlProvider.SendNotification(title, message, apiKeys, (NotificationPriority)priority); | ||||
|         } | ||||
|  | ||||
|         protected override void OnDownload(string message, Series series) | ||||
|         { | ||||
|             const string title = "Episode Downloaded"; | ||||
|  | ||||
|             var apiKeys = _configService.ProwlApiKeys; | ||||
|             var priority = _configService.ProwlPriority; | ||||
|  | ||||
|             _prowlProvider.SendNotification(title, message, apiKeys, (NotificationPriority)priority); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,59 +0,0 @@ | ||||
| using System.Linq; | ||||
| using NLog; | ||||
| using NzbDrone.Core.Configuration; | ||||
| using NzbDrone.Core.Providers; | ||||
| using NzbDrone.Core.Tv; | ||||
|  | ||||
| namespace NzbDrone.Core.ExternalNotification | ||||
| { | ||||
|     public class Xbmc : ExternalNotificationBase | ||||
|     { | ||||
|         private readonly IConfigService _configService; | ||||
|         private readonly XbmcProvider _xbmcProvider; | ||||
|  | ||||
|         public Xbmc(IConfigService configService, IExternalNotificationRepository repository, XbmcProvider xbmcProvider, Logger logger) | ||||
|             : base(repository, logger) | ||||
|         { | ||||
|             _configService = configService; | ||||
|             _xbmcProvider = xbmcProvider; | ||||
|         } | ||||
|  | ||||
|         public override string Name | ||||
|         { | ||||
|             get { return "XBMC"; } | ||||
|         } | ||||
|  | ||||
|         protected override void OnGrab(string message) | ||||
|         { | ||||
|             const string header = "NzbDrone [TV] - Grabbed"; | ||||
|  | ||||
|             _xbmcProvider.Notify(header, message); | ||||
|         } | ||||
|  | ||||
|         protected override void OnDownload(string message, Series series) | ||||
|         { | ||||
|             const string header = "NzbDrone [TV] - Downloaded"; | ||||
|  | ||||
|             _xbmcProvider.Notify(header, message); | ||||
|             UpdateAndClean(series); | ||||
|         } | ||||
|  | ||||
|         protected override void AfterRename(Series series) | ||||
|         { | ||||
|             UpdateAndClean(series); | ||||
|         } | ||||
|  | ||||
|         private void UpdateAndClean(Series series) | ||||
|         { | ||||
|             if (_configService.XbmcUpdateLibrary) | ||||
|             { | ||||
|                 _xbmcProvider.Update(series); | ||||
|             } | ||||
|  | ||||
|             if (_configService.XbmcCleanLibrary) | ||||
|             { | ||||
|                 _xbmcProvider.Clean(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -134,7 +134,5 @@ namespace NzbDrone.Core.IndexerSearch | ||||
|  | ||||
|             return _makeDownloadDecision.GetSearchDecision(reports, definitionBase).ToList(); | ||||
|         } | ||||
|  | ||||
|  | ||||
|     } | ||||
| } | ||||
| @@ -18,7 +18,7 @@ namespace NzbDrone.Core.Indexers | ||||
|                     Name = Name, | ||||
|                     Enable = true, | ||||
|                     Implementation = GetType().Name, | ||||
|                     Settings = string.Empty | ||||
|                     Settings = String.Empty | ||||
|                 }; | ||||
|             } | ||||
|         } | ||||
| @@ -32,7 +32,6 @@ namespace NzbDrone.Core.Indexers | ||||
|         } | ||||
|  | ||||
|         public abstract IEnumerable<string> RecentFeed { get; } | ||||
|  | ||||
|         public abstract IEnumerable<string> GetEpisodeSearchUrls(string seriesTitle, int seasonNumber, int episodeNumber); | ||||
|         public abstract IEnumerable<string> GetDailyEpisodeSearchUrls(string seriesTitle, DateTime date); | ||||
|         public abstract IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int seasonNumber); | ||||
|   | ||||
| @@ -40,7 +40,5 @@ namespace NzbDrone.Core.Indexers.NzbsRUs | ||||
|         { | ||||
|             return new List<string>(); | ||||
|         } | ||||
|  | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										40
									
								
								NzbDrone.Core/Notifications/Growl/Growl.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								NzbDrone.Core/Notifications/Growl/Growl.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| using System; | ||||
| using NLog; | ||||
| using NzbDrone.Core.Configuration; | ||||
| using NzbDrone.Core.Tv; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications.Growl | ||||
| { | ||||
|     public class Growl : NotificationWithSetting<GrowlSettings> | ||||
|     { | ||||
|         private readonly GrowlProvider _growlProvider; | ||||
|  | ||||
|         public Growl(GrowlProvider growlProvider) | ||||
|         { | ||||
|             _growlProvider = growlProvider; | ||||
|         } | ||||
|  | ||||
|         public override string Name | ||||
|         { | ||||
|             get { return "Growl"; } | ||||
|         } | ||||
|  | ||||
|         public override void OnGrab(string message) | ||||
|         { | ||||
|             const string title = "Episode Grabbed"; | ||||
|  | ||||
|             _growlProvider.SendNotification(title, message, "GRAB", Settings.Host, Settings.Port, Settings.Password); | ||||
|         } | ||||
|  | ||||
|         public override void OnDownload(string message, Series series) | ||||
|         { | ||||
|             const string title = "Episode Downloaded"; | ||||
|  | ||||
|             _growlProvider.SendNotification(title, message, "DOWNLOAD", Settings.Host, Settings.Port, Settings.Password); | ||||
|         } | ||||
|  | ||||
|         public override void AfterRename(Series series) | ||||
|         { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -3,8 +3,9 @@ using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using Growl.Connector; | ||||
| using NLog; | ||||
| using GrowlNotification = Growl.Connector.Notification; | ||||
| 
 | ||||
| namespace NzbDrone.Core.ExternalNotification | ||||
| namespace NzbDrone.Core.Notifications.Growl | ||||
| { | ||||
|     public class GrowlProvider | ||||
|     { | ||||
| @@ -39,7 +40,7 @@ namespace NzbDrone.Core.ExternalNotification | ||||
|         { | ||||
|             var notificationType = _notificationTypes.Single(n => n.Name == notificationTypeName); | ||||
| 
 | ||||
|             var notification = new Notification("NzbDrone", notificationType.Name, DateTime.Now.Ticks.ToString(), title, message); | ||||
|             var notification = new GrowlNotification("NzbDrone", notificationType.Name, DateTime.Now.Ticks.ToString(), title, message); | ||||
| 
 | ||||
|             _growlConnector = new GrowlConnector(password, hostname, port); | ||||
| 
 | ||||
							
								
								
									
										28
									
								
								NzbDrone.Core/Notifications/Growl/GrowlSettings.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								NzbDrone.Core/Notifications/Growl/GrowlSettings.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using NzbDrone.Core.Annotations; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications.Growl | ||||
| { | ||||
|     public class GrowlSettings : INotifcationSettings | ||||
|     { | ||||
|         [FieldDefinition(0, Label = "Host", HelpText = "Growl Host (IP or Hostname)")] | ||||
|         public String Host { get; set; } | ||||
|  | ||||
|         [FieldDefinition(1, Label = "Port", HelpText = "Growl Port")] | ||||
|         public Int32 Port { get; set; } | ||||
|  | ||||
|         [FieldDefinition(2, Label = "Password", HelpText = "Password for Growl")] | ||||
|         public String Password { get; set; } | ||||
|  | ||||
|         public bool IsValid | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 return !string.IsNullOrWhiteSpace(Host) && !string.IsNullOrWhiteSpace(Password) && Port > 0; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										30
									
								
								NzbDrone.Core/Notifications/INotifcationSettings.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								NzbDrone.Core/Notifications/INotifcationSettings.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications | ||||
| { | ||||
|     public interface INotifcationSettings | ||||
|     { | ||||
|         bool IsValid { get; } | ||||
|     } | ||||
|  | ||||
|     public class NullSetting : INotifcationSettings | ||||
|     { | ||||
|         public static NullSetting Instance = new NullSetting(); | ||||
|  | ||||
|         private NullSetting() | ||||
|         { | ||||
|  | ||||
|         } | ||||
|  | ||||
|         public bool IsValid | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										19
									
								
								NzbDrone.Core/Notifications/INotification.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								NzbDrone.Core/Notifications/INotification.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using NzbDrone.Core.Tv; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications | ||||
| { | ||||
|     public interface INotification | ||||
|     { | ||||
|         string Name { get; } | ||||
|  | ||||
|         NotificationDefinition InstanceDefinition { get; set; } | ||||
|  | ||||
|         void OnGrab(string message); | ||||
|         void OnDownload(string message, Series series); | ||||
|         void AfterRename(Series series); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										17
									
								
								NzbDrone.Core/Notifications/Notification.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								NzbDrone.Core/Notifications/Notification.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications | ||||
| { | ||||
|     public class Notification | ||||
|     { | ||||
|         public int Id { get; set; } | ||||
|         public string Name { get; set; } | ||||
|         public bool OnGrab { get; set; } | ||||
|         public bool OnDownload { get; set; } | ||||
|         public INotifcationSettings Settings { get; set; } | ||||
|         public INotification Instance { get; set; } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										17
									
								
								NzbDrone.Core/Notifications/NotificationBase.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								NzbDrone.Core/Notifications/NotificationBase.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| using System; | ||||
| using NLog; | ||||
| using NzbDrone.Core.Tv; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications | ||||
| { | ||||
|     public abstract class NotificationBase : INotification | ||||
|     { | ||||
|         public abstract string Name { get; } | ||||
|  | ||||
|         public NotificationDefinition InstanceDefinition { get; set; } | ||||
|  | ||||
|         public abstract void OnGrab(string message); | ||||
|         public abstract void OnDownload(string message, Series series); | ||||
|         public abstract void AfterRename(Series series); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										14
									
								
								NzbDrone.Core/Notifications/NotificationDefinition.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								NzbDrone.Core/Notifications/NotificationDefinition.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| using System; | ||||
| using NzbDrone.Core.Datastore; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications | ||||
| { | ||||
|     public class NotificationDefinition : ModelBase | ||||
|     { | ||||
|         public String Name { get; set; } | ||||
|         public Boolean OnGrab { get; set; } | ||||
|         public Boolean OnDownload { get; set; } | ||||
|         public String Settings { get; set; } | ||||
|         public String Implementation { get; set; } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										31
									
								
								NzbDrone.Core/Notifications/NotificationRepository.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								NzbDrone.Core/Notifications/NotificationRepository.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| using System; | ||||
| using System.Linq; | ||||
| using NzbDrone.Common.Messaging; | ||||
| using NzbDrone.Core.Datastore; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications | ||||
| { | ||||
|     public interface INotificationRepository : IBasicRepository<NotificationDefinition> | ||||
|     { | ||||
|         NotificationDefinition Get(string name); | ||||
|         NotificationDefinition Find(string name); | ||||
|     } | ||||
|  | ||||
|     public class NotificationRepository : BasicRepository<NotificationDefinition>, INotificationRepository | ||||
|     { | ||||
|         public NotificationRepository(IDatabase database, IMessageAggregator messageAggregator) | ||||
|             : base(database, messageAggregator) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         public NotificationDefinition Get(string name) | ||||
|         { | ||||
|             return Query.Single(i => i.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)); | ||||
|         } | ||||
|  | ||||
|         public NotificationDefinition Find(string name) | ||||
|         { | ||||
|             return Query.SingleOrDefault(i => i.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										106
									
								
								NzbDrone.Core/Notifications/NotificationService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								NzbDrone.Core/Notifications/NotificationService.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using NLog; | ||||
| using NzbDrone.Common; | ||||
| using NzbDrone.Common.Composition; | ||||
| using NzbDrone.Common.Messaging; | ||||
| using NzbDrone.Core.Download; | ||||
| using NzbDrone.Core.MediaFiles.Events; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications | ||||
| { | ||||
|     public interface INotificationService | ||||
|     { | ||||
|         List<Notification> All(); | ||||
|     } | ||||
|  | ||||
|     public class NotificationService | ||||
|         : INotificationService, | ||||
|           IHandle<EpisodeGrabbedEvent>, | ||||
|           IHandle<EpisodeDownloadedEvent>, | ||||
|           IHandle<SeriesRenamedEvent> | ||||
|     { | ||||
|         private readonly INotificationRepository _notificationRepository; | ||||
|         private readonly IContainer _container; | ||||
|         private readonly List<INotification> _notifications; | ||||
|         private readonly Logger _logger; | ||||
|  | ||||
|         public NotificationService(INotificationRepository notificationRepository, | ||||
|                                    IEnumerable<INotification> notifications, | ||||
|                                    IContainer container, | ||||
|                                    Logger logger) | ||||
|         { | ||||
|             _notificationRepository = notificationRepository; | ||||
|             _container = container; | ||||
|             _notifications = notifications.ToList(); | ||||
|             _logger = logger; | ||||
|         } | ||||
|  | ||||
|         public List<Notification> All() | ||||
|         { | ||||
|             return _notificationRepository.All().Select(ToNotification).ToList(); | ||||
|         } | ||||
|  | ||||
|         private Notification ToNotification(NotificationDefinition definition) | ||||
|         { | ||||
|             var notification = new Notification(); | ||||
|             notification.Id = definition.Id; | ||||
|             notification.OnGrab = definition.OnGrab; | ||||
|             notification.OnDownload = definition.OnDownload; | ||||
|             notification.Instance = GetInstance(definition); | ||||
|             notification.Name = definition.Name; | ||||
|  | ||||
|             if (notification.Instance.GetType().GetMethod("ImportSettingsFromJson") != null) | ||||
|             { | ||||
|                 notification.Settings = ((dynamic)notification.Instance).ImportSettingsFromJson(definition.Settings); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 notification.Settings = NullSetting.Instance; | ||||
|             } | ||||
|  | ||||
|             return notification; | ||||
|         } | ||||
|  | ||||
|         private INotification GetInstance(NotificationDefinition indexerDefinition) | ||||
|         {            | ||||
|             var type = _notifications.Single(c => c.GetType().Name.Equals(indexerDefinition.Implementation, StringComparison.InvariantCultureIgnoreCase)).GetType(); | ||||
|  | ||||
|             var instance = (INotification)_container.Resolve(type); | ||||
|  | ||||
|             instance.InstanceDefinition = indexerDefinition; | ||||
|             return instance; | ||||
|         } | ||||
|  | ||||
|         public void Handle(EpisodeGrabbedEvent message) | ||||
|         { | ||||
|             All().Where(n => n.OnGrab) | ||||
|                 .ToList() | ||||
|                 .ForEach(notification => | ||||
|                             notification.Instance | ||||
|                                         .OnGrab("Grabbed!") | ||||
|                         ); | ||||
|         } | ||||
|  | ||||
|         public void Handle(EpisodeDownloadedEvent message) | ||||
|         { | ||||
|             All().Where(n => n.OnDownload) | ||||
|                 .ToList() | ||||
|                 .ForEach(notification => | ||||
|                             notification.Instance | ||||
|                                         .OnDownload("Downloaded!", message.Series) | ||||
|                         ); | ||||
|         } | ||||
|  | ||||
|         public void Handle(SeriesRenamedEvent message) | ||||
|         { | ||||
|             All().Where(n => n.OnDownload) | ||||
|                 .ToList() | ||||
|                 .ForEach(notification => | ||||
|                             notification.Instance | ||||
|                                         .OnDownload("Renamed!", message.Series) | ||||
|                         ); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										31
									
								
								NzbDrone.Core/Notifications/NotificationSettingsProvider.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								NzbDrone.Core/Notifications/NotificationSettingsProvider.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| using Newtonsoft.Json; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications | ||||
| { | ||||
|     public interface INotificationSettingsProvider | ||||
|     { | ||||
|         TSetting Get<TSetting>(INotification indexer) where TSetting : INotifcationSettings, new(); | ||||
|     } | ||||
|  | ||||
|     public class NotificationSettingsProvider : INotificationSettingsProvider | ||||
|     { | ||||
|         private readonly INotificationRepository _notificationRepository; | ||||
|  | ||||
|         public NotificationSettingsProvider(INotificationRepository notificationRepository) | ||||
|         { | ||||
|             _notificationRepository = notificationRepository; | ||||
|         } | ||||
|  | ||||
|         public TSetting Get<TSetting>(INotification indexer) where TSetting : INotifcationSettings, new() | ||||
|         { | ||||
|             var indexerDef = _notificationRepository.Find(indexer.Name); | ||||
|  | ||||
|             if (indexerDef == null || string.IsNullOrWhiteSpace(indexerDef.Settings)) | ||||
|             { | ||||
|                 return new TSetting(); | ||||
|             } | ||||
|  | ||||
|             return JsonConvert.DeserializeObject<TSetting>(indexerDef.Settings); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										20
									
								
								NzbDrone.Core/Notifications/NotificationWithSetting.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								NzbDrone.Core/Notifications/NotificationWithSetting.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using NzbDrone.Common.Serializer; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications | ||||
| { | ||||
|     public abstract class NotificationWithSetting<TSetting> : NotificationBase where TSetting : class, INotifcationSettings, new() | ||||
|     { | ||||
|         public TSetting Settings { get; private set; } | ||||
|  | ||||
|         public TSetting ImportSettingsFromJson(string json) | ||||
|         { | ||||
|             Settings = Json.Deserialize<TSetting>(json) ?? new TSetting(); | ||||
|  | ||||
|             return Settings; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										37
									
								
								NzbDrone.Core/Notifications/Plex/PlexClient.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								NzbDrone.Core/Notifications/Plex/PlexClient.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| using NLog; | ||||
| using NzbDrone.Core.Configuration; | ||||
| using NzbDrone.Core.Tv; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications.Plex | ||||
| { | ||||
|     public class PlexClient : NotificationWithSetting<PlexClientSettings> | ||||
|     { | ||||
|         private readonly PlexProvider _plexProvider; | ||||
|  | ||||
|         public PlexClient(PlexProvider plexProvider) | ||||
|         { | ||||
|             _plexProvider = plexProvider; | ||||
|         } | ||||
|  | ||||
|         public override string Name | ||||
|         { | ||||
|             get { return "Plex Client"; } | ||||
|         } | ||||
|  | ||||
|         public override void OnGrab(string message) | ||||
|         { | ||||
|             const string header = "NzbDrone [TV] - Grabbed"; | ||||
|             _plexProvider.Notify(Settings, header, message); | ||||
|         } | ||||
|  | ||||
|         public override void OnDownload(string message, Series series) | ||||
|         { | ||||
|             const string header = "NzbDrone [TV] - Downloaded"; | ||||
|             _plexProvider.Notify(Settings, header, message); | ||||
|         } | ||||
|  | ||||
|         public override void AfterRename(Series series) | ||||
|         { | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										31
									
								
								NzbDrone.Core/Notifications/Plex/PlexClientSettings.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								NzbDrone.Core/Notifications/Plex/PlexClientSettings.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using NzbDrone.Core.Annotations; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications.Plex | ||||
| { | ||||
|     public class PlexClientSettings : INotifcationSettings | ||||
|     { | ||||
|         [FieldDefinition(0, Label = "Host", HelpText = "Plex Client Host (IP or Hostname)")] | ||||
|         public String Host { get; set; } | ||||
|  | ||||
|         [FieldDefinition(1, Label = "Port", HelpText = "Plex Client Port")] | ||||
|         public Int32 Port { get; set; } | ||||
|  | ||||
|         [FieldDefinition(2, Label = "Username", HelpText = "Username for Plex")] | ||||
|         public String Username { get; set; } | ||||
|  | ||||
|         [FieldDefinition(3, Label = "Password", HelpText = "Password for Plex")] | ||||
|         public String Password { get; set; } | ||||
|  | ||||
|         public bool IsValid | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 return !string.IsNullOrWhiteSpace(Host); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -6,46 +6,33 @@ using NLog; | ||||
| using NzbDrone.Common; | ||||
| using NzbDrone.Core.Configuration; | ||||
| 
 | ||||
| namespace NzbDrone.Core.ExternalNotification | ||||
| namespace NzbDrone.Core.Notifications.Plex | ||||
| { | ||||
|     public class PlexProvider | ||||
|     { | ||||
|         private readonly IHttpProvider _httpProvider; | ||||
|         private readonly IConfigService _configService; | ||||
|         private static readonly Logger logger = LogManager.GetCurrentClassLogger(); | ||||
| 
 | ||||
|         public PlexProvider(IHttpProvider httpProvider, IConfigService configService) | ||||
|         public PlexProvider(IHttpProvider httpProvider) | ||||
|         { | ||||
|             _httpProvider = httpProvider; | ||||
|             _configService = configService; | ||||
|         } | ||||
| 
 | ||||
|         public PlexProvider() | ||||
|         public virtual void Notify(PlexClientSettings settings, string header, string message) | ||||
|         { | ||||
|              | ||||
|         } | ||||
| 
 | ||||
|         public virtual void Notify(string header, string message) | ||||
|         { | ||||
|             //Foreach plex client send a notification | ||||
|             foreach(var host in _configService.PlexClientHosts.Split(',')) | ||||
|             try | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     var command = String.Format("ExecBuiltIn(Notification({0}, {1}))", header, message); | ||||
|                     SendCommand(host.Trim(), command, _configService.PlexUsername, _configService.PlexPassword); | ||||
|                 } | ||||
|                 catch(Exception ex) | ||||
|                 { | ||||
|                     logger.WarnException("Failed to send notification to Plex Client: " + host.Trim(), ex); | ||||
|                 } | ||||
|                 var command = String.Format("ExecBuiltIn(Notification({0}, {1}))", header, message); | ||||
|                 SendCommand(settings.Host, command, settings.Username, settings.Password); | ||||
|             } | ||||
|             catch(Exception ex) | ||||
|             { | ||||
|                 logger.WarnException("Failed to send notification to Plex Client: " + settings.Host, ex); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public virtual void UpdateLibrary() | ||||
|         public virtual void UpdateLibrary(string host) | ||||
|         { | ||||
|             var host = _configService.PlexServerHost; | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
|                 logger.Trace("Sending Update Request to Plex Server"); | ||||
| @@ -91,14 +78,11 @@ namespace NzbDrone.Core.ExternalNotification | ||||
|             return _httpProvider.DownloadString(url); | ||||
|         } | ||||
| 
 | ||||
|         public virtual void TestNotification(string hosts, string username, string password) | ||||
|         public virtual void TestNotification(string host, string username, string password) | ||||
|         { | ||||
|             foreach (var host in hosts.Split(',')) | ||||
|             { | ||||
|                 logger.Trace("Sending Test Notifcation to XBMC Host: {0}", host); | ||||
|                 var command = String.Format("ExecBuiltIn(Notification({0}, {1}))", "Test Notification", "Success! Notifications are setup correctly"); | ||||
|                 SendCommand(host.Trim(), command, _configService.PlexUsername, _configService.PlexPassword); | ||||
|             } | ||||
|             logger.Trace("Sending Test Notifcation to XBMC Host: {0}", host); | ||||
|             var command = String.Format("ExecBuiltIn(Notification({0}, {1}))", "Test Notification", "Success! Notifications are setup correctly"); | ||||
|             SendCommand(host.Trim(), command, username, password); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										43
									
								
								NzbDrone.Core/Notifications/Plex/PlexServer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								NzbDrone.Core/Notifications/Plex/PlexServer.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| using NLog; | ||||
| using NzbDrone.Core.Configuration; | ||||
| using NzbDrone.Core.Tv; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications.Plex | ||||
| { | ||||
|     public class PlexServer : NotificationWithSetting<PlexServerSettings> | ||||
|     { | ||||
|         private readonly PlexProvider _plexProvider; | ||||
|  | ||||
|         public PlexServer(PlexProvider plexProvider) | ||||
|         { | ||||
|             _plexProvider = plexProvider; | ||||
|         } | ||||
|  | ||||
|         public override string Name | ||||
|         { | ||||
|             get { return "Plex Server"; } | ||||
|         } | ||||
|  | ||||
|         public override void OnGrab(string message) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         public override void OnDownload(string message, Series series) | ||||
|         { | ||||
|             UpdateIfEnabled(); | ||||
|         } | ||||
|  | ||||
|         public override void AfterRename(Series series) | ||||
|         { | ||||
|             UpdateIfEnabled(); | ||||
|         } | ||||
|  | ||||
|         private void UpdateIfEnabled() | ||||
|         { | ||||
|             if (Settings.UpdateLibrary) | ||||
|             { | ||||
|                 _plexProvider.UpdateLibrary(Settings.Host); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										25
									
								
								NzbDrone.Core/Notifications/Plex/PlexServerSettings.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								NzbDrone.Core/Notifications/Plex/PlexServerSettings.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using NzbDrone.Core.Annotations; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications.Plex | ||||
| { | ||||
|     public class PlexServerSettings : INotifcationSettings | ||||
|     { | ||||
|         [FieldDefinition(0, Label = "Host", HelpText = "Plex Server Host (IP or Hostname)")] | ||||
|         public String Host { get; set; } | ||||
|  | ||||
|         [FieldDefinition(1, Label = "Update Library", HelpText = "Update Library on Download/Rename")] | ||||
|         public Boolean UpdateLibrary { get; set; } | ||||
|  | ||||
|         public bool IsValid | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 return !string.IsNullOrWhiteSpace(Host); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										38
									
								
								NzbDrone.Core/Notifications/Prowl/Prowl.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								NzbDrone.Core/Notifications/Prowl/Prowl.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| using NzbDrone.Core.Tv; | ||||
| using Prowlin; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications.Prowl | ||||
| { | ||||
|     public class Prowl : NotificationWithSetting<ProwlSettings> | ||||
|     { | ||||
|         private readonly ProwlProvider _prowlProvider; | ||||
|  | ||||
|         public Prowl(ProwlProvider prowlProvider) | ||||
|         { | ||||
|             _prowlProvider = prowlProvider; | ||||
|         } | ||||
|  | ||||
|         public override string Name | ||||
|         { | ||||
|             get { return "Prowl"; } | ||||
|         } | ||||
|  | ||||
|         public override void OnGrab(string message) | ||||
|         { | ||||
|             const string title = "Episode Grabbed"; | ||||
|  | ||||
|             _prowlProvider.SendNotification(title, message, Settings.ApiKey, (NotificationPriority)Settings.Priority); | ||||
|         } | ||||
|  | ||||
|         public override void OnDownload(string message, Series series) | ||||
|         { | ||||
|             const string title = "Episode Downloaded"; | ||||
|  | ||||
|             _prowlProvider.SendNotification(title, message, Settings.ApiKey, (NotificationPriority)Settings.Priority); | ||||
|         } | ||||
|  | ||||
|         public override void AfterRename(Series series) | ||||
|         { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,9 +1,8 @@ | ||||
| using System; | ||||
| using System.Linq; | ||||
| using NLog; | ||||
| using Prowlin; | ||||
| 
 | ||||
| namespace NzbDrone.Core.Providers | ||||
| namespace NzbDrone.Core.Notifications.Prowl | ||||
| { | ||||
|     public class ProwlProvider | ||||
|     { | ||||
| @@ -34,11 +33,11 @@ namespace NzbDrone.Core.Providers | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         public virtual bool SendNotification(string title, string message, string apiKeys, NotificationPriority priority = NotificationPriority.Normal, string url = null) | ||||
|         public virtual bool SendNotification(string title, string message, string apiKey, NotificationPriority priority = NotificationPriority.Normal, string url = null) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 var notification = new Notification | ||||
|                 var notification = new Prowlin.Notification | ||||
|                                    { | ||||
|                                        Application = "NzbDrone", | ||||
|                                        Description = message, | ||||
| @@ -47,8 +46,7 @@ namespace NzbDrone.Core.Providers | ||||
|                                        Url = url | ||||
|                                    }; | ||||
| 
 | ||||
|                 foreach (var apiKey in apiKeys.Split(',')) | ||||
|                     notification.AddApiKey(apiKey.Trim()); | ||||
|                 notification.AddApiKey(apiKey.Trim()); | ||||
| 
 | ||||
|                 var client = new ProwlClient(); | ||||
| 
 | ||||
| @@ -63,7 +61,7 @@ namespace NzbDrone.Core.Providers | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 Logger.TraceException(ex.Message, ex); | ||||
|                 Logger.Warn("Invalid API Key(s): {0}", apiKeys); | ||||
|                 Logger.Warn("Invalid API Key: {0}", apiKey); | ||||
|             } | ||||
| 
 | ||||
|             return false; | ||||
							
								
								
									
										25
									
								
								NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								NzbDrone.Core/Notifications/Prowl/ProwlSettings.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using NzbDrone.Core.Annotations; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications.Prowl | ||||
| { | ||||
|     public class ProwlSettings : INotifcationSettings | ||||
|     { | ||||
|         [FieldDefinition(0, Label = "API Key", HelpText = "API Key for Prowl")] | ||||
|         public String ApiKey { get; set; } | ||||
|  | ||||
|         [FieldDefinition(1, Label = "Priority", HelpText = "Priority to send messages at")] | ||||
|         public Int32 Priority { get; set; } | ||||
|  | ||||
|         public bool IsValid | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 return !string.IsNullOrWhiteSpace(ApiKey) && Priority > 0; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,17 +1,15 @@ | ||||
| using System.Linq; | ||||
| using System; | ||||
| using System; | ||||
| using NLog; | ||||
| using NzbDrone.Core.Providers; | ||||
| using NzbDrone.Core.Tv; | ||||
| 
 | ||||
| namespace NzbDrone.Core.ExternalNotification | ||||
| namespace NzbDrone.Core.Notifications.Smtp | ||||
| { | ||||
|     public class Smtp : ExternalNotificationBase | ||||
|     public class Smtp : NotificationWithSetting<SmtpSettings> | ||||
|     { | ||||
|         private readonly SmtpProvider _smtpProvider; | ||||
| 
 | ||||
|         public Smtp(IExternalNotificationRepository repository, SmtpProvider smtpProvider, Logger logger) | ||||
|             : base(repository, logger) | ||||
|         public Smtp(SmtpProvider smtpProvider) | ||||
|         { | ||||
|             _smtpProvider = smtpProvider; | ||||
|         } | ||||
| @@ -21,19 +19,24 @@ namespace NzbDrone.Core.ExternalNotification | ||||
|             get { return "SMTP"; } | ||||
|         } | ||||
| 
 | ||||
|         protected override void OnGrab(string message) | ||||
|         public override void OnGrab(string message) | ||||
|         { | ||||
|             const string subject = "NzbDrone [TV] - Grabbed"; | ||||
|             var body = String.Format("{0} sent to SABnzbd queue.", message); | ||||
|             _smtpProvider.SendEmail(subject, body); | ||||
| 
 | ||||
|             _smtpProvider.SendEmail(Settings, subject, body); | ||||
|         } | ||||
| 
 | ||||
|         protected override void OnDownload(string message, Series series) | ||||
|         public override void OnDownload(string message, Series series) | ||||
|         { | ||||
|             const string subject = "NzbDrone [TV] - Downloaded"; | ||||
|             var body = String.Format("{0} Downloaded and sorted.", message); | ||||
| 
 | ||||
|             _smtpProvider.SendEmail(subject, body); | ||||
|             _smtpProvider.SendEmail(Settings, subject, body); | ||||
|         } | ||||
| 
 | ||||
|         public override void AfterRename(Series series) | ||||
|         { | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										66
									
								
								NzbDrone.Core/Notifications/Smtp/SmtpProvider.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								NzbDrone.Core/Notifications/Smtp/SmtpProvider.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| using System; | ||||
| using System.Net; | ||||
| using System.Net.Mail; | ||||
| using NLog; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications.Smtp | ||||
| { | ||||
|     public class SmtpProvider | ||||
|     { | ||||
|         private readonly Logger _logger; | ||||
|  | ||||
|         public SmtpProvider(Logger logger) | ||||
|         { | ||||
|             _logger = logger; | ||||
|         } | ||||
|  | ||||
| //        var subject = "NzbDrone SMTP Test Notification"; | ||||
| //        var body = "This is a test email from NzbDrone, if you received this message you properly configured your SMTP settings! (Now save them!)"; | ||||
|         public virtual void SendEmail(SmtpSettings settings, string subject, string body, bool htmlBody = false) | ||||
|         { | ||||
|             var email = new MailMessage(); | ||||
|             email.From = new MailAddress(settings.From); | ||||
|              | ||||
|             email.To.Add(settings.To); | ||||
|  | ||||
|             email.Subject = subject; | ||||
|             email.Body = body; | ||||
|             email.IsBodyHtml = htmlBody; | ||||
|  | ||||
|             NetworkCredential credentials = null; | ||||
|  | ||||
|             if (!String.IsNullOrWhiteSpace(settings.Username)) | ||||
|                 credentials = new NetworkCredential(settings.Username, settings.Password); | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 Send(email, settings.Server, settings.Port, settings.UseSsl, credentials); | ||||
|             } | ||||
|             catch(Exception ex) | ||||
|             { | ||||
|                 _logger.Error("Error sending email. Subject: {0}", email.Subject); | ||||
|                 _logger.TraceException(ex.Message, ex); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public virtual void Send(MailMessage email, string server, int port, bool ssl, NetworkCredential credentials) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 var smtp = new SmtpClient(server, port); | ||||
|  | ||||
|                 smtp.EnableSsl = ssl; | ||||
|  | ||||
|                 smtp.Credentials = credentials; | ||||
|  | ||||
|                 smtp.Send(email); | ||||
|             } | ||||
|  | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 _logger.ErrorException("There was an error sending an email.", ex); | ||||
|                 throw; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										40
									
								
								NzbDrone.Core/Notifications/Smtp/SmtpSettings.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								NzbDrone.Core/Notifications/Smtp/SmtpSettings.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using NzbDrone.Core.Annotations; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications.Smtp | ||||
| { | ||||
|     public class SmtpSettings : INotifcationSettings | ||||
|     { | ||||
|         [FieldDefinition(0, Label = "Server", HelpText = "Hostname or IP of SMTP server")] | ||||
|         public String Server { get; set; } | ||||
|  | ||||
|         [FieldDefinition(1, Label = "Port", HelpText = "SMTP Server Port")] | ||||
|         public Int32 Port { get; set; } | ||||
|  | ||||
|         [FieldDefinition(2, Label = "Use SSL", HelpText = "Does your SMTP server use SSL?")] | ||||
|         public Boolean UseSsl { get; set; } | ||||
|  | ||||
|         [FieldDefinition(3, Label = "Username", HelpText = "SMTP Server Username")] | ||||
|         public String Username { get; set; } | ||||
|  | ||||
|         [FieldDefinition(4, Label = "Password", HelpText = "SMTP Server Password")] | ||||
|         public String Password { get; set; } | ||||
|  | ||||
|         [FieldDefinition(5, Label = "From Address", HelpText = "Sender's address")] | ||||
|         public String From { get; set; } | ||||
|  | ||||
|         [FieldDefinition(6, Label = "To Address", HelpText = "Recipient address")] | ||||
|         public String To { get; set; } | ||||
|  | ||||
|         public bool IsValid | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 return !string.IsNullOrWhiteSpace(Server) && Port > 0 && !string.IsNullOrWhiteSpace(From) && !string.IsNullOrWhiteSpace(To); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,10 +1,8 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
| using NzbDrone.Common; | ||||
| using NzbDrone.Core.Model.Xbmc; | ||||
| 
 | ||||
| namespace NzbDrone.Core.Providers.Xbmc | ||||
| namespace NzbDrone.Core.Notifications.Xbmc | ||||
| { | ||||
|     public class EventClientProvider | ||||
|     { | ||||
| @@ -1,7 +1,7 @@ | ||||
| using System.Drawing; | ||||
| using System.IO; | ||||
| 
 | ||||
| namespace NzbDrone.Core.Providers.Xbmc | ||||
| namespace NzbDrone.Core.Notifications.Xbmc | ||||
| { | ||||
|     public class ResourceManager | ||||
|     { | ||||
							
								
								
									
										53
									
								
								NzbDrone.Core/Notifications/Xbmc/Xbmc.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								NzbDrone.Core/Notifications/Xbmc/Xbmc.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| using NLog; | ||||
| using NzbDrone.Core.Tv; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications.Xbmc | ||||
| { | ||||
|     public class Xbmc : NotificationWithSetting<XbmcSettings> | ||||
|     { | ||||
|         private readonly XbmcProvider _xbmcProvider; | ||||
|  | ||||
|         public Xbmc(XbmcProvider xbmcProvider, Logger logger) | ||||
|         { | ||||
|             _xbmcProvider = xbmcProvider; | ||||
|         } | ||||
|  | ||||
|         public override string Name | ||||
|         { | ||||
|             get { return "XBMC"; } | ||||
|         } | ||||
|  | ||||
|         public override void OnGrab(string message) | ||||
|         { | ||||
|             const string header = "NzbDrone [TV] - Grabbed"; | ||||
|  | ||||
|             _xbmcProvider.Notify(Settings, header, message); | ||||
|         } | ||||
|  | ||||
|         public override void OnDownload(string message, Series series) | ||||
|         { | ||||
|             const string header = "NzbDrone [TV] - Downloaded"; | ||||
|  | ||||
|             _xbmcProvider.Notify(Settings, header, message); | ||||
|             UpdateAndClean(series); | ||||
|         } | ||||
|  | ||||
|         public override void AfterRename(Series series) | ||||
|         { | ||||
|             UpdateAndClean(series); | ||||
|         } | ||||
|  | ||||
|         private void UpdateAndClean(Series series) | ||||
|         { | ||||
|             if (Settings.UpdateLibrary) | ||||
|             { | ||||
|                 _xbmcProvider.Update(Settings, series); | ||||
|             } | ||||
|  | ||||
|             if (Settings.CleanLibrary) | ||||
|             { | ||||
|                 _xbmcProvider.Clean(Settings); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -7,118 +7,105 @@ using Newtonsoft.Json; | ||||
| using Newtonsoft.Json.Linq; | ||||
| using NLog; | ||||
| using NzbDrone.Common; | ||||
| using NzbDrone.Core.Configuration; | ||||
| using NzbDrone.Core.Tv; | ||||
| using NzbDrone.Core.Model.Xbmc; | ||||
| using NzbDrone.Core.Providers.Xbmc; | ||||
| 
 | ||||
| namespace NzbDrone.Core.Providers | ||||
| namespace NzbDrone.Core.Notifications.Xbmc | ||||
| { | ||||
|     public class XbmcProvider | ||||
|     { | ||||
|         private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); | ||||
|         private readonly IConfigService _configService; | ||||
|         private readonly IHttpProvider _httpProvider; | ||||
|         private readonly EventClientProvider _eventClientProvider; | ||||
| 
 | ||||
|         public XbmcProvider(IConfigService configService, IHttpProvider httpProvider, EventClientProvider eventClientProvider) | ||||
|         public XbmcProvider(IHttpProvider httpProvider, EventClientProvider eventClientProvider) | ||||
|         { | ||||
|             _configService = configService; | ||||
|             _httpProvider = httpProvider; | ||||
|             _eventClientProvider = eventClientProvider; | ||||
|         } | ||||
| 
 | ||||
|         public XbmcProvider() | ||||
|         { | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         public virtual void Notify(string header, string message) | ||||
|         public virtual void Notify(XbmcSettings settings, string header, string message) | ||||
|         { | ||||
|             //Always use EventServer, until Json has real support for it | ||||
|             foreach (var host in _configService.XbmcHosts.Split(',')) | ||||
|             { | ||||
|                 Logger.Trace("Sending Notifcation to XBMC Host: {0}", host); | ||||
|                 _eventClientProvider.SendNotification(header, message, IconType.Jpeg, "NzbDrone.jpg", GetHostWithoutPort(host)); | ||||
|             } | ||||
|             var host = settings.Host; | ||||
|             Logger.Trace("Sending Notifcation to XBMC Host: {0}", host); | ||||
|             _eventClientProvider.SendNotification(header, message, IconType.Jpeg, "NzbDrone.jpg", host); | ||||
|         } | ||||
| 
 | ||||
|         public virtual void Update(Series series) | ||||
|         public virtual void Update(XbmcSettings settings, Series series) | ||||
|         { | ||||
|             //Use Json for Eden/Nightly or depricated HTTP for 10.x (Dharma) to get the proper path | ||||
|             //Perform update with EventServer (Json currently doesn't support updating a specific path only - July 2011) | ||||
| 
 | ||||
|             var username = _configService.XbmcUsername; | ||||
|             var password = _configService.XbmcPassword; | ||||
|             var username = settings.Username; | ||||
|             var password = settings.Password; | ||||
|             var host = settings.Host; | ||||
| 
 | ||||
|             foreach (var host in _configService.XbmcHosts.Split(',')) | ||||
|             Logger.Trace("Determining version of XBMC Host: {0}", host); | ||||
|             var version = GetJsonVersion(host, username, password); | ||||
| 
 | ||||
|             //If Dharma | ||||
|             if (version == new XbmcVersion(2)) | ||||
|             { | ||||
|                 Logger.Trace("Determining version of XBMC Host: {0}", host); | ||||
|                 var version = GetJsonVersion(host, username, password); | ||||
| 
 | ||||
|                 //If Dharma | ||||
|                 if (version == new XbmcVersion(2)) | ||||
|                 //Check for active player only when we should skip updates when playing | ||||
|                 if (!settings.AlwaysUpdate) | ||||
|                 { | ||||
|                     //Check for active player only when we should skip updates when playing | ||||
|                     if (!_configService.XbmcUpdateWhenPlaying) | ||||
|                     Logger.Trace("Determining if there are any active players on XBMC host: {0}", host); | ||||
|                     var activePlayers = GetActivePlayersDharma(host, username, password); | ||||
| 
 | ||||
|                     //If video is currently playing, then skip update | ||||
|                     if (activePlayers["video"]) | ||||
|                     { | ||||
|                         Logger.Trace("Determining if there are any active players on XBMC host: {0}", host); | ||||
|                         var activePlayers = GetActivePlayersDharma(host, username, password); | ||||
| 
 | ||||
|                         //If video is currently playing, then skip update | ||||
|                         if (activePlayers["video"]) | ||||
|                         { | ||||
|                             Logger.Debug("Video is currently playing, skipping library update"); | ||||
|                             continue; | ||||
|                         } | ||||
|                         Logger.Debug("Video is currently playing, skipping library update"); | ||||
|                         return; | ||||
|                     } | ||||
|                 } | ||||
|                 UpdateWithHttp(series, host, username, password); | ||||
|             } | ||||
| 
 | ||||
|                     UpdateWithHttp(series, host, username, password); | ||||
|             //If Eden or newer (attempting to make it future compatible) | ||||
|             else if (version == new XbmcVersion(3) || version == new XbmcVersion(4)) | ||||
|             { | ||||
|                 //Check for active player only when we should skip updates when playing | ||||
|                 if (!settings.AlwaysUpdate) | ||||
|                 { | ||||
|                     Logger.Trace("Determining if there are any active players on XBMC host: {0}", host); | ||||
|                     var activePlayers = GetActivePlayersEden(host, username, password); | ||||
| 
 | ||||
|                     //If video is currently playing, then skip update | ||||
|                     if (activePlayers.Any(a => a.Type.Equals("video"))) | ||||
|                     { | ||||
|                         Logger.Debug("Video is currently playing, skipping library update"); | ||||
|                         return; | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 //If Eden or newer (attempting to make it future compatible) | ||||
|                 else if (version == new XbmcVersion(3) || version == new XbmcVersion(4)) | ||||
|                 UpdateWithJsonExecBuiltIn(series, host, username, password); | ||||
|             } | ||||
| 
 | ||||
|             else if (version >= new XbmcVersion(5)) | ||||
|             { | ||||
|                 //Check for active player only when we should skip updates when playing | ||||
|                 if (!settings.AlwaysUpdate) | ||||
|                 { | ||||
|                     //Check for active player only when we should skip updates when playing | ||||
|                     if (!_configService.XbmcUpdateWhenPlaying) | ||||
|                     Logger.Trace("Determining if there are any active players on XBMC host: {0}", host); | ||||
|                     var activePlayers = GetActivePlayersEden(host, username, password); | ||||
| 
 | ||||
|                     //If video is currently playing, then skip update | ||||
|                     if (activePlayers.Any(a => a.Type.Equals("video"))) | ||||
|                     { | ||||
|                         Logger.Trace("Determining if there are any active players on XBMC host: {0}", host); | ||||
|                         var activePlayers = GetActivePlayersEden(host, username, password); | ||||
| 
 | ||||
|                         //If video is currently playing, then skip update | ||||
|                         if (activePlayers.Any(a => a.Type.Equals("video"))) | ||||
|                         { | ||||
|                             Logger.Debug("Video is currently playing, skipping library update"); | ||||
|                             continue; | ||||
|                         } | ||||
|                         Logger.Debug("Video is currently playing, skipping library update"); | ||||
|                         return; | ||||
|                     } | ||||
| 
 | ||||
|                     UpdateWithJsonExecBuiltIn(series, host, username, password); | ||||
|                 } | ||||
| 
 | ||||
|                 else if (version >= new XbmcVersion(5)) | ||||
|                 { | ||||
|                     //Check for active player only when we should skip updates when playing | ||||
|                     if (!_configService.XbmcUpdateWhenPlaying) | ||||
|                     { | ||||
|                         Logger.Trace("Determining if there are any active players on XBMC host: {0}", host); | ||||
|                         var activePlayers = GetActivePlayersEden(host, username, password); | ||||
| 
 | ||||
|                         //If video is currently playing, then skip update | ||||
|                         if (activePlayers.Any(a => a.Type.Equals("video"))) | ||||
|                         { | ||||
|                             Logger.Debug("Video is currently playing, skipping library update"); | ||||
|                             continue; | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     UpdateWithJsonVideoLibraryScan(series, host, username, password); | ||||
|                 } | ||||
|                 UpdateWithJsonVideoLibraryScan(series, host, username, password); | ||||
|             } | ||||
| 
 | ||||
|                 //Log Version zero if check failed | ||||
|                 else | ||||
|                     Logger.Trace("Unknown version: [{0}], skipping.", version); | ||||
|             } | ||||
|             else | ||||
|                 Logger.Trace("Unknown version: [{0}], skipping.", version); | ||||
|          | ||||
|         } | ||||
| 
 | ||||
|         public virtual bool UpdateWithJsonExecBuiltIn(Series series, string host, string username, string password) | ||||
| @@ -245,16 +232,14 @@ namespace NzbDrone.Core.Providers | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         public virtual void Clean() | ||||
|         public virtual void Clean(XbmcSettings settings) | ||||
|         { | ||||
|             //Use EventServer, once Dharma is extinct use Json? | ||||
| 
 | ||||
|             foreach (var host in _configService.XbmcHosts.Split(',')) | ||||
|             { | ||||
|                 Logger.Trace("Sending DB Clean Request to XBMC Host: {0}", host); | ||||
|                 var command = "ExecBuiltIn(CleanLibrary(video))"; | ||||
|                 _eventClientProvider.SendAction(GetHostWithoutPort(host), ActionType.ExecBuiltin, command); | ||||
|             } | ||||
|             var host = settings.Host; | ||||
|             Logger.Trace("Sending DB Clean Request to XBMC Host: {0}", host); | ||||
|             var command = "ExecBuiltIn(CleanLibrary(video))"; | ||||
|             _eventClientProvider.SendAction(host, ActionType.ExecBuiltin, command); | ||||
|         } | ||||
| 
 | ||||
|         public virtual string SendCommand(string host, string command, string username, string password) | ||||
| @@ -451,7 +436,7 @@ namespace NzbDrone.Core.Providers | ||||
|             foreach (var host in hosts.Split(',')) | ||||
|             { | ||||
|                 Logger.Trace("Sending Test Notifcation to XBMC Host: {0}", host); | ||||
|                 _eventClientProvider.SendNotification("Test Notification", "Success! Notifications are setup correctly", IconType.Jpeg, "NzbDrone.jpg", GetHostWithoutPort(host)); | ||||
|                 _eventClientProvider.SendNotification("Test Notification", "Success! Notifications are setup correctly", IconType.Jpeg, "NzbDrone.jpg", host); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| @@ -465,10 +450,5 @@ namespace NzbDrone.Core.Providers | ||||
|                     throw new Exception("Failed to get JSON version in test"); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private string GetHostWithoutPort(string address) | ||||
|         { | ||||
|             return address.Split(':')[0]; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										40
									
								
								NzbDrone.Core/Notifications/Xbmc/XbmcSettings.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								NzbDrone.Core/Notifications/Xbmc/XbmcSettings.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using NzbDrone.Core.Annotations; | ||||
|  | ||||
| namespace NzbDrone.Core.Notifications.Xbmc | ||||
| { | ||||
|     public class XbmcSettings : INotifcationSettings | ||||
|     { | ||||
|         [FieldDefinition(0, Label = "Host", HelpText = "XBMC Hostnname or IP")] | ||||
|         public String Host { get; set; } | ||||
|  | ||||
|         [FieldDefinition(1, Label = "Port", HelpText = "Webserver port")] | ||||
|         public Int32 Port { get; set; } | ||||
|  | ||||
|         [FieldDefinition(2, Label = "Username", HelpText = "Webserver Username")] | ||||
|         public String Username { get; set; } | ||||
|  | ||||
|         [FieldDefinition(3, Label = "Password", HelpText = "Webserver Password ")] | ||||
|         public String Password { get; set; } | ||||
|  | ||||
|         [FieldDefinition(4, Label = "Update Library", HelpText = "Update Library on Download & Rename?")] | ||||
|         public Boolean UpdateLibrary { get; set; } | ||||
|  | ||||
|         [FieldDefinition(5, Label = "Update Library", HelpText = "Clean Library after update?")] | ||||
|         public Boolean CleanLibrary { get; set; } | ||||
|  | ||||
|         [FieldDefinition(6, Label = "Always Update", HelpText = "Update Library even when a video is playing?")] | ||||
|         public Boolean AlwaysUpdate { get; set; } | ||||
|  | ||||
|         public bool IsValid | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 return !string.IsNullOrWhiteSpace(Host) && Port > 0; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -254,7 +254,12 @@ | ||||
|     <Compile Include="MediaFiles\Events\EpisodeDownloadedEvent.cs" /> | ||||
|     <Compile Include="Download\EpisodeGrabbedEvent.cs" /> | ||||
|     <Compile Include="Download\SeriesRenamedEvent.cs" /> | ||||
|     <Compile Include="ExternalNotification\ExternalNotificationRepository.cs" /> | ||||
|     <Compile Include="Notifications\Growl\GrowlSettings.cs" /> | ||||
|     <Compile Include="Notifications\NotificationSettingsProvider.cs" /> | ||||
|     <Compile Include="Notifications\INotification.cs" /> | ||||
|     <Compile Include="Notifications\Notification.cs" /> | ||||
|     <Compile Include="Notifications\NotificationService.cs" /> | ||||
|     <Compile Include="Notifications\NotificationRepository.cs" /> | ||||
|     <Compile Include="Fluent.cs" /> | ||||
|     <Compile Include="Helpers\SortHelper.cs" /> | ||||
|     <Compile Include="History\HistoryRepository.cs" /> | ||||
| @@ -282,7 +287,7 @@ | ||||
|     <Compile Include="Indexers\Nzbx\NzbxParser.cs" /> | ||||
|     <Compile Include="Indexers\Omgwtfnzbs\Omgwtfnzbs.cs" /> | ||||
|     <Compile Include="Indexers\Omgwtfnzbs\OmgwtfnzbsParser.cs" /> | ||||
|     <Compile Include="Indexers\IIndexerSettings.cs" /> | ||||
|     <Compile Include="Indexers\IIndexerSetting.cs" /> | ||||
|     <Compile Include="Indexers\NzbsRUs\NzbsrusSettings.cs" /> | ||||
|     <Compile Include="Indexers\Omgwtfnzbs\OmgwtfnzbsSettings.cs" /> | ||||
|     <Compile Include="Indexers\Wombles\Wombles.cs" /> | ||||
| @@ -307,6 +312,14 @@ | ||||
|     <Compile Include="MetadataSource\Trakt\Images.cs" /> | ||||
|     <Compile Include="MetadataSource\Trakt\Season.cs" /> | ||||
|     <Compile Include="MetadataSource\Trakt\Show.cs" /> | ||||
|     <Compile Include="Notifications\INotifcationSettings.cs" /> | ||||
|     <Compile Include="Notifications\NotificationWithSetting.cs" /> | ||||
|     <Compile Include="Notifications\Plex\PlexServer.cs" /> | ||||
|     <Compile Include="Notifications\Plex\PlexClientSettings.cs" /> | ||||
|     <Compile Include="Notifications\Plex\PlexServerSettings.cs" /> | ||||
|     <Compile Include="Notifications\Prowl\ProwlSettings.cs" /> | ||||
|     <Compile Include="Notifications\Smtp\SmtpSettings.cs" /> | ||||
|     <Compile Include="Notifications\Xbmc\XbmcSettings.cs" /> | ||||
|     <Compile Include="Organizer\EpisodeSortingType.cs" /> | ||||
|     <Compile Include="Organizer\FileNameBuilder.cs" /> | ||||
|     <Compile Include="Instrumentation\LogService.cs" /> | ||||
| @@ -417,25 +430,25 @@ | ||||
|     <Compile Include="Tv\EpisodeRepository.cs"> | ||||
|       <SubType>Code</SubType> | ||||
|     </Compile> | ||||
|     <Compile Include="ExternalNotification\ExternalNotificationBase.cs"> | ||||
|     <Compile Include="Notifications\NotificationBase.cs"> | ||||
|       <SubType>Code</SubType> | ||||
|     </Compile> | ||||
|     <Compile Include="ExternalNotification\Growl.cs"> | ||||
|     <Compile Include="Notifications\Growl\Growl.cs"> | ||||
|       <SubType>Code</SubType> | ||||
|     </Compile> | ||||
|     <Compile Include="ExternalNotification\Plex.cs"> | ||||
|     <Compile Include="Notifications\Plex\PlexClient.cs"> | ||||
|       <SubType>Code</SubType> | ||||
|     </Compile> | ||||
|     <Compile Include="ExternalNotification\Prowl.cs"> | ||||
|     <Compile Include="Notifications\Prowl\Prowl.cs"> | ||||
|       <SubType>Code</SubType> | ||||
|     </Compile> | ||||
|     <Compile Include="ExternalNotification\Smtp.cs"> | ||||
|     <Compile Include="Notifications\Smtp\Smtp.cs"> | ||||
|       <SubType>Code</SubType> | ||||
|     </Compile> | ||||
|     <Compile Include="ExternalNotification\Xbmc.cs"> | ||||
|     <Compile Include="Notifications\Xbmc\Xbmc.cs"> | ||||
|       <SubType>Code</SubType> | ||||
|     </Compile> | ||||
|     <Compile Include="ExternalNotification\GrowlProvider.cs"> | ||||
|     <Compile Include="Notifications\Growl\GrowlProvider.cs"> | ||||
|       <SubType>Code</SubType> | ||||
|     </Compile> | ||||
|     <Compile Include="History\HistoryService.cs"> | ||||
| @@ -459,11 +472,11 @@ | ||||
|     <Compile Include="Providers\NotificationProvider.cs"> | ||||
|       <SubType>Code</SubType> | ||||
|     </Compile> | ||||
|     <Compile Include="ExternalNotification\PlexProvider.cs" /> | ||||
|     <Compile Include="Notifications\Plex\PlexProvider.cs" /> | ||||
|     <Compile Include="MediaFiles\DownloadedEpisodesImportService.cs"> | ||||
|       <SubType>Code</SubType> | ||||
|     </Compile> | ||||
|     <Compile Include="Providers\ProwlProvider.cs"> | ||||
|     <Compile Include="Notifications\Prowl\ProwlProvider.cs"> | ||||
|       <SubType>Code</SubType> | ||||
|     </Compile> | ||||
|     <Compile Include="Qualities\QualityProfileService.cs"> | ||||
| @@ -479,19 +492,19 @@ | ||||
|     <Compile Include="Tv\SeriesService.cs"> | ||||
|       <SubType>Code</SubType> | ||||
|     </Compile> | ||||
|     <Compile Include="Providers\SmtpProvider.cs"> | ||||
|     <Compile Include="Notifications\Smtp\SmtpProvider.cs"> | ||||
|       <SubType>Code</SubType> | ||||
|     </Compile> | ||||
|     <Compile Include="Providers\XbmcProvider.cs"> | ||||
|     <Compile Include="Notifications\Xbmc\XbmcProvider.cs"> | ||||
|       <SubType>Code</SubType> | ||||
|     </Compile> | ||||
|     <Compile Include="Providers\Xbmc\EventClientProvider.cs"> | ||||
|     <Compile Include="Notifications\Xbmc\EventClientProvider.cs"> | ||||
|       <SubType>Code</SubType> | ||||
|     </Compile> | ||||
|     <Compile Include="Providers\Xbmc\ResourceManager.cs"> | ||||
|     <Compile Include="Notifications\Xbmc\ResourceManager.cs"> | ||||
|       <SubType>Code</SubType> | ||||
|     </Compile> | ||||
|     <Compile Include="ExternalNotification\ExternalNotificationDefinition.cs" /> | ||||
|     <Compile Include="Notifications\NotificationDefinition.cs" /> | ||||
|     <Compile Include="Download\Clients\Sabnzbd\SabPriorityType.cs" /> | ||||
|     <Compile Include="MediaFiles\EpisodeFile.cs" /> | ||||
|     <Compile Include="Model\Notification\ProgressNotificationStatus.cs" /> | ||||
|   | ||||
| @@ -1,111 +0,0 @@ | ||||
| using System; | ||||
| using System.Linq; | ||||
| using System.Net; | ||||
| using System.Net.Mail; | ||||
| using NLog; | ||||
| using NzbDrone.Core.Configuration; | ||||
|  | ||||
| namespace NzbDrone.Core.Providers | ||||
| { | ||||
|     public class SmtpProvider | ||||
|     { | ||||
|         private readonly IConfigService _configService; | ||||
|         private readonly Logger _logger; | ||||
|  | ||||
|         public SmtpProvider(IConfigService configService, Logger logger) | ||||
|         { | ||||
|             _configService = configService; | ||||
|             _logger = logger; | ||||
|         } | ||||
|  | ||||
|         public virtual void SendEmail(string subject, string body, bool htmlBody = false) | ||||
|         { | ||||
|             var email = new MailMessage(); | ||||
|             email.From = new MailAddress(_configService.SmtpFromAddress); | ||||
|              | ||||
|             foreach (var toAddress in _configService.SmtpToAddresses.Split(',')) | ||||
|             { | ||||
|                 email.To.Add(toAddress.Trim()); | ||||
|             } | ||||
|  | ||||
|             email.Subject = subject; | ||||
|             email.Body = body; | ||||
|             email.IsBodyHtml = htmlBody; | ||||
|              | ||||
|             var username = _configService.SmtpUsername; | ||||
|             var password = _configService.SmtpPassword; | ||||
|  | ||||
|             NetworkCredential credentials = null; | ||||
|  | ||||
|             if (!String.IsNullOrWhiteSpace(username)) | ||||
|                 credentials = new NetworkCredential(username, password); | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 Send(email, _configService.SmtpServer, _configService.SmtpPort, _configService.SmtpUseSsl, credentials); | ||||
|             } | ||||
|             catch(Exception ex) | ||||
|             { | ||||
|                 _logger.Error("Error sending email. Subject: {0}", email.Subject); | ||||
|                 _logger.TraceException(ex.Message, ex); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public virtual bool SendTestEmail(string server, int port, bool ssl, string username, string password, string fromAddress, string toAddresses) | ||||
|         { | ||||
|             var subject = "NzbDrone SMTP Test Notification"; | ||||
|             var body = "This is a test email from NzbDrone, if you received this message you properly configured your SMTP settings! (Now save them!)"; | ||||
|  | ||||
|             var email = new MailMessage(); | ||||
|  | ||||
|             email.From = new MailAddress(fromAddress); | ||||
|  | ||||
|             foreach (var toAddress in toAddresses.Split(',')) | ||||
|             { | ||||
|                 email.To.Add(toAddress.Trim()); | ||||
|             } | ||||
|  | ||||
|             email.Subject = subject; | ||||
|  | ||||
|             email.Body = body; | ||||
|  | ||||
|             email.IsBodyHtml = false; | ||||
|  | ||||
|             NetworkCredential credentials = null; | ||||
|  | ||||
|             if (!String.IsNullOrWhiteSpace(username)) | ||||
|                 credentials = new NetworkCredential(username, password); | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 Send(email, server, port, ssl, credentials); | ||||
|             } | ||||
|             catch(Exception ex) | ||||
|             { | ||||
|                 _logger.TraceException("Failed to send test email", ex); | ||||
|                 return false; | ||||
|             } | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         public virtual void Send(MailMessage email, string server, int port, bool ssl, NetworkCredential credentials) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 var smtp = new SmtpClient(server, port); | ||||
|  | ||||
|                 smtp.EnableSsl = ssl; | ||||
|  | ||||
|                 smtp.Credentials = credentials; | ||||
|  | ||||
|                 smtp.Send(email); | ||||
|             } | ||||
|  | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 _logger.ErrorException("There was an error sending an email.", ex); | ||||
|                 throw; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -6,7 +6,7 @@ using NzbDrone.Api.SignalR; | ||||
| using NzbDrone.Common; | ||||
| using NzbDrone.Common.Composition; | ||||
| using NzbDrone.Core.Datastore; | ||||
| using NzbDrone.Core.ExternalNotification; | ||||
| using NzbDrone.Core.Notifications; | ||||
| using NzbDrone.Core.Organizer; | ||||
| using NzbDrone.Core.RootFolders; | ||||
|  | ||||
| @@ -25,7 +25,7 @@ namespace NzbDrone | ||||
|         private MainAppContainerBuilder() | ||||
|             : base("NzbDrone", "NzbDrone.Common", "NzbDrone.Core", "NzbDrone.Api") | ||||
|         { | ||||
|             AutoRegisterImplementations<ExternalNotificationBase>(); | ||||
|             AutoRegisterImplementations<NotificationBase>(); | ||||
|             AutoRegisterImplementations<NzbDronePersistentConnection>(); | ||||
|  | ||||
|             Container.Register(typeof(IBasicRepository<RootFolder>), typeof(BasicRepository<RootFolder>)); | ||||
|   | ||||
							
								
								
									
										19
									
								
								UI/Form/CheckboxTemplate.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								UI/Form/CheckboxTemplate.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| <div class="control-group"> | ||||
|     <label class="control-label">{{label}}</label> | ||||
|  | ||||
|     <div class="controls"> | ||||
|         <label class="checkbox toggle well"> | ||||
|             <input type="checkbox" name="fields.{{order}}.value"/> | ||||
|             <p> | ||||
|                 <span>On</span> | ||||
|                 <span>Off</span> | ||||
|             </p> | ||||
|  | ||||
|             <div class="btn btn-primary slide-button"></div> | ||||
|         </label> | ||||
|  | ||||
|             <span class="help-inline-checkbox"> | ||||
|                 <i class="icon-question-sign" title="{{helpText}}"></i> | ||||
|             </span> | ||||
|     </div> | ||||
| </div> | ||||
							
								
								
									
										10
									
								
								UI/Form/TextboxTemplate.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								UI/Form/TextboxTemplate.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| <div class="control-group"> | ||||
|     <label class="control-label">{{label}}</label> | ||||
|  | ||||
|     <div class="controls"> | ||||
|         <input type="text" name="fields.{{order}}.value"/> | ||||
|         <span class="help-inline"> | ||||
|             <i class="icon-question-sign" title="{{helpText}}"></i> | ||||
|         </span> | ||||
|     </div> | ||||
| </div> | ||||
| @@ -7,6 +7,14 @@ Handlebars.registerHelper('partial', function (templateName) { | ||||
|     return new Handlebars.SafeString(templateFunction(this)); | ||||
| }); | ||||
|  | ||||
| Handlebars.registerHelper('formField', function () { | ||||
|     if (!this.type) { | ||||
|         return Handlebars.helpers.partial.apply(this, ['Form/TextboxTemplate']); | ||||
|     } | ||||
|  | ||||
|     return Handlebars.helpers.partial.apply(this, ['Form/TextboxTemplate']); | ||||
| }); | ||||
|  | ||||
| Handlebars.registerHelper("debug", function(optionalValue) { | ||||
|     console.log("Current Context"); | ||||
|     console.log("===================="); | ||||
|   | ||||
| @@ -22,15 +22,6 @@ | ||||
|     </div> | ||||
|  | ||||
|     {{#each fields}} | ||||
|         <div class="control-group"> | ||||
|             <label class="control-label">{{label}}</label> | ||||
|  | ||||
|             <div class="controls"> | ||||
|                 <input type="text" name="fields.{{@index}}.value"/> | ||||
|             <span class="help-inline"> | ||||
|                 <i class="icon-question-sign" title="{{helpText}}"></i> | ||||
|             </span> | ||||
|             </div> | ||||
|         </div> | ||||
|         {{formField}} | ||||
|     {{/each}} | ||||
| </fieldset> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user