parent
9dc87762b7
commit
32ced861a7
@ -1,72 +0,0 @@
|
|||||||
using Moq;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Common.Http;
|
|
||||||
using NzbDrone.Core.Notifications.Plex.HomeTheater;
|
|
||||||
using NzbDrone.Core.Test.Framework;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.NotificationTests
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
|
|
||||||
public class PlexClientServiceTest : CoreTest
|
|
||||||
{
|
|
||||||
private PlexClientSettings _clientSettings;
|
|
||||||
|
|
||||||
public void WithClientCredentials()
|
|
||||||
{
|
|
||||||
_clientSettings.Username = "plex";
|
|
||||||
_clientSettings.Password = "plex";
|
|
||||||
}
|
|
||||||
|
|
||||||
[SetUp]
|
|
||||||
public void Setup()
|
|
||||||
{
|
|
||||||
_clientSettings = new PlexClientSettings
|
|
||||||
{
|
|
||||||
Host = "localhost",
|
|
||||||
Port = 3000
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Notify_should_send_notification()
|
|
||||||
{
|
|
||||||
|
|
||||||
const string header = "Test Header";
|
|
||||||
const string message = "Test Message";
|
|
||||||
|
|
||||||
var expectedUrl = string.Format("http://localhost:3000/xbmcCmds/xbmcHttp?command=ExecBuiltIn(Notification({0}, {1}))", header, message);
|
|
||||||
|
|
||||||
var fakeHttp = Mocker.GetMock<IHttpProvider>();
|
|
||||||
fakeHttp.Setup(s => s.DownloadString(expectedUrl))
|
|
||||||
.Returns("ok");
|
|
||||||
|
|
||||||
|
|
||||||
Mocker.Resolve<PlexClientService>().Notify(_clientSettings, header, message);
|
|
||||||
|
|
||||||
|
|
||||||
fakeHttp.Verify(v => v.DownloadString(expectedUrl), Times.Once());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Notify_should_send_notification_with_credentials_when_configured()
|
|
||||||
{
|
|
||||||
WithClientCredentials();
|
|
||||||
|
|
||||||
const string header = "Test Header";
|
|
||||||
const string message = "Test Message";
|
|
||||||
|
|
||||||
var expectedUrl = string.Format("http://localhost:3000/xbmcCmds/xbmcHttp?command=ExecBuiltIn(Notification({0}, {1}))", header, message);
|
|
||||||
|
|
||||||
var fakeHttp = Mocker.GetMock<IHttpProvider>();
|
|
||||||
fakeHttp.Setup(s => s.DownloadString(expectedUrl, "plex", "plex"))
|
|
||||||
.Returns("ok");
|
|
||||||
|
|
||||||
|
|
||||||
Mocker.Resolve<PlexClientService>().Notify(_clientSettings, header, message);
|
|
||||||
|
|
||||||
|
|
||||||
fakeHttp.Verify(v => v.DownloadString(expectedUrl, "plex", "plex"), Times.Once());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,15 @@
|
|||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(38)]
|
||||||
|
public class remove_plex_hometheatre : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Delete.FromTable("Notifications").Row(new { Implementation = "PlexHomeTheater" });
|
||||||
|
Delete.FromTable("Notifications").Row(new { Implementation = "PlexClient" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,43 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using FluentValidation.Results;
|
|
||||||
using NzbDrone.Common.Extensions;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Plex.HomeTheater
|
|
||||||
{
|
|
||||||
public class PlexClient : NotificationBase<PlexClientSettings>
|
|
||||||
{
|
|
||||||
private readonly IPlexClientService _plexClientService;
|
|
||||||
|
|
||||||
public override string Link => "https://www.plex.tv/";
|
|
||||||
public override string Name => "Plex Media Center";
|
|
||||||
|
|
||||||
public PlexClient(IPlexClientService plexClientService)
|
|
||||||
{
|
|
||||||
_plexClientService = plexClientService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
|
||||||
{
|
|
||||||
_plexClientService.Notify(Settings, ALBUM_GRABBED_TITLE_BRANDED, grabMessage.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
|
||||||
{
|
|
||||||
_plexClientService.Notify(Settings, ALBUM_DOWNLOADED_TITLE_BRANDED, message.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnHealthIssue(HealthCheck.HealthCheck message)
|
|
||||||
{
|
|
||||||
_plexClientService.Notify(Settings, HEALTH_ISSUE_TITLE_BRANDED, message.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override ValidationResult Test()
|
|
||||||
{
|
|
||||||
var failures = new List<ValidationFailure>();
|
|
||||||
|
|
||||||
failures.AddIfNotNull(_plexClientService.Test(Settings));
|
|
||||||
|
|
||||||
return new ValidationResult(failures);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
using System;
|
|
||||||
using FluentValidation.Results;
|
|
||||||
using NLog;
|
|
||||||
using NzbDrone.Common.Http;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Plex.HomeTheater
|
|
||||||
{
|
|
||||||
public interface IPlexClientService
|
|
||||||
{
|
|
||||||
void Notify(PlexClientSettings settings, string header, string message);
|
|
||||||
ValidationFailure Test(PlexClientSettings settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PlexClientService : IPlexClientService
|
|
||||||
{
|
|
||||||
private readonly IHttpProvider _httpProvider;
|
|
||||||
private readonly Logger _logger;
|
|
||||||
|
|
||||||
public PlexClientService(IHttpProvider httpProvider, Logger logger)
|
|
||||||
{
|
|
||||||
_httpProvider = httpProvider;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Notify(PlexClientSettings settings, string header, string message)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var command = string.Format("ExecBuiltIn(Notification({0}, {1}))", header, message);
|
|
||||||
SendCommand(settings.Host, settings.Port, command, settings.Username, settings.Password);
|
|
||||||
}
|
|
||||||
catch(Exception ex)
|
|
||||||
{
|
|
||||||
_logger.Warn(ex, "Failed to send notification to Plex Client: " + settings.Host);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string SendCommand(string host, int port, string command, string username, string password)
|
|
||||||
{
|
|
||||||
var url = string.Format("http://{0}:{1}/xbmcCmds/xbmcHttp?command={2}", host, port, command);
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(username))
|
|
||||||
{
|
|
||||||
return _httpProvider.DownloadString(url, username, password);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _httpProvider.DownloadString(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ValidationFailure Test(PlexClientSettings settings)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_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.Error(ex, "Unable to send test message");
|
|
||||||
return new ValidationFailure("Host", "Unable to send test message");
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
using FluentValidation;
|
|
||||||
using NzbDrone.Core.Annotations;
|
|
||||||
using NzbDrone.Core.ThingiProvider;
|
|
||||||
using NzbDrone.Core.Validation;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Plex.HomeTheater
|
|
||||||
{
|
|
||||||
public class PlexClientSettingsValidator : AbstractValidator<PlexClientSettings>
|
|
||||||
{
|
|
||||||
public PlexClientSettingsValidator()
|
|
||||||
{
|
|
||||||
RuleFor(c => c.Host).ValidHost();
|
|
||||||
RuleFor(c => c.Port).InclusiveBetween(1, 65535);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PlexClientSettings : IProviderConfig
|
|
||||||
{
|
|
||||||
private static readonly PlexClientSettingsValidator Validator = new PlexClientSettingsValidator();
|
|
||||||
|
|
||||||
public PlexClientSettings()
|
|
||||||
{
|
|
||||||
Port = 3000;
|
|
||||||
}
|
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Host")]
|
|
||||||
public string Host { get; set; }
|
|
||||||
|
|
||||||
[FieldDefinition(1, Label = "Port")]
|
|
||||||
public int Port { get; set; }
|
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "Username")]
|
|
||||||
public string Username { get; set; }
|
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "Password", Type = FieldType.Password)]
|
|
||||||
public string Password { get; set; }
|
|
||||||
|
|
||||||
public bool IsValid => !string.IsNullOrWhiteSpace(Host);
|
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
|
||||||
{
|
|
||||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Net.Sockets;
|
|
||||||
using FluentValidation.Results;
|
|
||||||
using NLog;
|
|
||||||
using NzbDrone.Common.Extensions;
|
|
||||||
using NzbDrone.Core.Notifications.Xbmc;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Plex.HomeTheater
|
|
||||||
{
|
|
||||||
public class PlexHomeTheater : NotificationBase<PlexHomeTheaterSettings>
|
|
||||||
{
|
|
||||||
private readonly IXbmcService _xbmcService;
|
|
||||||
private readonly Logger _logger;
|
|
||||||
|
|
||||||
public PlexHomeTheater(IXbmcService xbmcService, Logger logger)
|
|
||||||
{
|
|
||||||
_xbmcService = xbmcService;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string Name => "Plex Home Theater";
|
|
||||||
public override string Link => "https://plex.tv/";
|
|
||||||
|
|
||||||
public override void OnGrab(GrabMessage grabMessage)
|
|
||||||
{
|
|
||||||
Notify(ALBUM_GRABBED_TITLE_BRANDED, grabMessage.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnReleaseImport(AlbumDownloadMessage message)
|
|
||||||
{
|
|
||||||
Notify(ALBUM_DOWNLOADED_TITLE_BRANDED, message.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override ValidationResult Test()
|
|
||||||
{
|
|
||||||
var failures = new List<ValidationFailure>();
|
|
||||||
|
|
||||||
failures.AddIfNotNull(_xbmcService.Test(Settings, "Success! PHT has been successfully configured!"));
|
|
||||||
|
|
||||||
return new ValidationResult(failures);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Notify(string header, string message)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (Settings.Notify)
|
|
||||||
{
|
|
||||||
_xbmcService.Notify(Settings, header, message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (SocketException ex)
|
|
||||||
{
|
|
||||||
var logMessage = $"Unable to connect to PHT Host: {Settings.Host}:{Settings.Port}";
|
|
||||||
_logger.Debug(ex, logMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
using NzbDrone.Core.Annotations;
|
|
||||||
using NzbDrone.Core.Notifications.Xbmc;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Plex.HomeTheater
|
|
||||||
{
|
|
||||||
public class PlexHomeTheaterSettings : XbmcSettings
|
|
||||||
{
|
|
||||||
public PlexHomeTheaterSettings()
|
|
||||||
{
|
|
||||||
Port = 3005;
|
|
||||||
Notify = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//These need to be kept in the same order as XBMC Settings, but we don't want them displayed
|
|
||||||
|
|
||||||
[FieldDefinition(2, Label = "Username", Hidden = HiddenType.Hidden)]
|
|
||||||
public new string Username { get; set; }
|
|
||||||
|
|
||||||
[FieldDefinition(3, Label = "Password", Hidden = HiddenType.Hidden)]
|
|
||||||
public new string Password { get; set; }
|
|
||||||
|
|
||||||
[FieldDefinition(5, Label = "GUI Notification", Type = FieldType.Checkbox, Hidden = HiddenType.Hidden)]
|
|
||||||
public new bool Notify { get; set; }
|
|
||||||
|
|
||||||
[FieldDefinition(6, Label = "Update Library", HelpText = "Update Library on Download & Rename?", Type = FieldType.Checkbox, Hidden = HiddenType.Hidden)]
|
|
||||||
public new bool UpdateLibrary { get; set; }
|
|
||||||
|
|
||||||
[FieldDefinition(7, Label = "Clean Library", HelpText = "Clean Library after update?", Type = FieldType.Checkbox, Hidden = HiddenType.Hidden)]
|
|
||||||
public new bool CleanLibrary { get; set; }
|
|
||||||
|
|
||||||
[FieldDefinition(8, Label = "Always Update", HelpText = "Update Library even when a video is playing?", Type = FieldType.Checkbox, Hidden = HiddenType.Hidden)]
|
|
||||||
public new bool AlwaysUpdate { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in new issue