diff --git a/.github/workflows/dotnet-test.yml b/.github/workflows/dotnet-test.yml index bc852d1..7345ced 100644 --- a/.github/workflows/dotnet-test.yml +++ b/.github/workflows/dotnet-test.yml @@ -21,4 +21,4 @@ jobs: - name: Build run: dotnet build --no-restore server - name: Test - run: dotnet test --no-build --verbosity normal -maxcpucount:1 server + run: dotnet test --no-build --verbosity normal server diff --git a/server/RdtClient.Service.Test/BackgroundServices/WatchFolderCheckerTests.cs b/server/RdtClient.Service.Test/BackgroundServices/WatchFolderCheckerTests.cs index 2353d67..d9a6f90 100644 --- a/server/RdtClient.Service.Test/BackgroundServices/WatchFolderCheckerTests.cs +++ b/server/RdtClient.Service.Test/BackgroundServices/WatchFolderCheckerTests.cs @@ -2,7 +2,6 @@ using System.Reflection; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Moq; -using RdtClient.Data.Data; using RdtClient.Data.Models.Data; using RdtClient.Data.Models.Internal; using RdtClient.Service.BackgroundServices; @@ -17,6 +16,7 @@ public class WatchFolderCheckerTests : IDisposable private readonly Mock _serviceProviderMock; private readonly Mock _serviceScopeMock; private readonly String _testPath; + private readonly TestSettings _settings; private readonly Mock _torrentsServiceMock; public WatchFolderCheckerTests() @@ -25,7 +25,16 @@ public class WatchFolderCheckerTests : IDisposable _serviceProviderMock = new(); _serviceScopeMock = new(); _scopeServiceProviderMock = new(); - _torrentsServiceMock = new(null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!); + _settings = new(new DbSettings + { + Watch = new() + { + Interval = 0, + Default = new() + }, + DownloadClient = new() + }); + _torrentsServiceMock = new(null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, _settings, new TorrentRunnerState()); _serviceProviderMock .Setup(x => x.GetService(typeof(IServiceScopeFactory))) @@ -42,10 +51,8 @@ public class WatchFolderCheckerTests : IDisposable _testPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); Directory.CreateDirectory(_testPath); - // Reset Settings and Startup SetStartupReady(true); - ResetSettings(); - Settings.Get.Watch.Path = _testPath; + _settings.Current.Watch.Path = _testPath; } public void Dispose() @@ -62,22 +69,6 @@ public class WatchFolderCheckerTests : IDisposable property?.SetValue(null, ready); } - private static void ResetSettings() - { - var settings = new DbSettings - { - Watch = new() - { - Interval = 0, - Default = new() - }, - DownloadClient = new() - }; - - var property = typeof(SettingData).GetProperty("Get", BindingFlags.Public | BindingFlags.Static); - property?.SetValue(null, settings); - } - private static void ResetPrevCheck(WatchFolderChecker checker) { var field = typeof(WatchFolderChecker).GetField("_prevCheck", BindingFlags.NonPublic | BindingFlags.Instance); @@ -92,7 +83,7 @@ public class WatchFolderCheckerTests : IDisposable var content = "torrent content"u8.ToArray(); await File.WriteAllBytesAsync(filePath, content); - var checker = new WatchFolderChecker(_loggerMock.Object, _serviceProviderMock.Object); + var checker = new WatchFolderChecker(_loggerMock.Object, _serviceProviderMock.Object, _settings); ResetPrevCheck(checker); var cts = new CancellationTokenSource(); @@ -131,7 +122,7 @@ public class WatchFolderCheckerTests : IDisposable var content = "magnet:?xt=urn:btih:123"; await File.WriteAllTextAsync(filePath, content); - var checker = new WatchFolderChecker(_loggerMock.Object, _serviceProviderMock.Object); + var checker = new WatchFolderChecker(_loggerMock.Object, _serviceProviderMock.Object, _settings); ResetPrevCheck(checker); var cts = new CancellationTokenSource(); @@ -170,7 +161,7 @@ public class WatchFolderCheckerTests : IDisposable var content = "nzb content"u8.ToArray(); await File.WriteAllBytesAsync(filePath, content); - var checker = new WatchFolderChecker(_loggerMock.Object, _serviceProviderMock.Object); + var checker = new WatchFolderChecker(_loggerMock.Object, _serviceProviderMock.Object, _settings); ResetPrevCheck(checker); var cts = new CancellationTokenSource(); @@ -209,7 +200,7 @@ public class WatchFolderCheckerTests : IDisposable var filePath = Path.Combine(_testPath, "test.txt"); await File.WriteAllTextAsync(filePath, "ignore me"); - var checker = new WatchFolderChecker(_loggerMock.Object, _serviceProviderMock.Object); + var checker = new WatchFolderChecker(_loggerMock.Object, _serviceProviderMock.Object, _settings); ResetPrevCheck(checker); var cts = new CancellationTokenSource(); diff --git a/server/RdtClient.Service.Test/GlobalTestConfig.cs b/server/RdtClient.Service.Test/GlobalTestConfig.cs deleted file mode 100644 index 2171200..0000000 --- a/server/RdtClient.Service.Test/GlobalTestConfig.cs +++ /dev/null @@ -1,3 +0,0 @@ -using Xunit; - -[assembly: CollectionBehavior(DisableTestParallelization = true)] diff --git a/server/RdtClient.Service.Test/RdtClient.Service.Test.csproj b/server/RdtClient.Service.Test/RdtClient.Service.Test.csproj index dba5280..6b0217d 100644 --- a/server/RdtClient.Service.Test/RdtClient.Service.Test.csproj +++ b/server/RdtClient.Service.Test/RdtClient.Service.Test.csproj @@ -5,6 +5,7 @@ enable enable false + true RdtClient.Service.Test RdtClient.Service.Test diff --git a/server/RdtClient.Service.Test/Services/NzbTorrentsTest.cs b/server/RdtClient.Service.Test/Services/NzbTorrentsTest.cs index 7d6f4df..4751b40 100644 --- a/server/RdtClient.Service.Test/Services/NzbTorrentsTest.cs +++ b/server/RdtClient.Service.Test/Services/NzbTorrentsTest.cs @@ -3,6 +3,8 @@ using System.Text; using Moq; using RdtClient.Data.Enums; using RdtClient.Data.Models.Data; +using TestSettings = RdtClient.Service.Services.TestSettings; +using TorrentRunnerState = RdtClient.Service.Services.TorrentRunnerState; using TorrentsService = RdtClient.Service.Services.Torrents; namespace RdtClient.Service.Test.Services; @@ -28,7 +30,9 @@ public class NzbTorrentsTest null!, null!, null!, - null!); + null!, + new TestSettings(), + new TorrentRunnerState()); } [Fact] diff --git a/server/RdtClient.Service.Test/Services/QBittorrentTest.cs b/server/RdtClient.Service.Test/Services/QBittorrentTest.cs index 80b23b6..e03d532 100644 --- a/server/RdtClient.Service.Test/Services/QBittorrentTest.cs +++ b/server/RdtClient.Service.Test/Services/QBittorrentTest.cs @@ -1,7 +1,6 @@ using Microsoft.Extensions.Logging; using Moq; using System.Text.Json; -using RdtClient.Data.Data; using RdtClient.Data.Enums; using RdtClient.Data.Models.Data; using RdtClient.Data.Models.DebridClient; @@ -14,15 +13,19 @@ public class QBittorrentTest private readonly Mock _authenticationMock; private readonly Mock> _loggerMock; private readonly QBittorrent _qBittorrent; + private readonly TestSettings _settings; + private readonly TorrentRunnerState _runnerState; private readonly Mock _torrentsMock; public QBittorrentTest() { _loggerMock = new(); - _torrentsMock = new(null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!); + _settings = new(); + _runnerState = new(); + _torrentsMock = new(null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, _settings, _runnerState); _authenticationMock = new(null!, null!, null!); - _qBittorrent = new(_loggerMock.Object, null!, _authenticationMock.Object, _torrentsMock.Object, null!); + _qBittorrent = new(_loggerMock.Object, _settings, _authenticationMock.Object, _torrentsMock.Object, null!, _runnerState); } [Fact] @@ -214,8 +217,8 @@ public class QBittorrentTest public async Task TorrentInfo_ShouldUseSelectedTopLevelFileName_WhenRootFileAddsOnlyTheExtension() { // Arrange - var previousMappedPath = SettingData.Get.DownloadClient.MappedPath; - SettingData.Get.DownloadClient.MappedPath = "/data/downloads"; + var previousMappedPath = _settings.Current.DownloadClient.MappedPath; + _settings.Current.DownloadClient.MappedPath = "/data/downloads"; try { @@ -260,16 +263,16 @@ public class QBittorrentTest } finally { - SettingData.Get.DownloadClient.MappedPath = previousMappedPath; + _settings.Current.DownloadClient.MappedPath = previousMappedPath; } } [Fact] public async Task TorrentInfo_ShouldUseExistingCompletedContentRoot_WhenSingleFileDirectoryDiffersFromRdName() { - var previousMappedPath = SettingData.Get.DownloadClient.MappedPath; + var previousMappedPath = _settings.Current.DownloadClient.MappedPath; var mappedPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); - SettingData.Get.DownloadClient.MappedPath = mappedPath; + _settings.Current.DownloadClient.MappedPath = mappedPath; try { @@ -317,7 +320,7 @@ public class QBittorrentTest } finally { - SettingData.Get.DownloadClient.MappedPath = previousMappedPath; + _settings.Current.DownloadClient.MappedPath = previousMappedPath; if (Directory.Exists(mappedPath)) { @@ -329,9 +332,9 @@ public class QBittorrentTest [Fact] public async Task TorrentInfo_ShouldUseExistingCompletedContentRoot_WhenSelectedFileIsNestedUnderDifferentRoot() { - var previousMappedPath = SettingData.Get.DownloadClient.MappedPath; + var previousMappedPath = _settings.Current.DownloadClient.MappedPath; var mappedPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); - SettingData.Get.DownloadClient.MappedPath = mappedPath; + _settings.Current.DownloadClient.MappedPath = mappedPath; try { @@ -382,7 +385,7 @@ public class QBittorrentTest } finally { - SettingData.Get.DownloadClient.MappedPath = previousMappedPath; + _settings.Current.DownloadClient.MappedPath = previousMappedPath; if (Directory.Exists(mappedPath)) { diff --git a/server/RdtClient.Service.Test/Services/SabnzbdTest.cs b/server/RdtClient.Service.Test/Services/SabnzbdTest.cs index bd81173..55a729f 100644 --- a/server/RdtClient.Service.Test/Services/SabnzbdTest.cs +++ b/server/RdtClient.Service.Test/Services/SabnzbdTest.cs @@ -1,6 +1,5 @@ using Microsoft.Extensions.Logging; using Moq; -using RdtClient.Data.Data; using RdtClient.Data.Enums; using RdtClient.Data.Models.Data; using RdtClient.Data.Models.Internal; @@ -16,11 +15,13 @@ public class SabnzbdTest }; private readonly Mock> _loggerMock = new(); + private readonly TestSettings _settings; private readonly Mock _torrentsMock; public SabnzbdTest() { - _torrentsMock = new(null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!); + _settings = new(); + _torrentsMock = new(null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, _settings, new TorrentRunnerState()); _torrentsMock.Setup(t => t.Get()).ReturnsAsync(new List()); } @@ -50,7 +51,7 @@ public class SabnzbdTest _torrentsMock.Setup(t => t.Get()).ReturnsAsync(torrentList); _torrentsMock.Setup(t => t.GetDownloadStats(It.IsAny())).Returns((0, 1000, 500)); - var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings); + var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings, _settings); // Act var result = await sabnzbd.GetQueue(); @@ -90,7 +91,7 @@ public class SabnzbdTest _torrentsMock.Setup(t => t.Get()).ReturnsAsync(torrentList); - var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings); + var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings, _settings); // Act var result = await sabnzbd.GetQueue(); @@ -134,7 +135,7 @@ public class SabnzbdTest _torrentsMock.Setup(t => t.Get()).ReturnsAsync(torrentList); - var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings); + var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings, _settings); // Act var result = await sabnzbd.GetQueue(); @@ -186,7 +187,7 @@ public class SabnzbdTest _torrentsMock.Setup(t => t.Get()).ReturnsAsync(torrentList); - var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings); + var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings, _settings); // Act var result = await sabnzbd.GetQueue(); @@ -224,7 +225,7 @@ public class SabnzbdTest _torrentsMock.Setup(t => t.Get()).ReturnsAsync(torrentList); - var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings); + var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings, _settings); // Act var result = await sabnzbd.GetQueue(); @@ -260,7 +261,7 @@ public class SabnzbdTest _torrentsMock.Setup(t => t.Get()).ReturnsAsync(torrentList); - var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings); + var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings, _settings); // Act var result = await sabnzbd.GetHistory(); @@ -275,7 +276,7 @@ public class SabnzbdTest { // Arrange var savePath = @"C:\Downloads"; - SettingData.Get.DownloadClient.MappedPath = savePath; + _settings.Current.DownloadClient.MappedPath = savePath; var torrentList = new List { @@ -292,7 +293,7 @@ public class SabnzbdTest _torrentsMock.Setup(t => t.Get()).ReturnsAsync(torrentList); - var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings); + var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings, _settings); // Act var result = await sabnzbd.GetHistory(); @@ -308,7 +309,7 @@ public class SabnzbdTest { // Arrange var savePath = @"C:\Downloads"; - SettingData.Get.DownloadClient.MappedPath = savePath; + _settings.Current.DownloadClient.MappedPath = savePath; var torrentList = new List { @@ -325,7 +326,7 @@ public class SabnzbdTest _torrentsMock.Setup(t => t.Get()).ReturnsAsync(torrentList); - var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings); + var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings, _settings); // Act var result = await sabnzbd.GetHistory(); @@ -355,7 +356,7 @@ public class SabnzbdTest _torrentsMock.Setup(t => t.Get()).ReturnsAsync(torrentList); - var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings); + var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings, _settings); // Act var result = await sabnzbd.GetHistory(); @@ -369,7 +370,7 @@ public class SabnzbdTest public void GetConfig_ShouldReturnCorrectConfig() { // Arrange - var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings); + var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings, _settings); // Act var result = sabnzbd.GetConfig(); @@ -399,9 +400,9 @@ public class SabnzbdTest _torrentsMock.Setup(t => t.Get()).ReturnsAsync(torrentList); - SettingData.Get.General.Categories = "TV, Music, *"; + _settings.Current.General.Categories = "TV, Music, *"; - var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings); + var sabnzbd = new Sabnzbd(_loggerMock.Object, _torrentsMock.Object, _appSettings, _settings); // Act var result = sabnzbd.GetCategories(); diff --git a/server/RdtClient.Service.Test/Services/TorrentClients/PremiumizeDebridClientTest.cs b/server/RdtClient.Service.Test/Services/TorrentClients/PremiumizeDebridClientTest.cs index 6d6d0ba..204de56 100644 --- a/server/RdtClient.Service.Test/Services/TorrentClients/PremiumizeDebridClientTest.cs +++ b/server/RdtClient.Service.Test/Services/TorrentClients/PremiumizeDebridClientTest.cs @@ -8,30 +8,20 @@ using RdtClient.Service.Services.DebridClients; namespace RdtClient.Service.Test.Services.TorrentClients; -[CollectionDefinition(nameof(PremiumizeSettingsCollection), DisableParallelization = true)] -public class PremiumizeSettingsCollection; - -[Collection(nameof(PremiumizeSettingsCollection))] -public class PremiumizeDebridClientTest : IDisposable +public class PremiumizeDebridClientTest { private readonly Mock _fileFilterMock; private readonly Mock _httpClientFactoryMock; private readonly Mock> _loggerMock; - private readonly String _originalApiKey; + private readonly TestSettings _settings; public PremiumizeDebridClientTest() { _loggerMock = new(); _httpClientFactoryMock = new(); _fileFilterMock = new(); - _originalApiKey = Settings.Get.Provider.ApiKey ?? String.Empty; - - Settings.Get.Provider.ApiKey = "test-api-key"; - } - - public void Dispose() - { - Settings.Get.Provider.ApiKey = _originalApiKey; + _settings = new(); + _settings.Current.Provider.ApiKey = "test-api-key"; } [Fact] @@ -208,7 +198,7 @@ public class PremiumizeDebridClientTest : IDisposable { _httpClientFactoryMock.Setup(m => m.CreateClient(It.IsAny())).Returns(new HttpClient(handler)); - return new(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object); + return new(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _settings); } private static HttpResponseMessage JsonResponse(String json, HttpStatusCode statusCode = HttpStatusCode.OK) diff --git a/server/RdtClient.Service.Test/Services/TorrentClients/TorBoxDebridClientTest.cs b/server/RdtClient.Service.Test/Services/TorrentClients/TorBoxDebridClientTest.cs index a19381f..66b405c 100644 --- a/server/RdtClient.Service.Test/Services/TorrentClients/TorBoxDebridClientTest.cs +++ b/server/RdtClient.Service.Test/Services/TorrentClients/TorBoxDebridClientTest.cs @@ -21,6 +21,7 @@ public class TorBoxDebridClientTest private readonly Mock _fileFilterMock; private readonly Mock _httpClientFactoryMock; private readonly Mock> _loggerMock; + private readonly TestSettings _settings; public TorBoxDebridClientTest() { @@ -28,12 +29,13 @@ public class TorBoxDebridClientTest _httpClientFactoryMock = new(); _fileFilterMock = new(); _coordinatorMock = new(); + _settings = new(); var httpClient = new HttpClient(); _httpClientFactoryMock.Setup(m => m.CreateClient(It.IsAny())).Returns(httpClient); - Settings.Get.Provider.ApiKey = "test-api-key"; - Settings.Get.Provider.Timeout = 100; + _settings.Current.Provider.ApiKey = "test-api-key"; + _settings.Current.Provider.Timeout = 100; } [Fact] @@ -64,7 +66,7 @@ public class TorBoxDebridClientTest } }; - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object); + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings); clientMock.Protected().Setup?>>("GetCurrentTorrents").ReturnsAsync(torrents); clientMock.Protected().Setup?>>("GetQueuedTorrents").ReturnsAsync(new List()); clientMock.Protected().Setup?>>("GetCurrentUsenet").ReturnsAsync(nzbs); @@ -114,7 +116,7 @@ public class TorBoxDebridClientTest } }; - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object); + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings); clientMock.Protected().Setup>>>("GetTorrentAvailability", hash).ReturnsAsync(availability); // Act @@ -157,7 +159,7 @@ public class TorBoxDebridClientTest } }; - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object); + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings); clientMock.Protected().Setup>>>("GetTorrentAvailability", hash).ReturnsAsync(torrentAvailability); clientMock.Protected().Setup>>>("GetUsenetAvailability", hash).ReturnsAsync(usenetAvailability); @@ -186,7 +188,7 @@ public class TorBoxDebridClientTest Data = new() }; - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object); + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings); clientMock.Protected().Setup>>>("GetTorrentAvailability", hash).ReturnsAsync(torrentAvailability); clientMock.Protected().Setup>>>("GetUsenetAvailability", hash).ReturnsAsync(usenetAvailability); @@ -208,7 +210,7 @@ public class TorBoxDebridClientTest }; var torrentsApiMock = new Mock(); - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object); + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings); var torBoxClientMock = new Mock(); torBoxClientMock.Setup(m => m.Torrents).Returns(torrentsApiMock.Object); @@ -232,7 +234,7 @@ public class TorBoxDebridClientTest }; var usenetApiMock = new Mock(); - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object); + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings); var torBoxClientMock = new Mock(); torBoxClientMock.Setup(m => m.Usenet).Returns(usenetApiMock.Object); @@ -258,7 +260,7 @@ public class TorBoxDebridClientTest var link = "https://torbox.app/d/123/456"; var torrentsApiMock = new Mock(); - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object); + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings); var torBoxClientMock = new Mock(); torBoxClientMock.Setup(m => m.Torrents).Returns(torrentsApiMock.Object); @@ -291,7 +293,7 @@ public class TorBoxDebridClientTest var link = "https://torbox.app/d/123/456"; var usenetApiMock = new Mock(); - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object); + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings); var torBoxClientMock = new Mock(); torBoxClientMock.Setup(m => m.Usenet).Returns(usenetApiMock.Object); @@ -323,7 +325,7 @@ public class TorBoxDebridClientTest var name = "test-nzb"; var usenetApiMock = new Mock(); - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object) + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings) { CallBase = true }; @@ -377,7 +379,7 @@ public class TorBoxDebridClientTest }; var torrentsApiMock = new Mock(); - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object); + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings); var torBoxClientMock = new Mock(); torBoxClientMock.Setup(m => m.Torrents).Returns(torrentsApiMock.Object); @@ -391,7 +393,7 @@ public class TorBoxDebridClientTest _fileFilterMock.Setup(m => m.IsDownloadable(torrent, It.IsAny(), It.IsAny())).Returns(true); - Settings.Get.Provider.PreferZippedDownloads = false; + _settings.Current.Provider.PreferZippedDownloads = false; // Act var result = await clientMock.Object.GetDownloadInfos(torrent); @@ -425,10 +427,10 @@ public class TorBoxDebridClientTest DownloadClient = DownloadClient.Aria2c }; - Settings.Get.Provider.PreferZippedDownloads = true; + _settings.Current.Provider.PreferZippedDownloads = true; var torrentsApiMock = new Mock(); - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object); + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings); var torBoxClientMock = new Mock(); torBoxClientMock.Setup(m => m.Torrents).Returns(torrentsApiMock.Object); @@ -464,7 +466,7 @@ public class TorBoxDebridClientTest var link = "https://torbox.app/fakedl/12345/6789"; var torrentsApiMock = new Mock(); - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object); + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings); var torBoxClientMock = new Mock(); torBoxClientMock.Setup(m => m.Torrents).Returns(torrentsApiMock.Object); @@ -496,7 +498,7 @@ public class TorBoxDebridClientTest var link = "https://torbox.app/fakedl/12345/zip"; var torrentsApiMock = new Mock(); - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object); + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings); var torBoxClientMock = new Mock(); torBoxClientMock.Setup(m => m.Torrents).Returns(torrentsApiMock.Object); @@ -538,7 +540,7 @@ public class TorBoxDebridClientTest }; var usenetApiMock = new Mock(); - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object); + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings); var torBoxClientMock = new Mock(); torBoxClientMock.Setup(m => m.Usenet).Returns(usenetApiMock.Object); @@ -556,7 +558,7 @@ public class TorBoxDebridClientTest _fileFilterMock.Setup(m => m.IsDownloadable(torrent, It.IsAny(), It.IsAny())).Returns(true); - Settings.Get.Provider.PreferZippedDownloads = false; + _settings.Current.Provider.PreferZippedDownloads = false; // Act var result = await clientMock.Object.GetDownloadInfos(torrent); @@ -579,7 +581,7 @@ public class TorBoxDebridClientTest var link = "https://torbox.app/fakedl/98765/4321"; var usenetApiMock = new Mock(); - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object); + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings); var torBoxClientMock = new Mock(); torBoxClientMock.Setup(m => m.Usenet).Returns(usenetApiMock.Object); @@ -607,7 +609,7 @@ public class TorBoxDebridClientTest var torrentsApiMock = new Mock(); var userApiMock = new Mock(); - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object) + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings) { CallBase = true }; @@ -647,7 +649,7 @@ public class TorBoxDebridClientTest var torrentsApiMock = new Mock(); var userApiMock = new Mock(); - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object) + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings) { CallBase = true }; @@ -685,7 +687,7 @@ public class TorBoxDebridClientTest var torrentsApiMock = new Mock(); var userApiMock = new Mock(); - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object) + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings) { CallBase = true }; @@ -724,7 +726,7 @@ public class TorBoxDebridClientTest var torrentsApiMock = new Mock(); var userApiMock = new Mock(); - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object) + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings) { CallBase = true }; @@ -767,7 +769,7 @@ public class TorBoxDebridClientTest var torrentsApiMock = new Mock(); var userApiMock = new Mock(); - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object) + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings) { CallBase = true }; @@ -806,7 +808,7 @@ public class TorBoxDebridClientTest var nzbLink = "https://example.com/test.nzb"; var usenetApiMock = new Mock(); - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object) + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings) { CallBase = true }; @@ -837,7 +839,7 @@ public class TorBoxDebridClientTest var name = "test.nzb"; var usenetApiMock = new Mock(); - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object) + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings) { CallBase = true }; @@ -872,7 +874,7 @@ public class TorBoxDebridClientTest Filename = "test-file" }; - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object); + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings); // Act var result = await clientMock.Object.UpdateData(torrent, torrentClientTorrent); @@ -898,7 +900,7 @@ public class TorBoxDebridClientTest Filename = "test-torrent" }; - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object); + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings); // Act await clientMock.Object.UpdateData(torrent, torrentClientTorrent); @@ -929,7 +931,7 @@ public class TorBoxDebridClientTest Filename = "test-torrent" }; - var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object); + var clientMock = new Mock(_loggerMock.Object, _httpClientFactoryMock.Object, _fileFilterMock.Object, _coordinatorMock.Object, _settings); // Act var result = await clientMock.Object.UpdateData(torrent, torrentClientTorrent); diff --git a/server/RdtClient.Service.Test/Services/TorrentRunnerTest.cs b/server/RdtClient.Service.Test/Services/TorrentRunnerTest.cs index edc2b6c..5d20df9 100644 --- a/server/RdtClient.Service.Test/Services/TorrentRunnerTest.cs +++ b/server/RdtClient.Service.Test/Services/TorrentRunnerTest.cs @@ -13,76 +13,63 @@ public class TorrentRunnerTest [Fact] public async Task Tick_ShouldNotRequeueCompletedErrorTorrent() { - var originalApiKey = Settings.Get.Provider.ApiKey; - var originalProvider = Settings.Get.Provider.Provider; - var originalMaxParallelDownloads = Settings.Get.Provider.MaxParallelDownloads; - var originalDownloadPath = Settings.Get.DownloadClient.DownloadPath; + var testSettings = new TestSettings(); + var runnerState = new TorrentRunnerState(); - TorrentRunner.ActiveDownloadClients.Clear(); - TorrentRunner.ActiveUnpackClients.Clear(); + testSettings.Current.Provider.ApiKey = "test-api-key"; + testSettings.Current.Provider.Provider = Provider.RealDebrid; + testSettings.Current.Provider.MaxParallelDownloads = 1; + testSettings.Current.DownloadClient.DownloadPath = "/downloads"; - try + var erroredTorrent = new Torrent { - Settings.Get.Provider.ApiKey = "test-api-key"; - Settings.Get.Provider.Provider = Provider.RealDebrid; - Settings.Get.Provider.MaxParallelDownloads = 1; - Settings.Get.DownloadClient.DownloadPath = "/downloads"; + TorrentId = Guid.NewGuid(), + Hash = "hash-1", + RdName = "Torrent 1", + FileOrMagnet = "magnet:?xt=urn:btih:hash-1", + Type = DownloadType.Torrent, + RdStatus = TorrentStatus.Queued, + DeleteOnError = 10, + Error = "Could not add to provider: Infringing file", + Completed = DateTimeOffset.UtcNow.AddMinutes(-5), + Downloads = new List() + }; - var erroredTorrent = new Torrent - { - TorrentId = Guid.NewGuid(), - Hash = "hash-1", - RdName = "Torrent 1", - FileOrMagnet = "magnet:?xt=urn:btih:hash-1", - Type = DownloadType.Torrent, - RdStatus = TorrentStatus.Queued, - DeleteOnError = 10, - Error = "Could not add to provider: Infringing file", - Completed = DateTimeOffset.UtcNow.AddMinutes(-5), - Downloads = new List() - }; - - var torrentDataMock = new Mock(MockBehavior.Strict); - torrentDataMock.Setup(m => m.Get()).ReturnsAsync(new List - { - erroredTorrent - }); - - var torrents = new Torrents(Mock.Of>(), - torrentDataMock.Object, - Mock.Of(), - null!, - null!, - null!, - null!, - null!, - null!, - null!, - null!); - - var torrentRunner = new TorrentRunner(Mock.Of>(), - torrents, - new(null!), - new(null!, torrents), - Mock.Of(), - new RateLimitCoordinator()); - - await torrentRunner.Tick(); - - torrentDataMock.Verify(m => m.UpdateComplete(It.IsAny(), - It.IsAny(), - It.IsAny(), - It.IsAny()), - Times.Never); - } - finally + var torrentDataMock = new Mock(MockBehavior.Strict); + torrentDataMock.Setup(m => m.Get()).ReturnsAsync(new List { - Settings.Get.Provider.ApiKey = originalApiKey; - Settings.Get.Provider.Provider = originalProvider; - Settings.Get.Provider.MaxParallelDownloads = originalMaxParallelDownloads; - Settings.Get.DownloadClient.DownloadPath = originalDownloadPath; - TorrentRunner.ActiveDownloadClients.Clear(); - TorrentRunner.ActiveUnpackClients.Clear(); - } + erroredTorrent + }); + + var torrents = new Torrents(Mock.Of>(), + torrentDataMock.Object, + Mock.Of(), + null!, + null!, + null!, + null!, + null!, + null!, + null!, + null!, + testSettings, + runnerState); + + var torrentRunner = new TorrentRunner(Mock.Of>(), + torrents, + new(null!), + new(null!, torrents), + Mock.Of(), + new RateLimitCoordinator(), + testSettings, + runnerState); + + await torrentRunner.Tick(); + + torrentDataMock.Verify(m => m.UpdateComplete(It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Never); } -} \ No newline at end of file +} diff --git a/server/RdtClient.Service.Test/Services/TorrentsTest.cs b/server/RdtClient.Service.Test/Services/TorrentsTest.cs index ad7103e..a3d3c8a 100644 --- a/server/RdtClient.Service.Test/Services/TorrentsTest.cs +++ b/server/RdtClient.Service.Test/Services/TorrentsTest.cs @@ -120,7 +120,9 @@ public class TorrentsTest null!, null!, null!, - null!); + null!, + new TestSettings(), + new TorrentRunnerState()); mocks.ProcessMock.Setup(p => p.WaitForExit(It.IsAny())).Returns(true); @@ -186,7 +188,9 @@ public class TorrentsTest null!, null!, null!, - null!); + null!, + new TestSettings(), + new TorrentRunnerState()); //Act await torrents.RunTorrentComplete(torrent.TorrentId, settings); @@ -234,7 +238,9 @@ public class TorrentsTest null!, null!, null!, - null!); + null!, + new TestSettings(), + new TorrentRunnerState()); mocks.ProcessMock.Setup(p => p.WaitForExit(It.IsAny())) .Callback(() => @@ -301,7 +307,9 @@ public class TorrentsTest null!, null!, null!, - null!); + null!, + new TestSettings(), + new TorrentRunnerState()); mocks.ProcessMock.Setup(p => p.WaitForExit(It.IsAny())) .Callback(() => @@ -364,7 +372,9 @@ public class TorrentsTest null!, null!, null!, - null!); + null!, + new TestSettings(), + new TorrentRunnerState()); // Act await torrents.AddNzbFileToDebridQueue(bytes, "filename.nzb", torrent); @@ -412,7 +422,9 @@ public class TorrentsTest null!, null!, null!, - null!); + null!, + new TestSettings(), + new TorrentRunnerState()); // Act await torrents.AddNzbLinkToDebridQueue(link, torrent); diff --git a/server/RdtClient.Service.Test/TestSettings.cs b/server/RdtClient.Service.Test/TestSettings.cs new file mode 100644 index 0000000..7ffc2ea --- /dev/null +++ b/server/RdtClient.Service.Test/TestSettings.cs @@ -0,0 +1,58 @@ +using RdtClient.Data.Models.Internal; + +namespace RdtClient.Service.Services; + +internal sealed class TestSettings(DbSettings? settings = null) : ISettings +{ + public DbSettings Current { get; } = settings ?? new(); + + public String DefaultSavePath + { + get + { + var downloadPath = Current.DownloadClient.MappedPath.TrimEnd('\\').TrimEnd('/'); + + return downloadPath + Path.DirectorySeparatorChar; + } + } + + public IList GetAll() + { + return []; + } + + public Task Update(IList settings) + { + return Task.CompletedTask; + } + + public Task Update(String settingId, Object? value) + { + SetValue(Current, settingId.Split(':'), 0, value); + + return Task.CompletedTask; + } + + private static void SetValue(Object target, IReadOnlyList path, Int32 index, Object? value) + { + var property = target.GetType().GetProperty(path[index]) ?? throw new($"Unknown setting {String.Join(":", path)}"); + + if (index < path.Count - 1) + { + SetValue(property.GetValue(target)!, path, index + 1, value); + + return; + } + + if (value == null) + { + property.SetValue(target, null); + + return; + } + + var propertyType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType; + var convertedValue = propertyType.IsEnum ? Enum.Parse(propertyType, value.ToString()!) : Convert.ChangeType(value, propertyType); + property.SetValue(target, convertedValue); + } +} diff --git a/server/RdtClient.Service/BackgroundServices/DiskSpaceMonitor.cs b/server/RdtClient.Service/BackgroundServices/DiskSpaceMonitor.cs index ec1e218..f4fc414 100644 --- a/server/RdtClient.Service/BackgroundServices/DiskSpaceMonitor.cs +++ b/server/RdtClient.Service/BackgroundServices/DiskSpaceMonitor.cs @@ -8,7 +8,7 @@ using DownloadClient = RdtClient.Data.Enums.DownloadClient; namespace RdtClient.Service.BackgroundServices; -public class DiskSpaceMonitor(ILogger logger, IServiceProvider serviceProvider) : BackgroundService +public class DiskSpaceMonitor(ILogger logger, IServiceProvider serviceProvider, ISettings settings, ITorrentRunnerState runnerState) : BackgroundService { private static DiskSpaceStatus? _lastStatus; private Boolean _isPausedForLowDiskSpace; @@ -34,7 +34,7 @@ public class DiskSpaceMonitor(ILogger logger, IServiceProvider { try { - var minimumFreeSpaceGB = Settings.Get.DownloadClient.MinimumFreeSpaceGB; + var minimumFreeSpaceGB = settings.Current.DownloadClient.MinimumFreeSpaceGB; if (minimumFreeSpaceGB <= 0) { @@ -43,14 +43,14 @@ public class DiskSpaceMonitor(ILogger logger, IServiceProvider continue; } - var intervalMinutes = Settings.Get.DownloadClient.DiskSpaceCheckIntervalMinutes; + var intervalMinutes = settings.Current.DownloadClient.DiskSpaceCheckIntervalMinutes; if (intervalMinutes < 1) { intervalMinutes = 1; } - var downloadPath = Settings.Get.DownloadClient.DownloadPath; + var downloadPath = settings.Current.DownloadClient.DownloadPath; logger.LogDebug($"Checking disk space for path: {downloadPath}"); if (!Directory.Exists(downloadPath)) @@ -78,7 +78,7 @@ public class DiskSpaceMonitor(ILogger logger, IServiceProvider var pausedCount = 0; - foreach (var download in TorrentRunner.ActiveDownloadClients) + foreach (var download in runnerState.ActiveDownloadClients) { if (download.Value.Type == DownloadClient.Bezzad) { @@ -90,7 +90,7 @@ public class DiskSpaceMonitor(ILogger logger, IServiceProvider logger.LogInformation($"Paused {pausedCount} active Bezzad downloads"); - TorrentRunner.IsPausedForLowDiskSpace = true; + runnerState.IsPausedForLowDiskSpace = true; _isPausedForLowDiskSpace = true; var status = new DiskSpaceStatus @@ -125,7 +125,7 @@ public class DiskSpaceMonitor(ILogger logger, IServiceProvider var resumedCount = 0; - foreach (var download in TorrentRunner.ActiveDownloadClients) + foreach (var download in runnerState.ActiveDownloadClients) { if (download.Value.Type == DownloadClient.Bezzad) { @@ -137,7 +137,7 @@ public class DiskSpaceMonitor(ILogger logger, IServiceProvider logger.LogInformation($"Resumed {resumedCount} Bezzad downloads"); - TorrentRunner.IsPausedForLowDiskSpace = false; + runnerState.IsPausedForLowDiskSpace = false; _isPausedForLowDiskSpace = false; var status = new DiskSpaceStatus diff --git a/server/RdtClient.Service/BackgroundServices/ProviderUpdater.cs b/server/RdtClient.Service/BackgroundServices/ProviderUpdater.cs index 7405dcb..a619a9d 100644 --- a/server/RdtClient.Service/BackgroundServices/ProviderUpdater.cs +++ b/server/RdtClient.Service/BackgroundServices/ProviderUpdater.cs @@ -7,7 +7,7 @@ using RdtClient.Service.Services; namespace RdtClient.Service.BackgroundServices; -public class ProviderUpdater(ILogger logger, IServiceProvider serviceProvider) : BackgroundService +public class ProviderUpdater(ILogger logger, IServiceProvider serviceProvider, ISettings settings) : BackgroundService { private static DateTime _nextUpdate = DateTime.UtcNow; @@ -30,11 +30,11 @@ public class ProviderUpdater(ILogger logger, IServiceProvider s { var torrents = await torrentService.Get(); - if (_nextUpdate < DateTime.UtcNow && (Settings.Get.Provider.AutoImport || torrents.Any(t => t.RdStatus != TorrentStatus.Finished) || RdtHub.HasConnections)) + if (_nextUpdate < DateTime.UtcNow && (settings.Current.Provider.AutoImport || torrents.Any(t => t.RdStatus != TorrentStatus.Finished) || RdtHub.HasConnections)) { logger.LogDebug($"Updating torrent info from debrid provider"); - var updateTime = Settings.Get.Provider.CheckInterval * 3; + var updateTime = settings.Current.Provider.CheckInterval * 3; if (updateTime < 30) { @@ -43,7 +43,7 @@ public class ProviderUpdater(ILogger logger, IServiceProvider s if (RdtHub.HasConnections) { - updateTime = Settings.Get.Provider.CheckInterval; + updateTime = settings.Current.Provider.CheckInterval; if (updateTime < 5) { diff --git a/server/RdtClient.Service/BackgroundServices/WatchFolderChecker.cs b/server/RdtClient.Service/BackgroundServices/WatchFolderChecker.cs index ce84030..db3cfa2 100644 --- a/server/RdtClient.Service/BackgroundServices/WatchFolderChecker.cs +++ b/server/RdtClient.Service/BackgroundServices/WatchFolderChecker.cs @@ -8,7 +8,7 @@ using LogLevel = Microsoft.Extensions.Logging.LogLevel; namespace RdtClient.Service.BackgroundServices; -public class WatchFolderChecker(ILogger logger, IServiceProvider serviceProvider) : BackgroundService +public class WatchFolderChecker(ILogger logger, IServiceProvider serviceProvider, ISettings settings) : BackgroundService { private DateTime _prevCheck = DateTime.MinValue; @@ -28,7 +28,7 @@ public class WatchFolderChecker(ILogger logger, IServiceProv { try { - var nextCheck = _prevCheck.AddSeconds(Math.Max(Settings.Get.Watch.Interval, 10)); + var nextCheck = _prevCheck.AddSeconds(Math.Max(settings.Current.Watch.Interval, 10)); if (DateTime.Now < nextCheck) { @@ -38,25 +38,25 @@ public class WatchFolderChecker(ILogger logger, IServiceProv _prevCheck = DateTime.Now; - if (String.IsNullOrWhiteSpace(Settings.Get.Watch.Path)) + if (String.IsNullOrWhiteSpace(settings.Current.Watch.Path)) { continue; } - var processedStorePath = Path.Combine(Settings.Get.Watch.Path, "processed"); - var errorStorePath = Path.Combine(Settings.Get.Watch.Path, "error"); + var processedStorePath = Path.Combine(settings.Current.Watch.Path, "processed"); + var errorStorePath = Path.Combine(settings.Current.Watch.Path, "error"); - if (!String.IsNullOrWhiteSpace(Settings.Get.Watch.ProcessedPath)) + if (!String.IsNullOrWhiteSpace(settings.Current.Watch.ProcessedPath)) { - processedStorePath = Settings.Get.Watch.ProcessedPath; + processedStorePath = settings.Current.Watch.ProcessedPath; } - if (!String.IsNullOrWhiteSpace(Settings.Get.Watch.ErrorPath)) + if (!String.IsNullOrWhiteSpace(settings.Current.Watch.ErrorPath)) { - errorStorePath = Settings.Get.Watch.ErrorPath; + errorStorePath = settings.Current.Watch.ErrorPath; } - var torrentFiles = Directory.GetFiles(Settings.Get.Watch.Path, "*.*", SearchOption.TopDirectoryOnly); + var torrentFiles = Directory.GetFiles(settings.Current.Watch.Path, "*.*", SearchOption.TopDirectoryOnly); foreach (var torrentFile in torrentFiles) { @@ -78,22 +78,22 @@ public class WatchFolderChecker(ILogger logger, IServiceProv var torrent = new Torrent { - DownloadClient = Settings.Get.DownloadClient.Client, - Category = Settings.Get.Watch.Default.Category, - HostDownloadAction = Settings.Get.Watch.Default.HostDownloadAction, - FinishedActionDelay = Settings.Get.Watch.Default.FinishedActionDelay, - DownloadAction = Settings.Get.Watch.Default.OnlyDownloadAvailableFiles + DownloadClient = settings.Current.DownloadClient.Client, + Category = settings.Current.Watch.Default.Category, + HostDownloadAction = settings.Current.Watch.Default.HostDownloadAction, + FinishedActionDelay = settings.Current.Watch.Default.FinishedActionDelay, + DownloadAction = settings.Current.Watch.Default.OnlyDownloadAvailableFiles ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll, - FinishedAction = Settings.Get.Watch.Default.FinishedAction, - DownloadMinSize = Settings.Get.Watch.Default.MinFileSize, - IncludeRegex = Settings.Get.Watch.Default.IncludeRegex, - ExcludeRegex = Settings.Get.Watch.Default.ExcludeRegex, - TorrentRetryAttempts = Settings.Get.Watch.Default.TorrentRetryAttempts, - DownloadRetryAttempts = Settings.Get.Watch.Default.DownloadRetryAttempts, - DeleteOnError = Settings.Get.Watch.Default.DeleteOnError, - Lifetime = Settings.Get.Watch.Default.TorrentLifetime, - Priority = Settings.Get.Watch.Default.Priority > 0 ? Settings.Get.Watch.Default.Priority : null + FinishedAction = settings.Current.Watch.Default.FinishedAction, + DownloadMinSize = settings.Current.Watch.Default.MinFileSize, + IncludeRegex = settings.Current.Watch.Default.IncludeRegex, + ExcludeRegex = settings.Current.Watch.Default.ExcludeRegex, + TorrentRetryAttempts = settings.Current.Watch.Default.TorrentRetryAttempts, + DownloadRetryAttempts = settings.Current.Watch.Default.DownloadRetryAttempts, + DeleteOnError = settings.Current.Watch.Default.DeleteOnError, + Lifetime = settings.Current.Watch.Default.TorrentLifetime, + Priority = settings.Current.Watch.Default.Priority > 0 ? settings.Current.Watch.Default.Priority : null }; if (fileInfo.Extension == ".torrent") diff --git a/server/RdtClient.Service/DiConfig.cs b/server/RdtClient.Service/DiConfig.cs index 6c1f0fe..de6e8ae 100644 --- a/server/RdtClient.Service/DiConfig.cs +++ b/server/RdtClient.Service/DiConfig.cs @@ -30,6 +30,7 @@ public static class DiConfig services.AddScoped(); services.AddSingleton(); + services.AddSingleton(TorrentRunner.SharedState); services.AddSingleton(); services.AddSingleton(); @@ -41,7 +42,8 @@ public static class DiConfig services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); + services.AddSingleton(); + services.AddSingleton(serviceProvider => serviceProvider.GetRequiredService()); services.AddScoped(); services.AddScoped(); services.AddScoped(); @@ -51,7 +53,7 @@ public static class DiConfig services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); + services.AddScoped(); services.AddScoped(); services.AddHostedService(); diff --git a/server/RdtClient.Service/Middleware/AuthSettingHandler.cs b/server/RdtClient.Service/Middleware/AuthSettingHandler.cs index 2cb8a12..bce8e85 100644 --- a/server/RdtClient.Service/Middleware/AuthSettingHandler.cs +++ b/server/RdtClient.Service/Middleware/AuthSettingHandler.cs @@ -8,7 +8,7 @@ public class AuthSettingRequirement : IAuthorizationRequirement { } -public class AuthSettingHandler : AuthorizationHandler +public class AuthSettingHandler(ISettings settings) : AuthorizationHandler { protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AuthSettingRequirement requirement) { @@ -17,7 +17,7 @@ public class AuthSettingHandler : AuthorizationHandler context.Succeed(requirement); } - if (Settings.Get.General.AuthenticationType == AuthenticationType.None) + if (settings.Current.General.AuthenticationType == AuthenticationType.None) { context.Succeed(requirement); } diff --git a/server/RdtClient.Service/Middleware/SabnzbdHandler.cs b/server/RdtClient.Service/Middleware/SabnzbdHandler.cs index 42dede8..2779faf 100644 --- a/server/RdtClient.Service/Middleware/SabnzbdHandler.cs +++ b/server/RdtClient.Service/Middleware/SabnzbdHandler.cs @@ -9,7 +9,7 @@ public class SabnzbdRequirement : IAuthorizationRequirement { } -public class SabnzbdHandler(Authentication authentication, IHttpContextAccessor httpContextAccessor) : AuthorizationHandler +public class SabnzbdHandler(Authentication authentication, IHttpContextAccessor httpContextAccessor, ISettings settings) : AuthorizationHandler { protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, SabnzbdRequirement requirement) { @@ -22,7 +22,7 @@ public class SabnzbdHandler(Authentication authentication, IHttpContextAccessor return; } - if (Settings.Get.General.AuthenticationType == AuthenticationType.None) + if (settings.Current.General.AuthenticationType == AuthenticationType.None) { context.Succeed(requirement); diff --git a/server/RdtClient.Service/Services/DebridClients/AllDebridDebridClient.cs b/server/RdtClient.Service/Services/DebridClients/AllDebridDebridClient.cs index aa1663e..52aeb29 100644 --- a/server/RdtClient.Service/Services/DebridClients/AllDebridDebridClient.cs +++ b/server/RdtClient.Service/Services/DebridClients/AllDebridDebridClient.cs @@ -17,13 +17,13 @@ public interface IAllDebridNetClientFactory public IAllDebridNETClient GetClient(); } -public class AllDebridNetClientFactory(ILogger logger, IHttpClientFactory httpClientFactory) : IAllDebridNetClientFactory +public class AllDebridNetClientFactory(ILogger logger, IHttpClientFactory httpClientFactory, ISettings settings) : IAllDebridNetClientFactory { public IAllDebridNETClient GetClient() { try { - var apiKey = Settings.Get.Provider.ApiKey; + var apiKey = settings.Current.Provider.ApiKey; if (String.IsNullOrWhiteSpace(apiKey)) { diff --git a/server/RdtClient.Service/Services/DebridClients/DebridLinkTorrentClient.cs b/server/RdtClient.Service/Services/DebridClients/DebridLinkTorrentClient.cs index 02cfd04..8fe1011 100644 --- a/server/RdtClient.Service/Services/DebridClients/DebridLinkTorrentClient.cs +++ b/server/RdtClient.Service/Services/DebridClients/DebridLinkTorrentClient.cs @@ -12,7 +12,7 @@ using Torrent = DebridLinkFrNET.Models.Torrent; namespace RdtClient.Service.Services.DebridClients; -public class DebridLinkClient(ILogger logger, IHttpClientFactory httpClientFactory, IDownloadableFileFilter fileFilter) : IDebridClient +public class DebridLinkClient(ILogger logger, IHttpClientFactory httpClientFactory, IDownloadableFileFilter fileFilter, ISettings settings) : IDebridClient { public async Task> GetDownloads() { @@ -228,7 +228,7 @@ public class DebridLinkClient(ILogger logger, IHttpClientFacto { try { - var apiKey = Settings.Get.Provider.ApiKey; + var apiKey = settings.Current.Provider.ApiKey; if (String.IsNullOrWhiteSpace(apiKey)) { @@ -236,7 +236,7 @@ public class DebridLinkClient(ILogger logger, IHttpClientFacto } var httpClient = httpClientFactory.CreateClient(); - httpClient.Timeout = TimeSpan.FromSeconds(Settings.Get.Provider.Timeout); + httpClient.Timeout = TimeSpan.FromSeconds(settings.Current.Provider.Timeout); var debridLinkClient = new DebridLinkFrNETClient(apiKey, httpClient); diff --git a/server/RdtClient.Service/Services/DebridClients/PremiumizeDebridClient.cs b/server/RdtClient.Service/Services/DebridClients/PremiumizeDebridClient.cs index dc79367..a162c0a 100644 --- a/server/RdtClient.Service/Services/DebridClients/PremiumizeDebridClient.cs +++ b/server/RdtClient.Service/Services/DebridClients/PremiumizeDebridClient.cs @@ -12,7 +12,7 @@ using Torrent = RdtClient.Data.Models.Data.Torrent; namespace RdtClient.Service.Services.DebridClients; -public class PremiumizeDebridClient(ILogger logger, IHttpClientFactory httpClientFactory, IDownloadableFileFilter fileFilter) : IDebridClient +public class PremiumizeDebridClient(ILogger logger, IHttpClientFactory httpClientFactory, IDownloadableFileFilter fileFilter, ISettings settings) : IDebridClient { private const String TransferCreateUrl = "https://www.premiumize.me/api/transfer/create"; @@ -216,9 +216,9 @@ public class PremiumizeDebridClient(ILogger logger, IHtt } } - private static String GetApiKey() + private String GetApiKey() { - var apiKey = Settings.Get.Provider.ApiKey; + var apiKey = settings.Current.Provider.ApiKey; if (String.IsNullOrWhiteSpace(apiKey)) { diff --git a/server/RdtClient.Service/Services/DebridClients/RealDebridDebridClient.cs b/server/RdtClient.Service/Services/DebridClients/RealDebridDebridClient.cs index 5f74e47..ea8505a 100644 --- a/server/RdtClient.Service/Services/DebridClients/RealDebridDebridClient.cs +++ b/server/RdtClient.Service/Services/DebridClients/RealDebridDebridClient.cs @@ -12,7 +12,7 @@ using Torrent = RDNET.Torrent; namespace RdtClient.Service.Services.DebridClients; -public class RealDebridDebridClient(ILogger logger, IHttpClientFactory httpClientFactory, IDownloadableFileFilter fileFilter) : IDebridClient +public class RealDebridDebridClient(ILogger logger, IHttpClientFactory httpClientFactory, IDownloadableFileFilter fileFilter, ISettings settings) : IDebridClient { private TimeSpan? _offset; @@ -53,7 +53,7 @@ public class RealDebridDebridClient(ILogger logger, IHtt { try { - var timeoutCancellationToken = new CancellationTokenSource(TimeSpan.FromSeconds(Settings.Get.Provider.Timeout)); + var timeoutCancellationToken = new CancellationTokenSource(TimeSpan.FromSeconds(settings.Current.Provider.Timeout)); var result = await GetClient().Torrents.AddMagnetAsync(magnetLink, timeoutCancellationToken.Token); @@ -70,7 +70,7 @@ public class RealDebridDebridClient(ILogger logger, IHtt { try { - var timeoutCancellationToken = new CancellationTokenSource(TimeSpan.FromSeconds(Settings.Get.Provider.Timeout)); + var timeoutCancellationToken = new CancellationTokenSource(TimeSpan.FromSeconds(settings.Current.Provider.Timeout)); var result = await GetClient().Torrents.AddFileAsync(bytes, timeoutCancellationToken.Token); @@ -314,7 +314,7 @@ public class RealDebridDebridClient(ILogger logger, IHtt { try { - var apiKey = Settings.Get.Provider.ApiKey; + var apiKey = settings.Current.Provider.ApiKey; if (String.IsNullOrWhiteSpace(apiKey)) { @@ -322,9 +322,9 @@ public class RealDebridDebridClient(ILogger logger, IHtt } var httpClient = httpClientFactory.CreateClient(DiConfig.RD_CLIENT); - httpClient.Timeout = TimeSpan.FromSeconds(Settings.Get.Provider.Timeout); + httpClient.Timeout = TimeSpan.FromSeconds(settings.Current.Provider.Timeout); - var rdtNetClient = new RdNetClient(null, httpClient, 5, Settings.Get.Provider.ApiHostname); + var rdtNetClient = new RdNetClient(null, httpClient, 5, settings.Current.Provider.ApiHostname); rdtNetClient.UseApiAuthentication(apiKey); // Get the server time to fix up the timezones on results diff --git a/server/RdtClient.Service/Services/DebridClients/TorBoxDebridClient.cs b/server/RdtClient.Service/Services/DebridClients/TorBoxDebridClient.cs index 47aad2a..254bc4a 100644 --- a/server/RdtClient.Service/Services/DebridClients/TorBoxDebridClient.cs +++ b/server/RdtClient.Service/Services/DebridClients/TorBoxDebridClient.cs @@ -11,7 +11,7 @@ using Torrent = RdtClient.Data.Models.Data.Torrent; namespace RdtClient.Service.Services.DebridClients; -public class TorBoxDebridClient(ILogger logger, IHttpClientFactory httpClientFactory, IDownloadableFileFilter fileFilter, IRateLimitCoordinator coordinator) +public class TorBoxDebridClient(ILogger logger, IHttpClientFactory httpClientFactory, IDownloadableFileFilter fileFilter, IRateLimitCoordinator coordinator, ISettings settings) : IDebridClient { private const String TorBoxApiHost = "api.torbox.app"; @@ -327,7 +327,7 @@ public class TorBoxDebridClient(ILogger logger, IHttpClientF var downloadableFiles = torrent.Files.Where(file => fileFilter.IsDownloadable(torrent, file.Path, file.Bytes)).ToList(); - if (downloadableFiles.Count == torrent.Files.Count && torrent.DownloadClient != Data.Enums.DownloadClient.Symlink && Settings.Get.Provider.PreferZippedDownloads) + if (downloadableFiles.Count == torrent.Files.Count && torrent.DownloadClient != Data.Enums.DownloadClient.Symlink && settings.Current.Provider.PreferZippedDownloads) { logger.LogDebug("Downloading files from TorBox as a zip."); @@ -364,7 +364,7 @@ public class TorBoxDebridClient(ILogger logger, IHttpClientF { try { - var apiKey = Settings.Get.Provider.ApiKey; + var apiKey = settings.Current.Provider.ApiKey; if (String.IsNullOrWhiteSpace(apiKey)) { diff --git a/server/RdtClient.Service/Services/QBittorrent.cs b/server/RdtClient.Service/Services/QBittorrent.cs index 0192ee4..465c69a 100644 --- a/server/RdtClient.Service/Services/QBittorrent.cs +++ b/server/RdtClient.Service/Services/QBittorrent.cs @@ -5,7 +5,7 @@ using RdtClient.Data.Models.QBittorrent; namespace RdtClient.Service.Services; -public class QBittorrent(ILogger logger, Settings settings, Authentication authentication, Torrents torrents, Downloads downloads) +public class QBittorrent(ILogger logger, ISettings settings, Authentication authentication, Torrents torrents, Downloads downloads, ITorrentRunnerState runnerState) { public async Task AuthLogin(String userName, String password) { @@ -168,7 +168,7 @@ public class QBittorrent(ILogger logger, Settings settings, Authent WebUiUsername = "" }; - var savePath = Settings.AppDefaultSavePath; + var savePath = settings.DefaultSavePath; preferences.SavePath = savePath; preferences.TempPath = $"{savePath}temp{Path.DirectorySeparatorChar}"; @@ -185,7 +185,7 @@ public class QBittorrent(ILogger logger, Settings settings, Authent public virtual async Task> TorrentInfo() { - var savePath = Settings.AppDefaultSavePath; + var savePath = settings.DefaultSavePath; var results = new List(); @@ -515,7 +515,7 @@ public class QBittorrent(ILogger logger, Settings settings, Authent public async Task TorrentProperties(String hash) { - var savePath = Settings.AppDefaultSavePath; + var savePath = settings.DefaultSavePath; var torrent = await torrents.GetByHash(hash); @@ -605,7 +605,7 @@ public class QBittorrent(ILogger logger, Settings settings, Authent return; } - switch (Settings.Get.Integrations.Default.FinishedAction) + switch (settings.Current.Integrations.Default.FinishedAction) { case TorrentFinishedAction.RemoveAllTorrents: logger.LogDebug("Removing torrents from debrid provider and RDT-Client, no files"); @@ -640,19 +640,19 @@ public class QBittorrent(ILogger logger, Settings settings, Authent var torrent = new Torrent { Category = category, - DownloadClient = Settings.Get.DownloadClient.Client, - HostDownloadAction = Settings.Get.Integrations.Default.HostDownloadAction, - FinishedActionDelay = Settings.Get.Integrations.Default.FinishedActionDelay, - DownloadAction = Settings.Get.Integrations.Default.OnlyDownloadAvailableFiles ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll, + DownloadClient = settings.Current.DownloadClient.Client, + HostDownloadAction = settings.Current.Integrations.Default.HostDownloadAction, + FinishedActionDelay = settings.Current.Integrations.Default.FinishedActionDelay, + DownloadAction = settings.Current.Integrations.Default.OnlyDownloadAvailableFiles ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll, FinishedAction = TorrentFinishedAction.None, - DownloadMinSize = Settings.Get.Integrations.Default.MinFileSize, - IncludeRegex = Settings.Get.Integrations.Default.IncludeRegex, - ExcludeRegex = Settings.Get.Integrations.Default.ExcludeRegex, - TorrentRetryAttempts = Settings.Get.Integrations.Default.TorrentRetryAttempts, - DownloadRetryAttempts = Settings.Get.Integrations.Default.DownloadRetryAttempts, - DeleteOnError = Settings.Get.Integrations.Default.DeleteOnError, - Lifetime = Settings.Get.Integrations.Default.TorrentLifetime, - Priority = priority ?? (Settings.Get.Integrations.Default.Priority > 0 ? Settings.Get.Integrations.Default.Priority : null) + DownloadMinSize = settings.Current.Integrations.Default.MinFileSize, + IncludeRegex = settings.Current.Integrations.Default.IncludeRegex, + ExcludeRegex = settings.Current.Integrations.Default.ExcludeRegex, + TorrentRetryAttempts = settings.Current.Integrations.Default.TorrentRetryAttempts, + DownloadRetryAttempts = settings.Current.Integrations.Default.DownloadRetryAttempts, + DeleteOnError = settings.Current.Integrations.Default.DeleteOnError, + Lifetime = settings.Current.Integrations.Default.TorrentLifetime, + Priority = priority ?? (settings.Current.Integrations.Default.Priority > 0 ? settings.Current.Integrations.Default.Priority : null) }; await torrents.AddMagnetToDebridQueue(magnetLink, torrent); @@ -665,19 +665,19 @@ public class QBittorrent(ILogger logger, Settings settings, Authent var torrent = new Torrent { Category = category, - DownloadClient = Settings.Get.DownloadClient.Client, - HostDownloadAction = Settings.Get.Integrations.Default.HostDownloadAction, - FinishedActionDelay = Settings.Get.Integrations.Default.FinishedActionDelay, - DownloadAction = Settings.Get.Integrations.Default.OnlyDownloadAvailableFiles ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll, + DownloadClient = settings.Current.DownloadClient.Client, + HostDownloadAction = settings.Current.Integrations.Default.HostDownloadAction, + FinishedActionDelay = settings.Current.Integrations.Default.FinishedActionDelay, + DownloadAction = settings.Current.Integrations.Default.OnlyDownloadAvailableFiles ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll, FinishedAction = TorrentFinishedAction.None, - DownloadMinSize = Settings.Get.Integrations.Default.MinFileSize, - IncludeRegex = Settings.Get.Integrations.Default.IncludeRegex, - ExcludeRegex = Settings.Get.Integrations.Default.ExcludeRegex, - TorrentRetryAttempts = Settings.Get.Integrations.Default.TorrentRetryAttempts, - DownloadRetryAttempts = Settings.Get.Integrations.Default.DownloadRetryAttempts, - DeleteOnError = Settings.Get.Integrations.Default.DeleteOnError, - Lifetime = Settings.Get.Integrations.Default.TorrentLifetime, - Priority = priority ?? (Settings.Get.Integrations.Default.Priority > 0 ? Settings.Get.Integrations.Default.Priority : null) + DownloadMinSize = settings.Current.Integrations.Default.MinFileSize, + IncludeRegex = settings.Current.Integrations.Default.IncludeRegex, + ExcludeRegex = settings.Current.Integrations.Default.ExcludeRegex, + TorrentRetryAttempts = settings.Current.Integrations.Default.TorrentRetryAttempts, + DownloadRetryAttempts = settings.Current.Integrations.Default.DownloadRetryAttempts, + DeleteOnError = settings.Current.Integrations.Default.DeleteOnError, + Lifetime = settings.Current.Integrations.Default.TorrentLifetime, + Priority = priority ?? (settings.Current.Integrations.Default.Priority > 0 ? settings.Current.Integrations.Default.Priority : null) }; await torrents.AddFileToDebridQueue(fileBytes, torrent); @@ -696,7 +696,7 @@ public class QBittorrent(ILogger logger, Settings settings, Authent .Select(m => m.Category!.ToLower()) .ToList(); - var categoryList = (Settings.Get.General.Categories ?? "") + var categoryList = (settings.Current.General.Categories ?? "") .Split(",", StringSplitOptions.RemoveEmptyEntries) .Distinct(StringComparer.CurrentCultureIgnoreCase) .Select(m => m.Trim()) @@ -713,7 +713,7 @@ public class QBittorrent(ILogger logger, Settings settings, Authent m => new TorrentCategory { Name = m, - SavePath = Path.Combine(Settings.AppDefaultSavePath, m) + SavePath = Path.Combine(settings.DefaultSavePath, m) }); } @@ -729,7 +729,7 @@ public class QBittorrent(ILogger logger, Settings settings, Authent category = category.Trim(); - var categoriesSetting = Settings.Get.General.Categories; + var categoriesSetting = settings.Current.General.Categories; var categoryList = (categoriesSetting ?? "") .Split(",", StringSplitOptions.RemoveEmptyEntries) @@ -756,7 +756,7 @@ public class QBittorrent(ILogger logger, Settings settings, Authent category = category.Trim(); - var categoriesSetting = Settings.Get.General.Categories; + var categoriesSetting = settings.Current.General.Categories; var categoryList = (categoriesSetting ?? "") .Split(",", StringSplitOptions.RemoveEmptyEntries) @@ -796,7 +796,7 @@ public class QBittorrent(ILogger logger, Settings settings, Authent foreach (var download in downloadsForTorrent) { - if (TorrentRunner.ActiveDownloadClients.TryGetValue(download.DownloadId, out var downloadClient)) + if (runnerState.ActiveDownloadClients.TryGetValue(download.DownloadId, out var downloadClient)) { await downloadClient.Pause(); } @@ -816,7 +816,7 @@ public class QBittorrent(ILogger logger, Settings settings, Authent foreach (var download in downloadsForTorrent) { - if (TorrentRunner.ActiveDownloadClients.TryGetValue(download.DownloadId, out var downloadClient)) + if (runnerState.ActiveDownloadClients.TryGetValue(download.DownloadId, out var downloadClient)) { await downloadClient.Resume(); } @@ -829,7 +829,7 @@ public class QBittorrent(ILogger logger, Settings settings, Authent var categories = await TorrentsCategories(); - var activeDownloads = TorrentRunner.ActiveDownloadClients.Sum(m => m.Value.Speed); + var activeDownloads = runnerState.ActiveDownloadClients.Sum(m => m.Value.Speed); return new() { @@ -847,16 +847,16 @@ public class QBittorrent(ILogger logger, Settings settings, Authent }; } - public static TransferInfo TransferInfo() + public virtual TransferInfo TransferInfo() { - var activeDownloads = TorrentRunner.ActiveDownloadClients.Sum(m => m.Value.Speed); + var activeDownloads = runnerState.ActiveDownloadClients.Sum(m => m.Value.Speed); return new() { ConnectionStatus = "connected", DlInfoData = DownloadClient.GetTotalBytesDownloadedThisSession(), DlInfoSpeed = activeDownloads, - DlRateLimit = Settings.Get.DownloadClient.MaxSpeed + DlRateLimit = settings.Current.DownloadClient.MaxSpeed }; } diff --git a/server/RdtClient.Service/Services/Sabnzbd.cs b/server/RdtClient.Service/Services/Sabnzbd.cs index 71cce9a..c95abc9 100644 --- a/server/RdtClient.Service/Services/Sabnzbd.cs +++ b/server/RdtClient.Service/Services/Sabnzbd.cs @@ -7,7 +7,7 @@ using RdtClient.Service.Helpers; namespace RdtClient.Service.Services; -public class Sabnzbd(ILogger logger, Torrents torrents, AppSettings appSettings) +public class Sabnzbd(ILogger logger, Torrents torrents, AppSettings appSettings, ISettings settings) { public virtual async Task GetQueue() { @@ -87,7 +87,7 @@ public class Sabnzbd(ILogger logger, Torrents torrents, AppSettings app var allTorrents = await torrents.Get(); var completedTorrents = allTorrents.Where(t => t.Type == DownloadType.Nzb && t.Completed != null).ToList(); - var savePath = Settings.AppDefaultSavePath; + var savePath = settings.DefaultSavePath; var history = new SabnzbdHistory { @@ -130,19 +130,19 @@ public class Sabnzbd(ILogger logger, Torrents torrents, AppSettings app var torrent = new Torrent { Category = category, - DownloadClient = Settings.Get.DownloadClient.Client, - HostDownloadAction = Settings.Get.Integrations.Default.HostDownloadAction, - FinishedActionDelay = Settings.Get.Integrations.Default.FinishedActionDelay, - DownloadAction = Settings.Get.Integrations.Default.OnlyDownloadAvailableFiles ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll, + DownloadClient = settings.Current.DownloadClient.Client, + HostDownloadAction = settings.Current.Integrations.Default.HostDownloadAction, + FinishedActionDelay = settings.Current.Integrations.Default.FinishedActionDelay, + DownloadAction = settings.Current.Integrations.Default.OnlyDownloadAvailableFiles ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll, FinishedAction = TorrentFinishedAction.None, - DownloadMinSize = Settings.Get.Integrations.Default.MinFileSize, - IncludeRegex = Settings.Get.Integrations.Default.IncludeRegex, - ExcludeRegex = Settings.Get.Integrations.Default.ExcludeRegex, - TorrentRetryAttempts = Settings.Get.Integrations.Default.TorrentRetryAttempts, - DownloadRetryAttempts = Settings.Get.Integrations.Default.DownloadRetryAttempts, - DeleteOnError = Settings.Get.Integrations.Default.DeleteOnError, - Lifetime = Settings.Get.Integrations.Default.TorrentLifetime, - Priority = (priority ?? Settings.Get.Integrations.Default.Priority) > 0 ? 1 : null + DownloadMinSize = settings.Current.Integrations.Default.MinFileSize, + IncludeRegex = settings.Current.Integrations.Default.IncludeRegex, + ExcludeRegex = settings.Current.Integrations.Default.ExcludeRegex, + TorrentRetryAttempts = settings.Current.Integrations.Default.TorrentRetryAttempts, + DownloadRetryAttempts = settings.Current.Integrations.Default.DownloadRetryAttempts, + DeleteOnError = settings.Current.Integrations.Default.DeleteOnError, + Lifetime = settings.Current.Integrations.Default.TorrentLifetime, + Priority = (priority ?? settings.Current.Integrations.Default.Priority) > 0 ? 1 : null }; var result = await torrents.AddNzbFileToDebridQueue(fileBytes, fileName, torrent); @@ -157,19 +157,19 @@ public class Sabnzbd(ILogger logger, Torrents torrents, AppSettings app var torrent = new Torrent { Category = category, - DownloadClient = Settings.Get.DownloadClient.Client, - HostDownloadAction = Settings.Get.Integrations.Default.HostDownloadAction, - FinishedActionDelay = Settings.Get.Integrations.Default.FinishedActionDelay, - DownloadAction = Settings.Get.Integrations.Default.OnlyDownloadAvailableFiles ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll, + DownloadClient = settings.Current.DownloadClient.Client, + HostDownloadAction = settings.Current.Integrations.Default.HostDownloadAction, + FinishedActionDelay = settings.Current.Integrations.Default.FinishedActionDelay, + DownloadAction = settings.Current.Integrations.Default.OnlyDownloadAvailableFiles ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll, FinishedAction = TorrentFinishedAction.None, - DownloadMinSize = Settings.Get.Integrations.Default.MinFileSize, - IncludeRegex = Settings.Get.Integrations.Default.IncludeRegex, - ExcludeRegex = Settings.Get.Integrations.Default.ExcludeRegex, - TorrentRetryAttempts = Settings.Get.Integrations.Default.TorrentRetryAttempts, - DownloadRetryAttempts = Settings.Get.Integrations.Default.DownloadRetryAttempts, - DeleteOnError = Settings.Get.Integrations.Default.DeleteOnError, - Lifetime = Settings.Get.Integrations.Default.TorrentLifetime, - Priority = priority ?? (Settings.Get.Integrations.Default.Priority > 0 ? Settings.Get.Integrations.Default.Priority : null) + DownloadMinSize = settings.Current.Integrations.Default.MinFileSize, + IncludeRegex = settings.Current.Integrations.Default.IncludeRegex, + ExcludeRegex = settings.Current.Integrations.Default.ExcludeRegex, + TorrentRetryAttempts = settings.Current.Integrations.Default.TorrentRetryAttempts, + DownloadRetryAttempts = settings.Current.Integrations.Default.DownloadRetryAttempts, + DeleteOnError = settings.Current.Integrations.Default.DeleteOnError, + Lifetime = settings.Current.Integrations.Default.TorrentLifetime, + Priority = priority ?? (settings.Current.Integrations.Default.Priority > 0 ? settings.Current.Integrations.Default.Priority : null) }; var result = await torrents.AddNzbLinkToDebridQueue(url, torrent); @@ -186,7 +186,7 @@ public class Sabnzbd(ILogger logger, Torrents torrents, AppSettings app return; } - switch (Settings.Get.Integrations.Default.FinishedAction) + switch (settings.Current.Integrations.Default.FinishedAction) { case TorrentFinishedAction.RemoveAllTorrents: logger.LogDebug("Removing nzb from debrid provider and RDT-Client, no files"); @@ -216,7 +216,7 @@ public class Sabnzbd(ILogger logger, Torrents torrents, AppSettings app public virtual List GetCategories() { - var categoryList = (Settings.Get.General.Categories ?? "") + var categoryList = (settings.Current.General.Categories ?? "") .Split(",", StringSplitOptions.RemoveEmptyEntries) .Select(m => m.Trim()) .Where(m => m != "*") @@ -230,7 +230,7 @@ public class Sabnzbd(ILogger logger, Torrents torrents, AppSettings app public virtual SabnzbdConfig GetConfig() { - var savePath = Settings.AppDefaultSavePath; + var savePath = settings.DefaultSavePath; var categoryList = GetCategories(); diff --git a/server/RdtClient.Service/Services/Settings.cs b/server/RdtClient.Service/Services/Settings.cs index 035a56a..b471192 100644 --- a/server/RdtClient.Service/Services/Settings.cs +++ b/server/RdtClient.Service/Services/Settings.cs @@ -1,49 +1,83 @@ using RdtClient.Data.Data; using RdtClient.Data.Enums; using RdtClient.Data.Models.Internal; +using Microsoft.Extensions.DependencyInjection; using Serilog.Core; using Serilog.Events; namespace RdtClient.Service.Services; -public class Settings(SettingData settingData) +public interface ISettings +{ + DbSettings Current { get; } + + String DefaultSavePath { get; } + + IList GetAll(); + + Task Update(IList settings); + + Task Update(String settingId, Object? value); +} + +public class Settings(IServiceScopeFactory serviceScopeFactory) : ISettings { public static readonly LoggingLevelSwitch LoggingLevelSwitch = new(LogEventLevel.Debug); public static DbSettings Get => SettingData.Get; - public static String AppDefaultSavePath + public DbSettings Current => Get; + + public static String AppDefaultSavePath => GetDefaultSavePath(Get); + + public String DefaultSavePath => GetDefaultSavePath(Current); + + public IList GetAll() { - get - { - var downloadPath = Get.DownloadClient.MappedPath; + return SettingData.GetAll(); + } - downloadPath = downloadPath.TrimEnd('\\') - .TrimEnd('/'); + private static String GetDefaultSavePath(DbSettings settings) + { + var downloadPath = settings.DownloadClient.MappedPath; - downloadPath += Path.DirectorySeparatorChar; + downloadPath = downloadPath.TrimEnd('\\') + .TrimEnd('/'); - return downloadPath; - } + downloadPath += Path.DirectorySeparatorChar; + + return downloadPath; } public async Task Update(IList settings) { + using var scope = serviceScopeFactory.CreateScope(); + var settingData = scope.ServiceProvider.GetRequiredService(); + await settingData.Update(settings); } public async Task Update(String settingId, Object? value) { + using var scope = serviceScopeFactory.CreateScope(); + var settingData = scope.ServiceProvider.GetRequiredService(); + await settingData.Update(settingId, value); } public async Task Seed() { + using var scope = serviceScopeFactory.CreateScope(); + var settingData = scope.ServiceProvider.GetRequiredService(); + await settingData.Seed(); } public async Task ResetCache() { + using var scope = serviceScopeFactory.CreateScope(); + var settingData = scope.ServiceProvider.GetRequiredService(); + await settingData.ResetCache(); LoggingLevelSwitch.MinimumLevel = Get.General.LogLevel switch diff --git a/server/RdtClient.Service/Services/TorrentRunner.cs b/server/RdtClient.Service/Services/TorrentRunner.cs index 761057b..1215cf1 100644 --- a/server/RdtClient.Service/Services/TorrentRunner.cs +++ b/server/RdtClient.Service/Services/TorrentRunner.cs @@ -17,34 +17,34 @@ public class TorrentRunner( Downloads downloads, RemoteService remoteService, IHttpClientFactory httpClientFactory, - IRateLimitCoordinator coordinator) + IRateLimitCoordinator coordinator, + ISettings settings, + ITorrentRunnerState runnerState) { - public static readonly ConcurrentDictionary ActiveDownloadClients = new(); - public static readonly ConcurrentDictionary ActiveUnpackClients = new(); + public static readonly ITorrentRunnerState SharedState = new TorrentRunnerState(); + + public static ConcurrentDictionary ActiveDownloadClients => SharedState.ActiveDownloadClients; + + public static ConcurrentDictionary ActiveUnpackClients => SharedState.ActiveUnpackClients; + private DateTimeOffset? _lastNextAllowedAt; - public static Boolean IsPausedForLowDiskSpace { get; set; } + public static Boolean IsPausedForLowDiskSpace + { + get => SharedState.IsPausedForLowDiskSpace; + set => SharedState.IsPausedForLowDiskSpace = value; + } public static (Int64 Speed, Int64 BytesTotal, Int64 BytesDone) GetStats(Guid downloadId) { - if (ActiveDownloadClients.TryGetValue(downloadId, out var downloadClient)) - { - return (downloadClient.Speed, downloadClient.BytesTotal, downloadClient.BytesDone); - } - - if (ActiveUnpackClients.TryGetValue(downloadId, out var unpackClient)) - { - return (0, 100, unpackClient.Progess); - } - - return (0, 0, 0); + return SharedState.GetStats(downloadId); } public async Task Initialize() { Log("Initializing TorrentRunner"); - var settingsCopy = JsonSerializer.Deserialize(JsonSerializer.Serialize(Settings.Get)); + var settingsCopy = JsonSerializer.Deserialize(JsonSerializer.Serialize(settings.Current)); if (settingsCopy != null) { @@ -87,28 +87,28 @@ public class TorrentRunner( public async Task Tick() { - if (String.IsNullOrWhiteSpace(Settings.Get.Provider.ApiKey)) + if (String.IsNullOrWhiteSpace(settings.Current.Provider.ApiKey)) { Log($"No RealDebridApiKey set in settings"); return; } - var settingDownloadLimit = Settings.Get.General.DownloadLimit; + var settingDownloadLimit = settings.Current.General.DownloadLimit; if (settingDownloadLimit < 1) { settingDownloadLimit = 1; } - var settingUnpackLimit = Settings.Get.General.UnpackLimit; + var settingUnpackLimit = settings.Current.General.UnpackLimit; if (settingUnpackLimit < 0) { settingUnpackLimit = 0; } - var settingDownloadPath = Settings.Get.DownloadClient.DownloadPath; + var settingDownloadPath = settings.Current.DownloadClient.DownloadPath; if (String.IsNullOrWhiteSpace(settingDownloadPath)) { @@ -141,25 +141,25 @@ public class TorrentRunner( _lastNextAllowedAt = currentNextAllowedAt; } - if (!ActiveDownloadClients.IsEmpty || !ActiveUnpackClients.IsEmpty) + if (!runnerState.ActiveDownloadClients.IsEmpty || !runnerState.ActiveUnpackClients.IsEmpty) { - Log($"TorrentRunner Tick Start, {ActiveDownloadClients.Count} active downloads, {ActiveUnpackClients.Count} active unpacks"); + Log($"TorrentRunner Tick Start, {runnerState.ActiveDownloadClients.Count} active downloads, {runnerState.ActiveUnpackClients.Count} active unpacks"); } - if (ActiveDownloadClients.Any(m => m.Value.Type == Data.Enums.DownloadClient.Aria2c)) + if (runnerState.ActiveDownloadClients.Any(m => m.Value.Type == Data.Enums.DownloadClient.Aria2c)) { Log("Updating Aria2 status"); var httpClient = httpClientFactory.CreateClient(); httpClient.Timeout = TimeSpan.FromSeconds(10); - var aria2NetClient = new Aria2NetClient(Settings.Get.DownloadClient.Aria2cUrl, Settings.Get.DownloadClient.Aria2cSecret, httpClient, 1); + var aria2NetClient = new Aria2NetClient(settings.Current.DownloadClient.Aria2cUrl, settings.Current.DownloadClient.Aria2cSecret, httpClient, 1); var allDownloads = await aria2NetClient.TellAllAsync(); Log($"Found {allDownloads.Count} Aria2 downloads"); - foreach (var activeDownload in ActiveDownloadClients) + foreach (var activeDownload in runnerState.ActiveDownloadClients) { if (activeDownload.Value.Downloader is Aria2cDownloader aria2Downloader) { @@ -170,11 +170,11 @@ public class TorrentRunner( Log("Finished updating Aria2 status"); } - if (ActiveDownloadClients.Any(m => m.Value.Type == Data.Enums.DownloadClient.DownloadStation)) + if (runnerState.ActiveDownloadClients.Any(m => m.Value.Type == Data.Enums.DownloadClient.DownloadStation)) { Log("Updating DownloadStation status"); - foreach (var activeDownload in ActiveDownloadClients) + foreach (var activeDownload in runnerState.ActiveDownloadClients) { if (activeDownload.Value.Downloader is DownloadStationDownloader downloadStationDownloader) { @@ -184,7 +184,7 @@ public class TorrentRunner( } // Check if any torrents are finished downloading to the host, remove them from the active download list. - var completedActiveDownloads = ActiveDownloadClients.Where(m => m.Value.Finished).ToList(); + var completedActiveDownloads = runnerState.ActiveDownloadClients.Where(m => m.Value.Finished).ToList(); if (completedActiveDownloads.Count > 0) { @@ -196,7 +196,7 @@ public class TorrentRunner( if (download == null) { - ActiveDownloadClients.TryRemove(downloadId, out _); + runnerState.ActiveDownloadClients.TryRemove(downloadId, out _); Log($"Download with ID {downloadId} not found! Removed from download queue"); @@ -237,14 +237,14 @@ public class TorrentRunner( await downloads.UpdateUnpackingQueued(downloadId, DateTimeOffset.UtcNow); } - ActiveDownloadClients.TryRemove(downloadId, out _); + runnerState.ActiveDownloadClients.TryRemove(downloadId, out _); Log($"Removed from ActiveDownloadClients", download, download.Torrent); } } // Check if any torrents are finished unpacking, remove them from the active unpack list. - var completedUnpacks = ActiveUnpackClients.Where(m => m.Value.Finished).ToList(); + var completedUnpacks = runnerState.ActiveUnpackClients.Where(m => m.Value.Finished).ToList(); if (completedUnpacks.Count > 0) { @@ -256,7 +256,7 @@ public class TorrentRunner( if (download == null) { - ActiveUnpackClients.TryRemove(downloadId, out _); + runnerState.ActiveUnpackClients.TryRemove(downloadId, out _); Log($"Download with ID {downloadId} not found! Removed from unpack queue"); @@ -278,7 +278,7 @@ public class TorrentRunner( await downloads.UpdateCompleted(downloadId, DateTimeOffset.UtcNow); - ActiveUnpackClients.TryRemove(downloadId, out _); + runnerState.ActiveUnpackClients.TryRemove(downloadId, out _); Log($"Removed from ActiveUnpackClients", download, download.Torrent); } @@ -288,23 +288,23 @@ public class TorrentRunner( var downloadsById = allTorrents.SelectMany(m => m.Downloads).ToDictionary(m => m.DownloadId, m => m); // Check for deleted torrents that are stuck in the ActiveDownloads or ActiveUnpacks - foreach (var activeDownload in ActiveDownloadClients) + foreach (var activeDownload in runnerState.ActiveDownloadClients) { if (!downloadsById.ContainsKey(activeDownload.Key)) { await activeDownload.Value.Cancel(); - ActiveDownloadClients.TryRemove(activeDownload.Key, out _); + runnerState.ActiveDownloadClients.TryRemove(activeDownload.Key, out _); break; } } - foreach (var activeUnpacks in ActiveUnpackClients) + foreach (var activeUnpacks in runnerState.ActiveUnpackClients) { if (!downloadsById.ContainsKey(activeUnpacks.Key)) { activeUnpacks.Value.Cancel(); - ActiveUnpackClients.TryRemove(activeUnpacks.Key, out _); + runnerState.ActiveUnpackClients.TryRemove(activeUnpacks.Key, out _); break; } @@ -382,7 +382,7 @@ public class TorrentRunner( { var downloadingTorrentsCount = allTorrents.Count(m => m.RdStatus is not (TorrentStatus.Queued or TorrentStatus.Finished or TorrentStatus.Error)); - var maxParallelDownloads = Settings.Get.Provider.MaxParallelDownloads; + var maxParallelDownloads = settings.Current.Provider.MaxParallelDownloads; logger.LogDebug("Currently downloading {downloadingTorrentCount}/{maxParallelDownloads} torrents, {queuedCount} queued.", downloadingTorrentsCount, @@ -481,27 +481,27 @@ public class TorrentRunner( .OrderBy(m => m.DownloadQueued) .ToList(); - Log($"Currently {queuedDownloads.Count} queued downloads and {ActiveDownloadClients.Count} total active downloads", torrent); + Log($"Currently {queuedDownloads.Count} queued downloads and {runnerState.ActiveDownloadClients.Count} total active downloads", torrent); foreach (var download in queuedDownloads) { Log($"Processing to download", download, torrent); - if (ActiveDownloadClients.Count >= settingDownloadLimit && torrent.DownloadClient != Data.Enums.DownloadClient.Symlink) + if (runnerState.ActiveDownloadClients.Count >= settingDownloadLimit && torrent.DownloadClient != Data.Enums.DownloadClient.Symlink) { Log($"Not starting download because there are already the max number of downloads active", download, torrent); return; } - if (IsPausedForLowDiskSpace && torrent.DownloadClient == Data.Enums.DownloadClient.Bezzad) + if (runnerState.IsPausedForLowDiskSpace && torrent.DownloadClient == Data.Enums.DownloadClient.Bezzad) { logger.LogInformation($"Not starting Bezzad download because of low disk space {download.ToLog()} {torrent.ToLog()}"); return; } - if (ActiveDownloadClients.ContainsKey(download.DownloadId)) + if (runnerState.ActiveDownloadClients.ContainsKey(download.DownloadId)) { Log($"Not starting download because this download is already active", download, torrent); @@ -553,7 +553,7 @@ public class TorrentRunner( // Start the download process var downloadClient = new DownloadClient(download, torrent, downloadPath, torrent.Category); - if (ActiveDownloadClients.TryAdd(download.DownloadId, downloadClient)) + if (runnerState.ActiveDownloadClients.TryAdd(download.DownloadId, downloadClient)) { Log($"Starting download", download, torrent); @@ -573,7 +573,7 @@ public class TorrentRunner( await downloads.UpdateRemoteId(download.DownloadId, remoteId); } - if (IsPausedForLowDiskSpace && downloadClient.Type == Data.Enums.DownloadClient.Bezzad) + if (runnerState.IsPausedForLowDiskSpace && downloadClient.Type == Data.Enums.DownloadClient.Bezzad) { logger.LogInformation($"Pausing new Bezzad download due to low disk space {download.ToLog()} {torrent.ToLog()}"); await downloadClient.Pause(); @@ -633,14 +633,14 @@ public class TorrentRunner( } // Check if we have reached the download limit, if so queue the download, but don't start it. - if (ActiveUnpackClients.Count >= settingUnpackLimit) + if (runnerState.ActiveUnpackClients.Count >= settingUnpackLimit) { Log($"Not starting unpack because there are already the max number of unpacks active", download, torrent); continue; } - if (ActiveUnpackClients.ContainsKey(download.DownloadId)) + if (runnerState.ActiveUnpackClients.ContainsKey(download.DownloadId)) { Log($"Not starting unpack because this download is already active", download, torrent); @@ -662,7 +662,7 @@ public class TorrentRunner( // Start the unpacking process var unpackClient = new UnpackClient(download, downloadPath); - if (ActiveUnpackClients.TryAdd(download.DownloadId, unpackClient)) + if (runnerState.ActiveUnpackClients.TryAdd(download.DownloadId, unpackClient)) { Log($"Starting unpack", download, torrent); @@ -720,8 +720,8 @@ public class TorrentRunner( var completePerc = 0; - var totalDownloadBytes = torrent.Downloads.Sum(m => GetStats(m.DownloadId).BytesTotal); - var totalDoneBytes = torrent.Downloads.Sum(m => GetStats(m.DownloadId).BytesDone); + var totalDownloadBytes = torrent.Downloads.Sum(m => runnerState.GetStats(m.DownloadId).BytesTotal); + var totalDoneBytes = torrent.Downloads.Sum(m => runnerState.GetStats(m.DownloadId).BytesDone); if (totalDownloadBytes > 0) { diff --git a/server/RdtClient.Service/Services/TorrentRunnerState.cs b/server/RdtClient.Service/Services/TorrentRunnerState.cs new file mode 100644 index 0000000..55f5d9e --- /dev/null +++ b/server/RdtClient.Service/Services/TorrentRunnerState.cs @@ -0,0 +1,47 @@ +using System.Collections.Concurrent; + +namespace RdtClient.Service.Services; + +public interface ITorrentRunnerState +{ + ConcurrentDictionary ActiveDownloadClients { get; } + + ConcurrentDictionary ActiveUnpackClients { get; } + + Boolean IsPausedForLowDiskSpace { get; set; } + + (Int64 Speed, Int64 BytesTotal, Int64 BytesDone) GetStats(Guid downloadId); + + void Clear(); +} + +public class TorrentRunnerState : ITorrentRunnerState +{ + public ConcurrentDictionary ActiveDownloadClients { get; } = new(); + + public ConcurrentDictionary ActiveUnpackClients { get; } = new(); + + public Boolean IsPausedForLowDiskSpace { get; set; } + + public (Int64 Speed, Int64 BytesTotal, Int64 BytesDone) GetStats(Guid downloadId) + { + if (ActiveDownloadClients.TryGetValue(downloadId, out var downloadClient)) + { + return (downloadClient.Speed, downloadClient.BytesTotal, downloadClient.BytesDone); + } + + if (ActiveUnpackClients.TryGetValue(downloadId, out var unpackClient)) + { + return (0, 100, unpackClient.Progess); + } + + return (0, 0, 0); + } + + public void Clear() + { + ActiveDownloadClients.Clear(); + ActiveUnpackClients.Clear(); + IsPausedForLowDiskSpace = false; + } +} diff --git a/server/RdtClient.Service/Services/Torrents.cs b/server/RdtClient.Service/Services/Torrents.cs index bdd34b8..1827375 100644 --- a/server/RdtClient.Service/Services/Torrents.cs +++ b/server/RdtClient.Service/Services/Torrents.cs @@ -32,7 +32,9 @@ public class Torrents( PremiumizeDebridClient premiumizeDebridClient, RealDebridDebridClient realDebridDebridClient, DebridLinkClient debridLinkClient, - TorBoxDebridClient torBoxDebridClient) + TorBoxDebridClient torBoxDebridClient, + ISettings settings, + ITorrentRunnerState runnerState) { private static readonly SemaphoreSlim RealDebridUpdateLock = new(1, 1); @@ -47,7 +49,7 @@ public class Torrents( { get { - return Settings.Get.Provider.Provider switch + return settings.Current.Provider.Provider switch { Provider.Premiumize => premiumizeDebridClient, Provider.RealDebrid => realDebridDebridClient, @@ -61,7 +63,7 @@ public class Torrents( public virtual (Int64 Speed, Int64 BytesTotal, Int64 BytesDone) GetDownloadStats(Guid downloadId) { - return TorrentRunner.GetStats(downloadId); + return runnerState.GetStats(downloadId); } public virtual async Task> Get() @@ -197,9 +199,9 @@ public class Torrents( throw new($"{ex.Message}, trying to parse {magnetLink}"); } - if (!String.IsNullOrWhiteSpace(Settings.Get.General.BannedTrackers)) + if (!String.IsNullOrWhiteSpace(settings.Current.General.BannedTrackers)) { - var bannedTrackers = Settings.Get.General.BannedTrackers.Split(','); + var bannedTrackers = settings.Current.General.BannedTrackers.Split(','); foreach (var bannedTracker in bannedTrackers) { @@ -264,9 +266,9 @@ public class Torrents( throw new($"{ex.Message}, trying to parse {fileAsBase64}"); } - if (!String.IsNullOrWhiteSpace(Settings.Get.General.BannedTrackers)) + if (!String.IsNullOrWhiteSpace(settings.Current.General.BannedTrackers)) { - var bannedTrackers = Settings.Get.General.BannedTrackers.Split(','); + var bannedTrackers = settings.Current.General.BannedTrackers.Split(','); foreach (var bannedTracker in bannedTrackers) { @@ -312,16 +314,16 @@ public class Torrents( private async Task CopyAddedTorrent(Torrent torrent) { - if (String.IsNullOrWhiteSpace(Settings.Get.General.CopyAddedTorrents) || String.IsNullOrWhiteSpace(torrent.FileOrMagnet) || String.IsNullOrWhiteSpace(torrent.RdName)) + if (String.IsNullOrWhiteSpace(settings.Current.General.CopyAddedTorrents) || String.IsNullOrWhiteSpace(torrent.FileOrMagnet) || String.IsNullOrWhiteSpace(torrent.RdName)) { return; } try { - if (!fileSystem.Directory.Exists(Settings.Get.General.CopyAddedTorrents)) + if (!fileSystem.Directory.Exists(settings.Current.General.CopyAddedTorrents)) { - fileSystem.Directory.CreateDirectory(Settings.Get.General.CopyAddedTorrents); + fileSystem.Directory.CreateDirectory(settings.Current.General.CopyAddedTorrents); } var extension = torrent.Type switch @@ -331,7 +333,7 @@ public class Torrents( _ => throw new ArgumentException("Unexpected DownloadType") }; - var copyFileName = Path.Combine(Settings.Get.General.CopyAddedTorrents, FileHelper.RemoveInvalidFileNameChars(torrent.RdName)); + var copyFileName = Path.Combine(settings.Current.General.CopyAddedTorrents, FileHelper.RemoveInvalidFileNameChars(torrent.RdName)); if (!copyFileName.EndsWith(extension, StringComparison.OrdinalIgnoreCase)) { @@ -355,7 +357,7 @@ public class Torrents( } catch (Exception ex) { - logger.LogError(ex, $"Unable to create torrent blackhole directory: {Settings.Get.General.CopyAddedTorrents}: {ex.Message}"); + logger.LogError(ex, $"Unable to create torrent blackhole directory: {settings.Current.General.CopyAddedTorrents}: {ex.Message}"); } } @@ -511,7 +513,7 @@ public class Torrents( { var retry = 10; - while (TorrentRunner.ActiveDownloadClients.TryGetValue(download.DownloadId, out var downloadClient)) + while (runnerState.ActiveDownloadClients.TryGetValue(download.DownloadId, out var downloadClient)) { Log($"Cancelling download", download, torrent); @@ -529,7 +531,7 @@ public class Torrents( retry = 10; - while (TorrentRunner.ActiveUnpackClients.TryGetValue(download.DownloadId, out var unpackClient)) + while (runnerState.ActiveUnpackClients.TryGetValue(download.DownloadId, out var unpackClient)) { Log($"Cancelling unpack", download, torrent); @@ -569,7 +571,7 @@ public class Torrents( if (deleteLocalFiles && !String.IsNullOrWhiteSpace(torrent.RdName)) { - var downloadPath = DownloadPath(torrent, Settings.Get); + var downloadPath = DownloadPath(torrent, settings.Current); downloadPath = Path.Combine(downloadPath, torrent.RdName); Log($"Deleting local files in {downloadPath}", torrent); @@ -634,13 +636,13 @@ public class Torrents( var profile = new Profile { - Provider = Enum.GetName(Settings.Get.Provider.Provider), + Provider = Enum.GetName(settings.Current.Provider.Provider), UserName = user.Username, Expiration = user.Expiration, CurrentVersion = UpdateChecker.CurrentVersion, LatestVersion = UpdateChecker.LatestVersion, IsInsecure = UpdateChecker.IsInsecure, - DisableUpdateNotification = Settings.Get.General.DisableUpdateNotifications + DisableUpdateNotification = settings.Current.General.DisableUpdateNotifications }; return profile; @@ -663,25 +665,25 @@ public class Torrents( torrentsByRdId.TryGetValue(rdTorrent.Id, out var torrent); // Auto import torrents only torrents that have their files selected - if (torrent == null && Settings.Get.Provider.AutoImport) + if (torrent == null && settings.Current.Provider.AutoImport) { var newTorrent = new Torrent { - Category = Settings.Get.Provider.Default.Category, - DownloadClient = Settings.Get.DownloadClient.Client, + Category = settings.Current.Provider.Default.Category, + DownloadClient = settings.Current.DownloadClient.Client, DownloadAction = - Settings.Get.Provider.Default.OnlyDownloadAvailableFiles ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll, - HostDownloadAction = Settings.Get.Provider.Default.HostDownloadAction, - FinishedActionDelay = Settings.Get.Provider.Default.FinishedActionDelay, - FinishedAction = Settings.Get.Provider.Default.FinishedAction, - DownloadMinSize = Settings.Get.Provider.Default.MinFileSize, - IncludeRegex = Settings.Get.Provider.Default.IncludeRegex, - ExcludeRegex = Settings.Get.Provider.Default.ExcludeRegex, - TorrentRetryAttempts = Settings.Get.Provider.Default.TorrentRetryAttempts, - DownloadRetryAttempts = Settings.Get.Provider.Default.DownloadRetryAttempts, - DeleteOnError = Settings.Get.Provider.Default.DeleteOnError, - Lifetime = Settings.Get.Provider.Default.TorrentLifetime, - Priority = Settings.Get.Provider.Default.Priority > 0 ? Settings.Get.Provider.Default.Priority : null, + settings.Current.Provider.Default.OnlyDownloadAvailableFiles ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll, + HostDownloadAction = settings.Current.Provider.Default.HostDownloadAction, + FinishedActionDelay = settings.Current.Provider.Default.FinishedActionDelay, + FinishedAction = settings.Current.Provider.Default.FinishedAction, + DownloadMinSize = settings.Current.Provider.Default.MinFileSize, + IncludeRegex = settings.Current.Provider.Default.IncludeRegex, + ExcludeRegex = settings.Current.Provider.Default.ExcludeRegex, + TorrentRetryAttempts = settings.Current.Provider.Default.TorrentRetryAttempts, + DownloadRetryAttempts = settings.Current.Provider.Default.DownloadRetryAttempts, + DeleteOnError = settings.Current.Provider.Default.DeleteOnError, + Lifetime = settings.Current.Provider.Default.TorrentLifetime, + Priority = settings.Current.Provider.Default.Priority > 0 ? settings.Current.Provider.Default.Priority : null, RdId = rdTorrent.Id }; @@ -690,7 +692,7 @@ public class Torrents( continue; } - torrent = await torrentData.Add(rdTorrent.Id, rdTorrent.Hash, null, false, DownloadType.Torrent, Settings.Get.DownloadClient.Client, newTorrent); + torrent = await torrentData.Add(rdTorrent.Id, rdTorrent.Hash, null, false, DownloadType.Torrent, settings.Current.DownloadClient.Client, newTorrent); torrentsByRdId[rdTorrent.Id] = torrent; torrents.Add(torrent); @@ -706,7 +708,7 @@ public class Torrents( { var rdTorrent = torrent.RdId != null && providerTorrentsById.TryGetValue(torrent.RdId, out var providerTorrent) ? providerTorrent : null; - if (rdTorrent == null && Settings.Get.Provider.AutoDelete && torrent.RdStatus != TorrentStatus.Queued) + if (rdTorrent == null && settings.Current.Provider.AutoDelete && torrent.RdStatus != TorrentStatus.Queued) { await Delete(torrent.TorrentId, true, false, true); } @@ -744,14 +746,14 @@ public class Torrents( foreach (var download in torrent.Downloads) { - while (TorrentRunner.ActiveDownloadClients.TryRemove(download.DownloadId, out var downloadClient)) + while (runnerState.ActiveDownloadClients.TryRemove(download.DownloadId, out var downloadClient)) { await downloadClient.Cancel(); await Task.Delay(100); } - while (TorrentRunner.ActiveUnpackClients.TryRemove(download.DownloadId, out var unpackClient)) + while (runnerState.ActiveUnpackClients.TryRemove(download.DownloadId, out var unpackClient)) { unpackClient.Cancel(); @@ -814,21 +816,21 @@ public class Torrents( Log($"Retrying Download", download, download.Torrent); - while (TorrentRunner.ActiveDownloadClients.TryRemove(download.DownloadId, out var downloadClient)) + while (runnerState.ActiveDownloadClients.TryRemove(download.DownloadId, out var downloadClient)) { await downloadClient.Cancel(); await Task.Delay(100); } - while (TorrentRunner.ActiveUnpackClients.TryRemove(download.DownloadId, out var unpackClient)) + while (runnerState.ActiveUnpackClients.TryRemove(download.DownloadId, out var unpackClient)) { unpackClient.Cancel(); await Task.Delay(100); } - var downloadPath = DownloadPath(download.Torrent!, Settings.Get); + var downloadPath = DownloadPath(download.Torrent!, settings.Current); var filePath = DownloadHelper.GetDownloadPath(downloadPath, download.Torrent!, download); @@ -970,11 +972,11 @@ public class Torrents( await torrentData.Update(torrent); } - public async Task RunTorrentComplete(Guid torrentId, DbSettings? settings = null) + public async Task RunTorrentComplete(Guid torrentId, DbSettings? runSettings = null) { - settings ??= Settings.Get; + runSettings ??= settings.Current; - if (String.IsNullOrWhiteSpace(settings.General.RunOnTorrentCompleteFileName)) + if (String.IsNullOrWhiteSpace(runSettings.General.RunOnTorrentCompleteFileName)) { return; } @@ -983,12 +985,12 @@ public class Torrents( var downloadsForTorrent = await downloads.GetForTorrent(torrentId); - var fileName = settings.General.RunOnTorrentCompleteFileName; - var arguments = settings.General.RunOnTorrentCompleteArguments ?? ""; + var fileName = runSettings.General.RunOnTorrentCompleteFileName; + var arguments = runSettings.General.RunOnTorrentCompleteArguments ?? ""; Log($"Parsing external program {fileName} with arguments {arguments}", torrent); - var downloadPath = DownloadPath(torrent, settings); + var downloadPath = DownloadPath(torrent, runSettings); var torrentPath = Path.Combine(downloadPath, torrent.RdName ?? "Unknown"); var filePath = torrentPath; diff --git a/server/RdtClient.Web.Test/Controllers/QBittorrentControllerTest.cs b/server/RdtClient.Web.Test/Controllers/QBittorrentControllerTest.cs index 9e43df1..6784884 100644 --- a/server/RdtClient.Web.Test/Controllers/QBittorrentControllerTest.cs +++ b/server/RdtClient.Web.Test/Controllers/QBittorrentControllerTest.cs @@ -12,15 +12,18 @@ public class QBittorrentControllerTest { private readonly QBittorrentController _controller; private readonly Mock _qBittorrentMock; + private readonly TestSettings _settings; public QBittorrentControllerTest() { - _qBittorrentMock = new(new Mock>().Object, null!, null!, null!, null!); + _settings = new(); + _qBittorrentMock = new(new Mock>().Object, _settings, null!, null!, null!, new TorrentRunnerState()); _controller = new( new Mock>().Object, _qBittorrentMock.Object, - new Mock().Object); + new Mock().Object, + _settings); _controller.ControllerContext = new() { @@ -88,4 +91,4 @@ public class QBittorrentControllerTest Assert.Single(payload); Assert.Equal("hash1", payload[0].Hash); } -} \ No newline at end of file +} diff --git a/server/RdtClient.Web.Test/Controllers/SabnzbdControllerTest.cs b/server/RdtClient.Web.Test/Controllers/SabnzbdControllerTest.cs index 4f3a5a1..4a1a52b 100644 --- a/server/RdtClient.Web.Test/Controllers/SabnzbdControllerTest.cs +++ b/server/RdtClient.Web.Test/Controllers/SabnzbdControllerTest.cs @@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Moq; -using RdtClient.Data.Data; using RdtClient.Data.Enums; using RdtClient.Data.Models.Sabnzbd; using RdtClient.Service.Services; @@ -17,15 +16,17 @@ public class SabnzbdControllerTest private readonly Mock _authenticationMock; private readonly SabnzbdController _controller; private readonly Mock _sabnzbdMock; + private readonly TestSettings _settings; public SabnzbdControllerTest() { - SettingData.Get.General.AuthenticationType = AuthenticationType.None; - SettingData.Get.Provider.ApiKey = "test-api-key"; + _settings = new(); + _settings.Current.General.AuthenticationType = AuthenticationType.None; + _settings.Current.Provider.ApiKey = "test-api-key"; - var torrentsMock = new Mock(null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!); + var torrentsMock = new Mock(null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, _settings, new TorrentRunnerState()); var sabnzbdLoggerMock = new Mock>(); - _sabnzbdMock = new(sabnzbdLoggerMock.Object, torrentsMock.Object, null!); + _sabnzbdMock = new(sabnzbdLoggerMock.Object, torrentsMock.Object, null!, _settings); var loggerMock = new Mock>(); _authenticationMock = new(null!, null!, null!); @@ -64,7 +65,7 @@ public class SabnzbdControllerTest public async Task GetQueue_Unauthorized_ReturnsOk_BecauseFilterIsSkippedInUnitTests() { // Arrange - SettingData.Get.General.AuthenticationType = AuthenticationType.UserNamePassword; + _settings.Current.General.AuthenticationType = AuthenticationType.UserNamePassword; var queue = new SabnzbdQueue { @@ -86,7 +87,7 @@ public class SabnzbdControllerTest public async Task GetQueue_WithMaAuth_ReturnsOk() { // Arrange - SettingData.Get.General.AuthenticationType = AuthenticationType.UserNamePassword; + _settings.Current.General.AuthenticationType = AuthenticationType.UserNamePassword; var httpContext = new DefaultHttpContext(); httpContext.Request.QueryString = new("?ma_username=user&ma_password=pass"); _controller.ControllerContext.HttpContext = httpContext; @@ -146,7 +147,7 @@ public class SabnzbdControllerTest public void GetVersion_ReturnsOk() { // Arrange - SettingData.Get.General.AuthenticationType = AuthenticationType.UserNamePassword; + _settings.Current.General.AuthenticationType = AuthenticationType.UserNamePassword; // Act var result = _controller.Version(); diff --git a/server/RdtClient.Web.Test/Controllers/SabnzbdHandlerTest.cs b/server/RdtClient.Web.Test/Controllers/SabnzbdHandlerTest.cs index e2e23f5..313427b 100644 --- a/server/RdtClient.Web.Test/Controllers/SabnzbdHandlerTest.cs +++ b/server/RdtClient.Web.Test/Controllers/SabnzbdHandlerTest.cs @@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Moq; -using RdtClient.Data.Data; using RdtClient.Data.Enums; using RdtClient.Service.Middleware; using RdtClient.Service.Services; @@ -15,20 +14,22 @@ public class SabnzbdHandlerTest private readonly Mock _authenticationMock; private readonly SabnzbdHandler _handler; private readonly Mock _httpContextAccessorMock; + private readonly TestSettings _settings; public SabnzbdHandlerTest() { _authenticationMock = new(null!, null!, null!); _httpContextAccessorMock = new(); - _handler = new(_authenticationMock.Object, _httpContextAccessorMock.Object); - SettingData.Get.General.AuthenticationType = AuthenticationType.UserNamePassword; + _settings = new(); + _handler = new(_authenticationMock.Object, _httpContextAccessorMock.Object, _settings); + _settings.Current.General.AuthenticationType = AuthenticationType.UserNamePassword; } [Fact] public async Task HandleAsync_AuthNone_Succeeds() { // Arrange - SettingData.Get.General.AuthenticationType = AuthenticationType.None; + _settings.Current.General.AuthenticationType = AuthenticationType.None; var context = CreateContext(); // Act @@ -42,7 +43,7 @@ public class SabnzbdHandlerTest public async Task HandleAsync_ValidCredentials_Succeeds() { // Arrange - Settings.Get.General.AuthenticationType = AuthenticationType.UserNamePassword; + _settings.Current.General.AuthenticationType = AuthenticationType.UserNamePassword; var httpContext = new DefaultHttpContext { Request = @@ -67,7 +68,7 @@ public class SabnzbdHandlerTest public async Task HandleAsync_AlreadyAuthenticated_Succeeds() { // Arrange - Settings.Get.General.AuthenticationType = AuthenticationType.UserNamePassword; + _settings.Current.General.AuthenticationType = AuthenticationType.UserNamePassword; var httpContext = new DefaultHttpContext(); var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity("TestAuth")); httpContext.User = claimsPrincipal; @@ -86,7 +87,7 @@ public class SabnzbdHandlerTest public async Task HandleAsync_InvalidCredentials_DoesNotSucceed() { // Arrange - Settings.Get.General.AuthenticationType = AuthenticationType.UserNamePassword; + _settings.Current.General.AuthenticationType = AuthenticationType.UserNamePassword; var httpContext = new DefaultHttpContext { Request = @@ -111,7 +112,7 @@ public class SabnzbdHandlerTest public async Task HandleAsync_MissingCredentials_DoesNotSucceed() { // Arrange - Settings.Get.General.AuthenticationType = AuthenticationType.UserNamePassword; + _settings.Current.General.AuthenticationType = AuthenticationType.UserNamePassword; var httpContext = new DefaultHttpContext(); _httpContextAccessorMock.Setup(a => a.HttpContext).Returns(httpContext); diff --git a/server/RdtClient.Web.Test/Controllers/TorrentsControllerNzbTest.cs b/server/RdtClient.Web.Test/Controllers/TorrentsControllerNzbTest.cs index 17adbdf..5466dbb 100644 --- a/server/RdtClient.Web.Test/Controllers/TorrentsControllerNzbTest.cs +++ b/server/RdtClient.Web.Test/Controllers/TorrentsControllerNzbTest.cs @@ -17,7 +17,7 @@ public class TorrentsControllerNzbTest public TorrentsControllerNzbTest() { - _torrentsMock = new(null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!); + _torrentsMock = new(null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, new TestSettings(), new TorrentRunnerState()); _loggerMock = new(); _coordinatorMock = new(); _controller = new(_loggerMock.Object, _torrentsMock.Object, null!, _coordinatorMock.Object); diff --git a/server/RdtClient.Web.Test/GlobalTestConfig.cs b/server/RdtClient.Web.Test/GlobalTestConfig.cs deleted file mode 100644 index 2171200..0000000 --- a/server/RdtClient.Web.Test/GlobalTestConfig.cs +++ /dev/null @@ -1,3 +0,0 @@ -using Xunit; - -[assembly: CollectionBehavior(DisableTestParallelization = true)] diff --git a/server/RdtClient.Web.Test/RdtClient.Web.Test.csproj b/server/RdtClient.Web.Test/RdtClient.Web.Test.csproj index 7cf368c..4190fa9 100644 --- a/server/RdtClient.Web.Test/RdtClient.Web.Test.csproj +++ b/server/RdtClient.Web.Test/RdtClient.Web.Test.csproj @@ -5,6 +5,7 @@ enable enable false + true RdtClient.Web.Test RdtClient.Web.Test diff --git a/server/RdtClient.Web.Test/TestSettings.cs b/server/RdtClient.Web.Test/TestSettings.cs new file mode 100644 index 0000000..7ffc2ea --- /dev/null +++ b/server/RdtClient.Web.Test/TestSettings.cs @@ -0,0 +1,58 @@ +using RdtClient.Data.Models.Internal; + +namespace RdtClient.Service.Services; + +internal sealed class TestSettings(DbSettings? settings = null) : ISettings +{ + public DbSettings Current { get; } = settings ?? new(); + + public String DefaultSavePath + { + get + { + var downloadPath = Current.DownloadClient.MappedPath.TrimEnd('\\').TrimEnd('/'); + + return downloadPath + Path.DirectorySeparatorChar; + } + } + + public IList GetAll() + { + return []; + } + + public Task Update(IList settings) + { + return Task.CompletedTask; + } + + public Task Update(String settingId, Object? value) + { + SetValue(Current, settingId.Split(':'), 0, value); + + return Task.CompletedTask; + } + + private static void SetValue(Object target, IReadOnlyList path, Int32 index, Object? value) + { + var property = target.GetType().GetProperty(path[index]) ?? throw new($"Unknown setting {String.Join(":", path)}"); + + if (index < path.Count - 1) + { + SetValue(property.GetValue(target)!, path, index + 1, value); + + return; + } + + if (value == null) + { + property.SetValue(target, null); + + return; + } + + var propertyType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType; + var convertedValue = propertyType.IsEnum ? Enum.Parse(propertyType, value.ToString()!) : Convert.ChangeType(value, propertyType); + property.SetValue(target, convertedValue); + } +} diff --git a/server/RdtClient.Web/Controllers/AuthController.cs b/server/RdtClient.Web/Controllers/AuthController.cs index 5e5d8de..093bff4 100644 --- a/server/RdtClient.Web/Controllers/AuthController.cs +++ b/server/RdtClient.Web/Controllers/AuthController.cs @@ -6,14 +6,14 @@ using RdtClient.Service.Services; namespace RdtClient.Web.Controllers; [Route("Api/Authentication")] -public class AuthController(Authentication authentication, Settings settings) : Controller +public class AuthController(Authentication authentication, ISettings settings) : Controller { [AllowAnonymous] [Route("IsLoggedIn")] [HttpGet] public async Task IsLoggedIn() { - if (Settings.Get.General.AuthenticationType == AuthenticationType.None) + if (settings.Current.General.AuthenticationType == AuthenticationType.None) { return Ok(); } @@ -77,7 +77,7 @@ public class AuthController(Authentication authentication, Settings settings) : return BadRequest(); } - if (!String.IsNullOrEmpty(Settings.Get.Provider.ApiKey)) + if (!String.IsNullOrEmpty(settings.Current.Provider.ApiKey)) { return StatusCode(401); } diff --git a/server/RdtClient.Web/Controllers/QBittorrentController.cs b/server/RdtClient.Web/Controllers/QBittorrentController.cs index 110e775..06034c0 100644 --- a/server/RdtClient.Web/Controllers/QBittorrentController.cs +++ b/server/RdtClient.Web/Controllers/QBittorrentController.cs @@ -14,7 +14,7 @@ namespace RdtClient.Web.Controllers; [ApiController] [Route("api/v2")] [Route("qbittorrent/api/v2")] -public class QBittorrentController(ILogger logger, QBittorrent qBittorrent, IHttpClientFactory httpClientFactory) : Controller +public class QBittorrentController(ILogger logger, QBittorrent qBittorrent, IHttpClientFactory httpClientFactory, ISettings settings) : Controller { [AllowAnonymous] [Route("/version/api")] @@ -33,7 +33,7 @@ public class QBittorrentController(ILogger logger, QBitto { logger.LogDebug($"Auth login"); - if (Settings.Get.General.AuthenticationType == AuthenticationType.None) + if (settings.Current.General.AuthenticationType == AuthenticationType.None) { return Content("Ok.", "text/plain"); } @@ -146,7 +146,7 @@ public class QBittorrentController(ILogger logger, QBitto [HttpPost] public ActionResult AppDefaultSavePath() { - var result = Settings.AppDefaultSavePath; + var result = settings.DefaultSavePath; return Ok(result); } @@ -613,7 +613,7 @@ public class QBittorrentController(ILogger logger, QBitto [HttpGet] public ActionResult TransferInfo() { - return Ok(QBittorrent.TransferInfo()); + return Ok(qBittorrent.TransferInfo()); } [Authorize(Policy = "AuthSetting")] diff --git a/server/RdtClient.Web/Controllers/SettingsController.cs b/server/RdtClient.Web/Controllers/SettingsController.cs index 548861f..5e58296 100644 --- a/server/RdtClient.Web/Controllers/SettingsController.cs +++ b/server/RdtClient.Web/Controllers/SettingsController.cs @@ -15,13 +15,13 @@ namespace RdtClient.Web.Controllers; [Authorize(Policy = "AuthSetting")] [Route("Api/Settings")] -public class SettingsController(Settings settings, Torrents torrents) : Controller +public class SettingsController(ISettings settings, Torrents torrents) : Controller { [HttpGet] [Route("")] public ActionResult Get() { - var result = SettingData.GetAll(); + var result = settings.GetAll(); return Ok(result); } @@ -95,7 +95,7 @@ public class SettingsController(Settings settings, Torrents torrents) : Controll [Route("TestDownloadSpeed")] public async Task TestDownloadSpeed(CancellationToken cancellationToken) { - var downloadPath = Settings.Get.DownloadClient.DownloadPath; + var downloadPath = settings.Current.DownloadClient.DownloadPath; var testFilePath = Path.Combine(downloadPath, "testDefault.rar"); @@ -106,7 +106,7 @@ public class SettingsController(Settings settings, Torrents torrents) : Controll Link = "https://34.download.real-debrid.com/speedtest/testDefault.rar", Torrent = new() { - DownloadClient = Settings.Get.DownloadClient.Client == DownloadClient.Symlink ? DownloadClient.Bezzad : Settings.Get.DownloadClient.Client, + DownloadClient = settings.Current.DownloadClient.Client == DownloadClient.Symlink ? DownloadClient.Bezzad : settings.Current.DownloadClient.Client, RdName = "testDefault.rar" } }; @@ -131,7 +131,7 @@ public class SettingsController(Settings settings, Torrents torrents) : Controll if (downloadClient.Downloader is Aria2cDownloader aria2Downloader) { - var aria2NetClient = new Aria2NetClient(Settings.Get.DownloadClient.Aria2cUrl, Settings.Get.DownloadClient.Aria2cSecret, httpClient, 1); + var aria2NetClient = new Aria2NetClient(settings.Current.DownloadClient.Aria2cUrl, settings.Current.DownloadClient.Aria2cSecret, httpClient, 1); var allDownloads = await aria2NetClient.TellAllAsync(cancellationToken); @@ -155,7 +155,7 @@ public class SettingsController(Settings settings, Torrents torrents) : Controll [Route("TestWriteSpeed")] public async Task TestWriteSpeed() { - var downloadPath = Settings.Get.DownloadClient.DownloadPath; + var downloadPath = settings.Current.DownloadClient.DownloadPath; var testFilePath = Path.Combine(downloadPath, "test.tmp");