diff --git a/client/src/app/navbar/settings/settings.component.html b/client/src/app/navbar/settings/settings.component.html index 875831a..42d6c90 100644 --- a/client/src/app/navbar/settings/settings.component.html +++ b/client/src/app/navbar/settings/settings.component.html @@ -17,6 +17,7 @@ >.

+
@@ -24,6 +25,7 @@

Path in the docker container to download files to (i.e. /data/downloads).

+
@@ -34,6 +36,18 @@ to find your downloads.

+ +
+ +
+ +
+

+ Path in the docker container to temporarily download to (i.e. /data/temp). Make sure the docker container has + enough disk space if using a path inside the container. +

+
+
@@ -41,6 +55,26 @@

Maximum amount of torrents that get downloaded to your host at the same time.

+ +
+ +
+ +
+

+ Maximum amount of parallel threads that are used to download a single torrent to your host. If set to 1 no + parallel downloading will be done. +

+
+ +
+ +
+ +
+

Maximum download speed in Megabytes per second. When set to 0 unlimited speed is used.

+
+
diff --git a/client/src/app/navbar/settings/settings.component.ts b/client/src/app/navbar/settings/settings.component.ts index dbd7efd..42a8b52 100644 --- a/client/src/app/navbar/settings/settings.component.ts +++ b/client/src/app/navbar/settings/settings.component.ts @@ -38,7 +38,10 @@ export class SettingsComponent implements OnInit { public settingRealDebridApiKey: string; public settingDownloadPath: string; public settingMappedPath: string; + public settingTempPath: string; public settingDownloadLimit: number; + public settingDownloadChunkCount: number; + public settingDownloadMaxSpeed: number; public settingUnpackLimit: number; public settingMinFileSize: number; @@ -55,7 +58,10 @@ export class SettingsComponent implements OnInit { this.settingRealDebridApiKey = this.getSetting(results, 'RealDebridApiKey'); this.settingDownloadPath = this.getSetting(results, 'DownloadPath'); this.settingMappedPath = this.getSetting(results, 'MappedPath'); + this.settingTempPath = this.getSetting(results, 'TempPath'); this.settingDownloadLimit = parseInt(this.getSetting(results, 'DownloadLimit'), 10); + this.settingDownloadChunkCount = parseInt(this.getSetting(results, 'DownloadChunkCount'), 10); + this.settingDownloadMaxSpeed = parseInt(this.getSetting(results, 'DownloadMaxSpeed'), 10); this.settingUnpackLimit = parseInt(this.getSetting(results, 'UnpackLimit'), 10); this.settingMinFileSize = parseInt(this.getSetting(results, 'MinFileSize'), 10); }, @@ -82,10 +88,22 @@ export class SettingsComponent implements OnInit { settingId: 'MappedPath', value: this.settingMappedPath, }, + { + settingId: 'TempPath', + value: this.settingTempPath, + }, { settingId: 'DownloadLimit', value: (this.settingDownloadLimit ?? 10).toString(), }, + { + settingId: 'DownloadChunkCount', + value: (this.settingDownloadChunkCount ?? 8).toString(), + }, + { + settingId: 'DownloadMaxSpeed', + value: (this.settingDownloadMaxSpeed ?? 0).toString(), + }, { settingId: 'UnpackLimit', value: (this.settingUnpackLimit ?? 1).toString(), diff --git a/server/RdtClient.Data/Data/DataContext.cs b/server/RdtClient.Data/Data/DataContext.cs index 4e014e7..9380ca4 100644 --- a/server/RdtClient.Data/Data/DataContext.cs +++ b/server/RdtClient.Data/Data/DataContext.cs @@ -57,6 +57,16 @@ namespace RdtClient.Data.Data #endif }, new Setting + { + SettingId = "TempPath", + Type = "String", +#if DEBUG + Value = @"C:\Temp\rdtclient" +#else + Value = "/data/downloads" +#endif + }, + new Setting { SettingId = "MappedPath", Type = "String", @@ -83,6 +93,18 @@ namespace RdtClient.Data.Data SettingId = "MinFileSize", Type = "Int32", Value = "0" + }, + new Setting + { + SettingId = "DownloadChunkCount", + Type = "Int32", + Value = "8" + }, + new Setting + { + SettingId = "DownloadMaxSpeed", + Type = "Int32", + Value = "0" } }; diff --git a/server/RdtClient.Service/Helpers/SettingsHelper.cs b/server/RdtClient.Service/Helpers/SettingsHelper.cs new file mode 100644 index 0000000..b9c0459 --- /dev/null +++ b/server/RdtClient.Service/Helpers/SettingsHelper.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using RdtClient.Data.Models.Data; + +namespace RdtClient.Service.Helpers +{ + public static class SettingsHelper + { + public static String GetString(this IList settings, String key) + { + var setting = settings.FirstOrDefault(m => m.SettingId == key); + + if (setting == null) + { + throw new Exception($"Setting with key {key} not found"); + } + + return setting.Value; + } + + public static Int32 GetNumber(this IList settings, String key) + { + var setting = settings.FirstOrDefault(m => m.SettingId == key); + + if (setting == null) + { + throw new Exception($"Setting with key {key} not found"); + } + + return Int32.Parse(setting.Value); + } + } +} diff --git a/server/RdtClient.Service/Services/DownloadClient.cs b/server/RdtClient.Service/Services/DownloadClient.cs index b5e3dd1..ecc3ba3 100644 --- a/server/RdtClient.Service/Services/DownloadClient.cs +++ b/server/RdtClient.Service/Services/DownloadClient.cs @@ -34,9 +34,9 @@ namespace RdtClient.Service.Services public Int64 BytesDone { get; private set; } private static Int64 LastTick { get; set; } - private static ConcurrentBag AverageSpeed { get; } = new ConcurrentBag(); + private static ConcurrentBag AverageSpeed { get; } = new ConcurrentBag(); - public async Task Start(Boolean writeToMemory) + public async Task Start(Boolean onTheFlyDownload, String tempDirectory, Int32 chunkCount, Int64 maximumBytesPerSecond) { BytesDone = 0; BytesTotal = 0; @@ -69,7 +69,7 @@ namespace RdtClient.Service.Services await Task.Factory.StartNew(async delegate { - await Download(filePath, writeToMemory); + await Download(filePath, onTheFlyDownload, tempDirectory, chunkCount, maximumBytesPerSecond); }); } catch (Exception ex) @@ -84,7 +84,7 @@ namespace RdtClient.Service.Services _downloader?.CancelAsync(); } - private async Task Download(String filePath, Boolean writeToMemory) + private async Task Download(String filePath, Boolean onTheFlyDownload, String tempDirectory, Int32 chunkCount, Int64 maximumBytesPerSecond) { try { @@ -93,13 +93,13 @@ namespace RdtClient.Service.Services var downloadOpt = new DownloadConfiguration { MaxTryAgainOnFailover = Int32.MaxValue, - ParallelDownload = true, - ChunkCount = 8, - Timeout = 100, - OnTheFlyDownload = writeToMemory, + ParallelDownload = chunkCount > 1, + ChunkCount = chunkCount, + Timeout = 1000, + OnTheFlyDownload = onTheFlyDownload, BufferBlockSize = 1024 * 8, - MaximumBytesPerSecond = 100 * 1024 * 1024, - TempDirectory = @"C:\temp", + MaximumBytesPerSecond = maximumBytesPerSecond, + TempDirectory = tempDirectory, RequestConfiguration = { Accept = "*/*", @@ -124,7 +124,7 @@ namespace RdtClient.Service.Services } Speed = (Int64) AverageSpeed.Average(); - BytesDone = args.BytesReceived; + BytesDone = args.ReceivedBytesSize; BytesTotal = args.TotalBytesToReceive; }; diff --git a/server/RdtClient.Service/Services/Settings.cs b/server/RdtClient.Service/Services/Settings.cs index 9606a99..9d0d54d 100644 --- a/server/RdtClient.Service/Services/Settings.cs +++ b/server/RdtClient.Service/Services/Settings.cs @@ -90,6 +90,7 @@ namespace RdtClient.Service.Services public async Task TestDownloadSpeed(CancellationToken cancellationToken) { var downloadPath = await GetString("DownloadPath"); + var tempPath = await GetString("TempPath"); var testFilePath = Path.Combine(downloadPath, "testDefault.rar"); @@ -109,10 +110,11 @@ namespace RdtClient.Service.Services var downloadClient = new DownloadClient(download, downloadPath); - await downloadClient.Start(true); + await downloadClient.Start(false, tempPath, 8, 0); while (!downloadClient.Finished) { + // ReSharper disable once MethodSupportsCancellation await Task.Delay(1000); if (cancellationToken.IsCancellationRequested) @@ -120,7 +122,7 @@ namespace RdtClient.Service.Services downloadClient.Cancel(); } - if (downloadClient.BytesDone > 1024 * 1024 * 100) + if (downloadClient.BytesDone > 1024 * 1024 * 50) { downloadClient.Cancel(); } @@ -131,6 +133,13 @@ namespace RdtClient.Service.Services File.Delete(testFilePath); } + var files = Directory.GetFiles(tempPath, "*.dsc", SearchOption.TopDirectoryOnly); + + foreach (var file in files) + { + File.Delete(file); + } + return downloadClient.Speed; } diff --git a/server/RdtClient.Service/Services/TorrentRunner.cs b/server/RdtClient.Service/Services/TorrentRunner.cs index 6478028..6ee9c14 100644 --- a/server/RdtClient.Service/Services/TorrentRunner.cs +++ b/server/RdtClient.Service/Services/TorrentRunner.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; using RdtClient.Data.Enums; +using RdtClient.Service.Helpers; namespace RdtClient.Service.Services { @@ -61,19 +62,59 @@ namespace RdtClient.Service.Services public async Task Tick() { - var settingApiKey = await _settings.GetString("RealDebridApiKey"); - var settingMinFileSize = await _settings.GetNumber("MinFileSize"); - var settingDownloadLimit = await _settings.GetNumber("DownloadLimit"); - var settingUnpackLimit = await _settings.GetNumber("UnpackLimit"); - var settingDownloadPath = await _settings.GetString("DownloadPath"); + var settings = await _settings.GetAll(); - settingMinFileSize = settingMinFileSize * 1024 * 1024; - + var settingApiKey = settings.GetString("RealDebridApiKey"); if (String.IsNullOrWhiteSpace(settingApiKey)) { return; } + var settingMinFileSize = settings.GetNumber("MinFileSize"); + if (settingMinFileSize <= 0) + { + settingMinFileSize = 0; + } + + settingMinFileSize = settingMinFileSize * 1024 * 1024; + + var settingDownloadLimit = settings.GetNumber("DownloadLimit"); + if (settingDownloadLimit < 1) + { + settingDownloadLimit = 1; + } + + var settingUnpackLimit = settings.GetNumber("UnpackLimit"); + if (settingUnpackLimit < 1) + { + settingUnpackLimit = 1; + } + + var settingDownloadPath = settings.GetString("DownloadPath"); + if (String.IsNullOrWhiteSpace(settingDownloadPath)) + { + return; + } + + var settingTempPath = settings.GetString("TempPath"); + if (String.IsNullOrWhiteSpace(settingTempPath)) + { + settingTempPath = Path.GetTempPath(); + } + + var settingDownloadChunkCount = settings.GetNumber("DownloadChunkCount"); + if (settingDownloadChunkCount <= 0) + { + settingDownloadChunkCount = 1; + } + + var settingDownloadMaxSpeed = settings.GetNumber("DownloadMaxSpeed"); + if (settingDownloadMaxSpeed <= 0) + { + settingDownloadMaxSpeed = 0; + } + settingDownloadMaxSpeed = settingDownloadMaxSpeed * 1024 * 1024; + // 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(); @@ -172,7 +213,7 @@ namespace RdtClient.Service.Services if (TorrentRunner.ActiveDownloadClients.TryAdd(download.DownloadId, downloadClient)) { - await downloadClient.Start(false); + await downloadClient.Start(false, settingTempPath, settingDownloadChunkCount, settingDownloadMaxSpeed); } }