mirror of
https://github.com/Radarr/Radarr
synced 2025-12-13 20:05:11 +01:00
Modernize startup and ConfigFileProvider
This commit is contained in:
parent
e3468daba0
commit
41e8f7aa45
58 changed files with 704 additions and 853 deletions
|
|
@ -1,4 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
|
|
@ -13,7 +13,7 @@ namespace NzbDrone.Common.Test
|
|||
{
|
||||
[TestFixture]
|
||||
|
||||
public class ConfigFileProviderTest : TestBase<ConfigFileProvider>
|
||||
public class ConfigFileWriterTest : TestBase<ConfigFileWriter>
|
||||
{
|
||||
private string _configFileContents;
|
||||
private string _configFilePath;
|
||||
|
|
@ -45,56 +45,7 @@ protected void WithMockConfigFile(string configFile)
|
|||
.Callback<string, string>((p, t) => _configFileContents = t);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetValue_Success()
|
||||
{
|
||||
const string key = "Port";
|
||||
const string value = "7878";
|
||||
|
||||
var result = Subject.GetValue(key, value);
|
||||
|
||||
result.Should().Be(value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetInt_Success()
|
||||
{
|
||||
const string key = "Port";
|
||||
const int value = 7878;
|
||||
|
||||
var result = Subject.GetValueInt(key, value);
|
||||
|
||||
result.Should().Be(value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetBool_Success()
|
||||
{
|
||||
const string key = "LaunchBrowser";
|
||||
const bool value = true;
|
||||
|
||||
var result = Subject.GetValueBoolean(key, value);
|
||||
|
||||
result.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetLaunchBrowser_Success()
|
||||
{
|
||||
var result = Subject.LaunchBrowser;
|
||||
|
||||
result.Should().Be(true);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetPort_Success()
|
||||
{
|
||||
const int value = 7878;
|
||||
|
||||
var result = Subject.Port;
|
||||
|
||||
result.Should().Be(value);
|
||||
}
|
||||
/*
|
||||
|
||||
[Test]
|
||||
public void SetValue_bool()
|
||||
|
|
@ -120,17 +71,6 @@ public void SetValue_int()
|
|||
result.Should().Be(value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetValue_New_Key()
|
||||
{
|
||||
const string key = "Hello";
|
||||
const string value = "World";
|
||||
|
||||
var result = Subject.GetValue(key, value);
|
||||
|
||||
result.Should().Be(value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetAuthenticationType_No_Existing_Value()
|
||||
{
|
||||
|
|
@ -139,6 +79,7 @@ public void GetAuthenticationType_No_Existing_Value()
|
|||
result.Should().Be(AuthenticationType.None);
|
||||
}
|
||||
|
||||
/*
|
||||
[Test]
|
||||
public void SaveDictionary_should_save_proper_value()
|
||||
{
|
||||
|
|
@ -170,32 +111,6 @@ public void SaveDictionary_should_only_save_specified_values()
|
|||
|
||||
Subject.Port.Should().Be(port);
|
||||
Subject.SslPort.Should().Be(sslPort);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_if_config_file_is_empty()
|
||||
{
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.FileExists(_configFilePath))
|
||||
.Returns(true);
|
||||
|
||||
Assert.Throws<InvalidConfigFileException>(() => Subject.GetValue("key", "value"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_if_config_file_contains_only_null_character()
|
||||
{
|
||||
_configFileContents = "\0";
|
||||
|
||||
Assert.Throws<InvalidConfigFileException>(() => Subject.GetValue("key", "value"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_if_config_file_contains_invalid_xml()
|
||||
{
|
||||
_configFileContents = "{ \"key\": \"value\" }";
|
||||
|
||||
Assert.Throws<InvalidConfigFileException>(() => Subject.GetValue("key", "value"));
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
using NzbDrone.Common.Composition.Extensions;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Instrumentation.Extensions;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Datastore.Extensions;
|
||||
using NzbDrone.Core.Lifecycle;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
|
|
@ -32,7 +32,7 @@ public void event_handlers_should_be_unique()
|
|||
.AddStartupContext(new StartupContext("first", "second"));
|
||||
|
||||
container.RegisterInstance(new Mock<IHostLifetime>().Object);
|
||||
container.RegisterInstance(new Mock<IOptions<PostgresOptions>>().Object);
|
||||
container.RegisterInstance(new Mock<IOptions<ConfigFileOptions>>().Object);
|
||||
|
||||
var serviceProvider = container.GetServiceProvider();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
|
|
|
|||
|
|
@ -3,9 +3,11 @@
|
|||
using System.Data.SQLite;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using Npgsql;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Extensions;
|
||||
|
|
@ -124,13 +126,13 @@ private IDatabase CreateDatabase(MigrationContext migrationContext)
|
|||
|
||||
private void CreatePostgresDb()
|
||||
{
|
||||
var options = Mocker.Resolve<IOptions<PostgresOptions>>().Value;
|
||||
var options = Mocker.Resolve<IOptionsMonitor<ConfigFileOptions>>().CurrentValue;
|
||||
PostgresDatabase.Create(options, MigrationType);
|
||||
}
|
||||
|
||||
private void DropPostgresDb()
|
||||
{
|
||||
var options = Mocker.Resolve<IOptions<PostgresOptions>>().Value;
|
||||
var options = Mocker.Resolve<IOptionsMonitor<ConfigFileOptions>>().CurrentValue;
|
||||
PostgresDatabase.Drop(options, MigrationType);
|
||||
}
|
||||
|
||||
|
|
@ -174,12 +176,11 @@ protected void SetupContainer()
|
|||
SetupLogging();
|
||||
|
||||
// populate the possible postgres options
|
||||
var postgresOptions = PostgresDatabase.GetTestOptions();
|
||||
_databaseType = postgresOptions.Host.IsNotNullOrWhiteSpace() ? DatabaseType.PostgreSQL : DatabaseType.SQLite;
|
||||
var options = PostgresDatabase.GetTestOptions();
|
||||
_databaseType = options.PostgresHost.IsNotNullOrWhiteSpace() ? DatabaseType.PostgreSQL : DatabaseType.SQLite;
|
||||
|
||||
// Set up remaining container services
|
||||
Mocker.SetConstant(Options.Create(postgresOptions));
|
||||
Mocker.SetConstant<IConfigFileProvider>(Mocker.Resolve<ConfigFileProvider>());
|
||||
Mocker.GetMock<IOptionsMonitor<ConfigFileOptions>>().Setup(x => x.CurrentValue).Returns(options);
|
||||
Mocker.SetConstant<IConnectionStringFactory>(Mocker.Resolve<ConnectionStringFactory>());
|
||||
Mocker.SetConstant<IMigrationController>(Mocker.Resolve<MigrationController>());
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.HealthCheck.Checks;
|
||||
using NzbDrone.Core.Localization;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Update;
|
||||
|
||||
namespace NzbDrone.Core.Test.HealthCheck.Checks
|
||||
{
|
||||
|
|
@ -20,9 +22,9 @@ public void Setup()
|
|||
|
||||
private void GivenValidBranch(string branch)
|
||||
{
|
||||
Mocker.GetMock<IConfigFileProvider>()
|
||||
.SetupGet(s => s.Branch)
|
||||
.Returns(branch);
|
||||
Mocker.GetMock<IOptionsMonitor<ConfigFileOptions>>()
|
||||
.Setup(s => s.CurrentValue)
|
||||
.Returns(new ConfigFileOptions { Branch = branch });
|
||||
}
|
||||
|
||||
[TestCase("aphrodite")]
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Disk;
|
||||
|
|
@ -19,6 +20,10 @@ public void Setup()
|
|||
Mocker.GetMock<ILocalizationService>()
|
||||
.Setup(s => s.GetLocalizedString(It.IsAny<string>()))
|
||||
.Returns("Some Warning Message");
|
||||
|
||||
Mocker.GetMock<IOptionsMonitor<ConfigFileOptions>>()
|
||||
.Setup(c => c.CurrentValue)
|
||||
.Returns(new ConfigFileOptions());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
@ -44,9 +49,9 @@ public void should_return_error_when_app_folder_is_write_protected_and_update_au
|
|||
|
||||
const string startupFolder = @"/opt/nzbdrone";
|
||||
|
||||
Mocker.GetMock<IConfigFileProvider>()
|
||||
.Setup(s => s.UpdateAutomatically)
|
||||
.Returns(true);
|
||||
Mocker.GetMock<IOptionsMonitor<ConfigFileOptions>>()
|
||||
.Setup(s => s.CurrentValue)
|
||||
.Returns(new ConfigFileOptions { UpdateAutomatically = true });
|
||||
|
||||
Mocker.GetMock<IAppFolderInfo>()
|
||||
.Setup(s => s.StartUpFolder)
|
||||
|
|
@ -67,9 +72,9 @@ public void should_return_error_when_ui_folder_is_write_protected_and_update_aut
|
|||
const string startupFolder = @"/opt/nzbdrone";
|
||||
const string uiFolder = @"/opt/nzbdrone/UI";
|
||||
|
||||
Mocker.GetMock<IConfigFileProvider>()
|
||||
.Setup(s => s.UpdateAutomatically)
|
||||
.Returns(true);
|
||||
Mocker.GetMock<IOptionsMonitor<ConfigFileOptions>>()
|
||||
.Setup(s => s.CurrentValue)
|
||||
.Returns(new ConfigFileOptions { UpdateAutomatically = true });
|
||||
|
||||
Mocker.GetMock<IAppFolderInfo>()
|
||||
.Setup(s => s.StartUpFolder)
|
||||
|
|
@ -91,13 +96,9 @@ public void should_not_return_error_when_app_folder_is_write_protected_and_exter
|
|||
{
|
||||
PosixOnly();
|
||||
|
||||
Mocker.GetMock<IConfigFileProvider>()
|
||||
.Setup(s => s.UpdateAutomatically)
|
||||
.Returns(true);
|
||||
|
||||
Mocker.GetMock<IConfigFileProvider>()
|
||||
.Setup(s => s.UpdateMechanism)
|
||||
.Returns(UpdateMechanism.Script);
|
||||
Mocker.GetMock<IOptionsMonitor<ConfigFileOptions>>()
|
||||
.Setup(s => s.CurrentValue)
|
||||
.Returns(new ConfigFileOptions { UpdateAutomatically = true, UpdateMechanism = UpdateMechanism.Script });
|
||||
|
||||
Mocker.GetMock<IAppFolderInfo>()
|
||||
.Setup(s => s.StartUpFolder)
|
||||
|
|
|
|||
|
|
@ -4,10 +4,12 @@
|
|||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.MediaCover;
|
||||
using NzbDrone.Core.Movies;
|
||||
using NzbDrone.Core.Movies.Events;
|
||||
|
|
@ -31,6 +33,10 @@ public void Setup()
|
|||
.Build();
|
||||
|
||||
Mocker.GetMock<IMovieService>().Setup(m => m.GetMovie(It.Is<int>(id => id == _movie.Id))).Returns(_movie);
|
||||
|
||||
Mocker.GetMock<IOptionsMonitor<ConfigFileOptions>>()
|
||||
.Setup(x => x.CurrentValue)
|
||||
.Returns(new ConfigFileOptions());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using FluentAssertions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
|
|
@ -60,9 +61,9 @@ public void Setup()
|
|||
Mocker.GetMock<IProcessProvider>().Setup(c => c.GetCurrentProcess()).Returns(new ProcessInfo { Id = 12 });
|
||||
Mocker.GetMock<IRuntimeInfo>().Setup(c => c.ExecutingApplication).Returns(@"C:\Test\Radarr.exe");
|
||||
|
||||
Mocker.GetMock<IConfigFileProvider>()
|
||||
.SetupGet(s => s.UpdateAutomatically)
|
||||
.Returns(true);
|
||||
Mocker.GetMock<IOptionsMonitor<ConfigFileOptions>>()
|
||||
.Setup(s => s.CurrentValue)
|
||||
.Returns(new ConfigFileOptions { UpdateAutomatically = true });
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(c => c.FolderWritable(It.IsAny<string>()))
|
||||
|
|
@ -77,13 +78,9 @@ public void Setup()
|
|||
|
||||
private void GivenInstallScript(string path)
|
||||
{
|
||||
Mocker.GetMock<IConfigFileProvider>()
|
||||
.SetupGet(s => s.UpdateMechanism)
|
||||
.Returns(UpdateMechanism.Script);
|
||||
|
||||
Mocker.GetMock<IConfigFileProvider>()
|
||||
.SetupGet(s => s.UpdateScriptPath)
|
||||
.Returns(path);
|
||||
Mocker.GetMock<IOptionsMonitor<ConfigFileOptions>>()
|
||||
.Setup(s => s.CurrentValue)
|
||||
.Returns(new ConfigFileOptions { UpdateMechanism = UpdateMechanism.Script, UpdateScriptPath = path });
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(s => s.FileExists(path, StringComparison.Ordinal))
|
||||
|
|
@ -334,7 +331,7 @@ public void should_switch_to_branch_specified_in_updatepackage()
|
|||
|
||||
Subject.Execute(new ApplicationUpdateCommand());
|
||||
|
||||
Mocker.GetMock<IConfigFileProvider>()
|
||||
Mocker.GetMock<IConfigFileWriter>()
|
||||
.Verify(v => v.SaveConfigDictionary(It.Is<Dictionary<string, object>>(d => d.ContainsKey("Branch") && (string)d["Branch"] == "fake")), Times.Once());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Datastore;
|
||||
|
|
@ -15,16 +16,16 @@ public interface IAnalyticsService
|
|||
|
||||
public class AnalyticsService : IAnalyticsService
|
||||
{
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
private readonly IHistoryService _historyService;
|
||||
|
||||
public AnalyticsService(IHistoryService historyService, IConfigFileProvider configFileProvider)
|
||||
public AnalyticsService(IHistoryService historyService, IOptionsMonitor<ConfigFileOptions> configFileProvider)
|
||||
{
|
||||
_configFileProvider = configFileProvider;
|
||||
_historyService = historyService;
|
||||
}
|
||||
|
||||
public bool IsEnabled => (_configFileProvider.AnalyticsEnabled && RuntimeInfo.IsProduction) || RuntimeInfo.IsDevelopment;
|
||||
public bool IsEnabled => (_configFileProvider.CurrentValue.AnalyticsEnabled && RuntimeInfo.IsProduction) || RuntimeInfo.IsDevelopment;
|
||||
|
||||
public bool InstallIsActive
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Extensions;
|
||||
|
|
@ -19,17 +20,17 @@ public interface IUserService
|
|||
User FindUser(Guid identifier);
|
||||
}
|
||||
|
||||
public class UserService : IUserService, IHandle<ApplicationStartedEvent>
|
||||
public class UserService : IUserService
|
||||
{
|
||||
private readonly IUserRepository _repo;
|
||||
private readonly IAppFolderInfo _appFolderInfo;
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
|
||||
public UserService(IUserRepository repo,
|
||||
IAppFolderInfo appFolderInfo,
|
||||
IDiskProvider diskProvider,
|
||||
IConfigFileProvider configFileProvider)
|
||||
IOptionsMonitor<ConfigFileOptions> configFileProvider)
|
||||
{
|
||||
_repo = repo;
|
||||
_appFolderInfo = appFolderInfo;
|
||||
|
|
@ -102,28 +103,5 @@ public User FindUser(Guid identifier)
|
|||
{
|
||||
return _repo.FindUser(identifier);
|
||||
}
|
||||
|
||||
public void Handle(ApplicationStartedEvent message)
|
||||
{
|
||||
if (_repo.All().Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var xDoc = _configFileProvider.LoadConfigFile();
|
||||
var config = xDoc.Descendants("Config").Single();
|
||||
var usernameElement = config.Descendants("Username").FirstOrDefault();
|
||||
var passwordElement = config.Descendants("Password").FirstOrDefault();
|
||||
|
||||
if (usernameElement == null || passwordElement == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var username = usernameElement.Value;
|
||||
var password = passwordElement.Value;
|
||||
|
||||
Add(username, password);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
71
src/NzbDrone.Core/Configuration/ConfigFileOptions.cs
Normal file
71
src/NzbDrone.Core/Configuration/ConfigFileOptions.cs
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
using System;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Core.Authentication;
|
||||
using NzbDrone.Core.Update;
|
||||
|
||||
namespace NzbDrone.Core.Configuration
|
||||
{
|
||||
public class ConfigFileOptions
|
||||
{
|
||||
[Persist]
|
||||
public string BindAddress { get; set; } = "*";
|
||||
[Persist]
|
||||
public int Port { get; set; } = 7878;
|
||||
[Persist]
|
||||
public int SslPort { get; set; } = 9898;
|
||||
[Persist]
|
||||
public bool EnableSsl { get; set; }
|
||||
[Persist]
|
||||
public bool LaunchBrowser { get; set; } = true;
|
||||
public AuthenticationType AuthenticationMethod { get; set; }
|
||||
public bool AnalyticsEnabled { get; set; } = true;
|
||||
[Persist]
|
||||
public string Branch { get; set; } = "master";
|
||||
[Persist]
|
||||
public string LogLevel { get; set; } = "info";
|
||||
public string ConsoleLogLevel { get; set; } = string.Empty;
|
||||
public bool LogSql { get; set; }
|
||||
public int LogRotate { get; set; } = 50;
|
||||
public bool FilterSentryEvents { get; set; } = true;
|
||||
[Persist]
|
||||
public string ApiKey { get; set; } = GenerateApiKey();
|
||||
[Persist]
|
||||
public string SslCertPath { get; set; }
|
||||
[Persist]
|
||||
public string SslCertPassword { get; set; }
|
||||
[Persist]
|
||||
public string UrlBase { get; set; } = string.Empty;
|
||||
[Persist]
|
||||
public string InstanceName { get; set; } = BuildInfo.AppName;
|
||||
public bool UpdateAutomatically { get; set; }
|
||||
public UpdateMechanism UpdateMechanism { get; set; } = UpdateMechanism.BuiltIn;
|
||||
public string UpdateScriptPath { get; set; } = string.Empty;
|
||||
public string SyslogServer { get; set; } = string.Empty;
|
||||
public int SyslogPort { get; set; } = 514;
|
||||
public string SyslogLevel { get; set; } = "info";
|
||||
public string PostgresHost { get; set; }
|
||||
public int PostgresPort { get; set; }
|
||||
public string PostgresUser { get; set; }
|
||||
public string PostgresPassword { get; set; }
|
||||
public string PostgresMainDb { get; set; } = BuildInfo.AppName.ToLower() + "-main";
|
||||
public string PostgresLogDb { get; set; } = BuildInfo.AppName.ToLower() + "-log";
|
||||
|
||||
private static string GenerateApiKey()
|
||||
{
|
||||
return Guid.NewGuid().ToString().Replace("-", "");
|
||||
}
|
||||
|
||||
public static ConfigFileOptions GetOptions()
|
||||
{
|
||||
var config = new ConfigurationBuilder()
|
||||
.AddEnvironmentVariables($"{BuildInfo.AppName}:")
|
||||
.Build();
|
||||
|
||||
var options = new ConfigFileOptions();
|
||||
config.Bind(options);
|
||||
|
||||
return options;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,401 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NzbDrone.Common.Cache;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Authentication;
|
||||
using NzbDrone.Core.Configuration.Events;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Lifecycle;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.Update;
|
||||
|
||||
namespace NzbDrone.Core.Configuration
|
||||
{
|
||||
public interface IConfigFileProvider : IHandleAsync<ApplicationStartedEvent>,
|
||||
IExecute<ResetApiKeyCommand>
|
||||
{
|
||||
XDocument LoadConfigFile();
|
||||
Dictionary<string, object> GetConfigDictionary();
|
||||
void SaveConfigDictionary(Dictionary<string, object> configValues);
|
||||
|
||||
string BindAddress { get; }
|
||||
int Port { get; }
|
||||
int SslPort { get; }
|
||||
bool EnableSsl { get; }
|
||||
bool LaunchBrowser { get; }
|
||||
AuthenticationType AuthenticationMethod { get; }
|
||||
bool AnalyticsEnabled { get; }
|
||||
string LogLevel { get; }
|
||||
string ConsoleLogLevel { get; }
|
||||
bool LogSql { get; }
|
||||
int LogRotate { get; }
|
||||
bool FilterSentryEvents { get; }
|
||||
string Branch { get; }
|
||||
string ApiKey { get; }
|
||||
string SslCertPath { get; }
|
||||
string SslCertPassword { get; }
|
||||
string UrlBase { get; }
|
||||
string UiFolder { get; }
|
||||
string InstanceName { get; }
|
||||
bool UpdateAutomatically { get; }
|
||||
UpdateMechanism UpdateMechanism { get; }
|
||||
string UpdateScriptPath { get; }
|
||||
string SyslogServer { get; }
|
||||
int SyslogPort { get; }
|
||||
string SyslogLevel { get; }
|
||||
string PostgresHost { get; }
|
||||
int PostgresPort { get; }
|
||||
string PostgresUser { get; }
|
||||
string PostgresPassword { get; }
|
||||
string PostgresMainDb { get; }
|
||||
string PostgresLogDb { get; }
|
||||
}
|
||||
|
||||
public class ConfigFileProvider : IConfigFileProvider
|
||||
{
|
||||
public const string CONFIG_ELEMENT_NAME = "Config";
|
||||
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly ICached<string> _cache;
|
||||
private readonly PostgresOptions _postgresOptions;
|
||||
|
||||
private readonly string _configFile;
|
||||
private static readonly Regex HiddenCharacterRegex = new Regex("[^a-z0-9]", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
private static readonly object Mutex = new object();
|
||||
|
||||
public ConfigFileProvider(IAppFolderInfo appFolderInfo,
|
||||
ICacheManager cacheManager,
|
||||
IEventAggregator eventAggregator,
|
||||
IDiskProvider diskProvider,
|
||||
IOptions<PostgresOptions> postgresOptions)
|
||||
{
|
||||
_cache = cacheManager.GetCache<string>(GetType());
|
||||
_eventAggregator = eventAggregator;
|
||||
_diskProvider = diskProvider;
|
||||
_configFile = appFolderInfo.GetConfigPath();
|
||||
_postgresOptions = postgresOptions.Value;
|
||||
}
|
||||
|
||||
public Dictionary<string, object> GetConfigDictionary()
|
||||
{
|
||||
var dict = new Dictionary<string, object>(StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
var type = GetType();
|
||||
var properties = type.GetProperties();
|
||||
|
||||
foreach (var propertyInfo in properties)
|
||||
{
|
||||
var value = propertyInfo.GetValue(this, null);
|
||||
|
||||
dict.Add(propertyInfo.Name, value);
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
public void SaveConfigDictionary(Dictionary<string, object> configValues)
|
||||
{
|
||||
_cache.Clear();
|
||||
|
||||
var allWithDefaults = GetConfigDictionary();
|
||||
|
||||
foreach (var configValue in configValues)
|
||||
{
|
||||
if (configValue.Key.Equals("ApiKey", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
object currentValue;
|
||||
allWithDefaults.TryGetValue(configValue.Key, out currentValue);
|
||||
if (currentValue == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var equal = configValue.Value.ToString().Equals(currentValue.ToString());
|
||||
|
||||
if (!equal)
|
||||
{
|
||||
SetValue(configValue.Key.FirstCharToUpper(), configValue.Value.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
_eventAggregator.PublishEvent(new ConfigFileSavedEvent());
|
||||
}
|
||||
|
||||
public string BindAddress
|
||||
{
|
||||
get
|
||||
{
|
||||
const string defaultValue = "*";
|
||||
|
||||
string bindAddress = GetValue("BindAddress", defaultValue);
|
||||
if (string.IsNullOrWhiteSpace(bindAddress))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return bindAddress;
|
||||
}
|
||||
}
|
||||
|
||||
public int Port => GetValueInt("Port", 7878);
|
||||
|
||||
public int SslPort => GetValueInt("SslPort", 9898);
|
||||
|
||||
public bool EnableSsl => GetValueBoolean("EnableSsl", false);
|
||||
|
||||
public bool LaunchBrowser => GetValueBoolean("LaunchBrowser", true);
|
||||
|
||||
public string ApiKey
|
||||
{
|
||||
get
|
||||
{
|
||||
var apiKey = GetValue("ApiKey", GenerateApiKey());
|
||||
|
||||
if (apiKey.IsNullOrWhiteSpace())
|
||||
{
|
||||
apiKey = GenerateApiKey();
|
||||
SetValue("ApiKey", apiKey);
|
||||
}
|
||||
|
||||
return apiKey;
|
||||
}
|
||||
}
|
||||
|
||||
public AuthenticationType AuthenticationMethod
|
||||
{
|
||||
get
|
||||
{
|
||||
var enabled = GetValueBoolean("AuthenticationEnabled", false, false);
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
SetValue("AuthenticationMethod", AuthenticationType.Basic);
|
||||
return AuthenticationType.Basic;
|
||||
}
|
||||
|
||||
return GetValueEnum("AuthenticationMethod", AuthenticationType.None);
|
||||
}
|
||||
}
|
||||
|
||||
public bool AnalyticsEnabled => GetValueBoolean("AnalyticsEnabled", true, persist: false);
|
||||
|
||||
public string Branch => GetValue("Branch", "master").ToLowerInvariant();
|
||||
|
||||
public string LogLevel => GetValue("LogLevel", "info").ToLowerInvariant();
|
||||
public string ConsoleLogLevel => GetValue("ConsoleLogLevel", string.Empty, persist: false);
|
||||
public string PostgresHost => _postgresOptions?.Host ?? GetValue("PostgresHost", string.Empty, persist: false);
|
||||
public string PostgresUser => _postgresOptions?.User ?? GetValue("PostgresUser", string.Empty, persist: false);
|
||||
public string PostgresPassword => _postgresOptions?.Password ?? GetValue("PostgresPassword", string.Empty, persist: false);
|
||||
public string PostgresMainDb => _postgresOptions?.MainDb ?? GetValue("PostgresMainDb", "radarr-main", persist: false);
|
||||
public string PostgresLogDb => _postgresOptions?.LogDb ?? GetValue("PostgresLogDb", "radarr-log", persist: false);
|
||||
public int PostgresPort => (_postgresOptions?.Port ?? 0) != 0 ? _postgresOptions.Port : GetValueInt("PostgresPort", 5432, persist: false);
|
||||
public bool LogSql => GetValueBoolean("LogSql", false, persist: false);
|
||||
public int LogRotate => GetValueInt("LogRotate", 50, persist: false);
|
||||
public bool FilterSentryEvents => GetValueBoolean("FilterSentryEvents", true, persist: false);
|
||||
public string SslCertPath => GetValue("SslCertPath", "");
|
||||
public string SslCertPassword => GetValue("SslCertPassword", "");
|
||||
|
||||
public string UrlBase
|
||||
{
|
||||
get
|
||||
{
|
||||
var urlBase = GetValue("UrlBase", "").Trim('/');
|
||||
|
||||
if (urlBase.IsNullOrWhiteSpace())
|
||||
{
|
||||
return urlBase;
|
||||
}
|
||||
|
||||
return "/" + urlBase.Trim('/').ToLower();
|
||||
}
|
||||
}
|
||||
|
||||
public string UiFolder => BuildInfo.IsDebug ? Path.Combine("..", "UI") : "UI";
|
||||
public string InstanceName => GetValue("InstanceName", BuildInfo.AppName);
|
||||
|
||||
public bool UpdateAutomatically => GetValueBoolean("UpdateAutomatically", false, false);
|
||||
|
||||
public UpdateMechanism UpdateMechanism => GetValueEnum("UpdateMechanism", UpdateMechanism.BuiltIn, false);
|
||||
|
||||
public string UpdateScriptPath => GetValue("UpdateScriptPath", "", false);
|
||||
|
||||
public string SyslogServer => GetValue("SyslogServer", "", persist: false);
|
||||
|
||||
public int SyslogPort => GetValueInt("SyslogPort", 514, persist: false);
|
||||
|
||||
public string SyslogLevel => GetValue("SyslogLevel", LogLevel, false).ToLowerInvariant();
|
||||
|
||||
public int GetValueInt(string key, int defaultValue, bool persist = true)
|
||||
{
|
||||
return Convert.ToInt32(GetValue(key, defaultValue, persist));
|
||||
}
|
||||
|
||||
public bool GetValueBoolean(string key, bool defaultValue, bool persist = true)
|
||||
{
|
||||
return Convert.ToBoolean(GetValue(key, defaultValue, persist));
|
||||
}
|
||||
|
||||
public T GetValueEnum<T>(string key, T defaultValue, bool persist = true)
|
||||
{
|
||||
return (T)Enum.Parse(typeof(T), GetValue(key, defaultValue), persist);
|
||||
}
|
||||
|
||||
public string GetValue(string key, object defaultValue, bool persist = true)
|
||||
{
|
||||
return _cache.Get(key, () =>
|
||||
{
|
||||
var xDoc = LoadConfigFile();
|
||||
var config = xDoc.Descendants(CONFIG_ELEMENT_NAME).Single();
|
||||
|
||||
var parentContainer = config;
|
||||
|
||||
var valueHolder = parentContainer.Descendants(key).ToList();
|
||||
|
||||
if (valueHolder.Count == 1)
|
||||
{
|
||||
return valueHolder.First().Value.Trim();
|
||||
}
|
||||
|
||||
//Save the value
|
||||
if (persist)
|
||||
{
|
||||
SetValue(key, defaultValue);
|
||||
}
|
||||
|
||||
//return the default value
|
||||
return defaultValue.ToString();
|
||||
});
|
||||
}
|
||||
|
||||
public void SetValue(string key, object value)
|
||||
{
|
||||
var valueString = value.ToString().Trim();
|
||||
var xDoc = LoadConfigFile();
|
||||
var config = xDoc.Descendants(CONFIG_ELEMENT_NAME).Single();
|
||||
|
||||
var parentContainer = config;
|
||||
|
||||
var keyHolder = parentContainer.Descendants(key);
|
||||
|
||||
if (keyHolder.Count() != 1)
|
||||
{
|
||||
parentContainer.Add(new XElement(key, valueString));
|
||||
}
|
||||
else
|
||||
{
|
||||
parentContainer.Descendants(key).Single().Value = valueString;
|
||||
}
|
||||
|
||||
_cache.Set(key, valueString);
|
||||
|
||||
SaveConfigFile(xDoc);
|
||||
}
|
||||
|
||||
public void SetValue(string key, Enum value)
|
||||
{
|
||||
SetValue(key, value.ToString().ToLower());
|
||||
}
|
||||
|
||||
private void EnsureDefaultConfigFile()
|
||||
{
|
||||
if (!File.Exists(_configFile))
|
||||
{
|
||||
SaveConfigDictionary(GetConfigDictionary());
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteOldValues()
|
||||
{
|
||||
var xDoc = LoadConfigFile();
|
||||
var config = xDoc.Descendants(CONFIG_ELEMENT_NAME).Single();
|
||||
|
||||
var type = GetType();
|
||||
var properties = type.GetProperties();
|
||||
|
||||
foreach (var configValue in config.Descendants().ToList())
|
||||
{
|
||||
var name = configValue.Name.LocalName;
|
||||
|
||||
if (!properties.Any(p => p.Name == name))
|
||||
{
|
||||
config.Descendants(name).Remove();
|
||||
}
|
||||
}
|
||||
|
||||
SaveConfigFile(xDoc);
|
||||
}
|
||||
|
||||
public XDocument LoadConfigFile()
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (Mutex)
|
||||
{
|
||||
if (_diskProvider.FileExists(_configFile))
|
||||
{
|
||||
var contents = _diskProvider.ReadAllText(_configFile);
|
||||
|
||||
if (contents.IsNullOrWhiteSpace())
|
||||
{
|
||||
throw new InvalidConfigFileException($"{_configFile} is empty. Please delete the config file and Radarr will recreate it.");
|
||||
}
|
||||
|
||||
if (contents.All(char.IsControl))
|
||||
{
|
||||
throw new InvalidConfigFileException($"{_configFile} is corrupt. Please delete the config file and Radarr will recreate it.");
|
||||
}
|
||||
|
||||
return XDocument.Parse(_diskProvider.ReadAllText(_configFile));
|
||||
}
|
||||
|
||||
var xDoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));
|
||||
xDoc.Add(new XElement(CONFIG_ELEMENT_NAME));
|
||||
|
||||
return xDoc;
|
||||
}
|
||||
}
|
||||
catch (XmlException ex)
|
||||
{
|
||||
throw new InvalidConfigFileException($"{_configFile} is corrupt is invalid. Please delete the config file and Radarr will recreate it.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveConfigFile(XDocument xDoc)
|
||||
{
|
||||
lock (Mutex)
|
||||
{
|
||||
_diskProvider.WriteAllText(_configFile, xDoc.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private string GenerateApiKey()
|
||||
{
|
||||
return Guid.NewGuid().ToString().Replace("-", "");
|
||||
}
|
||||
|
||||
public void HandleAsync(ApplicationStartedEvent message)
|
||||
{
|
||||
EnsureDefaultConfigFile();
|
||||
DeleteOldValues();
|
||||
}
|
||||
|
||||
public void Execute(ResetApiKeyCommand message)
|
||||
{
|
||||
SetValue("ApiKey", GenerateApiKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
219
src/NzbDrone.Core/Configuration/ConfigFileWriter.cs
Normal file
219
src/NzbDrone.Core/Configuration/ConfigFileWriter.cs
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Configuration.Events;
|
||||
using NzbDrone.Core.Lifecycle;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
|
||||
namespace NzbDrone.Core.Configuration
|
||||
{
|
||||
public interface IConfigFileWriter : IHandleAsync<ApplicationStartedEvent>,
|
||||
IExecute<ResetApiKeyCommand>
|
||||
{
|
||||
public void EnsureDefaultConfigFile();
|
||||
void SaveConfigDictionary(Dictionary<string, object> configValues);
|
||||
}
|
||||
|
||||
public class ConfigFileWriter : IConfigFileWriter
|
||||
{
|
||||
public static string CONFIG_ELEMENT_NAME = BuildInfo.AppName;
|
||||
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IConfigurationRoot _configuration;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileOptions;
|
||||
private readonly Logger _logger;
|
||||
|
||||
private readonly string _configFile;
|
||||
|
||||
private static readonly object Mutex = new object();
|
||||
|
||||
public ConfigFileWriter(IAppFolderInfo appFolderInfo,
|
||||
IEventAggregator eventAggregator,
|
||||
IDiskProvider diskProvider,
|
||||
IConfiguration configuration,
|
||||
IOptionsMonitor<ConfigFileOptions> configFileOptions,
|
||||
Logger logger)
|
||||
{
|
||||
_eventAggregator = eventAggregator;
|
||||
_diskProvider = diskProvider;
|
||||
_configuration = configuration as IConfigurationRoot;
|
||||
_configFileOptions = configFileOptions;
|
||||
_logger = logger;
|
||||
|
||||
_configFile = appFolderInfo.GetConfigPath();
|
||||
|
||||
_configFileOptions.OnChange(OnChange);
|
||||
}
|
||||
|
||||
private Dictionary<string, object> GetConfigDictionary()
|
||||
{
|
||||
var dict = new Dictionary<string, object>(StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
var properties = typeof(ConfigFileOptions).GetProperties();
|
||||
|
||||
foreach (var propertyInfo in properties)
|
||||
{
|
||||
var value = propertyInfo.GetValue(_configFileOptions.CurrentValue, null);
|
||||
|
||||
dict.Add(propertyInfo.Name, value);
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
public void SaveConfigDictionary(Dictionary<string, object> configValues)
|
||||
{
|
||||
var allWithDefaults = GetConfigDictionary();
|
||||
|
||||
var persistKeys = typeof(ConfigFileOptions).GetProperties()
|
||||
.Where(x => Attribute.IsDefined(x, typeof(PersistAttribute)))
|
||||
.Select(x => x.Name)
|
||||
.ToList();
|
||||
|
||||
foreach (var configValue in configValues)
|
||||
{
|
||||
if (configValue.Key.Equals("ApiKey", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
allWithDefaults.TryGetValue(configValue.Key, out var currentValue);
|
||||
if (currentValue == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var equal = configValue.Value.ToString().Equals(currentValue.ToString());
|
||||
var persist = persistKeys.Contains(configValue.Key);
|
||||
|
||||
if (persist || !equal)
|
||||
{
|
||||
SetValue(configValue.Key.FirstCharToUpper(), configValue.Value.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
_eventAggregator.PublishEvent(new ConfigFileSavedEvent());
|
||||
}
|
||||
|
||||
public void SetValue(string key, object value)
|
||||
{
|
||||
var valueString = value.ToString().Trim();
|
||||
var xDoc = LoadConfigFile();
|
||||
var config = xDoc.Descendants(CONFIG_ELEMENT_NAME).Single();
|
||||
|
||||
var keyHolder = config.Descendants(key);
|
||||
|
||||
if (keyHolder.Count() != 1)
|
||||
{
|
||||
config.Add(new XElement(key, valueString));
|
||||
}
|
||||
else
|
||||
{
|
||||
config.Descendants(key).Single().Value = valueString;
|
||||
}
|
||||
|
||||
SaveConfigFile(xDoc);
|
||||
}
|
||||
|
||||
public void EnsureDefaultConfigFile()
|
||||
{
|
||||
if (!File.Exists(_configFile))
|
||||
{
|
||||
SaveConfigDictionary(GetConfigDictionary());
|
||||
SetValue(nameof(ConfigFileOptions.ApiKey), _configFileOptions.CurrentValue.ApiKey);
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteOldValues()
|
||||
{
|
||||
var xDoc = LoadConfigFile();
|
||||
var config = xDoc.Descendants(CONFIG_ELEMENT_NAME).Single();
|
||||
|
||||
var properties = typeof(ConfigFileOptions).GetProperties();
|
||||
|
||||
foreach (var configValue in config.Descendants().ToList())
|
||||
{
|
||||
var name = configValue.Name.LocalName;
|
||||
|
||||
if (!properties.Any(p => p.Name == name))
|
||||
{
|
||||
config.Descendants(name).Remove();
|
||||
}
|
||||
}
|
||||
|
||||
SaveConfigFile(xDoc);
|
||||
}
|
||||
|
||||
public XDocument LoadConfigFile()
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (Mutex)
|
||||
{
|
||||
if (_diskProvider.FileExists(_configFile))
|
||||
{
|
||||
var contents = _diskProvider.ReadAllText(_configFile);
|
||||
|
||||
if (contents.IsNullOrWhiteSpace())
|
||||
{
|
||||
throw new InvalidConfigFileException($"{_configFile} is empty. Please delete the config file and Radarr will recreate it.");
|
||||
}
|
||||
|
||||
if (contents.All(char.IsControl))
|
||||
{
|
||||
throw new InvalidConfigFileException($"{_configFile} is corrupt. Please delete the config file and Radarr will recreate it.");
|
||||
}
|
||||
|
||||
return XDocument.Parse(_diskProvider.ReadAllText(_configFile));
|
||||
}
|
||||
|
||||
var xDoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));
|
||||
xDoc.Add(new XElement(CONFIG_ELEMENT_NAME));
|
||||
|
||||
return xDoc;
|
||||
}
|
||||
}
|
||||
catch (XmlException ex)
|
||||
{
|
||||
throw new InvalidConfigFileException($"{_configFile} is corrupt is invalid. Please delete the config file and Radarr will recreate it.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveConfigFile(XDocument xDoc)
|
||||
{
|
||||
lock (Mutex)
|
||||
{
|
||||
_diskProvider.WriteAllText(_configFile, xDoc.ToString());
|
||||
_configuration.Reload();
|
||||
}
|
||||
}
|
||||
|
||||
public void HandleAsync(ApplicationStartedEvent message)
|
||||
{
|
||||
DeleteOldValues();
|
||||
}
|
||||
|
||||
public void Execute(ResetApiKeyCommand message)
|
||||
{
|
||||
SetValue(nameof(ConfigFileOptions.ApiKey), new ConfigFileOptions().ApiKey);
|
||||
}
|
||||
|
||||
private void OnChange(ConfigFileOptions options)
|
||||
{
|
||||
_logger.Info("Config file updated");
|
||||
|
||||
_eventAggregator.PublishEvent(new ConfigFileSavedEvent());
|
||||
}
|
||||
}
|
||||
}
|
||||
9
src/NzbDrone.Core/Configuration/PersistAttribute.cs
Normal file
9
src/NzbDrone.Core/Configuration/PersistAttribute.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
using System;
|
||||
|
||||
namespace NzbDrone.Core.Configuration
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class PersistAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Data.SQLite;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Npgsql;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Extensions;
|
||||
|
|
@ -16,16 +17,16 @@ public interface IConnectionStringFactory
|
|||
|
||||
public class ConnectionStringFactory : IConnectionStringFactory
|
||||
{
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
|
||||
public ConnectionStringFactory(IAppFolderInfo appFolderInfo, IConfigFileProvider configFileProvider)
|
||||
public ConnectionStringFactory(IAppFolderInfo appFolderInfo, IOptionsMonitor<ConfigFileOptions> configFileProvider)
|
||||
{
|
||||
_configFileProvider = configFileProvider;
|
||||
|
||||
MainDbConnectionString = _configFileProvider.PostgresHost.IsNotNullOrWhiteSpace() ? GetPostgresConnectionString(_configFileProvider.PostgresMainDb) :
|
||||
MainDbConnectionString = _configFileProvider.CurrentValue.PostgresHost.IsNotNullOrWhiteSpace() ? GetPostgresConnectionString(_configFileProvider.CurrentValue.PostgresMainDb) :
|
||||
GetConnectionString(appFolderInfo.GetDatabase());
|
||||
|
||||
LogDbConnectionString = _configFileProvider.PostgresHost.IsNotNullOrWhiteSpace() ? GetPostgresConnectionString(_configFileProvider.PostgresLogDb) :
|
||||
LogDbConnectionString = _configFileProvider.CurrentValue.PostgresHost.IsNotNullOrWhiteSpace() ? GetPostgresConnectionString(_configFileProvider.CurrentValue.PostgresLogDb) :
|
||||
GetConnectionString(appFolderInfo.GetLogDatabase());
|
||||
}
|
||||
|
||||
|
|
@ -63,10 +64,10 @@ private string GetPostgresConnectionString(string dbName)
|
|||
var connectionBuilder = new NpgsqlConnectionStringBuilder();
|
||||
|
||||
connectionBuilder.Database = dbName;
|
||||
connectionBuilder.Host = _configFileProvider.PostgresHost;
|
||||
connectionBuilder.Username = _configFileProvider.PostgresUser;
|
||||
connectionBuilder.Password = _configFileProvider.PostgresPassword;
|
||||
connectionBuilder.Port = _configFileProvider.PostgresPort;
|
||||
connectionBuilder.Host = _configFileProvider.CurrentValue.PostgresHost;
|
||||
connectionBuilder.Username = _configFileProvider.CurrentValue.PostgresUser;
|
||||
connectionBuilder.Password = _configFileProvider.CurrentValue.PostgresPassword;
|
||||
connectionBuilder.Port = _configFileProvider.CurrentValue.PostgresPort;
|
||||
connectionBuilder.Enlist = false;
|
||||
|
||||
return connectionBuilder.ConnectionString;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Core.Datastore
|
||||
{
|
||||
|
|
@ -18,7 +19,7 @@ public static PostgresOptions GetOptions()
|
|||
.Build();
|
||||
|
||||
var postgresOptions = new PostgresOptions();
|
||||
config.GetSection("Radarr:Postgres").Bind(postgresOptions);
|
||||
config.GetSection($"{BuildInfo.AppName}:Postgres").Bind(postgresOptions);
|
||||
|
||||
return postgresOptions;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Configuration.Events;
|
||||
using NzbDrone.Core.Localization;
|
||||
|
|
@ -9,9 +10,9 @@ namespace NzbDrone.Core.HealthCheck.Checks
|
|||
[CheckOn(typeof(ConfigSavedEvent))]
|
||||
public class ReleaseBranchCheck : HealthCheckBase
|
||||
{
|
||||
private readonly IConfigFileProvider _configFileService;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileService;
|
||||
|
||||
public ReleaseBranchCheck(IConfigFileProvider configFileService, ILocalizationService localizationService)
|
||||
public ReleaseBranchCheck(IOptionsMonitor<ConfigFileOptions> configFileService, ILocalizationService localizationService)
|
||||
: base(localizationService)
|
||||
{
|
||||
_configFileService = configFileService;
|
||||
|
|
@ -19,11 +20,11 @@ public ReleaseBranchCheck(IConfigFileProvider configFileService, ILocalizationSe
|
|||
|
||||
public override HealthCheck Check()
|
||||
{
|
||||
var currentBranch = _configFileService.Branch.ToLower();
|
||||
var currentBranch = _configFileService.CurrentValue.Branch.ToLower();
|
||||
|
||||
if (!Enum.GetNames(typeof(ReleaseBranches)).Any(x => x.ToLower() == currentBranch))
|
||||
{
|
||||
return new HealthCheck(GetType(), HealthCheckResult.Warning, string.Format(_localizationService.GetLocalizedString("ReleaseBranchCheckOfficialBranchMessage"), _configFileService.Branch), "#branch-is-not-a-valid-release-branch");
|
||||
return new HealthCheck(GetType(), HealthCheckResult.Warning, string.Format(_localizationService.GetLocalizedString("ReleaseBranchCheckOfficialBranchMessage"), _configFileService.CurrentValue.Branch), "#branch-is-not-a-valid-release-branch");
|
||||
}
|
||||
|
||||
return new HealthCheck(GetType());
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Extensions;
|
||||
|
|
@ -16,13 +17,13 @@ public class UpdateCheck : HealthCheckBase
|
|||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IAppFolderInfo _appFolderInfo;
|
||||
private readonly ICheckUpdateService _checkUpdateService;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
private readonly IOsInfo _osInfo;
|
||||
|
||||
public UpdateCheck(IDiskProvider diskProvider,
|
||||
IAppFolderInfo appFolderInfo,
|
||||
ICheckUpdateService checkUpdateService,
|
||||
IConfigFileProvider configFileProvider,
|
||||
IOptionsMonitor<ConfigFileOptions> configFileProvider,
|
||||
IOsInfo osInfo,
|
||||
ILocalizationService localizationService)
|
||||
: base(localizationService)
|
||||
|
|
@ -39,8 +40,8 @@ public override HealthCheck Check()
|
|||
var startupFolder = _appFolderInfo.StartUpFolder;
|
||||
var uiFolder = Path.Combine(startupFolder, "UI");
|
||||
|
||||
if ((OsInfo.IsWindows || _configFileProvider.UpdateAutomatically) &&
|
||||
_configFileProvider.UpdateMechanism == UpdateMechanism.BuiltIn &&
|
||||
if ((OsInfo.IsWindows || _configFileProvider.CurrentValue.UpdateAutomatically) &&
|
||||
_configFileProvider.CurrentValue.UpdateMechanism == UpdateMechanism.BuiltIn &&
|
||||
!_osInfo.IsDocker)
|
||||
{
|
||||
if (OsInfo.IsOsx && startupFolder.GetAncestorFolders().Contains("AppTranslocation"))
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Cloud;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
|
@ -19,11 +20,11 @@ public interface IServerSideNotificationService
|
|||
public class ServerSideNotificationService : IServerSideNotificationService
|
||||
{
|
||||
private readonly IHttpClient _client;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
private readonly IHttpRequestBuilderFactory _cloudRequestBuilder;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public ServerSideNotificationService(IHttpClient client, IConfigFileProvider configFileProvider, IRadarrCloudRequestBuilder cloudRequestBuilder, Logger logger)
|
||||
public ServerSideNotificationService(IHttpClient client, IOptionsMonitor<ConfigFileOptions> configFileProvider, IRadarrCloudRequestBuilder cloudRequestBuilder, Logger logger)
|
||||
{
|
||||
_client = client;
|
||||
_configFileProvider = configFileProvider;
|
||||
|
|
@ -39,7 +40,7 @@ public List<HealthCheck> GetServerChecks()
|
|||
.AddQueryParam("os", OsInfo.Os.ToString().ToLowerInvariant())
|
||||
.AddQueryParam("arch", RuntimeInformation.OSArchitecture)
|
||||
.AddQueryParam("runtime", PlatformInfo.Platform.ToString().ToLowerInvariant())
|
||||
.AddQueryParam("branch", _configFileProvider.Branch)
|
||||
.AddQueryParam("branch", _configFileProvider.CurrentValue.Branch)
|
||||
.Build();
|
||||
try
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NLog;
|
||||
using NLog.Config;
|
||||
using NLog.Targets.Syslog;
|
||||
|
|
@ -17,21 +18,21 @@ namespace NzbDrone.Core.Instrumentation
|
|||
{
|
||||
public class ReconfigureLogging : IHandleAsync<ConfigFileSavedEvent>
|
||||
{
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
|
||||
public ReconfigureLogging(IConfigFileProvider configFileProvider)
|
||||
public ReconfigureLogging(IOptionsMonitor<ConfigFileOptions> configFileProvider)
|
||||
{
|
||||
_configFileProvider = configFileProvider;
|
||||
}
|
||||
|
||||
public void Reconfigure()
|
||||
{
|
||||
var minimumLogLevel = LogLevel.FromString(_configFileProvider.LogLevel);
|
||||
var minimumLogLevel = LogLevel.FromString(_configFileProvider.CurrentValue.LogLevel);
|
||||
LogLevel minimumConsoleLogLevel;
|
||||
|
||||
if (_configFileProvider.ConsoleLogLevel.IsNotNullOrWhiteSpace())
|
||||
if (_configFileProvider.CurrentValue.ConsoleLogLevel.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
minimumConsoleLogLevel = LogLevel.FromString(_configFileProvider.ConsoleLogLevel);
|
||||
minimumConsoleLogLevel = LogLevel.FromString(_configFileProvider.CurrentValue.ConsoleLogLevel);
|
||||
}
|
||||
else if (minimumLogLevel > LogLevel.Info)
|
||||
{
|
||||
|
|
@ -42,10 +43,10 @@ public void Reconfigure()
|
|||
minimumConsoleLogLevel = LogLevel.Info;
|
||||
}
|
||||
|
||||
if (_configFileProvider.SyslogServer.IsNotNullOrWhiteSpace())
|
||||
if (_configFileProvider.CurrentValue.SyslogServer.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
var syslogLevel = LogLevel.FromString(_configFileProvider.SyslogLevel);
|
||||
SetSyslogParameters(_configFileProvider.SyslogServer, _configFileProvider.SyslogPort, syslogLevel);
|
||||
var syslogLevel = LogLevel.FromString(_configFileProvider.CurrentValue.SyslogLevel);
|
||||
SetSyslogParameters(_configFileProvider.CurrentValue.SyslogServer, _configFileProvider.CurrentValue.SyslogPort, syslogLevel);
|
||||
}
|
||||
|
||||
var rules = LogManager.Configuration.LoggingRules;
|
||||
|
|
@ -60,7 +61,7 @@ public void Reconfigure()
|
|||
SetLogRotation();
|
||||
|
||||
//Log Sql
|
||||
SqlBuilderExtensions.LogSql = _configFileProvider.LogSql;
|
||||
SqlBuilderExtensions.LogSql = _configFileProvider.CurrentValue.LogSql;
|
||||
|
||||
//Sentry
|
||||
ReconfigureSentry();
|
||||
|
|
@ -95,7 +96,7 @@ private void SetLogRotation()
|
|||
{
|
||||
foreach (var target in LogManager.Configuration.AllTargets.OfType<NzbDroneFileTarget>())
|
||||
{
|
||||
target.MaxArchiveFiles = _configFileProvider.LogRotate;
|
||||
target.MaxArchiveFiles = _configFileProvider.CurrentValue.LogRotate;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -104,8 +105,8 @@ private void ReconfigureSentry()
|
|||
var sentryTarget = LogManager.Configuration.AllTargets.OfType<SentryTarget>().FirstOrDefault();
|
||||
if (sentryTarget != null)
|
||||
{
|
||||
sentryTarget.SentryEnabled = (RuntimeInfo.IsProduction && _configFileProvider.AnalyticsEnabled) || RuntimeInfo.IsDevelopment;
|
||||
sentryTarget.FilterEvents = _configFileProvider.FilterSentryEvents;
|
||||
sentryTarget.SentryEnabled = (RuntimeInfo.IsProduction && _configFileProvider.CurrentValue.AnalyticsEnabled) || RuntimeInfo.IsDevelopment;
|
||||
sentryTarget.FilterEvents = _configFileProvider.CurrentValue.FilterSentryEvents;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -119,7 +120,7 @@ private void SetSyslogParameters(string syslogServer, int syslogPort, LogLevel m
|
|||
syslogTarget.MessageSend.Udp.Server = syslogServer;
|
||||
syslogTarget.MessageSend.Udp.ReconnectInterval = 500;
|
||||
syslogTarget.MessageCreation.Rfc = RfcNumber.Rfc5424;
|
||||
syslogTarget.MessageCreation.Rfc5424.AppName = _configFileProvider.InstanceName;
|
||||
syslogTarget.MessageCreation.Rfc5424.AppName = _configFileProvider.CurrentValue.InstanceName;
|
||||
|
||||
var loggingRule = new LoggingRule("*", minimumLogLevel, syslogTarget);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Linq;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Instrumentation.Sentry;
|
||||
|
|
@ -11,11 +12,11 @@ namespace NzbDrone.Core.Instrumentation
|
|||
{
|
||||
public class ReconfigureSentry : IHandleAsync<ApplicationStartedEvent>
|
||||
{
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
private readonly IPlatformInfo _platformInfo;
|
||||
private readonly IMainDatabase _database;
|
||||
|
||||
public ReconfigureSentry(IConfigFileProvider configFileProvider,
|
||||
public ReconfigureSentry(IOptionsMonitor<ConfigFileOptions> configFileProvider,
|
||||
IPlatformInfo platformInfo,
|
||||
IMainDatabase database)
|
||||
{
|
||||
|
|
@ -30,7 +31,7 @@ public void Reconfigure()
|
|||
var sentryTarget = LogManager.Configuration.AllTargets.OfType<SentryTarget>().FirstOrDefault();
|
||||
if (sentryTarget != null)
|
||||
{
|
||||
sentryTarget.UpdateScope(_database.Version, _database.Migration, _configFileProvider.Branch, _platformInfo);
|
||||
sentryTarget.UpdateScope(_database.Version, _database.Migration, _configFileProvider.CurrentValue.Branch, _platformInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NzbDrone.Common.Cache;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
|
@ -18,10 +19,10 @@ public interface IMediaCoverProxy
|
|||
public class MediaCoverProxy : IMediaCoverProxy
|
||||
{
|
||||
private readonly IHttpClient _httpClient;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
private readonly ICached<string> _cache;
|
||||
|
||||
public MediaCoverProxy(IHttpClient httpClient, IConfigFileProvider configFileProvider, ICacheManager cacheManager)
|
||||
public MediaCoverProxy(IHttpClient httpClient, IOptionsMonitor<ConfigFileOptions> configFileProvider, ICacheManager cacheManager)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
_configFileProvider = configFileProvider;
|
||||
|
|
@ -37,7 +38,7 @@ public string RegisterUrl(string url)
|
|||
_cache.ClearExpired();
|
||||
|
||||
var fileName = Path.GetFileName(url);
|
||||
return _configFileProvider.UrlBase + @"/MediaCoverProxy/" + hash + "/" + fileName;
|
||||
return _configFileProvider.CurrentValue.UrlBase + @"/MediaCoverProxy/" + hash + "/" + fileName;
|
||||
}
|
||||
|
||||
public string GetUrl(string hash)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Disk;
|
||||
|
|
@ -35,7 +36,7 @@ public class MediaCoverService :
|
|||
private readonly IHttpClient _httpClient;
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly ICoverExistsSpecification _coverExistsSpecification;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly Logger _logger;
|
||||
|
||||
|
|
@ -51,7 +52,7 @@ public MediaCoverService(IMediaCoverProxy mediaCoverProxy,
|
|||
IDiskProvider diskProvider,
|
||||
IAppFolderInfo appFolderInfo,
|
||||
ICoverExistsSpecification coverExistsSpecification,
|
||||
IConfigFileProvider configFileProvider,
|
||||
IOptionsMonitor<ConfigFileOptions> configFileProvider,
|
||||
IEventAggregator eventAggregator,
|
||||
Logger logger)
|
||||
{
|
||||
|
|
@ -104,7 +105,7 @@ public void ConvertToLocalUrls(int movieId, IEnumerable<MediaCover> covers, Dict
|
|||
var filePath = GetCoverPath(movieId, mediaCover.CoverType);
|
||||
|
||||
mediaCover.RemoteUrl = mediaCover.Url;
|
||||
mediaCover.Url = _configFileProvider.UrlBase + @"/MediaCover/" + movieId + "/" + mediaCover.CoverType.ToString().ToLower() + ".jpg";
|
||||
mediaCover.Url = _configFileProvider.CurrentValue.UrlBase + @"/MediaCover/" + movieId + "/" + mediaCover.CoverType.ToString().ToLower() + ".jpg";
|
||||
|
||||
FileInfo file;
|
||||
var fileExists = false;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@
|
|||
<PackageReference Include="System.Memory" Version="4.5.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0-preview.5.22301.12" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="7.0.0-preview.5.22301.12" />
|
||||
<PackageReference Include="FluentMigrator.Runner" Version="3.3.2" />
|
||||
<PackageReference Include="FluentMigrator.Runner.SQLite" Version="3.3.2" />
|
||||
<PackageReference Include="FluentValidation" Version="8.6.2" />
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
|
@ -16,19 +17,21 @@ public interface IUpdaterConfigProvider
|
|||
public class UpdaterConfigProvider : IUpdaterConfigProvider, IHandle<ApplicationStartedEvent>
|
||||
{
|
||||
private readonly Logger _logger;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
private readonly IConfigFileWriter _configFileWriter;
|
||||
private readonly IDeploymentInfoProvider _deploymentInfoProvider;
|
||||
|
||||
public UpdaterConfigProvider(IDeploymentInfoProvider deploymentInfoProvider, IConfigFileProvider configFileProvider, Logger logger)
|
||||
public UpdaterConfigProvider(IDeploymentInfoProvider deploymentInfoProvider, IOptionsMonitor<ConfigFileOptions> configFileProvider, IConfigFileWriter configFileWriter, Logger logger)
|
||||
{
|
||||
_deploymentInfoProvider = deploymentInfoProvider;
|
||||
_configFileProvider = configFileProvider;
|
||||
_configFileWriter = configFileWriter;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void Handle(ApplicationStartedEvent message)
|
||||
{
|
||||
var updateMechanism = _configFileProvider.UpdateMechanism;
|
||||
var updateMechanism = _configFileProvider.CurrentValue.UpdateMechanism;
|
||||
var packageUpdateMechanism = _deploymentInfoProvider.PackageUpdateMechanism;
|
||||
|
||||
var externalMechanisms = Enum.GetValues(typeof(UpdateMechanism))
|
||||
|
|
@ -49,7 +52,7 @@ public void Handle(ApplicationStartedEvent message)
|
|||
|
||||
if (_deploymentInfoProvider.IsExternalUpdateMechanism)
|
||||
{
|
||||
var currentBranch = _configFileProvider.Branch;
|
||||
var currentBranch = _configFileProvider.CurrentValue.Branch;
|
||||
var packageBranch = _deploymentInfoProvider.PackageBranch;
|
||||
if (packageBranch.IsNotNullOrWhiteSpace() && packageBranch != currentBranch)
|
||||
{
|
||||
|
|
@ -63,18 +66,18 @@ private void ChangeUpdateMechanism(UpdateMechanism updateMechanism)
|
|||
{
|
||||
var config = new Dictionary<string, object>
|
||||
{
|
||||
[nameof(_configFileProvider.UpdateMechanism)] = updateMechanism
|
||||
[nameof(_configFileProvider.CurrentValue.UpdateMechanism)] = updateMechanism
|
||||
};
|
||||
_configFileProvider.SaveConfigDictionary(config);
|
||||
_configFileWriter.SaveConfigDictionary(config);
|
||||
}
|
||||
|
||||
private void ChangeBranch(string branch)
|
||||
{
|
||||
var config = new Dictionary<string, object>
|
||||
{
|
||||
[nameof(_configFileProvider.Branch)] = branch
|
||||
[nameof(_configFileProvider.CurrentValue.Branch)] = branch
|
||||
};
|
||||
_configFileProvider.SaveConfigDictionary(config);
|
||||
_configFileWriter.SaveConfigDictionary(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Disk;
|
||||
|
|
@ -34,7 +36,8 @@ public class InstallUpdateService : IExecute<ApplicationCheckUpdateCommand>, IEx
|
|||
private readonly IVerifyUpdates _updateVerifier;
|
||||
private readonly IStartupContext _startupContext;
|
||||
private readonly IDeploymentInfoProvider _deploymentInfoProvider;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
private readonly IConfigFileWriter _configFileWriter;
|
||||
private readonly IRuntimeInfo _runtimeInfo;
|
||||
private readonly IBackupService _backupService;
|
||||
private readonly IOsInfo _osInfo;
|
||||
|
|
@ -50,7 +53,8 @@ public InstallUpdateService(ICheckUpdateService checkUpdateService,
|
|||
IVerifyUpdates updateVerifier,
|
||||
IStartupContext startupContext,
|
||||
IDeploymentInfoProvider deploymentInfoProvider,
|
||||
IConfigFileProvider configFileProvider,
|
||||
IOptionsMonitor<ConfigFileOptions> configFileProvider,
|
||||
IConfigFileWriter configFileWriter,
|
||||
IRuntimeInfo runtimeInfo,
|
||||
IBackupService backupService,
|
||||
IOsInfo osInfo,
|
||||
|
|
@ -73,6 +77,7 @@ public InstallUpdateService(ICheckUpdateService checkUpdateService,
|
|||
_startupContext = startupContext;
|
||||
_deploymentInfoProvider = deploymentInfoProvider;
|
||||
_configFileProvider = configFileProvider;
|
||||
_configFileWriter = configFileWriter;
|
||||
_runtimeInfo = runtimeInfo;
|
||||
_backupService = backupService;
|
||||
_osInfo = osInfo;
|
||||
|
|
@ -83,7 +88,7 @@ private bool InstallUpdate(UpdatePackage updatePackage)
|
|||
{
|
||||
EnsureAppDataSafety();
|
||||
|
||||
if (OsInfo.IsWindows || _configFileProvider.UpdateMechanism != UpdateMechanism.Script)
|
||||
if (OsInfo.IsWindows || _configFileProvider.CurrentValue.UpdateMechanism != UpdateMechanism.Script)
|
||||
{
|
||||
var startupFolder = _appFolderInfo.StartUpFolder;
|
||||
var uiFolder = Path.Combine(startupFolder, "UI");
|
||||
|
|
@ -137,7 +142,7 @@ private bool InstallUpdate(UpdatePackage updatePackage)
|
|||
|
||||
_backupService.Backup(BackupType.Update);
|
||||
|
||||
if (OsInfo.IsNotWindows && _configFileProvider.UpdateMechanism == UpdateMechanism.Script)
|
||||
if (OsInfo.IsNotWindows && _configFileProvider.CurrentValue.UpdateMechanism == UpdateMechanism.Script)
|
||||
{
|
||||
InstallUpdateWithScript(updateSandboxFolder);
|
||||
return true;
|
||||
|
|
@ -170,7 +175,7 @@ private bool InstallUpdate(UpdatePackage updatePackage)
|
|||
|
||||
private void EnsureValidBranch(UpdatePackage package)
|
||||
{
|
||||
var currentBranch = _configFileProvider.Branch;
|
||||
var currentBranch = _configFileProvider.CurrentValue.Branch;
|
||||
if (package.Branch != currentBranch)
|
||||
{
|
||||
try
|
||||
|
|
@ -178,7 +183,7 @@ private void EnsureValidBranch(UpdatePackage package)
|
|||
_logger.Info("Branch [{0}] is being redirected to [{1}]]", currentBranch, package.Branch);
|
||||
var config = new Dictionary<string, object>();
|
||||
config["Branch"] = package.Branch;
|
||||
_configFileProvider.SaveConfigDictionary(config);
|
||||
_configFileWriter.SaveConfigDictionary(config);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
@ -189,7 +194,7 @@ private void EnsureValidBranch(UpdatePackage package)
|
|||
|
||||
private void InstallUpdateWithScript(string updateSandboxFolder)
|
||||
{
|
||||
var scriptPath = _configFileProvider.UpdateScriptPath;
|
||||
var scriptPath = _configFileProvider.CurrentValue.UpdateScriptPath;
|
||||
|
||||
if (scriptPath.IsNullOrWhiteSpace())
|
||||
{
|
||||
|
|
@ -204,7 +209,7 @@ private void InstallUpdateWithScript(string updateSandboxFolder)
|
|||
_logger.Info("Removing Radarr.Update");
|
||||
_diskProvider.DeleteFolder(_appFolderInfo.GetUpdateClientFolder(), true);
|
||||
|
||||
_logger.ProgressInfo("Starting update script: {0}", _configFileProvider.UpdateScriptPath);
|
||||
_logger.ProgressInfo("Starting update script: {0}", _configFileProvider.CurrentValue.UpdateScriptPath);
|
||||
_processProvider.Start(scriptPath, GetUpdaterArgs(updateSandboxFolder));
|
||||
}
|
||||
|
||||
|
|
@ -243,19 +248,19 @@ private UpdatePackage GetUpdatePackage(CommandTrigger updateTrigger)
|
|||
return null;
|
||||
}
|
||||
|
||||
if (OsInfo.IsNotWindows && !_configFileProvider.UpdateAutomatically && updateTrigger != CommandTrigger.Manual)
|
||||
if (OsInfo.IsNotWindows && !_configFileProvider.CurrentValue.UpdateAutomatically && updateTrigger != CommandTrigger.Manual)
|
||||
{
|
||||
_logger.ProgressDebug("Auto-update not enabled, not installing available update.");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Safety net, ConfigureUpdateMechanism should take care of invalid settings
|
||||
if (_configFileProvider.UpdateMechanism == UpdateMechanism.BuiltIn && _deploymentInfoProvider.IsExternalUpdateMechanism)
|
||||
if (_configFileProvider.CurrentValue.UpdateMechanism == UpdateMechanism.BuiltIn && _deploymentInfoProvider.IsExternalUpdateMechanism)
|
||||
{
|
||||
_logger.ProgressDebug("Built-In updater disabled, please use {0} to install", _deploymentInfoProvider.PackageUpdateMechanism);
|
||||
return null;
|
||||
}
|
||||
else if (_configFileProvider.UpdateMechanism != UpdateMechanism.Script && _deploymentInfoProvider.IsExternalUpdateMechanism)
|
||||
else if (_configFileProvider.CurrentValue.UpdateMechanism != UpdateMechanism.Script && _deploymentInfoProvider.IsExternalUpdateMechanism)
|
||||
{
|
||||
_logger.ProgressDebug("Update available, please use {0} to install", _deploymentInfoProvider.PackageUpdateMechanism);
|
||||
return null;
|
||||
|
|
@ -315,8 +320,8 @@ public void Handle(ApplicationStartingEvent message)
|
|||
_logger.Debug("Post-install update check requested");
|
||||
|
||||
// Don't do a prestartup update check unless BuiltIn update is enabled
|
||||
if (!_configFileProvider.UpdateAutomatically ||
|
||||
_configFileProvider.UpdateMechanism != UpdateMechanism.BuiltIn ||
|
||||
if (!_configFileProvider.CurrentValue.UpdateAutomatically ||
|
||||
_configFileProvider.CurrentValue.UpdateMechanism != UpdateMechanism.BuiltIn ||
|
||||
_deploymentInfoProvider.IsExternalUpdateMechanism)
|
||||
{
|
||||
_logger.Debug("Built-in updater disabled, skipping post-install update check");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Update.History;
|
||||
|
|
@ -12,11 +13,11 @@ public interface IRecentUpdateProvider
|
|||
|
||||
public class RecentUpdateProvider : IRecentUpdateProvider
|
||||
{
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
private readonly IUpdatePackageProvider _updatePackageProvider;
|
||||
private readonly IUpdateHistoryService _updateHistoryService;
|
||||
|
||||
public RecentUpdateProvider(IConfigFileProvider configFileProvider,
|
||||
public RecentUpdateProvider(IOptionsMonitor<ConfigFileOptions> configFileProvider,
|
||||
IUpdatePackageProvider updatePackageProvider,
|
||||
IUpdateHistoryService updateHistoryService)
|
||||
{
|
||||
|
|
@ -27,7 +28,7 @@ public RecentUpdateProvider(IConfigFileProvider configFileProvider,
|
|||
|
||||
public List<UpdatePackage> GetRecentUpdatePackages()
|
||||
{
|
||||
var branch = _configFileProvider.Branch;
|
||||
var branch = _configFileProvider.CurrentValue.Branch;
|
||||
var version = BuildInfo.Version;
|
||||
var prevVersion = _updateHistoryService.PreviouslyInstalled();
|
||||
return _updatePackageProvider.GetRecentUpdates(branch, version, prevVersion);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using Microsoft.Extensions.Options;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
||||
|
|
@ -11,10 +12,10 @@ public interface ICheckUpdateService
|
|||
public class CheckUpdateService : ICheckUpdateService
|
||||
{
|
||||
private readonly IUpdatePackageProvider _updatePackageProvider;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
|
||||
public CheckUpdateService(IUpdatePackageProvider updatePackageProvider,
|
||||
IConfigFileProvider configFileProvider)
|
||||
IOptionsMonitor<ConfigFileOptions> configFileProvider)
|
||||
{
|
||||
_updatePackageProvider = updatePackageProvider;
|
||||
_configFileProvider = configFileProvider;
|
||||
|
|
@ -22,7 +23,7 @@ public CheckUpdateService(IUpdatePackageProvider updatePackageProvider,
|
|||
|
||||
public UpdatePackage AvailableUpdate()
|
||||
{
|
||||
return _updatePackageProvider.GetLatestUpdate(_configFileProvider.Branch, BuildInfo.Version);
|
||||
return _updatePackageProvider.GetLatestUpdate(_configFileProvider.CurrentValue.Branch, BuildInfo.Version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
using NzbDrone.Common.Composition.Extensions;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Instrumentation.Extensions;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Datastore.Extensions;
|
||||
using NzbDrone.Core.Download;
|
||||
|
|
@ -44,9 +45,9 @@ public void SetUp()
|
|||
.AddStartupContext(args);
|
||||
|
||||
// dummy lifetime and broadcaster so tests resolve
|
||||
container.RegisterInstance<IHostLifetime>(new Mock<IHostLifetime>().Object);
|
||||
container.RegisterInstance<IBroadcastSignalRMessage>(new Mock<IBroadcastSignalRMessage>().Object);
|
||||
container.RegisterInstance<IOptions<PostgresOptions>>(new Mock<IOptions<PostgresOptions>>().Object);
|
||||
container.RegisterInstance(new Mock<IHostLifetime>().Object);
|
||||
container.RegisterInstance(new Mock<IBroadcastSignalRMessage>().Object);
|
||||
container.RegisterInstance(new Mock<IOptionsMonitor<ConfigFileOptions>>().Object);
|
||||
|
||||
_container = container.GetServiceProvider();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NetFwTypeLib;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
|
@ -16,10 +17,10 @@ public class FirewallAdapter : IFirewallAdapter
|
|||
{
|
||||
private const NET_FW_PROFILE_TYPE_ FIREWALL_PROFILE = NET_FW_PROFILE_TYPE_.NET_FW_PROFILE_STANDARD;
|
||||
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public FirewallAdapter(IConfigFileProvider configFileProvider, Logger logger)
|
||||
public FirewallAdapter(IOptionsMonitor<ConfigFileOptions> configFileProvider, Logger logger)
|
||||
{
|
||||
_configFileProvider = configFileProvider;
|
||||
_logger = logger;
|
||||
|
|
@ -29,16 +30,16 @@ public void MakeAccessible()
|
|||
{
|
||||
if (IsFirewallEnabled())
|
||||
{
|
||||
if (!IsNzbDronePortOpen(_configFileProvider.Port))
|
||||
if (!IsNzbDronePortOpen(_configFileProvider.CurrentValue.Port))
|
||||
{
|
||||
_logger.Debug("Opening Port for Radarr: {0}", _configFileProvider.Port);
|
||||
OpenFirewallPort(_configFileProvider.Port);
|
||||
_logger.Debug("Opening Port for Radarr: {0}", _configFileProvider.CurrentValue.Port);
|
||||
OpenFirewallPort(_configFileProvider.CurrentValue.Port);
|
||||
}
|
||||
|
||||
if (_configFileProvider.EnableSsl && !IsNzbDronePortOpen(_configFileProvider.SslPort))
|
||||
if (_configFileProvider.CurrentValue.EnableSsl && !IsNzbDronePortOpen(_configFileProvider.CurrentValue.SslPort))
|
||||
{
|
||||
_logger.Debug("Opening SSL Port for Radarr: {0}", _configFileProvider.SslPort);
|
||||
OpenFirewallPort(_configFileProvider.SslPort);
|
||||
_logger.Debug("Opening SSL Port for Radarr: {0}", _configFileProvider.CurrentValue.SslPort);
|
||||
OpenFirewallPort(_configFileProvider.CurrentValue.SslPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Processes;
|
||||
|
|
@ -14,7 +15,7 @@ namespace NzbDrone.Host
|
|||
public class AppLifetime : IHostedService, IHandle<ApplicationShutdownRequested>
|
||||
{
|
||||
private readonly IHostApplicationLifetime _appLifetime;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
private readonly IRuntimeInfo _runtimeInfo;
|
||||
private readonly IStartupContext _startupContext;
|
||||
private readonly IBrowserService _browserService;
|
||||
|
|
@ -23,7 +24,7 @@ public class AppLifetime : IHostedService, IHandle<ApplicationShutdownRequested>
|
|||
private readonly Logger _logger;
|
||||
|
||||
public AppLifetime(IHostApplicationLifetime appLifetime,
|
||||
IConfigFileProvider configFileProvider,
|
||||
IOptionsMonitor<ConfigFileOptions> configFileProvider,
|
||||
IRuntimeInfo runtimeInfo,
|
||||
IStartupContext startupContext,
|
||||
IBrowserService browserService,
|
||||
|
|
@ -59,7 +60,7 @@ private void OnAppStarted()
|
|||
_runtimeInfo.IsExiting = false;
|
||||
|
||||
if (!_startupContext.Flags.Contains(StartupContext.NO_BROWSER)
|
||||
&& _configFileProvider.LaunchBrowser)
|
||||
&& _configFileProvider.CurrentValue.LaunchBrowser)
|
||||
{
|
||||
_browserService.LaunchWebUI();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using DryIoc;
|
||||
using DryIoc.Microsoft.DependencyInjection;
|
||||
|
|
@ -23,7 +21,6 @@
|
|||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Datastore.Extensions;
|
||||
using NzbDrone.Host;
|
||||
using PostgresOptions = NzbDrone.Core.Datastore.PostgresOptions;
|
||||
|
||||
namespace Radarr.Host
|
||||
{
|
||||
|
|
@ -53,7 +50,6 @@ public static void Start(string[] args, Action<IHostBuilder> trayCallback = null
|
|||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
|
||||
var appMode = GetApplicationMode(startupContext);
|
||||
var config = GetConfiguration(startupContext);
|
||||
|
||||
switch (appMode)
|
||||
{
|
||||
|
|
@ -86,18 +82,13 @@ public static void Start(string[] args, Action<IHostBuilder> trayCallback = null
|
|||
.UseServiceProviderFactory(new DryIocServiceProviderFactory(new Container(rules => rules.WithNzbDroneRules())))
|
||||
.ConfigureContainer<IContainer>(c =>
|
||||
{
|
||||
c.AutoAddServices(Bootstrap.ASSEMBLIES)
|
||||
c.AutoAddServices(ASSEMBLIES)
|
||||
.AddNzbDroneLogger()
|
||||
.AddDatabase()
|
||||
.AddStartupContext(startupContext)
|
||||
.Resolve<UtilityModeRouter>()
|
||||
.Route(appMode);
|
||||
})
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.Configure<PostgresOptions>(config.GetSection("Radarr:Postgres"));
|
||||
}).Build();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -115,55 +106,20 @@ public static void Start(string[] args, Action<IHostBuilder> trayCallback = null
|
|||
|
||||
public static IHostBuilder CreateConsoleHostBuilder(string[] args, StartupContext context)
|
||||
{
|
||||
var config = GetConfiguration(context);
|
||||
|
||||
var bindAddress = config.GetValue(nameof(ConfigFileProvider.BindAddress), "*");
|
||||
var port = config.GetValue(nameof(ConfigFileProvider.Port), 7878);
|
||||
var sslPort = config.GetValue(nameof(ConfigFileProvider.SslPort), 8787);
|
||||
var enableSsl = config.GetValue(nameof(ConfigFileProvider.EnableSsl), false);
|
||||
var sslCertPath = config.GetValue<string>(nameof(ConfigFileProvider.SslCertPath));
|
||||
var sslCertPassword = config.GetValue<string>(nameof(ConfigFileProvider.SslCertPassword));
|
||||
|
||||
var urls = new List<string> { BuildUrl("http", bindAddress, port) };
|
||||
|
||||
if (enableSsl && sslCertPath.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
urls.Add(BuildUrl("https", bindAddress, sslPort));
|
||||
}
|
||||
|
||||
return new HostBuilder()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.AddConfig(context)
|
||||
.UseServiceProviderFactory(new DryIocServiceProviderFactory(new Container(rules => rules.WithNzbDroneRules())))
|
||||
.ConfigureContainer<IContainer>(c =>
|
||||
{
|
||||
c.AutoAddServices(Bootstrap.ASSEMBLIES)
|
||||
c.AutoAddServices(ASSEMBLIES)
|
||||
.AddNzbDroneLogger()
|
||||
.AddDatabase()
|
||||
.AddStartupContext(context);
|
||||
})
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.Configure<PostgresOptions>(config.GetSection("Radarr:Postgres"));
|
||||
})
|
||||
.ConfigureWebHost(builder =>
|
||||
{
|
||||
builder.UseConfiguration(config);
|
||||
builder.UseUrls(urls.ToArray());
|
||||
builder.UseKestrel(options =>
|
||||
{
|
||||
if (enableSsl && sslCertPath.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
options.ConfigureHttpsDefaults(configureOptions =>
|
||||
{
|
||||
configureOptions.ServerCertificate = ValidateSslCertificate(sslCertPath, sslCertPassword);
|
||||
});
|
||||
}
|
||||
});
|
||||
builder.ConfigureKestrel(serverOptions =>
|
||||
{
|
||||
serverOptions.AllowSynchronousIO = true;
|
||||
serverOptions.Limits.MaxRequestBodySize = null;
|
||||
});
|
||||
builder.UseKestrel();
|
||||
builder.UseStartup<Startup>();
|
||||
});
|
||||
}
|
||||
|
|
@ -209,41 +165,15 @@ public static ApplicationModes GetApplicationMode(IStartupContext startupContext
|
|||
return ApplicationModes.Interactive;
|
||||
}
|
||||
|
||||
private static IConfiguration GetConfiguration(StartupContext context)
|
||||
private static IHostBuilder AddConfig(this IHostBuilder builder, StartupContext context)
|
||||
{
|
||||
var appFolder = new AppFolderInfo(context);
|
||||
return new ConfigurationBuilder()
|
||||
.AddXmlFile(appFolder.GetConfigPath(), optional: true, reloadOnChange: false)
|
||||
return builder.ConfigureAppConfiguration((_, config) =>
|
||||
{
|
||||
config.AddXmlFile(appFolder.GetConfigPath(), optional: true, reloadOnChange: true)
|
||||
.AddInMemoryCollection(new List<KeyValuePair<string, string>> { new ("dataProtectionFolder", appFolder.GetDataProtectionPath()) })
|
||||
.AddEnvironmentVariables()
|
||||
.Build();
|
||||
}
|
||||
|
||||
private static string BuildUrl(string scheme, string bindAddress, int port)
|
||||
{
|
||||
return $"{scheme}://{bindAddress}:{port}";
|
||||
}
|
||||
|
||||
private static X509Certificate2 ValidateSslCertificate(string cert, string password)
|
||||
{
|
||||
X509Certificate2 certificate;
|
||||
|
||||
try
|
||||
{
|
||||
certificate = new X509Certificate2(cert, password, X509KeyStorageFlags.DefaultKeySet);
|
||||
}
|
||||
catch (CryptographicException ex)
|
||||
{
|
||||
if (ex.HResult == 0x2 || ex.HResult == 0x2006D080)
|
||||
{
|
||||
throw new RadarrStartupException(ex,
|
||||
$"The SSL certificate file {cert} does not exist");
|
||||
}
|
||||
|
||||
throw new RadarrStartupException(ex);
|
||||
}
|
||||
|
||||
return certificate;
|
||||
.AddEnvironmentVariables($"{BuildInfo.AppName}:");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Processes;
|
||||
|
|
@ -14,11 +15,11 @@ public interface IBrowserService
|
|||
public class BrowserService : IBrowserService
|
||||
{
|
||||
private readonly IProcessProvider _processProvider;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
private readonly IRuntimeInfo _runtimeInfo;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public BrowserService(IProcessProvider processProvider, IConfigFileProvider configFileProvider, IRuntimeInfo runtimeInfo, Logger logger)
|
||||
public BrowserService(IProcessProvider processProvider, IOptionsMonitor<ConfigFileOptions> configFileProvider, IRuntimeInfo runtimeInfo, Logger logger)
|
||||
{
|
||||
_processProvider = processProvider;
|
||||
_configFileProvider = configFileProvider;
|
||||
|
|
@ -28,7 +29,7 @@ public BrowserService(IProcessProvider processProvider, IConfigFileProvider conf
|
|||
|
||||
public void LaunchWebUI()
|
||||
{
|
||||
var url = string.Format("http://localhost:{0}", _configFileProvider.Port);
|
||||
var url = string.Format("http://localhost:{0}", _configFileProvider.CurrentValue.Port);
|
||||
try
|
||||
{
|
||||
if (_runtimeInfo.IsUserInteractive)
|
||||
|
|
|
|||
81
src/NzbDrone.Host/ConfigureKestrel.cs
Normal file
81
src/NzbDrone.Host/ConfigureKestrel.cs
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NzbDrone.Common.Exceptions;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
||||
namespace NzbDrone.Host
|
||||
{
|
||||
public class ConfigureKestrel : IConfigureOptions<KestrelServerOptions>
|
||||
{
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _config;
|
||||
|
||||
public ConfigureKestrel(IOptionsMonitor<ConfigFileOptions> config)
|
||||
{
|
||||
_config = config;
|
||||
}
|
||||
|
||||
public void Configure(KestrelServerOptions options)
|
||||
{
|
||||
options.AllowSynchronousIO = true;
|
||||
options.Limits.MaxRequestBodySize = null;
|
||||
|
||||
Listen(options, _config.CurrentValue.BindAddress, _config.CurrentValue.Port);
|
||||
|
||||
if (_config.CurrentValue.EnableSsl && _config.CurrentValue.SslCertPath.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
options.ConfigureHttpsDefaults(opts => opts.ServerCertificate = ValidateSslCertificate(_config.CurrentValue.SslCertPath, _config.CurrentValue.SslCertPassword));
|
||||
Listen(options, _config.CurrentValue.BindAddress, _config.CurrentValue.SslPort, opts => opts.UseHttps());
|
||||
}
|
||||
}
|
||||
|
||||
private static void Listen(KestrelServerOptions options, string address, int port)
|
||||
{
|
||||
Listen(options, address, port, _ => { });
|
||||
}
|
||||
|
||||
private static void Listen(KestrelServerOptions options, string address, int port, Action<ListenOptions> configureListenOptions)
|
||||
{
|
||||
// following https://github.com/dotnet/aspnetcore/blob/d96a100bddc72606f7417b665428411388b8ac54/src/Servers/Kestrel/Core/src/Internal/AddressBinder.cs#L123
|
||||
if (string.Equals(address, "localhost", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
options.ListenLocalhost(port, configureListenOptions);
|
||||
}
|
||||
else if (IPAddress.TryParse(address, out var endpoint))
|
||||
{
|
||||
options.Listen(endpoint, port, configureListenOptions);
|
||||
}
|
||||
else
|
||||
{
|
||||
options.ListenAnyIP(port, configureListenOptions);
|
||||
}
|
||||
}
|
||||
|
||||
private static X509Certificate2 ValidateSslCertificate(string cert, string password)
|
||||
{
|
||||
X509Certificate2 certificate;
|
||||
|
||||
try
|
||||
{
|
||||
certificate = new X509Certificate2(cert, password, X509KeyStorageFlags.DefaultKeySet);
|
||||
}
|
||||
catch (CryptographicException ex)
|
||||
{
|
||||
if (ex.HResult == 0x2 || ex.HResult == 0x2006D080)
|
||||
{
|
||||
throw new RadarrStartupException(ex,
|
||||
$"The SSL certificate file {cert} does not exist");
|
||||
}
|
||||
|
||||
throw new RadarrStartupException(ex);
|
||||
}
|
||||
|
||||
return certificate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
|
@ -10,6 +11,7 @@
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using NLog.Extensions.Logging;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
|
@ -44,13 +46,14 @@ public Startup(IConfiguration configuration)
|
|||
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.Configure<ConfigFileOptions>(Configuration);
|
||||
|
||||
services.AddLogging(b =>
|
||||
{
|
||||
b.ClearProviders();
|
||||
b.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
|
||||
b.AddFilter("Microsoft.AspNetCore", Microsoft.Extensions.Logging.LogLevel.Warning);
|
||||
b.SetMinimumLevel(LogLevel.Trace);
|
||||
b.AddFilter("Microsoft.AspNetCore", LogLevel.Warning);
|
||||
b.AddFilter("Radarr.Http.Authentication", LogLevel.Information);
|
||||
b.AddFilter("Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager", LogLevel.Error);
|
||||
b.AddNLog();
|
||||
});
|
||||
|
||||
|
|
@ -213,7 +216,8 @@ public void Configure(IApplicationBuilder app,
|
|||
ReconfigureLogging reconfigureLogging,
|
||||
IAppFolderFactory appFolderFactory,
|
||||
IProvidePidFile pidFileProvider,
|
||||
IConfigFileProvider configFileProvider,
|
||||
IConfigFileWriter configFileWriter,
|
||||
IOptions<ConfigFileOptions> configFileProvider,
|
||||
IRuntimeInfo runtimeInfo,
|
||||
IFirewallAdapter firewallAdapter,
|
||||
RadarrErrorPipeline errorHandler)
|
||||
|
|
@ -221,6 +225,7 @@ public void Configure(IApplicationBuilder app,
|
|||
initializeLogger.Initialize();
|
||||
appFolderFactory.Register();
|
||||
pidFileProvider.Write();
|
||||
configFileWriter.EnsureDefaultConfigFile();
|
||||
|
||||
reconfigureLogging.Reconfigure();
|
||||
|
||||
|
|
@ -244,7 +249,7 @@ public void Configure(IApplicationBuilder app,
|
|||
|
||||
app.UseForwardedHeaders();
|
||||
app.UseMiddleware<LoggingMiddleware>();
|
||||
app.UsePathBase(new PathString(configFileProvider.UrlBase));
|
||||
app.UsePathBase(new PathString(configFileProvider.Value.UrlBase));
|
||||
app.UseExceptionHandler(new ExceptionHandlerOptions
|
||||
{
|
||||
AllowStatusCode404Response = true,
|
||||
|
|
@ -259,7 +264,7 @@ public void Configure(IApplicationBuilder app,
|
|||
app.Properties["host.AppName"] = BuildInfo.AppName;
|
||||
|
||||
app.UseMiddleware<VersionMiddleware>();
|
||||
app.UseMiddleware<UrlBaseMiddleware>(configFileProvider.UrlBase);
|
||||
app.UseMiddleware<UrlBaseMiddleware>(configFileProvider.Value.UrlBase);
|
||||
app.UseMiddleware<CacheHeaderMiddleware>();
|
||||
app.UseMiddleware<IfModifiedMiddleware>();
|
||||
app.UseMiddleware<BufferingMiddleware>(new List<string> { "/api/v3/command" });
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
using Npgsql;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
using NzbDrone.Core.Indexers.Newznab;
|
||||
|
|
@ -25,7 +26,7 @@ public abstract class IntegrationTest : IntegrationTestBase
|
|||
|
||||
protected int Port { get; private set; }
|
||||
|
||||
protected PostgresOptions PostgresOptions { get; set; } = new ();
|
||||
protected ConfigFileOptions Options { get; set; } = new ();
|
||||
|
||||
protected override string RootUrl => $"http://localhost:{Port}/";
|
||||
|
||||
|
|
@ -35,14 +36,14 @@ protected override void StartTestTarget()
|
|||
{
|
||||
Port = Interlocked.Increment(ref StaticPort);
|
||||
|
||||
PostgresOptions = PostgresDatabase.GetTestOptions();
|
||||
Options = ConfigFileOptions.GetOptions();
|
||||
|
||||
if (PostgresOptions?.Host != null)
|
||||
if (Options?.PostgresHost != null)
|
||||
{
|
||||
CreatePostgresDb(PostgresOptions);
|
||||
CreatePostgresDb(Options);
|
||||
}
|
||||
|
||||
_runner = new NzbDroneRunner(LogManager.GetCurrentClassLogger(), PostgresOptions, Port);
|
||||
_runner = new NzbDroneRunner(LogManager.GetCurrentClassLogger(), Options, Port);
|
||||
_runner.Kill();
|
||||
|
||||
_runner.Start();
|
||||
|
|
@ -74,19 +75,19 @@ protected override void InitializeTestTarget()
|
|||
protected override void StopTestTarget()
|
||||
{
|
||||
_runner.Kill();
|
||||
if (PostgresOptions?.Host != null)
|
||||
if (Options?.PostgresHost != null)
|
||||
{
|
||||
DropPostgresDb(PostgresOptions);
|
||||
DropPostgresDb(Options);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CreatePostgresDb(PostgresOptions options)
|
||||
private static void CreatePostgresDb(ConfigFileOptions options)
|
||||
{
|
||||
PostgresDatabase.Create(options, MigrationType.Main);
|
||||
PostgresDatabase.Create(options, MigrationType.Log);
|
||||
}
|
||||
|
||||
private static void DropPostgresDb(PostgresOptions options)
|
||||
private static void DropPostgresDb(ConfigFileOptions options)
|
||||
{
|
||||
PostgresDatabase.Drop(options, MigrationType.Main);
|
||||
PostgresDatabase.Drop(options, MigrationType.Log);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using Npgsql;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
|
|
@ -7,18 +8,18 @@ namespace NzbDrone.Test.Common.Datastore
|
|||
{
|
||||
public static class PostgresDatabase
|
||||
{
|
||||
public static PostgresOptions GetTestOptions()
|
||||
public static ConfigFileOptions GetTestOptions()
|
||||
{
|
||||
var options = PostgresOptions.GetOptions();
|
||||
var options = ConfigFileOptions.GetOptions();
|
||||
|
||||
var uid = TestBase.GetUID();
|
||||
options.MainDb = uid + "_main";
|
||||
options.LogDb = uid + "_log";
|
||||
options.PostgresMainDb = uid + "_main";
|
||||
options.PostgresLogDb = uid + "_log";
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
public static void Create(PostgresOptions options, MigrationType migrationType)
|
||||
public static void Create(ConfigFileOptions options, MigrationType migrationType)
|
||||
{
|
||||
var db = GetDatabaseName(options, migrationType);
|
||||
var connectionString = GetConnectionString(options);
|
||||
|
|
@ -26,11 +27,11 @@ public static void Create(PostgresOptions options, MigrationType migrationType)
|
|||
conn.Open();
|
||||
|
||||
using var cmd = conn.CreateCommand();
|
||||
cmd.CommandText = $"CREATE DATABASE \"{db}\" WITH OWNER = {options.User} ENCODING = 'UTF8' CONNECTION LIMIT = -1;";
|
||||
cmd.CommandText = $"CREATE DATABASE \"{db}\" WITH OWNER = {options.PostgresUser} ENCODING = 'UTF8' CONNECTION LIMIT = -1;";
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
public static void Drop(PostgresOptions options, MigrationType migrationType)
|
||||
public static void Drop(ConfigFileOptions options, MigrationType migrationType)
|
||||
{
|
||||
var db = GetDatabaseName(options, migrationType);
|
||||
var connectionString = GetConnectionString(options);
|
||||
|
|
@ -42,26 +43,26 @@ public static void Drop(PostgresOptions options, MigrationType migrationType)
|
|||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
private static string GetConnectionString(PostgresOptions options)
|
||||
private static string GetConnectionString(ConfigFileOptions options)
|
||||
{
|
||||
var builder = new NpgsqlConnectionStringBuilder()
|
||||
{
|
||||
Host = options.Host,
|
||||
Port = options.Port,
|
||||
Username = options.User,
|
||||
Password = options.Password,
|
||||
Host = options.PostgresHost,
|
||||
Port = options.PostgresPort,
|
||||
Username = options.PostgresUser,
|
||||
Password = options.PostgresPassword,
|
||||
Enlist = false
|
||||
};
|
||||
|
||||
return builder.ConnectionString;
|
||||
}
|
||||
|
||||
private static string GetDatabaseName(PostgresOptions options, MigrationType migrationType)
|
||||
private static string GetDatabaseName(ConfigFileOptions options, MigrationType migrationType)
|
||||
{
|
||||
return migrationType switch
|
||||
{
|
||||
MigrationType.Main => options.MainDb,
|
||||
MigrationType.Log => options.LogDb,
|
||||
MigrationType.Main => options.PostgresMainDb,
|
||||
MigrationType.Log => options.PostgresLogDb,
|
||||
_ => throw new NotImplementedException("Unknown migration type")
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,15 +25,15 @@ public class NzbDroneRunner
|
|||
|
||||
public string AppData { get; private set; }
|
||||
public string ApiKey { get; private set; }
|
||||
public PostgresOptions PostgresOptions { get; private set; }
|
||||
public ConfigFileOptions Options { get; private set; }
|
||||
public int Port { get; private set; }
|
||||
|
||||
public NzbDroneRunner(Logger logger, PostgresOptions postgresOptions, int port = 7878)
|
||||
public NzbDroneRunner(Logger logger, ConfigFileOptions options, int port = 7878)
|
||||
{
|
||||
_processProvider = new ProcessProvider(logger);
|
||||
_restClient = new RestClient($"http://localhost:{port}/api/v3");
|
||||
|
||||
PostgresOptions = postgresOptions;
|
||||
Options = options;
|
||||
Port = port;
|
||||
}
|
||||
|
||||
|
|
@ -138,14 +138,14 @@ public void KillAll()
|
|||
private void Start(string outputRadarrConsoleExe)
|
||||
{
|
||||
StringDictionary envVars = new ();
|
||||
if (PostgresOptions?.Host != null)
|
||||
if (Options?.PostgresHost != null)
|
||||
{
|
||||
envVars.Add("Radarr__Postgres__Host", PostgresOptions.Host);
|
||||
envVars.Add("Radarr__Postgres__Port", PostgresOptions.Port.ToString());
|
||||
envVars.Add("Radarr__Postgres__User", PostgresOptions.User);
|
||||
envVars.Add("Radarr__Postgres__Password", PostgresOptions.Password);
|
||||
envVars.Add("Radarr__Postgres__MainDb", PostgresOptions.MainDb);
|
||||
envVars.Add("Radarr__Postgres__LogDb", PostgresOptions.LogDb);
|
||||
envVars.Add("Radarr__PostgresHost", Options.PostgresHost);
|
||||
envVars.Add("Radarr__PostgresPort", Options.PostgresPort.ToString());
|
||||
envVars.Add("Radarr__PostgresUser", Options.PostgresUser);
|
||||
envVars.Add("Radarr__PostgresPassword", Options.PostgresPassword);
|
||||
envVars.Add("Radarr__PostgresMainDb", Options.PostgresMainDb);
|
||||
envVars.Add("Radarr__PostgresLogDb", Options.PostgresLogDb);
|
||||
|
||||
TestContext.Progress.WriteLine("Using env vars:\n{0}", envVars.ToJson());
|
||||
}
|
||||
|
|
@ -175,11 +175,11 @@ private void GenerateConfigFile()
|
|||
|
||||
var xDoc = new XDocument(
|
||||
new XDeclaration("1.0", "utf-8", "yes"),
|
||||
new XElement(ConfigFileProvider.CONFIG_ELEMENT_NAME,
|
||||
new XElement(nameof(ConfigFileProvider.ApiKey), apiKey),
|
||||
new XElement(nameof(ConfigFileProvider.LogLevel), "trace"),
|
||||
new XElement(nameof(ConfigFileProvider.AnalyticsEnabled), false),
|
||||
new XElement(nameof(ConfigFileProvider.Port), Port)));
|
||||
new XElement(ConfigFileWriter.CONFIG_ELEMENT_NAME,
|
||||
new XElement(nameof(ConfigFileOptions.ApiKey), apiKey),
|
||||
new XElement(nameof(ConfigFileOptions.LogLevel), "trace"),
|
||||
new XElement(nameof(ConfigFileOptions.AnalyticsEnabled), false),
|
||||
new XElement(nameof(ConfigFileOptions.Port), Port)));
|
||||
|
||||
var data = xDoc.ToString();
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
using System.Security.Cryptography.X509Certificates;
|
||||
using FluentValidation;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Authentication;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
|
@ -19,16 +20,19 @@ namespace Radarr.Api.V3.Config
|
|||
[V3ApiController("config/host")]
|
||||
public class HostConfigController : RestController<HostConfigResource>
|
||||
{
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
private readonly IConfigFileWriter _configFileWriter;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly IUserService _userService;
|
||||
|
||||
public HostConfigController(IConfigFileProvider configFileProvider,
|
||||
public HostConfigController(IOptionsMonitor<ConfigFileOptions> configFileProvider,
|
||||
IConfigFileWriter configFileWriter,
|
||||
IConfigService configService,
|
||||
IUserService userService,
|
||||
FileExistsValidator fileExistsValidator)
|
||||
{
|
||||
_configFileProvider = configFileProvider;
|
||||
_configFileWriter = configFileWriter;
|
||||
_configService = configService;
|
||||
_userService = userService;
|
||||
|
||||
|
|
@ -87,7 +91,7 @@ protected override HostConfigResource GetResourceById(int id)
|
|||
[HttpGet]
|
||||
public HostConfigResource GetHostConfig()
|
||||
{
|
||||
var resource = _configFileProvider.ToResource(_configService);
|
||||
var resource = _configFileProvider.CurrentValue.ToResource(_configService);
|
||||
resource.Id = 1;
|
||||
|
||||
var user = _userService.FindUser();
|
||||
|
|
@ -107,7 +111,7 @@ public ActionResult<HostConfigResource> SaveHostConfig(HostConfigResource resour
|
|||
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
|
||||
.ToDictionary(prop => prop.Name, prop => prop.GetValue(resource, null));
|
||||
|
||||
_configFileProvider.SaveConfigDictionary(dictionary);
|
||||
_configFileWriter.SaveConfigDictionary(dictionary);
|
||||
_configService.SaveConfigDictionary(dictionary);
|
||||
|
||||
if (resource.Username.IsNotNullOrWhiteSpace() && resource.Password.IsNotNullOrWhiteSpace())
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ public class HostConfigResource : RestResource
|
|||
|
||||
public static class HostConfigResourceMapper
|
||||
{
|
||||
public static HostConfigResource ToResource(this IConfigFileProvider model, IConfigService configService)
|
||||
public static HostConfigResource ToResource(this ConfigFileOptions model, IConfigService configService)
|
||||
{
|
||||
// TODO: Clean this mess up. don't mix data from multiple classes, use sub-resources instead?
|
||||
return new HostConfigResource
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Extensions;
|
||||
|
|
@ -16,7 +17,7 @@ public class LogFileController : LogFileControllerBase
|
|||
|
||||
public LogFileController(IAppFolderInfo appFolderInfo,
|
||||
IDiskProvider diskProvider,
|
||||
IConfigFileProvider configFileProvider)
|
||||
IOptionsMonitor<ConfigFileOptions> configFileProvider)
|
||||
: base(diskProvider, configFileProvider, "")
|
||||
{
|
||||
_appFolderInfo = appFolderInfo;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
|
@ -14,10 +15,10 @@ public abstract class LogFileControllerBase : Controller
|
|||
protected string _resource;
|
||||
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
|
||||
public LogFileControllerBase(IDiskProvider diskProvider,
|
||||
IConfigFileProvider configFileProvider,
|
||||
IOptionsMonitor<ConfigFileOptions> configFileProvider,
|
||||
string resource)
|
||||
{
|
||||
_diskProvider = diskProvider;
|
||||
|
|
@ -42,8 +43,8 @@ public List<LogFileResource> GetLogFilesResponse()
|
|||
Id = i + 1,
|
||||
Filename = filename,
|
||||
LastWriteTime = _diskProvider.FileGetLastWrite(file),
|
||||
ContentsUrl = string.Format("{0}/api/v1/{1}/{2}", _configFileProvider.UrlBase, _resource, filename),
|
||||
DownloadUrl = string.Format("{0}/{1}/{2}", _configFileProvider.UrlBase, DownloadUrlRoot, filename)
|
||||
ContentsUrl = string.Format("{0}/api/v1/{1}/{2}", _configFileProvider.CurrentValue.UrlBase, _resource, filename),
|
||||
DownloadUrl = string.Format("{0}/{1}/{2}", _configFileProvider.CurrentValue.UrlBase, DownloadUrlRoot, filename)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Extensions;
|
||||
|
|
@ -18,7 +19,7 @@ public class UpdateLogFileController : LogFileControllerBase
|
|||
|
||||
public UpdateLogFileController(IAppFolderInfo appFolderInfo,
|
||||
IDiskProvider diskProvider,
|
||||
IConfigFileProvider configFileProvider)
|
||||
IOptionsMonitor<ConfigFileOptions> configFileProvider)
|
||||
: base(diskProvider, configFileProvider, "update")
|
||||
{
|
||||
_appFolderInfo = appFolderInfo;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Routing.Internal;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
|
@ -20,7 +21,7 @@ public class SystemController : Controller
|
|||
private readonly IRuntimeInfo _runtimeInfo;
|
||||
private readonly IPlatformInfo _platformInfo;
|
||||
private readonly IOsInfo _osInfo;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
private readonly IMainDatabase _database;
|
||||
private readonly ILifecycleService _lifecycleService;
|
||||
private readonly IDeploymentInfoProvider _deploymentInfoProvider;
|
||||
|
|
@ -32,7 +33,7 @@ public SystemController(IAppFolderInfo appFolderInfo,
|
|||
IRuntimeInfo runtimeInfo,
|
||||
IPlatformInfo platformInfo,
|
||||
IOsInfo osInfo,
|
||||
IConfigFileProvider configFileProvider,
|
||||
IOptionsMonitor<ConfigFileOptions> configFileProvider,
|
||||
IMainDatabase database,
|
||||
ILifecycleService lifecycleService,
|
||||
IDeploymentInfoProvider deploymentInfoProvider,
|
||||
|
|
@ -59,7 +60,7 @@ public object GetStatus()
|
|||
return new
|
||||
{
|
||||
AppName = BuildInfo.AppName,
|
||||
InstanceName = _configFileProvider.InstanceName,
|
||||
InstanceName = _configFileProvider.CurrentValue.InstanceName,
|
||||
Version = BuildInfo.Version.ToString(),
|
||||
BuildTime = BuildInfo.BuildDateTime,
|
||||
IsDebug = BuildInfo.IsDebug,
|
||||
|
|
@ -76,12 +77,12 @@ public object GetStatus()
|
|||
IsWindows = OsInfo.IsWindows,
|
||||
IsDocker = _osInfo.IsDocker,
|
||||
Mode = _runtimeInfo.Mode,
|
||||
Branch = _configFileProvider.Branch,
|
||||
Authentication = _configFileProvider.AuthenticationMethod,
|
||||
Branch = _configFileProvider.CurrentValue.Branch,
|
||||
Authentication = _configFileProvider.CurrentValue.AuthenticationMethod,
|
||||
DatabaseType = _database.DatabaseType,
|
||||
DatabaseVersion = _database.Version,
|
||||
MigrationVersion = _database.Migration,
|
||||
UrlBase = _configFileProvider.UrlBase,
|
||||
UrlBase = _configFileProvider.CurrentValue.UrlBase,
|
||||
RuntimeVersion = _platformInfo.Version,
|
||||
RuntimeName = PlatformInfo.Platform,
|
||||
StartTime = _runtimeInfo.StartTime,
|
||||
|
|
|
|||
|
|
@ -28,10 +28,10 @@ public ApiKeyAuthenticationHandler(IOptionsMonitor<ApiKeyAuthenticationOptions>
|
|||
ILoggerFactory logger,
|
||||
UrlEncoder encoder,
|
||||
ISystemClock clock,
|
||||
IConfigFileProvider config)
|
||||
IOptionsMonitor<ConfigFileOptions> config)
|
||||
: base(options, logger, encoder, clock)
|
||||
{
|
||||
_apiKey = config.ApiKey;
|
||||
_apiKey = config.CurrentValue.ApiKey;
|
||||
}
|
||||
|
||||
private string ParseApiKey()
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NzbDrone.Core.Authentication;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
||||
|
|
@ -14,9 +15,9 @@ namespace Radarr.Http.Authentication
|
|||
public class AuthenticationController : Controller
|
||||
{
|
||||
private readonly IAuthenticationService _authService;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
|
||||
public AuthenticationController(IAuthenticationService authService, IConfigFileProvider configFileProvider)
|
||||
public AuthenticationController(IAuthenticationService authService, IOptionsMonitor<ConfigFileOptions> configFileProvider)
|
||||
{
|
||||
_authService = authService;
|
||||
_configFileProvider = configFileProvider;
|
||||
|
|
@ -46,7 +47,7 @@ public async Task<IActionResult> Login([FromForm] LoginResource resource, [FromQ
|
|||
|
||||
await HttpContext.SignInAsync(AuthenticationType.Forms.ToString(), new ClaimsPrincipal(new ClaimsIdentity(claims, "Cookies", "user", "identifier")), authProperties);
|
||||
|
||||
return Redirect(_configFileProvider.UrlBase + "/");
|
||||
return Redirect(_configFileProvider.CurrentValue.UrlBase + "/");
|
||||
}
|
||||
|
||||
[HttpGet("logout")]
|
||||
|
|
@ -54,7 +55,7 @@ public async Task<IActionResult> Logout()
|
|||
{
|
||||
_authService.Logout(HttpContext);
|
||||
await HttpContext.SignOutAsync(AuthenticationType.Forms.ToString());
|
||||
return Redirect(_configFileProvider.UrlBase + "/");
|
||||
return Redirect(_configFileProvider.CurrentValue.UrlBase + "/");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Authentication;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
|
@ -22,11 +23,11 @@ public class AuthenticationService : IAuthenticationService
|
|||
private static string API_KEY;
|
||||
private static AuthenticationType AUTH_METHOD;
|
||||
|
||||
public AuthenticationService(IConfigFileProvider configFileProvider, IUserService userService)
|
||||
public AuthenticationService(IOptionsMonitor<ConfigFileOptions> configFileProvider, IUserService userService)
|
||||
{
|
||||
_userService = userService;
|
||||
API_KEY = configFileProvider.ApiKey;
|
||||
AUTH_METHOD = configFileProvider.AuthenticationMethod;
|
||||
API_KEY = configFileProvider.CurrentValue.ApiKey;
|
||||
AUTH_METHOD = configFileProvider.CurrentValue.AuthenticationMethod;
|
||||
}
|
||||
|
||||
public User Login(HttpRequest request, string username, string password)
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@ namespace NzbDrone.Http.Authentication
|
|||
public class UiAuthorizationPolicyProvider : IAuthorizationPolicyProvider
|
||||
{
|
||||
private const string POLICY_NAME = "UI";
|
||||
private readonly IConfigFileProvider _config;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _config;
|
||||
|
||||
public DefaultAuthorizationPolicyProvider FallbackPolicyProvider { get; }
|
||||
|
||||
public UiAuthorizationPolicyProvider(IOptions<AuthorizationOptions> options,
|
||||
IConfigFileProvider config)
|
||||
IOptionsMonitor<ConfigFileOptions> config)
|
||||
{
|
||||
FallbackPolicyProvider = new DefaultAuthorizationPolicyProvider(options);
|
||||
_config = config;
|
||||
|
|
@ -28,7 +28,7 @@ public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
|
|||
{
|
||||
if (policyName.Equals(POLICY_NAME, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var policy = new AuthorizationPolicyBuilder(_config.AuthenticationMethod.ToString())
|
||||
var policy = new AuthorizationPolicyBuilder(_config.CurrentValue.AuthenticationMethod.ToString())
|
||||
.RequireAuthenticatedUser();
|
||||
return Task.FromResult(policy.Build());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System.Text;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Core.Analytics;
|
||||
|
|
@ -12,21 +13,17 @@ namespace Radarr.Http.Frontend
|
|||
[ApiController]
|
||||
public class InitializeJsController : Controller
|
||||
{
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
private readonly IAnalyticsService _analyticsService;
|
||||
|
||||
private static string _apiKey;
|
||||
private static string _urlBase;
|
||||
private string _generatedContent;
|
||||
private string ApiKey => _configFileProvider.CurrentValue.ApiKey;
|
||||
private string UrlBase => _configFileProvider.CurrentValue.UrlBase;
|
||||
|
||||
public InitializeJsController(IConfigFileProvider configFileProvider,
|
||||
public InitializeJsController(IOptionsMonitor<ConfigFileOptions> configFileProvider,
|
||||
IAnalyticsService analyticsService)
|
||||
{
|
||||
_configFileProvider = configFileProvider;
|
||||
_analyticsService = analyticsService;
|
||||
|
||||
_apiKey = configFileProvider.ApiKey;
|
||||
_urlBase = configFileProvider.UrlBase;
|
||||
}
|
||||
|
||||
[HttpGet("/initialize.js")]
|
||||
|
|
@ -37,28 +34,21 @@ public IActionResult Index()
|
|||
|
||||
private string GetContent()
|
||||
{
|
||||
if (RuntimeInfo.IsProduction && _generatedContent != null)
|
||||
{
|
||||
return _generatedContent;
|
||||
}
|
||||
|
||||
var builder = new StringBuilder();
|
||||
builder.AppendLine("window.Radarr = {");
|
||||
builder.AppendLine($" apiRoot: '{_urlBase}/api/v3',");
|
||||
builder.AppendLine($" apiKey: '{_apiKey}',");
|
||||
builder.AppendLine($" apiRoot: '{UrlBase}/api/v3',");
|
||||
builder.AppendLine($" apiKey: '{ApiKey}',");
|
||||
builder.AppendLine($" release: '{BuildInfo.Release}',");
|
||||
builder.AppendLine($" version: '{BuildInfo.Version.ToString()}',");
|
||||
builder.AppendLine($" instanceName: '{_configFileProvider.InstanceName.ToString()}',");
|
||||
builder.AppendLine($" branch: '{_configFileProvider.Branch.ToLower()}',");
|
||||
builder.AppendLine($" instanceName: '{_configFileProvider.CurrentValue.InstanceName}',");
|
||||
builder.AppendLine($" branch: '{_configFileProvider.CurrentValue.Branch.ToLower()}',");
|
||||
builder.AppendLine($" analytics: {_analyticsService.IsEnabled.ToString().ToLowerInvariant()},");
|
||||
builder.AppendLine($" userHash: '{HashUtil.AnonymousToken()}',");
|
||||
builder.AppendLine($" urlBase: '{_urlBase}',");
|
||||
builder.AppendLine($" urlBase: '{UrlBase}',");
|
||||
builder.AppendLine($" isProduction: {RuntimeInfo.IsProduction.ToString().ToLowerInvariant()}");
|
||||
builder.AppendLine("};");
|
||||
|
||||
_generatedContent = builder.ToString();
|
||||
|
||||
return _generatedContent;
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.IO;
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
|
@ -9,9 +10,9 @@ namespace Radarr.Http.Frontend.Mappers
|
|||
public class BrowserConfig : StaticResourceMapperBase
|
||||
{
|
||||
private readonly IAppFolderInfo _appFolderInfo;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
|
||||
public BrowserConfig(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IConfigFileProvider configFileProvider, Logger logger)
|
||||
public BrowserConfig(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IOptionsMonitor<ConfigFileOptions> configFileProvider, Logger logger)
|
||||
: base(diskProvider, logger)
|
||||
{
|
||||
_appFolderInfo = appFolderInfo;
|
||||
|
|
@ -23,7 +24,7 @@ public override string Map(string resourceUrl)
|
|||
var path = resourceUrl.Replace('/', Path.DirectorySeparatorChar);
|
||||
path = path.Trim(Path.DirectorySeparatorChar);
|
||||
|
||||
return Path.ChangeExtension(Path.Combine(_appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, path), "xml");
|
||||
return Path.ChangeExtension(Path.Combine(_appFolderInfo.StartUpFolder, _uiFolder, path), "xml");
|
||||
}
|
||||
|
||||
public override bool CanHandle(string resourceUrl)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.IO;
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
|
@ -9,9 +10,9 @@ namespace Radarr.Http.Frontend.Mappers
|
|||
public class FaviconMapper : StaticResourceMapperBase
|
||||
{
|
||||
private readonly IAppFolderInfo _appFolderInfo;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
|
||||
public FaviconMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IConfigFileProvider configFileProvider, Logger logger)
|
||||
public FaviconMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IOptionsMonitor<ConfigFileOptions> configFileProvider, Logger logger)
|
||||
: base(diskProvider, logger)
|
||||
{
|
||||
_appFolderInfo = appFolderInfo;
|
||||
|
|
@ -29,7 +30,7 @@ public override string Map(string resourceUrl)
|
|||
|
||||
var path = Path.Combine("Content", "Images", "Icons", fileName);
|
||||
|
||||
return Path.Combine(_appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, path);
|
||||
return Path.Combine(_appFolderInfo.StartUpFolder, _uiFolder, path);
|
||||
}
|
||||
|
||||
public override bool CanHandle(string resourceUrl)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
|
@ -9,19 +10,19 @@ namespace Radarr.Http.Frontend.Mappers
|
|||
{
|
||||
public class IndexHtmlMapper : HtmlMapperBase
|
||||
{
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
|
||||
public IndexHtmlMapper(IAppFolderInfo appFolderInfo,
|
||||
IDiskProvider diskProvider,
|
||||
IConfigFileProvider configFileProvider,
|
||||
IOptionsMonitor<ConfigFileOptions> configFileProvider,
|
||||
Lazy<ICacheBreakerProvider> cacheBreakProviderFactory,
|
||||
Logger logger)
|
||||
: base(diskProvider, cacheBreakProviderFactory, logger)
|
||||
{
|
||||
_configFileProvider = configFileProvider;
|
||||
|
||||
HtmlPath = Path.Combine(appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, "index.html");
|
||||
UrlBase = configFileProvider.UrlBase;
|
||||
HtmlPath = Path.Combine(appFolderInfo.StartUpFolder, _uiFolder, "index.html");
|
||||
UrlBase = configFileProvider.CurrentValue.UrlBase;
|
||||
}
|
||||
|
||||
public override string Map(string resourceUrl)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
|
@ -12,12 +13,12 @@ public class LoginHtmlMapper : HtmlMapperBase
|
|||
public LoginHtmlMapper(IAppFolderInfo appFolderInfo,
|
||||
IDiskProvider diskProvider,
|
||||
Lazy<ICacheBreakerProvider> cacheBreakProviderFactory,
|
||||
IConfigFileProvider configFileProvider,
|
||||
IOptionsMonitor<ConfigFileOptions> configFileProvider,
|
||||
Logger logger)
|
||||
: base(diskProvider, cacheBreakProviderFactory, logger)
|
||||
{
|
||||
HtmlPath = Path.Combine(appFolderInfo.StartUpFolder, configFileProvider.UiFolder, "login.html");
|
||||
UrlBase = configFileProvider.UrlBase;
|
||||
HtmlPath = Path.Combine(appFolderInfo.StartUpFolder, _uiFolder, "login.html");
|
||||
UrlBase = configFileProvider.CurrentValue.UrlBase;
|
||||
}
|
||||
|
||||
public override string Map(string resourceUrl)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.IO;
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
|
@ -9,9 +10,9 @@ namespace Radarr.Http.Frontend.Mappers
|
|||
public class ManifestMapper : StaticResourceMapperBase
|
||||
{
|
||||
private readonly IAppFolderInfo _appFolderInfo;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
|
||||
public ManifestMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IConfigFileProvider configFileProvider, Logger logger)
|
||||
public ManifestMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IOptionsMonitor<ConfigFileOptions> configFileProvider, Logger logger)
|
||||
: base(diskProvider, logger)
|
||||
{
|
||||
_appFolderInfo = appFolderInfo;
|
||||
|
|
@ -23,7 +24,7 @@ public override string Map(string resourceUrl)
|
|||
var path = resourceUrl.Replace('/', Path.DirectorySeparatorChar);
|
||||
path = path.Trim(Path.DirectorySeparatorChar);
|
||||
|
||||
return Path.ChangeExtension(Path.Combine(_appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, path), "json");
|
||||
return Path.ChangeExtension(Path.Combine(_appFolderInfo.StartUpFolder, _uiFolder, path), "json");
|
||||
}
|
||||
|
||||
public override bool CanHandle(string resourceUrl)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.IO;
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
|
@ -9,9 +10,9 @@ namespace Radarr.Http.Frontend.Mappers
|
|||
public class RobotsTxtMapper : StaticResourceMapperBase
|
||||
{
|
||||
private readonly IAppFolderInfo _appFolderInfo;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
|
||||
public RobotsTxtMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IConfigFileProvider configFileProvider, Logger logger)
|
||||
public RobotsTxtMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IOptionsMonitor<ConfigFileOptions> configFileProvider, Logger logger)
|
||||
: base(diskProvider, logger)
|
||||
{
|
||||
_appFolderInfo = appFolderInfo;
|
||||
|
|
@ -22,7 +23,7 @@ public override string Map(string resourceUrl)
|
|||
{
|
||||
var path = Path.Combine("Content", "robots.txt");
|
||||
|
||||
return Path.Combine(_appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, path);
|
||||
return Path.Combine(_appFolderInfo.StartUpFolder, _uiFolder, path);
|
||||
}
|
||||
|
||||
public override bool CanHandle(string resourceUrl)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.IO;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
|
@ -9,9 +10,9 @@ namespace Radarr.Http.Frontend.Mappers
|
|||
public class StaticResourceMapper : StaticResourceMapperBase
|
||||
{
|
||||
private readonly IAppFolderInfo _appFolderInfo;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IOptionsMonitor<ConfigFileOptions> _configFileProvider;
|
||||
|
||||
public StaticResourceMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IConfigFileProvider configFileProvider, Logger logger)
|
||||
public StaticResourceMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IOptionsMonitor<ConfigFileOptions> configFileProvider, Logger logger)
|
||||
: base(diskProvider, logger)
|
||||
{
|
||||
_appFolderInfo = appFolderInfo;
|
||||
|
|
@ -23,7 +24,7 @@ public override string Map(string resourceUrl)
|
|||
var path = resourceUrl.Replace('/', Path.DirectorySeparatorChar);
|
||||
path = path.Trim(Path.DirectorySeparatorChar);
|
||||
|
||||
return Path.Combine(_appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, path);
|
||||
return Path.Combine(_appFolderInfo.StartUpFolder, _uiFolder, path);
|
||||
}
|
||||
|
||||
public override bool CanHandle(string resourceUrl)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ namespace Radarr.Http.Frontend.Mappers
|
|||
{
|
||||
public abstract class StaticResourceMapperBase : IMapHttpRequestsToDisk
|
||||
{
|
||||
protected readonly string _uiFolder;
|
||||
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly Logger _logger;
|
||||
private readonly StringComparison _caseSensitive;
|
||||
|
|
@ -22,6 +24,7 @@ protected StaticResourceMapperBase(IDiskProvider diskProvider, Logger logger)
|
|||
|
||||
_mimeTypeProvider = new FileExtensionContentTypeProvider();
|
||||
_caseSensitive = RuntimeInfo.IsProduction ? DiskProviderBase.PathStringComparison : StringComparison.OrdinalIgnoreCase;
|
||||
_uiFolder = BuildInfo.IsDebug ? Path.Combine("..", "UI") : "UI";
|
||||
}
|
||||
|
||||
public abstract string Map(string resourceUrl);
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
<RunSettings>
|
||||
<RunConfiguration>
|
||||
<EnvironmentVariables>
|
||||
<Radarr__Postgres__Host>192.168.100.5</Radarr__Postgres__Host>
|
||||
<Radarr__Postgres__Port>5432</Radarr__Postgres__Port>
|
||||
<Radarr__Postgres__User>abc</Radarr__Postgres__User>
|
||||
<Radarr__Postgres__Password>abc</Radarr__Postgres__Password>
|
||||
<Radarr__PostgresHost>192.168.100.5</Radarr__PostgresHost>
|
||||
<Radarr__PostgresPort>5432</Radarr__PostgresPort>
|
||||
<Radarr__PostgresUser>abc</Radarr__PostgresUser>
|
||||
<Radarr__PostgresPassword>abc</Radarr__PostgresPassword>
|
||||
</EnvironmentVariables>
|
||||
</RunConfiguration>
|
||||
</RunSettings>
|
||||
Loading…
Reference in a new issue