diff --git a/NzbDrone.Core.Test/ProviderTests/XbmcProviderTest.cs b/NzbDrone.Core.Test/ProviderTests/XbmcProviderTest.cs
index dc3692270..9e4a7a19d 100644
--- a/NzbDrone.Core.Test/ProviderTests/XbmcProviderTest.cs
+++ b/NzbDrone.Core.Test/ProviderTests/XbmcProviderTest.cs
@@ -505,7 +505,7 @@ namespace NzbDrone.Core.Test.ProviderTests
}
[Test]
- public void UpdateWithJson_Single()
+ public void UpdateWithJsonBuiltIn_Single()
{
//Setup
@@ -530,18 +530,15 @@ namespace NzbDrone.Core.Test.ProviderTests
fakeHttp.Setup(s => s.DownloadString(url, username, password)).Returns("
OK");
- //var fakeEventClient = Mocker.GetMock();
- //fakeEventClient.Setup(s => s.SendAction("localhost", ActionType.ExecBuiltin, "ExecBuiltIn(UpdateLibrary(video,smb://HOMESERVER/TV/30 Rock/))"));
-
//Act
- var result = Mocker.Resolve().UpdateWithJson(fakeSeries, host, username, password);
+ var result = Mocker.Resolve().UpdateWithJsonExecBuiltIn(fakeSeries, host, username, password);
//Assert
result.Should().BeTrue();
}
[Test]
- public void UpdateWithJson_All()
+ public void UpdateWithJsonBuiltIn_All()
{
//Setup
@@ -570,7 +567,71 @@ namespace NzbDrone.Core.Test.ProviderTests
//fakeEventClient.Setup(s => s.SendAction("localhost", ActionType.ExecBuiltin, "ExecBuiltIn(UpdateLibrary(video))"));
//Act
- var result = Mocker.Resolve().UpdateWithJson(fakeSeries, host, username, password);
+ var result = Mocker.Resolve().UpdateWithJsonExecBuiltIn(fakeSeries, host, username, password);
+
+ //Assert
+ result.Should().BeTrue();
+ }
+
+ [Test]
+ public void UpdateWithJsonVideoLibraryScan_Single()
+ {
+ var host = "localhost:8080";
+ var username = "xbmc";
+ var password = "xbmc";
+ var expectedJson = "{\"jsonrpc\":\"2.0\",\"method\":\"VideoLibrary.GetTvShows\",\"params\":{\"properties\":[\"file\",\"imdbnumber\"]},\"id\":10}";
+ var tvshows = "{\"id\":10,\"jsonrpc\":\"2.0\",\"result\":{\"limits\":{\"end\":5,\"start\":0,\"total\":5},\"tvshows\":[{\"file\":\"smb://HOMESERVER/TV/7th Heaven/\",\"imdbnumber\":\"73928\",\"label\":\"7th Heaven\",\"tvshowid\":3},{\"file\":\"smb://HOMESERVER/TV/8 Simple Rules/\",\"imdbnumber\":\"78461\",\"label\":\"8 Simple Rules\",\"tvshowid\":4},{\"file\":\"smb://HOMESERVER/TV/24-7 Penguins-Capitals- Road to the NHL Winter Classic/\",\"imdbnumber\":\"213041\",\"label\":\"24/7 Penguins/Capitals: Road to the NHL Winter Classic\",\"tvshowid\":1},{\"file\":\"smb://HOMESERVER/TV/30 Rock/\",\"imdbnumber\":\"79488\",\"label\":\"30 Rock\",\"tvshowid\":2},{\"file\":\"smb://HOMESERVER/TV/90210/\",\"imdbnumber\":\"82716\",\"label\":\"90210\",\"tvshowid\":5}]}}";
+
+ var fakeSeries = Builder.CreateNew()
+ .With(s => s.SeriesId = 79488)
+ .With(s => s.Title = "30 Rock")
+ .Build();
+
+ var fakeHttp = Mocker.GetMock();
+ fakeHttp.Setup(s => s.PostCommand(host, username, password, It.Is(e => e.Replace(" ", "").Replace("\r\n", "").Replace("\t", "") == expectedJson.Replace(" ", ""))))
+ .Returns(tvshows);
+
+ fakeHttp.Setup(s => s.PostCommand(host, username, password, It.Is(
+ e => e.Replace(" ", "")
+ .Replace("\r\n", "")
+ .Replace("\t", "")
+ .Contains("\"params\":{\"directory\":\"smb://HOMESERVER/TV/30Rock/\"}"))))
+ .Returns("{\"id\":55,\"jsonrpc\":\"2.0\",\"result\":\"OK\"}");
+
+ //Act
+ var result = Mocker.Resolve().UpdateWithJsonVideoLibraryScan(fakeSeries, host, username, password);
+
+ //Assert
+ result.Should().BeTrue();
+ }
+
+ [Test]
+ public void UpdateWithJsonVideoLibraryScan_All()
+ {
+ var host = "localhost:8080";
+ var username = "xbmc";
+ var password = "xbmc";
+ var expectedJson = "{\"jsonrpc\":\"2.0\",\"method\":\"VideoLibrary.GetTvShows\",\"params\":{\"properties\":[\"file\",\"imdbnumber\"]},\"id\":10}";
+ var tvshows = "{\"id\":10,\"jsonrpc\":\"2.0\",\"result\":{\"limits\":{\"end\":5,\"start\":0,\"total\":5},\"tvshows\":[{\"file\":\"smb://HOMESERVER/TV/7th Heaven/\",\"imdbnumber\":\"73928\",\"label\":\"7th Heaven\",\"tvshowid\":3},{\"file\":\"smb://HOMESERVER/TV/8 Simple Rules/\",\"imdbnumber\":\"78461\",\"label\":\"8 Simple Rules\",\"tvshowid\":4},{\"file\":\"smb://HOMESERVER/TV/24-7 Penguins-Capitals- Road to the NHL Winter Classic/\",\"imdbnumber\":\"213041\",\"label\":\"24/7 Penguins/Capitals: Road to the NHL Winter Classic\",\"tvshowid\":1},{\"file\":\"smb://HOMESERVER/TV/90210/\",\"imdbnumber\":\"82716\",\"label\":\"90210\",\"tvshowid\":5}]}}";
+
+ var fakeSeries = Builder.CreateNew()
+ .With(s => s.SeriesId = 79488)
+ .With(s => s.Title = "30 Rock")
+ .Build();
+
+ var fakeHttp = Mocker.GetMock();
+ fakeHttp.Setup(s => s.PostCommand(host, username, password, It.Is(e => e.Replace(" ", "").Replace("\r\n", "").Replace("\t", "") == expectedJson.Replace(" ", ""))))
+ .Returns(tvshows);
+
+ fakeHttp.Setup(s => s.PostCommand(host, username, password, It.Is(
+ e => !e.Replace(" ", "")
+ .Replace("\r\n", "")
+ .Replace("\t", "")
+ .Contains("\"params\":{\"directory\":\"smb://HOMESERVER/TV/30Rock/\"}"))))
+ .Returns("{\"id\":55,\"jsonrpc\":\"2.0\",\"result\":\"OK\"}");
+
+ //Act
+ var result = Mocker.Resolve().UpdateWithJsonVideoLibraryScan(fakeSeries, host, username, password);
//Assert
result.Should().BeTrue();
diff --git a/NzbDrone.Core/Model/Xbmc/XbmcVersion.cs b/NzbDrone.Core/Model/Xbmc/XbmcVersion.cs
index b5ad93ead..5b777844d 100644
--- a/NzbDrone.Core/Model/Xbmc/XbmcVersion.cs
+++ b/NzbDrone.Core/Model/Xbmc/XbmcVersion.cs
@@ -119,5 +119,10 @@ namespace NzbDrone.Core.Model.Xbmc
if (obj.GetType() != typeof(XbmcVersion)) return false;
return Equals((XbmcVersion)obj);
}
+
+ public static XbmcVersion NONE = new XbmcVersion(0, 0, 0);
+ public static XbmcVersion DHARMA = new XbmcVersion(2, 0, 0);
+ public static XbmcVersion EDEN = new XbmcVersion(4, 0, 0);
+ public static XbmcVersion FRODO = new XbmcVersion(6, 0, 0);
}
}
diff --git a/NzbDrone.Core/Providers/XbmcProvider.cs b/NzbDrone.Core/Providers/XbmcProvider.cs
index c4cc4aa8d..62482e869 100644
--- a/NzbDrone.Core/Providers/XbmcProvider.cs
+++ b/NzbDrone.Core/Providers/XbmcProvider.cs
@@ -96,7 +96,7 @@ namespace NzbDrone.Core.Providers
}
}
- UpdateWithJson(series, host, username, password);
+ UpdateWithJsonExecBuiltIn(series, host, username, password);
}
else if (version >= new XbmcVersion(5))
@@ -115,7 +115,7 @@ namespace NzbDrone.Core.Providers
}
}
- UpdateWithJson(series, host, username, password);
+ UpdateWithJsonVideoLibraryScan(series, host, username, password);
}
//Log Version zero if check failed
@@ -124,7 +124,7 @@ namespace NzbDrone.Core.Providers
}
}
- public virtual bool UpdateWithJson(Series series, string host, string username, string password)
+ public virtual bool UpdateWithJsonExecBuiltIn(Series series, string host, string username, string password)
{
try
{
@@ -145,8 +145,6 @@ namespace NzbDrone.Core.Providers
if (path != null)
{
Logger.Trace("Updating series [{0}] (Path: {1}) on XBMC host: {2}", series.Title, path.File, host);
- //var command = String.Format("ExecBuiltIn(UpdateLibrary(video, {0}))", path.File);
- //_eventClientProvider.SendAction(hostOnly, ActionType.ExecBuiltin, command);
var command = String.Format("ExecBuiltIn(UpdateLibrary(video,{0}))", path.File);
SendCommand(host, command, username, password);
}
@@ -154,8 +152,6 @@ namespace NzbDrone.Core.Providers
else
{
Logger.Trace("Series [{0}] doesn't exist on XBMC host: {1}, Updating Entire Library", series.Title, host);
- var command = String.Format("ExecBuiltIn(UpdateLibrary(video))");
- //_eventClientProvider.SendAction(hostOnly, ActionType.ExecBuiltin, command);
SendCommand(host, "ExecBuiltIn(UpdateLibrary(video))", username, password);
}
}
@@ -169,6 +165,57 @@ namespace NzbDrone.Core.Providers
return true;
}
+ public virtual bool UpdateWithJsonVideoLibraryScan(Series series, string host, string username, string password)
+ {
+ try
+ {
+ //Use Json!
+ var xbmcShows = GetTvShowsJson(host, username, password);
+
+ TvShow path = null;
+
+ //Log if response is null, otherwise try to find XBMC's path for series
+ if (xbmcShows == null)
+ Logger.Trace("Failed to get TV Shows from XBMC");
+
+ else
+ path = xbmcShows.FirstOrDefault(s => s.ImdbNumber == series.SeriesId || s.Label == series.Title);
+
+ var postJson = new JObject();
+ postJson.Add(new JProperty("jsonrpc", "2.0"));
+ postJson.Add(new JProperty("method", "VideoLibrary.Scan"));
+ postJson.Add(new JProperty("id", 55));
+
+ if (path != null)
+ {
+ Logger.Trace("Updating series [{0}] (Path: {1}) on XBMC host: {2}", series.Title, path.File, host);
+ postJson.Add(new JProperty("params", new JObject(new JObject(new JProperty("directory", path.File)))));
+ }
+
+ else
+ Logger.Trace("Series [{0}] doesn't exist on XBMC host: {1}, Updating Entire Library", series.Title, host);
+
+ var response = _httpProvider.PostCommand(host, username, password, postJson.ToString());
+
+ if (CheckForJsonError(response))
+ return false;
+
+ Logger.Trace(" from response");
+ var result = JsonConvert.DeserializeObject>(response);
+
+ if(!result.Result.Equals("OK", StringComparison.InvariantCultureIgnoreCase))
+ return false;
+ }
+
+ catch (Exception ex)
+ {
+ Logger.DebugException(ex.Message, ex);
+ return false;
+ }
+
+ return true;
+ }
+
public virtual bool UpdateWithHttp(Series series, string host, string username, string password)
{
try