update to show progress for download

This commit is contained in:
CWX 2022-06-07 20:34:09 +01:00
parent 224bfaa456
commit c55e5c8f1f
3 changed files with 86 additions and 17 deletions

View File

@ -55,7 +55,7 @@ namespace SPT_AKI_Installer.Aki.Core
if (patcherZipPath == null && DownloadHelper.patchNeedCheck)
{
LogHelper.Info("No Patcher zip file present in directory, downloading...");
var task = DownloadHelper.DownloadFileAsync(targetPath, DownloadHelper.patcherLink, "/PATCHERZIP.zip");
var task = DownloadHelper.DownloadFile(targetPath, DownloadHelper.patcherLink, "/PATCHERZIP.zip");
while(task.Status != System.Threading.Tasks.TaskStatus.RanToCompletion)
{
}
@ -65,7 +65,7 @@ namespace SPT_AKI_Installer.Aki.Core
if (akiZipPath == null)
{
LogHelper.Info("No AKI zip file present in directory, downloading...");
var task = DownloadHelper.DownloadFileAsync(targetPath, DownloadHelper.akiLink, "/AKIZIP.zip");
var task = DownloadHelper.DownloadFile(targetPath, DownloadHelper.akiLink, "/AKIZIP.zip");
while (task.Status != System.Threading.Tasks.TaskStatus.RanToCompletion)
{
}

View File

@ -3,10 +3,12 @@ using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using System.Threading;
using Gitea.Api;
using Gitea.Client;
using Gitea.Model;
using System.Collections.Generic;
using Spectre.Console;
using HttpClientProgress;
namespace SPT_AKI_Installer.Aki.Helper
{
@ -16,14 +18,6 @@ namespace SPT_AKI_Installer.Aki.Helper
public static string akiLink;
public static string patcherLink;
public static async Task DownloadFileAsync(string targetFilePath, string targetLink, string newFileName)
{
using (var httpClient = new HttpClient())
{
await httpClient.DownloadFile(targetLink, Path.Join(targetFilePath, newFileName));
}
}
public static async Task ReleaseCheck()
{
Configuration.Default.BasePath = "https://dev.sp-tarkov.com/api/v1";
@ -79,14 +73,32 @@ namespace SPT_AKI_Installer.Aki.Helper
}
}
public static async Task DownloadFile(this HttpClient client, string address, string fileName)
public static async Task DownloadFile(string targetFilePath, string targetLink, string newFileName)
{
using (var response = await client.GetAsync(address))
using (var stream = await response.Content.ReadAsStreamAsync())
using (var file = File.OpenWrite(fileName))
await AnsiConsole.Progress().Columns(
new PercentageColumn(),
new TaskDescriptionColumn(),
new ProgressBarColumn(),
new ElapsedTimeColumn(),
new SpinnerColumn()
).StartAsync(async (ProgressContext context) =>
{
stream.CopyTo(file);
}
var task = context.AddTask("Downloading File");
var client = new HttpClient();
var docUrl = targetLink;
var filePath = Path.Join(targetFilePath, newFileName);
// Setup your progress reporter
var progress = new Progress<float>((float progress) =>
{
task.Value = progress;
});
// Use the provided extension method
using (var file = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
await client.DownloadDataAsync(docUrl, file, progress);
});
}
}
}

View File

@ -0,0 +1,57 @@
using System;
using System.IO;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace HttpClientProgress
{
public static class HttpClientProgressExtensions
{
public static async Task DownloadDataAsync(this HttpClient client, string requestUrl, Stream destination, IProgress<float> progress = null, CancellationToken cancellationToken = default(CancellationToken))
{
using (var response = await client.GetAsync(requestUrl, HttpCompletionOption.ResponseHeadersRead))
{
var contentLength = response.Content.Headers.ContentLength;
using (var download = await response.Content.ReadAsStreamAsync())
{
// no progress... no contentLength... very sad
if (progress is null || !contentLength.HasValue)
{
await download.CopyToAsync(destination);
return;
}
// Such progress and contentLength much reporting Wow!
var progressWrapper = new Progress<long>(totalBytes => progress.Report(GetProgressPercentage(totalBytes, contentLength.Value)));
await download.CopyToAsync(destination, 81920, progressWrapper, cancellationToken);
}
}
float GetProgressPercentage(float totalBytes, float currentBytes) => (totalBytes / currentBytes) * 100f;
}
static async Task CopyToAsync(this Stream source, Stream destination, int bufferSize, IProgress<long> progress = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (bufferSize < 0)
throw new ArgumentOutOfRangeException(nameof(bufferSize));
if (source is null)
throw new ArgumentNullException(nameof(source));
if (!source.CanRead)
throw new InvalidOperationException($"'{nameof(source)}' is not readable.");
if (destination == null)
throw new ArgumentNullException(nameof(destination));
if (!destination.CanWrite)
throw new InvalidOperationException($"'{nameof(destination)}' is not writable.");
var buffer = new byte[bufferSize];
long totalBytesRead = 0;
int bytesRead;
while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) != 0)
{
await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
totalBytesRead += bytesRead;
progress?.Report(totalBytesRead);
}
}
}
}