Added the previous downloader back in, keep the Bezzad downloader in as a secondary.

This commit is contained in:
Roger Far 2024-01-21 16:48:44 -07:00
parent c95f0171f7
commit 6c47ebcfad
6 changed files with 232 additions and 76 deletions

View file

@ -145,10 +145,20 @@ If you use Proxmox for your homelab, you can run rdt-client in a linux container
### Download Clients
Currently there 2 available download clients:
Currently there 4 available download clients:
#### Internal Downloader
This experimental [downloader](https://github.com/rogerfar/Downloader.NET) can be used to download files with multiple sections in parallel.
It has the following options:
- Download speed (in MB/s): This number indicates the speed in MB/s per download over all parallel downloads and chunks.
- Parallel connections per download: When a file is downloaded it is split in sections, this setting indicates how many sections you will download in parallel.
- Connection Timeout: This number indicates the timeout in milliseconds before a download chunk times out. It will retry each chunk 5 times before completely failing.
#### Bezzad Downloader
This [downloader](https://github.com/bezzad/Downloader) can be used to download files in parallel and with multiple chunks.
It has the following options:

View file

@ -7,6 +7,9 @@ public enum DownloadClient
[Description("Internal Downloader")]
Internal,
[Description("Bezzad Downloader")]
Bezzad,
[Description("Aria2c")]
Aria2c,

View file

@ -12,6 +12,7 @@
<PackageReference Include="AllDebrid.NET" Version="1.0.12" />
<PackageReference Include="Aria2.NET" Version="1.0.5" />
<PackageReference Include="Downloader" Version="3.0.6" />
<PackageReference Include="Downloader.NET" Version="1.0.9" />
<PackageReference Include="MonoTorrent" Version="2.0.7" />
<PackageReference Include="Premiumize.NET" Version="1.0.4" />
<PackageReference Include="RD.NET" Version="2.1.4" />

View file

@ -58,6 +58,7 @@ public class DownloadClient
Downloader = Settings.Get.DownloadClient.Client switch
{
Data.Enums.DownloadClient.Internal => new InternalDownloader(_download.Link, filePath),
Data.Enums.DownloadClient.Bezzad => new BezzadDownloader(_download.Link, filePath),
Data.Enums.DownloadClient.Aria2c => new Aria2cDownloader(_download.RemoteId, _download.Link, filePath, downloadPath),
Data.Enums.DownloadClient.Symlink => new SymlinkDownloader(_download.Link, filePath),
_ => throw new Exception($"Unknown download client {Settings.Get.DownloadClient}")

View file

@ -0,0 +1,186 @@
using System.Net;
using Downloader;
using Serilog;
namespace RdtClient.Service.Services.Downloaders;
public class BezzadDownloader : IDownloader
{
public event EventHandler<DownloadCompleteEventArgs>? DownloadComplete;
public event EventHandler<DownloadProgressEventArgs>? DownloadProgress;
private readonly DownloadService _downloadService;
private readonly DownloadConfiguration _downloadConfiguration;
private readonly String _filePath;
private readonly String _uri;
private readonly ILogger _logger;
private Boolean _finished;
public BezzadDownloader(String uri, String filePath)
{
_logger = Log.ForContext<BezzadDownloader>();
_uri = uri;
_filePath = filePath;
var settingProxyServer = Settings.Get.DownloadClient.ProxyServer;
// For all options, see https://github.com/bezzad/Downloader
_downloadConfiguration = new DownloadConfiguration
{
MaxTryAgainOnFailover = 5,
RangeDownload = false,
ClearPackageOnCompletionWithFailure = true,
ReserveStorageSpaceBeforeStartingDownload = false,
CheckDiskSizeBeforeDownload = false,
MaximumMemoryBufferBytes = 1024 * 1024 * 10,
RequestConfiguration =
{
Accept = "*/*",
UserAgent = $"rdt-client",
ProtocolVersion = HttpVersion.Version11,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
KeepAlive = true,
UseDefaultCredentials = false
}
};
SetSettings();
if (!String.IsNullOrWhiteSpace(settingProxyServer))
{
_downloadConfiguration.RequestConfiguration.Proxy = new WebProxy(new Uri(settingProxyServer), false);
}
_downloadService = new DownloadService(_downloadConfiguration);
_downloadService.DownloadProgressChanged += (_, args) =>
{
if (DownloadProgress == null)
{
return;
}
DownloadProgress.Invoke(this,
new DownloadProgressEventArgs
{
Speed = (Int64)args.BytesPerSecondSpeed,
BytesDone = args.ReceivedBytesSize,
BytesTotal = args.TotalBytesToReceive
});
};
_downloadService.DownloadFileCompleted += (_, args) =>
{
String? error = null;
if (args.Cancelled)
{
error = $"The download was cancelled";
}
else if (args.Error != null)
{
error = args.Error.Message;
}
DownloadComplete?.Invoke(this,
new DownloadCompleteEventArgs
{
Error = error
});
_finished = true;
};
}
public Task<String?> Download()
{
_logger.Debug($"Starting download of {_uri}, writing to path: {_filePath}");
_ = Task.Run(async () =>
{
await _downloadService.DownloadFileTaskAsync(_uri, _filePath);
});
_ = Task.Run(StartTimer);
return Task.FromResult<String?>(Guid.NewGuid().ToString());
}
public Task Cancel()
{
_logger.Debug($"Cancelling download {_uri}");
_downloadService.CancelAsync();
return Task.CompletedTask;
}
public Task Pause()
{
return Task.CompletedTask;
}
public Task Resume()
{
return Task.CompletedTask;
}
private void SetSettings()
{
var settingDownloadMaxSpeed = Settings.Get.DownloadClient.MaxSpeed;
if (settingDownloadMaxSpeed <= 0)
{
settingDownloadMaxSpeed = 0;
}
settingDownloadMaxSpeed = settingDownloadMaxSpeed * 1024 * 1024;
var settingDownloadTimeout = Settings.Get.DownloadClient.Timeout;
if (settingDownloadTimeout <= 0)
{
settingDownloadTimeout = 1000;
}
var settingParallelCount = Settings.Get.DownloadClient.ParallelCount;
if (settingParallelCount <= 0)
{
settingParallelCount = 4;
}
if (Settings.Get.DownloadClient.ChunkCount <= 0)
{
_downloadConfiguration.ChunkCount = 8;
}
else
{
_downloadConfiguration.ChunkCount = Settings.Get.DownloadClient.ChunkCount;
}
_downloadConfiguration.MaximumBytesPerSecond = settingDownloadMaxSpeed;
_downloadConfiguration.ParallelDownload = settingParallelCount > 1;
_downloadConfiguration.ParallelCount = settingParallelCount;
_downloadConfiguration.Timeout = settingDownloadTimeout;
}
private async Task StartTimer()
{
using var timer = new PeriodicTimer(TimeSpan.FromSeconds(5));
while (await timer.WaitForNextTickAsync())
{
if (_finished)
{
return;
}
SetSettings();
}
}
}

View file

@ -1,6 +1,4 @@
using System.Net;
using Downloader;
using Serilog;
using Serilog;
namespace RdtClient.Service.Services.Downloaders;
@ -9,14 +7,16 @@ public class InternalDownloader : IDownloader
public event EventHandler<DownloadCompleteEventArgs>? DownloadComplete;
public event EventHandler<DownloadProgressEventArgs>? DownloadProgress;
private readonly DownloadService _downloadService;
private readonly DownloadConfiguration _downloadConfiguration;
private readonly DownloaderNET.Downloader _downloadService;
private readonly DownloaderNET.Settings _downloadConfiguration;
private readonly String _filePath;
private readonly String _uri;
private readonly ILogger _logger;
private readonly CancellationTokenSource _cancellationToken = new();
private Boolean _finished;
public InternalDownloader(String uri, String filePath)
@ -25,39 +25,16 @@ public class InternalDownloader : IDownloader
_uri = uri;
_filePath = filePath;
var settingProxyServer = Settings.Get.DownloadClient.ProxyServer;
// For all options, see https://github.com/bezzad/Downloader
_downloadConfiguration = new DownloadConfiguration
{
MaxTryAgainOnFailover = 5,
RangeDownload = false,
ClearPackageOnCompletionWithFailure = true,
ReserveStorageSpaceBeforeStartingDownload = false,
CheckDiskSizeBeforeDownload = false,
MaximumMemoryBufferBytes = 1024 * 1024 * 10,
RequestConfiguration =
{
Accept = "*/*",
UserAgent = $"rdt-client",
ProtocolVersion = HttpVersion.Version11,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
KeepAlive = true,
UseDefaultCredentials = false
}
};
_downloadConfiguration = new DownloaderNET.Settings();
SetSettings();
if (!String.IsNullOrWhiteSpace(settingProxyServer))
{
_downloadConfiguration.RequestConfiguration.Proxy = new WebProxy(new Uri(settingProxyServer), false);
}
_downloadService = new DownloaderNET.Downloader(_uri, _filePath, _downloadConfiguration);
_downloadService = new DownloadService(_downloadConfiguration);
//_downloadService.OnLog += message => Debug.WriteLine(message.Message);
_downloadService.DownloadProgressChanged += (_, args) =>
_downloadService.OnProgress += (chunks, _) =>
{
if (DownloadProgress == null)
{
@ -67,54 +44,41 @@ public class InternalDownloader : IDownloader
DownloadProgress.Invoke(this,
new DownloadProgressEventArgs
{
Speed = (Int64)args.BytesPerSecondSpeed,
BytesDone = args.ReceivedBytesSize,
BytesTotal = args.TotalBytesToReceive
Speed = (Int64)chunks.Where(m => m.IsActive).Sum(m => m.Speed),
BytesDone = chunks.Sum(m => m.DownloadBytes),
BytesTotal = chunks.Sum(m => m.LengthBytes)
});
};
_downloadService.DownloadFileCompleted += (_, args) =>
_downloadService.OnComplete += (_, error) =>
{
String? error = null;
if (args.Cancelled)
{
error = $"The download was cancelled";
}
else if (args.Error != null)
{
error = args.Error.Message;
}
DownloadComplete?.Invoke(this,
new DownloadCompleteEventArgs
{
Error = error
Error = error?.Message
});
_finished = true;
return Task.CompletedTask;
};
}
public Task<String?> Download()
public async Task<String?> Download()
{
_logger.Debug($"Starting download of {_uri}, writing to path: {_filePath}");
_ = Task.Run(async () =>
{
await _downloadService.DownloadFileTaskAsync(_uri, _filePath);
});
await _downloadService.Download(_cancellationToken.Token);
_ = Task.Run(StartTimer);
return Task.FromResult<String?>(Guid.NewGuid().ToString());
return Guid.NewGuid().ToString();
}
public Task Cancel()
{
_logger.Debug($"Cancelling download {_uri}");
_downloadService.CancelAsync();
_cancellationToken.Cancel(false);
return Task.CompletedTask;
}
@ -131,6 +95,13 @@ public class InternalDownloader : IDownloader
private void SetSettings()
{
var settingDownloadParallelCount = Settings.Get.DownloadClient.ParallelCount;
if (settingDownloadParallelCount <= 0)
{
settingDownloadParallelCount = 1;
}
var settingDownloadMaxSpeed = Settings.Get.DownloadClient.MaxSpeed;
if (settingDownloadMaxSpeed <= 0)
@ -146,27 +117,11 @@ public class InternalDownloader : IDownloader
{
settingDownloadTimeout = 1000;
}
var settingParallelCount = Settings.Get.DownloadClient.ParallelCount;
if (settingParallelCount <= 0)
{
settingParallelCount = 4;
}
if (Settings.Get.DownloadClient.ChunkCount <= 0)
{
_downloadConfiguration.ChunkCount = 8;
}
else
{
_downloadConfiguration.ChunkCount = Settings.Get.DownloadClient.ChunkCount;
}
_downloadConfiguration.Parallel = settingDownloadParallelCount;
_downloadConfiguration.MaximumBytesPerSecond = settingDownloadMaxSpeed;
_downloadConfiguration.ParallelDownload = settingParallelCount > 1;
_downloadConfiguration.ParallelCount = settingParallelCount;
_downloadConfiguration.Timeout = settingDownloadTimeout;
_downloadConfiguration.RetryCount = 5;
}
private async Task StartTimer()