diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj
index 27be2f100..01459ee65 100644
--- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj
+++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj
@@ -241,6 +241,7 @@
+
diff --git a/NzbDrone.Core.Test/ProviderTests/XbmcProviderTest.cs b/NzbDrone.Core.Test/ProviderTests/XbmcProviderTest.cs
index 79a96ab33..dc3692270 100644
--- a/NzbDrone.Core.Test/ProviderTests/XbmcProviderTest.cs
+++ b/NzbDrone.Core.Test/ProviderTests/XbmcProviderTest.cs
@@ -93,11 +93,8 @@ namespace NzbDrone.Core.Test.ProviderTests
[TestCase(3)]
[TestCase(2)]
[TestCase(0)]
- public void GetJsonVersion(int number)
+ public void GetJsonVersionIntOnly(int number)
{
- //Setup
-
-
var message = "{\"id\":10,\"jsonrpc\":\"2.0\",\"result\":{\"version\":" + number + "}}";
var fakeHttp = Mocker.GetMock();
@@ -108,15 +105,32 @@ namespace NzbDrone.Core.Test.ProviderTests
var result = Mocker.Resolve().GetJsonVersion("localhost:8080", "xbmc", "xbmc");
//Assert
- Assert.AreEqual(number, result);
+ result.Should().Be(new XbmcVersion(number));
+ }
+
+ [TestCase(5, 0, 0)]
+ [TestCase(6, 0, 0)]
+ [TestCase(6, 1, 0)]
+ [TestCase(6, 0, 23)]
+ [TestCase(0, 0, 0)]
+ public void GetJsonVersionFrodo(int major, int minor, int patch)
+ {
+ var message = "{\"id\":10,\"jsonrpc\":\"2.0\",\"result\":{\"version\":{\"major\":" + major + ",\"minor\":" + minor + ",\"patch\":" + patch + "}}}";
+
+ var fakeHttp = Mocker.GetMock();
+ fakeHttp.Setup(s => s.PostCommand("localhost:8080", "xbmc", "xbmc", It.IsAny()))
+ .Returns(message);
+
+ //Act
+ var result = Mocker.Resolve().GetJsonVersion("localhost:8080", "xbmc", "xbmc");
+
+ //Assert
+ result.Should().Be(new XbmcVersion(major, minor, patch));
}
[Test]
public void GetJsonVersion_error()
{
- //Setup
-
-
var message = "{\"error\":{\"code\":-32601,\"message\":\"Method not found.\"},\"id\":10,\"jsonrpc\":\"2.0\"}";
var fakeHttp = Mocker.GetMock();
@@ -127,7 +141,7 @@ namespace NzbDrone.Core.Test.ProviderTests
var result = Mocker.Resolve().GetJsonVersion("localhost:8080", "xbmc", "xbmc");
//Assert
- Assert.AreEqual(0, result);
+ result.Should().Be(new XbmcVersion(0));
}
[TestCase(false, false, false)]
diff --git a/NzbDrone.Core.Test/XbmcVersionTests.cs b/NzbDrone.Core.Test/XbmcVersionTests.cs
new file mode 100644
index 000000000..65b986400
--- /dev/null
+++ b/NzbDrone.Core.Test/XbmcVersionTests.cs
@@ -0,0 +1,94 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using FluentAssertions;
+using NUnit.Framework;
+using NzbDrone.Core.Model.Xbmc;
+using NzbDrone.Core.Repository.Quality;
+
+namespace NzbDrone.Core.Test
+{
+ public class XbmcVersionTests
+ {
+ [TestCase(6, 0, 0)]
+ [TestCase(5, 1, 0)]
+ [TestCase(5, 0, 1)]
+ public void Icomparer_greater_test(int major, int minor, int patch)
+ {
+ var first = new XbmcVersion(5, 0, 0);
+ var second = new XbmcVersion(major, minor, patch);
+
+ second.Should().BeGreaterThan(first);
+ }
+
+ [TestCase(4, 5, 5)]
+ [TestCase(5, 4, 5)]
+ [TestCase(5, 5, 4)]
+ public void Icomparer_lesser_test(int major, int minor, int patch)
+ {
+ var first = new XbmcVersion(5, 5, 5);
+ var second = new XbmcVersion(major, minor, patch);
+
+ second.Should().BeLessThan(first);
+ }
+
+ [Test]
+ public void equal_operand()
+ {
+ var first = new XbmcVersion(5, 0, 0);
+ var second = new XbmcVersion(5, 0, 0);
+
+ (first == second).Should().BeTrue();
+ (first >= second).Should().BeTrue();
+ (first <= second).Should().BeTrue();
+ }
+
+ [Test]
+ public void equal_operand_false()
+ {
+ var first = new XbmcVersion(5, 0, 0);
+ var second = new XbmcVersion(6, 0, 0);
+
+ (first == second).Should().BeFalse();
+ }
+
+ [Test]
+ public void not_equal_operand_false()
+ {
+ var first = new XbmcVersion(5, 0, 0);
+ var second = new XbmcVersion(5, 0, 0);
+
+ (first != second).Should().BeFalse();
+ }
+
+ [Test]
+ public void not_equal_operand_true()
+ {
+ var first = new XbmcVersion(5, 0, 0);
+ var second = new XbmcVersion(6, 0, 0);
+
+ (first != second).Should().BeTrue();
+ }
+
+ [Test]
+ public void greater_operand()
+ {
+ var first = new XbmcVersion(5, 0, 0);
+ var second = new XbmcVersion(6, 0, 0);
+
+ (first < second).Should().BeTrue();
+ (first <= second).Should().BeTrue();
+ }
+
+ [Test]
+ public void lesser_operand()
+ {
+ var first = new XbmcVersion(5, 0, 0);
+ var second = new XbmcVersion(6, 0, 0);
+
+ (second > first).Should().BeTrue();
+ (second >= first).Should().BeTrue();
+ }
+ }
+}
diff --git a/NzbDrone.Core/Model/Xbmc/XbmcJsonResult.cs b/NzbDrone.Core/Model/Xbmc/XbmcJsonResult.cs
new file mode 100644
index 000000000..be4ed1d88
--- /dev/null
+++ b/NzbDrone.Core/Model/Xbmc/XbmcJsonResult.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace NzbDrone.Core.Model.Xbmc
+{
+ public class XbmcJsonResult
+ {
+ public string Id { get; set; }
+ public string JsonRpc { get; set; }
+ public T Result { get; set; }
+ }
+}
diff --git a/NzbDrone.Core/Model/Xbmc/XbmcVersion.cs b/NzbDrone.Core/Model/Xbmc/XbmcVersion.cs
new file mode 100644
index 000000000..b5ad93ead
--- /dev/null
+++ b/NzbDrone.Core/Model/Xbmc/XbmcVersion.cs
@@ -0,0 +1,123 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace NzbDrone.Core.Model.Xbmc
+{
+ public class XbmcVersion : IComparable
+ {
+ public XbmcVersion()
+ {
+ }
+
+ public XbmcVersion(int major)
+ {
+ Major = major;
+ }
+
+ public XbmcVersion(int major, int minor, int patch)
+ {
+ Major = major;
+ Minor = minor;
+ Patch = patch;
+ }
+
+ public int Major { get; set; }
+ public int Minor { get; set; }
+ public int Patch { get; set; }
+
+ public int CompareTo(XbmcVersion other)
+ {
+ if(other.Major > Major)
+ return -1;
+
+ if(other.Major < Major)
+ return 1;
+
+ if (other.Minor > Minor)
+ return -1;
+
+ if (other.Minor < Minor)
+ return 1;
+
+ if (other.Patch > Patch)
+ return -1;
+
+ if (other.Patch < Patch)
+ return 1;
+
+ return 0;
+ }
+
+ public static bool operator !=(XbmcVersion x, XbmcVersion y)
+ {
+ return !(x == y);
+ }
+
+ public static bool operator ==(XbmcVersion x, XbmcVersion y)
+ {
+ var xObj = (Object)x;
+ var yObj = (object)y;
+
+ if (xObj == null || yObj == null)
+ {
+ return xObj == yObj;
+ }
+
+ return x.CompareTo(y) == 0;
+ }
+
+ public static bool operator >(XbmcVersion x, XbmcVersion y)
+ {
+ return x.CompareTo(y) > 0;
+ }
+
+ public static bool operator <(XbmcVersion x, XbmcVersion y)
+ {
+ return x.CompareTo(y) < 0;
+ }
+
+ public static bool operator <=(XbmcVersion x, XbmcVersion y)
+ {
+ return x.CompareTo(y) <= 0;
+ }
+
+ public static bool operator >=(XbmcVersion x, XbmcVersion y)
+ {
+ return x.CompareTo(y) >= 0;
+ }
+
+ public override string ToString()
+ {
+ return String.Format("{0}.{1}.{2}", Major, Minor, Patch);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked // Overflow is fine, just wrap
+ {
+ int hash = 17;
+ hash = hash * 23 + Major.GetHashCode();
+ hash = hash * 23 + Minor.GetHashCode();
+ hash = hash * 23 + Patch.GetHashCode();
+ return hash;
+ }
+ }
+
+ public bool Equals(XbmcVersion other)
+ {
+ if (ReferenceEquals(null, other)) return false;
+ if (ReferenceEquals(this, other)) return true;
+ return (Equals(other.Major, Major) && Equals(other.Minor, Minor) && Equals(other.Patch, Patch));
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != typeof(XbmcVersion)) return false;
+ return Equals((XbmcVersion)obj);
+ }
+ }
+}
diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj
index c1f0181e6..360b57ed2 100644
--- a/NzbDrone.Core/NzbDrone.Core.csproj
+++ b/NzbDrone.Core/NzbDrone.Core.csproj
@@ -299,6 +299,8 @@
+
+
diff --git a/NzbDrone.Core/Providers/XbmcProvider.cs b/NzbDrone.Core/Providers/XbmcProvider.cs
index 6e7f6e867..c4cc4aa8d 100644
--- a/NzbDrone.Core/Providers/XbmcProvider.cs
+++ b/NzbDrone.Core/Providers/XbmcProvider.cs
@@ -60,7 +60,7 @@ namespace NzbDrone.Core.Providers
var version = GetJsonVersion(host, username, password);
//If Dharma
- if (version == 2)
+ if (version == new XbmcVersion(2))
{
//Check for active player only when we should skip updates when playing
if (!_configProvider.XbmcUpdateWhenPlaying)
@@ -80,7 +80,7 @@ namespace NzbDrone.Core.Providers
}
//If Eden or newer (attempting to make it future compatible)
- else if (version >= 3)
+ else if (version == new XbmcVersion(3) || version == new XbmcVersion(4))
{
//Check for active player only when we should skip updates when playing
if (!_configProvider.XbmcUpdateWhenPlaying)
@@ -99,6 +99,25 @@ namespace NzbDrone.Core.Providers
UpdateWithJson(series, host, username, password);
}
+ else if (version >= new XbmcVersion(5))
+ {
+ //Check for active player only when we should skip updates when playing
+ if (!_configProvider.XbmcUpdateWhenPlaying)
+ {
+ Logger.Trace("Determining if there are any active players on XBMC host: {0}", host);
+ var activePlayers = GetActivePlayersEden(host, username, password);
+
+ //If video is currently playing, then skip update
+ if (activePlayers.Any(a => a.Type.Equals("video")))
+ {
+ Logger.Debug("Video is currently playing, skipping library update");
+ continue;
+ }
+ }
+
+ UpdateWithJson(series, host, username, password);
+ }
+
//Log Version zero if check failed
else
Logger.Trace("Unknown version: [{0}], skipping.", version);
@@ -239,12 +258,11 @@ namespace NzbDrone.Core.Providers
return field.Value;
}
- public virtual int GetJsonVersion(string host, string username, string password)
+ public virtual XbmcVersion GetJsonVersion(string host, string username, string password)
{
//2 = Dharma
- //3 = Eden/Nightly (as of July 2011)
-
- var version = 0;
+ //3 & 4 = Eden
+ //5 & 6 = Frodo
try
{
@@ -256,11 +274,20 @@ namespace NzbDrone.Core.Providers
var response = _httpProvider.PostCommand(host, username, password, postJson.ToString());
if (CheckForJsonError(response))
- return version;
+ return new XbmcVersion();
Logger.Trace("Getting version from response");
- var result = JsonConvert.DeserializeObject(response);
- result.Result.TryGetValue("version", out version);
+ var result = JsonConvert.DeserializeObject>(response);
+
+ var versionObject = result.Result.Property("version");
+
+ if (versionObject.Value.Type == JTokenType.Integer)
+ return new XbmcVersion((int)versionObject.Value);
+
+ if(versionObject.Value.Type == JTokenType.Object)
+ return JsonConvert.DeserializeObject(versionObject.Value.ToString());
+
+ throw new InvalidCastException("Unknown Version structure!: " + versionObject);
}
catch (Exception ex)
@@ -268,7 +295,7 @@ namespace NzbDrone.Core.Providers
Logger.DebugException(ex.Message, ex);
}
- return version;
+ return new XbmcVersion();
}
public virtual Dictionary GetActivePlayersDharma(string host, string username, string password)
@@ -391,7 +418,7 @@ namespace NzbDrone.Core.Providers
{
Logger.Trace("Sending Test Notifcation to XBMC Host: {0}", host);
var version = GetJsonVersion(host, username, password);
- if (version == 0)
+ if (version == new XbmcVersion())
throw new Exception("Failed to get JSON version in test");
}
}