diff --git a/NzbDrone.Api/Commands/CommandModule.cs b/NzbDrone.Api/Commands/CommandModule.cs index 231089734..ddb5ff956 100644 --- a/NzbDrone.Api/Commands/CommandModule.cs +++ b/NzbDrone.Api/Commands/CommandModule.cs @@ -6,7 +6,6 @@ using NzbDrone.Api.Mapping; using NzbDrone.Api.Validation; using NzbDrone.Common.Composition; using NzbDrone.Core.Datastore.Events; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Commands.Tracking; using NzbDrone.Core.Messaging.Events; diff --git a/NzbDrone.Api/ErrorManagement/NzbDroneErrorPipeline.cs b/NzbDrone.Api/ErrorManagement/NzbDroneErrorPipeline.cs index 47d79c849..04e9263e2 100644 --- a/NzbDrone.Api/ErrorManagement/NzbDroneErrorPipeline.cs +++ b/NzbDrone.Api/ErrorManagement/NzbDroneErrorPipeline.cs @@ -3,7 +3,7 @@ using FluentValidation; using NLog; using Nancy; using NzbDrone.Api.Extensions; -using NzbDrone.Core; +using NzbDrone.Core.Exceptions; using HttpStatusCode = Nancy.HttpStatusCode; namespace NzbDrone.Api.ErrorManagement @@ -17,9 +17,11 @@ namespace NzbDrone.Api.ErrorManagement _logger = logger; } - public Response HandleException(NancyContext context, Exception exception) + public Response HandleException(NancyContext context, Exception aggregateException) { - var apiException = exception as ApiException; + var innerException = (aggregateException.InnerException).InnerException; + + var apiException = innerException as ApiException; if (apiException != null) { @@ -27,7 +29,7 @@ namespace NzbDrone.Api.ErrorManagement return apiException.ToErrorResponse(); } - var validationException = exception as ValidationException; + var validationException = innerException as ValidationException; if (validationException != null) { @@ -36,23 +38,23 @@ namespace NzbDrone.Api.ErrorManagement return validationException.Errors.AsResponse(HttpStatusCode.BadRequest); } - var clientException = exception as NzbDroneClientException; + var clientException = innerException as NzbDroneClientException; if (clientException != null) { return new ErrorModel { - Message = exception.Message, - Description = exception.ToString() + Message = innerException.Message, + Description = innerException.ToString() }.AsResponse((HttpStatusCode)clientException.StatusCode); } - _logger.FatalException("Request Failed", exception); + _logger.FatalException("Request Failed", innerException); return new ErrorModel { - Message = exception.Message, - Description = exception.ToString() + Message = innerException.Message, + Description = innerException.ToString() }.AsResponse(HttpStatusCode.InternalServerError); } } diff --git a/NzbDrone.Api/Frontend/Mappers/IndexHtmlMapper.cs b/NzbDrone.Api/Frontend/Mappers/IndexHtmlMapper.cs index fb11b68aa..b15167619 100644 --- a/NzbDrone.Api/Frontend/Mappers/IndexHtmlMapper.cs +++ b/NzbDrone.Api/Frontend/Mappers/IndexHtmlMapper.cs @@ -1,4 +1,5 @@ using System.IO; +using Nancy; using NLog; using NzbDrone.Common; using NzbDrone.Common.EnvironmentInfo; @@ -27,6 +28,14 @@ namespace NzbDrone.Api.Frontend.Mappers return !resourceUrl.Contains("."); } + public override Response GetResponse(string resourceUrl) + { + var response = base.GetResponse(resourceUrl); + response.Headers["X-UA-Compatible"] = "IE=edge"; + + return response; + } + protected override Stream GetContentStream(string filePath) { return StringToStream(GetIndexText()); diff --git a/NzbDrone.Api/Frontend/Mappers/StaticResourceMapperBase.cs b/NzbDrone.Api/Frontend/Mappers/StaticResourceMapperBase.cs index e789c01a7..eae69b9de 100644 --- a/NzbDrone.Api/Frontend/Mappers/StaticResourceMapperBase.cs +++ b/NzbDrone.Api/Frontend/Mappers/StaticResourceMapperBase.cs @@ -33,7 +33,7 @@ namespace NzbDrone.Api.Frontend.Mappers public abstract bool CanHandle(string resourceUrl); - public Response GetResponse(string resourceUrl) + public virtual Response GetResponse(string resourceUrl) { var filePath = Map(resourceUrl); diff --git a/NzbDrone.Api/Indexers/ReleaseModule.cs b/NzbDrone.Api/Indexers/ReleaseModule.cs index f00d30542..2fd32e2ea 100644 --- a/NzbDrone.Api/Indexers/ReleaseModule.cs +++ b/NzbDrone.Api/Indexers/ReleaseModule.cs @@ -1,7 +1,8 @@ using System.Collections.Generic; +using FluentValidation; using Nancy; -using NLog; using NzbDrone.Api.Mapping; +using NzbDrone.Api.REST; using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.DecisionEngine.Specifications; using NzbDrone.Core.Download; @@ -9,6 +10,7 @@ using NzbDrone.Core.IndexerSearch; using NzbDrone.Core.Indexers; using NzbDrone.Core.Parser; using NzbDrone.Core.Parser.Model; +using NzbDrone.Core.Tv; using Omu.ValueInjecter; using System.Linq; using Nancy.ModelBinding; @@ -37,13 +39,14 @@ namespace NzbDrone.Api.Indexers _parsingService = parsingService; GetResourceAll = GetReleases; Post["/"] = x=> DownloadRelease(this.Bind()); + + PostValidator.RuleFor(s => s.DownloadAllowed).Equal(true); } private Response DownloadRelease(ReleaseResource release) { var remoteEpisode = _parsingService.Map(release.InjectTo(), 0); remoteEpisode.Release = release.InjectTo(); - _downloadService.DownloadReport(remoteEpisode); return release.AsResponse(); @@ -86,6 +89,7 @@ namespace NzbDrone.Api.Indexers release.InjectFrom(downloadDecision.RemoteEpisode.ParsedEpisodeInfo); release.InjectFrom(downloadDecision); release.Rejections = downloadDecision.Rejections.ToList(); + release.DownloadAllowed = downloadDecision.RemoteEpisode.DownloadAllowed; result.Add(release); } diff --git a/NzbDrone.Api/Indexers/ReleaseResource.cs b/NzbDrone.Api/Indexers/ReleaseResource.cs index 3cc4a054a..a745f3869 100644 --- a/NzbDrone.Api/Indexers/ReleaseResource.cs +++ b/NzbDrone.Api/Indexers/ReleaseResource.cs @@ -28,5 +28,6 @@ namespace NzbDrone.Api.Indexers public String CommentUrl { get; set; } public String DownloadUrl { get; set; } public String InfoUrl { get; set; } + public Boolean DownloadAllowed { get; set; } } } \ No newline at end of file diff --git a/NzbDrone.Api/NancyBootstrapper.cs b/NzbDrone.Api/NancyBootstrapper.cs index 263c4f265..29535d272 100644 --- a/NzbDrone.Api/NancyBootstrapper.cs +++ b/NzbDrone.Api/NancyBootstrapper.cs @@ -7,7 +7,6 @@ using NzbDrone.Api.Extensions.Pipelines; using NzbDrone.Common.Instrumentation; using NzbDrone.Core.Instrumentation; using NzbDrone.Core.Lifecycle; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; using TinyIoC; diff --git a/NzbDrone.Api/NzbDrone.Api.csproj b/NzbDrone.Api/NzbDrone.Api.csproj index a4fb4ee50..331591808 100644 --- a/NzbDrone.Api/NzbDrone.Api.csproj +++ b/NzbDrone.Api/NzbDrone.Api.csproj @@ -46,12 +46,13 @@ False ..\packages\Microsoft.AspNet.SignalR.Core.1.1.3\lib\net40\Microsoft.AspNet.SignalR.Core.dll - - ..\packages\Nancy.0.18.0\lib\net40\Nancy.dll + + False + ..\packages\Nancy.0.20.0\lib\net40\Nancy.dll - + False - ..\packages\Nancy.Authentication.Basic.0.18.0\lib\net40\Nancy.Authentication.Basic.dll + ..\packages\Nancy.Authentication.Basic.0.20.0\lib\net40\Nancy.Authentication.Basic.dll False @@ -190,4 +191,4 @@ --> - + \ No newline at end of file diff --git a/NzbDrone.Api/NzbDroneRestModuleWithSignalR.cs b/NzbDrone.Api/NzbDroneRestModuleWithSignalR.cs index d8350b8ae..7cdfb3f53 100644 --- a/NzbDrone.Api/NzbDroneRestModuleWithSignalR.cs +++ b/NzbDrone.Api/NzbDroneRestModuleWithSignalR.cs @@ -1,7 +1,6 @@ using NzbDrone.Api.REST; using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore.Events; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; using NzbDrone.SignalR; diff --git a/NzbDrone.Api/Qualities/QualityProfileModule.cs b/NzbDrone.Api/Qualities/QualityProfileModule.cs index 1ff4379a6..a08fdb12c 100644 --- a/NzbDrone.Api/Qualities/QualityProfileModule.cs +++ b/NzbDrone.Api/Qualities/QualityProfileModule.cs @@ -8,9 +8,9 @@ namespace NzbDrone.Api.Qualities { public class QualityProfileModule : NzbDroneRestModule { - private readonly QualityProfileService _qualityProfileService; + private readonly IQualityProfileService _qualityProfileService; - public QualityProfileModule(QualityProfileService qualityProfileService) + public QualityProfileModule(IQualityProfileService qualityProfileService) : base("/qualityprofiles") { _qualityProfileService = qualityProfileService; diff --git a/NzbDrone.Api/Qualities/QualitySizeModule.cs b/NzbDrone.Api/Qualities/QualitySizeModule.cs index 27d3b329e..206bc9c51 100644 --- a/NzbDrone.Api/Qualities/QualitySizeModule.cs +++ b/NzbDrone.Api/Qualities/QualitySizeModule.cs @@ -6,9 +6,9 @@ namespace NzbDrone.Api.Qualities { public class QualitySizeModule : NzbDroneRestModule { - private readonly QualitySizeService _qualityTypeProvider; + private readonly IQualitySizeService _qualityTypeProvider; - public QualitySizeModule(QualitySizeService qualityTypeProvider) + public QualitySizeModule(IQualitySizeService qualityTypeProvider) { _qualityTypeProvider = qualityTypeProvider; diff --git a/NzbDrone.Api/packages.config b/NzbDrone.Api/packages.config index dff31468c..722ec5a8b 100644 --- a/NzbDrone.Api/packages.config +++ b/NzbDrone.Api/packages.config @@ -2,8 +2,8 @@ - - + + diff --git a/NzbDrone.App.Test/ContainerFixture.cs b/NzbDrone.App.Test/ContainerFixture.cs index 244901c0a..14a35688d 100644 --- a/NzbDrone.App.Test/ContainerFixture.cs +++ b/NzbDrone.App.Test/ContainerFixture.cs @@ -6,7 +6,6 @@ using NzbDrone.Core.Download; using NzbDrone.Core.Indexers; using NzbDrone.Core.Jobs; using NzbDrone.Core.Lifecycle; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; using NzbDrone.Host; diff --git a/NzbDrone.App.Test/MonitoringProviderTest.cs b/NzbDrone.App.Test/MonitoringProviderTest.cs index 2d504b072..f1e4b0a9b 100644 --- a/NzbDrone.App.Test/MonitoringProviderTest.cs +++ b/NzbDrone.App.Test/MonitoringProviderTest.cs @@ -4,6 +4,7 @@ using Moq; using NUnit.Framework; using NzbDrone.Common; using NzbDrone.Common.Model; +using NzbDrone.Common.Processes; using NzbDrone.Host; using NzbDrone.Test.Common; diff --git a/NzbDrone.Common.Test/DiskProviderTests/FreeSpaceFixture.cs b/NzbDrone.Common.Test/DiskProviderTests/FreeSpaceFixture.cs index f3ede03eb..b29f60180 100644 --- a/NzbDrone.Common.Test/DiskProviderTests/FreeSpaceFixture.cs +++ b/NzbDrone.Common.Test/DiskProviderTests/FreeSpaceFixture.cs @@ -1,36 +1,43 @@ -using FluentAssertions; +using System.IO; +using FluentAssertions; using NUnit.Framework; using NzbDrone.Test.Common; namespace NzbDrone.Common.Test.DiskProviderTests { [TestFixture] - public class IsParentFixture : TestBase + public class FreeSpaceFixture : TestBase { - private string _parent = @"C:\Test".AsOsAgnostic(); - [Test] - public void should_return_false_when_not_a_child() + public void should_get_free_space_for_folder() { - var path = @"C:\Another Folder".AsOsAgnostic(); + var path = @"C:\".AsOsAgnostic(); - Subject.IsParent(_parent, path).Should().BeFalse(); + Subject.GetAvailableSpace(path).Should().NotBe(0); } [Test] - public void should_return_true_when_folder_is_parent_of_another_folder() + public void should_get_free_space_for_folder_that_doesnt_exist() { - var path = @"C:\Test\TV".AsOsAgnostic(); + var path = @"C:\".AsOsAgnostic(); - Subject.IsParent(_parent, path).Should().BeTrue(); + Subject.GetAvailableSpace(Path.Combine(path, "invalidFolder")).Should().NotBe(0); } + [Test] - public void should_return_true_when_folder_is_parent_of_a_file() + public void should_get_free_space_for_drive_that_doesnt_exist() { - var path = @"C:\Test\30.Rock.S01E01.Pilot.avi".AsOsAgnostic(); + WindowsOnly(); + + Assert.Throws(() => Subject.GetAvailableSpace("J:\\").Should().NotBe(0)); + } - Subject.IsParent(_parent, path).Should().BeTrue(); + [Test] + public void should_be_able_to_check_space_on_ramdrive() + { + LinuxOnly(); + Subject.GetAvailableSpace("/run/").Should().NotBe(0); } } } diff --git a/NzbDrone.Common.Test/DiskProviderTests/IsParentFixture.cs b/NzbDrone.Common.Test/DiskProviderTests/IsParentFixture.cs index b29f60180..f3ede03eb 100644 --- a/NzbDrone.Common.Test/DiskProviderTests/IsParentFixture.cs +++ b/NzbDrone.Common.Test/DiskProviderTests/IsParentFixture.cs @@ -1,43 +1,36 @@ -using System.IO; -using FluentAssertions; +using FluentAssertions; using NUnit.Framework; using NzbDrone.Test.Common; namespace NzbDrone.Common.Test.DiskProviderTests { [TestFixture] - public class FreeSpaceFixture : TestBase + public class IsParentFixture : TestBase { - [Test] - public void should_get_free_space_for_folder() - { - var path = @"C:\".AsOsAgnostic(); - - Subject.GetAvailableSpace(path).Should().NotBe(0); - } + private string _parent = @"C:\Test".AsOsAgnostic(); [Test] - public void should_get_free_space_for_folder_that_doesnt_exist() + public void should_return_false_when_not_a_child() { - var path = @"C:\".AsOsAgnostic(); + var path = @"C:\Another Folder".AsOsAgnostic(); - Subject.GetAvailableSpace(Path.Combine(path, "invalidFolder")).Should().NotBe(0); + Subject.IsParent(_parent, path).Should().BeFalse(); } - [Test] - public void should_get_free_space_for_drive_that_doesnt_exist() + public void should_return_true_when_folder_is_parent_of_another_folder() { - WindowsOnly(); + var path = @"C:\Test\TV".AsOsAgnostic(); - Assert.Throws(() => Subject.GetAvailableSpace("J:\\").Should().NotBe(0)); + Subject.IsParent(_parent, path).Should().BeTrue(); } [Test] - public void should_be_able_to_check_space_on_ramdrive() + public void should_return_true_when_folder_is_parent_of_a_file() { - LinuxOnly(); - Subject.GetAvailableSpace("/run/").Should().NotBe(0); + var path = @"C:\Test\30.Rock.S01E01.Pilot.avi".AsOsAgnostic(); + + Subject.IsParent(_parent, path).Should().BeTrue(); } } } diff --git a/NzbDrone.Common.Test/ProcessProviderTests.cs b/NzbDrone.Common.Test/ProcessProviderTests.cs index 4155ab4d0..099defbe9 100644 --- a/NzbDrone.Common.Test/ProcessProviderTests.cs +++ b/NzbDrone.Common.Test/ProcessProviderTests.cs @@ -6,6 +6,7 @@ using System.Linq; using FluentAssertions; using NUnit.Framework; using NzbDrone.Common.Model; +using NzbDrone.Common.Processes; using NzbDrone.Test.Common; using NzbDrone.Test.Dummy; diff --git a/NzbDrone.Common.Test/ServiceFactoryFixture.cs b/NzbDrone.Common.Test/ServiceFactoryFixture.cs index 7777476ff..78dcbe442 100644 --- a/NzbDrone.Common.Test/ServiceFactoryFixture.cs +++ b/NzbDrone.Common.Test/ServiceFactoryFixture.cs @@ -3,7 +3,6 @@ using FluentAssertions; using NUnit.Framework; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Core.Lifecycle; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; using NzbDrone.Host; using NzbDrone.Test.Common; diff --git a/NzbDrone.Common/Contract/ParseErrorReport.cs b/NzbDrone.Common/Contract/ParseErrorReport.cs deleted file mode 100644 index fe78111e6..000000000 --- a/NzbDrone.Common/Contract/ParseErrorReport.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace NzbDrone.Common.Contract -{ - public class ParseErrorReport : ReportBase - { - [JsonProperty("t")] - public string Title { get; set; } - - protected override Dictionary GetString() - { - var dic = new Dictionary - { - {"Title", Title.NullSafe()}, - }; - - return dic; - } - } -} diff --git a/NzbDrone.Common/Contract/ReportBase.cs b/NzbDrone.Common/Contract/ReportBase.cs deleted file mode 100644 index 559a3a847..000000000 --- a/NzbDrone.Common/Contract/ReportBase.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace NzbDrone.Common.Contract -{ - public abstract class ReportBase - { - [JsonProperty("v")] - public string Version { get; set; } - - [JsonProperty("p")] - public bool IsProduction { get; set; } - - [JsonProperty("u")] - public Guid UGuid { get; set; } - - public override string ToString() - { - var childString = ""; - foreach (var keyValue in GetString()) - { - childString += string.Format("{0}: {1} ", keyValue.Key, keyValue.Value); - } - - return string.Format("[{0} Prd:{1} V:{2} ID:{3} | {4}]", GetType().Name, IsProduction, Version, UGuid, childString.Trim()); - } - - protected abstract Dictionary GetString(); - } -} diff --git a/NzbDrone.Common/EnsureThat/EnsureStringExtensions.cs b/NzbDrone.Common/EnsureThat/EnsureStringExtensions.cs index b3b840491..411a31f41 100644 --- a/NzbDrone.Common/EnsureThat/EnsureStringExtensions.cs +++ b/NzbDrone.Common/EnsureThat/EnsureStringExtensions.cs @@ -1,4 +1,7 @@ +using System.Collections; +using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Text.RegularExpressions; using NzbDrone.Common.EnsureThat.Resources; using NzbDrone.Common.EnvironmentInfo; @@ -73,7 +76,6 @@ namespace NzbDrone.Common.EnsureThat return param; } - [DebuggerStepThrough] public static Param IsRelativePath(this Param param) { @@ -94,8 +96,6 @@ namespace NzbDrone.Common.EnsureThat return param; } - - [DebuggerStepThrough] public static Param IsValidPath(this Param param) { diff --git a/NzbDrone.Common/IEnumerableExtensions.cs b/NzbDrone.Common/IEnumerableExtensions.cs index cefa4c26b..11626292a 100644 --- a/NzbDrone.Common/IEnumerableExtensions.cs +++ b/NzbDrone.Common/IEnumerableExtensions.cs @@ -4,7 +4,7 @@ using System.Linq; namespace NzbDrone.Common { - public static class IEnumerableExtensions + public static class EnumerableExtensions { public static IEnumerable DistinctBy(this IEnumerable source, Func keySelector) { diff --git a/NzbDrone.Common/NzbDrone.Common.csproj b/NzbDrone.Common/NzbDrone.Common.csproj index d55670a61..0d76e91a2 100644 --- a/NzbDrone.Common/NzbDrone.Common.csproj +++ b/NzbDrone.Common/NzbDrone.Common.csproj @@ -98,6 +98,8 @@ + + @@ -117,16 +119,13 @@ - - - + - diff --git a/NzbDrone.Common/Processes/ProcessOutput.cs b/NzbDrone.Common/Processes/ProcessOutput.cs new file mode 100644 index 000000000..231b6097e --- /dev/null +++ b/NzbDrone.Common/Processes/ProcessOutput.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; + +namespace NzbDrone.Common.Processes +{ + public class ProcessOutput + { + public List Standard { get; set; } + public List Error { get; set; } + + public ProcessOutput() + { + Standard = new List(); + Error = new List(); + } + } +} diff --git a/NzbDrone.Common/ProcessProvider.cs b/NzbDrone.Common/Processes/ProcessProvider.cs similarity index 94% rename from NzbDrone.Common/ProcessProvider.cs rename to NzbDrone.Common/Processes/ProcessProvider.cs index e93edd781..75bde50f8 100644 --- a/NzbDrone.Common/ProcessProvider.cs +++ b/NzbDrone.Common/Processes/ProcessProvider.cs @@ -9,7 +9,7 @@ using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.Instrumentation; using NzbDrone.Common.Model; -namespace NzbDrone.Common +namespace NzbDrone.Common.Processes { public interface IProcessProvider { @@ -23,6 +23,7 @@ namespace NzbDrone.Common ProcessPriorityClass GetCurrentProcessPriority(); Process Start(string path, string args = null, Action onOutputDataReceived = null, Action onErrorDataReceived = null); Process SpawnNewProcess(string path, string args = null); + ProcessOutput StartAndCapture(string path, string args = null); } public class ProcessProvider : IProcessProvider @@ -88,11 +89,8 @@ namespace NzbDrone.Common process.Start(); } - - public Process Start(string path, string args = null, Action onOutputDataReceived = null, Action onErrorDataReceived = null) { - if (OsInfo.IsMono && path.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase)) { args = path + " " + args; @@ -147,7 +145,6 @@ namespace NzbDrone.Common process.BeginErrorReadLine(); process.BeginOutputReadLine(); - return process; } @@ -172,6 +169,16 @@ namespace NzbDrone.Common return process; } + public ProcessOutput StartAndCapture(string path, string args = null) + { + var output = new ProcessOutput(); + var process = Start(path, args, s => output.Standard.Add(s), error => output.Error.Add(error)); + + WaitForExit(process); + + return output; + } + public void WaitForExit(Process process) { Logger.Trace("Waiting for process {0} to exit.", process.ProcessName); @@ -225,7 +232,6 @@ namespace NzbDrone.Common return null; } - private static string GetExeFileName(Process process) { if (process.MainModule.FileName != "mono.exe") diff --git a/NzbDrone.Common/RestProvider.cs b/NzbDrone.Common/RestProvider.cs deleted file mode 100644 index 9b1823257..000000000 --- a/NzbDrone.Common/RestProvider.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.IO; -using System.Net; -using System.Text; -using Newtonsoft.Json; -using NzbDrone.Common.Contract; -using NzbDrone.Common.EnvironmentInfo; - -namespace NzbDrone.Common -{ - - public class RestProvider - { - private const int TIMEOUT = 15000; - private const string METHOD = "POST"; - - public virtual void PostData(string url, ReportBase reportBase) - { - reportBase.Version = BuildInfo.Version.ToString(); - reportBase.IsProduction = RuntimeInfo.IsProduction; - - PostData(url, reportBase as object); - } - - - private static void PostData(string url, object message) - { - try - { - var json = JsonConvert.SerializeObject(message); - - var request = (HttpWebRequest)WebRequest.Create(url); - request.Timeout = TIMEOUT; - - request.Proxy = WebRequest.DefaultWebProxy; - - request.KeepAlive = false; - request.ProtocolVersion = HttpVersion.Version10; - request.Method = METHOD; - request.ContentType = "application/json"; - - byte[] postBytes = Encoding.UTF8.GetBytes(json); - request.ContentLength = postBytes.Length; - - var requestStream = request.GetRequestStream(); - requestStream.Write(postBytes, 0, postBytes.Length); - requestStream.Close(); - - var response = (HttpWebResponse)request.GetResponse(); - var streamreader = new StreamReader(response.GetResponseStream()); - streamreader.Close(); - } - catch (Exception e) - { - e.Data.Add("URL", url); - throw; - } - } - } -} diff --git a/NzbDrone.Common/Serializer/IntConverter.cs b/NzbDrone.Common/Serializer/IntConverter.cs new file mode 100644 index 000000000..d30db4c74 --- /dev/null +++ b/NzbDrone.Common/Serializer/IntConverter.cs @@ -0,0 +1,39 @@ +using System; +using Newtonsoft.Json; + +namespace NzbDrone.Common.Serializer +{ + public class IntConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + if (value == null) + { + writer.WriteNull(); + } + else + { + writer.WriteValue(value); + } + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (!CanConvert(objectType)) + { + throw new JsonSerializationException("Can't convert type " + existingValue.GetType().FullName + " to number"); + } + if (objectType == typeof(Int64)) + { + return Convert.ToInt64(reader.Value); + } + + return Convert.ToInt32(reader.Value); + } + + public override bool CanConvert(Type objectType) + { + return objectType == typeof(Int32) || objectType == typeof(Int64) || objectType == typeof(int); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Common/Serializer/Json.cs b/NzbDrone.Common/Serializer/Json.cs index 866776ec9..bf54fb250 100644 --- a/NzbDrone.Common/Serializer/Json.cs +++ b/NzbDrone.Common/Serializer/Json.cs @@ -8,42 +8,48 @@ namespace NzbDrone.Common.Serializer { public static class Json { - private static readonly JsonSerializer JsonNetSerializer; - + private static readonly JsonSerializer Serializer; + private static readonly JsonSerializerSettings SerializerSetting; static Json() { - JsonNetSerializer = new JsonSerializer() - { - DateTimeZoneHandling = DateTimeZoneHandling.Utc, - NullValueHandling = NullValueHandling.Ignore, - Formatting = Formatting.Indented, - DefaultValueHandling = DefaultValueHandling.Include, - ContractResolver = new CamelCasePropertyNamesContractResolver() - }; - - JsonNetSerializer.Converters.Add(new StringEnumConverter { CamelCaseText = true }); + SerializerSetting = new JsonSerializerSettings + { + DateTimeZoneHandling = DateTimeZoneHandling.Utc, + NullValueHandling = NullValueHandling.Ignore, + Formatting = Formatting.Indented, + DefaultValueHandling = DefaultValueHandling.Include, + ContractResolver = new CamelCasePropertyNamesContractResolver() + }; + + + SerializerSetting.Converters.Add(new StringEnumConverter { CamelCaseText = true }); + //SerializerSetting.Converters.Add(new IntConverter()); + SerializerSetting.Converters.Add(new VersionConverter()); + + Serializer = JsonSerializer.Create(SerializerSetting); + } - public static T Deserialize(string json) where T : class, new() + public static T Deserialize(string json) where T : new() { - return JsonConvert.DeserializeObject(json); + return JsonConvert.DeserializeObject(json, SerializerSetting); } public static object Deserialize(string json, Type type) { - return JsonConvert.DeserializeObject(json, type); + return JsonConvert.DeserializeObject(json, type, SerializerSetting); } public static string ToJson(this object obj) { - return JsonConvert.SerializeObject(obj); + return JsonConvert.SerializeObject(obj, SerializerSetting); } public static void Serialize(TModel model, TextWriter outputStream) { var jsonTextWriter = new JsonTextWriter(outputStream); - JsonNetSerializer.Serialize(jsonTextWriter, model); + Serializer.Serialize(jsonTextWriter, model); jsonTextWriter.Flush(); } diff --git a/NzbDrone.Core.Test/DataAugmentationFixture/Scene/SceneMappingProxyFixture.cs b/NzbDrone.Core.Test/DataAugmentationFixture/Scene/SceneMappingProxyFixture.cs index 587e70697..cef5a5d0b 100644 --- a/NzbDrone.Core.Test/DataAugmentationFixture/Scene/SceneMappingProxyFixture.cs +++ b/NzbDrone.Core.Test/DataAugmentationFixture/Scene/SceneMappingProxyFixture.cs @@ -1,7 +1,7 @@ using System.Net; using FluentAssertions; -using NUnit.Framework; using Newtonsoft.Json; +using NUnit.Framework; using NzbDrone.Common; using NzbDrone.Core.DataAugmentation.Scene; using NzbDrone.Core.Test.Framework; diff --git a/NzbDrone.Core.Test/Download/DownloadClientTests/NzbgetProviderTests/DownloadNzbFixture.cs b/NzbDrone.Core.Test/Download/DownloadClientTests/NzbgetProviderTests/DownloadNzbFixture.cs index c897df251..2e042dca1 100644 --- a/NzbDrone.Core.Test/Download/DownloadClientTests/NzbgetProviderTests/DownloadNzbFixture.cs +++ b/NzbDrone.Core.Test/Download/DownloadClientTests/NzbgetProviderTests/DownloadNzbFixture.cs @@ -4,6 +4,7 @@ using FizzWare.NBuilder; using Moq; using NUnit.Framework; using NzbDrone.Common; +using NzbDrone.Common.Serializer; using NzbDrone.Core.Configuration; using NzbDrone.Core.Download.Clients.Nzbget; using NzbDrone.Core.Parser.Model; @@ -51,9 +52,16 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetProviderTests [Test] public void should_add_item_to_queue() { + + var command = new JsonRequest + { + Method = "appendurl", + Params = new object[] { "30.Rock.S01E01.Pilot.720p.hdtv.nzb", "TV", 50, false, "http://www.nzbdrone.com" } + }; + Mocker.GetMock() .Setup(s => s.PostCommand("192.168.5.55:6789", "nzbget", "pass", - It.Is(c => c.Equals("{\"method\":\"appendurl\",\"params\":[\"30.Rock.S01E01.Pilot.720p.hdtv.nzb\",\"TV\",50,false,\"http://www.nzbdrone.com\"]}")))) + It.Is(c => c.Equals(command.ToJson())))) .Returns("{\"version\": \"1.1\",\"result\": true}"); Mocker.Resolve().DownloadNzb(_remoteEpisode); diff --git a/NzbDrone.Core.Test/Framework/DbTest.cs b/NzbDrone.Core.Test/Framework/DbTest.cs index f8d3a0979..4fdd67869 100644 --- a/NzbDrone.Core.Test/Framework/DbTest.cs +++ b/NzbDrone.Core.Test/Framework/DbTest.cs @@ -8,7 +8,6 @@ using Moq; using NUnit.Framework; using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore.Migration.Framework; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; @@ -61,8 +60,6 @@ namespace NzbDrone.Core.Test.Framework } } - - [Category("DbTest")] public abstract class DbTest : CoreTest { diff --git a/NzbDrone.Core.Test/HelperTests/SortHelperTest.cs b/NzbDrone.Core.Test/HelperTests/SortHelperTest.cs deleted file mode 100644 index c1f31c0cd..000000000 --- a/NzbDrone.Core.Test/HelperTests/SortHelperTest.cs +++ /dev/null @@ -1,26 +0,0 @@ -using FluentAssertions; -using NUnit.Framework; -using NzbDrone.Core.Helpers; -using NzbDrone.Core.Test.Framework; - -namespace NzbDrone.Core.Test.HelperTests -{ - [TestFixture] - public class SortHelperTest : CoreTest - { - [TestCase("The Office (US)", "Office (US)")] - [TestCase("A Man in Anger", "Man in Anger")] - [TestCase("An Idiot Abroad", "Idiot Abroad")] - [TestCase("American Gladiators", "American Gladiators")] - [TestCase("Ancient Apocalyps", "Ancient Apocalyps")] - [TestCase("There Will Be Brawl", "There Will Be Brawl")] - [TestCase("30 Rock", "30 Rock")] - [TestCase(null, "")] - public void SkipArticles(string title, string expected) - { - var result = title.IgnoreArticles(); - result.Should().Be(expected); - } - } - -} \ No newline at end of file diff --git a/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs b/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs index 4ccc2364b..9b8a90643 100644 --- a/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs +++ b/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs @@ -4,6 +4,7 @@ using FluentAssertions; using NUnit.Framework; using NzbDrone.Core.History; using NzbDrone.Core.Test.Framework; +using NzbDrone.Core.Tv; namespace NzbDrone.Core.Test.HistoryTests { diff --git a/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedEpisodesFixture.cs b/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedEpisodesFixture.cs new file mode 100644 index 000000000..03f8b395e --- /dev/null +++ b/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedEpisodesFixture.cs @@ -0,0 +1,43 @@ +using FizzWare.NBuilder; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Housekeeping.Housekeepers; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Core.Tv; + +namespace NzbDrone.Core.Test.Housekeeping.Housekeepers +{ + [TestFixture] + public class CleanupOrphanedEpisodesFixture : DbTest + { + [Test] + public void should_delete_orphaned_episodes() + { + var episode = Builder.CreateNew() + .BuildNew(); + + Db.Insert(episode); + Subject.Clean(); + AllStoredModels.Should().BeEmpty(); + } + + [Test] + public void should_not_delete_unorphaned_episodes() + { + var series = Builder.CreateNew() + .BuildNew(); + + Db.Insert(series); + + var episodes = Builder.CreateListOfSize(2) + .TheFirst(1) + .With(e => e.SeriesId = series.Id) + .BuildListOfNew(); + + Db.InsertMany(episodes); + Subject.Clean(); + AllStoredModels.Should().HaveCount(1); + AllStoredModels.Should().Contain(e => e.SeriesId == series.Id); + } + } +} diff --git a/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedHistoryItemsFixture.cs b/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedHistoryItemsFixture.cs new file mode 100644 index 000000000..df24add3e --- /dev/null +++ b/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedHistoryItemsFixture.cs @@ -0,0 +1,105 @@ +using System; +using FizzWare.NBuilder; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Housekeeping.Housekeepers; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Core.Tv; + +namespace NzbDrone.Core.Test.Housekeeping.Housekeepers +{ + [TestFixture] + public class CleanupOrphanedHistoryItemsFixture : DbTest + { + private Series _series; + private Episode _episode; + + [SetUp] + public void Setup() + { + _series = Builder.CreateNew() + .BuildNew(); + + _episode = Builder.CreateNew() + .BuildNew(); + } + + private void GivenSeries() + { + Db.Insert(_series); + } + + private void GivenEpisode() + { + Db.Insert(_episode); + } + + [Test] + public void should_delete_orphaned_items_by_series() + { + GivenEpisode(); + + var history = Builder.CreateNew() + .With(h => h.EpisodeId = _episode.Id) + .BuildNew(); + Db.Insert(history); + + Subject.Clean(); + AllStoredModels.Should().BeEmpty(); + } + + [Test] + public void should_delete_orphaned_items_by_episode() + { + GivenSeries(); + + var history = Builder.CreateNew() + .With(h => h.SeriesId = _series.Id) + .BuildNew(); + Db.Insert(history); + + Subject.Clean(); + AllStoredModels.Should().BeEmpty(); + } + + [Test] + public void should_not_delete_unorphaned_data_by_series() + { + GivenSeries(); + GivenEpisode(); + + var history = Builder.CreateListOfSize(2) + .All() + .With(h => h.EpisodeId = _episode.Id) + .TheFirst(1) + .With(h => h.SeriesId = _series.Id) + .BuildListOfNew(); + + Db.InsertMany(history); + + Subject.Clean(); + AllStoredModels.Should().HaveCount(1); + AllStoredModels.Should().Contain(h => h.SeriesId == _series.Id); + } + + [Test] + public void should_not_delete_unorphaned_data_by_episode() + { + GivenSeries(); + GivenEpisode(); + + var history = Builder.CreateListOfSize(2) + .All() + .With(h => h.SeriesId = _series.Id) + .TheFirst(1) + .With(h => h.EpisodeId = _episode.Id) + .BuildListOfNew(); + + Db.InsertMany(history); + + Subject.Clean(); + AllStoredModels.Should().HaveCount(1); + AllStoredModels.Should().Contain(h => h.EpisodeId == _episode.Id); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core.Test/MediaFiles/EpisodeImport/Specifications/NotSampleSpecificationFixture.cs b/NzbDrone.Core.Test/MediaFiles/EpisodeImport/Specifications/NotSampleSpecificationFixture.cs index c3f5b0429..3699ffeb6 100644 --- a/NzbDrone.Core.Test/MediaFiles/EpisodeImport/Specifications/NotSampleSpecificationFixture.cs +++ b/NzbDrone.Core.Test/MediaFiles/EpisodeImport/Specifications/NotSampleSpecificationFixture.cs @@ -7,7 +7,6 @@ using NUnit.Framework; using NzbDrone.Core.MediaFiles.EpisodeImport.Specifications; using NzbDrone.Core.MediaFiles.MediaInfo; using NzbDrone.Core.Parser.Model; -using NzbDrone.Core.Providers; using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Tv; using NzbDrone.Test.Common; diff --git a/NzbDrone.Core.Test/MediaFiles/ImportApprovedEpisodesFixture.cs b/NzbDrone.Core.Test/MediaFiles/ImportApprovedEpisodesFixture.cs index b1cab5f58..fd8fa0345 100644 --- a/NzbDrone.Core.Test/MediaFiles/ImportApprovedEpisodesFixture.cs +++ b/NzbDrone.Core.Test/MediaFiles/ImportApprovedEpisodesFixture.cs @@ -7,7 +7,6 @@ using NUnit.Framework; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles.EpisodeImport; using NzbDrone.Core.MediaFiles.Events; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Qualities; diff --git a/NzbDrone.Core.Test/MediaFiles/MediaFileRepositoryFixture.cs b/NzbDrone.Core.Test/MediaFiles/MediaFileRepositoryFixture.cs index 2b54fff52..e0db21265 100644 --- a/NzbDrone.Core.Test/MediaFiles/MediaFileRepositoryFixture.cs +++ b/NzbDrone.Core.Test/MediaFiles/MediaFileRepositoryFixture.cs @@ -1,12 +1,10 @@ using FizzWare.NBuilder; using FluentAssertions; using NUnit.Framework; -using NzbDrone.Common; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Qualities; using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Tv; -using NzbDrone.Test.Common; namespace NzbDrone.Core.Test.MediaFiles { @@ -33,37 +31,5 @@ namespace NzbDrone.Core.Test.MediaFiles seriesFiles.Should().OnlyContain(c => c.SeriesId == 12); } - - - [Test] - public void GetFileByPath_should_return_null_if_file_does_not_exist_in_database() - { - Subject.GetFileByPath(@"C:\Test\EpisodeFile.avi").Should().BeNull(); - } - - [Test] - public void exists_should_return_false_if_file_doesnt_exist() - { - Subject.Exists(@"C:\Test\EpisodeFile.avi").Should().BeFalse(); - } - - [Test] - public void GetFileByPath_should_return_EpisodeFile_if_file_exists_in_database() - { - var path = @"C:\Test\EpisodeFile.avi".AsOsAgnostic(); - - var episodeFile = Builder.CreateNew() - .With(f => f.Id = 0) - .With(f => f.Path = path.CleanFilePath()) - .Build(); - - Subject.Insert(episodeFile); - - var file = Subject.GetFileByPath(path); - - //Resolve - file.Should().NotBeNull(); - file.Path.Should().Be(path.CleanFilePath()); - } } } \ No newline at end of file diff --git a/NzbDrone.Core.Test/MediaFiles/RenameEpisodeFileServiceFixture.cs b/NzbDrone.Core.Test/MediaFiles/RenameEpisodeFileServiceFixture.cs index 070b4eb03..662727575 100644 --- a/NzbDrone.Core.Test/MediaFiles/RenameEpisodeFileServiceFixture.cs +++ b/NzbDrone.Core.Test/MediaFiles/RenameEpisodeFileServiceFixture.cs @@ -8,7 +8,6 @@ using NzbDrone.Core.MediaFiles.Commands; using NzbDrone.Core.MediaFiles.Events; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Test.Framework; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Tv; namespace NzbDrone.Core.Test.MediaFiles diff --git a/NzbDrone.Core.Test/Messaging/Events/EventAggregatorFixture.cs b/NzbDrone.Core.Test/Messaging/Events/EventAggregatorFixture.cs index e5bdd313a..2251915e8 100644 --- a/NzbDrone.Core.Test/Messaging/Events/EventAggregatorFixture.cs +++ b/NzbDrone.Core.Test/Messaging/Events/EventAggregatorFixture.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Threading; -using FluentAssertions; using Moq; using NUnit.Framework; using NzbDrone.Common; diff --git a/NzbDrone.Core.Test/NotificationTests/Xbmc/GetJsonVersionFixture.cs b/NzbDrone.Core.Test/NotificationTests/Xbmc/GetJsonVersionFixture.cs index 19f7db315..7ade31623 100644 --- a/NzbDrone.Core.Test/NotificationTests/Xbmc/GetJsonVersionFixture.cs +++ b/NzbDrone.Core.Test/NotificationTests/Xbmc/GetJsonVersionFixture.cs @@ -3,7 +3,7 @@ using Moq; using NUnit.Framework; using NzbDrone.Common; using NzbDrone.Core.Notifications.Xbmc; -using NzbDrone.Core.Model.Xbmc; +using NzbDrone.Core.Notifications.Xbmc.Model; using NzbDrone.Core.Test.Framework; namespace NzbDrone.Core.Test.NotificationTests.Xbmc diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index c855d7ad9..22ee553f8 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -125,6 +125,7 @@ + @@ -165,6 +166,7 @@ + @@ -178,6 +180,7 @@ + @@ -197,9 +200,6 @@ - - - diff --git a/NzbDrone.Core.Test/ParserTests/ParserFixture.cs b/NzbDrone.Core.Test/ParserTests/ParserFixture.cs index ace78f50e..d74c5aedf 100644 --- a/NzbDrone.Core.Test/ParserTests/ParserFixture.cs +++ b/NzbDrone.Core.Test/ParserTests/ParserFixture.cs @@ -3,7 +3,6 @@ using System.Linq; using FluentAssertions; using Moq; using NUnit.Framework; -using NzbDrone.Common.Contract; using NzbDrone.Common.Expansive; using NzbDrone.Core.Parser; using NzbDrone.Core.Test.Framework; @@ -116,17 +115,6 @@ namespace NzbDrone.Core.Test.ParserTests ExceptionVerification.IgnoreWarns(); } - [Test] - [Ignore] - public void unparsable_path_should_report_the_path() - { - Parser.Parser.ParsePath("C:\\SOMETHING 12345.avi").Should().BeNull(); - - MockedRestProvider.Verify(c => c.PostData(It.IsAny(), It.IsAny()), Times.Exactly(2)); - - ExceptionVerification.IgnoreWarns(); - } - [TestCase("[DmonHiro] The Severing Crime Edge - Cut 02 - Portrait Of Heresy [BD, 720p] [BE36E9E0]")] public void unparsable_title_should_log_warn_and_return_null(string title) { diff --git a/NzbDrone.Core.Test/ParserTests/ParsingServiceTests/GetEpisodesFixture.cs b/NzbDrone.Core.Test/ParserTests/ParsingServiceTests/GetEpisodesFixture.cs index b0692b6fb..35dc82373 100644 --- a/NzbDrone.Core.Test/ParserTests/ParsingServiceTests/GetEpisodesFixture.cs +++ b/NzbDrone.Core.Test/ParserTests/ParsingServiceTests/GetEpisodesFixture.cs @@ -1,11 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using FizzWare.NBuilder; using Moq; using NUnit.Framework; -using NzbDrone.Core.DataAugmentation.Scene; using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.Parser; using NzbDrone.Core.Parser.Model; diff --git a/NzbDrone.Core.Test/ParserTests/ParsingServiceTests/MapFixture.cs b/NzbDrone.Core.Test/ParserTests/ParsingServiceTests/MapFixture.cs index efa6c5b3d..70860de84 100644 --- a/NzbDrone.Core.Test/ParserTests/ParsingServiceTests/MapFixture.cs +++ b/NzbDrone.Core.Test/ParserTests/ParsingServiceTests/MapFixture.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using FizzWare.NBuilder; using Moq; using NUnit.Framework; diff --git a/NzbDrone.Core.Test/ProviderTests/XemCommunicationProviderTests/GetSceneTvdbMappingsFixture.cs b/NzbDrone.Core.Test/ProviderTests/XemCommunicationProviderTests/GetSceneTvdbMappingsFixture.cs deleted file mode 100644 index c8066ace5..000000000 --- a/NzbDrone.Core.Test/ProviderTests/XemCommunicationProviderTests/GetSceneTvdbMappingsFixture.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Linq; -using FluentAssertions; -using Moq; -using NUnit.Framework; -using NzbDrone.Common; -using NzbDrone.Core.Providers; - -using NzbDrone.Core.Test.Framework; - -namespace NzbDrone.Core.Test.ProviderTests.XemCommunicationProviderTests -{ - [TestFixture] - - public class GetSceneTvdbMappingsFixture : CoreTest - { - private void WithFailureJson() - { - Mocker.GetMock().Setup(s => s.DownloadString(It.IsAny())) - .Returns(ReadAllText("Files","Xem","Failure.txt")); - } - - private void WithIdsJson() - { - Mocker.GetMock().Setup(s => s.DownloadString(It.IsAny())) - .Returns(ReadAllText("Files","Xem","Ids.txt")); - } - - private void WithMappingsJson() - { - Mocker.GetMock().Setup(s => s.DownloadString(It.IsAny())) - .Returns(ReadAllText("Files","Xem","Mappings.txt")); - } - - [Test] - public void should_throw_when_failure_is_found() - { - WithFailureJson(); - Assert.Throws(() => Mocker.Resolve().GetSceneTvdbMappings(12345)); - } - - [Test] - public void should_get_list_of_mappings() - { - WithMappingsJson(); - Mocker.Resolve().GetSceneTvdbMappings(12345).Should().NotBeEmpty(); - } - - [Test] - public void should_have_two_mappings() - { - WithMappingsJson(); - Mocker.Resolve().GetSceneTvdbMappings(12345).Should().HaveCount(2); - } - - [Test] - public void should_have_expected_results() - { - WithMappingsJson(); - var results = Mocker.Resolve().GetSceneTvdbMappings(12345); - var first = results.First(); - first.Scene.Absolute.Should().Be(1); - first.Scene.Season.Should().Be(1); - first.Scene.Episode.Should().Be(1); - first.Tvdb.Absolute.Should().Be(1); - first.Tvdb.Season.Should().Be(1); - first.Tvdb.Episode.Should().Be(1); - } - } -} \ No newline at end of file diff --git a/NzbDrone.Core.Test/ProviderTests/XemCommunicationProviderTests/GetXemSeriesIdsFixture.cs b/NzbDrone.Core.Test/ProviderTests/XemCommunicationProviderTests/GetXemSeriesIdsFixture.cs deleted file mode 100644 index 82035d5c8..000000000 --- a/NzbDrone.Core.Test/ProviderTests/XemCommunicationProviderTests/GetXemSeriesIdsFixture.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using FluentAssertions; -using Moq; -using NUnit.Framework; -using NzbDrone.Common; -using NzbDrone.Core.Providers; - -using NzbDrone.Core.Test.Framework; - -namespace NzbDrone.Core.Test.ProviderTests.XemCommunicationProviderTests -{ - [TestFixture] - - public class GetXemSeriesIdsFixture : CoreTest - { - private void WithFailureJson() - { - Mocker.GetMock().Setup(s => s.DownloadString(It.IsAny())) - .Returns(ReadAllText("Files", "Xem", "Failure.txt")); - } - - private void WithIdsJson() - { - Mocker.GetMock().Setup(s => s.DownloadString(It.IsAny())) - .Returns(ReadAllText("Files", "Xem", "Ids.txt")); - } - - private void WithMappingsJson() - { - Mocker.GetMock().Setup(s => s.DownloadString(It.IsAny())) - .Returns(ReadAllText("Files", "Xem", "Mappings.txt")); - } - - [Test] - public void should_throw_when_failure_is_found() - { - WithFailureJson(); - Assert.Throws(() => Mocker.Resolve().GetXemSeriesIds()); - } - - [Test] - public void should_get_list_of_int() - { - WithIdsJson(); - Mocker.Resolve().GetXemSeriesIds().Should().NotBeEmpty(); - } - - [Test] - public void should_have_two_ids() - { - WithIdsJson(); - Mocker.Resolve().GetXemSeriesIds().Should().HaveCount(2); - } - } -} \ No newline at end of file diff --git a/NzbDrone.Core.Test/Providers/XemProxyFixture.cs b/NzbDrone.Core.Test/Providers/XemProxyFixture.cs new file mode 100644 index 000000000..e8501e401 --- /dev/null +++ b/NzbDrone.Core.Test/Providers/XemProxyFixture.cs @@ -0,0 +1,60 @@ +using System; +using System.Linq; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.DataAugmentation; +using NzbDrone.Core.DataAugmentation.Xem; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Test.Common.Categories; + +namespace NzbDrone.Core.Test.Providers +{ + [TestFixture] + [IntegrationTest] + public class XemProxyFixture : CoreTest + { + [SetUp] + public void Setup() + { + UseRealHttp(); + } + + [Test] + public void get_series_ids() + { + Subject.GetXemSeriesIds().Should().NotBeEmpty(); + } + + + [Test] + [Ignore("XEM's data is not clean")] + public void get_mapping_for_all_series() + { + var ids = Subject.GetXemSeriesIds(); + + var randomIds = ids.OrderBy(x => Guid.NewGuid()).Take(5); + + foreach (var randomId in randomIds) + { + Subject.GetSceneTvdbMappings(randomId).Should().NotBeEmpty(); + } + } + + [Test] + public void should_return_empty_when_series_is_not_found() + { + Subject.GetSceneTvdbMappings(12345).Should().BeEmpty(); + } + + + [Test] + public void should_get_mapping() + { + var result = Subject.GetSceneTvdbMappings(82807); + + result.Should().NotBeEmpty(); + result.Should().OnlyContain(c => c.Scene != null); + result.Should().OnlyContain(c => c.Tvdb != null); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core.Test/TvTests/SeriesServiceTests/UpdateSeriesFixture.cs b/NzbDrone.Core.Test/TvTests/SeriesServiceTests/UpdateSeriesFixture.cs index 903e98102..5d507967e 100644 Binary files a/NzbDrone.Core.Test/TvTests/SeriesServiceTests/UpdateSeriesFixture.cs and b/NzbDrone.Core.Test/TvTests/SeriesServiceTests/UpdateSeriesFixture.cs differ diff --git a/NzbDrone.Core.Test/UpdateTests/UpdateServiceFixture.cs b/NzbDrone.Core.Test/UpdateTests/UpdateServiceFixture.cs index 31ebee3e5..32b0c49ea 100644 --- a/NzbDrone.Core.Test/UpdateTests/UpdateServiceFixture.cs +++ b/NzbDrone.Core.Test/UpdateTests/UpdateServiceFixture.cs @@ -6,6 +6,7 @@ using NUnit.Framework; using NzbDrone.Common; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.Model; +using NzbDrone.Common.Processes; using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Update; using NzbDrone.Core.Update.Commands; diff --git a/NzbDrone.Core.Test/XbmcVersionTests.cs b/NzbDrone.Core.Test/XbmcVersionTests.cs index b4a118b0f..211bef487 100644 --- a/NzbDrone.Core.Test/XbmcVersionTests.cs +++ b/NzbDrone.Core.Test/XbmcVersionTests.cs @@ -1,6 +1,6 @@ using FluentAssertions; using NUnit.Framework; -using NzbDrone.Core.Model.Xbmc; +using NzbDrone.Core.Notifications.Xbmc.Model; namespace NzbDrone.Core.Test { diff --git a/NzbDrone.Core/Configuration/ConfigFileProvider.cs b/NzbDrone.Core/Configuration/ConfigFileProvider.cs index 8389ec658..4a1e93518 100644 --- a/NzbDrone.Core/Configuration/ConfigFileProvider.cs +++ b/NzbDrone.Core/Configuration/ConfigFileProvider.cs @@ -9,7 +9,6 @@ using NzbDrone.Common.Cache; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Core.Configuration.Events; using NzbDrone.Core.Lifecycle; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; @@ -21,6 +20,8 @@ namespace NzbDrone.Core.Configuration void SaveConfigDictionary(Dictionary configValues); int Port { get; } + int SslPort { get; } + bool EnableSsl { get; } bool LaunchBrowser { get; } bool AuthenticationEnabled { get; } string Username { get; } @@ -28,6 +29,7 @@ namespace NzbDrone.Core.Configuration string LogLevel { get; } string Branch { get; } bool Torrent { get; } + string SslCertHash { get; } } public class ConfigFileProvider : IConfigFileProvider @@ -91,6 +93,16 @@ namespace NzbDrone.Core.Configuration get { return GetValueInt("Port", 8989); } } + public int SslPort + { + get { return GetValueInt("SslPort", 9898); } + } + + public bool EnableSsl + { + get { return GetValueBoolean("EnableSsl", false); } + } + public bool LaunchBrowser { get { return GetValueBoolean("LaunchBrowser", true); } @@ -126,6 +138,11 @@ namespace NzbDrone.Core.Configuration get { return GetValue("LogLevel", "Info"); } } + public string SslCertHash + { + get { return GetValue("SslCertHash", ""); } + } + public int GetValueInt(string key, int defaultValue) { return Convert.ToInt32(GetValue(key, defaultValue)); diff --git a/NzbDrone.Core/Configuration/ConfigRepository.cs b/NzbDrone.Core/Configuration/ConfigRepository.cs index 0b8c3fffb..0c21b2793 100644 --- a/NzbDrone.Core/Configuration/ConfigRepository.cs +++ b/NzbDrone.Core/Configuration/ConfigRepository.cs @@ -1,6 +1,5 @@ using System.Linq; using NzbDrone.Core.Datastore; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; diff --git a/NzbDrone.Core/Configuration/ConfigService.cs b/NzbDrone.Core/Configuration/ConfigService.cs index 1e1af6182..8a9b7a5d5 100644 --- a/NzbDrone.Core/Configuration/ConfigService.cs +++ b/NzbDrone.Core/Configuration/ConfigService.cs @@ -6,7 +6,6 @@ using NzbDrone.Core.Configuration.Events; using NzbDrone.Core.Download; using NzbDrone.Core.Download.Clients.Nzbget; using NzbDrone.Core.Download.Clients.Sabnzbd; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; diff --git a/NzbDrone.Core/DataAugmentation/Scene/SceneMappingRepository.cs b/NzbDrone.Core/DataAugmentation/Scene/SceneMappingRepository.cs index 5f1ade5c2..b3075e88f 100644 --- a/NzbDrone.Core/DataAugmentation/Scene/SceneMappingRepository.cs +++ b/NzbDrone.Core/DataAugmentation/Scene/SceneMappingRepository.cs @@ -1,5 +1,4 @@ using NzbDrone.Core.Datastore; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; diff --git a/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs b/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs index d05dd69fd..91d18268b 100644 --- a/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs +++ b/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs @@ -3,7 +3,6 @@ using System.Linq; using NLog; using NzbDrone.Common.Cache; using NzbDrone.Core.Lifecycle; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Parser; diff --git a/NzbDrone.Core/Model/Xem/XemResult.cs b/NzbDrone.Core/DataAugmentation/Xem/Model/XemResult.cs similarity index 75% rename from NzbDrone.Core/Model/Xem/XemResult.cs rename to NzbDrone.Core/DataAugmentation/Xem/Model/XemResult.cs index 397700a11..2b041709d 100644 --- a/NzbDrone.Core/Model/Xem/XemResult.cs +++ b/NzbDrone.Core/DataAugmentation/Xem/Model/XemResult.cs @@ -1,4 +1,4 @@ -namespace NzbDrone.Core.Model.Xem +namespace NzbDrone.Core.DataAugmentation.Xem.Model { public class XemResult { diff --git a/NzbDrone.Core/Model/Xem/XemSceneTvdbMapping.cs b/NzbDrone.Core/DataAugmentation/Xem/Model/XemSceneTvdbMapping.cs similarity index 72% rename from NzbDrone.Core/Model/Xem/XemSceneTvdbMapping.cs rename to NzbDrone.Core/DataAugmentation/Xem/Model/XemSceneTvdbMapping.cs index 317efa3e4..1cc65524a 100644 --- a/NzbDrone.Core/Model/Xem/XemSceneTvdbMapping.cs +++ b/NzbDrone.Core/DataAugmentation/Xem/Model/XemSceneTvdbMapping.cs @@ -1,4 +1,4 @@ -namespace NzbDrone.Core.Model.Xem +namespace NzbDrone.Core.DataAugmentation.Xem.Model { public class XemSceneTvdbMapping { diff --git a/NzbDrone.Core/Model/Xem/XemValues.cs b/NzbDrone.Core/DataAugmentation/Xem/Model/XemValues.cs similarity index 75% rename from NzbDrone.Core/Model/Xem/XemValues.cs rename to NzbDrone.Core/DataAugmentation/Xem/Model/XemValues.cs index 6dc3d5e4a..ab6764e18 100644 --- a/NzbDrone.Core/Model/Xem/XemValues.cs +++ b/NzbDrone.Core/DataAugmentation/Xem/Model/XemValues.cs @@ -1,4 +1,4 @@ -namespace NzbDrone.Core.Model.Xem +namespace NzbDrone.Core.DataAugmentation.Xem.Model { public class XemValues { diff --git a/NzbDrone.Core/DataAugmentation/Xem/UpdateXemMappingsCommand.cs b/NzbDrone.Core/DataAugmentation/Xem/UpdateXemMappingsCommand.cs new file mode 100644 index 000000000..832e0ed58 --- /dev/null +++ b/NzbDrone.Core/DataAugmentation/Xem/UpdateXemMappingsCommand.cs @@ -0,0 +1,9 @@ +using NzbDrone.Core.Messaging.Commands; + +namespace NzbDrone.Core.DataAugmentation.Xem +{ + public class UpdateXemMappingsCommand : Command + { + + } +} \ No newline at end of file diff --git a/NzbDrone.Core/DataAugmentation/Xem/XemProxy.cs b/NzbDrone.Core/DataAugmentation/Xem/XemProxy.cs new file mode 100644 index 000000000..0747ab678 --- /dev/null +++ b/NzbDrone.Core/DataAugmentation/Xem/XemProxy.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NLog; +using NzbDrone.Core.DataAugmentation.Xem.Model; +using NzbDrone.Core.Rest; +using RestSharp; + +namespace NzbDrone.Core.DataAugmentation.Xem +{ + public interface IXemProxy + { + List GetXemSeriesIds(); + List GetSceneTvdbMappings(int id); + } + + public class XemProxy : IXemProxy + { + private readonly Logger _logger; + + private const string XEM_BASE_URL = "http://thexem.de/map/"; + + public XemProxy(Logger logger) + { + _logger = logger; + } + + + private static RestRequest BuildRequest(string resource) + { + var req = new RestRequest(resource, Method.GET); + req.AddParameter("origin", "tvdb"); + return req; + } + + public List GetXemSeriesIds() + { + _logger.Trace("Fetching Series IDs from"); + + var restClient = new RestClient(XEM_BASE_URL); + + var request = BuildRequest("havemap"); + + var response = restClient.ExecuteAndValidate>>(request); + CheckForFailureResult(response); + + return response.Data.ToList(); + } + + public List GetSceneTvdbMappings(int id) + { + _logger.Trace("Fetching Mappings for: {0}", id); + var url = String.Format("{0}all?id={1}&origin=tvdb", XEM_BASE_URL, id); + + + var restClient = new RestClient(XEM_BASE_URL); + + var request = BuildRequest("all"); + request.AddParameter("id", id); + + var response = restClient.ExecuteAndValidate>>(request); + CheckForFailureResult(response); + + return response.Data; + } + + private static void CheckForFailureResult(XemResult response) + { + if (response.Result.Equals("failure", StringComparison.InvariantCultureIgnoreCase) && + !response.Message.Contains("no show with the tvdb_id")) + { + throw new Exception("Error response received from Xem: " + response.Message); + } + } + } +} diff --git a/NzbDrone.Core/Providers/XemProvider.cs b/NzbDrone.Core/DataAugmentation/Xem/XemService.cs similarity index 68% rename from NzbDrone.Core/Providers/XemProvider.cs rename to NzbDrone.Core/DataAugmentation/Xem/XemService.cs index e66000afc..dd1e277cc 100644 --- a/NzbDrone.Core/Providers/XemProvider.cs +++ b/NzbDrone.Core/DataAugmentation/Xem/XemService.cs @@ -3,45 +3,52 @@ using System.Collections.Generic; using System.Linq; using NLog; using NzbDrone.Common.Cache; -using NzbDrone.Common.Instrumentation; using NzbDrone.Core.Lifecycle; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Tv; using NzbDrone.Core.Tv.Events; -namespace NzbDrone.Core.Providers +namespace NzbDrone.Core.DataAugmentation.Xem { - public interface IXemProvider - { - void UpdateMappings(); - void UpdateMappings(int seriesId); - void UpdateMappings(Series series); - void PerformUpdate(Series series); - } - - public class XemProvider : IXemProvider, IExecute, IHandle, IHandleAsync + public class XemService : IExecute, IHandle, IHandleAsync { private readonly IEpisodeService _episodeService; - private readonly IXemCommunicationProvider _xemCommunicationProvider; + private readonly IXemProxy _xemProxy; private readonly ISeriesService _seriesService; + private readonly Logger _logger; private readonly ICached _cache; - private static readonly Logger _logger = NzbDroneLogger.GetLogger(); - - public XemProvider(IEpisodeService episodeService, - IXemCommunicationProvider xemCommunicationProvider, - ISeriesService seriesService, ICacheManger cacheManger) + public XemService(IEpisodeService episodeService, + IXemProxy xemProxy, + ISeriesService seriesService, ICacheManger cacheManger, Logger logger) { if (seriesService == null) throw new ArgumentNullException("seriesService"); _episodeService = episodeService; - _xemCommunicationProvider = xemCommunicationProvider; + _xemProxy = xemProxy; _seriesService = seriesService; + _logger = logger; + _logger = logger; _cache = cacheManger.GetCache(GetType()); } - public void UpdateMappings() + + public void Execute(UpdateXemMappingsCommand message) + { + UpdateMappings(); + } + + public void Handle(SeriesUpdatedEvent message) + { + UpdateMappings(message.Series); + } + + public void HandleAsync(ApplicationStartedEvent message) + { + GetXemSeriesIds(); + } + + private void UpdateMappings() { _logger.Trace("Starting scene numbering update"); @@ -66,20 +73,7 @@ namespace NzbDrone.Core.Providers } } - public void UpdateMappings(int seriesId) - { - var series = _seriesService.GetSeries(seriesId); - - if (series == null) - { - _logger.Trace("Series could not be found: {0}", seriesId); - return; - } - - UpdateMappings(series); - } - - public void UpdateMappings(Series series) + private void UpdateMappings(Series series) { if (!_cache.Find(series.TvdbId.ToString())) { @@ -90,17 +84,18 @@ namespace NzbDrone.Core.Providers PerformUpdate(series); } - public void PerformUpdate(Series series) + private void PerformUpdate(Series series) { _logger.Trace("Updating scene numbering mapping for: {0}", series); try { var episodesToUpdate = new List(); - var mappings = _xemCommunicationProvider.GetSceneTvdbMappings(series.TvdbId); + var mappings = _xemProxy.GetSceneTvdbMappings(series.TvdbId); - if (mappings == null) + if (!mappings.Any()) { - _logger.Trace("Mappings for: {0} are null, skipping", series); + _logger.Trace("Mappings for: {0} are empty, skipping", series); + _cache.Remove(series.TvdbId.ToString()); return; } @@ -142,7 +137,7 @@ namespace NzbDrone.Core.Providers { _cache.Clear(); - var ids = _xemCommunicationProvider.GetXemSeriesIds(); + var ids = _xemProxy.GetXemSeriesIds(); foreach (var id in ids) { @@ -151,27 +146,5 @@ namespace NzbDrone.Core.Providers return ids; } - - public void Execute(UpdateXemMappingsCommand message) - { - if (message.SeriesId.HasValue) - { - UpdateMappings(message.SeriesId.Value); - } - else - { - UpdateMappings(); - } - } - - public void Handle(SeriesUpdatedEvent message) - { - UpdateMappings(message.Series); - } - - public void HandleAsync(ApplicationStartedEvent message) - { - GetXemSeriesIds(); - } } } diff --git a/NzbDrone.Core/Datastore/BasicRepository.cs b/NzbDrone.Core/Datastore/BasicRepository.cs index 8552930fd..96c03e51e 100644 --- a/NzbDrone.Core/Datastore/BasicRepository.cs +++ b/NzbDrone.Core/Datastore/BasicRepository.cs @@ -6,7 +6,6 @@ using Marr.Data; using Marr.Data.QGen; using NzbDrone.Core.Datastore.Events; using NzbDrone.Common; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; diff --git a/NzbDrone.Core/Datastore/DbFactory.cs b/NzbDrone.Core/Datastore/DbFactory.cs index 537fec3b0..9fcb6e673 100644 --- a/NzbDrone.Core/Datastore/DbFactory.cs +++ b/NzbDrone.Core/Datastore/DbFactory.cs @@ -5,7 +5,6 @@ using Marr.Data.Reflection; using NzbDrone.Common.Composition; using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.Instrumentation; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; diff --git a/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs b/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs index f2b1404cf..32e7087c6 100644 --- a/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs +++ b/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs @@ -70,6 +70,7 @@ namespace NzbDrone.Core.DecisionEngine if (remoteEpisode.Series != null) { + remoteEpisode.DownloadAllowed = true; decision = GetDecisionForReport(remoteEpisode, searchCriteria); } else diff --git a/NzbDrone.Core/Download/Clients/Nzbget/JsonRequest.cs b/NzbDrone.Core/Download/Clients/Nzbget/JsonRequest.cs index 29a22f763..a2e4b88c4 100644 --- a/NzbDrone.Core/Download/Clients/Nzbget/JsonRequest.cs +++ b/NzbDrone.Core/Download/Clients/Nzbget/JsonRequest.cs @@ -1,14 +1,10 @@ using System; -using Newtonsoft.Json; namespace NzbDrone.Core.Download.Clients.Nzbget { public class JsonRequest { - [JsonProperty(PropertyName = "method")] public String Method { get; set; } - - [JsonProperty(PropertyName = "params")] public object[] Params { get; set; } } } diff --git a/NzbDrone.Core/Download/Clients/Nzbget/NzbgetClient.cs b/NzbDrone.Core/Download/Clients/Nzbget/NzbgetClient.cs index 144805113..ee94a2198 100644 --- a/NzbDrone.Core/Download/Clients/Nzbget/NzbgetClient.cs +++ b/NzbDrone.Core/Download/Clients/Nzbget/NzbgetClient.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; -using Newtonsoft.Json; using NLog; using NzbDrone.Common; +using NzbDrone.Common.Serializer; using NzbDrone.Core.Configuration; using NzbDrone.Core.Parser.Model; @@ -36,11 +36,11 @@ namespace NzbDrone.Core.Download.Clients.Nzbget }; _logger.Info("Adding report [{0}] to the queue.", title); - var response = PostCommand(JsonConvert.SerializeObject(command)); + var response = PostCommand(command.ToJson()); CheckForError(response); - var success = JsonConvert.DeserializeObject(response).Result; + var success = Json.Deserialize(response).Result; _logger.Debug("Queue Response: [{0}]", success); } @@ -61,11 +61,11 @@ namespace NzbDrone.Core.Download.Clients.Nzbget Params = null }; - var response = PostCommand(JsonConvert.SerializeObject(command)); + var response = PostCommand(command.ToJson()); CheckForError(response); - var itmes = JsonConvert.DeserializeObject(response).QueueItems; + var itmes = Json.Deserialize(response).QueueItems; foreach (var nzbGetQueueItem in itmes) { @@ -101,11 +101,11 @@ namespace NzbDrone.Core.Download.Clients.Nzbget }; var address = String.Format(@"{0}:{1}", host, port); - var response = _httpProvider.PostCommand(address, username, password, JsonConvert.SerializeObject(command)); + var response = _httpProvider.PostCommand(address, username, password, command.ToJson()); CheckForError(response); - return JsonConvert.DeserializeObject(response); + return Json.Deserialize(response); } public virtual string Test(string host, int port, string username, string password) @@ -134,7 +134,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget private void CheckForError(string response) { - var result = JsonConvert.DeserializeObject(response); + var result = Json.Deserialize(response); if (result.Error != null) throw new ApplicationException(result.Error.ToString()); diff --git a/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdClient.cs b/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdClient.cs index 40a241a1c..7a6eac544 100644 --- a/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdClient.cs +++ b/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdClient.cs @@ -1,11 +1,11 @@ using System; using System.Collections.Generic; using System.Web; -using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NLog; using NzbDrone.Common; using NzbDrone.Common.Cache; +using NzbDrone.Common.Serializer; using NzbDrone.Core.Configuration; using NzbDrone.Core.Parser.Model; using RestSharp; @@ -107,7 +107,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd CheckForError(response); - var sabQueue = JsonConvert.DeserializeObject(JObject.Parse(response).SelectToken("queue").ToString()).Items; + var sabQueue = Json.Deserialize(JObject.Parse(response).SelectToken("queue").ToString()).Items; var queueItems = new List(); @@ -134,7 +134,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd CheckForError(response); - var items = JsonConvert.DeserializeObject(JObject.Parse(response).SelectToken("history").ToString()).Items; + var items = Json.Deserialize(JObject.Parse(response).SelectToken("history").ToString()).Items; return items ?? new List(); } @@ -166,7 +166,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd if (String.IsNullOrWhiteSpace(response)) return new SabCategoryModel { categories = new List() }; - var categories = JsonConvert.DeserializeObject(response); + var categories = Json.Deserialize(response); return categories; } @@ -199,7 +199,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd if (String.IsNullOrWhiteSpace(response)) return null; - var version = JsonConvert.DeserializeObject(response); + var version = Json.Deserialize(response); return version; } @@ -232,7 +232,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd private void CheckForError(string response) { - var result = JsonConvert.DeserializeObject(response); + var result = Json.Deserialize(response); if (result.Status != null && result.Status.Equals("false", StringComparison.InvariantCultureIgnoreCase)) throw new ApplicationException(result.Error); diff --git a/NzbDrone.Core/Download/DownloadService.cs b/NzbDrone.Core/Download/DownloadService.cs index a1c4f3bf1..f41acdafa 100644 --- a/NzbDrone.Core/Download/DownloadService.cs +++ b/NzbDrone.Core/Download/DownloadService.cs @@ -1,6 +1,6 @@ using NLog; +using NzbDrone.Common.EnsureThat; using NzbDrone.Core.Instrumentation; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Parser.Model; @@ -28,6 +28,9 @@ namespace NzbDrone.Core.Download public void DownloadReport(RemoteEpisode remoteEpisode) { + Ensure.That(() => remoteEpisode.Series).IsNotNull(); + Ensure.That(() => remoteEpisode.Episodes).HasItems(); + var downloadTitle = remoteEpisode.Release.Title; var downloadClient = _downloadClientProvider.GetDownloadClient(); diff --git a/NzbDrone.Core/Exceptions/BadRequestException.cs b/NzbDrone.Core/Exceptions/BadRequestException.cs new file mode 100644 index 000000000..212b69e87 --- /dev/null +++ b/NzbDrone.Core/Exceptions/BadRequestException.cs @@ -0,0 +1,15 @@ +using System.Net; + +namespace NzbDrone.Core.Exceptions +{ + public class BadRequestException : DownstreamException + { + public BadRequestException(HttpStatusCode statusCode, string message) : base(statusCode, message) + { + } + + public BadRequestException(HttpStatusCode statusCode, string message, params object[] args) : base(statusCode, message, args) + { + } + } +} diff --git a/NzbDrone.Core/Exceptions/DownstreamException.cs b/NzbDrone.Core/Exceptions/DownstreamException.cs new file mode 100644 index 000000000..0ce8f1a94 --- /dev/null +++ b/NzbDrone.Core/Exceptions/DownstreamException.cs @@ -0,0 +1,21 @@ +using System.Net; +using NzbDrone.Common.Exceptions; + +namespace NzbDrone.Core.Exceptions +{ + public class DownstreamException : NzbDroneException + { + public HttpStatusCode StatusCode { get; private set; } + + public DownstreamException(HttpStatusCode statusCode, string message, params object[] args) : base(message, args) + { + StatusCode = statusCode; + } + + public DownstreamException(HttpStatusCode statusCode, string message) + : base(message) + { + StatusCode = statusCode; + } + } +} diff --git a/NzbDrone.Core/NzbDroneClientException.cs b/NzbDrone.Core/Exceptions/NzbDroneClientException.cs similarity index 93% rename from NzbDrone.Core/NzbDroneClientException.cs rename to NzbDrone.Core/Exceptions/NzbDroneClientException.cs index cc94caffc..d9225eb2c 100644 --- a/NzbDrone.Core/NzbDroneClientException.cs +++ b/NzbDrone.Core/Exceptions/NzbDroneClientException.cs @@ -1,7 +1,7 @@ using System.Net; using NzbDrone.Common.Exceptions; -namespace NzbDrone.Core +namespace NzbDrone.Core.Exceptions { public class NzbDroneClientException : NzbDroneException { diff --git a/NzbDrone.Core/Exceptions/StatusCodeToExceptions.cs b/NzbDrone.Core/Exceptions/StatusCodeToExceptions.cs new file mode 100644 index 000000000..10513d9c6 --- /dev/null +++ b/NzbDrone.Core/Exceptions/StatusCodeToExceptions.cs @@ -0,0 +1,31 @@ +using System; +using System.Net; + +namespace NzbDrone.Core.Exceptions +{ + public static class StatusCodeToExceptions + { + public static void VerifyStatusCode(this HttpStatusCode statusCode, string message = null) + { + if (String.IsNullOrEmpty(message)) + { + message = statusCode.ToString(); + } + + switch (statusCode) + { + case HttpStatusCode.BadRequest: + throw new BadRequestException(statusCode, message); + + case HttpStatusCode.Unauthorized: + throw new UnauthorizedAccessException(message); + + case HttpStatusCode.PaymentRequired: + throw new DownstreamException(statusCode, message); + + case HttpStatusCode.InternalServerError: + throw new DownstreamException(statusCode, message); + } + } + } +} diff --git a/NzbDrone.Core/Helpers/SortHelper.cs b/NzbDrone.Core/Helpers/SortHelper.cs deleted file mode 100644 index bd2192a08..000000000 --- a/NzbDrone.Core/Helpers/SortHelper.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace NzbDrone.Core.Helpers -{ - public static class SortHelper - { - public static string IgnoreArticles(this string input) - { - if (String.IsNullOrEmpty(input)) - return String.Empty; - - var articles = new List { "The ", "An ", "A " }; - - foreach (string article in articles) - { - if (input.ToLower().StartsWith(article, StringComparison.InvariantCultureIgnoreCase)) - return input.Substring(article.Length).Trim(); - } - - return input; - } - } -} diff --git a/NzbDrone.Core/History/HistoryRepository.cs b/NzbDrone.Core/History/HistoryRepository.cs index 096397248..a39e117ea 100644 --- a/NzbDrone.Core/History/HistoryRepository.cs +++ b/NzbDrone.Core/History/HistoryRepository.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using Marr.Data.QGen; using NzbDrone.Core.Datastore; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Tv; @@ -17,9 +16,12 @@ namespace NzbDrone.Core.History public class HistoryRepository : BasicRepository, IHistoryRepository { + private readonly IDatabase _database; + public HistoryRepository(IDatabase database, IEventAggregator eventAggregator) : base(database, eventAggregator) { + _database = database; } public void Trim() diff --git a/NzbDrone.Core/History/HistoryService.cs b/NzbDrone.Core/History/HistoryService.cs index 6053541d0..64736c9f0 100644 --- a/NzbDrone.Core/History/HistoryService.cs +++ b/NzbDrone.Core/History/HistoryService.cs @@ -5,7 +5,6 @@ using NLog; using NzbDrone.Core.Datastore; using NzbDrone.Core.Download; using NzbDrone.Core.MediaFiles.Events; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Tv; diff --git a/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedEpisodes.cs b/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedEpisodes.cs new file mode 100644 index 000000000..0965fc33c --- /dev/null +++ b/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedEpisodes.cs @@ -0,0 +1,32 @@ +using NLog; +using NzbDrone.Core.Datastore; +using NzbDrone.Core.Tv; + +namespace NzbDrone.Core.Housekeeping.Housekeepers +{ + public class CleanupOrphanedEpisodes : IHousekeepingTask + { + private readonly IDatabase _database; + private readonly Logger _logger; + + public CleanupOrphanedEpisodes(IDatabase database, Logger logger) + { + _database = database; + _logger = logger; + } + + public void Clean() + { + _logger.Trace("Running orphaned episodes cleanup"); + + var mapper = _database.GetDataMapper(); + + mapper.ExecuteNonQuery(@"DELETE FROM Episodes + WHERE Id IN ( + SELECT Episodes.Id FROM Episodes + LEFT OUTER JOIN Series + ON Episodes.SeriesId = Series.Id + WHERE Series.Id IS NULL)"); + } + } +} diff --git a/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedHistoryItems.cs b/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedHistoryItems.cs new file mode 100644 index 000000000..11567a2ba --- /dev/null +++ b/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedHistoryItems.cs @@ -0,0 +1,49 @@ +using NLog; +using NzbDrone.Core.Datastore; +using NzbDrone.Core.History; + +namespace NzbDrone.Core.Housekeeping.Housekeepers +{ + public class CleanupOrphanedHistoryItems : IHousekeepingTask + { + private readonly IDatabase _database; + private readonly Logger _logger; + + public CleanupOrphanedHistoryItems(IDatabase database, Logger logger) + { + _database = database; + _logger = logger; + } + + public void Clean() + { + _logger.Trace("Running orphaned history cleanup"); + CleanupOrphanedBySeries(); + CleanupOrphanedByEpisode(); + } + + private void CleanupOrphanedBySeries() + { + var mapper = _database.GetDataMapper(); + + mapper.ExecuteNonQuery(@"DELETE FROM History + WHERE Id IN ( + SELECT History.Id FROM History + LEFT OUTER JOIN Series + ON History.SeriesId = Series.Id + WHERE Series.Id IS NULL)"); + } + + private void CleanupOrphanedByEpisode() + { + var mapper = _database.GetDataMapper(); + + mapper.ExecuteNonQuery(@"DELETE FROM History + WHERE Id IN ( + SELECT History.Id FROM History + LEFT OUTER JOIN Episodes + ON History.EpisodeId = Episodes.Id + WHERE Episodes.Id IS NULL)"); + } + } +} diff --git a/NzbDrone.Core/Housekeeping/HousekeepingCommand.cs b/NzbDrone.Core/Housekeeping/HousekeepingCommand.cs new file mode 100644 index 000000000..ebf482ee5 --- /dev/null +++ b/NzbDrone.Core/Housekeeping/HousekeepingCommand.cs @@ -0,0 +1,8 @@ +using NzbDrone.Core.Messaging.Commands; + +namespace NzbDrone.Core.Housekeeping +{ + public class HousekeepingCommand : Command + { + } +} diff --git a/NzbDrone.Core/Housekeeping/HousekeepingService.cs b/NzbDrone.Core/Housekeeping/HousekeepingService.cs new file mode 100644 index 000000000..fd030ffea --- /dev/null +++ b/NzbDrone.Core/Housekeeping/HousekeepingService.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using NLog; +using NzbDrone.Core.Messaging.Commands; + +namespace NzbDrone.Core.Housekeeping +{ + public class HousekeepingService : IExecute + { + private readonly IEnumerable _housekeepers; + private readonly Logger _logger; + + public HousekeepingService(IEnumerable housekeepers, Logger logger) + { + _housekeepers = housekeepers; + _logger = logger; + } + + public void Execute(HousekeepingCommand message) + { + _logger.Info("Running housecleaning tasks"); + + foreach (var housekeeper in _housekeepers) + { + try + { + housekeeper.Clean(); + } + catch (Exception ex) + { + _logger.ErrorException("Error running housekeeping task: " + housekeeper.GetType().FullName, ex); + } + } + } + } +} diff --git a/NzbDrone.Core/Housekeeping/IHousekeepingTask.cs b/NzbDrone.Core/Housekeeping/IHousekeepingTask.cs new file mode 100644 index 000000000..2a69cfdc5 --- /dev/null +++ b/NzbDrone.Core/Housekeeping/IHousekeepingTask.cs @@ -0,0 +1,7 @@ +namespace NzbDrone.Core.Housekeeping +{ + public interface IHousekeepingTask + { + void Clean(); + } +} \ No newline at end of file diff --git a/NzbDrone.Core/IndexerSearch/EpisodeSearchService.cs b/NzbDrone.Core/IndexerSearch/EpisodeSearchService.cs index 4f2860eb4..34fba629d 100644 --- a/NzbDrone.Core/IndexerSearch/EpisodeSearchService.cs +++ b/NzbDrone.Core/IndexerSearch/EpisodeSearchService.cs @@ -1,7 +1,6 @@ using NLog; using NzbDrone.Core.Download; using NzbDrone.Core.Instrumentation; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; namespace NzbDrone.Core.IndexerSearch diff --git a/NzbDrone.Core/IndexerSearch/SeasonSearchService.cs b/NzbDrone.Core/IndexerSearch/SeasonSearchService.cs index 0e4b67eab..13b384856 100644 --- a/NzbDrone.Core/IndexerSearch/SeasonSearchService.cs +++ b/NzbDrone.Core/IndexerSearch/SeasonSearchService.cs @@ -1,7 +1,6 @@ using NLog; using NzbDrone.Core.Download; using NzbDrone.Core.Instrumentation; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; namespace NzbDrone.Core.IndexerSearch diff --git a/NzbDrone.Core/IndexerSearch/SeriesSearchService.cs b/NzbDrone.Core/IndexerSearch/SeriesSearchService.cs index c87275648..149440b91 100644 --- a/NzbDrone.Core/IndexerSearch/SeriesSearchService.cs +++ b/NzbDrone.Core/IndexerSearch/SeriesSearchService.cs @@ -1,8 +1,6 @@ -using System.Linq; -using NLog; +using NLog; using NzbDrone.Core.Download; using NzbDrone.Core.Instrumentation; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Tv; diff --git a/NzbDrone.Core/Indexers/BasicTorrentRssParser.cs b/NzbDrone.Core/Indexers/BasicTorrentRssParser.cs index d3c8ab15a..1fa3ec6c6 100644 --- a/NzbDrone.Core/Indexers/BasicTorrentRssParser.cs +++ b/NzbDrone.Core/Indexers/BasicTorrentRssParser.cs @@ -1,6 +1,5 @@ using System; using System.Xml.Linq; -using NLog; using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.Indexers diff --git a/NzbDrone.Core/Indexers/IParseFeed.cs b/NzbDrone.Core/Indexers/IParseFeed.cs index a101f0a07..2722669b8 100644 --- a/NzbDrone.Core/Indexers/IParseFeed.cs +++ b/NzbDrone.Core/Indexers/IParseFeed.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.IO; using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.Indexers diff --git a/NzbDrone.Core/Indexers/IndexerRepository.cs b/NzbDrone.Core/Indexers/IndexerRepository.cs index fd66a3910..b4c6446a1 100644 --- a/NzbDrone.Core/Indexers/IndexerRepository.cs +++ b/NzbDrone.Core/Indexers/IndexerRepository.cs @@ -1,7 +1,6 @@ using System; using System.Linq; using NzbDrone.Core.Datastore; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; diff --git a/NzbDrone.Core/Indexers/IndexerService.cs b/NzbDrone.Core/Indexers/IndexerService.cs index d9fc3ba27..2c87569e3 100644 --- a/NzbDrone.Core/Indexers/IndexerService.cs +++ b/NzbDrone.Core/Indexers/IndexerService.cs @@ -6,7 +6,6 @@ using NzbDrone.Common.Serializer; using NzbDrone.Core.Configuration; using NzbDrone.Core.Indexers.Newznab; using NzbDrone.Core.Lifecycle; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; using Omu.ValueInjecter; diff --git a/NzbDrone.Core/Indexers/IndexerSettingProvider.cs b/NzbDrone.Core/Indexers/IndexerSettingProvider.cs index a0a0650c7..ab7da9e58 100644 --- a/NzbDrone.Core/Indexers/IndexerSettingProvider.cs +++ b/NzbDrone.Core/Indexers/IndexerSettingProvider.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using NzbDrone.Common.Serializer; namespace NzbDrone.Core.Indexers { @@ -25,7 +25,7 @@ namespace NzbDrone.Core.Indexers return new TSetting(); } - return JsonConvert.DeserializeObject(indexerDef.Settings); + return Json.Deserialize(indexerDef.Settings); } } } \ No newline at end of file diff --git a/NzbDrone.Core/Indexers/Newznab/NewznabParser.cs b/NzbDrone.Core/Indexers/Newznab/NewznabParser.cs index 06c45ea1d..fc9e54d93 100644 --- a/NzbDrone.Core/Indexers/Newznab/NewznabParser.cs +++ b/NzbDrone.Core/Indexers/Newznab/NewznabParser.cs @@ -17,12 +17,12 @@ namespace NzbDrone.Core.Indexers.Newznab var attributes = item.Elements("attr").ToList(); var sizeElement = attributes.SingleOrDefault(e => e.Attribute("name").Value.Equals("size", StringComparison.CurrentCultureIgnoreCase)); - if (sizeElement == null) + if (sizeElement != null) { - + return Convert.ToInt64(sizeElement.Attribute("value").Value); } - return Convert.ToInt64(sizeElement.Attribute("value").Value); + return ParseSize(item.Description()); } protected override ReleaseInfo PostProcessor(XElement item, ReleaseInfo currentResult) diff --git a/NzbDrone.Core/Indexers/RssParserBase.cs b/NzbDrone.Core/Indexers/RssParserBase.cs index 485bc0140..ca4bf91f8 100644 --- a/NzbDrone.Core/Indexers/RssParserBase.cs +++ b/NzbDrone.Core/Indexers/RssParserBase.cs @@ -108,8 +108,6 @@ namespace NzbDrone.Core.Indexers return currentResult; } - - public static string ParseReleaseGroup(string title) { title = title.Trim(); @@ -132,8 +130,6 @@ namespace NzbDrone.Core.Indexers private static readonly Regex ReportSizeRegex = new Regex(@"(?\d+\.\d{1,2}|\d+\,\d+\.\d{1,2}|\d+)\W?(?GB|MB|GiB|MiB)", RegexOptions.IgnoreCase | RegexOptions.Compiled); - - public static long ParseSize(string sizeString) { var match = ReportSizeRegex.Matches(sizeString); diff --git a/NzbDrone.Core/Indexers/RssSyncService.cs b/NzbDrone.Core/Indexers/RssSyncService.cs index 5f9be30a9..8435a1549 100644 --- a/NzbDrone.Core/Indexers/RssSyncService.cs +++ b/NzbDrone.Core/Indexers/RssSyncService.cs @@ -3,7 +3,6 @@ using NLog; using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.Instrumentation; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; namespace NzbDrone.Core.Indexers diff --git a/NzbDrone.Core/Instrumentation/DatabaseTarget.cs b/NzbDrone.Core/Instrumentation/DatabaseTarget.cs index 673f4f9d6..8c71174a4 100644 --- a/NzbDrone.Core/Instrumentation/DatabaseTarget.cs +++ b/NzbDrone.Core/Instrumentation/DatabaseTarget.cs @@ -4,7 +4,6 @@ using NLog; using NLog.Layouts; using NLog.Targets; using NzbDrone.Core.Lifecycle; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; namespace NzbDrone.Core.Instrumentation diff --git a/NzbDrone.Core/Instrumentation/DeleteLogFilesService.cs b/NzbDrone.Core/Instrumentation/DeleteLogFilesService.cs index 3a12cd057..657f8f7da 100644 --- a/NzbDrone.Core/Instrumentation/DeleteLogFilesService.cs +++ b/NzbDrone.Core/Instrumentation/DeleteLogFilesService.cs @@ -3,7 +3,6 @@ using NLog; using NzbDrone.Common; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Core.Instrumentation.Commands; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; namespace NzbDrone.Core.Instrumentation diff --git a/NzbDrone.Core/Instrumentation/LogRepository.cs b/NzbDrone.Core/Instrumentation/LogRepository.cs index 8259b5cf7..62d2d3a0e 100644 --- a/NzbDrone.Core/Instrumentation/LogRepository.cs +++ b/NzbDrone.Core/Instrumentation/LogRepository.cs @@ -1,6 +1,5 @@ using System; using NzbDrone.Core.Datastore; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; diff --git a/NzbDrone.Core/Instrumentation/LogService.cs b/NzbDrone.Core/Instrumentation/LogService.cs index f46dbf5dd..7f9000847 100644 --- a/NzbDrone.Core/Instrumentation/LogService.cs +++ b/NzbDrone.Core/Instrumentation/LogService.cs @@ -1,6 +1,5 @@ using NzbDrone.Core.Datastore; using NzbDrone.Core.Instrumentation.Commands; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; namespace NzbDrone.Core.Instrumentation diff --git a/NzbDrone.Core/Jobs/JobQueueItem.cs b/NzbDrone.Core/Jobs/JobQueueItem.cs deleted file mode 100644 index 079c186c9..000000000 --- a/NzbDrone.Core/Jobs/JobQueueItem.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; - -namespace NzbDrone.Core.Jobs -{ - public class JobQueueItem : IEquatable - { - public Type JobType { get; set; } - public dynamic Options { get; set; } - - public JobSourceType Source { get; set; } - - public bool Equals(JobQueueItem other) - { - return (JobType == other.JobType && Options == other.Options); - } - - public override string ToString() - { - if (Options != null) - { - return string.Format("[{0}({1})]", JobType.Name, Options); - } - - return string.Format("[{0}]", JobType.Name); - } - - public enum JobSourceType - { - User, - Scheduler - } - } -} diff --git a/NzbDrone.Core/Jobs/TaskManager.cs b/NzbDrone.Core/Jobs/TaskManager.cs index a04931ac3..e2bc22da2 100644 --- a/NzbDrone.Core/Jobs/TaskManager.cs +++ b/NzbDrone.Core/Jobs/TaskManager.cs @@ -4,14 +4,16 @@ using System.Linq; using NLog; using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration.Events; +using NzbDrone.Core.DataAugmentation; using NzbDrone.Core.DataAugmentation.Scene; +using NzbDrone.Core.DataAugmentation.Xem; +using NzbDrone.Core.Housekeeping; using NzbDrone.Core.Indexers; using NzbDrone.Core.Instrumentation.Commands; using NzbDrone.Core.Lifecycle; using NzbDrone.Core.MediaFiles.Commands; using NzbDrone.Core.Messaging.Commands.Tracking; using NzbDrone.Core.Messaging.Events; -using NzbDrone.Core.Providers; using NzbDrone.Core.Tv.Commands; using NzbDrone.Core.Update.Commands; @@ -51,7 +53,8 @@ namespace NzbDrone.Core.Jobs new ScheduledTask{ Interval = 60, TypeName = typeof(ApplicationUpdateCommand).FullName}, new ScheduledTask{ Interval = 1*60, TypeName = typeof(TrimLogCommand).FullName}, new ScheduledTask{ Interval = 3*60, TypeName = typeof(UpdateSceneMappingCommand).FullName}, - new ScheduledTask{ Interval = 1, TypeName = typeof(TrackedCommandCleanupCommand).FullName} + new ScheduledTask{ Interval = 1, TypeName = typeof(TrackedCommandCleanupCommand).FullName}, + new ScheduledTask{ Interval = 24*60, TypeName = typeof(HousekeepingCommand).FullName} }; var currentTasks = _scheduledTaskRepository.All(); diff --git a/NzbDrone.Core/MediaCover/MediaCoverService.cs b/NzbDrone.Core/MediaCover/MediaCoverService.cs index 67b0d0b21..a055dbef6 100644 --- a/NzbDrone.Core/MediaCover/MediaCoverService.cs +++ b/NzbDrone.Core/MediaCover/MediaCoverService.cs @@ -5,7 +5,6 @@ using System.Net; using NLog; using NzbDrone.Common; using NzbDrone.Common.EnvironmentInfo; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Tv; using NzbDrone.Core.Tv.Events; diff --git a/NzbDrone.Core/MediaFiles/DiskScanService.cs b/NzbDrone.Core/MediaFiles/DiskScanService.cs index 16b64789f..069bc18e3 100644 --- a/NzbDrone.Core/MediaFiles/DiskScanService.cs +++ b/NzbDrone.Core/MediaFiles/DiskScanService.cs @@ -5,7 +5,6 @@ using NzbDrone.Common; using NzbDrone.Core.Instrumentation; using NzbDrone.Core.MediaFiles.Commands; using NzbDrone.Core.MediaFiles.EpisodeImport; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Tv; diff --git a/NzbDrone.Core/MediaFiles/DownloadedEpisodesImportService.cs b/NzbDrone.Core/MediaFiles/DownloadedEpisodesImportService.cs index 55c6f4638..5f36b5910 100644 --- a/NzbDrone.Core/MediaFiles/DownloadedEpisodesImportService.cs +++ b/NzbDrone.Core/MediaFiles/DownloadedEpisodesImportService.cs @@ -8,7 +8,6 @@ using NzbDrone.Core.Configuration; using NzbDrone.Core.MediaFiles.Commands; using NzbDrone.Core.MediaFiles.EpisodeImport; using NzbDrone.Core.MediaFiles.EpisodeImport.Specifications; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Parser; using NzbDrone.Core.Tv; diff --git a/NzbDrone.Core/MediaFiles/EpisodeFileMovingService.cs b/NzbDrone.Core/MediaFiles/EpisodeFileMovingService.cs index 91157d26a..f14a0ae44 100644 --- a/NzbDrone.Core/MediaFiles/EpisodeFileMovingService.cs +++ b/NzbDrone.Core/MediaFiles/EpisodeFileMovingService.cs @@ -3,7 +3,6 @@ using System.IO; using System.Linq; using NLog; using NzbDrone.Common; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Organizer; using NzbDrone.Core.Parser.Model; diff --git a/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs b/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs index a9a92bb87..a725176e7 100644 --- a/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs +++ b/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs @@ -5,7 +5,6 @@ using System.Linq; using NLog; using NzbDrone.Common; using NzbDrone.Core.MediaFiles.Events; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; diff --git a/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/NotSampleSpecification.cs b/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/NotSampleSpecification.cs index 3d2901974..dba6cf400 100644 --- a/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/NotSampleSpecification.cs +++ b/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/NotSampleSpecification.cs @@ -3,7 +3,6 @@ using System.IO; using NLog; using NzbDrone.Core.MediaFiles.MediaInfo; using NzbDrone.Core.Parser.Model; -using NzbDrone.Core.Providers; using NzbDrone.Core.Tv; namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications diff --git a/NzbDrone.Core/MediaFiles/MediaFileRepository.cs b/NzbDrone.Core/MediaFiles/MediaFileRepository.cs index 7a0839594..18107b1ba 100644 --- a/NzbDrone.Core/MediaFiles/MediaFileRepository.cs +++ b/NzbDrone.Core/MediaFiles/MediaFileRepository.cs @@ -1,7 +1,5 @@ using System.Collections.Generic; -using System.Linq; using NzbDrone.Core.Datastore; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; @@ -9,10 +7,8 @@ namespace NzbDrone.Core.MediaFiles { public interface IMediaFileRepository : IBasicRepository { - EpisodeFile GetFileByPath(string path); List GetFilesBySeries(int seriesId); List GetFilesBySeason(int seriesId, int seasonNumber); - bool Exists(string path); } @@ -23,11 +19,6 @@ namespace NzbDrone.Core.MediaFiles { } - public EpisodeFile GetFileByPath(string path) - { - return Query.SingleOrDefault(c => c.Path == path); - } - public List GetFilesBySeries(int seriesId) { return Query.Where(c => c.SeriesId == seriesId).ToList(); @@ -40,9 +31,5 @@ namespace NzbDrone.Core.MediaFiles .ToList(); } - public bool Exists(string path) - { - return Query.Any(c => c.Path == path); - } } } \ No newline at end of file diff --git a/NzbDrone.Core/MediaFiles/MediaFileService.cs b/NzbDrone.Core/MediaFiles/MediaFileService.cs index b963b408e..44f67174c 100644 --- a/NzbDrone.Core/MediaFiles/MediaFileService.cs +++ b/NzbDrone.Core/MediaFiles/MediaFileService.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using NLog; using NzbDrone.Core.MediaFiles.Events; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Tv.Events; using NzbDrone.Common; @@ -14,8 +13,6 @@ namespace NzbDrone.Core.MediaFiles EpisodeFile Add(EpisodeFile episodeFile); void Update(EpisodeFile episodeFile); void Delete(EpisodeFile episodeFile, bool forUpgrade = false); - bool Exists(string path); - EpisodeFile GetFileByPath(string path); List GetFilesBySeries(int seriesId); List GetFilesBySeason(int seriesId, int seasonNumber); List FilterExistingFiles(List files, int seriesId); @@ -54,16 +51,6 @@ namespace NzbDrone.Core.MediaFiles _eventAggregator.PublishEvent(new EpisodeFileDeletedEvent(episodeFile, forUpgrade)); } - public bool Exists(string path) - { - return _mediaFileRepository.Exists(path); - } - - public EpisodeFile GetFileByPath(string path) - { - return _mediaFileRepository.GetFileByPath(path.Normalize()); - } - public List GetFilesBySeries(int seriesId) { return _mediaFileRepository.GetFilesBySeries(seriesId); diff --git a/NzbDrone.Core/MediaFiles/MediaFileTableCleanupService.cs b/NzbDrone.Core/MediaFiles/MediaFileTableCleanupService.cs index 26c4d1905..4b67befab 100644 --- a/NzbDrone.Core/MediaFiles/MediaFileTableCleanupService.cs +++ b/NzbDrone.Core/MediaFiles/MediaFileTableCleanupService.cs @@ -3,7 +3,6 @@ using System.Linq; using NLog; using NzbDrone.Common; using NzbDrone.Core.MediaFiles.Commands; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Tv; diff --git a/NzbDrone.Core/Model/MediaInfoModel.cs b/NzbDrone.Core/MediaFiles/MediaInfo/MediaInfoModel.cs similarity index 93% rename from NzbDrone.Core/Model/MediaInfoModel.cs rename to NzbDrone.Core/MediaFiles/MediaInfo/MediaInfoModel.cs index 9b2ada461..69e8f4760 100644 --- a/NzbDrone.Core/Model/MediaInfoModel.cs +++ b/NzbDrone.Core/MediaFiles/MediaInfo/MediaInfoModel.cs @@ -1,4 +1,4 @@ -namespace NzbDrone.Core.Model +namespace NzbDrone.Core.MediaFiles.MediaInfo { public class MediaInfoModel { diff --git a/NzbDrone.Core/MediaFiles/MediaInfo/VideoFileInfoReader.cs b/NzbDrone.Core/MediaFiles/MediaInfo/VideoFileInfoReader.cs index a2f1143e2..4879218d0 100644 --- a/NzbDrone.Core/MediaFiles/MediaInfo/VideoFileInfoReader.cs +++ b/NzbDrone.Core/MediaFiles/MediaInfo/VideoFileInfoReader.cs @@ -3,7 +3,6 @@ using System.IO; using MediaInfoLib; using NLog; using NzbDrone.Common; -using NzbDrone.Core.Model; namespace NzbDrone.Core.MediaFiles.MediaInfo { diff --git a/NzbDrone.Core/MediaFiles/RecycleBinProvider.cs b/NzbDrone.Core/MediaFiles/RecycleBinProvider.cs index 00ff120e2..460baa818 100644 --- a/NzbDrone.Core/MediaFiles/RecycleBinProvider.cs +++ b/NzbDrone.Core/MediaFiles/RecycleBinProvider.cs @@ -6,7 +6,6 @@ using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.Instrumentation; using NzbDrone.Core.Configuration; using NzbDrone.Core.MediaFiles.Commands; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Tv.Events; diff --git a/NzbDrone.Core/MediaFiles/RenameEpisodeFileService.cs b/NzbDrone.Core/MediaFiles/RenameEpisodeFileService.cs index 501963445..8cbfc51a2 100644 --- a/NzbDrone.Core/MediaFiles/RenameEpisodeFileService.cs +++ b/NzbDrone.Core/MediaFiles/RenameEpisodeFileService.cs @@ -5,7 +5,6 @@ using NLog; using NzbDrone.Core.Instrumentation; using NzbDrone.Core.MediaFiles.Commands; using NzbDrone.Core.MediaFiles.Events; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Tv; diff --git a/NzbDrone.Core/Messaging/Commands/CommandEqualityComparer.cs b/NzbDrone.Core/Messaging/Commands/CommandEqualityComparer.cs index 2b24895f1..38017fe4e 100644 --- a/NzbDrone.Core/Messaging/Commands/CommandEqualityComparer.cs +++ b/NzbDrone.Core/Messaging/Commands/CommandEqualityComparer.cs @@ -26,6 +26,11 @@ namespace NzbDrone.Core.Messaging.Commands continue; } + if (xProperty.DeclaringType == typeof (Command)) + { + continue; + } + var yProperty = yProperties.Single(p => p.Name == xProperty.Name); var xValue = xProperty.GetValue(x, null); diff --git a/NzbDrone.Core/Messaging/Commands/Tracking/CommandTrackingService.cs b/NzbDrone.Core/Messaging/Commands/Tracking/CommandTrackingService.cs index 3e5a6c619..f4ea7ddd0 100644 --- a/NzbDrone.Core/Messaging/Commands/Tracking/CommandTrackingService.cs +++ b/NzbDrone.Core/Messaging/Commands/Tracking/CommandTrackingService.cs @@ -58,8 +58,7 @@ namespace NzbDrone.Core.Messaging.Commands.Tracking public Command FindExisting(Command command) { - return RunningCommands().Where(c => c.GetType() == command.GetType()) - .SingleOrDefault(t => CommandEqualityComparer.Instance.Equals(t, command)); + return RunningCommands().SingleOrDefault(t => CommandEqualityComparer.Instance.Equals(t, command)); } public void Store(Command command) diff --git a/NzbDrone.Core/MetadataSource/Trakt/TraktException.cs b/NzbDrone.Core/MetadataSource/Trakt/TraktException.cs index 999122301..3d51fe8ab 100644 --- a/NzbDrone.Core/MetadataSource/Trakt/TraktException.cs +++ b/NzbDrone.Core/MetadataSource/Trakt/TraktException.cs @@ -1,4 +1,5 @@ using System.Net; +using NzbDrone.Core.Exceptions; namespace NzbDrone.Core.MetadataSource.Trakt { diff --git a/NzbDrone.Core/MetadataSource/TraktProxy.cs b/NzbDrone.Core/MetadataSource/TraktProxy.cs index f37cc8d6b..5ff74a23c 100644 --- a/NzbDrone.Core/MetadataSource/TraktProxy.cs +++ b/NzbDrone.Core/MetadataSource/TraktProxy.cs @@ -154,12 +154,6 @@ namespace NzbDrone.Core.MetadataSource { DateTime result; - //Todo: Remove this when DST ends and/or trakt fixes DST airings in EST/EDT - if (iso != null && iso.EndsWith("-05:00")) - { - iso = iso.Replace("-05:00", "-04:00"); - } - if (!DateTime.TryParse(iso, out result)) return null; diff --git a/NzbDrone.Core/Model/AtomicParsleyTitleType.cs b/NzbDrone.Core/Model/AtomicParsleyTitleType.cs deleted file mode 100644 index d133b977a..000000000 --- a/NzbDrone.Core/Model/AtomicParsleyTitleType.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace NzbDrone.Core.Model -{ - public enum AtomicParsleyTitleType - { - None = 0, - EpisodeNumber = 1, - Both = 2 - } -} \ No newline at end of file diff --git a/NzbDrone.Core/Model/MisnamedEpisodeModel.cs b/NzbDrone.Core/Model/MisnamedEpisodeModel.cs deleted file mode 100644 index 2c06b6d4f..000000000 --- a/NzbDrone.Core/Model/MisnamedEpisodeModel.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace NzbDrone.Core.Model -{ - public class MisnamedEpisodeModel - { - public int EpisodeFileId { get; set; } - public int SeriesId { get; set; } - public string SeriesTitle { get; set; } - public string CurrentName { get; set; } - public string ProperName { get; set; } - } -} diff --git a/NzbDrone.Core/Model/Xbmc/ActivePlayersEdenResult.cs b/NzbDrone.Core/Model/Xbmc/ActivePlayersEdenResult.cs deleted file mode 100644 index 191a5e7f2..000000000 --- a/NzbDrone.Core/Model/Xbmc/ActivePlayersEdenResult.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Collections.Generic; - -namespace NzbDrone.Core.Model.Xbmc -{ - public class ActivePlayersEdenResult - { - public string Id { get; set; } - public string JsonRpc { get; set; } - public List Result { get; set; } - } - - public class ActivePlayer - { - public int PlayerId { get; set; } - public string Type { get; set; } - - public ActivePlayer(int playerId, string type) - { - PlayerId = playerId; - Type = type; - } - } -} diff --git a/NzbDrone.Core/Notifications/Email/EmailService.cs b/NzbDrone.Core/Notifications/Email/EmailService.cs index 5625a9785..e103b144c 100644 --- a/NzbDrone.Core/Notifications/Email/EmailService.cs +++ b/NzbDrone.Core/Notifications/Email/EmailService.cs @@ -2,7 +2,6 @@ using System.Net; using System.Net.Mail; using NLog; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; using Omu.ValueInjecter; diff --git a/NzbDrone.Core/Notifications/Growl/GrowlService.cs b/NzbDrone.Core/Notifications/Growl/GrowlService.cs index 5ec00df7c..cfcba9ba6 100644 --- a/NzbDrone.Core/Notifications/Growl/GrowlService.cs +++ b/NzbDrone.Core/Notifications/Growl/GrowlService.cs @@ -4,7 +4,6 @@ using System.Linq; using Growl.Connector; using NLog; using NzbDrone.Common.Instrumentation; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; using GrowlNotification = Growl.Connector.Notification; diff --git a/NzbDrone.Core/Notifications/NotificationRepository.cs b/NzbDrone.Core/Notifications/NotificationRepository.cs index 79dedcf34..ab6d10d09 100644 --- a/NzbDrone.Core/Notifications/NotificationRepository.cs +++ b/NzbDrone.Core/Notifications/NotificationRepository.cs @@ -1,7 +1,6 @@ using System; using System.Linq; using NzbDrone.Core.Datastore; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; diff --git a/NzbDrone.Core/Notifications/NotificationService.cs b/NzbDrone.Core/Notifications/NotificationService.cs index 366129433..0553f4669 100644 --- a/NzbDrone.Core/Notifications/NotificationService.cs +++ b/NzbDrone.Core/Notifications/NotificationService.cs @@ -6,7 +6,6 @@ using NzbDrone.Common.Composition; using NzbDrone.Common.Serializer; using NzbDrone.Core.Download; using NzbDrone.Core.MediaFiles.Events; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Tv; using Omu.ValueInjecter; diff --git a/NzbDrone.Core/Notifications/NotificationSettingsProvider.cs b/NzbDrone.Core/Notifications/NotificationSettingsProvider.cs index 2ee5d7443..53f4d8a58 100644 --- a/NzbDrone.Core/Notifications/NotificationSettingsProvider.cs +++ b/NzbDrone.Core/Notifications/NotificationSettingsProvider.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using NzbDrone.Common.Serializer; namespace NzbDrone.Core.Notifications { @@ -25,7 +25,7 @@ namespace NzbDrone.Core.Notifications return new TSetting(); } - return JsonConvert.DeserializeObject(indexerDef.Settings); + return Json.Deserialize(indexerDef.Settings); } } } \ No newline at end of file diff --git a/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroid.cs b/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroid.cs new file mode 100644 index 000000000..22f4656f7 --- /dev/null +++ b/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroid.cs @@ -0,0 +1,47 @@ +using NzbDrone.Core.Tv; + +namespace NzbDrone.Core.Notifications.NotifyMyAndroid +{ + public class NotifyMyAndroid : NotificationBase + { + private readonly INotifyMyAndroidProxy _notifyMyAndroidProxy; + + public NotifyMyAndroid(INotifyMyAndroidProxy notifyMyAndroidProxy) + { + _notifyMyAndroidProxy = notifyMyAndroidProxy; + } + + public override string Name + { + get { return "NotifyMyAndroid"; } + } + + public override string ImplementationName + { + get { return "NotifyMyAndroid"; } + } + + public override string Link + { + get { return "http://www.notifymyandroid.com/"; } + } + + public override void OnGrab(string message) + { + const string title = "Episode Grabbed"; + + _notifyMyAndroidProxy.SendNotification(title, message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority); + } + + public override void OnDownload(string message, Series series) + { + const string title = "Episode Downloaded"; + + _notifyMyAndroidProxy.SendNotification(title, message, Settings.ApiKey, (NotifyMyAndroidPriority)Settings.Priority); + } + + public override void AfterRename(Series series) + { + } + } +} diff --git a/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroidPriority.cs b/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroidPriority.cs new file mode 100644 index 000000000..fd91e91d5 --- /dev/null +++ b/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroidPriority.cs @@ -0,0 +1,11 @@ +namespace NzbDrone.Core.Notifications.NotifyMyAndroid +{ + public enum NotifyMyAndroidPriority + { + VeryLow = -2, + Moderate = -1, + Normal = 0, + High = 1, + Emergency = 2 + } +} diff --git a/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroidProxy.cs b/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroidProxy.cs new file mode 100644 index 000000000..76ae52d98 --- /dev/null +++ b/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroidProxy.cs @@ -0,0 +1,67 @@ +using System; +using System.Linq; +using System.Net; +using System.Xml.Linq; +using NzbDrone.Core.Exceptions; +using NzbDrone.Core.Messaging.Commands; +using RestSharp; +using NzbDrone.Core.Rest; + +namespace NzbDrone.Core.Notifications.NotifyMyAndroid +{ + public interface INotifyMyAndroidProxy + { + void SendNotification(string title, string message, string apiKye, NotifyMyAndroidPriority priority); + } + + public class NotifyMyAndroidProxy : INotifyMyAndroidProxy, IExecute + { + private const string URL = "https://www.notifymyandroid.com/publicapi"; + + public void SendNotification(string title, string message, string apiKey, NotifyMyAndroidPriority priority) + { + var client = new RestClient(URL); + var request = new RestRequest("notify", Method.POST); + request.RequestFormat = DataFormat.Xml; + request.AddParameter("apikey", apiKey); + request.AddParameter("application", "NzbDrone"); + request.AddParameter("event", title); + request.AddParameter("description", message); + request.AddParameter("priority", (int)priority); + + var response = client.ExecuteAndValidate(request); + ValidateResponse(response); + } + + private void Verify(string apiKey) + { + var client = new RestClient(URL); + var request = new RestRequest("verify", Method.GET); + request.RequestFormat = DataFormat.Xml; + request.AddParameter("apikey", apiKey, ParameterType.GetOrPost); + + var response = client.ExecuteAndValidate(request); + ValidateResponse(response); + } + + private void ValidateResponse(IRestResponse response) + { + var xDoc = XDocument.Parse(response.Content); + var nma = xDoc.Descendants("nma").Single(); + var error = nma.Descendants("error").SingleOrDefault(); + + if (error != null) + { + ((HttpStatusCode)Convert.ToInt32(error.Attribute("code").Value)).VerifyStatusCode(error.Value); + } + } + + public void Execute(TestNotifyMyAndroidCommand message) + { + const string title = "Test Notification"; + const string body = "This is a test message from NzbDrone"; + Verify(message.ApiKey); + SendNotification(title, body, message.ApiKey, (NotifyMyAndroidPriority)message.Priority); + } + } +} diff --git a/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroidSettings.cs b/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroidSettings.cs new file mode 100644 index 000000000..c8c941239 --- /dev/null +++ b/NzbDrone.Core/Notifications/NotifyMyAndroid/NotifyMyAndroidSettings.cs @@ -0,0 +1,22 @@ +using System; +using NzbDrone.Core.Annotations; + +namespace NzbDrone.Core.Notifications.NotifyMyAndroid +{ + public class NotifyMyAndroidSettings : INotifcationSettings + { + [FieldDefinition(0, Label = "API Key", HelpLink = "http://www.notifymyandroid.com/")] + public String ApiKey { get; set; } + + [FieldDefinition(1, Label = "Priority", Type = FieldType.Select, SelectOptions = typeof(NotifyMyAndroidPriority))] + public Int32 Priority { get; set; } + + public bool IsValid + { + get + { + return !String.IsNullOrWhiteSpace(ApiKey) && Priority != null & Priority >= -1 && Priority <= 2; + } + } + } +} diff --git a/NzbDrone.Core/Notifications/NotifyMyAndroid/TestNotifyMyAndroidCommand.cs b/NzbDrone.Core/Notifications/NotifyMyAndroid/TestNotifyMyAndroidCommand.cs new file mode 100644 index 000000000..bb93b8fdd --- /dev/null +++ b/NzbDrone.Core/Notifications/NotifyMyAndroid/TestNotifyMyAndroidCommand.cs @@ -0,0 +1,18 @@ +using NzbDrone.Core.Messaging.Commands; + +namespace NzbDrone.Core.Notifications.NotifyMyAndroid +{ + public class TestNotifyMyAndroidCommand : Command + { + + public override bool SendUpdatesToClient + { + get + { + return true; + } + } + public string ApiKey { get; set; } + public int Priority { get; set; } + } +} diff --git a/NzbDrone.Core/Notifications/Plex/PlexService.cs b/NzbDrone.Core/Notifications/Plex/PlexService.cs index 5a5bc82e3..9ff7abc03 100644 --- a/NzbDrone.Core/Notifications/Plex/PlexService.cs +++ b/NzbDrone.Core/Notifications/Plex/PlexService.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Xml.Linq; using NLog; using NzbDrone.Common; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; namespace NzbDrone.Core.Notifications.Plex diff --git a/NzbDrone.Core/Notifications/Prowl/ProwlService.cs b/NzbDrone.Core/Notifications/Prowl/ProwlService.cs index e8c080f75..eb452f50a 100644 --- a/NzbDrone.Core/Notifications/Prowl/ProwlService.cs +++ b/NzbDrone.Core/Notifications/Prowl/ProwlService.cs @@ -1,6 +1,5 @@ using System; using NLog; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; using Prowlin; diff --git a/NzbDrone.Core/Notifications/PushBullet/PushBullet.cs b/NzbDrone.Core/Notifications/PushBullet/PushBullet.cs new file mode 100644 index 000000000..82c058729 --- /dev/null +++ b/NzbDrone.Core/Notifications/PushBullet/PushBullet.cs @@ -0,0 +1,47 @@ +using NzbDrone.Core.Tv; + +namespace NzbDrone.Core.Notifications.PushBullet +{ + public class PushBullet : NotificationBase + { + private readonly IPushBulletProxy _pushBulletProxy; + + public PushBullet(IPushBulletProxy pushBulletProxy) + { + _pushBulletProxy = pushBulletProxy; + } + + public override string Name + { + get { return "PushBullet"; } + } + + public override string ImplementationName + { + get { return "PushBullet"; } + } + + public override string Link + { + get { return "https://www.pushbullet.com/"; } + } + + public override void OnGrab(string message) + { + const string title = "Episode Grabbed"; + + _pushBulletProxy.SendNotification(title, message, Settings.ApiKey, Settings.DeviceId); + } + + public override void OnDownload(string message, Series series) + { + const string title = "Episode Downloaded"; + + _pushBulletProxy.SendNotification(title, message, Settings.ApiKey, Settings.DeviceId); + } + + public override void AfterRename(Series series) + { + } + } +} diff --git a/NzbDrone.Core/Notifications/PushBullet/PushBulletProxy.cs b/NzbDrone.Core/Notifications/PushBullet/PushBulletProxy.cs new file mode 100644 index 000000000..edeed98c4 --- /dev/null +++ b/NzbDrone.Core/Notifications/PushBullet/PushBulletProxy.cs @@ -0,0 +1,38 @@ +using System; +using NzbDrone.Core.Messaging.Commands; +using RestSharp; +using NzbDrone.Core.Rest; + +namespace NzbDrone.Core.Notifications.PushBullet +{ + public interface IPushBulletProxy + { + void SendNotification(string title, string message, string apiKey, int deviceId); + } + + public class PushBulletProxy : IPushBulletProxy, IExecute + { + private const string URL = "https://www.pushbullet.com/api/pushes"; + + public void SendNotification(string title, string message, string apiKey, int deviceId) + { + var client = new RestClient(URL); + var request = new RestRequest(Method.POST); + request.AddParameter("device_id", deviceId); + request.AddParameter("type", "note"); + request.AddParameter("title", title); + request.AddParameter("body", message); + + client.Authenticator = new HttpBasicAuthenticator(apiKey, String.Empty); + client.ExecuteAndValidate(request); + } + + public void Execute(TestPushBulletCommand message) + { + const string title = "Test Notification"; + const string body = "This is a test message from NzbDrone"; + + SendNotification(title, body, message.ApiKey, message.DeviceId); + } + } +} diff --git a/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs b/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs new file mode 100644 index 000000000..f7a492622 --- /dev/null +++ b/NzbDrone.Core/Notifications/PushBullet/PushBulletSettings.cs @@ -0,0 +1,22 @@ +using System; +using NzbDrone.Core.Annotations; + +namespace NzbDrone.Core.Notifications.PushBullet +{ + public class PushBulletSettings : INotifcationSettings + { + [FieldDefinition(0, Label = "API Key", HelpLink = "https://www.pushbullet.com/")] + public String ApiKey { get; set; } + + [FieldDefinition(1, Label = "Device ID")] + public Int32 DeviceId { get; set; } + + public bool IsValid + { + get + { + return !String.IsNullOrWhiteSpace(ApiKey) && DeviceId > 0; + } + } + } +} diff --git a/NzbDrone.Core/Notifications/PushBullet/TestPushBulletCommand.cs b/NzbDrone.Core/Notifications/PushBullet/TestPushBulletCommand.cs new file mode 100644 index 000000000..715be4661 --- /dev/null +++ b/NzbDrone.Core/Notifications/PushBullet/TestPushBulletCommand.cs @@ -0,0 +1,18 @@ +using NzbDrone.Core.Messaging.Commands; + +namespace NzbDrone.Core.Notifications.PushBullet +{ + public class TestPushBulletCommand : Command + { + + public override bool SendUpdatesToClient + { + get + { + return true; + } + } + public string ApiKey { get; set; } + public int DeviceId { get; set; } + } +} diff --git a/NzbDrone.Core/Notifications/Pushover/PushoverService.cs b/NzbDrone.Core/Notifications/Pushover/PushoverService.cs index 7e5725711..9813b9464 100644 --- a/NzbDrone.Core/Notifications/Pushover/PushoverService.cs +++ b/NzbDrone.Core/Notifications/Pushover/PushoverService.cs @@ -1,5 +1,4 @@ -using NzbDrone.Core.Messaging; -using NzbDrone.Core.Messaging.Commands; +using NzbDrone.Core.Messaging.Commands; using RestSharp; using NzbDrone.Core.Rest; diff --git a/NzbDrone.Core/Notifications/Xbmc/HttpApiProvider.cs b/NzbDrone.Core/Notifications/Xbmc/HttpApiProvider.cs index d03f88473..e0a2fa260 100644 --- a/NzbDrone.Core/Notifications/Xbmc/HttpApiProvider.cs +++ b/NzbDrone.Core/Notifications/Xbmc/HttpApiProvider.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Xml.Linq; using NLog; using NzbDrone.Common; -using NzbDrone.Core.Model.Xbmc; +using NzbDrone.Core.Notifications.Xbmc.Model; using NzbDrone.Core.Tv; namespace NzbDrone.Core.Notifications.Xbmc diff --git a/NzbDrone.Core/Notifications/Xbmc/IApiProvider.cs b/NzbDrone.Core/Notifications/Xbmc/IApiProvider.cs index a3ca85b71..28456249a 100644 --- a/NzbDrone.Core/Notifications/Xbmc/IApiProvider.cs +++ b/NzbDrone.Core/Notifications/Xbmc/IApiProvider.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using NzbDrone.Core.Model.Xbmc; +using NzbDrone.Core.Notifications.Xbmc.Model; using NzbDrone.Core.Tv; namespace NzbDrone.Core.Notifications.Xbmc diff --git a/NzbDrone.Core/Notifications/Xbmc/JsonApiProvider.cs b/NzbDrone.Core/Notifications/Xbmc/JsonApiProvider.cs index 1d7cb5377..f7fb1ed3b 100644 --- a/NzbDrone.Core/Notifications/Xbmc/JsonApiProvider.cs +++ b/NzbDrone.Core/Notifications/Xbmc/JsonApiProvider.cs @@ -2,10 +2,10 @@ using System.Collections.Generic; using System.Linq; using NLog; -using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NzbDrone.Common; -using NzbDrone.Core.Model.Xbmc; +using NzbDrone.Common.Serializer; +using NzbDrone.Core.Notifications.Xbmc.Model; using NzbDrone.Core.Tv; namespace NzbDrone.Core.Notifications.Xbmc @@ -72,7 +72,7 @@ namespace NzbDrone.Core.Notifications.Xbmc if (CheckForError(response)) return new List(); - var result = JsonConvert.DeserializeObject(response); + var result = Json.Deserialize(response); return result.Result; } @@ -97,7 +97,7 @@ namespace NzbDrone.Core.Notifications.Xbmc if (response.StartsWith("{\"error\"")) { - var error = JsonConvert.DeserializeObject(response); + var error = Json.Deserialize(response); var code = error.Error["code"]; var message = error.Error["message"]; @@ -159,7 +159,7 @@ namespace NzbDrone.Core.Notifications.Xbmc if (CheckForError(response)) return; _logger.Trace(" from response"); - var result = JsonConvert.DeserializeObject>(response); + var result = Json.Deserialize>(response); if (!result.Result.Equals("OK", StringComparison.InvariantCultureIgnoreCase)) { @@ -185,7 +185,7 @@ namespace NzbDrone.Core.Notifications.Xbmc if (CheckForError(response)) return new List(); - var result = JsonConvert.DeserializeObject(response); + var result = Json.Deserialize(response); var shows = result.Result.TvShows; return shows; diff --git a/NzbDrone.Core/Notifications/Xbmc/Model/ActivePlayer.cs b/NzbDrone.Core/Notifications/Xbmc/Model/ActivePlayer.cs new file mode 100644 index 000000000..ad4dafb68 --- /dev/null +++ b/NzbDrone.Core/Notifications/Xbmc/Model/ActivePlayer.cs @@ -0,0 +1,14 @@ +namespace NzbDrone.Core.Notifications.Xbmc.Model +{ + public class ActivePlayer + { + public int PlayerId { get; set; } + public string Type { get; set; } + + public ActivePlayer(int playerId, string type) + { + PlayerId = playerId; + Type = type; + } + } +} diff --git a/NzbDrone.Core/Model/Xbmc/ActivePlayersDharmaResult.cs b/NzbDrone.Core/Notifications/Xbmc/Model/ActivePlayersDharmaResult.cs similarity index 83% rename from NzbDrone.Core/Model/Xbmc/ActivePlayersDharmaResult.cs rename to NzbDrone.Core/Notifications/Xbmc/Model/ActivePlayersDharmaResult.cs index a88e190d3..49d942cc2 100644 --- a/NzbDrone.Core/Model/Xbmc/ActivePlayersDharmaResult.cs +++ b/NzbDrone.Core/Notifications/Xbmc/Model/ActivePlayersDharmaResult.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace NzbDrone.Core.Model.Xbmc +namespace NzbDrone.Core.Notifications.Xbmc.Model { public class ActivePlayersDharmaResult { diff --git a/NzbDrone.Core/Notifications/Xbmc/Model/ActivePlayersEdenResult.cs b/NzbDrone.Core/Notifications/Xbmc/Model/ActivePlayersEdenResult.cs new file mode 100644 index 000000000..2f3cc61d8 --- /dev/null +++ b/NzbDrone.Core/Notifications/Xbmc/Model/ActivePlayersEdenResult.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace NzbDrone.Core.Notifications.Xbmc.Model +{ + public class ActivePlayersEdenResult + { + public string Id { get; set; } + public string JsonRpc { get; set; } + public List Result { get; set; } + } +} \ No newline at end of file diff --git a/NzbDrone.Core/Model/Xbmc/ErrorResult.cs b/NzbDrone.Core/Notifications/Xbmc/Model/ErrorResult.cs similarity index 82% rename from NzbDrone.Core/Model/Xbmc/ErrorResult.cs rename to NzbDrone.Core/Notifications/Xbmc/Model/ErrorResult.cs index 42f609e7c..8de9b7c58 100644 --- a/NzbDrone.Core/Model/Xbmc/ErrorResult.cs +++ b/NzbDrone.Core/Notifications/Xbmc/Model/ErrorResult.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace NzbDrone.Core.Model.Xbmc +namespace NzbDrone.Core.Notifications.Xbmc.Model { public class ErrorResult { diff --git a/NzbDrone.Core/Model/Xbmc/TvShow.cs b/NzbDrone.Core/Notifications/Xbmc/Model/TvShow.cs similarity index 80% rename from NzbDrone.Core/Model/Xbmc/TvShow.cs rename to NzbDrone.Core/Notifications/Xbmc/Model/TvShow.cs index 74d0cb3d6..318167d37 100644 --- a/NzbDrone.Core/Model/Xbmc/TvShow.cs +++ b/NzbDrone.Core/Notifications/Xbmc/Model/TvShow.cs @@ -1,4 +1,4 @@ -namespace NzbDrone.Core.Model.Xbmc +namespace NzbDrone.Core.Notifications.Xbmc.Model { public class TvShow { diff --git a/NzbDrone.Core/Model/Xbmc/TvShowResponse.cs b/NzbDrone.Core/Notifications/Xbmc/Model/TvShowResponse.cs similarity index 77% rename from NzbDrone.Core/Model/Xbmc/TvShowResponse.cs rename to NzbDrone.Core/Notifications/Xbmc/Model/TvShowResponse.cs index 4f6ae929a..079ede558 100644 --- a/NzbDrone.Core/Model/Xbmc/TvShowResponse.cs +++ b/NzbDrone.Core/Notifications/Xbmc/Model/TvShowResponse.cs @@ -1,4 +1,4 @@ -namespace NzbDrone.Core.Model.Xbmc +namespace NzbDrone.Core.Notifications.Xbmc.Model { public class TvShowResponse { diff --git a/NzbDrone.Core/Model/Xbmc/TvShowResult.cs b/NzbDrone.Core/Notifications/Xbmc/Model/TvShowResult.cs similarity index 78% rename from NzbDrone.Core/Model/Xbmc/TvShowResult.cs rename to NzbDrone.Core/Notifications/Xbmc/Model/TvShowResult.cs index e9af56d1e..4e1a8074f 100644 --- a/NzbDrone.Core/Model/Xbmc/TvShowResult.cs +++ b/NzbDrone.Core/Notifications/Xbmc/Model/TvShowResult.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace NzbDrone.Core.Model.Xbmc +namespace NzbDrone.Core.Notifications.Xbmc.Model { public class TvShowResult { diff --git a/NzbDrone.Core/Model/Xbmc/VersionResult.cs b/NzbDrone.Core/Notifications/Xbmc/Model/VersionResult.cs similarity index 82% rename from NzbDrone.Core/Model/Xbmc/VersionResult.cs rename to NzbDrone.Core/Notifications/Xbmc/Model/VersionResult.cs index cc40e6004..01ad8c8e7 100644 --- a/NzbDrone.Core/Model/Xbmc/VersionResult.cs +++ b/NzbDrone.Core/Notifications/Xbmc/Model/VersionResult.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace NzbDrone.Core.Model.Xbmc +namespace NzbDrone.Core.Notifications.Xbmc.Model { public class VersionResult { diff --git a/NzbDrone.Core/Model/Xbmc/XbmcJsonResult.cs b/NzbDrone.Core/Notifications/Xbmc/Model/XbmcJsonResult.cs similarity index 76% rename from NzbDrone.Core/Model/Xbmc/XbmcJsonResult.cs rename to NzbDrone.Core/Notifications/Xbmc/Model/XbmcJsonResult.cs index 27cf8f749..d69dc4902 100644 --- a/NzbDrone.Core/Model/Xbmc/XbmcJsonResult.cs +++ b/NzbDrone.Core/Notifications/Xbmc/Model/XbmcJsonResult.cs @@ -1,4 +1,4 @@ -namespace NzbDrone.Core.Model.Xbmc +namespace NzbDrone.Core.Notifications.Xbmc.Model { public class XbmcJsonResult { diff --git a/NzbDrone.Core/Model/Xbmc/XbmcVersion.cs b/NzbDrone.Core/Notifications/Xbmc/Model/XbmcVersion.cs similarity index 98% rename from NzbDrone.Core/Model/Xbmc/XbmcVersion.cs rename to NzbDrone.Core/Notifications/Xbmc/Model/XbmcVersion.cs index 2fc1e8e7f..14c7c892d 100644 --- a/NzbDrone.Core/Model/Xbmc/XbmcVersion.cs +++ b/NzbDrone.Core/Notifications/Xbmc/Model/XbmcVersion.cs @@ -1,6 +1,6 @@ using System; -namespace NzbDrone.Core.Model.Xbmc +namespace NzbDrone.Core.Notifications.Xbmc.Model { public class XbmcVersion : IComparable { diff --git a/NzbDrone.Core/Notifications/Xbmc/XbmcService.cs b/NzbDrone.Core/Notifications/Xbmc/XbmcService.cs index bbc8a237a..3ffbeba98 100644 --- a/NzbDrone.Core/Notifications/Xbmc/XbmcService.cs +++ b/NzbDrone.Core/Notifications/Xbmc/XbmcService.cs @@ -1,15 +1,14 @@ using System; using System.Collections.Generic; using System.Linq; -using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NLog; using NzbDrone.Common; using NzbDrone.Common.Instrumentation; -using NzbDrone.Core.Messaging; +using NzbDrone.Common.Serializer; using NzbDrone.Core.Messaging.Commands; +using NzbDrone.Core.Notifications.Xbmc.Model; using NzbDrone.Core.Tv; -using NzbDrone.Core.Model.Xbmc; namespace NzbDrone.Core.Notifications.Xbmc { @@ -63,7 +62,7 @@ namespace NzbDrone.Core.Notifications.Xbmc var response = _httpProvider.PostCommand(settings.Address, settings.Username, settings.Password, postJson.ToString()); Logger.Trace("Getting version from response"); - var result = JsonConvert.DeserializeObject>(response); + var result = Json.Deserialize>(response); var versionObject = result.Result.Property("version"); @@ -71,7 +70,7 @@ namespace NzbDrone.Core.Notifications.Xbmc return new XbmcVersion((int)versionObject.Value); if (versionObject.Value.Type == JTokenType.Object) - return JsonConvert.DeserializeObject(versionObject.Value.ToString()); + return Json.Deserialize(versionObject.Value.ToString()); throw new InvalidCastException("Unknown Version structure!: " + versionObject); } diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index dae681ba9..08803f3fa 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -96,8 +96,9 @@ False ..\packages\Prowlin.0.9.4456.26422\lib\net40\Prowlin.dll - - ..\packages\RestSharp.104.1\lib\net4\RestSharp.dll + + False + ..\packages\RestSharp.104.2.0\lib\net4\RestSharp.dll @@ -131,6 +132,12 @@ + + + + + + @@ -210,6 +217,15 @@ + + + + + + + + + @@ -245,7 +261,15 @@ - + + + + + + + + + @@ -256,6 +280,16 @@ + + + + + + + + + + @@ -292,7 +326,6 @@ - @@ -317,7 +350,6 @@ - @@ -361,8 +393,7 @@ - - + @@ -371,7 +402,6 @@ - @@ -382,7 +412,6 @@ - @@ -399,7 +428,6 @@ - @@ -411,15 +439,6 @@ - - - - - - - - - @@ -427,11 +446,6 @@ - - - - - diff --git a/NzbDrone.Core/Parser/Model/RemoteEpisode.cs b/NzbDrone.Core/Parser/Model/RemoteEpisode.cs index ac394d0d8..f87f71c8e 100644 --- a/NzbDrone.Core/Parser/Model/RemoteEpisode.cs +++ b/NzbDrone.Core/Parser/Model/RemoteEpisode.cs @@ -8,12 +8,10 @@ namespace NzbDrone.Core.Parser.Model public class RemoteEpisode { public ReleaseInfo Release { get; set; } - public ParsedEpisodeInfo ParsedEpisodeInfo { get; set; } - public Series Series { get; set; } - public List Episodes { get; set; } + public Boolean DownloadAllowed { get; set; } public bool IsRecentEpisode() { diff --git a/NzbDrone.Core/ProgressMessaging/ProgressMessageTarget.cs b/NzbDrone.Core/ProgressMessaging/ProgressMessageTarget.cs index 49c20b0b2..13d4ae0de 100644 --- a/NzbDrone.Core/ProgressMessaging/ProgressMessageTarget.cs +++ b/NzbDrone.Core/ProgressMessaging/ProgressMessageTarget.cs @@ -2,7 +2,6 @@ using NLog; using NLog.Targets; using NzbDrone.Core.Lifecycle; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Commands.Tracking; using NzbDrone.Core.Messaging.Events; diff --git a/NzbDrone.Core/Providers/UpdateXemMappingsCommand.cs b/NzbDrone.Core/Providers/UpdateXemMappingsCommand.cs deleted file mode 100644 index a30c0c70d..000000000 --- a/NzbDrone.Core/Providers/UpdateXemMappingsCommand.cs +++ /dev/null @@ -1,14 +0,0 @@ -using NzbDrone.Core.Messaging.Commands; - -namespace NzbDrone.Core.Providers -{ - public class UpdateXemMappingsCommand : Command - { - public int? SeriesId { get; set; } - - public UpdateXemMappingsCommand(int? seriesId) - { - SeriesId = seriesId; - } - } -} \ No newline at end of file diff --git a/NzbDrone.Core/Providers/XemCommunicationProvider.cs b/NzbDrone.Core/Providers/XemCommunicationProvider.cs deleted file mode 100644 index 5c0e07132..000000000 --- a/NzbDrone.Core/Providers/XemCommunicationProvider.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using NLog; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using NzbDrone.Common; -using NzbDrone.Common.Instrumentation; -using NzbDrone.Core.Model.Xem; - -namespace NzbDrone.Core.Providers -{ - public interface IXemCommunicationProvider - { - List GetXemSeriesIds(string origin = "tvdb"); - List GetSceneTvdbMappings(int id); - void CheckForFailureResult(string response); - } - - public class XemCommunicationProvider : IXemCommunicationProvider - { - private readonly IHttpProvider _httpProvider; - - private static readonly Logger _logger = NzbDroneLogger.GetLogger(); - - private const string XEM_BASE_URL = "http://thexem.de/map/"; - - public XemCommunicationProvider(IHttpProvider httpProvider) - { - _httpProvider = httpProvider; - } - - public List GetXemSeriesIds(string origin = "tvdb") - { - _logger.Trace("Fetching Series IDs from: {0}", origin); - - var url = String.Format("{0}havemap?origin={1}", XEM_BASE_URL, origin); - var response =_httpProvider.DownloadString(url); - - CheckForFailureResult(response); - - var result = JsonConvert.DeserializeObject>>(response); - - return result.Data.ToList(); - } - - public List GetSceneTvdbMappings(int id) - { - _logger.Trace("Fetching Mappings for: {0}", id); - var url = String.Format("{0}all?id={1}&origin=tvdb", XEM_BASE_URL, id); - var response = _httpProvider.DownloadString(url); - - CheckForFailureResult(response); - - var result = JsonConvert.DeserializeObject>(JObject.Parse(response).SelectToken("data").ToString()); - - return result; - } - - public void CheckForFailureResult(string response) - { - var result = JsonConvert.DeserializeObject>(response); - - if (result != null && result.Result.Equals("failure", StringComparison.InvariantCultureIgnoreCase)) - throw new Exception("Error response received from Xem: " + result.Message); - } - } -} diff --git a/NzbDrone.Core/Qualities/QualityProfileRepository.cs b/NzbDrone.Core/Qualities/QualityProfileRepository.cs index 64e36b70b..408cc009e 100644 --- a/NzbDrone.Core/Qualities/QualityProfileRepository.cs +++ b/NzbDrone.Core/Qualities/QualityProfileRepository.cs @@ -1,5 +1,4 @@ using NzbDrone.Core.Datastore; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; diff --git a/NzbDrone.Core/Qualities/QualityProfileService.cs b/NzbDrone.Core/Qualities/QualityProfileService.cs index de79e36e9..82baaaa39 100644 --- a/NzbDrone.Core/Qualities/QualityProfileService.cs +++ b/NzbDrone.Core/Qualities/QualityProfileService.cs @@ -2,7 +2,6 @@ using System.Linq; using NLog; using NzbDrone.Core.Lifecycle; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Tv; diff --git a/NzbDrone.Core/Qualities/QualitySizeRepository.cs b/NzbDrone.Core/Qualities/QualitySizeRepository.cs index 84a21355d..f96f84be3 100644 --- a/NzbDrone.Core/Qualities/QualitySizeRepository.cs +++ b/NzbDrone.Core/Qualities/QualitySizeRepository.cs @@ -1,7 +1,6 @@ using System; using System.Linq; using NzbDrone.Core.Datastore; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; diff --git a/NzbDrone.Core/Qualities/QualitySizeService.cs b/NzbDrone.Core/Qualities/QualitySizeService.cs index c7719ef8b..0671a6c10 100644 --- a/NzbDrone.Core/Qualities/QualitySizeService.cs +++ b/NzbDrone.Core/Qualities/QualitySizeService.cs @@ -2,7 +2,6 @@ using System.Linq; using NLog; using NzbDrone.Core.Lifecycle; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; namespace NzbDrone.Core.Qualities @@ -10,7 +9,6 @@ namespace NzbDrone.Core.Qualities public interface IQualitySizeService { void Update(QualitySize qualitySize); - void UpdateAll(List qualitySizes); List All(); QualitySize Get(int qualityId); } @@ -31,10 +29,6 @@ namespace NzbDrone.Core.Qualities _qualitySizeRepository.Update(qualitySize); } - public virtual void UpdateAll(List qualitySizes) - { - _qualitySizeRepository.UpdateMany(qualitySizes); - } public virtual List All() { diff --git a/NzbDrone.Core/Rest/RestSharpExtensions.cs b/NzbDrone.Core/Rest/RestSharpExtensions.cs index 33b5e681b..2a25a1222 100644 --- a/NzbDrone.Core/Rest/RestSharpExtensions.cs +++ b/NzbDrone.Core/Rest/RestSharpExtensions.cs @@ -62,7 +62,6 @@ namespace NzbDrone.Core.Rest return client.Execute(request).ValidateResponse(client); } - public static void AddQueryString(this IRestRequest request, string name, object value) { request.AddParameter(name, value.ToString(), ParameterType.GetOrPost); diff --git a/NzbDrone.Core/Tv/EpisodeRepository.cs b/NzbDrone.Core/Tv/EpisodeRepository.cs index cd12016ed..3a9ade8d9 100644 --- a/NzbDrone.Core/Tv/EpisodeRepository.cs +++ b/NzbDrone.Core/Tv/EpisodeRepository.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using Marr.Data.QGen; using NzbDrone.Core.Datastore; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; @@ -11,7 +10,6 @@ namespace NzbDrone.Core.Tv { public interface IEpisodeRepository : IBasicRepository { - Episode Get(int seriesId, int season, int episodeNumber); Episode Find(int seriesId, int season, int episodeNumber); Episode Get(int seriesId, DateTime date); Episode Find(int seriesId, DateTime date); @@ -19,9 +17,7 @@ namespace NzbDrone.Core.Tv List GetEpisodes(int seriesId, int seasonNumber); List GetEpisodeByFileId(int fileId); PagingSpec EpisodesWithoutFiles(PagingSpec pagingSpec, bool includeSpecials); - Episode GetEpisodeBySceneNumbering(int seriesId, int seasonNumber, int episodeNumber); Episode FindEpisodeBySceneNumbering(int seriesId, int seasonNumber, int episodeNumber); - List EpisodesWithFiles(); List EpisodesBetweenDates(DateTime startDate, DateTime endDate); void SetMonitoredFlat(Episode episode, bool monitored); void SetMonitoredBySeason(int seriesId, int seasonNumber, bool monitored); @@ -38,11 +34,6 @@ namespace NzbDrone.Core.Tv _database = database; } - public Episode Get(int seriesId, int season, int episodeNumber) - { - return Query.Single(s => s.SeriesId == seriesId && s.SeasonNumber == season && s.EpisodeNumber == episodeNumber); - } - public Episode Find(int seriesId, int season, int episodeNumber) { return Query.SingleOrDefault(s => s.SeriesId == seriesId && s.SeasonNumber == season && s.EpisodeNumber == episodeNumber); @@ -89,20 +80,11 @@ namespace NzbDrone.Core.Tv return pagingSpec; } - public Episode GetEpisodeBySceneNumbering(int seriesId, int seasonNumber, int episodeNumber) - { - return Query.Single(s => s.SeriesId == seriesId && s.SceneSeasonNumber == seasonNumber && s.SceneEpisodeNumber == episodeNumber); - } - public Episode FindEpisodeBySceneNumbering(int seriesId, int seasonNumber, int episodeNumber) { return Query.SingleOrDefault(s => s.SeriesId == seriesId && s.SceneSeasonNumber == seasonNumber && s.SceneEpisodeNumber == episodeNumber); } - public List EpisodesWithFiles() - { - return Query.Where(s => s.EpisodeFileId != 0).ToList(); - } public List EpisodesBetweenDates(DateTime startDate, DateTime endDate) { diff --git a/NzbDrone.Core/Tv/EpisodeService.cs b/NzbDrone.Core/Tv/EpisodeService.cs index 8d3f3ccd2..8bd88187d 100644 --- a/NzbDrone.Core/Tv/EpisodeService.cs +++ b/NzbDrone.Core/Tv/EpisodeService.cs @@ -2,11 +2,9 @@ using System; using System.Collections.Generic; using System.Linq; using NLog; -using NzbDrone.Common.Instrumentation; using NzbDrone.Core.Configuration; using NzbDrone.Core.Datastore; using NzbDrone.Core.MediaFiles.Events; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Tv.Events; @@ -15,7 +13,6 @@ namespace NzbDrone.Core.Tv public interface IEpisodeService { Episode GetEpisode(int id); - Episode GetEpisode(int seriesId, int seasonNumber, int episodeNumber, bool useScene = false); Episode FindEpisode(int seriesId, int seasonNumber, int episodeNumber, bool useScene = false); Episode GetEpisode(int seriesId, DateTime date); Episode FindEpisode(int seriesId, DateTime date); @@ -23,9 +20,7 @@ namespace NzbDrone.Core.Tv List GetEpisodesBySeason(int seriesId, int seasonNumber); PagingSpec EpisodesWithoutFiles(PagingSpec pagingSpec); List GetEpisodesByFileId(int episodeFileId); - List EpisodesWithFiles(); void UpdateEpisode(Episode episode); - List GetEpisodeNumbersBySeason(int seriesId, int seasonNumber); void SetEpisodeMonitored(int episodeId, bool monitored); bool IsFirstOrLastEpisodeOfSeason(int episodeId); void UpdateEpisodes(List episodes); @@ -42,8 +37,6 @@ namespace NzbDrone.Core.Tv IHandleAsync { - private static readonly Logger logger = NzbDroneLogger.GetLogger(); - private readonly IEpisodeRepository _episodeRepository; private readonly IConfigService _configService; private readonly Logger _logger; @@ -60,15 +53,6 @@ namespace NzbDrone.Core.Tv return _episodeRepository.Get(id); } - public Episode GetEpisode(int seriesId, int seasonNumber, int episodeNumber, bool useSceneNumbering = false) - { - if (useSceneNumbering) - { - return _episodeRepository.GetEpisodeBySceneNumbering(seriesId, seasonNumber, episodeNumber); - } - return _episodeRepository.Find(seriesId, seasonNumber, episodeNumber); - } - public Episode FindEpisode(int seriesId, int seasonNumber, int episodeNumber, bool useSceneNumbering = false) { if (useSceneNumbering) @@ -110,27 +94,17 @@ namespace NzbDrone.Core.Tv return _episodeRepository.GetEpisodeByFileId(episodeFileId); } - public List EpisodesWithFiles() - { - return _episodeRepository.EpisodesWithFiles(); - } - public void UpdateEpisode(Episode episode) { _episodeRepository.Update(episode); } - public List GetEpisodeNumbersBySeason(int seriesId, int seasonNumber) - { - return GetEpisodesBySeason(seriesId, seasonNumber).Select(c => c.Id).ToList(); - } - public void SetEpisodeMonitored(int episodeId, bool monitored) { var episode = _episodeRepository.Get(episodeId); _episodeRepository.SetMonitoredFlat(episode, monitored); - logger.Debug("Monitored flag for Episode:{0} was set to {1}", episodeId, monitored); + _logger.Debug("Monitored flag for Episode:{0} was set to {1}", episodeId, monitored); } public void SetEpisodeMonitoredBySeason(int seriesId, int seasonNumber, bool monitored) diff --git a/NzbDrone.Core/Tv/RefreshEpisodeService.cs b/NzbDrone.Core/Tv/RefreshEpisodeService.cs index 5c4beb1b0..d714ddf3e 100644 --- a/NzbDrone.Core/Tv/RefreshEpisodeService.cs +++ b/NzbDrone.Core/Tv/RefreshEpisodeService.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using NLog; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Tv.Events; diff --git a/NzbDrone.Core/Tv/RefreshSeriesService.cs b/NzbDrone.Core/Tv/RefreshSeriesService.cs index d6607dda5..881c24b75 100644 --- a/NzbDrone.Core/Tv/RefreshSeriesService.cs +++ b/NzbDrone.Core/Tv/RefreshSeriesService.cs @@ -5,7 +5,6 @@ using System.Linq; using NLog; using NzbDrone.Core.DataAugmentation.DailySeries; using NzbDrone.Core.Instrumentation; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.MetadataSource; diff --git a/NzbDrone.Core/Tv/SeasonRepository.cs b/NzbDrone.Core/Tv/SeasonRepository.cs deleted file mode 100644 index 470c2e5ca..000000000 --- a/NzbDrone.Core/Tv/SeasonRepository.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using NzbDrone.Core.Datastore; -using NzbDrone.Core.Messaging; -using NzbDrone.Core.Messaging.Events; - - -namespace NzbDrone.Core.Tv -{ - public interface ISeasonRepository : IBasicRepository - { - List GetSeasonBySeries(int seriesId); - } - - public class SeasonRepository : BasicRepository, ISeasonRepository - { - public SeasonRepository(IDatabase database, IEventAggregator eventAggregator) - : base(database, eventAggregator) - { - } - - public List GetSeasonBySeries(int seriesId) - { - return Query.Single(s => s.Id == seriesId).Seasons; - } - } -} \ No newline at end of file diff --git a/NzbDrone.Core/Tv/SeriesRepository.cs b/NzbDrone.Core/Tv/SeriesRepository.cs index 161ebbac2..0c7d0288e 100644 --- a/NzbDrone.Core/Tv/SeriesRepository.cs +++ b/NzbDrone.Core/Tv/SeriesRepository.cs @@ -1,8 +1,6 @@ using System; -using System.Collections.Generic; using System.Linq; using NzbDrone.Core.Datastore; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; @@ -11,13 +9,10 @@ namespace NzbDrone.Core.Tv public interface ISeriesRepository : IBasicRepository { bool SeriesPathExists(string path); - List Search(string title); Series FindByTitle(string cleanTitle); Series FindByTvdbId(int tvdbId); Series FindByTvRageId(int tvRageId); void SetSeriesType(int seriesId, SeriesTypes seriesTypes); - Series FindBySlug(string slug); - List GetSeriesPaths(); } public class SeriesRepository : BasicRepository, ISeriesRepository @@ -32,11 +27,6 @@ namespace NzbDrone.Core.Tv return Query.Any(c => c.Path == path); } - public List Search(string title) - { - return Query.Where(s => s.Title.Contains(title)); - } - public Series FindByTitle(string cleanTitle) { return Query.SingleOrDefault(s => s.CleanTitle.Equals(cleanTitle, StringComparison.InvariantCultureIgnoreCase)); @@ -56,15 +46,5 @@ namespace NzbDrone.Core.Tv { SetFields(new Series { Id = seriesId, SeriesType = seriesType }, s => s.SeriesType); } - - public Series FindBySlug(string slug) - { - return Query.SingleOrDefault(c => c.TitleSlug == slug.ToLower()); - } - - public List GetSeriesPaths() - { - return Query.Select(s => s.Path).ToList(); - } } } \ No newline at end of file diff --git a/NzbDrone.Core/Tv/SeriesService.cs b/NzbDrone.Core/Tv/SeriesService.cs index 9e8d7ba99..7496a15e7 100644 --- a/NzbDrone.Core/Tv/SeriesService.cs +++ b/NzbDrone.Core/Tv/SeriesService.cs @@ -6,7 +6,6 @@ using NLog; using NzbDrone.Common.EnsureThat; using NzbDrone.Core.Configuration; using NzbDrone.Core.DataAugmentation.Scene; -using NzbDrone.Core.Messaging; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Organizer; using NzbDrone.Core.Tv.Events; diff --git a/NzbDrone.Core/Update/InstallUpdateService.cs b/NzbDrone.Core/Update/InstallUpdateService.cs index fd74f199c..b0088ee87 100644 --- a/NzbDrone.Core/Update/InstallUpdateService.cs +++ b/NzbDrone.Core/Update/InstallUpdateService.cs @@ -3,7 +3,7 @@ using System.IO; using NLog; using NzbDrone.Common; using NzbDrone.Common.EnvironmentInfo; -using NzbDrone.Core.Messaging; +using NzbDrone.Common.Processes; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Update.Commands; using NzbDrone.Core.Instrumentation; @@ -61,7 +61,7 @@ namespace NzbDrone.Core.Update _diskProvider.DeleteFolder(updateSandboxFolder, true); } - _logger.ProgressInfo("Downloading Updated {0} [{1}]", updatePackage.Version, updatePackage.Branch); + _logger.ProgressInfo("Downloading update {0} [{1}]", updatePackage.Version, updatePackage.Branch); _logger.Debug("Downloading update package from [{0}] to [{1}]", updatePackage.Url, packageDestination); _httpProvider.DownloadFile(updatePackage.Url, packageDestination); diff --git a/NzbDrone.Core/Update/UpdatePackage.cs b/NzbDrone.Core/Update/UpdatePackage.cs index 70ca40b87..f94a77e4b 100644 --- a/NzbDrone.Core/Update/UpdatePackage.cs +++ b/NzbDrone.Core/Update/UpdatePackage.cs @@ -1,6 +1,5 @@ using System; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; + namespace NzbDrone.Core.Update { @@ -8,7 +7,6 @@ namespace NzbDrone.Core.Update { public string Id { get; set; } - [JsonConverter(typeof(VersionConverter))] public Version Version { get; set; } public String Branch { get; set; } diff --git a/NzbDrone.Core/packages.config b/NzbDrone.Core/packages.config index 6674b3182..b0bc75532 100644 --- a/NzbDrone.Core/packages.config +++ b/NzbDrone.Core/packages.config @@ -7,6 +7,6 @@ - + \ No newline at end of file diff --git a/NzbDrone.Host/AccessControl/NetshProvider.cs b/NzbDrone.Host/AccessControl/NetshProvider.cs new file mode 100644 index 000000000..dc9e8b754 --- /dev/null +++ b/NzbDrone.Host/AccessControl/NetshProvider.cs @@ -0,0 +1,39 @@ +using System; +using NLog; +using NzbDrone.Common.Processes; + +namespace NzbDrone.Host.AccessControl +{ + public interface INetshProvider + { + ProcessOutput Run(string arguments); + } + + public class NetshProvider : INetshProvider + { + private readonly IProcessProvider _processProvider; + private readonly Logger _logger; + + public NetshProvider(IProcessProvider processProvider, Logger logger) + { + _processProvider = processProvider; + _logger = logger; + } + + public ProcessOutput Run(string arguments) + { + try + { + var output = _processProvider.StartAndCapture("netsh.exe", arguments); + + return output; + } + catch (Exception ex) + { + _logger.WarnException("Error executing netsh with arguments: " + arguments, ex); + } + + return null; + } + } +} diff --git a/NzbDrone.Host/AccessControl/SslAdapter.cs b/NzbDrone.Host/AccessControl/SslAdapter.cs new file mode 100644 index 000000000..c94e307a3 --- /dev/null +++ b/NzbDrone.Host/AccessControl/SslAdapter.cs @@ -0,0 +1,55 @@ +using System; +using System.Linq; +using NLog; +using NzbDrone.Core.Configuration; + +namespace NzbDrone.Host.AccessControl +{ + public interface ISslAdapter + { + void Register(); + } + + public class SslAdapter : ISslAdapter + { + private const string APP_ID = "C2172AF4-F9A6-4D91-BAEE-C2E4EE680613"; + + private readonly INetshProvider _netshProvider; + private readonly IConfigFileProvider _configFileProvider; + private readonly Logger _logger; + + public SslAdapter(INetshProvider netshProvider, IConfigFileProvider configFileProvider, Logger logger) + { + _netshProvider = netshProvider; + _configFileProvider = configFileProvider; + _logger = logger; + } + + public void Register() + { + if (!_configFileProvider.EnableSsl) return; + if (IsRegistered()) return; + + if (String.IsNullOrWhiteSpace(_configFileProvider.SslCertHash)) + { + _logger.Warn("Unable to enable SSL, SSL Cert Hash is required"); + return; + } + + var arguments = String.Format("netsh http add sslcert ipport=0.0.0.0:{0} certhash={1} appid={{{2}}", _configFileProvider.SslPort, _configFileProvider.SslCertHash, APP_ID); + _netshProvider.Run(arguments); + } + + private bool IsRegistered() + { + var ipPort = "0.0.0.0:" + _configFileProvider.SslPort; + var arguments = String.Format("http show sslcert ipport={0}", ipPort); + + var output = _netshProvider.Run(arguments); + + if (output == null || !output.Standard.Any()) return false; + + return output.Standard.Any(line => line.Contains(ipPort)); + } + } +} diff --git a/NzbDrone.Host/AccessControl/UrlAclAdapter.cs b/NzbDrone.Host/AccessControl/UrlAclAdapter.cs index e536fffbd..cca29eb2b 100644 --- a/NzbDrone.Host/AccessControl/UrlAclAdapter.cs +++ b/NzbDrone.Host/AccessControl/UrlAclAdapter.cs @@ -1,6 +1,6 @@ using System; +using System.Linq; using NLog; -using NzbDrone.Common; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Core.Configuration; @@ -8,56 +8,82 @@ namespace NzbDrone.Host.AccessControl { public interface IUrlAclAdapter { - void RefreshRegistration(); - string UrlAcl { get; } + void ConfigureUrl(); + string Url { get; } + string HttpsUrl { get; } } public class UrlAclAdapter : IUrlAclAdapter { - private readonly IProcessProvider _processProvider; + private readonly INetshProvider _netshProvider; private readonly IConfigFileProvider _configFileProvider; + private readonly IRuntimeInfo _runtimeInfo; private readonly Logger _logger; - public UrlAclAdapter(IProcessProvider processProvider, IConfigFileProvider configFileProvider, Logger logger) + public string Url { get; private set; } + public string HttpsUrl { get; private set; } + + private string _localUrl; + private string _wildcardUrl; + private string _localHttpsUrl; + private string _wildcardHttpsUrl; + + public UrlAclAdapter(INetshProvider netshProvider, + IConfigFileProvider configFileProvider, + IRuntimeInfo runtimeInfo, + Logger logger) { - _processProvider = processProvider; + _netshProvider = netshProvider; _configFileProvider = configFileProvider; + _runtimeInfo = runtimeInfo; _logger = logger; + + _localUrl = String.Format("http://localhost:{0}/", _configFileProvider.Port); + _wildcardUrl = String.Format("http://*:{0}/", _configFileProvider.Port); + _localHttpsUrl = String.Format("https://localhost:{0}/", _configFileProvider.SslPort); + _wildcardHttpsUrl = String.Format("https://*:{0}/", _configFileProvider.SslPort); + + Url = _wildcardUrl; + HttpsUrl = _wildcardHttpsUrl; } - public string UrlAcl + public void ConfigureUrl() { - get + if (!_runtimeInfo.IsAdmin) + { + if (!IsRegistered(_wildcardUrl)) Url = _localUrl; + if (!IsRegistered(_wildcardHttpsUrl)) HttpsUrl = _localHttpsUrl; + } + + if (_runtimeInfo.IsAdmin) { - return "http://*:" + _configFileProvider.Port + "/"; + RefreshRegistration(); } } - public void RefreshRegistration() + private void RefreshRegistration() { if (OsInfo.Version.Major < 6) return; - RegisterUrl(); + RegisterUrl(Url); + RegisterUrl(HttpsUrl); } - - private void RegisterUrl() + + private bool IsRegistered(string urlAcl) { - var arguments = String.Format("http add urlacl {0} sddl=D:(A;;GX;;;S-1-1-0)", UrlAcl); - RunNetsh(arguments); + var arguments = String.Format("http show urlacl {0}", urlAcl); + var output = _netshProvider.Run(arguments); + + if (output == null || !output.Standard.Any()) return false; + + return output.Standard.Any(line => line.Contains(urlAcl)); } - private void RunNetsh(string arguments) + private void RegisterUrl(string urlAcl) { - try - { - var process = _processProvider.Start("netsh.exe", arguments); - process.WaitForExit(5000); - } - catch (Exception ex) - { - _logger.WarnException("Error executing netsh with arguments: " + arguments, ex); - } + var arguments = String.Format("http add urlacl {0} sddl=D:(A;;GX;;;S-1-1-0)", urlAcl); + _netshProvider.Run(arguments); } } } \ No newline at end of file diff --git a/NzbDrone.Host/ApplicationServer.cs b/NzbDrone.Host/ApplicationServer.cs index d6e1e3625..ab0ee6f6e 100644 --- a/NzbDrone.Host/ApplicationServer.cs +++ b/NzbDrone.Host/ApplicationServer.cs @@ -3,6 +3,7 @@ using System.ServiceProcess; using NLog; using NzbDrone.Common; using NzbDrone.Common.EnvironmentInfo; +using NzbDrone.Common.Processes; using NzbDrone.Core.Configuration; using NzbDrone.Host.Owin; diff --git a/NzbDrone.Host/NzbDrone.Host.csproj b/NzbDrone.Host/NzbDrone.Host.csproj index 7ecf58a13..ff8922c0c 100644 --- a/NzbDrone.Host/NzbDrone.Host.csproj +++ b/NzbDrone.Host/NzbDrone.Host.csproj @@ -89,12 +89,13 @@ False ..\packages\Microsoft.Owin.Hosting.1.1.0-beta2\lib\net40\Microsoft.Owin.Hosting.dll - - ..\packages\Nancy.0.18.0\lib\net40\Nancy.dll + + False + ..\packages\Nancy.0.20.0\lib\net40\Nancy.dll - + False - ..\packages\Nancy.Owin.0.18.0\lib\net40\Nancy.Owin.dll + ..\packages\Nancy.Owin.0.20.0\lib\net40\Nancy.Owin.dll False @@ -116,6 +117,8 @@ Properties\SharedAssemblyInfo.cs + + Component diff --git a/NzbDrone.Host/Owin/MiddleWare/NancyMiddleWare.cs b/NzbDrone.Host/Owin/MiddleWare/NancyMiddleWare.cs index 54fc516d8..9e74c1e71 100644 --- a/NzbDrone.Host/Owin/MiddleWare/NancyMiddleWare.cs +++ b/NzbDrone.Host/Owin/MiddleWare/NancyMiddleWare.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Nancy.Bootstrapper; +using Nancy.Bootstrapper; using Nancy.Owin; using Owin; @@ -20,8 +17,13 @@ namespace NzbDrone.Host.Owin.MiddleWare public void Attach(IAppBuilder appBuilder) { - var nancyOwinHost = new NancyOwinHost(null, _nancyBootstrapper, new HostConfiguration()); - appBuilder.Use((Func, Task>, Func, Task>>)(next => (Func, Task>)nancyOwinHost.Invoke), new object[0]); + var options = new NancyOptions + { + Bootstrapper = _nancyBootstrapper, + PerformPassThrough = context => context.Request.Path.StartsWith("/signalr") + }; + + appBuilder.UseNancy(options); } } } \ No newline at end of file diff --git a/NzbDrone.Host/Owin/OwinHostController.cs b/NzbDrone.Host/Owin/OwinHostController.cs index b4d8d24ba..5af5a96c5 100644 --- a/NzbDrone.Host/Owin/OwinHostController.cs +++ b/NzbDrone.Host/Owin/OwinHostController.cs @@ -21,17 +21,24 @@ namespace NzbDrone.Host.Owin private readonly IRuntimeInfo _runtimeInfo; private readonly IUrlAclAdapter _urlAclAdapter; private readonly IFirewallAdapter _firewallAdapter; + private readonly ISslAdapter _sslAdapter; private readonly Logger _logger; private IDisposable _host; - public OwinHostController(IConfigFileProvider configFileProvider, IEnumerable owinMiddleWares, - IRuntimeInfo runtimeInfo, IUrlAclAdapter urlAclAdapter, IFirewallAdapter firewallAdapter, Logger logger) + public OwinHostController(IConfigFileProvider configFileProvider, + IEnumerable owinMiddleWares, + IRuntimeInfo runtimeInfo, + IUrlAclAdapter urlAclAdapter, + IFirewallAdapter firewallAdapter, + ISslAdapter sslAdapter, + Logger logger) { _configFileProvider = configFileProvider; _owinMiddleWares = owinMiddleWares; _runtimeInfo = runtimeInfo; _urlAclAdapter = urlAclAdapter; _firewallAdapter = firewallAdapter; + _sslAdapter = sslAdapter; _logger = logger; } @@ -39,18 +46,29 @@ namespace NzbDrone.Host.Owin { IgnoreCertErrorPolicy.Register(); - if (OsInfo.IsWindows && _runtimeInfo.IsAdmin) + if (OsInfo.IsWindows) { - _urlAclAdapter.RefreshRegistration(); - _firewallAdapter.MakeAccessible(); + if (_runtimeInfo.IsAdmin) + { + _firewallAdapter.MakeAccessible(); + _sslAdapter.Register(); + } + + _urlAclAdapter.ConfigureUrl(); } - var options = new StartOptions(_urlAclAdapter.UrlAcl) + var options = new StartOptions(_urlAclAdapter.Url) { ServerFactory = "Microsoft.Owin.Host.HttpListener" }; - _logger.Info("starting server on {0}", _urlAclAdapter.UrlAcl); + if (_configFileProvider.EnableSsl) + { + _logger.Trace("SSL enabled, listening on: {0}", _urlAclAdapter.HttpsUrl); + options.Urls.Add(_urlAclAdapter.HttpsUrl); + } + + _logger.Info("starting server on {0}", _urlAclAdapter.Url); try { @@ -99,6 +117,5 @@ namespace NzbDrone.Host.Owin _host = null; _logger.Info("Host has stopped"); } - } } \ No newline at end of file diff --git a/NzbDrone.Host/PriorityMonitor.cs b/NzbDrone.Host/PriorityMonitor.cs index 28caf28ac..9d2533791 100644 --- a/NzbDrone.Host/PriorityMonitor.cs +++ b/NzbDrone.Host/PriorityMonitor.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Threading; using NLog; using NzbDrone.Common; +using NzbDrone.Common.Processes; namespace NzbDrone.Host { diff --git a/NzbDrone.Host/packages.config b/NzbDrone.Host/packages.config index 36d7e82de..f134e38ed 100644 --- a/NzbDrone.Host/packages.config +++ b/NzbDrone.Host/packages.config @@ -5,8 +5,8 @@ - - + + diff --git a/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj b/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj index 9bba4d240..75bea0f21 100644 --- a/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj +++ b/NzbDrone.Integration.Test/NzbDrone.Integration.Test.csproj @@ -59,13 +59,13 @@ False ..\packages\Moq.4.0.10827\lib\NET40\Moq.dll - + False - ..\packages\Nancy.0.18.0\lib\net40\Nancy.dll + ..\packages\Nancy.0.20.0\lib\net40\Nancy.dll - + False - ..\packages\Nancy.Owin.0.18.0\lib\net40\Nancy.Owin.dll + ..\packages\Nancy.Owin.0.20.0\lib\net40\Nancy.Owin.dll False @@ -81,8 +81,9 @@ False ..\packages\Owin.1.0\lib\net40\Owin.dll - - ..\packages\RestSharp.104.1\lib\net4\RestSharp.dll + + False + ..\packages\RestSharp.104.2.0\lib\net4\RestSharp.dll diff --git a/NzbDrone.Integration.Test/NzbDroneRunner.cs b/NzbDrone.Integration.Test/NzbDroneRunner.cs index 5955166ff..b4bb8fa85 100644 --- a/NzbDrone.Integration.Test/NzbDroneRunner.cs +++ b/NzbDrone.Integration.Test/NzbDroneRunner.cs @@ -5,6 +5,7 @@ using System.Threading; using NUnit.Framework; using NzbDrone.Common; using NzbDrone.Common.EnvironmentInfo; +using NzbDrone.Common.Processes; using RestSharp; namespace NzbDrone.Integration.Test diff --git a/NzbDrone.Integration.Test/packages.config b/NzbDrone.Integration.Test/packages.config index 268fde156..101c14bc1 100644 --- a/NzbDrone.Integration.Test/packages.config +++ b/NzbDrone.Integration.Test/packages.config @@ -7,11 +7,11 @@ - - + + - + \ No newline at end of file diff --git a/NzbDrone.Libraries.Test/JsonTests/JsonFixture.cs b/NzbDrone.Libraries.Test/JsonTests/JsonFixture.cs index 19a663db4..951eaa4a1 100644 --- a/NzbDrone.Libraries.Test/JsonTests/JsonFixture.cs +++ b/NzbDrone.Libraries.Test/JsonTests/JsonFixture.cs @@ -1,3 +1,5 @@ +using System; +using FluentAssertions; using NUnit.Framework; using NzbDrone.Common.Serializer; using NzbDrone.Test.Common; @@ -9,15 +11,19 @@ namespace NzbDrone.Libraries.Test.JsonTests { public class TypeWithNumbers { - public int Id { get; set; } + public int Int32 { get; set; } + public Int64 Int64 { get; set; } + public int? nullableIntIsNull { get; set; } + public int? nullableWithValue { get; set; } } [Test] public void should_be_able_to_deserialize_numbers() { - var quality = new TypeWithNumbers { Id = 12 }; + var quality = new TypeWithNumbers { Int32 = Int32.MaxValue, Int64 = Int64.MaxValue, nullableWithValue = 12 }; + var result = Json.Deserialize(quality.ToJson()); - Json.Deserialize(quality.ToJson()); + result.ShouldHave().AllProperties().EqualTo(quality); } } } diff --git a/NzbDrone.Libraries.Test/NzbDrone.Libraries.Test.csproj b/NzbDrone.Libraries.Test/NzbDrone.Libraries.Test.csproj index 11d3bbdc2..14c492823 100644 --- a/NzbDrone.Libraries.Test/NzbDrone.Libraries.Test.csproj +++ b/NzbDrone.Libraries.Test/NzbDrone.Libraries.Test.csproj @@ -33,6 +33,14 @@ MinimumRecommendedRules.ruleset + + False + ..\packages\FluentAssertions.2.1.0.0\lib\net40\FluentAssertions.dll + + + False + ..\packages\Newtonsoft.Json.5.0.6\lib\net40\Newtonsoft.Json.dll + ..\packages\NUnit.2.6.2\lib\nunit.framework.dll @@ -65,9 +73,7 @@ NzbDrone.Test.Common - - - +