mirror of
https://github.com/Sonarr/Sonarr.git
synced 2025-02-20 12:43:28 +02:00
Notifications wired up server sided
This commit is contained in:
parent
3f44339381
commit
e9bf78a97d
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user