From 78eb8b0e6d98815a41307110e3d7d809a79f5d60 Mon Sep 17 00:00:00 2001 From: Qstick Date: Wed, 28 Jul 2021 23:13:06 -0400 Subject: [PATCH] Fixed: Remove obsolete XBMC HTTP notification API Co-Authored-By: ta264 --- .../Xbmc/Http/ActivePlayersFixture.cs | 70 ------ .../Xbmc/Http/CheckForErrorFixture.cs | 35 --- .../Xbmc/Http/GetSeriesPathFixture.cs | 94 --------- .../Xbmc/Http/UpdateFixture.cs | 75 ------- .../Xbmc/Json/GetSeriesPathFixture.cs | 2 +- .../Xbmc/Json/UpdateFixture.cs | 2 +- .../Notifications/Xbmc/HttpApiProvider.cs | 199 ------------------ .../Notifications/Xbmc/IApiProvider.cs | 13 -- .../Xbmc/InvalidXbmcVersionException.cs | 15 -- .../Notifications/Xbmc/JsonApiProvider.cs | 124 ----------- .../Xbmc/Model/ActivePlayersDharmaResult.cs | 11 - ...rsEdenResult.cs => ActivePlayersResult.cs} | 4 +- src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs | 2 +- .../Notifications/Xbmc/XbmcJsonApiProxy.cs | 2 +- .../Notifications/Xbmc/XbmcService.cs | 109 +++++----- 15 files changed, 61 insertions(+), 696 deletions(-) delete mode 100644 src/NzbDrone.Core.Test/NotificationTests/Xbmc/Http/ActivePlayersFixture.cs delete mode 100644 src/NzbDrone.Core.Test/NotificationTests/Xbmc/Http/CheckForErrorFixture.cs delete mode 100644 src/NzbDrone.Core.Test/NotificationTests/Xbmc/Http/GetSeriesPathFixture.cs delete mode 100644 src/NzbDrone.Core.Test/NotificationTests/Xbmc/Http/UpdateFixture.cs delete mode 100644 src/NzbDrone.Core/Notifications/Xbmc/HttpApiProvider.cs delete mode 100644 src/NzbDrone.Core/Notifications/Xbmc/IApiProvider.cs delete mode 100644 src/NzbDrone.Core/Notifications/Xbmc/InvalidXbmcVersionException.cs delete mode 100644 src/NzbDrone.Core/Notifications/Xbmc/JsonApiProvider.cs delete mode 100644 src/NzbDrone.Core/Notifications/Xbmc/Model/ActivePlayersDharmaResult.cs rename src/NzbDrone.Core/Notifications/Xbmc/Model/{ActivePlayersEdenResult.cs => ActivePlayersResult.cs} (85%) diff --git a/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Http/ActivePlayersFixture.cs b/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Http/ActivePlayersFixture.cs deleted file mode 100644 index bf5f4de2b..000000000 --- a/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Http/ActivePlayersFixture.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System.Linq; -using FluentAssertions; -using NUnit.Framework; -using NzbDrone.Common.Http; -using NzbDrone.Core.Notifications.Xbmc; -using NzbDrone.Core.Test.Framework; - -namespace NzbDrone.Core.Test.NotificationTests.Xbmc.Http -{ - [TestFixture] - public class ActivePlayersFixture : CoreTest - { - private XbmcSettings _settings; - private string _expectedUrl; - - private void WithNoActivePlayers() - { - Mocker.GetMock() - .Setup(s => s.DownloadString(_expectedUrl, _settings.Username, _settings.Password)) - .Returns("
  • Filename:[Nothing Playing]"); - } - - private void WithVideoPlayerActive() - { - var activePlayers = @"
  • Filename:C:\Test\TV\2 Broke Girls\Season 01\2 Broke Girls - S01E01 - Pilot [SDTV].avi" + - "
  • PlayStatus:Playing
  • VideoNo:0
  • Type:Video
  • Thumb:special://masterprofile/Thumbnails/Video/a/auto-a664d5a2.tbn" + - "
  • Time:00:06
  • Duration:21:35
  • Percentage:0
  • File size:183182590
  • Changed:True"; - - Mocker.GetMock() - .Setup(s => s.DownloadString(_expectedUrl, _settings.Username, _settings.Password)) - .Returns(activePlayers); - } - - [SetUp] - public void Setup() - { - _settings = new XbmcSettings - { - Host = "localhost", - Port = 8080, - Username = "xbmc", - Password = "xbmc", - AlwaysUpdate = false, - CleanLibrary = false, - UpdateLibrary = true - }; - - _expectedUrl = string.Format("http://{0}/xbmcCmds/xbmcHttp?command={1}", _settings.Address, "getcurrentlyplaying"); - } - - [Test] - public void _should_be_empty_when_no_active_players() - { - WithNoActivePlayers(); - - Subject.GetActivePlayers(_settings).Should().BeEmpty(); - } - - [Test] - public void should_have_active_video_player() - { - WithVideoPlayerActive(); - - var result = Subject.GetActivePlayers(_settings); - - result.Should().HaveCount(1); - result.First().Type.Should().Be("video"); - } - } -} diff --git a/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Http/CheckForErrorFixture.cs b/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Http/CheckForErrorFixture.cs deleted file mode 100644 index ea32b1b90..000000000 --- a/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Http/CheckForErrorFixture.cs +++ /dev/null @@ -1,35 +0,0 @@ -using FluentAssertions; -using NUnit.Framework; -using NzbDrone.Core.Notifications.Xbmc; -using NzbDrone.Core.Test.Framework; - -namespace NzbDrone.Core.Test.NotificationTests.Xbmc.Http -{ - [TestFixture] - public class CheckForErrorFixture : CoreTest - { - [Test] - public void should_be_true_when_the_response_contains_an_error() - { - const string response = "html>
  • Error:Unknown command"; - - Subject.CheckForError(response).Should().BeTrue(); - } - - [Test] - public void JsonError_true_empty_response() - { - var response = string.Empty; - - Subject.CheckForError(response).Should().BeTrue(); - } - - [Test] - public void JsonError_false() - { - const string response = "html>
  • Filename:[Nothing Playing]"; - - Subject.CheckForError(response).Should().BeFalse(); - } - } -} diff --git a/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Http/GetSeriesPathFixture.cs b/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Http/GetSeriesPathFixture.cs deleted file mode 100644 index 15ec93960..000000000 --- a/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Http/GetSeriesPathFixture.cs +++ /dev/null @@ -1,94 +0,0 @@ -using FluentAssertions; -using NUnit.Framework; -using NzbDrone.Common.Http; -using NzbDrone.Core.Notifications.Xbmc; -using NzbDrone.Core.Test.Framework; -using NzbDrone.Core.Tv; - -namespace NzbDrone.Core.Test.NotificationTests.Xbmc.Http -{ - [TestFixture] - public class GetSeriesPathFixture : CoreTest - { - private XbmcSettings _settings; - private Series _series; - - [SetUp] - public void Setup() - { - _settings = new XbmcSettings - { - Host = "localhost", - Port = 8080, - Username = "xbmc", - Password = "xbmc", - AlwaysUpdate = false, - CleanLibrary = false, - UpdateLibrary = true - }; - - _series = new Series - { - TvdbId = 79488, - Title = "30 Rock" - }; - - const string setResponseUrl = "http://localhost:8080/xbmcCmds/xbmcHttp?command=SetResponseFormat(webheader;false;webfooter;false;header;;footer;;opentag;;closetag;;closefinaltag;false)"; - const string resetResponseUrl = "http://localhost:8080/xbmcCmds/xbmcHttp?command=SetResponseFormat()"; - - Mocker.GetMock() - .Setup(s => s.DownloadString(setResponseUrl, _settings.Username, _settings.Password)) - .Returns("OK"); - - Mocker.GetMock() - .Setup(s => s.DownloadString(resetResponseUrl, _settings.Username, _settings.Password)) - .Returns(@" -
  • OK - "); - } - - [Test] - public void should_get_series_path() - { - const string queryResult = @"smb://xbmc:xbmc@HOMESERVER/TV/30 Rock/"; - var query = string.Format("http://localhost:8080/xbmcCmds/xbmcHttp?command=QueryVideoDatabase(select path.strPath from path, tvshow, tvshowlinkpath where tvshow.c12 = 79488 and tvshowlinkpath.idShow = tvshow.idShow and tvshowlinkpath.idPath = path.idPath)"); - - Mocker.GetMock() - .Setup(s => s.DownloadString(query, _settings.Username, _settings.Password)) - .Returns(queryResult); - - Subject.GetSeriesPath(_settings, _series) - .Should().Be("smb://xbmc:xbmc@HOMESERVER/TV/30 Rock/"); - } - - [Test] - public void should_get_null_for_series_path() - { - const string queryResult = @""; - var query = string.Format("http://localhost:8080/xbmcCmds/xbmcHttp?command=QueryVideoDatabase(select path.strPath from path, tvshow, tvshowlinkpath where tvshow.c12 = 79488 and tvshowlinkpath.idShow = tvshow.idShow and tvshowlinkpath.idPath = path.idPath)"); - - Mocker.GetMock() - .Setup(s => s.DownloadString(query, _settings.Username, _settings.Password)) - .Returns(queryResult); - - - Subject.GetSeriesPath(_settings, _series) - .Should().BeNull(); - } - - [Test] - public void should_get_series_path_with_special_characters_in_it() - { - const string queryResult = @"smb://xbmc:xbmc@HOMESERVER/TV/Law & Order- Special Victims Unit/"; - var query = string.Format("http://localhost:8080/xbmcCmds/xbmcHttp?command=QueryVideoDatabase(select path.strPath from path, tvshow, tvshowlinkpath where tvshow.c12 = 79488 and tvshowlinkpath.idShow = tvshow.idShow and tvshowlinkpath.idPath = path.idPath)"); - - Mocker.GetMock() - .Setup(s => s.DownloadString(query, _settings.Username, _settings.Password)) - .Returns(queryResult); - - - Subject.GetSeriesPath(_settings, _series) - .Should().Be("smb://xbmc:xbmc@HOMESERVER/TV/Law & Order- Special Victims Unit/"); - } - } -} diff --git a/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Http/UpdateFixture.cs b/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Http/UpdateFixture.cs deleted file mode 100644 index aad928f95..000000000 --- a/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Http/UpdateFixture.cs +++ /dev/null @@ -1,75 +0,0 @@ -using FizzWare.NBuilder; -using NUnit.Framework; -using NzbDrone.Common.Http; -using NzbDrone.Core.Notifications.Xbmc; -using NzbDrone.Core.Test.Framework; -using NzbDrone.Core.Tv; - -namespace NzbDrone.Core.Test.NotificationTests.Xbmc.Http -{ - [TestFixture] - public class UpdateFixture : CoreTest - { - private XbmcSettings _settings; - private string _seriesQueryUrl = "http://localhost:8080/xbmcCmds/xbmcHttp?command=QueryVideoDatabase(select path.strPath from path, tvshow, tvshowlinkpath where tvshow.c12 = 79488 and tvshowlinkpath.idShow = tvshow.idShow and tvshowlinkpath.idPath = path.idPath)"; - private Series _fakeSeries; - - [SetUp] - public void Setup() - { - _settings = new XbmcSettings - { - Host = "localhost", - Port = 8080, - Username = "xbmc", - Password = "xbmc", - AlwaysUpdate = false, - CleanLibrary = false, - UpdateLibrary = true - }; - - _fakeSeries = Builder.CreateNew() - .With(s => s.TvdbId = 79488) - .With(s => s.Title = "30 Rock") - .Build(); - } - - private void WithSeriesPath() - { - Mocker.GetMock() - .Setup(s => s.DownloadString(_seriesQueryUrl, _settings.Username, _settings.Password)) - .Returns("smb://xbmc:xbmc@HOMESERVER/TV/30 Rock/"); - } - - private void WithoutSeriesPath() - { - Mocker.GetMock() - .Setup(s => s.DownloadString(_seriesQueryUrl, _settings.Username, _settings.Password)) - .Returns(""); - } - - [Test] - public void should_update_using_series_path() - { - WithSeriesPath(); - const string url = "http://localhost:8080/xbmcCmds/xbmcHttp?command=ExecBuiltIn(UpdateLibrary(video,smb://xbmc:xbmc@HOMESERVER/TV/30 Rock/))"; - - Mocker.GetMock().Setup(s => s.DownloadString(url, _settings.Username, _settings.Password)); - - Subject.Update(_settings, _fakeSeries); - Mocker.VerifyAllMocks(); - } - - [Test] - public void should_update_all_paths_when_series_path_not_found() - { - WithoutSeriesPath(); - const string url = "http://localhost:8080/xbmcCmds/xbmcHttp?command=ExecBuiltIn(UpdateLibrary(video))"; - - Mocker.GetMock().Setup(s => s.DownloadString(url, _settings.Username, _settings.Password)); - - Subject.Update(_settings, _fakeSeries); - Mocker.VerifyAllMocks(); - } - } -} diff --git a/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Json/GetSeriesPathFixture.cs b/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Json/GetSeriesPathFixture.cs index b4b29dff2..a3d3962c7 100644 --- a/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Json/GetSeriesPathFixture.cs +++ b/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Json/GetSeriesPathFixture.cs @@ -11,7 +11,7 @@ using NzbDrone.Core.Tv; namespace NzbDrone.Core.Test.NotificationTests.Xbmc.Json { [TestFixture] - public class GetSeriesPathFixture : CoreTest + public class GetSeriesPathFixture : CoreTest { private const int TVDB_ID = 5; private XbmcSettings _settings; diff --git a/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Json/UpdateFixture.cs b/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Json/UpdateFixture.cs index 408f2eeba..564778936 100644 --- a/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Json/UpdateFixture.cs +++ b/src/NzbDrone.Core.Test/NotificationTests/Xbmc/Json/UpdateFixture.cs @@ -11,7 +11,7 @@ using NzbDrone.Core.Tv; namespace NzbDrone.Core.Test.NotificationTests.Xbmc.Json { [TestFixture] - public class UpdateFixture : CoreTest + public class UpdateFixture : CoreTest { private const int TVDB_ID = 5; private XbmcSettings _settings; diff --git a/src/NzbDrone.Core/Notifications/Xbmc/HttpApiProvider.cs b/src/NzbDrone.Core/Notifications/Xbmc/HttpApiProvider.cs deleted file mode 100644 index 31bddf80e..000000000 --- a/src/NzbDrone.Core/Notifications/Xbmc/HttpApiProvider.cs +++ /dev/null @@ -1,199 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Xml.Linq; -using NLog; -using NzbDrone.Common.Http; -using NzbDrone.Core.Notifications.Xbmc.Model; -using NzbDrone.Core.Tv; - -namespace NzbDrone.Core.Notifications.Xbmc -{ - public class HttpApiProvider : IApiProvider - { - private readonly IHttpProvider _httpProvider; - private readonly Logger _logger; - - public HttpApiProvider(IHttpProvider httpProvider, Logger logger) - { - _httpProvider = httpProvider; - _logger = logger; - } - - public bool CanHandle(XbmcVersion version) - { - return version < new XbmcVersion(5); - } - - public void Notify(XbmcSettings settings, string title, string message) - { - var notification = string.Format("Notification({0},{1},{2},{3})", title, message, settings.DisplayTime * 1000, "https://raw.github.com/Sonarr/Sonarr/develop/Logo/64.png"); - var command = BuildExecBuiltInCommand(notification); - - SendCommand(settings, command); - } - - public void Update(XbmcSettings settings, Series series) - { - if (!settings.AlwaysUpdate) - { - _logger.Debug("Determining if there are any active players on XBMC host: {0}", settings.Address); - var activePlayers = GetActivePlayers(settings); - - if (activePlayers.Any(a => a.Type.Equals("video"))) - { - _logger.Debug("Video is currently playing, skipping library update"); - return; - } - } - - UpdateLibrary(settings, series); - } - - public void Clean(XbmcSettings settings) - { - if (!settings.AlwaysUpdate) - { - _logger.Debug("Determining if there are any active players on XBMC host: {0}", settings.Address); - var activePlayers = GetActivePlayers(settings); - - if (activePlayers.Any(a => a.Type.Equals("video"))) - { - _logger.Debug("Video is currently playing, skipping library cleaning"); - return; - } - } - - const string cleanVideoLibrary = "CleanLibrary(video)"; - var command = BuildExecBuiltInCommand(cleanVideoLibrary); - - SendCommand(settings, command); - } - - internal List GetActivePlayers(XbmcSettings settings) - { - try - { - var result = new List(); - var response = SendCommand(settings, "getcurrentlyplaying"); - - if (response.Contains("
  • Filename:[Nothing Playing]")) return new List(); - if (response.Contains("
  • Type:Video")) result.Add(new ActivePlayer(1, "video")); - - return result; - } - - catch (Exception ex) - { - _logger.Debug(ex, ex.Message); - } - - return new List(); - } - - internal string GetSeriesPath(XbmcSettings settings, Series series) - { - var query = - string.Format( - "select path.strPath from path, tvshow, tvshowlinkpath where tvshow.c12 = {0} and tvshowlinkpath.idShow = tvshow.idShow and tvshowlinkpath.idPath = path.idPath", - series.TvdbId); - var command = string.Format("QueryVideoDatabase({0})", query); - - const string setResponseCommand = - "SetResponseFormat(webheader;false;webfooter;false;header;;footer;;opentag;;closetag;;closefinaltag;false)"; - const string resetResponseCommand = "SetResponseFormat()"; - - SendCommand(settings, setResponseCommand); - var response = SendCommand(settings, command); - SendCommand(settings, resetResponseCommand); - - if (string.IsNullOrEmpty(response)) - return string.Empty; - - var xDoc = XDocument.Load(new StringReader(response.Replace("&", "&"))); - var xml = xDoc.Descendants("xml").Select(x => x).FirstOrDefault(); - - if (xml == null) - return null; - - var field = xml.Descendants("field").FirstOrDefault(); - - if (field == null) - return null; - - return field.Value; - } - - internal bool CheckForError(string response) - { - _logger.Debug("Looking for error in response: {0}", response); - - if (string.IsNullOrWhiteSpace(response)) - { - _logger.Debug("Invalid response from XBMC, the response is not valid JSON"); - return true; - } - - var errorIndex = response.IndexOf("Error", StringComparison.InvariantCultureIgnoreCase); - - if (errorIndex > -1) - { - var errorMessage = response.Substring(errorIndex + 6); - errorMessage = errorMessage.Substring(0, errorMessage.IndexOfAny(new char[] { '<', ';' })); - - _logger.Debug("Error found in response: {0}", errorMessage); - return true; - } - - return false; - } - - private void UpdateLibrary(XbmcSettings settings, Series series) - { - try - { - _logger.Debug("Sending Update DB Request to XBMC Host: {0}", settings.Address); - var xbmcSeriesPath = GetSeriesPath(settings, series); - - //If the path is found update it, else update the whole library - if (!string.IsNullOrEmpty(xbmcSeriesPath)) - { - _logger.Debug("Updating series [{0}] on XBMC host: {1}", series, settings.Address); - var command = BuildExecBuiltInCommand(string.Format("UpdateLibrary(video,{0})", xbmcSeriesPath)); - SendCommand(settings, command); - } - - else - { - //Update the entire library - _logger.Debug("Series [{0}] doesn't exist on XBMC host: {1}, Updating Entire Library", series, settings.Address); - var command = BuildExecBuiltInCommand("UpdateLibrary(video)"); - SendCommand(settings, command); - } - } - - catch (Exception ex) - { - _logger.Debug(ex, ex.Message); - } - } - - private string SendCommand(XbmcSettings settings, string command) - { - var url = HttpRequestBuilder.BuildBaseUrl(settings.UseSsl, settings.Host, settings.Port, $"xbmcCmds/xbmcHttp?command={command}"); - - if (!string.IsNullOrEmpty(settings.Username)) - { - return _httpProvider.DownloadString(url, settings.Username, settings.Password); - } - - return _httpProvider.DownloadString(url); - } - - private string BuildExecBuiltInCommand(string command) - { - return string.Format("ExecBuiltIn({0})", command); - } - } -} diff --git a/src/NzbDrone.Core/Notifications/Xbmc/IApiProvider.cs b/src/NzbDrone.Core/Notifications/Xbmc/IApiProvider.cs deleted file mode 100644 index bf250edc3..000000000 --- a/src/NzbDrone.Core/Notifications/Xbmc/IApiProvider.cs +++ /dev/null @@ -1,13 +0,0 @@ -using NzbDrone.Core.Notifications.Xbmc.Model; -using NzbDrone.Core.Tv; - -namespace NzbDrone.Core.Notifications.Xbmc -{ - public interface IApiProvider - { - void Notify(XbmcSettings settings, string title, string message); - void Update(XbmcSettings settings, Series series); - void Clean(XbmcSettings settings); - bool CanHandle(XbmcVersion version); - } -} diff --git a/src/NzbDrone.Core/Notifications/Xbmc/InvalidXbmcVersionException.cs b/src/NzbDrone.Core/Notifications/Xbmc/InvalidXbmcVersionException.cs deleted file mode 100644 index 0a0a46da0..000000000 --- a/src/NzbDrone.Core/Notifications/Xbmc/InvalidXbmcVersionException.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace NzbDrone.Core.Notifications.Xbmc -{ - public class InvalidXbmcVersionException : Exception - { - public InvalidXbmcVersionException() - { - } - - public InvalidXbmcVersionException(string message) : base(message) - { - } - } -} diff --git a/src/NzbDrone.Core/Notifications/Xbmc/JsonApiProvider.cs b/src/NzbDrone.Core/Notifications/Xbmc/JsonApiProvider.cs deleted file mode 100644 index fbaa71544..000000000 --- a/src/NzbDrone.Core/Notifications/Xbmc/JsonApiProvider.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using NLog; -using NzbDrone.Core.Notifications.Xbmc.Model; -using NzbDrone.Core.Tv; - -namespace NzbDrone.Core.Notifications.Xbmc -{ - public class JsonApiProvider : IApiProvider - { - private readonly IXbmcJsonApiProxy _proxy; - private readonly Logger _logger; - - public JsonApiProvider(IXbmcJsonApiProxy proxy, Logger logger) - { - _proxy = proxy; - _logger = logger; - } - - public bool CanHandle(XbmcVersion version) - { - return version >= new XbmcVersion(5); - } - - public void Notify(XbmcSettings settings, string title, string message) - { - _proxy.Notify(settings, title, message); - } - - public void Update(XbmcSettings settings, Series series) - { - if (!settings.AlwaysUpdate) - { - _logger.Debug("Determining if there are any active players on XBMC host: {0}", settings.Address); - var activePlayers = GetActivePlayers(settings); - - if (activePlayers.Any(a => a.Type.Equals("video"))) - { - _logger.Debug("Video is currently playing, skipping library update"); - return; - } - } - - UpdateLibrary(settings, series); - } - - public void Clean(XbmcSettings settings) - { - if (!settings.AlwaysUpdate) - { - _logger.Debug("Determining if there are any active players on XBMC host: {0}", settings.Address); - var activePlayers = GetActivePlayers(settings); - - if (activePlayers.Any(a => a.Type.Equals("video"))) - { - _logger.Debug("Video is currently playing, skipping library cleaning"); - return; - } - } - - _proxy.CleanLibrary(settings); - } - - public List GetActivePlayers(XbmcSettings settings) - { - return _proxy.GetActivePlayers(settings); - } - - public string GetSeriesPath(XbmcSettings settings, Series series) - { - var allSeries = _proxy.GetSeries(settings); - - if (!allSeries.Any()) - { - _logger.Debug("No TV shows returned from XBMC"); - return null; - } - - var matchingSeries = allSeries.FirstOrDefault(s => - { - var tvdbId = 0; - int.TryParse(s.ImdbNumber, out tvdbId); - - return tvdbId == series.TvdbId || s.Label == series.Title; - }); - - if (matchingSeries != null) return matchingSeries.File; - - return null; - } - - private void UpdateLibrary(XbmcSettings settings, Series series) - { - try - { - var seriesPath = GetSeriesPath(settings, series); - - if (seriesPath != null) - { - _logger.Debug("Updating series {0} (Path: {1}) on XBMC host: {2}", series, seriesPath, settings.Address); - } - - else - { - _logger.Debug("Series {0} doesn't exist on XBMC host: {1}, Updating Entire Library", series, - settings.Address); - } - - var response = _proxy.UpdateLibrary(settings, seriesPath); - - if (!response.Equals("OK", StringComparison.InvariantCultureIgnoreCase)) - { - _logger.Debug("Failed to update library for: {0}", settings.Address); - } - } - - catch (Exception ex) - { - _logger.Debug(ex, ex.Message); - } - } - } -} diff --git a/src/NzbDrone.Core/Notifications/Xbmc/Model/ActivePlayersDharmaResult.cs b/src/NzbDrone.Core/Notifications/Xbmc/Model/ActivePlayersDharmaResult.cs deleted file mode 100644 index 49d942cc2..000000000 --- a/src/NzbDrone.Core/Notifications/Xbmc/Model/ActivePlayersDharmaResult.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; - -namespace NzbDrone.Core.Notifications.Xbmc.Model -{ - public class ActivePlayersDharmaResult - { - public string Id { get; set; } - public string JsonRpc { get; set; } - public Dictionary Result { get; set; } - } -} diff --git a/src/NzbDrone.Core/Notifications/Xbmc/Model/ActivePlayersEdenResult.cs b/src/NzbDrone.Core/Notifications/Xbmc/Model/ActivePlayersResult.cs similarity index 85% rename from src/NzbDrone.Core/Notifications/Xbmc/Model/ActivePlayersEdenResult.cs rename to src/NzbDrone.Core/Notifications/Xbmc/Model/ActivePlayersResult.cs index 2f3cc61d8..6868ae48b 100644 --- a/src/NzbDrone.Core/Notifications/Xbmc/Model/ActivePlayersEdenResult.cs +++ b/src/NzbDrone.Core/Notifications/Xbmc/Model/ActivePlayersResult.cs @@ -2,10 +2,10 @@ namespace NzbDrone.Core.Notifications.Xbmc.Model { - public class ActivePlayersEdenResult + public class ActivePlayersResult { public string Id { get; set; } public string JsonRpc { get; set; } public List Result { get; set; } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs b/src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs index 5e2ee5413..0ded5b378 100644 --- a/src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs +++ b/src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs @@ -20,7 +20,7 @@ namespace NzbDrone.Core.Notifications.Xbmc _logger = logger; } - public override string Link => "https://kodi.tv"; + public override string Link => "https://kodi.tv/"; public override void OnGrab(GrabMessage grabMessage) { diff --git a/src/NzbDrone.Core/Notifications/Xbmc/XbmcJsonApiProxy.cs b/src/NzbDrone.Core/Notifications/Xbmc/XbmcJsonApiProxy.cs index 8fa897271..35cc69036 100644 --- a/src/NzbDrone.Core/Notifications/Xbmc/XbmcJsonApiProxy.cs +++ b/src/NzbDrone.Core/Notifications/Xbmc/XbmcJsonApiProxy.cs @@ -63,7 +63,7 @@ namespace NzbDrone.Core.Notifications.Xbmc { var response = ProcessRequest(settings, "Player.GetActivePlayers"); - return Json.Deserialize(response).Result; + return Json.Deserialize(response).Result; } public List GetSeries(XbmcSettings settings) diff --git a/src/NzbDrone.Core/Notifications/Xbmc/XbmcService.cs b/src/NzbDrone.Core/Notifications/Xbmc/XbmcService.cs index d9cacf8f8..837877c93 100644 --- a/src/NzbDrone.Core/Notifications/Xbmc/XbmcService.cs +++ b/src/NzbDrone.Core/Notifications/Xbmc/XbmcService.cs @@ -1,11 +1,9 @@ using System; -using System.Collections.Generic; +using System.IO; using System.Linq; using FluentValidation.Results; -using Newtonsoft.Json.Linq; using NLog; -using NzbDrone.Common.Cache; -using NzbDrone.Common.Serializer; +using NzbDrone.Common.Disk; using NzbDrone.Core.Notifications.Xbmc.Model; using NzbDrone.Core.Tv; @@ -22,95 +20,98 @@ namespace NzbDrone.Core.Notifications.Xbmc public class XbmcService : IXbmcService { private readonly IXbmcJsonApiProxy _proxy; - private readonly IEnumerable _apiProviders; private readonly Logger _logger; - private readonly ICached _xbmcVersionCache; - public XbmcService(IXbmcJsonApiProxy proxy, - IEnumerable apiProviders, - ICacheManager cacheManager, Logger logger) { _proxy = proxy; - _apiProviders = apiProviders; _logger = logger; - - _xbmcVersionCache = cacheManager.GetCache(GetType()); } public void Notify(XbmcSettings settings, string title, string message) { - var provider = GetApiProvider(settings); - provider.Notify(settings, title, message); + _proxy.Notify(settings, title, message); } public void Update(XbmcSettings settings, Series series) { - var provider = GetApiProvider(settings); - provider.Update(settings, series); + if (!settings.AlwaysUpdate) + { + _logger.Debug("Determining if there are any active players on XBMC host: {0}", settings.Address); + var activePlayers = _proxy.GetActivePlayers(settings); + + if (activePlayers.Any(a => a.Type.Equals("video"))) + { + _logger.Debug("Video is currently playing, skipping library update"); + return; + } + } + + UpdateLibrary(settings, series); } public void Clean(XbmcSettings settings) { - var provider = GetApiProvider(settings); - provider.Clean(settings); + _proxy.CleanLibrary(settings); } - private XbmcVersion GetJsonVersion(XbmcSettings settings) + public string GetSeriesPath(XbmcSettings settings, Series series) { - return _xbmcVersionCache.Get(settings.Address, () => + var allSeries = _proxy.GetSeries(settings); + + if (!allSeries.Any()) { - var response = _proxy.GetJsonVersion(settings); + _logger.Debug("No TV shows returned from XBMC"); + return null; + } + + var matchingSeries = allSeries.FirstOrDefault(s => + { + var tvdbId = 0; + int.TryParse(s.ImdbNumber, out tvdbId); + + return tvdbId == series.TvdbId || s.Label == series.Title; + }); - _logger.Debug("Getting version from response: " + response); - var result = Json.Deserialize>(response); + if (matchingSeries != null) return matchingSeries.File; - var versionObject = result.Result.Property("version"); + return null; + } - if (versionObject.Value.Type == JTokenType.Integer) + private void UpdateLibrary(XbmcSettings settings, Series series) + { + try + { + var moviePath = GetSeriesPath(settings, series); + + if (moviePath != null) { - return new XbmcVersion((int)versionObject.Value); + moviePath = new OsPath(moviePath).Directory.FullPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); + _logger.Debug("Updating series {0} (Path: {1}) on XBMC host: {2}", series, moviePath, settings.Address); } - - if (versionObject.Value.Type == JTokenType.Object) + else { - return Json.Deserialize(versionObject.Value.ToString()); + _logger.Debug("Series {0} doesn't exist on XBMC host: {1}, Updating Entire Library", series, settings.Address); } - throw new InvalidCastException("Unknown Version structure!: " + versionObject); - }, TimeSpan.FromHours(12)); - } - - private IApiProvider GetApiProvider(XbmcSettings settings) - { - var version = GetJsonVersion(settings); - var apiProvider = _apiProviders.SingleOrDefault(a => a.CanHandle(version)); + var response = _proxy.UpdateLibrary(settings, moviePath); - if (apiProvider == null) + if (!response.Equals("OK", StringComparison.InvariantCultureIgnoreCase)) + { + _logger.Debug("Failed to update library for: {0}", settings.Address); + } + } + catch (Exception ex) { - var message = string.Format("Invalid API Version: {0} for {1}", version, settings.Address); - throw new InvalidXbmcVersionException(message); + _logger.Debug(ex, ex.Message); } - - return apiProvider; } public ValidationFailure Test(XbmcSettings settings, string message) { - _xbmcVersionCache.Clear(); - try { - _logger.Debug("Determining version of Host: {0}", settings.Address); - var version = GetJsonVersion(settings); - _logger.Debug("Version is: {0}", version); - - if (version == new XbmcVersion(0)) - { - throw new InvalidXbmcVersionException("Version received from XBMC is invalid, please correct your settings."); - } - Notify(settings, "Test Notification", message); } catch (Exception ex) @@ -122,4 +123,4 @@ namespace NzbDrone.Core.Notifications.Xbmc return null; } } -} \ No newline at end of file +}