external notifications are now based on Events.

This commit is contained in:
kay.one 2013-02-24 15:47:57 -08:00
parent a866c419e1
commit 5fc25b6095
32 changed files with 542 additions and 619 deletions

View File

@ -7,10 +7,10 @@ using FluentAssertions;
using NCrunch.Framework;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.ExternalNotification;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Jobs;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.ExternalNotification;
using NzbDrone.Core.Providers.Metadata;
using NzbDrone.Core.Test.Framework;
@ -115,12 +115,6 @@ namespace NzbDrone.Core.Test
kernel.Resolve<IIndexerService>().All().Select(c => c.Type).Should().BeEquivalentTo(indexers);
}
[Test]
public void externalNotifiers_are_initialized()
{
kernel.Resolve<ExternalNotificationProvider>().All().Should().HaveSameCount(extNotifications);
}
[Test]
public void metadata_clients_are_initialized()
{

View File

@ -9,6 +9,7 @@ using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.Download;
using NzbDrone.Core.ExternalNotification;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
@ -117,16 +118,9 @@ namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
.Setup(s => s.FileExists(currentFilename))
.Returns(true);
Mocker.GetMock<ExternalNotificationProvider>()
.Setup(e => e.OnDownload("30 Rock - 1x01 - [WEBDL]", It.IsAny<Series>()));
//Act
var result = Mocker.Resolve<DiskScanProvider>().MoveEpisodeFile(file, true);
//Assert
result.Should().NotBeNull();
Mocker.GetMock<ExternalNotificationProvider>()
.Verify(e => e.OnDownload("30 Rock - 1x01 - [WEBDL]", It.IsAny<Series>()), Times.Once());
}
[Test]
@ -172,13 +166,8 @@ namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
.Setup(e => e.CalculateFilePath(It.IsAny<Series>(), fakeEpisode.First().SeasonNumber, filename, ".mkv"))
.Returns(fi);
Mocker.GetMock<ExternalNotificationProvider>()
.Setup(e => e.OnDownload("30 Rock - 1x01 - [WEBDL]", It.IsAny<Series>()));
//Act
var result = Mocker.Resolve<DiskScanProvider>().MoveEpisodeFile(file, true);
//Assert
result.Should().BeNull();
ExceptionVerification.ExpectedErrors(1);
}

View File

@ -4,6 +4,7 @@ using FizzWare.NBuilder;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Core.ExternalNotification;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Repository;

View File

@ -11,6 +11,7 @@ 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.Core;

View File

@ -6,9 +6,9 @@ using Autofac.Core;
using NLog;
using NzbDrone.Common;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.ExternalNotification;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Providers.ExternalNotification;
using NzbDrone.Core.Providers.Metadata;
using NzbDrone.Core.Providers.Search;
using PetaPoco;

View File

@ -0,0 +1,16 @@
using System.Linq;
using NzbDrone.Common.Eventing;
using NzbDrone.Core.Model;
namespace NzbDrone.Core.Download
{
public class EpisodeDownloadedEvent : IEvent
{
public EpisodeParseResult ParseResult { get; private set; }
public EpisodeDownloadedEvent(EpisodeParseResult parseResult)
{
ParseResult = parseResult;
}
}
}

View File

@ -0,0 +1,16 @@
using System.Linq;
using NzbDrone.Common.Eventing;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Download
{
public class SeriesRenamedEvent : IEvent
{
public Series Series { get; private set; }
public SeriesRenamedEvent(Series series)
{
Series = series;
}
}
}

View File

@ -0,0 +1,149 @@
using System;
using System.Linq;
using NLog;
using NzbDrone.Common.Eventing;
using NzbDrone.Core.Download;
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);
OnGrab(message.ParseResult.GetDownloadTitle());
}
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.ParseResult.GetDownloadTitle(), message.ParseResult.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)
{
}
}
}

View File

@ -0,0 +1,14 @@
using System.Linq;
using NzbDrone.Core.Datastore;
using PetaPoco;
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; }
}
}

View File

@ -0,0 +1,23 @@
using System.Linq;
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(IObjectDatabase objectDatabase)
: base(objectDatabase)
{
}
public ExternalNotificationDefinition Get(string name)
{
return Queryable.SingleOrDefault(c => c.Name.ToLower() == name.ToLower());
}
}
}

View File

@ -0,0 +1,48 @@
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);
}
}
}

View File

@ -4,7 +4,7 @@ using System.Linq;
using Growl.Connector;
using NLog;
namespace NzbDrone.Core.Providers
namespace NzbDrone.Core.ExternalNotification
{
public class GrowlProvider
{

View File

@ -0,0 +1,51 @@
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();
}
}
}
}

View File

@ -1,15 +1,12 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using NLog;
using NzbDrone.Common;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Providers.Core;
namespace NzbDrone.Core.Providers
namespace NzbDrone.Core.ExternalNotification
{
public class PlexProvider
{
@ -51,6 +48,7 @@ namespace NzbDrone.Core.Providers
try
{
logger.Trace("Sending Update Request to Plex Server");
var sections = GetSectionKeys(host);
sections.ForEach(s => UpdateSection(host, s));
}

View File

@ -0,0 +1,48 @@
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);
}
}
}

View File

@ -0,0 +1,39 @@
using System.Linq;
using System;
using NLog;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.ExternalNotification
{
public class Smtp : ExternalNotificationBase
{
private readonly SmtpProvider _smtpProvider;
public Smtp(IExternalNotificationRepository repository, SmtpProvider smtpProvider, Logger logger)
: base(repository, logger)
{
_smtpProvider = smtpProvider;
}
public override string Name
{
get { return "SMTP"; }
}
protected 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);
}
protected 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);
}
}
}

View File

@ -0,0 +1,35 @@
using System.Linq;
using NLog;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.ExternalNotification
{
public class Twitter : ExternalNotificationBase
{
private readonly TwitterProvider _twitterProvider;
public Twitter(IExternalNotificationRepository repository, TwitterProvider twitterProvider, Logger logger)
: base(repository, logger)
{
_twitterProvider = twitterProvider;
}
public override string Name
{
get { return "Twitter"; }
}
protected override void OnGrab(string message)
{
_twitterProvider.SendTweet("Download Started: " + message);
}
protected override void OnDownload(string message, Series series)
{
_twitterProvider.SendTweet("Download Completed: " + message);
}
}
}

View File

@ -0,0 +1,59 @@
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();
}
}
}
}

View File

@ -2,6 +2,9 @@ using System.Collections.Generic;
using System.Linq;
using System;
using NLog;
using NzbDrone.Common.Eventing;
using NzbDrone.Core.Download;
using NzbDrone.Core.ExternalNotification;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Model.Notification;
using NzbDrone.Core.Providers;
@ -12,23 +15,22 @@ namespace NzbDrone.Core.Jobs
{
private readonly MediaFileProvider _mediaFileProvider;
private readonly DiskScanProvider _diskScanProvider;
private readonly ExternalNotificationProvider _externalNotificationProvider;
private readonly ISeriesService _seriesService;
private readonly MetadataProvider _metadataProvider;
private readonly ISeriesRepository _seriesRepository;
private readonly IEventAggregator _eventAggregator;
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
public RenameSeasonJob(MediaFileProvider mediaFileProvider, DiskScanProvider diskScanProvider,
ExternalNotificationProvider externalNotificationProvider, ISeriesService seriesService,
MetadataProvider metadataProvider, ISeriesRepository seriesRepository)
public RenameSeasonJob(MediaFileProvider mediaFileProvider, DiskScanProvider diskScanProvider, ISeriesService seriesService,
MetadataProvider metadataProvider, ISeriesRepository seriesRepository, IEventAggregator eventAggregator)
{
_mediaFileProvider = mediaFileProvider;
_diskScanProvider = diskScanProvider;
_externalNotificationProvider = externalNotificationProvider;
_seriesService = seriesService;
_metadataProvider = metadataProvider;
_seriesRepository = seriesRepository;
_eventAggregator = eventAggregator;
}
public string Name
@ -100,7 +102,8 @@ namespace NzbDrone.Core.Jobs
//Start AfterRename
var message = String.Format("Renamed: Series {0}, Season: {1}", series.Title, options.SeasonNumber);
_externalNotificationProvider.AfterRename(message, series);
_eventAggregator.Publish(new SeriesRenamedEvent(series));
notification.CurrentMessage = String.Format("Rename completed for {0} Season {1}", series.Title, options.SeasonNumber);
}

View File

@ -2,11 +2,11 @@ using System.Collections.Generic;
using System.Linq;
using System;
using NLog;
using NzbDrone.Core.Datastore;
using NzbDrone.Common.Eventing;
using NzbDrone.Core.Download;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Model.Notification;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Repository;
namespace NzbDrone.Core.Jobs
{
@ -14,23 +14,20 @@ namespace NzbDrone.Core.Jobs
{
private readonly MediaFileProvider _mediaFileProvider;
private readonly DiskScanProvider _diskScanProvider;
private readonly ExternalNotificationProvider _externalNotificationProvider;
private readonly ISeriesService _seriesService;
private readonly MetadataProvider _metadataProvider;
private readonly ISeriesRepository _seriesRepository;
private readonly IEventAggregator _eventAggregator;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public RenameSeriesJob(MediaFileProvider mediaFileProvider, DiskScanProvider diskScanProvider,
ExternalNotificationProvider externalNotificationProvider, ISeriesService seriesService,
MetadataProvider metadataProvider,ISeriesRepository seriesRepository)
MetadataProvider metadataProvider,ISeriesRepository seriesRepository,IEventAggregator eventAggregator)
{
_mediaFileProvider = mediaFileProvider;
_diskScanProvider = diskScanProvider;
_externalNotificationProvider = externalNotificationProvider;
_seriesService = seriesService;
_metadataProvider = metadataProvider;
_seriesRepository = seriesRepository;
_eventAggregator = eventAggregator;
}
public string Name
@ -99,8 +96,7 @@ namespace NzbDrone.Core.Jobs
//Start AfterRename
var message = String.Format("Renamed: Series {0}", series.Title);
_externalNotificationProvider.AfterRename(message, series);
_eventAggregator.Publish(new SeriesRenamedEvent(series));
notification.CurrentMessage = String.Format("Rename completed for {0}", series.Title);
}

View File

@ -260,7 +260,10 @@
<Compile Include="Datastore\PetaPoco\EpisodeSeasonRelator.cs" />
<Compile Include="Datastore\PetaPoco\PetaPoco.cs" />
<Compile Include="Datastore\SqlCeProxy.cs" />
<Compile Include="Download\EpisodeDownloadedEvent.cs" />
<Compile Include="Download\EpisodeGrabbedEvent.cs" />
<Compile Include="Download\SeriesRenamedEvent.cs" />
<Compile Include="ExternalNotification\ExternalNotificationRepository.cs" />
<Compile Include="Fluent.cs" />
<Compile Include="Helpers\Converters\EpochDateTimeConverter.cs" />
<Compile Include="Helpers\SabnzbdQueueTimeConverter.cs" />
@ -464,31 +467,28 @@
<Compile Include="Tv\EpisodeRepository.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Providers\ExternalNotificationProvider.cs">
<Compile Include="ExternalNotification\ExternalNotificationBase.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Providers\ExternalNotification\ExternalNotificationBase.cs">
<Compile Include="ExternalNotification\Growl.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Providers\ExternalNotification\Growl.cs">
<Compile Include="ExternalNotification\Plex.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Providers\ExternalNotification\Plex.cs">
<Compile Include="ExternalNotification\Prowl.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Providers\ExternalNotification\Prowl.cs">
<Compile Include="ExternalNotification\Smtp.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Providers\ExternalNotification\Smtp.cs">
<Compile Include="ExternalNotification\Twitter.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Providers\ExternalNotification\Twitter.cs">
<Compile Include="ExternalNotification\Xbmc.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Providers\ExternalNotification\Xbmc.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Providers\GrowlProvider.cs">
<Compile Include="ExternalNotification\GrowlProvider.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="History\HistoryService.cs">
@ -521,7 +521,7 @@
<Compile Include="Providers\NotificationProvider.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Providers\PlexProvider.cs" />
<Compile Include="ExternalNotification\PlexProvider.cs" />
<Compile Include="Providers\PostDownloadProvider.cs">
<SubType>Code</SubType>
</Compile>
@ -578,7 +578,7 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="Indexers\NewznabDefinition.cs" />
<Compile Include="Repository\ExternalNotificationDefinition.cs" />
<Compile Include="ExternalNotification\ExternalNotificationDefinition.cs" />
<Compile Include="Jobs\JobDefinition.cs" />
<Compile Include="Indexers\Indexer.cs" />
<Compile Include="Model\EpisodeParseResult.cs" />

View File

@ -4,7 +4,10 @@ using System.IO;
using System.Linq;
using NLog;
using NzbDrone.Common;
using NzbDrone.Common.Eventing;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Download;
using NzbDrone.Core.ExternalNotification;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Model;
@ -17,27 +20,26 @@ namespace NzbDrone.Core.Providers
private readonly DiskProvider _diskProvider;
private readonly IEpisodeService _episodeService;
private readonly MediaFileProvider _mediaFileProvider;
private readonly ExternalNotificationProvider _externalNotificationProvider;
private readonly SignalRProvider _signalRProvider;
private readonly IConfigService _configService;
private readonly RecycleBinProvider _recycleBinProvider;
private readonly MediaInfoProvider _mediaInfoProvider;
private readonly ISeriesRepository _seriesRepository;
private readonly IEventAggregator _eventAggregator;
public DiskScanProvider(DiskProvider diskProvider, IEpisodeService episodeService, MediaFileProvider mediaFileProvider,
ExternalNotificationProvider externalNotificationProvider,
SignalRProvider signalRProvider, IConfigService configService,
RecycleBinProvider recycleBinProvider, MediaInfoProvider mediaInfoProvider, ISeriesRepository seriesRepository)
RecycleBinProvider recycleBinProvider, MediaInfoProvider mediaInfoProvider, ISeriesRepository seriesRepository, IEventAggregator eventAggregator)
{
_diskProvider = diskProvider;
_episodeService = episodeService;
_mediaFileProvider = mediaFileProvider;
_externalNotificationProvider = externalNotificationProvider;
_signalRProvider = signalRProvider;
_configService = configService;
_recycleBinProvider = recycleBinProvider;
_mediaInfoProvider = mediaInfoProvider;
_seriesRepository = seriesRepository;
_eventAggregator = eventAggregator;
}
public DiskScanProvider()
@ -228,11 +230,10 @@ namespace NzbDrone.Core.Providers
parseResult.Quality = new QualityModel { Quality = episodeFile.Quality, Proper = episodeFile.Proper };
parseResult.Episodes = episodes;
var message = parseResult.GetDownloadTitle();
if (newDownload)
{
_externalNotificationProvider.OnDownload(message, series);
_eventAggregator.Publish(new EpisodeDownloadedEvent(parseResult));
foreach (var episode in episodes)
_signalRProvider.UpdateEpisodeStatus(episode.OID, EpisodeStatusType.Ready, parseResult.Quality);

View File

@ -1,43 +0,0 @@
using NLog;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Providers.ExternalNotification
{
public abstract class ExternalNotificationBase
{
protected readonly Logger _logger;
protected readonly IConfigService _configService;
protected ExternalNotificationBase(IConfigService configService)
{
_configService = configService;
_logger = LogManager.GetLogger(GetType().ToString());
}
/// <summary>
/// Gets the name for the notification provider
/// </summary>
public abstract string Name { get; }
/// <summary>
/// Performs the on grab action
/// </summary>
/// <param name = "message">The message to send to the receiver</param>
public abstract void OnGrab(string message);
/// <summary>
/// Performs the on download action
/// </summary>
/// <param name = "message">The message to send to the receiver</param>
/// <param name = "series">The Series for the new download</param>
public abstract void OnDownload(string message, Series series);
/// <summary>
/// Performs the after rename action, this will be handled after all renaming for episode/season/series
/// </summary>
/// <param name = "message">The message to send to the receiver</param>
/// <param name = "series">The Series for the new download</param>
public abstract void AfterRename(string message, Series series);
}
}

View File

@ -1,77 +0,0 @@
using System;
using NLog;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Repository;
namespace NzbDrone.Core.Providers.ExternalNotification
{
public class Growl : ExternalNotificationBase
{
private readonly GrowlProvider _growlProvider;
public Growl(IConfigService configService, GrowlProvider growlProvider)
: base(configService)
{
_growlProvider = growlProvider;
}
public override string Name
{
get { return "Growl"; }
}
public override void OnGrab(string message)
{
try
{
if(_configService.GrowlNotifyOnGrab)
{
_logger.Trace("Sending Notification to Growl");
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);
}
}
catch (Exception ex)
{
_logger.WarnException(ex.Message, ex);
}
}
public override void OnDownload(string message, Series series)
{
try
{
if (_configService.GrowlNotifyOnDownload)
{
_logger.Trace("Sending Notification to Growl");
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);
}
}
catch (Exception ex)
{
_logger.WarnException(ex.Message, ex);
}
}
public override void AfterRename(string message, Series series)
{
}
}
}

View File

@ -1,63 +0,0 @@
using System;
using NLog;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Repository;
namespace NzbDrone.Core.Providers.ExternalNotification
{
public class Plex : ExternalNotificationBase
{
private readonly PlexProvider _plexProvider;
public Plex(IConfigService configService, PlexProvider plexProvider)
: base(configService)
{
_plexProvider = plexProvider;
}
public override string Name
{
get { return "Plex"; }
}
public override void OnGrab(string message)
{
const string header = "NzbDrone [TV] - Grabbed";
if (_configService.PlexNotifyOnGrab)
{
_logger.Trace("Sending Notification to Plex Clients");
_plexProvider.Notify(header, message);
}
}
public override void OnDownload(string message, Series series)
{
const string header = "NzbDrone [TV] - Downloaded";
if (_configService.PlexNotifyOnDownload)
{
_logger.Trace("Sending Notification to Plex Clients");
_plexProvider.Notify(header, message);
}
UpdateIfEnabled();
}
public override void AfterRename(string message, Series series)
{
UpdateIfEnabled();
}
private void UpdateIfEnabled()
{
if (_configService.PlexUpdateLibrary)
{
_logger.Trace("Sending Update Request to Plex Server");
_plexProvider.UpdateLibrary();
}
}
}
}

View File

@ -1,75 +0,0 @@
using System;
using NLog;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Repository;
using Prowlin;
namespace NzbDrone.Core.Providers.ExternalNotification
{
public class Prowl : ExternalNotificationBase
{
private readonly ProwlProvider _prowlProvider;
public Prowl(IConfigService configService, ProwlProvider prowlProvider)
: base(configService)
{
_prowlProvider = prowlProvider;
}
public override string Name
{
get { return "Prowl"; }
}
public override void OnGrab(string message)
{
try
{
if(_configService.GrowlNotifyOnGrab)
{
_logger.Trace("Sending Notification to Prowl");
const string title = "Episode Grabbed";
var apiKeys = _configService.ProwlApiKeys;
var priority = _configService.ProwlPriority;
_prowlProvider.SendNotification(title, message, apiKeys, (NotificationPriority)priority);
}
}
catch (Exception ex)
{
_logger.WarnException(ex.Message, ex);
}
}
public override void OnDownload(string message, Series series)
{
try
{
if (_configService.GrowlNotifyOnDownload)
{
_logger.Trace("Sending Notification to Prowl");
const string title = "Episode Downloaded";
var apiKeys = _configService.ProwlApiKeys;
var priority = _configService.ProwlPriority;
_prowlProvider.SendNotification(title, message, apiKeys, (NotificationPriority)priority);
}
}
catch (Exception ex)
{
_logger.WarnException(ex.Message, ex);
}
}
public override void AfterRename(string message, Series series)
{
}
}
}

View File

@ -1,53 +0,0 @@
using System;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Providers.ExternalNotification
{
public class Smtp: ExternalNotificationBase
{
private readonly SmtpProvider _smtpProvider;
public Smtp(IConfigService configService, SmtpProvider smtpProvider)
: base(configService)
{
_smtpProvider = smtpProvider;
}
public override string Name
{
get { return "SMTP"; }
}
public override void OnGrab(string message)
{
const string subject = "NzbDrone [TV] - Grabbed";
var body = String.Format("{0} sent to SABnzbd queue.", message);
if (_configService.SmtpNotifyOnGrab)
{
_logger.Trace("Sending SMTP Notification");
_smtpProvider.SendEmail(subject, body);
}
}
public override void OnDownload(string message, Series series)
{
const string subject = "NzbDrone [TV] - Downloaded";
var body = String.Format("{0} Downloaded and sorted.", message);
if (_configService.SmtpNotifyOnDownload)
{
_logger.Trace("Sending SMTP Notification");
_smtpProvider.SendEmail(subject, body);
}
}
public override void AfterRename(string message, Series series)
{
}
}
}

View File

@ -1,47 +0,0 @@
using System;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Repository;
namespace NzbDrone.Core.Providers.ExternalNotification
{
public class Twitter : ExternalNotificationBase
{
private readonly TwitterProvider _twitterProvider;
public Twitter(IConfigService configService, TwitterProvider twitterProvider)
: base(configService)
{
_twitterProvider = twitterProvider;
}
public override string Name
{
get { return "Twitter"; }
}
public override void OnGrab(string message)
{
if (_configService.TwitterNotifyOnGrab)
{
_logger.Trace("Sending Notification to Twitter (On Grab)");
_twitterProvider.SendTweet("Download Started: " + message);
}
}
public override void OnDownload(string message, Series series)
{
if (_configService.TwitterNotifyOnDownload)
{
_logger.Trace("Sending Notification to Twitter (On Grab)");
_twitterProvider.SendTweet("Download Completed: " + message);
}
}
public override void AfterRename(string message, Series series)
{
}
}
}

View File

@ -1,68 +0,0 @@
using System;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Repository;
namespace NzbDrone.Core.Providers.ExternalNotification
{
public class Xbmc : ExternalNotificationBase
{
private readonly XbmcProvider _xbmcProvider;
public Xbmc(IConfigService configService, XbmcProvider xbmcProvider)
: base(configService)
{
_xbmcProvider = xbmcProvider;
}
public override string Name
{
get { return "XBMC"; }
}
public override void OnGrab(string message)
{
const string header = "NzbDrone [TV] - Grabbed";
if (_configService.XbmcNotifyOnGrab)
{
_logger.Trace("Sending Notification to XBMC");
_xbmcProvider.Notify(header, message);
}
}
public override void OnDownload(string message, Series series)
{
const string header = "NzbDrone [TV] - Downloaded";
if (_configService.XbmcNotifyOnDownload)
{
_logger.Trace("Sending Notification to XBMC");
_xbmcProvider.Notify(header, message);
}
UpdateAndClean(series);
}
public override void AfterRename(string message, Series series)
{
UpdateAndClean(series);
}
private void UpdateAndClean(Series series)
{
if (_configService.XbmcUpdateLibrary)
{
_logger.Trace("Sending Update Request to XBMC");
_xbmcProvider.Update(series);
}
if (_configService.XbmcCleanLibrary)
{
_logger.Trace("Sending Clean DB Request to XBMC");
_xbmcProvider.Clean();
}
}
}
}

View File

@ -1,114 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Common.Eventing;
using NzbDrone.Core.Download;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Providers.ExternalNotification;
using NzbDrone.Core.Repository;
using PetaPoco;
namespace NzbDrone.Core.Providers
{
public class ExternalNotificationProvider : IHandle<EpisodeGrabbedEvent>
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly IDatabase _database;
private IList<ExternalNotificationBase> _notifiers;
public ExternalNotificationProvider(IDatabase database, IEnumerable<ExternalNotificationBase> notifiers)
{
_database = database;
_notifiers = notifiers.ToList();
InitializeNotifiers(_notifiers);
}
public ExternalNotificationProvider()
{
}
public virtual List<ExternalNotificationDefinition> All()
{
return _database.Fetch<ExternalNotificationDefinition>();
}
public virtual void SaveSettings(ExternalNotificationDefinition settings)
{
if (settings.Id == 0)
{
Logger.Debug("Adding External Notification definition for {0}", settings.Name);
_database.Insert(settings);
}
else
{
Logger.Debug("Updating External Notification definition for {0}", settings.Name);
_database.Update(settings);
}
}
public virtual ExternalNotificationDefinition GetSettings(Type type)
{
return _database.SingleOrDefault<ExternalNotificationDefinition>("WHERE ExternalNotificationProviderType = @0", type.ToString());
}
public virtual IList<ExternalNotificationBase> GetEnabledExternalNotifiers()
{
var all = All();
return _notifiers.Where(i => all.Exists(c => c.ExternalNotificationProviderType == i.GetType().ToString() && c.Enable)).ToList();
}
private void InitializeNotifiers(IList<ExternalNotificationBase> notifiers)
{
Logger.Debug("Initializing notifiers. Count {0}", notifiers.Count);
_notifiers = notifiers;
var currentNotifiers = All();
foreach (var notificationProvider in notifiers)
{
ExternalNotificationBase externalNotificationProviderLocal = notificationProvider;
if (!currentNotifiers.Exists(c => c.ExternalNotificationProviderType == externalNotificationProviderLocal.GetType().ToString()))
{
var settings = new ExternalNotificationDefinition
{
Enable = false,
ExternalNotificationProviderType = externalNotificationProviderLocal.GetType().ToString(),
Name = externalNotificationProviderLocal.Name
};
SaveSettings(settings);
}
}
}
public virtual void OnDownload(string message, Series series)
{
foreach (var notifier in _notifiers.Where(i => GetSettings(i.GetType()).Enable))
{
notifier.OnDownload(message, series);
}
}
public virtual void AfterRename(string message, Series series)
{
foreach (var notifier in _notifiers.Where(i => GetSettings(i.GetType()).Enable))
{
notifier.AfterRename(message, series);
}
}
public void Handle(EpisodeGrabbedEvent message)
{
foreach (var notifier in _notifiers.Where(i => GetSettings(i.GetType()).Enable))
{
notifier.OnGrab(message.ParseResult.GetDownloadTitle());
}
}
}
}

View File

@ -5,7 +5,6 @@ using NLog;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers.ExternalNotification;
using NzbDrone.Core.Providers.Metadata;
using NzbDrone.Core.Repository;
using PetaPoco;

View File

@ -1,17 +0,0 @@
using PetaPoco;
namespace NzbDrone.Core.Repository
{
[TableName("ExternalNotificationDefinitions")]
[PrimaryKey("Id", autoIncrement = true)]
public class ExternalNotificationDefinition
{
public int Id { get; set; }
public bool Enable { get; set; }
public string ExternalNotificationProviderType { get; set; }
public string Name { get; set; }
}
}