diff --git a/server/RdtClient.Service.Test/Services/SabnzbdTest.cs b/server/RdtClient.Service.Test/Services/SabnzbdTest.cs index 85ddcee..de8dd1a 100644 --- a/server/RdtClient.Service.Test/Services/SabnzbdTest.cs +++ b/server/RdtClient.Service.Test/Services/SabnzbdTest.cs @@ -40,6 +40,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); diff --git a/server/RdtClient.Service/Services/QBittorrent.cs b/server/RdtClient.Service/Services/QBittorrent.cs index f65a013..028058e 100644 --- a/server/RdtClient.Service/Services/QBittorrent.cs +++ b/server/RdtClient.Service/Services/QBittorrent.cs @@ -223,29 +223,28 @@ public class QBittorrent(ILogger logger, Settings settings, Authent var speed = torrent.RdSpeed ?? 0; var bytesDone = (Int64)(bytesTotal * rdProgress); - Double downloadProgress = 0; - + Double progress; if (torrent.Downloads is { Count: > 0 }) { - var dlBytesDone = torrent.Downloads.Sum(m => m.BytesDone); - var dlBytesTotal = torrent.Downloads.Sum(m => m.BytesTotal); - speed = (Int32)torrent.Downloads.Average(m => m.Speed); - downloadProgress = bytesTotal > 0 ? Math.Clamp((Double)dlBytesDone / dlBytesTotal, 0.0, 1.0) : 0; + var dlStats = torrent.Downloads.Select(m => torrents.GetDownloadStats(m.DownloadId)).ToList(); + var dlBytesDone = dlStats.Sum(m => m.BytesDone); + var dlBytesTotal = dlStats.Sum(m => m.BytesTotal); + speed = (Int32)(dlStats.Any() ? dlStats.Average(m => m.Speed) : 0); + var downloadProgress = dlBytesTotal > 0 ? Math.Clamp((Double)dlBytesDone / dlBytesTotal, 0.0, 1.0) : 0; + progress = (rdProgress + downloadProgress) / 2.0; + } + else + { + progress = rdProgress; } - var progress = (rdProgress + downloadProgress) / 2.0; var remaining = TimeSpan.Zero; - var bytesRemaining = bytesTotal - bytesDone; - - if (speed > 0 && bytesRemaining > 0) + if (progress > 0 && progress < 1.0) { - remaining = TimeSpan.FromSeconds(bytesRemaining / (Double)speed); - - // In case there is clock skew - if (remaining < TimeSpan.Zero) - { - remaining = TimeSpan.Zero; - } + var startTime = torrent.Retry > torrent.Added ? torrent.Retry.Value : torrent.Added; + var elapsed = DateTimeOffset.UtcNow - startTime; + var totalEstimatedTime = TimeSpan.FromTicks((Int64)(elapsed.Ticks / progress)); + remaining = totalEstimatedTime - elapsed; } var result = new TorrentInfo @@ -361,9 +360,10 @@ public class QBittorrent(ILogger logger, Settings settings, Authent if (torrent.Downloads.Count > 0) { - bytesDone = torrent.Downloads.Sum(m => m.BytesDone); - bytesTotal = torrent.Downloads.Sum(m => m.BytesTotal); - speed = (Int32)torrent.Downloads.Average(m => m.Speed); + var dlStats = torrent.Downloads.Select(m => torrents.GetDownloadStats(m.DownloadId)).ToList(); + bytesDone = dlStats.Sum(m => m.BytesDone); + bytesTotal = dlStats.Sum(m => m.BytesTotal); + speed = (Int32)(dlStats.Any() ? dlStats.Average(m => m.Speed) : 0); } var result = new TorrentProperties diff --git a/server/RdtClient.Service/Services/Sabnzbd.cs b/server/RdtClient.Service/Services/Sabnzbd.cs index 16a3b5c..ca7df94 100644 --- a/server/RdtClient.Service/Services/Sabnzbd.cs +++ b/server/RdtClient.Service/Services/Sabnzbd.cs @@ -19,17 +19,21 @@ public class Sabnzbd(ILogger logger, Torrents torrents, AppSettings app NoOfSlots = activeTorrents.Count, Slots = activeTorrents.Select((t, index) => { - Double downloadProgress = 0; var rdProgress = Math.Clamp(t.RdProgress ?? 0.0, 0.0, 100.0) / 100.0; + Double progress; - if (t.Downloads is { Count: > 0 }) + var dlStats = t.Downloads.Select(m => torrents.GetDownloadStats(m.DownloadId)).ToList(); + if (dlStats.Count > 0) { - var bytesDone = t.Downloads.Sum(m => m.BytesDone); - var bytesTotal = t.Downloads.Sum(m => m.BytesTotal); - downloadProgress = bytesTotal > 0 ? Math.Clamp((Double)bytesDone / bytesTotal, 0.0, 1.0) : 0; + var bytesDone = dlStats.Sum(m => m.BytesDone); + var bytesTotal = dlStats.Sum(m => m.BytesTotal); + var downloadProgress = bytesTotal > 0 ? Math.Clamp((Double)bytesDone / bytesTotal, 0.0, 1.0) : 0; + progress = (rdProgress + downloadProgress) / 2.0; + } + else + { + progress = rdProgress; } - - var progress = (rdProgress + downloadProgress) / 2.0; var timeLeft = "0:00:00"; var startTime = t.Retry > t.Added ? t.Retry.Value : t.Added; @@ -50,8 +54,8 @@ public class Sabnzbd(ILogger logger, Torrents torrents, AppSettings app Index = index, NzoId = t.Hash, Filename = t.RdName ?? t.Hash, - Size = FileSizeHelper.FormatSize(t.Downloads.Sum(d => d.BytesTotal)), - SizeLeft = FileSizeHelper.FormatSize(t.Downloads.Sum(d => d.BytesTotal - d.BytesDone)), + Size = FileSizeHelper.FormatSize(dlStats.Sum(d => d.BytesTotal)), + SizeLeft = FileSizeHelper.FormatSize(dlStats.Sum(d => d.BytesTotal - d.BytesDone)), Percentage = (progress * 100.0).ToString("0"), Status = t.RdStatus switch diff --git a/server/RdtClient.Service/Services/TorrentRunner.cs b/server/RdtClient.Service/Services/TorrentRunner.cs index 1a4e1d2..6e98a1f 100644 --- a/server/RdtClient.Service/Services/TorrentRunner.cs +++ b/server/RdtClient.Service/Services/TorrentRunner.cs @@ -23,6 +23,21 @@ public class TorrentRunner(ILogger logger, Torrents torrents, Dow public static Boolean IsPausedForLowDiskSpace { get; set; } + 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); + } + public async Task Initialize() { Log("Initializing TorrentRunner"); @@ -665,8 +680,8 @@ public class TorrentRunner(ILogger logger, Torrents torrents, Dow var completePerc = 0; - var totalDownloadBytes = torrent.Downloads.Sum(m => m.BytesTotal); - var totalDoneBytes = torrent.Downloads.Sum(m => m.BytesDone); + var totalDownloadBytes = torrent.Downloads.Sum(m => GetStats(m.DownloadId).BytesTotal); + var totalDoneBytes = torrent.Downloads.Sum(m => GetStats(m.DownloadId).BytesDone); if (totalDownloadBytes > 0) { diff --git a/server/RdtClient.Service/Services/Torrents.cs b/server/RdtClient.Service/Services/Torrents.cs index 1e6f784..bdcd46b 100644 --- a/server/RdtClient.Service/Services/Torrents.cs +++ b/server/RdtClient.Service/Services/Torrents.cs @@ -58,29 +58,15 @@ public class Torrents( private static readonly SemaphoreSlim TorrentResetLock = new(1, 1); + public virtual (Int64 Speed, Int64 BytesTotal, Int64 BytesDone) GetDownloadStats(Guid downloadId) + { + return TorrentRunner.GetStats(downloadId); + } + public virtual async Task> Get() { var torrents = await torrentData.Get(); - foreach (var torrent in torrents) - { - foreach (var download in torrent.Downloads) - { - if (TorrentRunner.ActiveDownloadClients.TryGetValue(download.DownloadId, out var downloadClient)) - { - download.Speed = downloadClient.Speed; - download.BytesTotal = downloadClient.BytesTotal; - download.BytesDone = downloadClient.BytesDone; - } - - if (TorrentRunner.ActiveUnpackClients.TryGetValue(download.DownloadId, out var unpackClient)) - { - download.BytesTotal = 100; - download.BytesDone = unpackClient.Progess; - } - } - } - return torrents; } @@ -663,8 +649,7 @@ public class Torrents( { Category = Settings.Get.Provider.Default.Category, DownloadClient = Settings.Get.DownloadClient.Client, - DownloadAction = - Settings.Get.Provider.Default.OnlyDownloadAvailableFiles ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll, + 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, @@ -881,22 +866,6 @@ public class Torrents( await UpdateTorrentClientData(torrent); - foreach (var download in torrent.Downloads) - { - if (TorrentRunner.ActiveDownloadClients.TryGetValue(download.DownloadId, out var downloadClient)) - { - download.Speed = downloadClient.Speed; - download.BytesTotal = downloadClient.BytesTotal; - download.BytesDone = downloadClient.BytesDone; - } - - if (TorrentRunner.ActiveUnpackClients.TryGetValue(download.DownloadId, out var unpackClient)) - { - download.BytesTotal = 100; - download.BytesDone = unpackClient.Progess; - } - } - return torrent; } @@ -1084,6 +1053,7 @@ public class Torrents( logger.LogDebug(message); } + private static String ComputeSha1Hash(String input) { using var sha1 = System.Security.Cryptography.SHA1.Create();