Provider testing improvements
New: Test button for indexers in UI Fixed: Testing download clients shows error messages in UI Fixed: Testing notifications shows error messages in UI
This commit is contained in:
parent
c5bd8b27fb
commit
7af782d353
|
@ -23,7 +23,10 @@ namespace NzbDrone.Api
|
||||||
: base(resource)
|
: base(resource)
|
||||||
{
|
{
|
||||||
_providerFactory = providerFactory;
|
_providerFactory = providerFactory;
|
||||||
|
|
||||||
Get["schema"] = x => GetTemplates();
|
Get["schema"] = x => GetTemplates();
|
||||||
|
Post["test"] = x => Test(ReadResourceFromRequest());
|
||||||
|
|
||||||
GetResourceAll = GetAll;
|
GetResourceAll = GetAll;
|
||||||
GetResourceById = GetProviderById;
|
GetResourceById = GetProviderById;
|
||||||
CreateResource = CreateProvider;
|
CreateResource = CreateProvider;
|
||||||
|
@ -63,16 +66,26 @@ namespace NzbDrone.Api
|
||||||
|
|
||||||
private int CreateProvider(TProviderResource providerResource)
|
private int CreateProvider(TProviderResource providerResource)
|
||||||
{
|
{
|
||||||
var provider = GetDefinition(providerResource);
|
var providerDefinition = GetDefinition(providerResource);
|
||||||
provider = _providerFactory.Create(provider);
|
|
||||||
return provider.Id;
|
if (providerDefinition.Enable)
|
||||||
|
{
|
||||||
|
Test(providerDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
|
providerDefinition = _providerFactory.Create(providerDefinition);
|
||||||
|
|
||||||
|
return providerDefinition.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateProvider(TProviderResource providerResource)
|
private void UpdateProvider(TProviderResource providerResource)
|
||||||
{
|
{
|
||||||
var providerDefinition = GetDefinition(providerResource);
|
var providerDefinition = GetDefinition(providerResource);
|
||||||
|
|
||||||
Validate(providerDefinition);
|
if (providerDefinition.Enable)
|
||||||
|
{
|
||||||
|
Test(providerDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
_providerFactory.Update(providerDefinition);
|
_providerFactory.Update(providerDefinition);
|
||||||
}
|
}
|
||||||
|
@ -133,6 +146,25 @@ namespace NzbDrone.Api
|
||||||
return result.AsResponse();
|
return result.AsResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Response Test(TProviderResource providerResource)
|
||||||
|
{
|
||||||
|
var providerDefinition = GetDefinition(providerResource);
|
||||||
|
|
||||||
|
Test(providerDefinition);
|
||||||
|
|
||||||
|
return "{}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Test(TProviderDefinition providerDefinition)
|
||||||
|
{
|
||||||
|
var result = _providerFactory.Test(providerDefinition);
|
||||||
|
|
||||||
|
if (!result.IsValid)
|
||||||
|
{
|
||||||
|
throw new ValidationException(result.Errors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual void Validate(TProviderDefinition definition)
|
protected virtual void Validate(TProviderDefinition definition)
|
||||||
{
|
{
|
||||||
var validationResult = definition.Settings.Validate();
|
var validationResult = definition.Settings.Validate();
|
||||||
|
@ -143,4 +175,4 @@ namespace NzbDrone.Api
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,7 +194,7 @@ namespace NzbDrone.Api.REST
|
||||||
|
|
||||||
var errors = SharedValidator.Validate(resource).Errors.ToList();
|
var errors = SharedValidator.Validate(resource).Errors.ToList();
|
||||||
|
|
||||||
if (Request.Method.Equals("POST", StringComparison.InvariantCultureIgnoreCase))
|
if (Request.Method.Equals("POST", StringComparison.InvariantCultureIgnoreCase) && !Request.Url.Path.EndsWith("/test", StringComparison.InvariantCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
errors.AddRange(PostValidator.Validate(resource).Errors);
|
errors.AddRange(PostValidator.Validate(resource).Errors);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using FizzWare.NBuilder;
|
using FizzWare.NBuilder;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Moq;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Indexers.Newznab;
|
using NzbDrone.Core.Indexers.Newznab;
|
||||||
|
|
|
@ -2,19 +2,18 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using Omu.ValueInjecter;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.Nzbget
|
namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
{
|
{
|
||||||
public class Nzbget : DownloadClientBase<NzbgetSettings>, IExecute<TestNzbgetCommand>
|
public class Nzbget : DownloadClientBase<NzbgetSettings>
|
||||||
{
|
{
|
||||||
private readonly INzbgetProxy _proxy;
|
private readonly INzbgetProxy _proxy;
|
||||||
private readonly IHttpProvider _httpProvider;
|
private readonly IHttpProvider _httpProvider;
|
||||||
|
@ -265,25 +264,42 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
return _proxy.GetVersion(Settings);
|
return _proxy.GetVersion(Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Test(NzbgetSettings settings)
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
_proxy.GetVersion(settings);
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
||||||
var config = _proxy.GetConfig(settings);
|
failures.AddIfNotNull(TestConnection());
|
||||||
var categories = GetCategories(config);
|
failures.AddIfNotNull(TestCategory());
|
||||||
|
|
||||||
if (!settings.TvCategory.IsNullOrWhiteSpace() && !categories.Any(v => v.Name == settings.TvCategory))
|
return new ValidationResult(failures);
|
||||||
{
|
|
||||||
throw new ApplicationException("Category does not exist");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(TestNzbgetCommand message)
|
private ValidationFailure TestConnection()
|
||||||
{
|
{
|
||||||
var settings = new NzbgetSettings();
|
try
|
||||||
settings.InjectFrom(message);
|
{
|
||||||
|
_proxy.GetVersion(Settings);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.ErrorException(ex.Message, ex);
|
||||||
|
return new ValidationFailure("Host", "Unable to connect to NZBGet");
|
||||||
|
}
|
||||||
|
|
||||||
Test(settings);
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ValidationFailure TestCategory()
|
||||||
|
{
|
||||||
|
var config = _proxy.GetConfig(Settings);
|
||||||
|
var categories = GetCategories(config);
|
||||||
|
|
||||||
|
if (!Settings.TvCategory.IsNullOrWhiteSpace() && !categories.Any(v => v.Name == Settings.TvCategory))
|
||||||
|
{
|
||||||
|
return new ValidationFailure("TvCategory", "Category does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Javascript doesn't support 64 bit integers natively so json officially doesn't either.
|
// Javascript doesn't support 64 bit integers natively so json officially doesn't either.
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
using System;
|
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.Nzbget
|
|
||||||
{
|
|
||||||
public class TestNzbgetCommand : Command
|
|
||||||
{
|
|
||||||
public override bool SendUpdatesToClient
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String Host { get; set; }
|
|
||||||
public Int32 Port { get; set; }
|
|
||||||
public String Username { get; set; }
|
|
||||||
public String Password { get; set; }
|
|
||||||
public String TvCategory { get; set; }
|
|
||||||
public Int32 RecentTvPriority { get; set; }
|
|
||||||
public Int32 OlderTvPriority { get; set; }
|
|
||||||
public Boolean UseSsl { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +1,24 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Common.Instrumentation;
|
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
using NzbDrone.Core.Organizer;
|
using NzbDrone.Core.Organizer;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using Omu.ValueInjecter;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.Pneumatic
|
namespace NzbDrone.Core.Download.Clients.Pneumatic
|
||||||
{
|
{
|
||||||
public class Pneumatic : DownloadClientBase<PneumaticSettings>, IExecute<TestPneumaticCommand>
|
public class Pneumatic : DownloadClientBase<PneumaticSettings>
|
||||||
{
|
{
|
||||||
private readonly IHttpProvider _httpProvider;
|
private readonly IHttpProvider _httpProvider;
|
||||||
private readonly IDiskProvider _diskProvider;
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
|
||||||
private static readonly Logger logger = NzbDroneLogger.GetLogger();
|
|
||||||
|
|
||||||
public Pneumatic(IHttpProvider httpProvider,
|
public Pneumatic(IHttpProvider httpProvider,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
|
@ -57,10 +53,10 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic
|
||||||
//Save to the Pneumatic directory (The user will need to ensure its accessible by XBMC)
|
//Save to the Pneumatic directory (The user will need to ensure its accessible by XBMC)
|
||||||
var filename = Path.Combine(Settings.NzbFolder, title + ".nzb");
|
var filename = Path.Combine(Settings.NzbFolder, title + ".nzb");
|
||||||
|
|
||||||
logger.Debug("Downloading NZB from: {0} to: {1}", url, filename);
|
_logger.Debug("Downloading NZB from: {0} to: {1}", url, filename);
|
||||||
_httpProvider.DownloadFile(url, filename);
|
_httpProvider.DownloadFile(url, filename);
|
||||||
|
|
||||||
logger.Debug("NZB Download succeeded, saved to: {0}", filename);
|
_logger.Debug("NZB Download succeeded, saved to: {0}", filename);
|
||||||
|
|
||||||
var contents = String.Format("plugin://plugin.program.pneumatic/?mode=strm&type=add_file&nzb={0}&nzbname={1}", filename, title);
|
var contents = String.Format("plugin://plugin.program.pneumatic/?mode=strm&type=add_file&nzb={0}&nzbname={1}", filename, title);
|
||||||
_diskProvider.WriteAllText(Path.Combine(_configService.DownloadedEpisodesFolder, title + ".strm"), contents);
|
_diskProvider.WriteAllText(Path.Combine(_configService.DownloadedEpisodesFolder, title + ".strm"), contents);
|
||||||
|
@ -101,24 +97,35 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Test(PneumaticSettings settings)
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
PerformWriteTest(settings.NzbFolder);
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
||||||
|
failures.AddIfNotNull(TestWrite(Settings.NzbFolder, "NzbFolder"));
|
||||||
|
|
||||||
|
return new ValidationResult(failures);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PerformWriteTest(string folder)
|
private ValidationFailure TestWrite(String folder, String propertyName)
|
||||||
{
|
{
|
||||||
var testPath = Path.Combine(folder, "drone_test.txt");
|
if (!_diskProvider.FolderExists(folder))
|
||||||
_diskProvider.WriteAllText(testPath, DateTime.Now.ToString());
|
{
|
||||||
_diskProvider.DeleteFile(testPath);
|
return new ValidationFailure(propertyName, "Folder does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(TestPneumaticCommand message)
|
try
|
||||||
{
|
{
|
||||||
var settings = new PneumaticSettings();
|
var testPath = Path.Combine(folder, "drone_test.txt");
|
||||||
settings.InjectFrom(message);
|
_diskProvider.WriteAllText(testPath, DateTime.Now.ToString());
|
||||||
|
_diskProvider.DeleteFile(testPath);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.ErrorException(ex.Message, ex);
|
||||||
|
return new ValidationFailure(propertyName, "Unable to write to folder");
|
||||||
|
}
|
||||||
|
|
||||||
Test(settings);
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
using System;
|
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.Pneumatic
|
|
||||||
{
|
|
||||||
public class TestPneumaticCommand : Command
|
|
||||||
{
|
|
||||||
public override bool SendUpdatesToClient
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String Folder { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,19 +2,18 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using Omu.ValueInjecter;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
{
|
{
|
||||||
public class Sabnzbd : DownloadClientBase<SabnzbdSettings>, IExecute<TestSabnzbdCommand>
|
public class Sabnzbd : DownloadClientBase<SabnzbdSettings>
|
||||||
{
|
{
|
||||||
private readonly IHttpProvider _httpProvider;
|
private readonly IHttpProvider _httpProvider;
|
||||||
private readonly ISabnzbdProxy _proxy;
|
private readonly ISabnzbdProxy _proxy;
|
||||||
|
@ -218,22 +217,41 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Test(SabnzbdSettings settings)
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
var categories = _proxy.GetCategories(settings);
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
||||||
if (!settings.TvCategory.IsNullOrWhiteSpace() && !categories.Any(v => v == settings.TvCategory))
|
failures.AddIfNotNull(TestConnection());
|
||||||
{
|
failures.AddIfNotNull(TestCategory());
|
||||||
throw new ApplicationException("Category does not exist");
|
|
||||||
}
|
return new ValidationResult(failures);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(TestSabnzbdCommand message)
|
private ValidationFailure TestConnection()
|
||||||
{
|
{
|
||||||
var settings = new SabnzbdSettings();
|
try
|
||||||
settings.InjectFrom(message);
|
{
|
||||||
|
_proxy.GetCategories(Settings);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.ErrorException(ex.Message, ex);
|
||||||
|
return new ValidationFailure("Host", "Unable to connect to SABnzbd");
|
||||||
|
}
|
||||||
|
|
||||||
Test(settings);
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ValidationFailure TestCategory()
|
||||||
|
{
|
||||||
|
var categories = _proxy.GetCategories(Settings);
|
||||||
|
|
||||||
|
if (!Settings.TvCategory.IsNullOrWhiteSpace() && !categories.Any(v => v == Settings.TvCategory))
|
||||||
|
{
|
||||||
|
return new ValidationFailure("TvCategory", "Category does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,27 +0,0 @@
|
||||||
using System;
|
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
|
||||||
{
|
|
||||||
public class TestSabnzbdCommand : Command
|
|
||||||
{
|
|
||||||
public override bool SendUpdatesToClient
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String Host { get; set; }
|
|
||||||
public Int32 Port { get; set; }
|
|
||||||
public String ApiKey { get; set; }
|
|
||||||
public String Username { get; set; }
|
|
||||||
public String Password { get; set; }
|
|
||||||
public String TvCategory { get; set; }
|
|
||||||
public Int32 RecentTvPriority { get; set; }
|
|
||||||
public Int32 OlderTvPriority { get; set; }
|
|
||||||
public Boolean UseSsl { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
using System;
|
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.UsenetBlackhole
|
|
||||||
{
|
|
||||||
public class TestUsenetBlackholeCommand : Command
|
|
||||||
{
|
|
||||||
public override bool SendUpdatesToClient
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String NzbFolder { get; set; }
|
|
||||||
public String WatchFolder { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,22 +2,21 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
using NzbDrone.Core.Organizer;
|
using NzbDrone.Core.Organizer;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
using Omu.ValueInjecter;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.UsenetBlackhole
|
namespace NzbDrone.Core.Download.Clients.UsenetBlackhole
|
||||||
{
|
{
|
||||||
public class UsenetBlackhole : DownloadClientBase<UsenetBlackholeSettings>, IExecute<TestUsenetBlackholeCommand>
|
public class UsenetBlackhole : DownloadClientBase<UsenetBlackholeSettings>
|
||||||
{
|
{
|
||||||
private readonly IDiskProvider _diskProvider;
|
private readonly IDiskProvider _diskProvider;
|
||||||
private readonly IDiskScanService _diskScanService;
|
private readonly IDiskScanService _diskScanService;
|
||||||
|
@ -146,25 +145,36 @@ namespace NzbDrone.Core.Download.Clients.UsenetBlackhole
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Test(UsenetBlackholeSettings settings)
|
public override ValidationResult Test()
|
||||||
{
|
{
|
||||||
PerformWriteTest(settings.NzbFolder);
|
var failures = new List<ValidationFailure>();
|
||||||
PerformWriteTest(settings.WatchFolder);
|
|
||||||
|
failures.AddIfNotNull(TestWrite(Settings.NzbFolder, "NzbFolder"));
|
||||||
|
failures.AddIfNotNull(TestWrite(Settings.WatchFolder, "WatchFolder"));
|
||||||
|
|
||||||
|
return new ValidationResult(failures);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PerformWriteTest(string folder)
|
private ValidationFailure TestWrite(String folder, String propertyName)
|
||||||
{
|
{
|
||||||
var testPath = Path.Combine(folder, "drone_test.txt");
|
if (!_diskProvider.FolderExists(folder))
|
||||||
_diskProvider.WriteAllText(testPath, DateTime.Now.ToString());
|
{
|
||||||
_diskProvider.DeleteFile(testPath);
|
return new ValidationFailure(propertyName, "Folder does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(TestUsenetBlackholeCommand message)
|
try
|
||||||
{
|
{
|
||||||
var settings = new UsenetBlackholeSettings();
|
var testPath = Path.Combine(folder, "drone_test.txt");
|
||||||
settings.InjectFrom(message);
|
_diskProvider.WriteAllText(testPath, DateTime.Now.ToString());
|
||||||
|
_diskProvider.DeleteFile(testPath);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.ErrorException(ex.Message, ex);
|
||||||
|
return new ValidationFailure(propertyName, "Unable to write to folder");
|
||||||
|
}
|
||||||
|
|
||||||
Test(settings);
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Common.Disk;
|
|
||||||
using NzbDrone.Core.Annotations;
|
using NzbDrone.Core.Annotations;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
using NzbDrone.Core.Validation.Paths;
|
using NzbDrone.Core.Validation.Paths;
|
||||||
|
@ -12,7 +11,6 @@ namespace NzbDrone.Core.Download.Clients.UsenetBlackhole
|
||||||
{
|
{
|
||||||
public UsenetBlackholeSettingsValidator()
|
public UsenetBlackholeSettingsValidator()
|
||||||
{
|
{
|
||||||
//Todo: Validate that the path actually exists
|
|
||||||
RuleFor(c => c.NzbFolder).IsValidPath();
|
RuleFor(c => c.NzbFolder).IsValidPath();
|
||||||
RuleFor(c => c.WatchFolder).IsValidPath();
|
RuleFor(c => c.WatchFolder).IsValidPath();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
@ -34,6 +34,7 @@ namespace NzbDrone.Core.Download
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProviderDefinition Definition { get; set; }
|
public ProviderDefinition Definition { get; set; }
|
||||||
|
public abstract ValidationResult Test();
|
||||||
|
|
||||||
protected TSettings Settings
|
protected TSettings Settings
|
||||||
{
|
{
|
||||||
|
@ -55,8 +56,6 @@ namespace NzbDrone.Core.Download
|
||||||
return GetType().Name;
|
return GetType().Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public abstract DownloadProtocol Protocol
|
public abstract DownloadProtocol Protocol
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
|
@ -68,8 +67,6 @@ namespace NzbDrone.Core.Download
|
||||||
public abstract void RetryDownload(string id);
|
public abstract void RetryDownload(string id);
|
||||||
public abstract DownloadClientStatus GetStatus();
|
public abstract DownloadClientStatus GetStatus();
|
||||||
|
|
||||||
public abstract void Test(TSettings settings);
|
|
||||||
|
|
||||||
protected RemoteEpisode GetRemoteEpisode(String title)
|
protected RemoteEpisode GetRemoteEpisode(String title)
|
||||||
{
|
{
|
||||||
var parsedEpisodeInfo = Parser.Parser.ParseTitle(title);
|
var parsedEpisodeInfo = Parser.Parser.ParseTitle(title);
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
using System;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Indexers;
|
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download
|
namespace NzbDrone.Core.Download
|
||||||
{
|
{
|
||||||
public class DownloadClientDefinition : ProviderDefinition
|
public class DownloadClientDefinition : ProviderDefinition
|
||||||
{
|
{
|
||||||
public Boolean Enable { get; set; }
|
|
||||||
public DownloadProtocol Protocol { get; set; }
|
public DownloadProtocol Protocol { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers.Animezb
|
namespace NzbDrone.Core.Indexers.Animezb
|
||||||
|
@ -72,6 +73,11 @@ namespace NzbDrone.Core.Indexers.Animezb
|
||||||
return new List<string>();
|
return new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ValidationResult Test()
|
||||||
|
{
|
||||||
|
return new ValidationResult();
|
||||||
|
}
|
||||||
|
|
||||||
private String GetSearchQuery(string title, int absoluteEpisodeNumber)
|
private String GetSearchQuery(string title, int absoluteEpisodeNumber)
|
||||||
{
|
{
|
||||||
var match = RemoveSingleCharacterRegex.Match(title);
|
var match = RemoveSingleCharacterRegex.Match(title);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers.Fanzub
|
namespace NzbDrone.Core.Indexers.Fanzub
|
||||||
|
@ -69,6 +70,11 @@ namespace NzbDrone.Core.Indexers.Fanzub
|
||||||
return new List<string>();
|
return new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ValidationResult Test()
|
||||||
|
{
|
||||||
|
return new ValidationResult();
|
||||||
|
}
|
||||||
|
|
||||||
private IEnumerable<String> GetTitleSearchStrings(string title, int absoluteEpisodeNumber)
|
private IEnumerable<String> GetTitleSearchStrings(string title, int absoluteEpisodeNumber)
|
||||||
{
|
{
|
||||||
var formats = new[] { "{0}%20{1:00}", "{0}%20-%20{1:00}" };
|
var formats = new[] { "{0}%20{1:00}", "{0}%20-%20{1:00}" };
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers
|
namespace NzbDrone.Core.Indexers
|
||||||
|
@ -32,6 +33,7 @@ namespace NzbDrone.Core.Indexers
|
||||||
|
|
||||||
public virtual ProviderDefinition Definition { get; set; }
|
public virtual ProviderDefinition Definition { get; set; }
|
||||||
|
|
||||||
|
public abstract ValidationResult Test();
|
||||||
public abstract DownloadProtocol Protocol { get; }
|
public abstract DownloadProtocol Protocol { get; }
|
||||||
|
|
||||||
public virtual Boolean SupportsFeed { get { return true; } }
|
public virtual Boolean SupportsFeed { get { return true; } }
|
||||||
|
|
|
@ -4,8 +4,6 @@ namespace NzbDrone.Core.Indexers
|
||||||
{
|
{
|
||||||
public class IndexerDefinition : ProviderDefinition
|
public class IndexerDefinition : ProviderDefinition
|
||||||
{
|
{
|
||||||
public bool Enable { get; set; }
|
|
||||||
|
|
||||||
public DownloadProtocol Protocol { get; set; }
|
public DownloadProtocol Protocol { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ namespace NzbDrone.Core.Indexers
|
||||||
|
|
||||||
public class IndexerFactory : ProviderFactory<IIndexer, IndexerDefinition>, IIndexerFactory
|
public class IndexerFactory : ProviderFactory<IIndexer, IndexerDefinition>, IIndexerFactory
|
||||||
{
|
{
|
||||||
private readonly IIndexerRepository _providerRepository;
|
|
||||||
private readonly INewznabTestService _newznabTestService;
|
private readonly INewznabTestService _newznabTestService;
|
||||||
|
|
||||||
public IndexerFactory(IIndexerRepository providerRepository,
|
public IndexerFactory(IIndexerRepository providerRepository,
|
||||||
|
@ -25,7 +24,6 @@ namespace NzbDrone.Core.Indexers
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(providerRepository, providers, container, eventAggregator, logger)
|
: base(providerRepository, providers, container, eventAggregator, logger)
|
||||||
{
|
{
|
||||||
_providerRepository = providerRepository;
|
|
||||||
_newznabTestService = newznabTestService;
|
_newznabTestService = newznabTestService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,17 +37,6 @@ namespace NzbDrone.Core.Indexers
|
||||||
return base.Active().Where(c => c.Enable).ToList();
|
return base.Active().Where(c => c.Enable).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IndexerDefinition Create(IndexerDefinition definition)
|
|
||||||
{
|
|
||||||
if (definition.Implementation == typeof(Newznab.Newznab).Name)
|
|
||||||
{
|
|
||||||
var indexer = GetInstance(definition);
|
|
||||||
_newznabTestService.Test(indexer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.Create(definition);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override IndexerDefinition GetProviderCharacteristics(IIndexer provider, IndexerDefinition definition)
|
protected override IndexerDefinition GetProviderCharacteristics(IIndexer provider, IndexerDefinition definition)
|
||||||
{
|
{
|
||||||
definition = base.GetProviderCharacteristics(provider, definition);
|
definition = base.GetProviderCharacteristics(provider, definition);
|
||||||
|
|
|
@ -1,14 +1,35 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.Eventing.Reader;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using FluentValidation;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Core.Indexers.Exceptions;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers.Newznab
|
namespace NzbDrone.Core.Indexers.Newznab
|
||||||
{
|
{
|
||||||
public class Newznab : IndexerBase<NewznabSettings>
|
public class Newznab : IndexerBase<NewznabSettings>
|
||||||
{
|
{
|
||||||
|
private readonly IFetchFeedFromIndexers _feedFetcher;
|
||||||
|
private readonly HttpProvider _httpProvider;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public Newznab(IFetchFeedFromIndexers feedFetcher, HttpProvider httpProvider, Logger logger)
|
||||||
|
{
|
||||||
|
_feedFetcher = feedFetcher;
|
||||||
|
_httpProvider = httpProvider;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Newznab()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override DownloadProtocol Protocol { get { return DownloadProtocol.Usenet; } }
|
public override DownloadProtocol Protocol { get { return DownloadProtocol.Usenet; } }
|
||||||
public override Int32 SupportedPageSize { get { return 100; } }
|
public override Int32 SupportedPageSize { get { return 100; } }
|
||||||
|
|
||||||
|
@ -169,6 +190,41 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||||
return RecentFeed.Select(url => String.Format("{0}&offset={1}&limit=100&q={2}", url.Replace("t=tvsearch", "t=search"), offset, query));
|
return RecentFeed.Select(url => String.Format("{0}&offset={1}&limit=100&q={2}", url.Replace("t=tvsearch", "t=search"), offset, query));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ValidationResult Test()
|
||||||
|
{
|
||||||
|
var releases = _feedFetcher.FetchRss(this);
|
||||||
|
|
||||||
|
if (releases.Any()) return new ValidationResult();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var url = RecentFeed.First();
|
||||||
|
var xml = _httpProvider.DownloadString(url);
|
||||||
|
|
||||||
|
NewznabPreProcessor.Process(xml, url);
|
||||||
|
}
|
||||||
|
catch (ApiKeyException)
|
||||||
|
{
|
||||||
|
_logger.Warn("Indexer returned result for Newznab RSS URL, API Key appears to be invalid");
|
||||||
|
|
||||||
|
var apiKeyFailure = new ValidationFailure("ApiKey", "Invalid API Key");
|
||||||
|
return new ValidationResult(new List<ValidationFailure> { apiKeyFailure });
|
||||||
|
}
|
||||||
|
catch (RequestLimitReachedException)
|
||||||
|
{
|
||||||
|
_logger.Warn("Request limit reached");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.WarnException("Unable to connect to indexer: " + ex.Message, ex);
|
||||||
|
|
||||||
|
var failure = new ValidationFailure("Url", "Unable to connect to indexer, check the log for more details");
|
||||||
|
return new ValidationResult(new List<ValidationFailure> { failure });
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ValidationResult();
|
||||||
|
}
|
||||||
|
|
||||||
private static string NewsnabifyTitle(string title)
|
private static string NewsnabifyTitle(string title)
|
||||||
{
|
{
|
||||||
return title.Replace("+", "%20");
|
return title.Replace("+", "%20");
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers.Omgwtfnzbs
|
namespace NzbDrone.Core.Indexers.Omgwtfnzbs
|
||||||
{
|
{
|
||||||
|
@ -79,5 +81,10 @@ namespace NzbDrone.Core.Indexers.Omgwtfnzbs
|
||||||
{
|
{
|
||||||
return new List<string>();
|
return new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ValidationResult Test()
|
||||||
|
{
|
||||||
|
return new ValidationResult();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers.Wombles
|
namespace NzbDrone.Core.Indexers.Wombles
|
||||||
|
@ -46,5 +48,10 @@ namespace NzbDrone.Core.Indexers.Wombles
|
||||||
{
|
{
|
||||||
return new List<string>();
|
return new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ValidationResult Test()
|
||||||
|
{
|
||||||
|
return new ValidationResult();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,10 +1,8 @@
|
||||||
using System;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Metadata
|
namespace NzbDrone.Core.Metadata
|
||||||
{
|
{
|
||||||
public class MetadataDefinition : ProviderDefinition
|
public class MetadataDefinition : ProviderDefinition
|
||||||
{
|
{
|
||||||
public Boolean Enable { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.Metadata.Files;
|
using NzbDrone.Core.Metadata.Files;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
@ -27,6 +29,11 @@ namespace NzbDrone.Core.Metadata
|
||||||
|
|
||||||
public ProviderDefinition Definition { get; set; }
|
public ProviderDefinition Definition { get; set; }
|
||||||
|
|
||||||
|
public ValidationResult Test()
|
||||||
|
{
|
||||||
|
return new ValidationResult();
|
||||||
|
}
|
||||||
|
|
||||||
public abstract List<MetadataFile> AfterRename(Series series, List<MetadataFile> existingMetadataFiles, List<EpisodeFile> episodeFiles);
|
public abstract List<MetadataFile> AfterRename(Series series, List<MetadataFile> existingMetadataFiles, List<EpisodeFile> episodeFiles);
|
||||||
public abstract MetadataFile FindMetadataFile(Series series, string path);
|
public abstract MetadataFile FindMetadataFile(Series series, string path);
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Email
|
namespace NzbDrone.Core.Notifications.Email
|
||||||
{
|
{
|
||||||
public class Email : NotificationBase<EmailSettings>
|
public class Email : NotificationBase<EmailSettings>
|
||||||
{
|
{
|
||||||
private readonly IEmailService _smtpProvider;
|
private readonly IEmailService _emailService;
|
||||||
|
|
||||||
public Email(IEmailService smtpProvider)
|
public Email(IEmailService emailService)
|
||||||
{
|
{
|
||||||
_smtpProvider = smtpProvider;
|
_emailService = emailService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Link
|
public override string Link
|
||||||
|
@ -20,9 +23,9 @@ namespace NzbDrone.Core.Notifications.Email
|
||||||
public override void OnGrab(string message)
|
public override void OnGrab(string message)
|
||||||
{
|
{
|
||||||
const string subject = "NzbDrone [TV] - Grabbed";
|
const string subject = "NzbDrone [TV] - Grabbed";
|
||||||
var body = String.Format("{0} sent to SABnzbd queue.", message);
|
var body = String.Format("{0} sent to queue.", message);
|
||||||
|
|
||||||
_smtpProvider.SendEmail(Settings, subject, body);
|
_emailService.SendEmail(Settings, subject, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
|
@ -30,11 +33,20 @@ namespace NzbDrone.Core.Notifications.Email
|
||||||
const string subject = "NzbDrone [TV] - Downloaded";
|
const string subject = "NzbDrone [TV] - Downloaded";
|
||||||
var body = String.Format("{0} Downloaded and sorted.", message.Message);
|
var body = String.Format("{0} Downloaded and sorted.", message.Message);
|
||||||
|
|
||||||
_smtpProvider.SendEmail(Settings, subject, body);
|
_emailService.SendEmail(Settings, subject, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AfterRename(Series series)
|
public override void AfterRename(Series series)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ValidationResult Test()
|
||||||
|
{
|
||||||
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
||||||
|
failures.AddIfNotNull(_emailService.Test(Settings));
|
||||||
|
|
||||||
|
return new ValidationResult(failures);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Mail;
|
using System.Net.Mail;
|
||||||
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
using Omu.ValueInjecter;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Email
|
namespace NzbDrone.Core.Notifications.Email
|
||||||
{
|
{
|
||||||
public interface IEmailService
|
public interface IEmailService
|
||||||
{
|
{
|
||||||
void SendEmail(EmailSettings settings, string subject, string body, bool htmlBody = false);
|
void SendEmail(EmailSettings settings, string subject, string body, bool htmlBody = false);
|
||||||
|
ValidationFailure Test(EmailSettings settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class EmailService : IEmailService, IExecute<TestEmailCommand>
|
public class EmailService : IEmailService
|
||||||
{
|
{
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
@ -66,14 +66,21 @@ namespace NzbDrone.Core.Notifications.Email
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(TestEmailCommand message)
|
public ValidationFailure Test(EmailSettings settings)
|
||||||
{
|
{
|
||||||
var settings = new EmailSettings();
|
|
||||||
settings.InjectFrom(message);
|
|
||||||
|
|
||||||
const string body = "Success! You have properly configured your email notification settings";
|
const string body = "Success! You have properly configured your email notification settings";
|
||||||
|
|
||||||
SendEmail(settings, "NzbDrone - Test Notification", body);
|
try
|
||||||
|
{
|
||||||
|
SendEmail(settings, "NzbDrone - Test Notification", body);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.ErrorException("Unable to send test email: " + ex.Message, ex);
|
||||||
|
return new ValidationFailure("Server", "Unable to send test email");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Email
|
|
||||||
{
|
|
||||||
public class TestEmailCommand : Command
|
|
||||||
{
|
|
||||||
public override bool SendUpdatesToClient
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Server { get; set; }
|
|
||||||
public int Port { get; set; }
|
|
||||||
public bool Ssl { get; set; }
|
|
||||||
public string Username { get; set; }
|
|
||||||
public string Password { get; set; }
|
|
||||||
public string From { get; set; }
|
|
||||||
public string To { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +1,17 @@
|
||||||
using NzbDrone.Core.Tv;
|
using System.Collections.Generic;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Growl
|
namespace NzbDrone.Core.Notifications.Growl
|
||||||
{
|
{
|
||||||
public class Growl : NotificationBase<GrowlSettings>
|
public class Growl : NotificationBase<GrowlSettings>
|
||||||
{
|
{
|
||||||
private readonly IGrowlService _growlProvider;
|
private readonly IGrowlService _growlService;
|
||||||
|
|
||||||
public Growl(IGrowlService growlProvider)
|
public Growl(IGrowlService growlService)
|
||||||
{
|
{
|
||||||
_growlProvider = growlProvider;
|
_growlService = growlService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Link
|
public override string Link
|
||||||
|
@ -20,18 +23,27 @@ namespace NzbDrone.Core.Notifications.Growl
|
||||||
{
|
{
|
||||||
const string title = "Episode Grabbed";
|
const string title = "Episode Grabbed";
|
||||||
|
|
||||||
_growlProvider.SendNotification(title, message, "GRAB", Settings.Host, Settings.Port, Settings.Password);
|
_growlService.SendNotification(title, message, "GRAB", Settings.Host, Settings.Port, Settings.Password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Episode Downloaded";
|
const string title = "Episode Downloaded";
|
||||||
|
|
||||||
_growlProvider.SendNotification(title, message.Message, "DOWNLOAD", Settings.Host, Settings.Port, Settings.Password);
|
_growlService.SendNotification(title, message.Message, "DOWNLOAD", Settings.Host, Settings.Port, Settings.Password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AfterRename(Series series)
|
public override void AfterRename(Series series)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ValidationResult Test()
|
||||||
|
{
|
||||||
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
||||||
|
failures.AddIfNotNull(_growlService.Test(Settings));
|
||||||
|
|
||||||
|
return new ValidationResult(failures);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using FluentValidation.Results;
|
||||||
using Growl.Connector;
|
using Growl.Connector;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Instrumentation;
|
using NzbDrone.Common.Instrumentation;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
using GrowlNotification = Growl.Connector.Notification;
|
using GrowlNotification = Growl.Connector.Notification;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Growl
|
namespace NzbDrone.Core.Notifications.Growl
|
||||||
|
@ -13,18 +13,20 @@ namespace NzbDrone.Core.Notifications.Growl
|
||||||
public interface IGrowlService
|
public interface IGrowlService
|
||||||
{
|
{
|
||||||
void SendNotification(string title, string message, string notificationTypeName, string hostname, int port, string password);
|
void SendNotification(string title, string message, string notificationTypeName, string hostname, int port, string password);
|
||||||
|
ValidationFailure Test(GrowlSettings settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GrowlService : IGrowlService, IExecute<TestGrowlCommand>
|
public class GrowlService : IGrowlService
|
||||||
{
|
{
|
||||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
|
private readonly Logger _logger;
|
||||||
|
|
||||||
private readonly Application _growlApplication = new Application("NzbDrone");
|
private readonly Application _growlApplication = new Application("NzbDrone");
|
||||||
private GrowlConnector _growlConnector;
|
private GrowlConnector _growlConnector;
|
||||||
private readonly List<NotificationType> _notificationTypes;
|
private readonly List<NotificationType> _notificationTypes;
|
||||||
|
|
||||||
public GrowlService()
|
public GrowlService(Logger logger)
|
||||||
{
|
{
|
||||||
|
_logger = logger;
|
||||||
_notificationTypes = GetNotificationTypes();
|
_notificationTypes = GetNotificationTypes();
|
||||||
_growlApplication.Icon = "https://raw.github.com/NzbDrone/NzbDrone/master/Logo/64.png";
|
_growlApplication.Icon = "https://raw.github.com/NzbDrone/NzbDrone/master/Logo/64.png";
|
||||||
}
|
}
|
||||||
|
@ -36,13 +38,13 @@ namespace NzbDrone.Core.Notifications.Growl
|
||||||
|
|
||||||
_growlConnector = new GrowlConnector(password, hostname, port);
|
_growlConnector = new GrowlConnector(password, hostname, port);
|
||||||
|
|
||||||
Logger.Debug("Sending Notification to: {0}:{1}", hostname, port);
|
_logger.Debug("Sending Notification to: {0}:{1}", hostname, port);
|
||||||
_growlConnector.Notify(notification);
|
_growlConnector.Notify(notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Register(string host, int port, string password)
|
private void Register(string host, int port, string password)
|
||||||
{
|
{
|
||||||
Logger.Debug("Registering NzbDrone with Growl host: {0}:{1}", host, port);
|
_logger.Debug("Registering NzbDrone with Growl host: {0}:{1}", host, port);
|
||||||
_growlConnector = new GrowlConnector(password, host, port);
|
_growlConnector = new GrowlConnector(password, host, port);
|
||||||
_growlConnector.Register(_growlApplication, _notificationTypes.ToArray());
|
_growlConnector.Register(_growlApplication, _notificationTypes.ToArray());
|
||||||
}
|
}
|
||||||
|
@ -57,16 +59,26 @@ namespace NzbDrone.Core.Notifications.Growl
|
||||||
return notificationTypes;
|
return notificationTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(TestGrowlCommand message)
|
public ValidationFailure Test(GrowlSettings settings)
|
||||||
{
|
{
|
||||||
Register(message.Host, message.Port, message.Password);
|
try
|
||||||
|
{
|
||||||
|
Register(settings.Host, settings.Port, settings.Password);
|
||||||
|
|
||||||
const string title = "Test Notification";
|
const string title = "Test Notification";
|
||||||
const string body = "This is a test message from NzbDrone";
|
const string body = "This is a test message from NzbDrone";
|
||||||
|
|
||||||
Thread.Sleep(5000);
|
Thread.Sleep(5000);
|
||||||
|
|
||||||
SendNotification(title, body, "TEST", message.Host, message.Port, message.Password);
|
SendNotification(title, body, "TEST", settings.Host, settings.Port, settings.Password);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.ErrorException("Unable to send test message: " + ex.Message, ex);
|
||||||
|
return new ValidationFailure("Host", "Unable to send test message");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Growl
|
|
||||||
{
|
|
||||||
public class TestGrowlCommand : Command
|
|
||||||
{
|
|
||||||
public override bool SendUpdatesToClient
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public string Host { get; set; }
|
|
||||||
public int Port { get; set; }
|
|
||||||
public string Password { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
@ -24,6 +26,7 @@ namespace NzbDrone.Core.Notifications
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProviderDefinition Definition { get; set; }
|
public ProviderDefinition Definition { get; set; }
|
||||||
|
public abstract ValidationResult Test();
|
||||||
|
|
||||||
public abstract string Link { get; }
|
public abstract string Link { get; }
|
||||||
|
|
||||||
|
|
|
@ -8,5 +8,13 @@ namespace NzbDrone.Core.Notifications
|
||||||
public Boolean OnGrab { get; set; }
|
public Boolean OnGrab { get; set; }
|
||||||
public Boolean OnDownload { get; set; }
|
public Boolean OnDownload { get; set; }
|
||||||
public Boolean OnUpgrade { get; set; }
|
public Boolean OnUpgrade { get; set; }
|
||||||
|
|
||||||
|
public override Boolean Enable
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return OnGrab || OnDownload || OnUpgrade;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,19 @@
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.NotifyMyAndroid
|
namespace NzbDrone.Core.Notifications.NotifyMyAndroid
|
||||||
{
|
{
|
||||||
public class NotifyMyAndroid : NotificationBase<NotifyMyAndroidSettings>
|
public class NotifyMyAndroid : NotificationBase<NotifyMyAndroidSettings>
|
||||||
{
|
{
|
||||||
private readonly INotifyMyAndroidProxy _notifyMyAndroidProxy;
|
private readonly INotifyMyAndroidProxy _proxy;
|
||||||
|
|
||||||
public NotifyMyAndroid(INotifyMyAndroidProxy notifyMyAndroidProxy)
|
public NotifyMyAndroid(INotifyMyAndroidProxy proxy)
|
||||||
{
|
{
|
||||||
_notifyMyAndroidProxy = notifyMyAndroidProxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Link
|
public override string Link
|
||||||
|
@ -20,18 +25,27 @@ namespace NzbDrone.Core.Notifications.NotifyMyAndroid
|
||||||
{
|
{
|
||||||
const string title = "Episode Grabbed";
|
const string title = "Episode Grabbed";
|
||||||
|
|
||||||
_notifyMyAndroidProxy.SendNotification(title, message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
|
_proxy.SendNotification(title, message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Episode Downloaded";
|
const string title = "Episode Downloaded";
|
||||||
|
|
||||||
_notifyMyAndroidProxy.SendNotification(title, message.Message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
|
_proxy.SendNotification(title, message.Message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AfterRename(Series series)
|
public override void AfterRename(Series series)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ValidationResult Test()
|
||||||
|
{
|
||||||
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
||||||
|
failures.AddIfNotNull(_proxy.Test(Settings));
|
||||||
|
|
||||||
|
return new ValidationResult(failures);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
using NLog;
|
||||||
using NzbDrone.Core.Exceptions;
|
using NzbDrone.Core.Exceptions;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
using NzbDrone.Core.Rest;
|
using NzbDrone.Core.Rest;
|
||||||
|
|
||||||
|
@ -12,12 +13,19 @@ namespace NzbDrone.Core.Notifications.NotifyMyAndroid
|
||||||
public interface INotifyMyAndroidProxy
|
public interface INotifyMyAndroidProxy
|
||||||
{
|
{
|
||||||
void SendNotification(string title, string message, string apiKye, NotifyMyAndroidPriority priority);
|
void SendNotification(string title, string message, string apiKye, NotifyMyAndroidPriority priority);
|
||||||
|
ValidationFailure Test(NotifyMyAndroidSettings settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NotifyMyAndroidProxy : INotifyMyAndroidProxy, IExecute<TestNotifyMyAndroidCommand>
|
public class NotifyMyAndroidProxy : INotifyMyAndroidProxy
|
||||||
{
|
{
|
||||||
|
private readonly Logger _logger;
|
||||||
private const string URL = "https://www.notifymyandroid.com/publicapi";
|
private const string URL = "https://www.notifymyandroid.com/publicapi";
|
||||||
|
|
||||||
|
public NotifyMyAndroidProxy(Logger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
public void SendNotification(string title, string message, string apiKey, NotifyMyAndroidPriority priority)
|
public void SendNotification(string title, string message, string apiKey, NotifyMyAndroidPriority priority)
|
||||||
{
|
{
|
||||||
var client = new RestClient(URL);
|
var client = new RestClient(URL);
|
||||||
|
@ -56,12 +64,22 @@ namespace NzbDrone.Core.Notifications.NotifyMyAndroid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(TestNotifyMyAndroidCommand message)
|
public ValidationFailure Test(NotifyMyAndroidSettings settings)
|
||||||
{
|
{
|
||||||
const string title = "Test Notification";
|
try
|
||||||
const string body = "This is a test message from NzbDrone";
|
{
|
||||||
Verify(message.ApiKey);
|
const string title = "Test Notification";
|
||||||
SendNotification(title, body, message.ApiKey, (NotifyMyAndroidPriority)message.Priority);
|
const string body = "This is a test message from NzbDrone";
|
||||||
|
Verify(settings.ApiKey);
|
||||||
|
SendNotification(title, body, settings.ApiKey, (NotifyMyAndroidPriority)settings.Priority);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.ErrorException("Unable to send test message: " + ex.Message, ex);
|
||||||
|
return new ValidationFailure("ApiKey", "Unable to send test message");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace NzbDrone.Core.Notifications.NotifyMyAndroid
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return !String.IsNullOrWhiteSpace(ApiKey) && Priority != null & Priority >= -1 && Priority <= 2;
|
return !String.IsNullOrWhiteSpace(ApiKey) && Priority >= -1 && Priority <= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.NotifyMyAndroid
|
|
||||||
{
|
|
||||||
public class TestNotifyMyAndroidCommand : Command
|
|
||||||
{
|
|
||||||
|
|
||||||
public override bool SendUpdatesToClient
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public string ApiKey { get; set; }
|
|
||||||
public int Priority { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +1,17 @@
|
||||||
using NzbDrone.Core.Tv;
|
using System.Collections.Generic;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Plex
|
namespace NzbDrone.Core.Notifications.Plex
|
||||||
{
|
{
|
||||||
public class PlexClient : NotificationBase<PlexClientSettings>
|
public class PlexClient : NotificationBase<PlexClientSettings>
|
||||||
{
|
{
|
||||||
private readonly IPlexService _plexProvider;
|
private readonly IPlexService _plexService;
|
||||||
|
|
||||||
public PlexClient(IPlexService plexProvider)
|
public PlexClient(IPlexService plexService)
|
||||||
{
|
{
|
||||||
_plexProvider = plexProvider;
|
_plexService = plexService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Link
|
public override string Link
|
||||||
|
@ -19,17 +22,26 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
public override void OnGrab(string message)
|
public override void OnGrab(string message)
|
||||||
{
|
{
|
||||||
const string header = "NzbDrone [TV] - Grabbed";
|
const string header = "NzbDrone [TV] - Grabbed";
|
||||||
_plexProvider.Notify(Settings, header, message);
|
_plexService.Notify(Settings, header, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string header = "NzbDrone [TV] - Downloaded";
|
const string header = "NzbDrone [TV] - Downloaded";
|
||||||
_plexProvider.Notify(Settings, header, message.Message);
|
_plexService.Notify(Settings, header, message.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AfterRename(Series series)
|
public override void AfterRename(Series series)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ValidationResult Test()
|
||||||
|
{
|
||||||
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
||||||
|
failures.AddIfNotNull(_plexService.Test(Settings));
|
||||||
|
|
||||||
|
return new ValidationResult(failures);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
using NzbDrone.Core.Tv;
|
using System.Collections.Generic;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Plex
|
namespace NzbDrone.Core.Notifications.Plex
|
||||||
{
|
{
|
||||||
public class PlexServer : NotificationBase<PlexServerSettings>
|
public class PlexServer : NotificationBase<PlexServerSettings>
|
||||||
{
|
{
|
||||||
private readonly IPlexService _plexProvider;
|
private readonly IPlexService _plexService;
|
||||||
|
|
||||||
public PlexServer(IPlexService plexProvider)
|
public PlexServer(IPlexService plexService)
|
||||||
{
|
{
|
||||||
_plexProvider = plexProvider;
|
_plexService = plexService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Link
|
public override string Link
|
||||||
|
@ -34,8 +37,17 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
{
|
{
|
||||||
if (Settings.UpdateLibrary)
|
if (Settings.UpdateLibrary)
|
||||||
{
|
{
|
||||||
_plexProvider.UpdateLibrary(Settings);
|
_plexService.UpdateLibrary(Settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ValidationResult Test()
|
||||||
|
{
|
||||||
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
||||||
|
failures.AddIfNotNull(_plexService.Test(Settings));
|
||||||
|
|
||||||
|
return new ValidationResult(failures);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using FluentValidation.Results;
|
||||||
using System.Xml.Linq;
|
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Plex
|
namespace NzbDrone.Core.Notifications.Plex
|
||||||
{
|
{
|
||||||
|
@ -14,9 +11,11 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
{
|
{
|
||||||
void Notify(PlexClientSettings settings, string header, string message);
|
void Notify(PlexClientSettings settings, string header, string message);
|
||||||
void UpdateLibrary(PlexServerSettings settings);
|
void UpdateLibrary(PlexServerSettings settings);
|
||||||
|
ValidationFailure Test(PlexClientSettings settings);
|
||||||
|
ValidationFailure Test(PlexServerSettings settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PlexService : IPlexService, IExecute<TestPlexClientCommand>, IExecute<TestPlexServerCommand>
|
public class PlexService : IPlexService
|
||||||
{
|
{
|
||||||
private readonly IHttpProvider _httpProvider;
|
private readonly IHttpProvider _httpProvider;
|
||||||
private readonly IPlexServerProxy _plexServerProxy;
|
private readonly IPlexServerProxy _plexServerProxy;
|
||||||
|
@ -84,31 +83,51 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
return _httpProvider.DownloadString(url);
|
return _httpProvider.DownloadString(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(TestPlexClientCommand message)
|
public ValidationFailure Test(PlexClientSettings settings)
|
||||||
{
|
{
|
||||||
_logger.Debug("Sending Test Notifcation to Plex Client: {0}", message.Host);
|
try
|
||||||
var command = String.Format("ExecBuiltIn(Notification({0}, {1}))", "Test Notification", "Success! Notifications are setup correctly");
|
|
||||||
var result = SendCommand(message.Host, message.Port, command, message.Username, message.Password);
|
|
||||||
|
|
||||||
if (String.IsNullOrWhiteSpace(result) ||
|
|
||||||
result.IndexOf("error", StringComparison.InvariantCultureIgnoreCase) > -1)
|
|
||||||
{
|
{
|
||||||
throw new Exception("Unable to connect to Plex Client");
|
_logger.Debug("Sending Test Notifcation to Plex Client: {0}", settings.Host);
|
||||||
|
var command = String.Format("ExecBuiltIn(Notification({0}, {1}))", "Test Notification", "Success! Notifications are setup correctly");
|
||||||
|
var result = SendCommand(settings.Host, settings.Port, command, settings.Username, settings.Password);
|
||||||
|
|
||||||
|
if (String.IsNullOrWhiteSpace(result) ||
|
||||||
|
result.IndexOf("error", StringComparison.InvariantCultureIgnoreCase) > -1)
|
||||||
|
{
|
||||||
|
throw new Exception("Unable to connect to Plex Client");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.ErrorException("Unable to send test message: " + ex.Message, ex);
|
||||||
|
return new ValidationFailure("Host", "Unable to send test message");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(TestPlexServerCommand message)
|
public ValidationFailure Test(PlexServerSettings settings)
|
||||||
{
|
{
|
||||||
if (!GetSectionKeys(new PlexServerSettings
|
try
|
||||||
{
|
|
||||||
Host = message.Host,
|
|
||||||
Port = message.Port,
|
|
||||||
Username = message.Username,
|
|
||||||
Password = message.Password
|
|
||||||
}).Any())
|
|
||||||
{
|
{
|
||||||
throw new Exception("Unable to connect to Plex Server");
|
if (!GetSectionKeys(new PlexServerSettings
|
||||||
|
{
|
||||||
|
Host = settings.Host,
|
||||||
|
Port = settings.Port,
|
||||||
|
Username = settings.Username,
|
||||||
|
Password = settings.Password
|
||||||
|
}).Any())
|
||||||
|
{
|
||||||
|
throw new Exception("Unable to connect to Plex Server");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.ErrorException("Unable to connect to Plex Server: " + ex.Message, ex);
|
||||||
|
return new ValidationFailure("Host", "Unable to connect to Plex Server");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Plex
|
|
||||||
{
|
|
||||||
public class TestPlexClientCommand : Command
|
|
||||||
{
|
|
||||||
public override bool SendUpdatesToClient
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public string Host { get; set; }
|
|
||||||
public int Port { get; set; }
|
|
||||||
public string Username { get; set; }
|
|
||||||
public string Password { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Plex
|
|
||||||
{
|
|
||||||
public class TestPlexServerCommand : Command
|
|
||||||
{
|
|
||||||
public override bool SendUpdatesToClient
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Host { get; set; }
|
|
||||||
public int Port { get; set; }
|
|
||||||
public string Username { get; set; }
|
|
||||||
public string Password { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +1,18 @@
|
||||||
using NzbDrone.Core.Tv;
|
using System.Collections.Generic;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
using Prowlin;
|
using Prowlin;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Prowl
|
namespace NzbDrone.Core.Notifications.Prowl
|
||||||
{
|
{
|
||||||
public class Prowl : NotificationBase<ProwlSettings>
|
public class Prowl : NotificationBase<ProwlSettings>
|
||||||
{
|
{
|
||||||
private readonly IProwlService _prowlProvider;
|
private readonly IProwlService _prowlService;
|
||||||
|
|
||||||
public Prowl(IProwlService prowlProvider)
|
public Prowl(IProwlService prowlService)
|
||||||
{
|
{
|
||||||
_prowlProvider = prowlProvider;
|
_prowlService = prowlService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Link
|
public override string Link
|
||||||
|
@ -21,18 +24,27 @@ namespace NzbDrone.Core.Notifications.Prowl
|
||||||
{
|
{
|
||||||
const string title = "Episode Grabbed";
|
const string title = "Episode Grabbed";
|
||||||
|
|
||||||
_prowlProvider.SendNotification(title, message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
_prowlService.SendNotification(title, message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Episode Downloaded";
|
const string title = "Episode Downloaded";
|
||||||
|
|
||||||
_prowlProvider.SendNotification(title, message.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
_prowlService.SendNotification(title, message.Message, Settings.ApiKey, (NotificationPriority)Settings.Priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AfterRename(Series series)
|
public override void AfterRename(Series series)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ValidationResult Test()
|
||||||
|
{
|
||||||
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
||||||
|
failures.AddIfNotNull(_prowlService.Test(Settings));
|
||||||
|
|
||||||
|
return new ValidationResult(failures);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
using Prowlin;
|
using Prowlin;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Prowl
|
namespace NzbDrone.Core.Notifications.Prowl
|
||||||
|
@ -8,9 +8,10 @@ namespace NzbDrone.Core.Notifications.Prowl
|
||||||
public interface IProwlService
|
public interface IProwlService
|
||||||
{
|
{
|
||||||
void SendNotification(string title, string message, string apiKey, NotificationPriority priority = NotificationPriority.Normal, string url = null);
|
void SendNotification(string title, string message, string apiKey, NotificationPriority priority = NotificationPriority.Normal, string url = null);
|
||||||
|
ValidationFailure Test(ProwlSettings settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ProwlService : IProwlService, IExecute<TestProwlCommand>
|
public class ProwlService : IProwlService
|
||||||
{
|
{
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
@ -80,14 +81,24 @@ namespace NzbDrone.Core.Notifications.Prowl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(TestProwlCommand message)
|
public ValidationFailure Test(ProwlSettings settings)
|
||||||
{
|
{
|
||||||
Verify(message.ApiKey);
|
try
|
||||||
|
{
|
||||||
|
Verify(settings.ApiKey);
|
||||||
|
|
||||||
const string title = "Test Notification";
|
const string title = "Test Notification";
|
||||||
const string body = "This is a test message from NzbDrone";
|
const string body = "This is a test message from NzbDrone";
|
||||||
|
|
||||||
SendNotification(title, body, message.ApiKey);
|
SendNotification(title, body, settings.ApiKey);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.ErrorException("Unable to send test message: " + ex.Message, ex);
|
||||||
|
return new ValidationFailure("ApiKey", "Unable to send test message");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace NzbDrone.Core.Notifications.Prowl
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return !string.IsNullOrWhiteSpace(ApiKey) && Priority != null & Priority >= -2 && Priority <= 2;
|
return !string.IsNullOrWhiteSpace(ApiKey) && Priority >= -2 && Priority <= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Prowl
|
|
||||||
{
|
|
||||||
public class TestProwlCommand : Command
|
|
||||||
{
|
|
||||||
public override bool SendUpdatesToClient
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public string ApiKey { get; set; }
|
|
||||||
public int Priority { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +1,17 @@
|
||||||
using NzbDrone.Core.Tv;
|
using System.Collections.Generic;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.PushBullet
|
namespace NzbDrone.Core.Notifications.PushBullet
|
||||||
{
|
{
|
||||||
public class PushBullet : NotificationBase<PushBulletSettings>
|
public class PushBullet : NotificationBase<PushBulletSettings>
|
||||||
{
|
{
|
||||||
private readonly IPushBulletProxy _pushBulletProxy;
|
private readonly IPushBulletProxy _proxy;
|
||||||
|
|
||||||
public PushBullet(IPushBulletProxy pushBulletProxy)
|
public PushBullet(IPushBulletProxy proxy)
|
||||||
{
|
{
|
||||||
_pushBulletProxy = pushBulletProxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Link
|
public override string Link
|
||||||
|
@ -20,18 +23,27 @@ namespace NzbDrone.Core.Notifications.PushBullet
|
||||||
{
|
{
|
||||||
const string title = "Episode Grabbed";
|
const string title = "Episode Grabbed";
|
||||||
|
|
||||||
_pushBulletProxy.SendNotification(title, message, Settings.ApiKey, Settings.DeviceId);
|
_proxy.SendNotification(title, message, Settings.ApiKey, Settings.DeviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Episode Downloaded";
|
const string title = "Episode Downloaded";
|
||||||
|
|
||||||
_pushBulletProxy.SendNotification(title, message.Message, Settings.ApiKey, Settings.DeviceId);
|
_proxy.SendNotification(title, message.Message, Settings.ApiKey, Settings.DeviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AfterRename(Series series)
|
public override void AfterRename(Series series)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ValidationResult Test()
|
||||||
|
{
|
||||||
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
||||||
|
failures.AddIfNotNull(_proxy.Test(Settings));
|
||||||
|
|
||||||
|
return new ValidationResult(failures);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using System.Net;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
using NLog;
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
using NzbDrone.Core.Rest;
|
using NzbDrone.Core.Rest;
|
||||||
|
|
||||||
|
@ -8,12 +10,19 @@ namespace NzbDrone.Core.Notifications.PushBullet
|
||||||
public interface IPushBulletProxy
|
public interface IPushBulletProxy
|
||||||
{
|
{
|
||||||
void SendNotification(string title, string message, string apiKey, string deviceId);
|
void SendNotification(string title, string message, string apiKey, string deviceId);
|
||||||
|
ValidationFailure Test(PushBulletSettings settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PushBulletProxy : IPushBulletProxy, IExecute<TestPushBulletCommand>
|
public class PushBulletProxy : IPushBulletProxy
|
||||||
{
|
{
|
||||||
|
private readonly Logger _logger;
|
||||||
private const string URL = "https://api.pushbullet.com/api/pushes";
|
private const string URL = "https://api.pushbullet.com/api/pushes";
|
||||||
|
|
||||||
|
public PushBulletProxy(Logger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
public void SendNotification(string title, string message, string apiKey, string deviceId)
|
public void SendNotification(string title, string message, string apiKey, string deviceId)
|
||||||
{
|
{
|
||||||
var client = new RestClient(URL);
|
var client = new RestClient(URL);
|
||||||
|
@ -45,12 +54,33 @@ namespace NzbDrone.Core.Notifications.PushBullet
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(TestPushBulletCommand message)
|
public ValidationFailure Test(PushBulletSettings settings)
|
||||||
{
|
{
|
||||||
const string title = "Test Notification";
|
try
|
||||||
const string body = "This is a test message from NzbDrone";
|
{
|
||||||
|
const string title = "Test Notification";
|
||||||
|
const string body = "This is a test message from NzbDrone";
|
||||||
|
|
||||||
SendNotification(title, body, message.ApiKey, message.DeviceId);
|
SendNotification(title, body, settings.ApiKey, settings.DeviceId);
|
||||||
|
}
|
||||||
|
catch (RestException ex)
|
||||||
|
{
|
||||||
|
if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
|
||||||
|
{
|
||||||
|
_logger.ErrorException("API Key is invalid: " + ex.Message, ex);
|
||||||
|
return new ValidationFailure("ApiKey", "API Key is invalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.ErrorException("Unable to send test message: " + ex.Message, ex);
|
||||||
|
return new ValidationFailure("ApiKey", "Unable to send test message");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.ErrorException("Unable to send test message: " + ex.Message, ex);
|
||||||
|
return new ValidationFailure("", "Unable to send test message");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.PushBullet
|
|
||||||
{
|
|
||||||
public class TestPushBulletCommand : Command
|
|
||||||
{
|
|
||||||
|
|
||||||
public override bool SendUpdatesToClient
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public string ApiKey { get; set; }
|
|
||||||
public string DeviceId { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +1,17 @@
|
||||||
using NzbDrone.Core.Tv;
|
using System.Collections.Generic;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Pushover
|
namespace NzbDrone.Core.Notifications.Pushover
|
||||||
{
|
{
|
||||||
public class Pushover : NotificationBase<PushoverSettings>
|
public class Pushover : NotificationBase<PushoverSettings>
|
||||||
{
|
{
|
||||||
private readonly IPushoverProxy _pushoverProxy;
|
private readonly IPushoverProxy _proxy;
|
||||||
|
|
||||||
public Pushover(IPushoverProxy pushoverProxy)
|
public Pushover(IPushoverProxy proxy)
|
||||||
{
|
{
|
||||||
_pushoverProxy = pushoverProxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Link
|
public override string Link
|
||||||
|
@ -20,18 +23,27 @@ namespace NzbDrone.Core.Notifications.Pushover
|
||||||
{
|
{
|
||||||
const string title = "Episode Grabbed";
|
const string title = "Episode Grabbed";
|
||||||
|
|
||||||
_pushoverProxy.SendNotification(title, message, Settings.ApiKey, Settings.UserKey, (PushoverPriority)Settings.Priority, Settings.Sound);
|
_proxy.SendNotification(title, message, Settings.ApiKey, Settings.UserKey, (PushoverPriority)Settings.Priority, Settings.Sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(DownloadMessage message)
|
public override void OnDownload(DownloadMessage message)
|
||||||
{
|
{
|
||||||
const string title = "Episode Downloaded";
|
const string title = "Episode Downloaded";
|
||||||
|
|
||||||
_pushoverProxy.SendNotification(title, message.Message, Settings.ApiKey, Settings.UserKey, (PushoverPriority)Settings.Priority, Settings.Sound);
|
_proxy.SendNotification(title, message.Message, Settings.ApiKey, Settings.UserKey, (PushoverPriority)Settings.Priority, Settings.Sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AfterRename(Series series)
|
public override void AfterRename(Series series)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ValidationResult Test()
|
||||||
|
{
|
||||||
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
||||||
|
failures.AddIfNotNull(_proxy.Test(Settings));
|
||||||
|
|
||||||
|
return new ValidationResult(failures);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using NzbDrone.Common;
|
using System;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using FluentValidation.Results;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common;
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
using NzbDrone.Core.Rest;
|
using NzbDrone.Core.Rest;
|
||||||
|
|
||||||
|
@ -8,12 +10,19 @@ namespace NzbDrone.Core.Notifications.Pushover
|
||||||
public interface IPushoverProxy
|
public interface IPushoverProxy
|
||||||
{
|
{
|
||||||
void SendNotification(string title, string message, string apiKey, string userKey, PushoverPriority priority, string sound);
|
void SendNotification(string title, string message, string apiKey, string userKey, PushoverPriority priority, string sound);
|
||||||
|
ValidationFailure Test(PushoverSettings settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PushoverProxy : IPushoverProxy, IExecute<TestPushoverCommand>
|
public class PushoverProxy : IPushoverProxy
|
||||||
{
|
{
|
||||||
|
private readonly Logger _logger;
|
||||||
private const string URL = "https://api.pushover.net/1/messages.json";
|
private const string URL = "https://api.pushover.net/1/messages.json";
|
||||||
|
|
||||||
|
public PushoverProxy(Logger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
public void SendNotification(string title, string message, string apiKey, string userKey, PushoverPriority priority, string sound)
|
public void SendNotification(string title, string message, string apiKey, string userKey, PushoverPriority priority, string sound)
|
||||||
{
|
{
|
||||||
var client = new RestClient(URL);
|
var client = new RestClient(URL);
|
||||||
|
@ -30,12 +39,22 @@ namespace NzbDrone.Core.Notifications.Pushover
|
||||||
client.ExecuteAndValidate(request);
|
client.ExecuteAndValidate(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(TestPushoverCommand message)
|
public ValidationFailure Test(PushoverSettings settings)
|
||||||
{
|
{
|
||||||
const string title = "Test Notification";
|
try
|
||||||
const string body = "This is a test message from NzbDrone";
|
{
|
||||||
|
const string title = "Test Notification";
|
||||||
|
const string body = "This is a test message from NzbDrone";
|
||||||
|
|
||||||
SendNotification(title, body, message.ApiKey, message.UserKey, (PushoverPriority)message.Priority, message.Sound);
|
SendNotification(title, body, settings.ApiKey, settings.UserKey, (PushoverPriority)settings.Priority, settings.Sound);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.ErrorException("Unable to send test message: " + ex.Message, ex);
|
||||||
|
return new ValidationFailure("ApiKey", "Unable to send test message");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Pushover
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return !string.IsNullOrWhiteSpace(UserKey) && Priority != null & Priority >= -1 && Priority <= 2;
|
return !string.IsNullOrWhiteSpace(UserKey) && Priority >= -1 && Priority <= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Pushover
|
|
||||||
{
|
|
||||||
public class TestPushoverCommand : Command
|
|
||||||
{
|
|
||||||
|
|
||||||
public override bool SendUpdatesToClient
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ApiKey { get; set; }
|
|
||||||
public string UserKey { get; set; }
|
|
||||||
public int Priority { get; set; }
|
|
||||||
public string Sound { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Xbmc
|
|
||||||
{
|
|
||||||
public class TestXbmcCommand : Command
|
|
||||||
{
|
|
||||||
public override bool SendUpdatesToClient
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Host { get; set; }
|
|
||||||
public int Port { get; set; }
|
|
||||||
public string Username { get; set; }
|
|
||||||
public string Password { get; set; }
|
|
||||||
public int DisplayTime { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +1,18 @@
|
||||||
using System.Linq;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Xbmc
|
namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
{
|
{
|
||||||
public class Xbmc : NotificationBase<XbmcSettings>
|
public class Xbmc : NotificationBase<XbmcSettings>
|
||||||
{
|
{
|
||||||
private readonly IXbmcService _xbmcProvider;
|
private readonly IXbmcService _xbmcService;
|
||||||
|
|
||||||
public Xbmc(IXbmcService xbmcProvider)
|
public Xbmc(IXbmcService xbmcService)
|
||||||
{
|
{
|
||||||
_xbmcProvider = xbmcProvider;
|
_xbmcService = xbmcService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Link
|
public override string Link
|
||||||
|
@ -23,7 +26,7 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
|
|
||||||
if (Settings.Notify)
|
if (Settings.Notify)
|
||||||
{
|
{
|
||||||
_xbmcProvider.Notify(Settings, header, message);
|
_xbmcService.Notify(Settings, header, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +36,7 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
|
|
||||||
if (Settings.Notify)
|
if (Settings.Notify)
|
||||||
{
|
{
|
||||||
_xbmcProvider.Notify(Settings, header, message.Message);
|
_xbmcService.Notify(Settings, header, message.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateAndClean(message.Series, message.OldFiles.Any());
|
UpdateAndClean(message.Series, message.OldFiles.Any());
|
||||||
|
@ -44,16 +47,25 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
UpdateAndClean(series);
|
UpdateAndClean(series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ValidationResult Test()
|
||||||
|
{
|
||||||
|
var failures = new List<ValidationFailure>();
|
||||||
|
|
||||||
|
failures.AddIfNotNull(_xbmcService.Test(Settings));
|
||||||
|
|
||||||
|
return new ValidationResult(failures);
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateAndClean(Series series, bool clean = true)
|
private void UpdateAndClean(Series series, bool clean = true)
|
||||||
{
|
{
|
||||||
if (Settings.UpdateLibrary)
|
if (Settings.UpdateLibrary)
|
||||||
{
|
{
|
||||||
_xbmcProvider.Update(Settings, series);
|
_xbmcService.Update(Settings, series);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clean && Settings.CleanLibrary)
|
if (clean && Settings.CleanLibrary)
|
||||||
{
|
{
|
||||||
_xbmcProvider.Clean(Settings);
|
_xbmcService.Clean(Settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using FluentValidation.Results;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Common.Instrumentation;
|
using NzbDrone.Common.Instrumentation;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
|
||||||
using NzbDrone.Core.Notifications.Xbmc.Model;
|
using NzbDrone.Core.Notifications.Xbmc.Model;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
@ -19,18 +18,20 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
void Update(XbmcSettings settings, Series series);
|
void Update(XbmcSettings settings, Series series);
|
||||||
void Clean(XbmcSettings settings);
|
void Clean(XbmcSettings settings);
|
||||||
XbmcVersion GetJsonVersion(XbmcSettings settings);
|
XbmcVersion GetJsonVersion(XbmcSettings settings);
|
||||||
|
ValidationFailure Test(XbmcSettings settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class XbmcService : IXbmcService, IExecute<TestXbmcCommand>
|
public class XbmcService : IXbmcService
|
||||||
{
|
{
|
||||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
|
|
||||||
private readonly IHttpProvider _httpProvider;
|
private readonly IHttpProvider _httpProvider;
|
||||||
private readonly IEnumerable<IApiProvider> _apiProviders;
|
private readonly IEnumerable<IApiProvider> _apiProviders;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public XbmcService(IHttpProvider httpProvider, IEnumerable<IApiProvider> apiProviders)
|
public XbmcService(IHttpProvider httpProvider, IEnumerable<IApiProvider> apiProviders, Logger logger)
|
||||||
{
|
{
|
||||||
_httpProvider = httpProvider;
|
_httpProvider = httpProvider;
|
||||||
_apiProviders = apiProviders;
|
_apiProviders = apiProviders;
|
||||||
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Notify(XbmcSettings settings, string title, string message)
|
public void Notify(XbmcSettings settings, string title, string message)
|
||||||
|
@ -62,7 +63,7 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
|
|
||||||
var response = _httpProvider.PostCommand(settings.Address, settings.Username, settings.Password, postJson.ToString());
|
var response = _httpProvider.PostCommand(settings.Address, settings.Username, settings.Password, postJson.ToString());
|
||||||
|
|
||||||
Logger.Debug("Getting version from response: " + response);
|
_logger.Debug("Getting version from response: " + response);
|
||||||
var result = Json.Deserialize<XbmcJsonResult<JObject>>(response);
|
var result = Json.Deserialize<XbmcJsonResult<JObject>>(response);
|
||||||
|
|
||||||
var versionObject = result.Result.Property("version");
|
var versionObject = result.Result.Property("version");
|
||||||
|
@ -78,7 +79,7 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.DebugException(ex.Message, ex);
|
_logger.DebugException(ex.Message, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new XbmcVersion();
|
return new XbmcVersion();
|
||||||
|
@ -98,27 +99,28 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
return apiProvider;
|
return apiProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(TestXbmcCommand message)
|
public ValidationFailure Test(XbmcSettings settings)
|
||||||
{
|
{
|
||||||
var settings = new XbmcSettings
|
try
|
||||||
{
|
|
||||||
Host = message.Host,
|
|
||||||
Port = message.Port,
|
|
||||||
Username = message.Username,
|
|
||||||
Password = message.Password,
|
|
||||||
DisplayTime = message.DisplayTime
|
|
||||||
};
|
|
||||||
|
|
||||||
Logger.Debug("Determining version of XBMC Host: {0}", settings.Address);
|
|
||||||
var version = GetJsonVersion(settings);
|
|
||||||
Logger.Debug("Version is: {0}", version);
|
|
||||||
|
|
||||||
if (version == new XbmcVersion(0))
|
|
||||||
{
|
{
|
||||||
throw new InvalidXbmcVersionException("Verion received from XBMC is invalid, please correct your settings.");
|
_logger.Debug("Determining version of XBMC Host: {0}", settings.Address);
|
||||||
|
var version = GetJsonVersion(settings);
|
||||||
|
_logger.Debug("Version is: {0}", version);
|
||||||
|
|
||||||
|
if (version == new XbmcVersion(0))
|
||||||
|
{
|
||||||
|
throw new InvalidXbmcVersionException("Verion received from XBMC is invalid, please correct your settings.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Notify(settings, "Test Notification", "Success! XBMC has been successfully configured!");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.ErrorException("Unable to send test message: " + ex.Message, ex);
|
||||||
|
return new ValidationFailure("Host", "Unable to send test message");
|
||||||
}
|
}
|
||||||
|
|
||||||
Notify(settings, "Test Notification", "Success! XBMC has been successfully configured!");
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -253,21 +253,17 @@
|
||||||
<Compile Include="Download\Clients\Nzbget\NzbgetPostQueueItem.cs" />
|
<Compile Include="Download\Clients\Nzbget\NzbgetPostQueueItem.cs" />
|
||||||
<Compile Include="Download\Clients\Sabnzbd\SabnzbdDownloadStatus.cs" />
|
<Compile Include="Download\Clients\Sabnzbd\SabnzbdDownloadStatus.cs" />
|
||||||
<Compile Include="Download\Clients\UsenetBlackhole\UsenetBlackhole.cs" />
|
<Compile Include="Download\Clients\UsenetBlackhole\UsenetBlackhole.cs" />
|
||||||
<Compile Include="Download\Clients\UsenetBlackhole\TestUsenetBlackholeCommand.cs" />
|
|
||||||
<Compile Include="Download\Clients\UsenetBlackhole\UsenetBlackholeSettings.cs" />
|
<Compile Include="Download\Clients\UsenetBlackhole\UsenetBlackholeSettings.cs" />
|
||||||
<Compile Include="Download\Clients\DownloadClientException.cs" />
|
<Compile Include="Download\Clients\DownloadClientException.cs" />
|
||||||
<Compile Include="Download\Clients\Pneumatic\PneumaticSettings.cs" />
|
<Compile Include="Download\Clients\Pneumatic\PneumaticSettings.cs" />
|
||||||
<Compile Include="Download\Clients\Nzbget\NzbgetHistoryItem.cs" />
|
<Compile Include="Download\Clients\Nzbget\NzbgetHistoryItem.cs" />
|
||||||
<Compile Include="Download\Clients\Nzbget\NzbgetParameter.cs" />
|
<Compile Include="Download\Clients\Nzbget\NzbgetParameter.cs" />
|
||||||
<Compile Include="Download\Clients\Nzbget\NzbgetSettings.cs" />
|
<Compile Include="Download\Clients\Nzbget\NzbgetSettings.cs" />
|
||||||
<Compile Include="Download\Clients\Nzbget\TestNzbgetCommand.cs" />
|
|
||||||
<Compile Include="Download\Clients\Pneumatic\Pneumatic.cs" />
|
<Compile Include="Download\Clients\Pneumatic\Pneumatic.cs" />
|
||||||
<Compile Include="Download\Clients\Pneumatic\TestPneumaticCommand.cs" />
|
|
||||||
<Compile Include="Download\Clients\Sabnzbd\Responses\SabnzbdAddResponse.cs" />
|
<Compile Include="Download\Clients\Sabnzbd\Responses\SabnzbdAddResponse.cs" />
|
||||||
<Compile Include="Download\Clients\Sabnzbd\Responses\SabnzbdCategoryResponse.cs" />
|
<Compile Include="Download\Clients\Sabnzbd\Responses\SabnzbdCategoryResponse.cs" />
|
||||||
<Compile Include="Download\Clients\Sabnzbd\Responses\SabnzbdVersionResponse.cs" />
|
<Compile Include="Download\Clients\Sabnzbd\Responses\SabnzbdVersionResponse.cs" />
|
||||||
<Compile Include="Download\Clients\Sabnzbd\SabnzbdSettings.cs" />
|
<Compile Include="Download\Clients\Sabnzbd\SabnzbdSettings.cs" />
|
||||||
<Compile Include="Download\Clients\Sabnzbd\TestSabnzbdCommand.cs" />
|
|
||||||
<Compile Include="Download\CompletedDownloadService.cs" />
|
<Compile Include="Download\CompletedDownloadService.cs" />
|
||||||
<Compile Include="Download\DownloadClientBase.cs" />
|
<Compile Include="Download\DownloadClientBase.cs" />
|
||||||
<Compile Include="Download\DownloadClientDefinition.cs" />
|
<Compile Include="Download\DownloadClientDefinition.cs" />
|
||||||
|
@ -419,12 +415,10 @@
|
||||||
<Compile Include="Notifications\PushBullet\PushBullet.cs" />
|
<Compile Include="Notifications\PushBullet\PushBullet.cs" />
|
||||||
<Compile Include="Notifications\PushBullet\PushBulletProxy.cs" />
|
<Compile Include="Notifications\PushBullet\PushBulletProxy.cs" />
|
||||||
<Compile Include="Notifications\PushBullet\PushBulletSettings.cs" />
|
<Compile Include="Notifications\PushBullet\PushBulletSettings.cs" />
|
||||||
<Compile Include="Notifications\PushBullet\TestPushBulletCommand.cs" />
|
|
||||||
<Compile Include="Notifications\NotifyMyAndroid\NotifyMyAndroid.cs" />
|
<Compile Include="Notifications\NotifyMyAndroid\NotifyMyAndroid.cs" />
|
||||||
<Compile Include="Notifications\NotifyMyAndroid\NotifyMyAndroidPriority.cs" />
|
<Compile Include="Notifications\NotifyMyAndroid\NotifyMyAndroidPriority.cs" />
|
||||||
<Compile Include="Notifications\NotifyMyAndroid\NotifyMyAndroidProxy.cs" />
|
<Compile Include="Notifications\NotifyMyAndroid\NotifyMyAndroidProxy.cs" />
|
||||||
<Compile Include="Notifications\NotifyMyAndroid\NotifyMyAndroidSettings.cs" />
|
<Compile Include="Notifications\NotifyMyAndroid\NotifyMyAndroidSettings.cs" />
|
||||||
<Compile Include="Notifications\NotifyMyAndroid\TestNotifyMyAndroidCommand.cs" />
|
|
||||||
<Compile Include="MediaFiles\Commands\BackendCommandAttribute.cs" />
|
<Compile Include="MediaFiles\Commands\BackendCommandAttribute.cs" />
|
||||||
<Compile Include="Messaging\Commands\BackendCommandAttribute.cs" />
|
<Compile Include="Messaging\Commands\BackendCommandAttribute.cs" />
|
||||||
<Compile Include="Messaging\Commands\Command.cs" />
|
<Compile Include="Messaging\Commands\Command.cs" />
|
||||||
|
@ -480,9 +474,7 @@
|
||||||
<Compile Include="MediaFiles\RenameEpisodeFileService.cs" />
|
<Compile Include="MediaFiles\RenameEpisodeFileService.cs" />
|
||||||
<Compile Include="MediaFiles\SameFilenameException.cs" />
|
<Compile Include="MediaFiles\SameFilenameException.cs" />
|
||||||
<Compile Include="MediaFiles\UpgradeMediaFileService.cs" />
|
<Compile Include="MediaFiles\UpgradeMediaFileService.cs" />
|
||||||
<Compile Include="Notifications\Email\TestEmailCommand.cs" />
|
|
||||||
<Compile Include="Notifications\Growl\GrowlSettings.cs" />
|
<Compile Include="Notifications\Growl\GrowlSettings.cs" />
|
||||||
<Compile Include="Notifications\Growl\TestGrowlCommand.cs" />
|
|
||||||
<Compile Include="Notifications\INotification.cs" />
|
<Compile Include="Notifications\INotification.cs" />
|
||||||
<Compile Include="Notifications\NotificationRepository.cs" />
|
<Compile Include="Notifications\NotificationRepository.cs" />
|
||||||
<Compile Include="Fluent.cs" />
|
<Compile Include="Fluent.cs" />
|
||||||
|
@ -523,27 +515,22 @@
|
||||||
<Compile Include="MetadataSource\Trakt\Images.cs" />
|
<Compile Include="MetadataSource\Trakt\Images.cs" />
|
||||||
<Compile Include="MetadataSource\Trakt\Season.cs" />
|
<Compile Include="MetadataSource\Trakt\Season.cs" />
|
||||||
<Compile Include="MetadataSource\Trakt\FullShow.cs" />
|
<Compile Include="MetadataSource\Trakt\FullShow.cs" />
|
||||||
<Compile Include="Notifications\Plex\TestPlexServerCommand.cs" />
|
|
||||||
<Compile Include="Notifications\Plex\PlexServer.cs" />
|
<Compile Include="Notifications\Plex\PlexServer.cs" />
|
||||||
<Compile Include="Notifications\Plex\PlexClientSettings.cs" />
|
<Compile Include="Notifications\Plex\PlexClientSettings.cs" />
|
||||||
<Compile Include="Notifications\Plex\PlexServerSettings.cs" />
|
<Compile Include="Notifications\Plex\PlexServerSettings.cs" />
|
||||||
<Compile Include="Notifications\Plex\TestPlexClientCommand.cs" />
|
|
||||||
<Compile Include="Notifications\Prowl\InvalidApiKeyException.cs" />
|
<Compile Include="Notifications\Prowl\InvalidApiKeyException.cs" />
|
||||||
<Compile Include="Notifications\Prowl\ProwlPriority.cs" />
|
<Compile Include="Notifications\Prowl\ProwlPriority.cs" />
|
||||||
<Compile Include="Notifications\Prowl\ProwlSettings.cs" />
|
<Compile Include="Notifications\Prowl\ProwlSettings.cs" />
|
||||||
<Compile Include="Notifications\Email\EmailSettings.cs" />
|
<Compile Include="Notifications\Email\EmailSettings.cs" />
|
||||||
<Compile Include="Notifications\Prowl\TestProwlCommand.cs" />
|
|
||||||
<Compile Include="Notifications\Pushover\InvalidResponseException.cs" />
|
<Compile Include="Notifications\Pushover\InvalidResponseException.cs" />
|
||||||
<Compile Include="Notifications\Pushover\Pushover.cs" />
|
<Compile Include="Notifications\Pushover\Pushover.cs" />
|
||||||
<Compile Include="Notifications\Pushover\PushoverPriority.cs" />
|
<Compile Include="Notifications\Pushover\PushoverPriority.cs" />
|
||||||
<Compile Include="Notifications\Pushover\PushoverService.cs" />
|
<Compile Include="Notifications\Pushover\PushoverService.cs" />
|
||||||
<Compile Include="Notifications\Pushover\PushoverSettings.cs" />
|
<Compile Include="Notifications\Pushover\PushoverSettings.cs" />
|
||||||
<Compile Include="Notifications\Pushover\TestPushoverCommand.cs" />
|
|
||||||
<Compile Include="Notifications\Xbmc\HttpApiProvider.cs" />
|
<Compile Include="Notifications\Xbmc\HttpApiProvider.cs" />
|
||||||
<Compile Include="Notifications\Xbmc\IApiProvider.cs" />
|
<Compile Include="Notifications\Xbmc\IApiProvider.cs" />
|
||||||
<Compile Include="Notifications\Xbmc\InvalidXbmcVersionException.cs" />
|
<Compile Include="Notifications\Xbmc\InvalidXbmcVersionException.cs" />
|
||||||
<Compile Include="Notifications\Xbmc\JsonApiProvider.cs" />
|
<Compile Include="Notifications\Xbmc\JsonApiProvider.cs" />
|
||||||
<Compile Include="Notifications\Xbmc\TestXbmcCommand.cs" />
|
|
||||||
<Compile Include="Notifications\Xbmc\XbmcSettings.cs" />
|
<Compile Include="Notifications\Xbmc\XbmcSettings.cs" />
|
||||||
<Compile Include="Organizer\EpisodeSortingType.cs" />
|
<Compile Include="Organizer\EpisodeSortingType.cs" />
|
||||||
<Compile Include="Organizer\FileNameBuilder.cs" />
|
<Compile Include="Organizer\FileNameBuilder.cs" />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using FluentValidation.Results;
|
||||||
|
|
||||||
namespace NzbDrone.Core.ThingiProvider
|
namespace NzbDrone.Core.ThingiProvider
|
||||||
{
|
{
|
||||||
|
@ -10,5 +10,6 @@ namespace NzbDrone.Core.ThingiProvider
|
||||||
|
|
||||||
IEnumerable<ProviderDefinition> DefaultDefinitions { get; }
|
IEnumerable<ProviderDefinition> DefaultDefinitions { get; }
|
||||||
ProviderDefinition Definition { get; set; }
|
ProviderDefinition Definition { get; set; }
|
||||||
|
ValidationResult Test();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
using FluentValidation.Results;
|
||||||
|
|
||||||
namespace NzbDrone.Core.ThingiProvider
|
namespace NzbDrone.Core.ThingiProvider
|
||||||
{
|
{
|
||||||
|
@ -10,10 +10,11 @@ namespace NzbDrone.Core.ThingiProvider
|
||||||
List<TProviderDefinition> All();
|
List<TProviderDefinition> All();
|
||||||
List<TProvider> GetAvailableProviders();
|
List<TProvider> GetAvailableProviders();
|
||||||
TProviderDefinition Get(int id);
|
TProviderDefinition Get(int id);
|
||||||
TProviderDefinition Create(TProviderDefinition indexer);
|
TProviderDefinition Create(TProviderDefinition definition);
|
||||||
void Update(TProviderDefinition indexer);
|
void Update(TProviderDefinition definition);
|
||||||
void Delete(int id);
|
void Delete(int id);
|
||||||
IEnumerable<TProviderDefinition> GetDefaultDefinitions();
|
IEnumerable<TProviderDefinition> GetDefaultDefinitions();
|
||||||
IEnumerable<TProviderDefinition> GetPresetDefinitions(TProviderDefinition providerDefinition);
|
IEnumerable<TProviderDefinition> GetPresetDefinitions(TProviderDefinition providerDefinition);
|
||||||
|
ValidationResult Test(TProviderDefinition definition);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,14 +1,16 @@
|
||||||
using NzbDrone.Core.Datastore;
|
using System;
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
|
|
||||||
namespace NzbDrone.Core.ThingiProvider
|
namespace NzbDrone.Core.ThingiProvider
|
||||||
{
|
{
|
||||||
public abstract class ProviderDefinition : ModelBase
|
public abstract class ProviderDefinition : ModelBase
|
||||||
{
|
{
|
||||||
private IProviderConfig _settings;
|
private IProviderConfig _settings;
|
||||||
public string Name { get; set; }
|
|
||||||
public string Implementation { get; set; }
|
|
||||||
|
|
||||||
public string ConfigContract { get; set; }
|
public String Name { get; set; }
|
||||||
|
public String Implementation { get; set; }
|
||||||
|
public String ConfigContract { get; set; }
|
||||||
|
public virtual Boolean Enable { get; set; }
|
||||||
|
|
||||||
public IProviderConfig Settings
|
public IProviderConfig Settings
|
||||||
{
|
{
|
||||||
|
@ -26,4 +28,4 @@ namespace NzbDrone.Core.ThingiProvider
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using FluentValidation.Results;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Composition;
|
using NzbDrone.Common.Composition;
|
||||||
using NzbDrone.Core.Lifecycle;
|
using NzbDrone.Core.Lifecycle;
|
||||||
|
@ -75,6 +76,11 @@ namespace NzbDrone.Core.ThingiProvider
|
||||||
return definitions;
|
return definitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ValidationResult Test(TProviderDefinition definition)
|
||||||
|
{
|
||||||
|
return GetInstance(definition).Test();
|
||||||
|
}
|
||||||
|
|
||||||
public List<TProvider> GetAvailableProviders()
|
public List<TProvider> GetAvailableProviders()
|
||||||
{
|
{
|
||||||
return Active().Select(GetInstance).ToList();
|
return Active().Select(GetInstance).ToList();
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
define([
|
define([
|
||||||
'backbone.deepmodel'
|
'Settings/ProviderSettingsModelBase'
|
||||||
], function (DeepModel) {
|
], function (ProviderSettingsModelBase) {
|
||||||
return DeepModel.DeepModel.extend({
|
return ProviderSettingsModelBase.extend({
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -78,14 +78,7 @@ define([
|
||||||
},
|
},
|
||||||
|
|
||||||
_test: function () {
|
_test: function () {
|
||||||
var testCommand = 'test{0}'.format(this.model.get('implementation'));
|
this.model.test();
|
||||||
var properties = {};
|
|
||||||
|
|
||||||
_.each(this.model.get('fields'), function (field) {
|
|
||||||
properties[field.name] = field.value;
|
|
||||||
});
|
|
||||||
|
|
||||||
CommandController.Execute(testCommand, properties);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -82,14 +82,7 @@ define([
|
||||||
},
|
},
|
||||||
|
|
||||||
_test: function () {
|
_test: function () {
|
||||||
var testCommand = 'test{0}'.format(this.model.get('implementation'));
|
this.model.test();
|
||||||
var properties = {};
|
|
||||||
|
|
||||||
_.each(this.model.get('fields'), function (field) {
|
|
||||||
properties[field.name] = field.value;
|
|
||||||
});
|
|
||||||
|
|
||||||
CommandController.Execute(testCommand, properties);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -46,8 +46,7 @@
|
||||||
<button class="btn pull-left x-back">back</button>
|
<button class="btn pull-left x-back">back</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<!-- Testing is currently not yet supported for indexers, but leaving the infrastructure for later -->
|
<button class="btn x-test">test <i class="x-test-icon icon-nd-test"/></button>
|
||||||
<!-- <button class="btn x-test">test <i class="x-test-icon icon-nd-test"/></button> -->
|
|
||||||
<button class="btn x-close">cancel</button>
|
<button class="btn x-close">cancel</button>
|
||||||
|
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
define([
|
define([
|
||||||
'backbone.deepmodel'
|
'Settings/ProviderSettingsModelBase'
|
||||||
], function (DeepModel) {
|
], function (ProviderSettingsModelBase) {
|
||||||
return DeepModel.DeepModel.extend({
|
return ProviderSettingsModelBase.extend({
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
define(
|
|
||||||
[
|
|
||||||
'backbone.deepmodel'
|
|
||||||
], function (DeepModel) {
|
|
||||||
return DeepModel.DeepModel.extend({
|
|
||||||
|
|
||||||
});
|
define([
|
||||||
|
'Settings/ProviderSettingsModelBase'
|
||||||
|
], function (ProviderSettingsModelBase) {
|
||||||
|
return ProviderSettingsModelBase.extend({
|
||||||
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
|
@ -83,14 +83,7 @@ define([
|
||||||
},
|
},
|
||||||
|
|
||||||
_test: function () {
|
_test: function () {
|
||||||
var testCommand = 'test{0}'.format(this.model.get('implementation'));
|
this.model.test();
|
||||||
var properties = {};
|
|
||||||
|
|
||||||
_.each(this.model.get('fields'), function (field) {
|
|
||||||
properties[field.name] = field.value;
|
|
||||||
});
|
|
||||||
|
|
||||||
CommandController.Execute(testCommand, properties);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDownloadChanged: function () {
|
_onDownloadChanged: function () {
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
define([
|
|
||||||
'Settings/SettingsModelBase'
|
|
||||||
], function (ModelBase) {
|
|
||||||
return ModelBase.extend({
|
|
||||||
|
|
||||||
successMessage: 'Notification Saved',
|
define([
|
||||||
errorMessage : 'Couldn\'t save notification'
|
'Settings/ProviderSettingsModelBase'
|
||||||
|
], function (ProviderSettingsModelBase) {
|
||||||
|
return ProviderSettingsModelBase.extend({
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
define([
|
||||||
|
'jquery',
|
||||||
|
'backbone.deepmodel',
|
||||||
|
'Shared/Messenger'
|
||||||
|
], function ($, DeepModel, Messenger) {
|
||||||
|
return DeepModel.DeepModel.extend({
|
||||||
|
|
||||||
|
test: function () {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
this.trigger('validation:sync');
|
||||||
|
|
||||||
|
var params = {};
|
||||||
|
|
||||||
|
params.url = this.collection.url + '/test';
|
||||||
|
params.contentType = 'application/json';
|
||||||
|
params.data = JSON.stringify(this.toJSON());
|
||||||
|
params.type = 'POST';
|
||||||
|
params.isValidatedCall = true;
|
||||||
|
|
||||||
|
var promise = $.ajax(params);
|
||||||
|
|
||||||
|
Messenger.monitor({
|
||||||
|
promise : promise,
|
||||||
|
successMessage : 'Testing \'{0}\' completed'.format(this.get('name')),
|
||||||
|
errorMessage : 'Testing \'{0}\' failed'.format(this.get('name'))
|
||||||
|
});
|
||||||
|
|
||||||
|
promise.fail(function (response) {
|
||||||
|
self.trigger('validation:failed', response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -57,13 +57,17 @@ define(
|
||||||
};
|
};
|
||||||
|
|
||||||
$.fn.addFormError = function (error) {
|
$.fn.addFormError = function (error) {
|
||||||
var t1 = this.find('.form-horizontal');
|
if (this.find('.modal-body')) {
|
||||||
var t2 = this.find('.form-horizontal').parent();
|
this.find('.modal-body').prepend('<div class="alert alert-danger validation-error">' + error.errorMessage + '</div>');
|
||||||
|
}
|
||||||
this.prepend('<div class="alert alert-danger validation-error">' + error.errorMessage + '</div>');
|
|
||||||
|
else {
|
||||||
|
this.prepend('<div class="alert alert-danger validation-error">' + error.errorMessage + '</div>');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$.fn.removeAllErrors = function () {
|
$.fn.removeAllErrors = function () {
|
||||||
|
this.find('.has-error').removeClass('has-error');
|
||||||
this.find('.error').removeClass('error');
|
this.find('.error').removeClass('error');
|
||||||
this.find('.validation-errors').removeClass('alert').removeClass('alert-danger').html('');
|
this.find('.validation-errors').removeClass('alert').removeClass('alert-danger').html('');
|
||||||
this.find('.validation-error').remove();
|
this.find('.validation-error').remove();
|
||||||
|
|
Loading…
Reference in New Issue