diff --git a/NzbDrone.Core.Test/Files/Queue.txt b/NzbDrone.Core.Test/Files/Queue.txt index 13edf093c..58321b10a 100644 --- a/NzbDrone.Core.Test/Files/Queue.txt +++ b/NzbDrone.Core.Test/Files/Queue.txt @@ -67,7 +67,7 @@ "size":"267 MB", "sizeleft":"239 MB", "status":"Downloading", - "timeleft":"31:12:34", + "timeleft":"57:27:45", "unpackopts":"3", "verbosity":"" }, diff --git a/NzbDrone.Core.Test/ProviderTests/SabProviderTests/QueueFixture.cs b/NzbDrone.Core.Test/ProviderTests/SabProviderTests/QueueFixture.cs index 29af676b7..f81769814 100644 --- a/NzbDrone.Core.Test/ProviderTests/SabProviderTests/QueueFixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/SabProviderTests/QueueFixture.cs @@ -188,8 +188,6 @@ namespace NzbDrone.Core.Test.ProviderTests.SabProviderTests result.Should().BeTrue(); } - - [Test] public void IsInQueue_should_return_false_if_queue_is_empty() { @@ -209,6 +207,21 @@ namespace NzbDrone.Core.Test.ProviderTests.SabProviderTests result.Should().BeFalse(); } + [Test] + public void GetQueue_should_parse_timeleft_with_hours_greater_than_24_hours() + { + WithFullQueue(); + + var result = Mocker.Resolve().GetQueue(); + + result.Should().NotBeEmpty(); + var timeleft = result.First(q => q.Id == "SABnzbd_nzo_qv6ilb").Timeleft; + timeleft.Days.Should().Be(2); + timeleft.Hours.Should().Be(9); + timeleft.Minutes.Should().Be(27); + timeleft.Seconds.Should().Be(45); + } + [TearDown] public void TearDown() { diff --git a/NzbDrone.Core/Helpers/SabnzbdQueueTimeConverter.cs b/NzbDrone.Core/Helpers/SabnzbdQueueTimeConverter.cs new file mode 100644 index 000000000..61e70bc03 --- /dev/null +++ b/NzbDrone.Core/Helpers/SabnzbdQueueTimeConverter.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Newtonsoft.Json; + +namespace NzbDrone.Core.Helpers +{ + public class SabnzbdQueueTimeConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + if (value is TimeSpan) + writer.WriteValue(value.ToString()); + + else + throw new Exception("Expected TimeSpan object value."); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + var split = reader.Value.ToString().Split(':'); + + if (split.Count() == 3) + { + return new TimeSpan(int.Parse(split[0]), // hours + int.Parse(split[1]), // minutes + int.Parse(split[2]) // seconds + ); + } + + throw new ArgumentException("TimeSpan is invalid"); + } + + public override bool CanConvert(Type objectType) + { + if (objectType == typeof(TimeSpan)) + return true; + + return false; + } + } +} diff --git a/NzbDrone.Core/Model/Sabnzbd/SabQueueItem.cs b/NzbDrone.Core/Model/Sabnzbd/SabQueueItem.cs index 111a92753..b8e61fee5 100644 --- a/NzbDrone.Core/Model/Sabnzbd/SabQueueItem.cs +++ b/NzbDrone.Core/Model/Sabnzbd/SabQueueItem.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using Newtonsoft.Json; +using NzbDrone.Core.Helpers; namespace NzbDrone.Core.Model.Sabnzbd { @@ -10,6 +11,8 @@ namespace NzbDrone.Core.Model.Sabnzbd { public string Status { get; set; } public int Index { get; set; } + + [JsonConverter(typeof(SabnzbdQueueTimeConverter))] public TimeSpan Timeleft { get; set; } [JsonProperty(PropertyName = "mb")] diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 4a66dff38..db80ed76c 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -226,6 +226,7 @@ +