mirror of
https://github.com/Radarr/Radarr.git
synced 2024-09-11 12:02:35 +02:00
Added: Platform Detection Improvements
This commit is contained in:
parent
ea5ad24944
commit
aef89160e2
@ -14,7 +14,7 @@ public class CacheableSpecification : ICacheableSpecification
|
||||
{
|
||||
public bool IsCacheable(NancyContext context)
|
||||
{
|
||||
if (!RuntimeInfoBase.IsProduction)
|
||||
if (!RuntimeInfo.IsProduction)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -46,4 +46,4 @@ public bool IsCacheable(NancyContext context)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ protected override Stream GetContentStream(string filePath)
|
||||
|
||||
private string GetIndexText()
|
||||
{
|
||||
if (RuntimeInfoBase.IsProduction && _generatedContent != null)
|
||||
if (RuntimeInfo.IsProduction && _generatedContent != null)
|
||||
{
|
||||
return _generatedContent;
|
||||
}
|
||||
@ -111,7 +111,7 @@ private string GetIndexText()
|
||||
text = text.Replace("APP_BRANCH", _configFileProvider.Branch.ToLower());
|
||||
text = text.Replace("APP_ANALYTICS", _analyticsService.IsEnabled.ToString().ToLowerInvariant());
|
||||
text = text.Replace("URL_BASE", URL_BASE);
|
||||
text = text.Replace("PRODUCTION", RuntimeInfoBase.IsProduction.ToString().ToLowerInvariant());
|
||||
text = text.Replace("PRODUCTION", RuntimeInfo.IsProduction.ToString().ToLowerInvariant());
|
||||
|
||||
_generatedContent = text;
|
||||
|
||||
|
@ -67,7 +67,7 @@ protected override Stream GetContentStream(string filePath)
|
||||
|
||||
private string GetLoginText()
|
||||
{
|
||||
if (RuntimeInfoBase.IsProduction && _generatedContent != null)
|
||||
if (RuntimeInfo.IsProduction && _generatedContent != null)
|
||||
{
|
||||
return _generatedContent;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ protected StaticResourceMapperBase(IDiskProvider diskProvider, Logger logger)
|
||||
_diskProvider = diskProvider;
|
||||
_logger = logger;
|
||||
|
||||
if (!RuntimeInfoBase.IsProduction)
|
||||
if (!RuntimeInfo.IsProduction)
|
||||
{
|
||||
_caseSensitive = StringComparison.OrdinalIgnoreCase;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using Nancy.Bootstrapper;
|
||||
using Nancy.Diagnostics;
|
||||
using NLog;
|
||||
@ -24,9 +24,9 @@ public NancyBootstrapper(TinyIoCContainer tinyIoCContainer)
|
||||
|
||||
protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
|
||||
{
|
||||
Logger.Info("Starting NzbDrone API");
|
||||
Logger.Info("Starting Web Server");
|
||||
|
||||
if (RuntimeInfoBase.IsProduction)
|
||||
if (RuntimeInfo.IsProduction)
|
||||
{
|
||||
DiagnosticsHook.Disable(pipelines);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
using Nancy;
|
||||
using Nancy;
|
||||
using Nancy.Routing;
|
||||
using NzbDrone.Api.Extensions;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
@ -13,6 +13,8 @@ public class SystemModule : NzbDroneApiModule
|
||||
{
|
||||
private readonly IAppFolderInfo _appFolderInfo;
|
||||
private readonly IRuntimeInfo _runtimeInfo;
|
||||
private readonly IPlatformInfo _platformInfo;
|
||||
private readonly IOsInfo _osInfo;
|
||||
private readonly IRouteCacheProvider _routeCacheProvider;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IMainDatabase _database;
|
||||
@ -20,14 +22,17 @@ public class SystemModule : NzbDroneApiModule
|
||||
|
||||
public SystemModule(IAppFolderInfo appFolderInfo,
|
||||
IRuntimeInfo runtimeInfo,
|
||||
IPlatformInfo platformInfo,
|
||||
IOsInfo osInfo,
|
||||
IRouteCacheProvider routeCacheProvider,
|
||||
IConfigFileProvider configFileProvider,
|
||||
IMainDatabase database,
|
||||
ILifecycleService lifecycleService)
|
||||
: base("system")
|
||||
ILifecycleService lifecycleService) : base("system")
|
||||
{
|
||||
_appFolderInfo = appFolderInfo;
|
||||
_runtimeInfo = runtimeInfo;
|
||||
_platformInfo = platformInfo;
|
||||
_osInfo = osInfo;
|
||||
_routeCacheProvider = routeCacheProvider;
|
||||
_configFileProvider = configFileProvider;
|
||||
_database = database;
|
||||
@ -41,27 +46,29 @@ public SystemModule(IAppFolderInfo appFolderInfo,
|
||||
private Response GetStatus()
|
||||
{
|
||||
return new
|
||||
{
|
||||
Version = BuildInfo.Version.ToString(),
|
||||
BuildTime = BuildInfo.BuildDateTime,
|
||||
IsDebug = BuildInfo.IsDebug,
|
||||
IsProduction = RuntimeInfoBase.IsProduction,
|
||||
IsAdmin = _runtimeInfo.IsAdmin,
|
||||
IsUserInteractive = RuntimeInfoBase.IsUserInteractive,
|
||||
StartupPath = _appFolderInfo.StartUpFolder,
|
||||
AppData = _appFolderInfo.GetAppDataPath(),
|
||||
OsVersion = OsInfo.Version.ToString(),
|
||||
IsMonoRuntime = OsInfo.IsMonoRuntime,
|
||||
IsMono = OsInfo.IsNotWindows,
|
||||
IsLinux = OsInfo.IsLinux,
|
||||
IsOsx = OsInfo.IsOsx,
|
||||
IsWindows = OsInfo.IsWindows,
|
||||
Branch = _configFileProvider.Branch,
|
||||
Authentication = _configFileProvider.AuthenticationMethod,
|
||||
SqliteVersion = _database.Version,
|
||||
UrlBase = _configFileProvider.UrlBase,
|
||||
RuntimeVersion = _runtimeInfo.RuntimeVersion
|
||||
}.AsResponse();
|
||||
{
|
||||
Version = BuildInfo.Version.ToString(),
|
||||
BuildTime = BuildInfo.BuildDateTime,
|
||||
IsDebug = BuildInfo.IsDebug,
|
||||
IsProduction = RuntimeInfo.IsProduction,
|
||||
IsAdmin = _runtimeInfo.IsAdmin,
|
||||
IsUserInteractive = RuntimeInfo.IsUserInteractive,
|
||||
StartupPath = _appFolderInfo.StartUpFolder,
|
||||
AppData = _appFolderInfo.GetAppDataPath(),
|
||||
OsName = _osInfo.Name,
|
||||
OsVersion = _osInfo.Version,
|
||||
IsMonoRuntime = PlatformInfo.IsMono,
|
||||
IsMono = PlatformInfo.IsMono,
|
||||
IsLinux = OsInfo.IsLinux,
|
||||
IsOsx = OsInfo.IsOsx,
|
||||
IsWindows = OsInfo.IsWindows,
|
||||
Branch = _configFileProvider.Branch,
|
||||
Authentication = _configFileProvider.AuthenticationMethod,
|
||||
SqliteVersion = _database.Version,
|
||||
UrlBase = _configFileProvider.UrlBase,
|
||||
RuntimeVersion = _platformInfo.Version,
|
||||
RuntimeName = PlatformInfo.Platform
|
||||
}.AsResponse();
|
||||
}
|
||||
|
||||
private Response GetRoutes()
|
||||
|
@ -4,7 +4,7 @@
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="FluentMigrator" publicKeyToken="aacfc7de5acabf05" culture="neutral"/>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="FluentMigrator" publicKeyToken="aacfc7de5acabf05" culture="neutral" />
|
||||
|
@ -29,7 +29,7 @@ public void ApplicationPath_should_not_be_empty()
|
||||
[Test]
|
||||
public void IsProduction_should_return_false_when_run_within_nunit()
|
||||
{
|
||||
RuntimeInfoBase.IsProduction.Should().BeFalse("Process name is " + Process.GetCurrentProcess().ProcessName + " Folder is " + Directory.GetCurrentDirectory());
|
||||
RuntimeInfo.IsProduction.Should().BeFalse("Process name is " + Process.GetCurrentProcess().ProcessName + " Folder is " + Directory.GetCurrentDirectory());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
@ -9,6 +9,7 @@
|
||||
using NLog;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Cache;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Http.Dispatchers;
|
||||
using NzbDrone.Common.Http.Proxy;
|
||||
@ -30,6 +31,13 @@ public class HttpClientFixture<TDispatcher> : TestBase<HttpClient> where TDispat
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
|
||||
Mocker.GetMock<IPlatformInfo>().Setup(c => c.Version).Returns(new Version("1.0.0"));
|
||||
Mocker.GetMock<IOsInfo>().Setup(c => c.Name).Returns("TestOS");
|
||||
Mocker.GetMock<IOsInfo>().Setup(c => c.Version).Returns("9.0.0");
|
||||
|
||||
Mocker.SetConstant<IUserAgentBuilder>(Mocker.Resolve<UserAgentBuilder>());
|
||||
|
||||
Mocker.SetConstant<ICacheManager>(Mocker.Resolve<CacheManager>());
|
||||
Mocker.SetConstant<ICreateManagedWebProxy>(Mocker.Resolve<ManagedWebProxyFactory>());
|
||||
Mocker.SetConstant<IRateLimitService>(Mocker.Resolve<RateLimitService>());
|
||||
@ -48,7 +56,7 @@ public void SetUp()
|
||||
[Test]
|
||||
public void should_execute_simple_get()
|
||||
{
|
||||
var request = new HttpRequest(string.Format("http://{0}/get", _httpBinHost));
|
||||
var request = new HttpRequest($"http://{_httpBinHost}/get");
|
||||
|
||||
var response = Subject.Execute(request);
|
||||
|
||||
@ -58,7 +66,7 @@ public void should_execute_simple_get()
|
||||
[Test]
|
||||
public void should_execute_https_get()
|
||||
{
|
||||
var request = new HttpRequest(string.Format("https://{0}/get", _httpBinHost));
|
||||
var request = new HttpRequest($"https://{_httpBinHost}/get");
|
||||
|
||||
var response = Subject.Execute(request);
|
||||
|
||||
@ -68,7 +76,7 @@ public void should_execute_https_get()
|
||||
[Test]
|
||||
public void should_execute_typed_get()
|
||||
{
|
||||
var request = new HttpRequest(string.Format("http://{0}/get", _httpBinHost));
|
||||
var request = new HttpRequest($"http://{_httpBinHost}/get");
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
|
||||
@ -80,7 +88,7 @@ public void should_execute_simple_post()
|
||||
{
|
||||
var message = "{ my: 1 }";
|
||||
|
||||
var request = new HttpRequest(string.Format("http://{0}/post", _httpBinHost));
|
||||
var request = new HttpRequest($"http://{_httpBinHost}/post");
|
||||
request.SetContent(message);
|
||||
|
||||
var response = Subject.Post<HttpBinResource>(request);
|
||||
@ -91,7 +99,7 @@ public void should_execute_simple_post()
|
||||
[TestCase("gzip")]
|
||||
public void should_execute_get_using_gzip(string compression)
|
||||
{
|
||||
var request = new HttpRequest(string.Format("http://{0}/{1}", _httpBinHost, compression));
|
||||
var request = new HttpRequest($"http://{_httpBinHost}/{compression}");
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
|
||||
@ -107,7 +115,7 @@ public void should_execute_get_using_gzip(string compression)
|
||||
[TestCase(HttpStatusCode.BadGateway)]
|
||||
public void should_throw_on_unsuccessful_status_codes(int statusCode)
|
||||
{
|
||||
var request = new HttpRequest(string.Format("http://{0}/status/{1}", _httpBinHost, statusCode));
|
||||
var request = new HttpRequest($"http://{_httpBinHost}/status/{statusCode}");
|
||||
|
||||
var exception = Assert.Throws<HttpException>(() => Subject.Get<HttpBinResource>(request));
|
||||
|
||||
@ -119,7 +127,7 @@ public void should_throw_on_unsuccessful_status_codes(int statusCode)
|
||||
[Test]
|
||||
public void should_not_follow_redirects_when_not_in_production()
|
||||
{
|
||||
var request = new HttpRequest(string.Format("http://{0}/redirect/1", _httpBinHost));
|
||||
var request = new HttpRequest($"http://{_httpBinHost}/redirect/1");
|
||||
|
||||
Subject.Get(request);
|
||||
|
||||
@ -129,7 +137,7 @@ public void should_not_follow_redirects_when_not_in_production()
|
||||
[Test]
|
||||
public void should_follow_redirects()
|
||||
{
|
||||
var request = new HttpRequest(string.Format("http://{0}/redirect/1", _httpBinHost));
|
||||
var request = new HttpRequest($"http://{_httpBinHost}/redirect/1");
|
||||
request.AllowAutoRedirect = true;
|
||||
|
||||
var response = Subject.Get(request);
|
||||
@ -182,7 +190,7 @@ public void should_throw_on_too_many_redirects()
|
||||
[Test]
|
||||
public void should_send_user_agent()
|
||||
{
|
||||
var request = new HttpRequest(string.Format("http://{0}/get", _httpBinHost));
|
||||
var request = new HttpRequest($"http://{_httpBinHost}/get");
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
|
||||
@ -196,7 +204,7 @@ public void should_send_user_agent()
|
||||
[TestCase("Accept", "text/xml, text/rss+xml, application/rss+xml")]
|
||||
public void should_send_headers(string header, string value)
|
||||
{
|
||||
var request = new HttpRequest(string.Format("http://{0}/get", _httpBinHost));
|
||||
var request = new HttpRequest($"http://{_httpBinHost}/get");
|
||||
request.Headers.Add(header, value);
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
@ -219,7 +227,7 @@ public void should_not_download_file_with_error()
|
||||
[Test]
|
||||
public void should_send_cookie()
|
||||
{
|
||||
var request = new HttpRequest(string.Format("http://{0}/get", _httpBinHost));
|
||||
var request = new HttpRequest($"http://{_httpBinHost}/get");
|
||||
request.Cookies["my"] = "cookie";
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
@ -236,7 +244,7 @@ public void GivenOldCookie()
|
||||
var oldRequest = new HttpRequest("http://eu.httpbin.org/get");
|
||||
oldRequest.Cookies["my"] = "cookie";
|
||||
|
||||
var oldClient = new HttpClient(new IHttpRequestInterceptor[0], Mocker.Resolve<ICacheManager>(), Mocker.Resolve<IRateLimitService>(), Mocker.Resolve<IHttpDispatcher>(), Mocker.Resolve<Logger>());
|
||||
var oldClient = new HttpClient(new IHttpRequestInterceptor[0], Mocker.Resolve<ICacheManager>(), Mocker.Resolve<IRateLimitService>(), Mocker.Resolve<IHttpDispatcher>(), Mocker.GetMock<IUserAgentBuilder>().Object, Mocker.Resolve<Logger>());
|
||||
|
||||
oldClient.Should().NotBeSameAs(Subject);
|
||||
|
||||
@ -329,7 +337,7 @@ public void should_delete_request_cookie()
|
||||
[Test]
|
||||
public void should_not_store_response_cookie()
|
||||
{
|
||||
var requestSet = new HttpRequest(string.Format("http://{0}/cookies/set?my=cookie", _httpBinHost));
|
||||
var requestSet = new HttpRequest($"http://{_httpBinHost}/cookies/set?my=cookie");
|
||||
requestSet.AllowAutoRedirect = false;
|
||||
requestSet.StoreRequestCookie = false;
|
||||
requestSet.StoreResponseCookie.Should().BeFalse();
|
||||
@ -348,7 +356,7 @@ public void should_not_store_response_cookie()
|
||||
[Test]
|
||||
public void should_store_response_cookie()
|
||||
{
|
||||
var requestSet = new HttpRequest(string.Format("http://{0}/cookies/set?my=cookie", _httpBinHost));
|
||||
var requestSet = new HttpRequest($"http://{_httpBinHost}/cookies/set?my=cookie");
|
||||
requestSet.AllowAutoRedirect = false;
|
||||
requestSet.StoreRequestCookie = false;
|
||||
requestSet.StoreResponseCookie = true;
|
||||
@ -527,7 +535,7 @@ public void should_not_send_old_cookie()
|
||||
[Test]
|
||||
public void should_throw_on_http429_too_many_requests()
|
||||
{
|
||||
var request = new HttpRequest(string.Format("http://{0}/status/429", _httpBinHost));
|
||||
var request = new HttpRequest($"http://{_httpBinHost}/status/429");
|
||||
|
||||
Assert.Throws<TooManyRequestsException>(() => Subject.Get(request));
|
||||
|
||||
@ -547,7 +555,7 @@ public void should_call_interceptor()
|
||||
.Setup(v => v.PostResponse(It.IsAny<HttpResponse>()))
|
||||
.Returns<HttpResponse>(r => r);
|
||||
|
||||
var request = new HttpRequest(string.Format("http://{0}/get", _httpBinHost));
|
||||
var request = new HttpRequest($"http://{_httpBinHost}/get");
|
||||
|
||||
Subject.Get(request);
|
||||
|
||||
@ -569,7 +577,7 @@ public void should_parse_malformed_cloudflare_cookie(string culture)
|
||||
{
|
||||
// the date is bad in the below - should be 13-Jul-2026
|
||||
string malformedCookie = @"__cfduid=d29e686a9d65800021c66faca0a29b4261436890790; expires=Mon, 13-Jul-26 16:19:50 GMT; path=/; HttpOnly";
|
||||
var requestSet = new HttpRequestBuilder(string.Format("http://{0}/response-headers", _httpBinHost))
|
||||
var requestSet = new HttpRequestBuilder($"http://{_httpBinHost}/response-headers")
|
||||
.AddQueryParam("Set-Cookie", malformedCookie)
|
||||
.Build();
|
||||
|
||||
@ -578,7 +586,7 @@ public void should_parse_malformed_cloudflare_cookie(string culture)
|
||||
|
||||
var responseSet = Subject.Get(requestSet);
|
||||
|
||||
var request = new HttpRequest(string.Format("http://{0}/get", _httpBinHost));
|
||||
var request = new HttpRequest($"http://{_httpBinHost}/get");
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
|
||||
@ -602,7 +610,8 @@ public void should_reject_malformed_domain_cookie(string malformedCookie)
|
||||
{
|
||||
try
|
||||
{
|
||||
string url = string.Format("http://{0}/response-headers?Set-Cookie={1}", _httpBinHost, Uri.EscapeUriString(malformedCookie));
|
||||
string url =
|
||||
$"http://{_httpBinHost}/response-headers?Set-Cookie={Uri.EscapeUriString(malformedCookie)}";
|
||||
|
||||
var requestSet = new HttpRequest(url);
|
||||
requestSet.AllowAutoRedirect = false;
|
||||
@ -610,7 +619,7 @@ public void should_reject_malformed_domain_cookie(string malformedCookie)
|
||||
|
||||
var responseSet = Subject.Get(requestSet);
|
||||
|
||||
var request = new HttpRequest(string.Format("http://{0}/get", _httpBinHost));
|
||||
var request = new HttpRequest($"http://{_httpBinHost}/get");
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
|
||||
|
30
src/NzbDrone.Common.Test/Http/UserAgentBuilderFixture.cs
Normal file
30
src/NzbDrone.Common.Test/Http/UserAgentBuilderFixture.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Common.Test.Http
|
||||
{
|
||||
[TestFixture]
|
||||
public class UserAgentBuilderFixture : TestBase<UserAgentBuilder>
|
||||
{
|
||||
[Test]
|
||||
public void should_get_user_agent_if_os_version_is_null()
|
||||
{
|
||||
Mocker.GetMock<IOsInfo>().SetupGet(c => c.Version).Returns((string)null);
|
||||
Mocker.GetMock<IOsInfo>().SetupGet(c => c.Name).Returns("TestOS");
|
||||
|
||||
Subject.GetUserAgent(false).Should().NotBeNullOrWhiteSpace();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_get_use_os_family_if_name_is_null()
|
||||
{
|
||||
Mocker.GetMock<IOsInfo>().SetupGet(c => c.Version).Returns((string)null);
|
||||
Mocker.GetMock<IOsInfo>().SetupGet(c => c.Name).Returns((string)null);
|
||||
|
||||
Subject.GetUserAgent(false).Should().NotBeNullOrWhiteSpace();
|
||||
}
|
||||
}
|
||||
}
|
@ -92,6 +92,7 @@
|
||||
<Compile Include="Http\HttpRequestBuilderFixture.cs" />
|
||||
<Compile Include="Http\HttpRequestFixture.cs" />
|
||||
<Compile Include="Http\HttpUriFixture.cs" />
|
||||
<Compile Include="Http\UserAgentBuilderFixture.cs" />
|
||||
<Compile Include="InstrumentationTests\CleanseLogMessageFixture.cs" />
|
||||
<Compile Include="LevenshteinDistanceFixture.cs" />
|
||||
<Compile Include="OsPathFixture.cs" />
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@ -13,12 +13,15 @@ public abstract class ContainerBuilderBase
|
||||
{
|
||||
private readonly List<Type> _loadedTypes;
|
||||
|
||||
public IContainer Container { get; private set; }
|
||||
protected IContainer Container { get; }
|
||||
|
||||
protected ContainerBuilderBase(IStartupContext args, params string[] assemblies)
|
||||
protected ContainerBuilderBase(IStartupContext args, List<string> assemblies)
|
||||
{
|
||||
_loadedTypes = new List<Type>();
|
||||
|
||||
assemblies.Add(OsInfo.IsWindows ? "NzbDrone.Windows" : "NzbDrone.Mono");
|
||||
assemblies.Add("NzbDrone.Common");
|
||||
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
_loadedTypes.AddRange(Assembly.Load(assembly).GetTypes());
|
||||
|
@ -17,6 +17,19 @@ public abstract class DiskProviderBase : IDiskProvider
|
||||
{
|
||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(DiskProviderBase));
|
||||
|
||||
public static StringComparison PathStringComparison
|
||||
{
|
||||
get
|
||||
{
|
||||
if (OsInfo.IsWindows)
|
||||
{
|
||||
return StringComparison.OrdinalIgnoreCase;
|
||||
}
|
||||
|
||||
return StringComparison.Ordinal;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract long? GetAvailableSpace(string path);
|
||||
public abstract void InheritFolderPermissions(string filename);
|
||||
public abstract void SetPermissions(string path, string mask, string user, string group);
|
||||
@ -87,7 +100,7 @@ public bool FolderExists(string path)
|
||||
public bool FileExists(string path)
|
||||
{
|
||||
Ensure.That(path, () => path).IsValidPath();
|
||||
return FileExists(path, OsInfo.PathStringComparison);
|
||||
return FileExists(path, PathStringComparison);
|
||||
}
|
||||
|
||||
public bool FileExists(string path, StringComparison stringComparison)
|
||||
|
@ -101,12 +101,12 @@ public static Param<string> IsValidPath(this Param<string> param)
|
||||
|
||||
if (param.Value.IsPathValid()) return param;
|
||||
|
||||
if (OsInfo.IsNotWindows)
|
||||
if (OsInfo.IsWindows)
|
||||
{
|
||||
throw ExceptionFactory.CreateForParamValidation(param.Name, string.Format("value [{0}] is not a valid *nix path. paths must start with /", param.Value));
|
||||
throw ExceptionFactory.CreateForParamValidation(param.Name, string.Format("value [{0}] is not a valid Windows path. paths must be a full path eg. C:\\Windows", param.Value));
|
||||
}
|
||||
|
||||
throw ExceptionFactory.CreateForParamValidation(param.Name, string.Format("value [{0}] is not a valid Windows path. paths must be a full path eg. C:\\Windows", param.Value));
|
||||
throw ExceptionFactory.CreateForParamValidation(param.Name, string.Format("value [{0}] is not a valid *nix path. paths must start with /", param.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
namespace NzbDrone.Common.EnvironmentInfo
|
||||
{
|
||||
public interface IOperatingSystemVersionInfo
|
||||
{
|
||||
string Version { get; }
|
||||
string Name { get; }
|
||||
string FullName { get; }
|
||||
}
|
||||
}
|
9
src/NzbDrone.Common/EnvironmentInfo/IOsVersionAdapter.cs
Normal file
9
src/NzbDrone.Common/EnvironmentInfo/IOsVersionAdapter.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace NzbDrone.Common.EnvironmentInfo
|
||||
{
|
||||
|
||||
public interface IOsVersionAdapter
|
||||
{
|
||||
bool Enabled { get; }
|
||||
OsVersionModel Read();
|
||||
}
|
||||
}
|
50
src/NzbDrone.Common/EnvironmentInfo/IPlatformInfo.cs
Normal file
50
src/NzbDrone.Common/EnvironmentInfo/IPlatformInfo.cs
Normal file
@ -0,0 +1,50 @@
|
||||
using System;
|
||||
|
||||
namespace NzbDrone.Common.EnvironmentInfo
|
||||
{
|
||||
|
||||
public enum PlatformType
|
||||
{
|
||||
DotNet = 0,
|
||||
Mono = 1
|
||||
}
|
||||
|
||||
public interface IPlatformInfo
|
||||
{
|
||||
Version Version { get; }
|
||||
}
|
||||
|
||||
public abstract class PlatformInfo : IPlatformInfo
|
||||
{
|
||||
static PlatformInfo()
|
||||
{
|
||||
if (Type.GetType("Mono.Runtime") != null)
|
||||
{
|
||||
Platform = PlatformType.Mono;
|
||||
}
|
||||
else
|
||||
{
|
||||
Platform = PlatformType.DotNet;
|
||||
}
|
||||
}
|
||||
|
||||
public static PlatformType Platform { get; }
|
||||
public static bool IsMono => Platform == PlatformType.Mono;
|
||||
public static bool IsDotNet => Platform == PlatformType.DotNet;
|
||||
|
||||
public static string PlatformName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsDotNet)
|
||||
{
|
||||
return ".NET";
|
||||
}
|
||||
|
||||
return "Mono";
|
||||
}
|
||||
}
|
||||
|
||||
public abstract Version Version { get; }
|
||||
}
|
||||
}
|
@ -1,14 +1,13 @@
|
||||
namespace NzbDrone.Common.EnvironmentInfo
|
||||
namespace NzbDrone.Common.EnvironmentInfo
|
||||
{
|
||||
public interface IRuntimeInfo
|
||||
{
|
||||
bool IsUserInteractive { get; }
|
||||
bool IsAdmin { get; }
|
||||
bool IsWindowsService { get; }
|
||||
bool IsConsole { get; }
|
||||
bool IsRunning { get; set; }
|
||||
bool IsWindowsTray { get; }
|
||||
bool IsExiting { get; set; }
|
||||
bool RestartPending { get; set; }
|
||||
string ExecutingApplication { get; }
|
||||
string RuntimeVersion { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,87 +1,95 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
|
||||
namespace NzbDrone.Common.EnvironmentInfo
|
||||
{
|
||||
public static class OsInfo
|
||||
public class OsInfo : IOsInfo
|
||||
{
|
||||
public static Os Os { get; }
|
||||
|
||||
public static bool IsNotWindows => !IsWindows;
|
||||
public static bool IsLinux => Os == Os.Linux;
|
||||
public static bool IsOsx => Os == Os.Osx;
|
||||
public static bool IsWindows => Os == Os.Windows;
|
||||
|
||||
public string Version { get; }
|
||||
public string Name { get; }
|
||||
public string FullName { get; }
|
||||
|
||||
static OsInfo()
|
||||
{
|
||||
var platform = (int)Environment.OSVersion.Platform;
|
||||
var platform = Environment.OSVersion.Platform;
|
||||
|
||||
Version = Environment.OSVersion.Version;
|
||||
|
||||
IsMonoRuntime = Type.GetType("Mono.Runtime") != null;
|
||||
IsNotWindows = (platform == 4) || (platform == 6) || (platform == 128);
|
||||
IsOsx = IsRunningOnMac();
|
||||
IsLinux = IsNotWindows && !IsOsx;
|
||||
IsWindows = !IsNotWindows;
|
||||
|
||||
FirstDayOfWeek = CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek;
|
||||
|
||||
if (IsWindows)
|
||||
switch (platform)
|
||||
{
|
||||
Os = Os.Windows;
|
||||
PathStringComparison = StringComparison.OrdinalIgnoreCase;
|
||||
case PlatformID.Win32NT:
|
||||
{
|
||||
Os = Os.Windows;
|
||||
break;
|
||||
}
|
||||
case PlatformID.MacOSX:
|
||||
case PlatformID.Unix:
|
||||
{
|
||||
// Sometimes Mac OS reports itself as Unix
|
||||
if (Directory.Exists("/System/Library/CoreServices/") &&
|
||||
(File.Exists("/System/Library/CoreServices/SystemVersion.plist") ||
|
||||
File.Exists("/System/Library/CoreServices/ServerVersion.plist"))
|
||||
)
|
||||
{
|
||||
Os = Os.Osx;
|
||||
}
|
||||
else
|
||||
{
|
||||
Os = Os.Linux;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public OsInfo(IEnumerable<IOsVersionAdapter> versionAdapters, Logger logger)
|
||||
{
|
||||
OsVersionModel osInfo = null;
|
||||
|
||||
foreach (var osVersionAdapter in versionAdapters.Where(c => c.Enabled))
|
||||
{
|
||||
try
|
||||
{
|
||||
osInfo = osVersionAdapter.Read();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error(e, "Couldn't get OS Version info");
|
||||
}
|
||||
|
||||
if (osInfo != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (osInfo != null)
|
||||
{
|
||||
Name = osInfo.Name;
|
||||
Version = osInfo.Version;
|
||||
FullName = osInfo.FullName;
|
||||
}
|
||||
else
|
||||
{
|
||||
Os = IsOsx ? Os.Osx : Os.Linux;
|
||||
|
||||
PathStringComparison = StringComparison.Ordinal;
|
||||
Name = Os.ToString();
|
||||
FullName = Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Version Version { get; private set; }
|
||||
public static bool IsMonoRuntime { get; private set; }
|
||||
public static bool IsNotWindows { get; private set; }
|
||||
public static bool IsLinux { get; private set; }
|
||||
public static bool IsOsx { get; private set; }
|
||||
public static bool IsWindows { get; private set; }
|
||||
public static Os Os { get; private set; }
|
||||
public static DayOfWeek FirstDayOfWeek { get; private set; }
|
||||
public static StringComparison PathStringComparison { get; private set; }
|
||||
|
||||
//Borrowed from: https://github.com/jpobst/Pinta/blob/master/Pinta.Core/Managers/SystemManager.cs
|
||||
//From Managed.Windows.Forms/XplatUI
|
||||
[DllImport("libc")]
|
||||
static extern int uname(IntPtr buf);
|
||||
|
||||
[DebuggerStepThrough]
|
||||
static bool IsRunningOnMac()
|
||||
{
|
||||
var buf = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
buf = Marshal.AllocHGlobal(8192);
|
||||
// This is a hacktastic way of getting sysname from uname ()
|
||||
if (uname(buf) == 0)
|
||||
{
|
||||
var os = Marshal.PtrToStringAnsi(buf);
|
||||
|
||||
if (os == "Darwin")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (buf != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(buf);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
public interface IOsInfo
|
||||
{
|
||||
string Version { get; }
|
||||
string Name { get; }
|
||||
string FullName { get; }
|
||||
}
|
||||
|
||||
public enum Os
|
||||
@ -90,4 +98,4 @@ public enum Os
|
||||
Linux,
|
||||
Osx
|
||||
}
|
||||
}
|
||||
}
|
||||
|
29
src/NzbDrone.Common/EnvironmentInfo/OsVersionModel.cs
Normal file
29
src/NzbDrone.Common/EnvironmentInfo/OsVersionModel.cs
Normal file
@ -0,0 +1,29 @@
|
||||
namespace NzbDrone.Common.EnvironmentInfo
|
||||
{
|
||||
public class OsVersionModel
|
||||
{
|
||||
|
||||
|
||||
public OsVersionModel(string name, string version, string fullName = null)
|
||||
{
|
||||
Name = Trim(name);
|
||||
Version = Trim(version);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(fullName))
|
||||
{
|
||||
fullName = $"{Name} {Version}";
|
||||
}
|
||||
|
||||
FullName = Trim(fullName);
|
||||
}
|
||||
|
||||
private static string Trim(string source)
|
||||
{
|
||||
return source.Trim().Trim('"', '\'');
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
public string FullName { get; }
|
||||
public string Version { get; }
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
@ -9,11 +9,11 @@
|
||||
|
||||
namespace NzbDrone.Common.EnvironmentInfo
|
||||
{
|
||||
public abstract class RuntimeInfoBase : IRuntimeInfo
|
||||
public class RuntimeInfo : IRuntimeInfo
|
||||
{
|
||||
private readonly Logger _logger;
|
||||
|
||||
public RuntimeInfoBase(IServiceProvider serviceProvider, Logger logger)
|
||||
public RuntimeInfo(IServiceProvider serviceProvider, Logger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
|
||||
@ -28,10 +28,11 @@ public RuntimeInfoBase(IServiceProvider serviceProvider, Logger logger)
|
||||
if (entry != null)
|
||||
{
|
||||
ExecutingApplication = entry.Location;
|
||||
IsWindowsTray = entry.ManifestModule.Name == $"{ProcessProvider.NZB_DRONE_PROCESS_NAME}.exe";
|
||||
}
|
||||
}
|
||||
|
||||
static RuntimeInfoBase()
|
||||
static RuntimeInfo()
|
||||
{
|
||||
IsProduction = InternalIsProduction();
|
||||
}
|
||||
@ -59,31 +60,18 @@ public bool IsAdmin
|
||||
|
||||
public bool IsWindowsService { get; private set; }
|
||||
|
||||
public bool IsConsole
|
||||
{
|
||||
get
|
||||
{
|
||||
if (OsInfo.IsWindows)
|
||||
{
|
||||
return IsUserInteractive && Process.GetCurrentProcess().ProcessName.Equals(ProcessProvider.NZB_DRONE_CONSOLE_PROCESS_NAME, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsRunning { get; set; }
|
||||
public bool IsExiting { get; set; }
|
||||
public bool RestartPending { get; set; }
|
||||
public string ExecutingApplication { get; private set; }
|
||||
public string ExecutingApplication { get; }
|
||||
|
||||
public abstract string RuntimeVersion { get; }
|
||||
|
||||
public static bool IsProduction { get; private set; }
|
||||
public static bool IsProduction { get; }
|
||||
|
||||
private static bool InternalIsProduction()
|
||||
{
|
||||
if (BuildInfo.IsDebug || Debugger.IsAttached) return false;
|
||||
if (BuildInfo.Version.Revision > 10000) return false; //Official builds will never have such a high revision
|
||||
|
||||
//Official builds will never have such a high revision
|
||||
if (BuildInfo.Version.Revision > 10000) return false;
|
||||
|
||||
try
|
||||
{
|
||||
@ -99,21 +87,23 @@ private static bool InternalIsProduction()
|
||||
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var currentAssmeblyLocation = typeof(RuntimeInfoBase).Assembly.Location;
|
||||
if(currentAssmeblyLocation.ToLower().Contains("_output"))return false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
var currentAssmeblyLocation = typeof(RuntimeInfo).Assembly.Location;
|
||||
if (currentAssmeblyLocation.ToLower().Contains("_output")) return false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
string lowerCurrentDir = Directory.GetCurrentDirectory().ToLower();
|
||||
var lowerCurrentDir = Directory.GetCurrentDirectory().ToLower();
|
||||
if (lowerCurrentDir.Contains("teamcity")) return false;
|
||||
if (lowerCurrentDir.Contains("_output")) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsWindowsTray { get; private set; }
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
using System;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Common.Exceptron
|
||||
{
|
||||
public static class ExceptionExtentions
|
||||
{
|
||||
private const string IGNORE_FLAG = "exceptron_ignore";
|
||||
|
||||
public static Exception ExceptronIgnoreOnMono(this Exception exception)
|
||||
{
|
||||
if (OsInfo.IsNotWindows)
|
||||
{
|
||||
exception.ExceptronIgnore();
|
||||
}
|
||||
|
||||
return exception;
|
||||
}
|
||||
|
||||
public static Exception ExceptronIgnore(this Exception exception)
|
||||
{
|
||||
exception.Data.Add(IGNORE_FLAG, true);
|
||||
return exception;
|
||||
}
|
||||
|
||||
public static bool ExceptronShouldIgnore(this Exception exception)
|
||||
{
|
||||
return exception.Data.Contains(IGNORE_FLAG);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnsureThat;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
@ -47,7 +48,7 @@ public static bool PathEquals(this string firstPath, string secondPath, StringCo
|
||||
{
|
||||
if (!comparison.HasValue)
|
||||
{
|
||||
comparison = OsInfo.PathStringComparison;
|
||||
comparison = DiskProviderBase.PathStringComparison;
|
||||
}
|
||||
|
||||
if (firstPath.Equals(secondPath, comparison.Value)) return true;
|
||||
@ -93,7 +94,7 @@ public static bool IsParentPath(this string parentPath, string childPath)
|
||||
|
||||
while (child.Parent != null)
|
||||
{
|
||||
if (child.Parent.FullName.Equals(parent.FullName, OsInfo.PathStringComparison))
|
||||
if (child.Parent.FullName.Equals(parent.FullName, DiskProviderBase.PathStringComparison))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -275,4 +276,4 @@ public static string GetNlogConfigPath(this IAppFolderInfo appFolderInfo)
|
||||
return Path.Combine(appFolderInfo.StartUpFolder, NLOG_CONFIG_FILE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ public class CurlHttpDispatcher : IHttpDispatcher
|
||||
private static readonly Regex ExpiryDate = new Regex(@"(expires=)([^;]+)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
private readonly IHttpProxySettingsProvider _proxySettingsProvider;
|
||||
private readonly IUserAgentBuilder _userAgentBuilder;
|
||||
private readonly Logger _logger;
|
||||
|
||||
private const string _caBundleFileName = "curl-ca-bundle.crt";
|
||||
@ -38,9 +39,10 @@ static CurlHttpDispatcher()
|
||||
}
|
||||
}
|
||||
|
||||
public CurlHttpDispatcher(IHttpProxySettingsProvider proxySettingsProvider, Logger logger)
|
||||
public CurlHttpDispatcher(IHttpProxySettingsProvider proxySettingsProvider, IUserAgentBuilder userAgentBuilder, Logger logger)
|
||||
{
|
||||
_proxySettingsProvider = proxySettingsProvider;
|
||||
_userAgentBuilder = userAgentBuilder;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
@ -10,21 +10,23 @@ public class FallbackHttpDispatcher : IHttpDispatcher
|
||||
{
|
||||
private readonly ManagedHttpDispatcher _managedDispatcher;
|
||||
private readonly CurlHttpDispatcher _curlDispatcher;
|
||||
private readonly IPlatformInfo _platformInfo;
|
||||
private readonly Logger _logger;
|
||||
|
||||
private readonly ICached<bool> _curlTLSFallbackCache;
|
||||
|
||||
public FallbackHttpDispatcher(ManagedHttpDispatcher managedDispatcher, CurlHttpDispatcher curlDispatcher, ICacheManager cacheManager, Logger logger)
|
||||
public FallbackHttpDispatcher(ManagedHttpDispatcher managedDispatcher, CurlHttpDispatcher curlDispatcher, ICacheManager cacheManager, IPlatformInfo platformInfo, Logger logger)
|
||||
{
|
||||
_managedDispatcher = managedDispatcher;
|
||||
_curlDispatcher = curlDispatcher;
|
||||
_platformInfo = platformInfo;
|
||||
_curlTLSFallbackCache = cacheManager.GetCache<bool>(GetType(), "curlTLSFallback");
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public HttpResponse GetResponse(HttpRequest request, CookieContainer cookies)
|
||||
{
|
||||
if (OsInfo.IsMonoRuntime && request.Url.Scheme == "https")
|
||||
if (PlatformInfo.IsMono && request.Url.Scheme == "https")
|
||||
{
|
||||
if (!_curlTLSFallbackCache.Find(request.Url.Host))
|
||||
{
|
||||
|
@ -13,22 +13,35 @@ public class ManagedHttpDispatcher : IHttpDispatcher
|
||||
{
|
||||
private readonly IHttpProxySettingsProvider _proxySettingsProvider;
|
||||
private readonly ICreateManagedWebProxy _createManagedWebProxy;
|
||||
private readonly IUserAgentBuilder _userAgentBuilder;
|
||||
|
||||
public ManagedHttpDispatcher(IHttpProxySettingsProvider proxySettingsProvider, ICreateManagedWebProxy createManagedWebProxy)
|
||||
public ManagedHttpDispatcher(IHttpProxySettingsProvider proxySettingsProvider, ICreateManagedWebProxy createManagedWebProxy, IUserAgentBuilder userAgentBuilder)
|
||||
{
|
||||
_proxySettingsProvider = proxySettingsProvider;
|
||||
_createManagedWebProxy = createManagedWebProxy;
|
||||
_userAgentBuilder = userAgentBuilder;
|
||||
}
|
||||
|
||||
public HttpResponse GetResponse(HttpRequest request, CookieContainer cookies)
|
||||
{
|
||||
HttpWebResponse httpWebResponse = null;
|
||||
HttpWebRequest webRequest = null;
|
||||
try
|
||||
var webRequest = (HttpWebRequest)WebRequest.Create((Uri)request.Url);
|
||||
|
||||
// Deflate is not a standard and could break depending on implementation.
|
||||
// we should just stick with the more compatible Gzip
|
||||
//http://stackoverflow.com/questions/8490718/how-to-decompress-stream-deflated-with-java-util-zip-deflater-in-net
|
||||
webRequest.AutomaticDecompression = DecompressionMethods.GZip;
|
||||
|
||||
webRequest.Method = request.Method.ToString();
|
||||
webRequest.UserAgent = _userAgentBuilder.GetUserAgent(request.UseSimplifiedUserAgent);
|
||||
webRequest.KeepAlive = request.ConnectionKeepAlive;
|
||||
webRequest.AllowAutoRedirect = false;
|
||||
webRequest.CookieContainer = cookies;
|
||||
|
||||
if (request.RequestTimeout != TimeSpan.Zero)
|
||||
{
|
||||
webRequest = (HttpWebRequest) WebRequest.Create((Uri) request.Url);
|
||||
|
||||
if (OsInfo.IsMonoRuntime)
|
||||
if (PlatformInfo.IsMonoRuntime)
|
||||
{
|
||||
// On Mono GZipStream/DeflateStream leaks memory if an exception is thrown, use an intermediate buffer in that case.
|
||||
webRequest.AutomaticDecompression = DecompressionMethods.None;
|
||||
@ -98,7 +111,7 @@ public HttpResponse GetResponse(HttpRequest request, CookieContainer cookies)
|
||||
{
|
||||
data = responseStream.ToBytes();
|
||||
|
||||
if (OsInfo.IsMonoRuntime && httpWebResponse.ContentEncoding == "gzip")
|
||||
if (PlatformInfo.IsMonoRuntime && httpWebResponse.ContentEncoding == "gzip")
|
||||
{
|
||||
using (var compressedStream = new MemoryStream(data))
|
||||
using (var gzip = new GZipStream(compressedStream, CompressionMode.Decompress))
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
@ -31,12 +31,14 @@ public class HttpClient : IHttpClient
|
||||
private readonly ICached<CookieContainer> _cookieContainerCache;
|
||||
private readonly List<IHttpRequestInterceptor> _requestInterceptors;
|
||||
private readonly IHttpDispatcher _httpDispatcher;
|
||||
private readonly IUserAgentBuilder _userAgentBuilder;
|
||||
|
||||
public HttpClient(IEnumerable<IHttpRequestInterceptor> requestInterceptors, ICacheManager cacheManager, IRateLimitService rateLimitService, IHttpDispatcher httpDispatcher, Logger logger)
|
||||
public HttpClient(IEnumerable<IHttpRequestInterceptor> requestInterceptors, ICacheManager cacheManager, IRateLimitService rateLimitService, IHttpDispatcher httpDispatcher, IUserAgentBuilder userAgentBuilder, Logger logger)
|
||||
{
|
||||
_requestInterceptors = requestInterceptors.ToList();
|
||||
_rateLimitService = rateLimitService;
|
||||
_httpDispatcher = httpDispatcher;
|
||||
_userAgentBuilder = userAgentBuilder;
|
||||
_logger = logger;
|
||||
|
||||
ServicePointManager.DefaultConnectionLimit = 12;
|
||||
@ -71,7 +73,7 @@ public HttpResponse Execute(HttpRequest request)
|
||||
while (response.HasHttpRedirect);
|
||||
}
|
||||
|
||||
if (response.HasHttpRedirect && !RuntimeInfoBase.IsProduction)
|
||||
if (response.HasHttpRedirect && !RuntimeInfo.IsProduction)
|
||||
{
|
||||
_logger.Error("Server requested a redirect to [{0}] while in developer mode. Update the request URL to avoid this redirect.", response.Headers["Location"]);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ public HttpRequest(string url, HttpAccept httpAccept = null)
|
||||
IgnorePersistentCookies = false;
|
||||
Cookies = new Dictionary<string, string>();
|
||||
|
||||
if (!RuntimeInfoBase.IsProduction)
|
||||
if (!RuntimeInfo.IsProduction)
|
||||
{
|
||||
AllowAutoRedirect = false;
|
||||
}
|
||||
|
@ -2,19 +2,39 @@
|
||||
|
||||
namespace NzbDrone.Common.Http
|
||||
{
|
||||
public static class UserAgentBuilder
|
||||
public interface IUserAgentBuilder
|
||||
{
|
||||
public static string UserAgent { get; private set; }
|
||||
public static string UserAgentSimplified { get; private set; }
|
||||
string GetUserAgent(bool simplified = false);
|
||||
}
|
||||
|
||||
static UserAgentBuilder()
|
||||
public class UserAgentBuilder : IUserAgentBuilder
|
||||
{
|
||||
private readonly string _userAgentSimplified;
|
||||
private readonly string _userAgent;
|
||||
|
||||
public string GetUserAgent(bool simplified)
|
||||
{
|
||||
UserAgent = string.Format("Radarr/{0} ({1} {2})",
|
||||
BuildInfo.Version,
|
||||
OsInfo.Os, OsInfo.Version.ToString(2));
|
||||
if (simplified)
|
||||
{
|
||||
return _userAgentSimplified;
|
||||
}
|
||||
|
||||
UserAgentSimplified = string.Format("Radarr/{0}",
|
||||
BuildInfo.Version.ToString(2));
|
||||
return _userAgent;
|
||||
}
|
||||
|
||||
public UserAgentBuilder(IOsInfo osInfo)
|
||||
{
|
||||
var osName = OsInfo.Os.ToString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(osInfo.Name))
|
||||
{
|
||||
osName = osInfo.Name.ToLower();
|
||||
}
|
||||
|
||||
var osVersion = osInfo.Version?.ToLower();
|
||||
|
||||
_userAgent = $"Radarr/{BuildInfo.Version} ({osName} {osVersion})";
|
||||
_userAgentSimplified = $"Radarr/{BuildInfo.Version.ToString(2)}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,89 +0,0 @@
|
||||
using System;
|
||||
using NLog;
|
||||
using NLog.Common;
|
||||
using NLog.Layouts;
|
||||
using NLog.Targets;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Exceptron;
|
||||
using NzbDrone.Common.Exceptron.Configuration;
|
||||
|
||||
namespace NzbDrone.Common.Instrumentation
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="NLog"/> target for exceptron. Allows you to automatically report all
|
||||
/// exceptions logged to Nlog/>
|
||||
/// </summary>
|
||||
[Target("Exceptron")]
|
||||
public class ExceptronTarget : Target
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="ExceptronClient"/> instance that Nlog Target uses to report the exceptions.
|
||||
/// </summary>
|
||||
public IExceptronClient ExceptronClient { get; internal set; }
|
||||
|
||||
protected override void InitializeTarget()
|
||||
{
|
||||
var config = new ExceptronConfiguration
|
||||
{
|
||||
ApiKey = "d64e0a72845d495abc625af3a27cf5f5",
|
||||
IncludeMachineName = true,
|
||||
};
|
||||
|
||||
if (RuntimeInfoBase.IsProduction)
|
||||
{
|
||||
config.ApiKey = "82c0f66dd2d64d1480cc88b551c9bdd8";
|
||||
}
|
||||
|
||||
ExceptronClient = new ExceptronClient(config, BuildInfo.Version);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// String that identifies the active user
|
||||
/// </summary>
|
||||
public Layout UserId { get; set; }
|
||||
|
||||
protected override void Write(LogEventInfo logEvent)
|
||||
{
|
||||
if (logEvent == null || logEvent.Exception == null || logEvent.Exception.ExceptronShouldIgnore()) return;
|
||||
|
||||
try
|
||||
{
|
||||
var exceptionData = new ExceptionData
|
||||
{
|
||||
Exception = logEvent.Exception,
|
||||
Component = logEvent.LoggerName,
|
||||
Message = logEvent.FormattedMessage,
|
||||
};
|
||||
|
||||
if (UserId != null)
|
||||
{
|
||||
exceptionData.UserId = UserId.Render(logEvent);
|
||||
}
|
||||
|
||||
if (logEvent.Level <= LogLevel.Info)
|
||||
{
|
||||
exceptionData.Severity = ExceptionSeverity.None;
|
||||
}
|
||||
else if (logEvent.Level <= LogLevel.Warn)
|
||||
{
|
||||
exceptionData.Severity = ExceptionSeverity.Warning;
|
||||
}
|
||||
else if (logEvent.Level <= LogLevel.Error)
|
||||
{
|
||||
exceptionData.Severity = ExceptionSeverity.Error;
|
||||
}
|
||||
else if (logEvent.Level <= LogLevel.Fatal)
|
||||
{
|
||||
exceptionData.Severity = ExceptionSeverity.Fatal;
|
||||
}
|
||||
|
||||
ExceptronClient.SubmitException(exceptionData);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
InternalLogger.Warn("Unable to report exception. {0}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
@ -35,7 +35,7 @@ private static void HandleAppDomainException(object sender, UnhandledExceptionEv
|
||||
return;
|
||||
}
|
||||
|
||||
if (OsInfo.IsMonoRuntime)
|
||||
if (PlatformInfo.IsMono)
|
||||
{
|
||||
if (exception is TypeInitializationException && exception.InnerException is DllNotFoundException ||
|
||||
exception is DllNotFoundException)
|
||||
@ -51,4 +51,4 @@ private static void HandleAppDomainException(object sender, UnhandledExceptionEv
|
||||
Logger.Fatal(exception, "EPIC FAIL: " + exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using LogentriesNLog;
|
||||
@ -48,7 +48,7 @@ public static void Register(IStartupContext startupContext, bool updateApp, bool
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inConsole && (OsInfo.IsNotWindows || RuntimeInfoBase.IsUserInteractive))
|
||||
if (inConsole && (OsInfo.IsNotWindows || RuntimeInfo.IsUserInteractive))
|
||||
{
|
||||
RegisterConsole();
|
||||
}
|
||||
@ -152,16 +152,6 @@ private static void RegisterUpdateFile(IAppFolderInfo appFolderInfo)
|
||||
LogManager.Configuration.LoggingRules.Add(loggingRule);
|
||||
}
|
||||
|
||||
private static void RegisterExceptron()
|
||||
{
|
||||
var exceptronTarget = new ExceptronTarget();
|
||||
var rule = new LoggingRule("*", LogLevel.Warn, exceptronTarget);
|
||||
|
||||
LogManager.Configuration.AddTarget("ExceptronTarget", exceptronTarget);
|
||||
LogManager.Configuration.LoggingRules.Add(rule);
|
||||
}
|
||||
|
||||
|
||||
public static Logger GetLogger(Type obj)
|
||||
{
|
||||
return LogManager.GetLogger(obj.Name.Replace("NzbDrone.", ""));
|
||||
|
@ -94,6 +94,10 @@
|
||||
<Compile Include="Disk\RelativeFileSystemModel.cs" />
|
||||
<Compile Include="Disk\FileSystemModel.cs" />
|
||||
<Compile Include="Disk\FileSystemResult.cs" />
|
||||
<Compile Include="EnvironmentInfo\IOperatingSystemVersionInfo.cs" />
|
||||
<Compile Include="EnvironmentInfo\IOsVersionAdapter.cs" />
|
||||
<Compile Include="EnvironmentInfo\IPlatformInfo.cs" />
|
||||
<Compile Include="EnvironmentInfo\OsVersionModel.cs" />
|
||||
<Compile Include="Extensions\DictionaryExtensions.cs" />
|
||||
<Compile Include="Disk\GdiPlusInterop.cs" />
|
||||
<Compile Include="Disk\OsPath.cs" />
|
||||
@ -125,13 +129,12 @@
|
||||
<Compile Include="EnvironmentInfo\BuildInfo.cs" />
|
||||
<Compile Include="EnvironmentInfo\OsInfo.cs" />
|
||||
<Compile Include="EnvironmentInfo\IRuntimeInfo.cs" />
|
||||
<Compile Include="EnvironmentInfo\RuntimeInfoBase.cs" />
|
||||
<Compile Include="EnvironmentInfo\RuntimeInfo.cs" />
|
||||
<Compile Include="EnvironmentInfo\StartupContext.cs" />
|
||||
<Compile Include="Exceptions\NotParentException.cs" />
|
||||
<Compile Include="Exceptions\NzbDroneException.cs" />
|
||||
<Compile Include="Exceptron\Configuration\ExceptronConfiguration.cs" />
|
||||
<Compile Include="Exceptron\ExceptionData.cs" />
|
||||
<Compile Include="Exceptron\ExceptionExtentions.cs" />
|
||||
<Compile Include="Exceptron\ExceptionSeverity.cs" />
|
||||
<Compile Include="Exceptron\ExceptronApiException.cs" />
|
||||
<Compile Include="Exceptron\ExceptronClient.cs" />
|
||||
@ -194,7 +197,6 @@
|
||||
<Compile Include="Extensions\IEnumerableExtensions.cs" />
|
||||
<Compile Include="Http\UserAgentBuilder.cs" />
|
||||
<Compile Include="Instrumentation\CleanseLogMessage.cs" />
|
||||
<Compile Include="Instrumentation\ExceptronTarget.cs" />
|
||||
<Compile Include="Instrumentation\Extensions\LoggerProgressExtensions.cs" />
|
||||
<Compile Include="Instrumentation\GlobalExceptionHandlers.cs" />
|
||||
<Compile Include="Instrumentation\LogEventExtensions.cs" />
|
||||
|
@ -108,7 +108,7 @@ public void OpenDefaultBrowser(string url)
|
||||
|
||||
public Process Start(string path, string args = null, StringDictionary environmentVariables = null, Action<string> onOutputDataReceived = null, Action<string> onErrorDataReceived = null)
|
||||
{
|
||||
if (OsInfo.IsMonoRuntime && path.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase))
|
||||
if (PlatformInfo.IsMono && path.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
args = GetMonoArgs(path, args);
|
||||
path = "mono";
|
||||
@ -192,7 +192,7 @@ public Process Start(string path, string args = null, StringDictionary environme
|
||||
|
||||
public Process SpawnNewProcess(string path, string args = null, StringDictionary environmentVariables = null)
|
||||
{
|
||||
if (OsInfo.IsMonoRuntime && path.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase))
|
||||
if (PlatformInfo.IsMono && path.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
args = GetMonoArgs(path, args);
|
||||
path = "mono";
|
||||
|
@ -4,7 +4,7 @@
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
@ -1,9 +1,9 @@
|
||||
using System.Collections.Specialized;
|
||||
using System.Security.AccessControl;
|
||||
using Moq;
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Cache;
|
||||
using NzbDrone.Common.Cloud;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Http.Dispatchers;
|
||||
using NzbDrone.Common.TPL;
|
||||
@ -24,12 +24,16 @@ public abstract class CoreTest : TestBase
|
||||
{
|
||||
protected void UseRealHttp()
|
||||
{
|
||||
Mocker.GetMock<IPlatformInfo>().SetupGet(c => c.Version).Returns(new Version("3.0.0"));
|
||||
Mocker.GetMock<IOsInfo>().SetupGet(c => c.Version).Returns("1.0.0");
|
||||
Mocker.GetMock<IOsInfo>().SetupGet(c => c.Name).Returns("TestOS");
|
||||
|
||||
Mocker.SetConstant<IHttpProxySettingsProvider>(new HttpProxySettingsProvider(Mocker.Resolve<ConfigService>()));
|
||||
Mocker.SetConstant<ICreateManagedWebProxy>(new ManagedWebProxyFactory(Mocker.Resolve<CacheManager>()));
|
||||
Mocker.SetConstant<ManagedHttpDispatcher>(new ManagedHttpDispatcher(Mocker.Resolve<IHttpProxySettingsProvider>(), Mocker.Resolve<ICreateManagedWebProxy>()));
|
||||
Mocker.SetConstant<CurlHttpDispatcher>(new CurlHttpDispatcher(Mocker.Resolve<IHttpProxySettingsProvider>(), Mocker.Resolve<NLog.Logger>()));
|
||||
Mocker.SetConstant<ManagedHttpDispatcher>(new ManagedHttpDispatcher(Mocker.Resolve<IHttpProxySettingsProvider>(), Mocker.Resolve<ICreateManagedWebProxy>(), Mocker.Resolve<UserAgentBuilder>()));
|
||||
Mocker.SetConstant<CurlHttpDispatcher>(new CurlHttpDispatcher(Mocker.Resolve<IHttpProxySettingsProvider>(), Mocker.Resolve<UserAgentBuilder>(), Mocker.Resolve<NLog.Logger>()));
|
||||
Mocker.SetConstant<IHttpProvider>(new HttpProvider(TestLogger));
|
||||
Mocker.SetConstant<IHttpClient>(new HttpClient(new IHttpRequestInterceptor[0], Mocker.Resolve<CacheManager>(), Mocker.Resolve<RateLimitService>(), Mocker.Resolve<FallbackHttpDispatcher>(), TestLogger));
|
||||
Mocker.SetConstant<IHttpClient>(new HttpClient(new IHttpRequestInterceptor[0], Mocker.Resolve<CacheManager>(), Mocker.Resolve<RateLimitService>(), Mocker.Resolve<FallbackHttpDispatcher>(), Mocker.Resolve<UserAgentBuilder>(), TestLogger));
|
||||
Mocker.SetConstant<IRadarrCloudRequestBuilder>(new RadarrCloudRequestBuilder());
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Core.HealthCheck.Checks;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
@ -8,17 +9,12 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
||||
[TestFixture]
|
||||
public class MonoVersionCheckFixture : CoreTest<MonoVersionCheck>
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
MonoOnly();
|
||||
}
|
||||
|
||||
private void GivenOutput(string version)
|
||||
{
|
||||
Mocker.GetMock<IRuntimeInfo>()
|
||||
.SetupGet(s => s.RuntimeVersion)
|
||||
.Returns(string.Format("{0} (tarball Wed Sep 25 16:35:44 CDT 2013)", version));
|
||||
MonoOnly();
|
||||
Mocker.GetMock<IPlatformInfo>()
|
||||
.SetupGet(s => s.Version)
|
||||
.Returns(new Version(version));
|
||||
}
|
||||
|
||||
[TestCase("3.10")]
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Update;
|
||||
@ -10,6 +11,12 @@ namespace NzbDrone.Core.Test.UpdateTests
|
||||
{
|
||||
public class UpdatePackageProviderFixture : CoreTest<UpdatePackageProvider>
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
Mocker.GetMock<IPlatformInfo>().SetupGet(c => c.Version).Returns(new Version("9.9.9"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void no_update_when_version_higher()
|
||||
{
|
||||
|
@ -17,6 +17,6 @@ public AnalyticsService(IConfigFileProvider configFileProvider)
|
||||
_configFileProvider = configFileProvider;
|
||||
}
|
||||
|
||||
public bool IsEnabled => _configFileProvider.AnalyticsEnabled && RuntimeInfoBase.IsProduction;
|
||||
public bool IsEnabled => _configFileProvider.AnalyticsEnabled && RuntimeInfo.IsProduction;
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="FluentMigrator" publicKeyToken="aacfc7de5acabf05" culture="neutral"/>
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnsureThat;
|
||||
@ -373,7 +374,7 @@ public string ChownGroup
|
||||
|
||||
public int FirstDayOfWeek
|
||||
{
|
||||
get { return GetValueInt("FirstDayOfWeek", (int)OsInfo.FirstDayOfWeek); }
|
||||
get { return GetValueInt("FirstDayOfWeek", (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek); }
|
||||
|
||||
set { SetValue("FirstDayOfWeek", value); }
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
@ -9,50 +8,43 @@ namespace NzbDrone.Core.HealthCheck.Checks
|
||||
{
|
||||
public class MonoVersionCheck : HealthCheckBase
|
||||
{
|
||||
private readonly IRuntimeInfo _runtimeInfo;
|
||||
private readonly IPlatformInfo _platformInfo;
|
||||
private readonly Logger _logger;
|
||||
private static readonly Regex VersionRegex = new Regex(@"(?<=\W|^)(?<version>\d+\.\d+(\.\d+)?(\.\d+)?)(?=\W)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
public MonoVersionCheck(IRuntimeInfo runtimeInfo, Logger logger)
|
||||
public MonoVersionCheck(IPlatformInfo platformInfo, Logger logger)
|
||||
{
|
||||
_runtimeInfo = runtimeInfo;
|
||||
_platformInfo = platformInfo;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public override HealthCheck Check()
|
||||
{
|
||||
if (OsInfo.IsWindows)
|
||||
if (!PlatformInfo.IsMono)
|
||||
{
|
||||
return new HealthCheck(GetType());
|
||||
}
|
||||
|
||||
var versionString = _runtimeInfo.RuntimeVersion;
|
||||
var versionMatch = VersionRegex.Match(versionString);
|
||||
var monoVersion = _platformInfo.Version;
|
||||
|
||||
if (versionMatch.Success)
|
||||
if (monoVersion == new Version("3.4.0") && HasMonoBug18599())
|
||||
{
|
||||
var version = new Version(versionMatch.Groups["version"].Value);
|
||||
|
||||
if (version == new Version(3, 4, 0) && HasMonoBug18599())
|
||||
{
|
||||
_logger.Debug("mono version 3.4.0, checking for mono bug #18599 returned positive.");
|
||||
return new HealthCheck(GetType(), HealthCheckResult.Error, "your mono version 3.4.0 has a critical bug, you should upgrade to a higher version");
|
||||
}
|
||||
|
||||
if (version == new Version(4, 4, 0) || version == new Version(4, 4, 1))
|
||||
{
|
||||
_logger.Debug("mono version {0}", version);
|
||||
return new HealthCheck(GetType(), HealthCheckResult.Error, $"your mono version {version} has a bug that causes issues connecting to indexers/download clients");
|
||||
}
|
||||
|
||||
if (version >= new Version(3, 10))
|
||||
{
|
||||
_logger.Debug("mono version is 3.10 or better: {0}", version.ToString());
|
||||
return new HealthCheck(GetType());
|
||||
}
|
||||
_logger.Debug("Mono version 3.4.0, checking for Mono bug #18599 returned positive.");
|
||||
return new HealthCheck(GetType(), HealthCheckResult.Error, "You are running an old and unsupported version of Mono with a known bug. You should upgrade to a higher version");
|
||||
}
|
||||
|
||||
return new HealthCheck(GetType(), HealthCheckResult.Warning, "mono version is less than 3.10, upgrade for improved stability");
|
||||
if (monoVersion == new Version("4.4.0") || monoVersion == new Version("4.4.1"))
|
||||
{
|
||||
_logger.Debug("Mono version {0}", monoVersion);
|
||||
return new HealthCheck(GetType(), HealthCheckResult.Error, $"Your Mono version {monoVersion} has a bug that causes issues connecting to indexers/download clients. You should upgrade to a higher version");
|
||||
}
|
||||
|
||||
if (monoVersion >= new Version("3.10"))
|
||||
{
|
||||
_logger.Debug("Mono version is 3.10 or better: {0}", monoVersion);
|
||||
return new HealthCheck(GetType());
|
||||
}
|
||||
|
||||
return new HealthCheck(GetType(), HealthCheckResult.Warning, "You are running an old and unsupported version of Mono. Please upgrade Mono for improved stability.");
|
||||
}
|
||||
|
||||
public override bool CheckOnConfigChange => false;
|
||||
@ -70,7 +62,8 @@ private bool HasMonoBug18599()
|
||||
return false;
|
||||
}
|
||||
|
||||
var fieldInfo = numberFormatterType.GetField("userFormatProvider", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
var fieldInfo = numberFormatterType.GetField("userFormatProvider",
|
||||
BindingFlags.Static | BindingFlags.NonPublic);
|
||||
|
||||
if (fieldInfo == null)
|
||||
{
|
||||
|
@ -1,18 +1,14 @@
|
||||
using NzbDrone.Common.Messaging;
|
||||
using NzbDrone.Common.Messaging;
|
||||
|
||||
namespace NzbDrone.Core.Lifecycle
|
||||
{
|
||||
public class ApplicationShutdownRequested : IEvent
|
||||
{
|
||||
public bool Restarting { get; set; }
|
||||
public bool Restarting { get; }
|
||||
|
||||
public ApplicationShutdownRequested()
|
||||
{
|
||||
}
|
||||
|
||||
public ApplicationShutdownRequested(bool restarting)
|
||||
public ApplicationShutdownRequested(bool restarting = false)
|
||||
{
|
||||
Restarting = restarting;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +189,6 @@ private bool ChangeFileDateToUtcAirDate(string filePath, DateTime airDateUtc)
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.ExceptronIgnoreOnMono();
|
||||
_logger.Warn(ex, "Unable to set date of file [" + filePath + "]");
|
||||
}
|
||||
}
|
||||
|
@ -7,12 +7,10 @@ public static class RestClientFactory
|
||||
{
|
||||
public static RestClient BuildClient(string baseUrl)
|
||||
{
|
||||
var restClient = new RestClient(baseUrl);
|
||||
|
||||
restClient.UserAgent = string.Format("Radarr/{0} (RestSharp/{1}; {2}/{3})",
|
||||
BuildInfo.Version,
|
||||
restClient.GetType().Assembly.GetName().Version,
|
||||
OsInfo.Os, OsInfo.Version.ToString(2));
|
||||
var restClient = new RestClient(baseUrl)
|
||||
{
|
||||
UserAgent = $"Radarr/{BuildInfo.Version} ({OsInfo.Os})"
|
||||
};
|
||||
|
||||
return restClient;
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
||||
@ -14,16 +13,11 @@ public class CheckUpdateService : ICheckUpdateService
|
||||
private readonly IUpdatePackageProvider _updatePackageProvider;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
|
||||
private readonly Logger _logger;
|
||||
|
||||
|
||||
public CheckUpdateService(IUpdatePackageProvider updatePackageProvider,
|
||||
IConfigFileProvider configFileProvider,
|
||||
Logger logger)
|
||||
IConfigFileProvider configFileProvider)
|
||||
{
|
||||
_updatePackageProvider = updatePackageProvider;
|
||||
_configFileProvider = configFileProvider;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public UpdatePackage AvailableUpdate()
|
||||
@ -31,4 +25,4 @@ public UpdatePackage AvailableUpdate()
|
||||
return _updatePackageProvider.GetLatestUpdate(_configFileProvider.Branch, BuildInfo.Version);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Common.Cloud;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
@ -15,11 +15,13 @@ public interface IUpdatePackageProvider
|
||||
public class UpdatePackageProvider : IUpdatePackageProvider
|
||||
{
|
||||
private readonly IHttpClient _httpClient;
|
||||
private readonly IPlatformInfo _platformInfo;
|
||||
private readonly IHttpRequestBuilderFactory _requestBuilder;
|
||||
|
||||
public UpdatePackageProvider(IHttpClient httpClient, IRadarrCloudRequestBuilder requestBuilder)
|
||||
public UpdatePackageProvider(IHttpClient httpClient, IRadarrCloudRequestBuilder requestBuilder, IPlatformInfo platformInfo)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
_platformInfo = platformInfo;
|
||||
_requestBuilder = requestBuilder.Services;
|
||||
}
|
||||
|
||||
@ -29,6 +31,7 @@ public UpdatePackage GetLatestUpdate(string branch, Version currentVersion)
|
||||
.Resource("/update/{branch}")
|
||||
.AddQueryParam("version", currentVersion)
|
||||
.AddQueryParam("os", OsInfo.Os.ToString().ToLowerInvariant())
|
||||
.AddQueryParam("runtimeVer", _platformInfo.Version)
|
||||
.SetSegment("branch", branch)
|
||||
.Build();
|
||||
|
||||
@ -45,6 +48,7 @@ public List<UpdatePackage> GetRecentUpdates(string branch, Version currentVersio
|
||||
.Resource("/update/{branch}/changes")
|
||||
.AddQueryParam("version", currentVersion)
|
||||
.AddQueryParam("os", OsInfo.Os.ToString().ToLowerInvariant())
|
||||
.AddQueryParam("runtimeVer", _platformInfo.Version)
|
||||
.SetSegment("branch", branch)
|
||||
.Build();
|
||||
|
||||
@ -53,4 +57,4 @@ public List<UpdatePackage> GetRecentUpdates(string branch, Version currentVersio
|
||||
return updates.Resource;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ public class UrlAclAdapter : IUrlAclAdapter
|
||||
private readonly INetshProvider _netshProvider;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IRuntimeInfo _runtimeInfo;
|
||||
private readonly IOsInfo _osInfo;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public List<string> Urls
|
||||
@ -30,7 +31,7 @@ public List<string> Urls
|
||||
}
|
||||
}
|
||||
|
||||
private List<UrlAcl> InternalUrls { get; set; }
|
||||
private List<UrlAcl> InternalUrls { get; }
|
||||
private List<UrlAcl> RegisteredUrls { get; set; }
|
||||
|
||||
private static readonly Regex UrlAclRegex = new Regex(@"(?<scheme>https?)\:\/\/(?<address>.+?)\:(?<port>\d+)/(?<urlbase>.+)?", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
@ -38,19 +39,26 @@ public List<string> Urls
|
||||
public UrlAclAdapter(INetshProvider netshProvider,
|
||||
IConfigFileProvider configFileProvider,
|
||||
IRuntimeInfo runtimeInfo,
|
||||
IOsInfo osInfo,
|
||||
Logger logger)
|
||||
{
|
||||
_netshProvider = netshProvider;
|
||||
_configFileProvider = configFileProvider;
|
||||
_runtimeInfo = runtimeInfo;
|
||||
_osInfo = osInfo;
|
||||
_logger = logger;
|
||||
|
||||
InternalUrls = new List<UrlAcl>();
|
||||
RegisteredUrls = GetRegisteredUrls();
|
||||
RegisteredUrls = new List<UrlAcl>();
|
||||
}
|
||||
|
||||
public void ConfigureUrls()
|
||||
{
|
||||
if (RegisteredUrls.Empty())
|
||||
{
|
||||
GetRegisteredUrls();
|
||||
}
|
||||
|
||||
var localHostHttpUrls = BuildUrlAcls("http", "localhost", _configFileProvider.Port);
|
||||
var interfaceHttpUrls = BuildUrlAcls("http", _configFileProvider.BindAddress, _configFileProvider.Port);
|
||||
|
||||
@ -105,7 +113,8 @@ public void ConfigureUrls()
|
||||
|
||||
private void RefreshRegistration()
|
||||
{
|
||||
if (OsInfo.Version.Major < 6) return;
|
||||
var osVersion = new Version(_osInfo.Version);
|
||||
if (osVersion.Major < 6) return;
|
||||
|
||||
foreach (var urlAcl in InternalUrls)
|
||||
{
|
||||
@ -124,19 +133,24 @@ private bool IsRegistered(UrlAcl urlAcl)
|
||||
c.UrlBase == urlAcl.UrlBase);
|
||||
}
|
||||
|
||||
private List<UrlAcl> GetRegisteredUrls()
|
||||
private void GetRegisteredUrls()
|
||||
{
|
||||
if (OsInfo.IsNotWindows)
|
||||
{
|
||||
return new List<UrlAcl>();
|
||||
return;
|
||||
}
|
||||
|
||||
if (RegisteredUrls.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var arguments = string.Format("http show urlacl");
|
||||
var output = _netshProvider.Run(arguments);
|
||||
|
||||
if (output == null || !output.Standard.Any()) return new List<UrlAcl>();
|
||||
if (output == null || !output.Standard.Any()) return;
|
||||
|
||||
return output.Standard.Select(line =>
|
||||
RegisteredUrls = output.Standard.Select(line =>
|
||||
{
|
||||
var match = UrlAclRegex.Match(line.Content);
|
||||
|
||||
|
@ -58,7 +58,7 @@ public void Start()
|
||||
//_cancelHandler = new CancelHandler();
|
||||
}
|
||||
|
||||
_runtimeInfo.IsRunning = true;
|
||||
_runtimeInfo.IsExiting = false;
|
||||
DbFactory.RegisterDatabase(_container);
|
||||
_hostController.StartServer();
|
||||
|
||||
@ -87,7 +87,7 @@ private void Shutdown()
|
||||
_logger.Info("Attempting to stop application.");
|
||||
_hostController.StopServer();
|
||||
_logger.Info("Application has finished stop routine.");
|
||||
_runtimeInfo.IsRunning = false;
|
||||
_runtimeInfo.IsExiting = true;
|
||||
}
|
||||
|
||||
public void Handle(ApplicationShutdownRequested message)
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using Nancy.Bootstrapper;
|
||||
using NzbDrone.Api;
|
||||
using NzbDrone.Common.Composition;
|
||||
@ -15,26 +15,15 @@ public static IContainer BuildContainer(StartupContext args)
|
||||
var assemblies = new List<string>
|
||||
{
|
||||
"Radarr.Host",
|
||||
"NzbDrone.Common",
|
||||
"NzbDrone.Core",
|
||||
"NzbDrone.Api",
|
||||
"NzbDrone.SignalR"
|
||||
};
|
||||
|
||||
if (OsInfo.IsWindows)
|
||||
{
|
||||
assemblies.Add("NzbDrone.Windows");
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
assemblies.Add("NzbDrone.Mono");
|
||||
}
|
||||
|
||||
return new MainAppContainerBuilder(args, assemblies.ToArray()).Container;
|
||||
return new MainAppContainerBuilder(args, assemblies).Container;
|
||||
}
|
||||
|
||||
private MainAppContainerBuilder(StartupContext args, string[] assemblies)
|
||||
private MainAppContainerBuilder(StartupContext args, List<string> assemblies)
|
||||
: base(args, assemblies)
|
||||
{
|
||||
AutoRegisterImplementations<NzbDronePersistentConnection>();
|
||||
@ -43,4 +32,4 @@ private MainAppContainerBuilder(StartupContext args, string[] assemblies)
|
||||
Container.Register<IHttpDispatcher, FallbackHttpDispatcher>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using NLog;
|
||||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace Radarr.Host
|
||||
{
|
||||
@ -8,14 +9,16 @@ public class Router
|
||||
private readonly INzbDroneServiceFactory _nzbDroneServiceFactory;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IConsoleService _consoleService;
|
||||
private readonly IRuntimeInfo _runtimeInfo;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public Router(INzbDroneServiceFactory nzbDroneServiceFactory, IServiceProvider serviceProvider,
|
||||
IConsoleService consoleService, Logger logger)
|
||||
IConsoleService consoleService, IRuntimeInfo runtimeInfo, Logger logger)
|
||||
{
|
||||
_nzbDroneServiceFactory = nzbDroneServiceFactory;
|
||||
_serviceProvider = serviceProvider;
|
||||
_consoleService = consoleService;
|
||||
_runtimeInfo = runtimeInfo;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@ -34,7 +37,7 @@ public void Route(ApplicationModes applicationModes)
|
||||
|
||||
case ApplicationModes.Interactive:
|
||||
{
|
||||
_logger.Debug("Console selected");
|
||||
_logger.Debug(_runtimeInfo.IsWindowsTray ? "Tray selected" : "Console selected");
|
||||
_nzbDroneServiceFactory.Start();
|
||||
break;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System.Threading;
|
||||
using System.Threading;
|
||||
using NLog;
|
||||
using NLog.Common;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
@ -28,7 +28,7 @@ public SpinService(IRuntimeInfo runtimeInfo, IProcessProvider processProvider, I
|
||||
|
||||
public void Spin()
|
||||
{
|
||||
while (_runtimeInfo.IsRunning)
|
||||
while (!_runtimeInfo.IsExiting)
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
<probing privatePath="libs" />
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" />
|
||||
|
@ -4,7 +4,7 @@
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="FluentMigrator" publicKeyToken="aacfc7de5acabf05" culture="neutral" />
|
||||
|
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Mono.EnvironmentInfo;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Mono.Test.EnvironmentInfo
|
||||
{
|
||||
[TestFixture]
|
||||
[Platform("Mono")]
|
||||
public class MonoPlatformInfoFixture : TestBase<MonoPlatformInfo>
|
||||
{
|
||||
[Test]
|
||||
public void should_get_framework_version()
|
||||
{
|
||||
Subject.Version.Major.Should().BeOneOf(4, 5);
|
||||
if (Subject.Version.Major == 4)
|
||||
{
|
||||
Subject.Version.Minor.Should().BeOneOf(0, 5, 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Mono.Disk;
|
||||
using NzbDrone.Mono.EnvironmentInfo.VersionAdapters;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Mono.Test.EnvironmentInfo
|
||||
{
|
||||
[TestFixture]
|
||||
[Platform("Mono")]
|
||||
public class ReleaseFileVersionAdapterFixture : TestBase<ReleaseFileVersionAdapter>
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
Mocker.SetConstant<IDiskProvider>(Mocker.Resolve<DiskProvider>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_get_version_info()
|
||||
{
|
||||
var info = Subject.Read();
|
||||
info.FullName.Should().NotBeNullOrWhiteSpace();
|
||||
info.Name.Should().NotBeNullOrWhiteSpace();
|
||||
info.Version.Should().NotBeNullOrWhiteSpace();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Mono.EnvironmentInfo.VersionAdapters;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Mono.Test.EnvironmentInfo.VersionAdapters
|
||||
{
|
||||
[TestFixture]
|
||||
public class MacOsVersionAdapterFixture : TestBase<MacOsVersionAdapter>
|
||||
{
|
||||
[TestCase("10.8.0")]
|
||||
[TestCase("10.8")]
|
||||
[TestCase("10.8.1")]
|
||||
[TestCase("10.11.20")]
|
||||
public void should_get_version_info(string versionString)
|
||||
{
|
||||
var fileContent = File.ReadAllText(GetTestPath("Files/macOS/SystemVersion.plist")).Replace("10.0.0", versionString);
|
||||
|
||||
const string plistPath = "/System/Library/CoreServices/SystemVersion.plist";
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(c => c.FolderExists("/System/Library/CoreServices/")).Returns(true);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(c => c.GetFiles("/System/Library/CoreServices/", SearchOption.TopDirectoryOnly))
|
||||
.Returns(new[] { plistPath });
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(c => c.ReadAllText(plistPath))
|
||||
.Returns(fileContent);
|
||||
|
||||
var versionName = Subject.Read();
|
||||
versionName.Version.Should().Be(versionString);
|
||||
versionName.Name.Should().Be("macOS");
|
||||
versionName.FullName.Should().Be("macOS " + versionString);
|
||||
}
|
||||
|
||||
|
||||
[TestCase]
|
||||
public void should_detect_server()
|
||||
{
|
||||
var fileContent = File.ReadAllText(GetTestPath("Files/macOS/SystemVersion.plist"));
|
||||
|
||||
const string plistPath = "/System/Library/CoreServices/ServerVersion.plist";
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(c => c.FolderExists("/System/Library/CoreServices/")).Returns(true);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(c => c.GetFiles("/System/Library/CoreServices/", SearchOption.TopDirectoryOnly))
|
||||
.Returns(new[] { plistPath });
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(c => c.ReadAllText(plistPath))
|
||||
.Returns(fileContent);
|
||||
|
||||
var versionName = Subject.Read();
|
||||
versionName.Name.Should().Be("macOS Server");
|
||||
}
|
||||
|
||||
[TestCase]
|
||||
public void should_return_null_if_folder_doesnt_exist()
|
||||
{
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(c => c.FolderExists("/System/Library/CoreServices/")).Returns(false);
|
||||
|
||||
Subject.Read().Should().BeNull();
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(c => c.GetFiles(It.IsAny<string>(), SearchOption.TopDirectoryOnly), Times.Never());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
using System.IO;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Mono.Disk;
|
||||
using NzbDrone.Mono.EnvironmentInfo.VersionAdapters;
|
||||
using NzbDrone.Test.Common;
|
||||
using NzbDrone.Test.Common.Categories;
|
||||
|
||||
namespace NzbDrone.Mono.Test.EnvironmentInfo.VersionAdapters
|
||||
{
|
||||
[TestFixture]
|
||||
public class ReleaseFileVersionAdapterFixture : TestBase<ReleaseFileVersionAdapter>
|
||||
{
|
||||
[Test]
|
||||
[IntegrationTest]
|
||||
[Platform("Mono")]
|
||||
public void should_get_version_info_from_actual_linux()
|
||||
{
|
||||
Mocker.SetConstant<IDiskProvider>(Mocker.Resolve<DiskProvider>());
|
||||
var info = Subject.Read();
|
||||
info.FullName.Should().NotBeNullOrWhiteSpace();
|
||||
info.Name.Should().NotBeNullOrWhiteSpace();
|
||||
info.Version.Should().NotBeNullOrWhiteSpace();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_null_if_etc_doestn_exist()
|
||||
{
|
||||
Mocker.GetMock<IDiskProvider>().Setup(c => c.FolderExists("/etc/")).Returns(false);
|
||||
Subject.Read().Should().BeNull();
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(c => c.GetFiles(It.IsAny<string>(), SearchOption.TopDirectoryOnly), Times.Never());
|
||||
|
||||
Subject.Read().Should().BeNull();
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void should_return_null_if_release_file_doestn_exist()
|
||||
{
|
||||
Mocker.GetMock<IDiskProvider>().Setup(c => c.FolderExists("/etc/")).Returns(true);
|
||||
Subject.Read().Should().BeNull();
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(c => c.GetFiles(It.IsAny<string>(), SearchOption.TopDirectoryOnly)).Returns(new string[0]);
|
||||
|
||||
Subject.Read().Should().BeNull();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_detect_version()
|
||||
{
|
||||
Mocker.GetMock<IDiskProvider>().Setup(c => c.FolderExists("/etc/")).Returns(true);
|
||||
Subject.Read().Should().BeNull();
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(c => c.GetFiles(It.IsAny<string>(), SearchOption.TopDirectoryOnly)).Returns(new[]
|
||||
{
|
||||
"/etc/lsb-release",
|
||||
"/etc/os-release"
|
||||
});
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(c => c.ReadAllText("/etc/lsb-release"))
|
||||
.Returns(File.ReadAllText(GetTestPath("Files/linux/lsb-release")));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(c => c.ReadAllText("/etc/os-release"))
|
||||
.Returns(File.ReadAllText(GetTestPath("Files/linux/os-release")));
|
||||
|
||||
var version = Subject.Read();
|
||||
version.Should().NotBeNull();
|
||||
version.Name.Should().Be("ubuntu");
|
||||
version.Version.Should().Be("14.04");
|
||||
version.FullName.Should().Be("Ubuntu 14.04.5 LTS");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
4
src/NzbDrone.Mono.Test/Files/linux/lsb-release
Normal file
4
src/NzbDrone.Mono.Test/Files/linux/lsb-release
Normal file
@ -0,0 +1,4 @@
|
||||
DISTRIB_ID=Ubuntu
|
||||
DISTRIB_RELEASE=14.04
|
||||
DISTRIB_CODENAME=trusty
|
||||
DISTRIB_DESCRIPTION="Ubuntu 14.04.5 LTS"
|
9
src/NzbDrone.Mono.Test/Files/linux/os-release
Normal file
9
src/NzbDrone.Mono.Test/Files/linux/os-release
Normal file
@ -0,0 +1,9 @@
|
||||
NAME="Ubuntu"
|
||||
VERSION="14.04.5 LTS, Trusty Tahr"
|
||||
ID=ubuntu
|
||||
ID_LIKE=debian
|
||||
PRETTY_NAME="Ubuntu 14.04.5 LTS"
|
||||
VERSION_ID="14.04"
|
||||
HOME_URL="http://www.ubuntu.com/"
|
||||
SUPPORT_URL="http://help.ubuntu.com/"
|
||||
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
|
16
src/NzbDrone.Mono.Test/Files/macOS/SystemVersion.plist
Normal file
16
src/NzbDrone.Mono.Test/Files/macOS/SystemVersion.plist
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>ProductBuildVersion</key>
|
||||
<string>16C68</string>
|
||||
<key>ProductCopyright</key>
|
||||
<string>1983-2016 Apple Inc.</string>
|
||||
<key>ProductName</key>
|
||||
<string>Mac OS X</string>
|
||||
<key>ProductUserVisibleVersion</key>
|
||||
<string>10.0.0</string>
|
||||
<key>ProductVersion</key>
|
||||
<string>10.0.0</string>
|
||||
</dict>
|
||||
</plist>
|
8
src/NzbDrone.Mono.Test/Files/synology/VERSION
Normal file
8
src/NzbDrone.Mono.Test/Files/synology/VERSION
Normal file
@ -0,0 +1,8 @@
|
||||
majorversion="6"
|
||||
minorversion="0"
|
||||
productversion="6.0.2"
|
||||
buildphase="hotfix"
|
||||
buildnumber="8451"
|
||||
smallfixnumber="7"
|
||||
builddate="2016/12/20"
|
||||
buildtime="05:11:44"
|
@ -82,10 +82,26 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="DiskProviderTests\DiskProviderFixture.cs" />
|
||||
<Compile Include="DiskProviderTests\FreeSpaceFixture.cs" />
|
||||
<Compile Include="EnvironmentInfo\MonoPlatformInfoFixture.cs" />
|
||||
<Compile Include="EnvironmentInfo\ReleaseFileVersionAdapterFixture.cs" />
|
||||
<Compile Include="EnvironmentInfo\VersionAdapters\MacOsVersionAdapterFixture.cs" />
|
||||
<Compile Include="EnvironmentInfo\VersionAdapters\ReleaseFileVersionAdapterFixture.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="Files\linux\lsb-release">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Files\linux\os-release">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Files\macOS\SystemVersion.plist">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Files\synology\VERSION">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -8,7 +8,7 @@
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="FluentMigrator" publicKeyToken="aacfc7de5acabf05" culture="neutral" />
|
||||
|
46
src/NzbDrone.Mono/EnvironmentInfo/MonoPlatformInfo.cs
Normal file
46
src/NzbDrone.Mono/EnvironmentInfo/MonoPlatformInfo.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Mono.EnvironmentInfo
|
||||
{
|
||||
public class MonoPlatformInfo : PlatformInfo
|
||||
{
|
||||
private static readonly Regex VersionRegex = new Regex(@"(?<=\W|^)(?<version>\d+\.\d+(\.\d+)?(\.\d+)?)(?=\W)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
public override Version Version { get; }
|
||||
|
||||
public MonoPlatformInfo(Logger logger)
|
||||
{
|
||||
var runTimeVersion = new Version();
|
||||
|
||||
try
|
||||
{
|
||||
var type = Type.GetType("Mono.Runtime");
|
||||
|
||||
if (type != null)
|
||||
{
|
||||
var displayNameMethod = type.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
if (displayNameMethod != null)
|
||||
{
|
||||
var displayName = displayNameMethod.Invoke(null, null).ToString();
|
||||
var versionMatch = VersionRegex.Match(displayName);
|
||||
|
||||
if (versionMatch.Success)
|
||||
{
|
||||
runTimeVersion = new Version(versionMatch.Groups["version"].Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, "Unable to get mono version");
|
||||
}
|
||||
|
||||
|
||||
Version = runTimeVersion;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Mono.EnvironmentInfo
|
||||
{
|
||||
public class MonoRuntimeProvider : RuntimeInfoBase
|
||||
{
|
||||
private readonly Logger _logger;
|
||||
|
||||
public MonoRuntimeProvider(Common.IServiceProvider serviceProvider, Logger logger)
|
||||
:base(serviceProvider, logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public override string RuntimeVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var type = Type.GetType("Mono.Runtime");
|
||||
|
||||
if (type != null)
|
||||
{
|
||||
var displayName = type.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
|
||||
if (displayName != null)
|
||||
{
|
||||
return displayName.Invoke(null, null).ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex, "Unable to get mono version: " + ex.Message);
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Mono.EnvironmentInfo.VersionAdapters
|
||||
{
|
||||
public class IssueFileVersionAdapter : IOsVersionAdapter
|
||||
{
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
|
||||
public IssueFileVersionAdapter(IDiskProvider diskProvider)
|
||||
{
|
||||
_diskProvider = diskProvider;
|
||||
}
|
||||
|
||||
public OsVersionModel Read()
|
||||
{
|
||||
if (!_diskProvider.FolderExists("/etc/"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var issueFile = _diskProvider.GetFiles("/etc/", SearchOption.TopDirectoryOnly).SingleOrDefault(c => c.EndsWith("/issue"));
|
||||
|
||||
if (issueFile == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var fileContent = _diskProvider.ReadAllText(issueFile);
|
||||
|
||||
|
||||
// Ubuntu 14.04.5 LTS \n \l
|
||||
// Ubuntu 16.04.1 LTS \n \l
|
||||
|
||||
// Fedora/Centos
|
||||
// Kernel \r on an \m (\l)
|
||||
|
||||
// Arch Linux \r (\l)
|
||||
// Debian GNU/Linux 8 \n \l
|
||||
if (fileContent.Contains("Arch Linux"))
|
||||
{
|
||||
return new OsVersionModel("Arch", "1.0", "Arch Linux");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool Enabled => OsInfo.IsLinux;
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Mono.EnvironmentInfo.VersionAdapters
|
||||
{
|
||||
public class MacOsVersionAdapter : IOsVersionAdapter
|
||||
{
|
||||
private static readonly Regex DarwinVersionRegex = new Regex("<string>(?<version>10\\.\\d{1,2}\\.?\\d{0,2}?)<\\/string>",
|
||||
RegexOptions.Compiled |
|
||||
RegexOptions.IgnoreCase
|
||||
);
|
||||
|
||||
private const string PLIST_DIR = "/System/Library/CoreServices/";
|
||||
|
||||
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public MacOsVersionAdapter(IDiskProvider diskProvider, Logger logger)
|
||||
{
|
||||
_diskProvider = diskProvider;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public OsVersionModel Read()
|
||||
{
|
||||
var version = "10.0";
|
||||
|
||||
if (!_diskProvider.FolderExists(PLIST_DIR))
|
||||
{
|
||||
_logger.Debug("Directory {0} doesn't exist", PLIST_DIR);
|
||||
return null;
|
||||
}
|
||||
|
||||
var allFiles = _diskProvider.GetFiles(PLIST_DIR, SearchOption.TopDirectoryOnly);
|
||||
|
||||
var versionFile = allFiles.SingleOrDefault(c =>
|
||||
c.EndsWith("SystemVersion.plist") ||
|
||||
c.EndsWith("ServerVersion.plist")
|
||||
);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(versionFile))
|
||||
{
|
||||
_logger.Debug("Couldn't find version plist file in {0}", PLIST_DIR);
|
||||
return null;
|
||||
}
|
||||
|
||||
var text = _diskProvider.ReadAllText(versionFile);
|
||||
var match = DarwinVersionRegex.Match(text);
|
||||
|
||||
|
||||
|
||||
if (match.Success)
|
||||
{
|
||||
version = match.Groups["version"].Value;
|
||||
}
|
||||
|
||||
var name = versionFile.Contains("Server") ? "macOS Server" : "macOS";
|
||||
|
||||
return new OsVersionModel(name, version);
|
||||
}
|
||||
|
||||
public bool Enabled => OsInfo.IsOsx;
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Mono.EnvironmentInfo.VersionAdapters
|
||||
{
|
||||
public class ReleaseFileVersionAdapter : IOsVersionAdapter
|
||||
{
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
|
||||
public ReleaseFileVersionAdapter(IDiskProvider diskProvider)
|
||||
{
|
||||
_diskProvider = diskProvider;
|
||||
}
|
||||
|
||||
public OsVersionModel Read()
|
||||
{
|
||||
if (!_diskProvider.FolderExists("/etc/"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var releaseFiles = _diskProvider.GetFiles("/etc/", SearchOption.TopDirectoryOnly).Where(c => c.EndsWith("release")).ToList();
|
||||
|
||||
var name = "Linux";
|
||||
var fullName = "";
|
||||
var version = "";
|
||||
|
||||
bool success = false;
|
||||
|
||||
foreach (var releaseFile in releaseFiles)
|
||||
{
|
||||
var fileContent = _diskProvider.ReadAllText(releaseFile);
|
||||
var lines = Regex.Split(fileContent, "\r\n|\r|\n"); ;
|
||||
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var parts = line.Split('=');
|
||||
if (parts.Length >= 2)
|
||||
{
|
||||
var key = parts[0];
|
||||
var value = parts[1];
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case "ID":
|
||||
success = true;
|
||||
name = value;
|
||||
break;
|
||||
case "PRETTY_NAME":
|
||||
success = true;
|
||||
fullName = value;
|
||||
break;
|
||||
case "VERSION_ID":
|
||||
success = true;
|
||||
version = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new OsVersionModel(name, version, fullName);
|
||||
|
||||
}
|
||||
|
||||
public bool Enabled => OsInfo.IsLinux;
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Mono.EnvironmentInfo.VersionAdapters
|
||||
{
|
||||
public class SynologyVersionAdapter : IOsVersionAdapter
|
||||
{
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private const string NAME = "DSM";
|
||||
private const string FULL_NAME = "Synology DSM";
|
||||
|
||||
|
||||
public SynologyVersionAdapter(IDiskProvider diskProvider)
|
||||
{
|
||||
_diskProvider = diskProvider;
|
||||
}
|
||||
|
||||
public OsVersionModel Read()
|
||||
{
|
||||
if (!_diskProvider.FolderExists("/etc.defaults/"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var versionFile = _diskProvider.GetFiles("/etc.defaults/", SearchOption.TopDirectoryOnly).SingleOrDefault(c => c.EndsWith("VERSION"));
|
||||
|
||||
if (versionFile == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var version = "";
|
||||
var major = "";
|
||||
var minor = "0";
|
||||
|
||||
var fileContent = _diskProvider.ReadAllText(versionFile);
|
||||
var lines = Regex.Split(fileContent, "\r\n|\r|\n"); ;
|
||||
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var parts = line.Split('=');
|
||||
if (parts.Length >= 2)
|
||||
{
|
||||
var key = parts[0];
|
||||
var value = parts[1].Trim('"');
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case "productversion":
|
||||
version = value;
|
||||
break;
|
||||
case "majorversion":
|
||||
major = value;
|
||||
break;
|
||||
case "minorversion":
|
||||
minor = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(version) && !string.IsNullOrWhiteSpace(major))
|
||||
{
|
||||
version = $"{major}.{minor}";
|
||||
}
|
||||
|
||||
return new OsVersionModel(NAME, version, $"{FULL_NAME} {version}");
|
||||
}
|
||||
|
||||
public bool Enabled => OsInfo.IsLinux;
|
||||
}
|
||||
}
|
@ -79,9 +79,13 @@
|
||||
<Compile Include="Disk\DiskProvider.cs" />
|
||||
<Compile Include="Disk\FindDriveType.cs" />
|
||||
<Compile Include="Disk\LinuxPermissionsException.cs" />
|
||||
<Compile Include="EnvironmentInfo\MonoRuntimeProvider.cs" />
|
||||
<Compile Include="EnvironmentInfo\MonoPlatformInfo.cs" />
|
||||
<Compile Include="Disk\ProcMount.cs" />
|
||||
<Compile Include="Disk\ProcMountProvider.cs" />
|
||||
<Compile Include="EnvironmentInfo\VersionAdapters\IssueFileVersionAdapter.cs" />
|
||||
<Compile Include="EnvironmentInfo\VersionAdapters\MacOsVersionAdapter.cs" />
|
||||
<Compile Include="EnvironmentInfo\VersionAdapters\ReleaseFileVersionAdapter.cs" />
|
||||
<Compile Include="EnvironmentInfo\VersionAdapters\SynologyVersionAdapter.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Disk\SymbolicLinkResolver.cs" />
|
||||
</ItemGroup>
|
||||
@ -92,6 +96,7 @@
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
|
11
src/NzbDrone.Mono/app.config
Normal file
11
src/NzbDrone.Mono/app.config
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
@ -4,7 +4,7 @@
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="FluentMigrator" publicKeyToken="aacfc7de5acabf05" culture="neutral"/>
|
||||
|
@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
@ -151,7 +149,7 @@ private static void AddTheAutoMockingContainerExtensionToTheContainer(IUnityCont
|
||||
|
||||
private Mock<T> TheRegisteredMockForThisType<T>(Type type) where T : class
|
||||
{
|
||||
return (Mock<T>)_registeredMocks.Where(x => x.Key == type).First().Value;
|
||||
return (Mock<T>)_registeredMocks.First(x => x.Key == type).Value;
|
||||
}
|
||||
|
||||
private void CreateANewMockAndRegisterIt<T>(Type type, MockBehavior behavior) where T : class
|
||||
@ -190,4 +188,4 @@ private void RegisterPlatformLibrary(IUnityContainer container)
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using FluentAssertions;
|
||||
@ -133,7 +133,7 @@ protected void WindowsOnly()
|
||||
|
||||
protected void MonoOnly()
|
||||
{
|
||||
if (OsInfo.IsWindows)
|
||||
if (!PlatformInfo.IsMono)
|
||||
{
|
||||
throw new IgnoreException("mono specific test");
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Common.Composition;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Http.Dispatchers;
|
||||
@ -7,7 +7,7 @@ namespace NzbDrone.Update
|
||||
{
|
||||
public class UpdateContainerBuilder : ContainerBuilderBase
|
||||
{
|
||||
private UpdateContainerBuilder(IStartupContext startupContext, string[] assemblies)
|
||||
private UpdateContainerBuilder(IStartupContext startupContext, List<string> assemblies)
|
||||
: base(startupContext, assemblies)
|
||||
{
|
||||
Container.Register<IHttpDispatcher, FallbackHttpDispatcher>();
|
||||
@ -17,22 +17,10 @@ public static IContainer Build(IStartupContext startupContext)
|
||||
{
|
||||
var assemblies = new List<string>
|
||||
{
|
||||
"Radarr.Update",
|
||||
"NzbDrone.Common"
|
||||
"Radarr.Update"
|
||||
};
|
||||
|
||||
if (OsInfo.IsWindows)
|
||||
{
|
||||
assemblies.Add("NzbDrone.Windows");
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
assemblies.Add("NzbDrone.Mono");
|
||||
}
|
||||
|
||||
return new UpdateContainerBuilder(startupContext, assemblies.ToArray()).Container;
|
||||
return new UpdateContainerBuilder(startupContext, assemblies).Container;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ public AppType GetAppType()
|
||||
{
|
||||
if (OsInfo.IsNotWindows)
|
||||
{
|
||||
//Tehcnically its the console, but its been renamed for mono (Linux/OS X)
|
||||
//Tehcnically it is the console, but it has been renamed for mono (Linux/OS X)
|
||||
return AppType.Normal;
|
||||
}
|
||||
|
||||
@ -42,4 +42,4 @@ public AppType GetAppType()
|
||||
return AppType.Normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
@ -0,0 +1,19 @@
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
using NzbDrone.Windows.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Windows.Test.EnvironmentInfo
|
||||
{
|
||||
[TestFixture]
|
||||
[Platform("Win")]
|
||||
public class DotNetPlatformInfoFixture : TestBase<DotNetPlatformInfo>
|
||||
{
|
||||
[Test]
|
||||
public void should_get_framework_version()
|
||||
{
|
||||
Subject.Version.Major.Should().Be(4);
|
||||
Subject.Version.Minor.Should().BeOneOf(0, 5, 6);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
using NzbDrone.Windows.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Windows.Test.EnvironmentInfo
|
||||
{
|
||||
[TestFixture]
|
||||
[Platform("Win")]
|
||||
public class WindowsVersionInfoFixture : TestBase<WindowsVersionInfo>
|
||||
{
|
||||
[Test]
|
||||
public void should_get_windows_version()
|
||||
{
|
||||
var info = Subject.Read();
|
||||
info.Version.Should().NotBeNullOrWhiteSpace();
|
||||
info.Name.Should().Contain("Windows");
|
||||
info.FullName.Should().Contain("Windows");
|
||||
info.FullName.Should().Contain("NT");
|
||||
info.FullName.Should().Contain(info.Version);
|
||||
}
|
||||
}
|
||||
}
|
@ -75,6 +75,8 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="DiskProviderTests\DiskProviderFixture.cs" />
|
||||
<Compile Include="DiskProviderTests\FreeSpaceFixture.cs" />
|
||||
<Compile Include="EnvironmentInfo\DotNetPlatformInfoFixture.cs" />
|
||||
<Compile Include="EnvironmentInfo\WindowsVersionInfoFixture.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -8,7 +8,7 @@
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="FluentMigrator" publicKeyToken="aacfc7de5acabf05" culture="neutral" />
|
||||
|
70
src/NzbDrone.Windows/EnvironmentInfo/DotNetPlatformInfo.cs
Normal file
70
src/NzbDrone.Windows/EnvironmentInfo/DotNetPlatformInfo.cs
Normal file
@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using Microsoft.Win32;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Windows.EnvironmentInfo
|
||||
{
|
||||
public class DotNetPlatformInfo : PlatformInfo
|
||||
{
|
||||
private readonly Logger _logger;
|
||||
|
||||
public DotNetPlatformInfo(Logger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
var version = GetFrameworkVersion();
|
||||
Environment.SetEnvironmentVariable("RUNTIME_VERSION", version.ToString());
|
||||
Version = version;
|
||||
}
|
||||
|
||||
public override Version Version { get; }
|
||||
|
||||
private Version GetFrameworkVersion()
|
||||
{
|
||||
try
|
||||
{
|
||||
const string subkey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\";
|
||||
using (var ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(subkey))
|
||||
{
|
||||
if (ndpKey == null)
|
||||
{
|
||||
return new Version(4, 0);
|
||||
}
|
||||
|
||||
var releaseKey = (int)ndpKey.GetValue("Release");
|
||||
|
||||
if (releaseKey >= 394802)
|
||||
{
|
||||
return new Version(4, 6, 2);
|
||||
}
|
||||
if (releaseKey >= 394254)
|
||||
{
|
||||
return new Version(4, 6, 1);
|
||||
}
|
||||
if (releaseKey >= 393295)
|
||||
{
|
||||
return new Version(4, 6);
|
||||
}
|
||||
if (releaseKey >= 379893)
|
||||
{
|
||||
return new Version(4, 5, 2);
|
||||
}
|
||||
if (releaseKey >= 378675)
|
||||
{
|
||||
return new Version(4, 5, 1);
|
||||
}
|
||||
if (releaseKey >= 378389)
|
||||
{
|
||||
return new Version(4, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error(e, "Couldnt get .NET framework version");
|
||||
}
|
||||
|
||||
return new Version(4, 0);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
using System;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Windows.EnvironmentInfo
|
||||
{
|
||||
public class DotNetRuntimeProvider : RuntimeInfoBase
|
||||
{
|
||||
public DotNetRuntimeProvider(Common.IServiceProvider serviceProvider, Logger logger)
|
||||
: base(serviceProvider, logger)
|
||||
{
|
||||
}
|
||||
|
||||
public override string RuntimeVersion => Environment.Version.ToString();
|
||||
}
|
||||
}
|
49
src/NzbDrone.Windows/EnvironmentInfo/WindowsVersionInfo.cs
Normal file
49
src/NzbDrone.Windows/EnvironmentInfo/WindowsVersionInfo.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using Microsoft.Win32;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Windows.EnvironmentInfo
|
||||
{
|
||||
public class WindowsVersionInfo : IOsVersionAdapter
|
||||
{
|
||||
private readonly Logger _logger;
|
||||
public bool Enabled => OsInfo.IsWindows;
|
||||
|
||||
public WindowsVersionInfo(Logger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public OsVersionModel Read()
|
||||
{
|
||||
var windowsServer = IsServer();
|
||||
var osName = windowsServer ? "Windows Server" : "Windows";
|
||||
return new OsVersionModel(osName, Environment.OSVersion.Version.ToString(), Environment.OSVersion.VersionString);
|
||||
}
|
||||
|
||||
private bool IsServer()
|
||||
{
|
||||
try
|
||||
{
|
||||
const string subkey = @"Software\Microsoft\Windows NT\CurrentVersion";
|
||||
var openSubKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(subkey);
|
||||
if (openSubKey != null)
|
||||
{
|
||||
var productName = openSubKey.GetValue("ProductName").ToString();
|
||||
|
||||
if (productName.ToLower().Contains("server"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error(e, "Couldn't detect if running Windows Server");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -73,7 +73,8 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Disk\DiskProvider.cs" />
|
||||
<Compile Include="EnvironmentInfo\DotNetRuntimeProvider.cs" />
|
||||
<Compile Include="EnvironmentInfo\DotNetPlatformInfo.cs" />
|
||||
<Compile Include="EnvironmentInfo\WindowsVersionInfo.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -83,6 +84,7 @@
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
|
11
src/NzbDrone.Windows/app.config
Normal file
11
src/NzbDrone.Windows/app.config
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
4
tools/desktop.ini
Normal file
4
tools/desktop.ini
Normal file
@ -0,0 +1,4 @@
|
||||
[ViewState]
|
||||
Mode=
|
||||
Vid=
|
||||
FolderType=Documents
|
Loading…
Reference in New Issue
Block a user