Added Growl (Not yet visible on the GUI).

This commit is contained in:
Mark McDowall 2011-11-01 20:08:53 -07:00
parent dd7dcf4db8
commit 3fe1e80ccb
16 changed files with 327 additions and 2 deletions

View File

@ -80,6 +80,7 @@
<Compile Include="JobTests\BacklogSearchJobTest.cs" /> <Compile Include="JobTests\BacklogSearchJobTest.cs" />
<Compile Include="JobTests\BannerDownloadJobTest.cs" /> <Compile Include="JobTests\BannerDownloadJobTest.cs" />
<Compile Include="ProviderTests\ConfigFileProviderTest.cs" /> <Compile Include="ProviderTests\ConfigFileProviderTest.cs" />
<Compile Include="ProviderTests\GrowlProviderTest.cs" />
<Compile Include="ProviderTests\DiskProviderTests\ExtractArchiveFixture.cs" /> <Compile Include="ProviderTests\DiskProviderTests\ExtractArchiveFixture.cs" />
<Compile Include="ProviderTests\PostDownloadProviderTests\PostDownloadProviderFixture.cs" /> <Compile Include="ProviderTests\PostDownloadProviderTests\PostDownloadProviderFixture.cs" />
<Compile Include="JobTests\SearchJobTest.cs" /> <Compile Include="JobTests\SearchJobTest.cs" />

View File

@ -0,0 +1,73 @@
using System;
using AutoMoq;
using FizzWare.NBuilder;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Repository;
using NzbDrone.Core.Repository.Quality;
using NzbDrone.Core.Test.Framework;
// ReSharper disable InconsistentNaming
namespace NzbDrone.Core.Test.ProviderTests
{
[Explicit]
[TestFixture]
public class GrowlProviderTest : TestBase
{
[Test]
public void Register_should_add_new_application_to_local_growl_instance()
{
//Setup
var mocker = new AutoMoqer(MockBehavior.Strict);
//Act
mocker.Resolve<GrowlProvider>().Register("localhost", 23053, "");
//Assert
mocker.VerifyAllMocks();
}
[Test]
public void TestNotification_should_send_a_message_to_local_growl_instance()
{
//Setup
var mocker = new AutoMoqer(MockBehavior.Strict);
//Act
mocker.Resolve<GrowlProvider>().TestNotification("localhost", 23053, "");
//Assert
mocker.VerifyAllMocks();
}
[Test]
public void OnGrab_should_send_a_message_to_local_growl_instance()
{
//Setup
var mocker = new AutoMoqer(MockBehavior.Strict);
//Act
mocker.Resolve<GrowlProvider>().SendNotification("Episode Grabbed", "Series Title - 1x05 - Episode Title", "GRAB", "localhost", 23053, "");
//Assert
mocker.VerifyAllMocks();
}
[Test]
public void OnDownload_should_send_a_message_to_local_growl_instance()
{
//Setup
var mocker = new AutoMoqer(MockBehavior.Strict);
//Act
mocker.Resolve<GrowlProvider>().SendNotification("Episode Downloaded", "Series Title - 1x05 - Episode Title", "DOWNLOAD", "localhost", 23053, "");
//Assert
mocker.VerifyAllMocks();
}
}
}

View File

@ -35,7 +35,6 @@ namespace NzbDrone.Core
} }
} }
public static void InitializeApp() public static void InitializeApp()
{ {
BindKernel(); BindKernel();
@ -107,6 +106,7 @@ namespace NzbDrone.Core
_kernel.Bind<ExternalNotificationBase>().To<Xbmc>(); _kernel.Bind<ExternalNotificationBase>().To<Xbmc>();
_kernel.Bind<ExternalNotificationBase>().To<Smtp>(); _kernel.Bind<ExternalNotificationBase>().To<Smtp>();
_kernel.Bind<ExternalNotificationBase>().To<Twitter>(); _kernel.Bind<ExternalNotificationBase>().To<Twitter>();
_kernel.Bind<ExternalNotificationBase>().To<Growl>();
var notifiers = _kernel.GetAll<ExternalNotificationBase>(); var notifiers = _kernel.GetAll<ExternalNotificationBase>();
_kernel.Get<ExternalNotificationProvider>().InitializeNotifiers(notifiers.ToList()); _kernel.Get<ExternalNotificationProvider>().InitializeNotifiers(notifiers.ToList());

View File

@ -125,6 +125,12 @@
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\Libraries\Exceptioneer.WindowsFormsClient.dll</HintPath> <HintPath>..\Libraries\Exceptioneer.WindowsFormsClient.dll</HintPath>
</Reference> </Reference>
<Reference Include="Growl.Connector">
<HintPath>..\packages\Growl.0.6\lib\Growl.Connector.dll</HintPath>
</Reference>
<Reference Include="Growl.CoreLibrary">
<HintPath>..\packages\Growl.0.6\lib\Growl.CoreLibrary.dll</HintPath>
</Reference>
<Reference Include="Ionic.Zip"> <Reference Include="Ionic.Zip">
<HintPath>..\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll</HintPath> <HintPath>..\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll</HintPath>
</Reference> </Reference>
@ -221,8 +227,10 @@
<Compile Include="Providers\Converting\HandbrakeProvider.cs" /> <Compile Include="Providers\Converting\HandbrakeProvider.cs" />
<Compile Include="Providers\Core\ConfigFileProvider.cs" /> <Compile Include="Providers\Core\ConfigFileProvider.cs" />
<Compile Include="Providers\Core\UdpProvider.cs" /> <Compile Include="Providers\Core\UdpProvider.cs" />
<Compile Include="Providers\ExternalNotification\Growl.cs" />
<Compile Include="Providers\ExternalNotification\Twitter.cs" /> <Compile Include="Providers\ExternalNotification\Twitter.cs" />
<Compile Include="Providers\ExternalNotification\Smtp.cs" /> <Compile Include="Providers\ExternalNotification\Smtp.cs" />
<Compile Include="Providers\GrowlProvider.cs" />
<Compile Include="Providers\Jobs\BacklogSearchJob.cs" /> <Compile Include="Providers\Jobs\BacklogSearchJob.cs" />
<Compile Include="Providers\Jobs\BannerDownloadJob.cs" /> <Compile Include="Providers\Jobs\BannerDownloadJob.cs" />
<Compile Include="Providers\Jobs\ConvertEpisodeJob.cs" /> <Compile Include="Providers\Jobs\ConvertEpisodeJob.cs" />
@ -352,6 +360,10 @@
<Name>NzbDrone.Common</Name> <Name>NzbDrone.Common</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="NzbDrone.ico" />
<Content Include="license.txt" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup> <PropertyGroup>
<PostBuildEvent> <PostBuildEvent>

BIN
NzbDrone.Core/NzbDrone.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View File

@ -338,6 +338,32 @@ namespace NzbDrone.Core.Providers.Core
set { SetValue("TwitterAccessTokenSecret", value); } set { SetValue("TwitterAccessTokenSecret", value); }
} }
public virtual Boolean GrowlNotifyOnGrab
{
get { return GetValueBoolean("GrowlNotifyOnGrab"); }
set { SetValue("GrowlNotifyOnGrab", value); }
}
public virtual Boolean GrowlNotifyOnDownload
{
get { return GetValueBoolean("GrowlNotifyOnDownload"); }
set { SetValue("GrowlNotifyOnDownload", value); }
}
public virtual string GrowlHost
{
get { return GetValue("GrowlHost", String.Empty); }
set { SetValue("GrowlHost", value); }
}
public virtual string GrowlPassword
{
get { return GetValue("GrowlPassword", String.Empty); }
set { SetValue("GrowlPassword", value); }
}
private string GetValue(string key) private string GetValue(string key)
{ {
return GetValue(key, String.Empty); return GetValue(key, String.Empty);

View File

@ -0,0 +1,78 @@
using System;
using NLog;
using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Repository;
namespace NzbDrone.Core.Providers.ExternalNotification
{
public class Growl : ExternalNotificationBase
{
private readonly GrowlProvider _growlProvider;
private readonly Logger Logger = LogManager.GetCurrentClassLogger();
public Growl(ConfigProvider configProvider, GrowlProvider growlProvider)
: base(configProvider)
{
_growlProvider = growlProvider;
}
public override string Name
{
get { return "Growl"; }
}
public override void OnGrab(string message)
{
try
{
if(_configProvider.GrowlNotifyOnGrab)
{
_logger.Trace("Sending Notification to Growl");
const string title = "Episode Grabbed";
var growlHost = _configProvider.GrowlHost.Split(':');
var host = growlHost[0];
var port = Convert.ToInt32(growlHost[1]);
_growlProvider.SendNotification(title, message, host, "GRAB", port, _configProvider.GrowlPassword);
}
}
catch (Exception ex)
{
Logger.WarnException(ex.Message, ex);
throw;
}
}
public override void OnDownload(string message, Series series)
{
try
{
if (_configProvider.GrowlNotifyOnDownload)
{
_logger.Trace("Sending Notification to Growl");
const string title = "Episode Downloaded";
var growlHost = _configProvider.GrowlHost.Split(':');
var host = growlHost[0];
var port = Convert.ToInt32(growlHost[1]);
_growlProvider.SendNotification(title, message, host, "DOWNLOAD", port, _configProvider.GrowlPassword);
}
}
catch (Exception ex)
{
Logger.WarnException(ex.Message, ex);
throw;
}
}
public override void OnRename(string message, Series series)
{
}
}
}

View File

@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Growl.Connector;
using NLog;
namespace NzbDrone.Core.Providers
{
public class GrowlProvider
{
private readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly Application _growlApplication = new Application("NzbDrone");
private GrowlConnector _growlConnector;
private List<NotificationType> _notificationTypes;
public GrowlProvider()
{
_notificationTypes = GetNotificationTypes();
_growlApplication.Icon = "https://github.com/NzbDrone/NzbDrone/raw/master/NzbDrone.Core/NzbDrone.jpg";
}
public virtual void Register(string hostname, int port, string password)
{
Logger.Trace("Registering NzbDrone with Growl host: {0}:{1}", hostname, port);
_growlConnector = new GrowlConnector(password, hostname, port);
_growlConnector.Register(_growlApplication, _notificationTypes.ToArray());
}
public virtual void TestNotification(string hostname, int port, string password)
{
const string title = "Test Notification";
const string message = "This is a test message from NzbDrone";
SendNotification(title, message, "TEST", hostname, port, password);
}
public virtual void SendNotification(string title, string message, string notificationTypeName, string hostname, int port, string password)
{
var notificationType = _notificationTypes.Single(n => n.Name == notificationTypeName);
var notification = new Notification("NzbDrone", notificationType.Name, DateTime.Now.Ticks.ToString(), title, message);
_growlConnector = new GrowlConnector(password, hostname, port);
Logger.Trace("Sending Notification to: {0}:{1}", hostname, port);
_growlConnector.Notify(notification);
}
private List<NotificationType> GetNotificationTypes()
{
var notificationTypes = new List<NotificationType>();
notificationTypes.Add(new NotificationType("TEST", "Test"));
notificationTypes.Add(new NotificationType("GRAB", "Episode Grabbed"));
notificationTypes.Add(new NotificationType("DOWNLOAD", "Episode Complete"));
return notificationTypes;
}
}
}

View File

@ -37,7 +37,7 @@
public static System.Drawing.Bitmap GetIconAsImage(string Name) public static System.Drawing.Bitmap GetIconAsImage(string Name)
{ {
System.IO.Stream stm = typeof(ResourceManager).Assembly.GetManifestResourceStream(string.Format("{0}.Icons.{1}.ico", typeof(ResourceManager).Namespace, Name)); System.IO.Stream stm = typeof(ResourceManager).Assembly.GetManifestResourceStream(string.Format("NzbDrone.Core.{0}.ico", Name));
if (stm == null) return null; if (stm == null) return null;
System.Drawing.Bitmap bmp; System.Drawing.Bitmap bmp;
using (System.Drawing.Icon ico = new System.Drawing.Icon(stm)) using (System.Drawing.Icon ico = new System.Drawing.Icon(stm))

25
NzbDrone.Core/license.txt Normal file
View File

@ -0,0 +1,25 @@
Growl.NET GNTP Connector Library
-----------------------------------------------
Copyright (c) 2008 - Growl for Windows
All rights reserved
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="DotNetZip" version="1.9.1.8" /> <package id="DotNetZip" version="1.9.1.8" />
<package id="Growl" version="0.6" />
<package id="MiniProfiler" version="1.9" /> <package id="MiniProfiler" version="1.9" />
<package id="Newtonsoft.Json" version="3.5.8" /> <package id="Newtonsoft.Json" version="3.5.8" />
<package id="Ninject" version="2.2.1.4" /> <package id="Ninject" version="2.2.1.4" />

BIN
packages/Growl.0.6/Growl.0.6.nupkg vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Growl.Connector;
using Growl.CoreLibrary;
namespace $rootnamespace$
{
class GrowlHelper
{
public static void simpleGrowl(string title, string message = "")
{
GrowlConnector simpleGrowl = new GrowlConnector();
Growl.Connector.Application thisApp = new Growl.Connector.Application(System.Windows.Forms.Application.ProductName);
NotificationType simpleGrowlType = new NotificationType("SIMPLEGROWL");
simpleGrowl.Register(thisApp, new NotificationType[] { simpleGrowlType });
Notification myGrowl = new Notification(System.Windows.Forms.Application.ProductName, "SIMPLEGROWL", title, title, message);
simpleGrowl.Notify(myGrowl);
}
}
}

25
packages/Growl.0.6/content/license.txt vendored Normal file
View File

@ -0,0 +1,25 @@
Growl.NET GNTP Connector Library
-----------------------------------------------
Copyright (c) 2008 - Growl for Windows
All rights reserved
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

Binary file not shown.

Binary file not shown.