Skip to content

Commit

Permalink
Added ProgressBar for Download and Upload
Browse files Browse the repository at this point in the history
  • Loading branch information
CraftingDragon007 committed Feb 20, 2022
1 parent af3f25e commit ca4e6eb
Show file tree
Hide file tree
Showing 3 changed files with 259 additions and 17 deletions.
85 changes: 85 additions & 0 deletions KekUploadCLIClient/HttpClientDownloadWithProgress.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
namespace KekUploadCLIClient;

public class HttpClientDownloadWithProgress : IDisposable
{
private readonly string _downloadUrl;
private readonly string _destinationFilePath;

private HttpClient _httpClient;

public delegate void ProgressChangedHandler(long? totalFileSize, long totalBytesDownloaded, double? progressPercentage);

public event ProgressChangedHandler ProgressChanged;

public HttpClientDownloadWithProgress(string downloadUrl, string destinationFilePath)
{
_downloadUrl = downloadUrl;
_destinationFilePath = destinationFilePath;
}

public async Task StartDownload()
{
_httpClient = new HttpClient { Timeout = TimeSpan.FromMinutes(5) };

using (var response = await _httpClient.GetAsync(_downloadUrl, HttpCompletionOption.ResponseHeadersRead))
await DownloadFileFromHttpResponseMessage(response);
}

private async Task DownloadFileFromHttpResponseMessage(HttpResponseMessage response)
{
response.EnsureSuccessStatusCode();

var totalBytes = response.Content.Headers.ContentLength;

using (var contentStream = await response.Content.ReadAsStreamAsync())
await ProcessContentStream(totalBytes, contentStream);
}

private async Task ProcessContentStream(long? totalDownloadSize, Stream contentStream)
{
var totalBytesRead = 0L;
var readCount = 0L;
var buffer = new byte[8192];
var isMoreToRead = true;

using (var fileStream = new FileStream(_destinationFilePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true))
{
do
{
var bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length);
if (bytesRead == 0)
{
isMoreToRead = false;
TriggerProgressChanged(totalDownloadSize, totalBytesRead);
continue;
}

await fileStream.WriteAsync(buffer, 0, bytesRead);

totalBytesRead += bytesRead;
readCount += 1;

if (readCount % 100 == 0)
TriggerProgressChanged(totalDownloadSize, totalBytesRead);
}
while (isMoreToRead);
}
}

private void TriggerProgressChanged(long? totalDownloadSize, long totalBytesRead)
{
if (ProgressChanged == null)
return;

double? progressPercentage = null;
if (totalDownloadSize.HasValue)
progressPercentage = Math.Round((double)totalBytesRead / totalDownloadSize.Value * 100, 2);

ProgressChanged(totalDownloadSize, totalBytesRead, progressPercentage);
}

public void Dispose()
{
_httpClient?.Dispose();
}
}
48 changes: 31 additions & 17 deletions KekUploadCLIClient/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;

Expand Down Expand Up @@ -39,21 +40,28 @@ public static string MainLoop(string[] args) {
}
}

public static string Download(string url, string output) {
var client = new HttpClient();
public static string Download(string url, string output)
{
Console.WriteLine("Starting with the download!");
Console.WriteLine();
ProgressBar progressBar = new ProgressBar();


var downloadUrl = url.Replace("/e/", "/d/");

var downloadRequest = new HttpRequestMessage {
RequestUri = new Uri(downloadUrl),
Method = HttpMethod.Get
var client = new HttpClientDownloadWithProgress(downloadUrl, output);
client.ProgressChanged += (size, downloaded, percentage) =>
{
if (size != null)
{
Console.WriteLine("Downloaded " + SizeToString(downloaded) + " of " + SizeToString((long)size) + "!");
}else Console.WriteLine("Downloaded " + SizeToString(downloaded) + "!");
progressBar.SetProgress((float)(percentage != null ? percentage : 0));
};

var fileStream = File.OpenWrite(output);
var response = client.Send(downloadRequest);

if (response.IsSuccessStatusCode) {
response.Content.ReadAsStream().CopyTo(fileStream);
Task task = client.StartDownload();
task.Wait();
progressBar.Dispose();
if (task.IsCompletedSuccessfully) {
return "Successfully downloaded file to: " + Path.GetFullPath(output);
} else return "Could not download the file! Are you sure you entered a correct url?";
}
Expand Down Expand Up @@ -86,7 +94,10 @@ public static string Upload(string file, string baseapi) {
var chunks = (int)Math.Ceiling(fileSize/(double)maxChunkSize);

Console.WriteLine("Chunks: " + chunks);
Console.WriteLine();

ProgressBar progressBar = new ProgressBar();

for(int chunk = 0; chunk < chunks; chunk++) {
var chunkSize = Math.Min(stream.Length-chunk*maxChunkSize, maxChunkSize);

Expand All @@ -107,9 +118,12 @@ public static string Upload(string file, string baseapi) {

var responseMsg = client.Send(uploadRequest);
if (!responseMsg.IsSuccessStatusCode) return "Some error i dont want to show u lol.";
progressBar.SetProgress((chunk+1) * 100 / (float)chunks);
//DrawTextProgressBar(chunk + 1, chunks);
}



progressBar.Dispose();

var hash = HashFile(file);

Console.WriteLine("File Hash: " + hash);
Expand Down Expand Up @@ -141,13 +155,13 @@ private static string HashFile(string file) {

private static string SizeToString(long size) {
if(size >= 1099511627776) {
return Math.Round(size / 10995116277.76)*0.01 + " TiB";
return decimal.Round((decimal)(Math.Round(size / 10995116277.76)*0.01), 2) + " TiB";
} else if(size >= 1073741824) {
return Math.Round(size / 10737418.24)*0.01 + " GiB";
return decimal.Round((decimal)(Math.Round(size / 10737418.24)*0.01), 2) + " GiB";
} else if(size >= 1048576) {
return Math.Round(size / 10485.76)*0.01 + " MiB";
return decimal.Round((decimal)(Math.Round(size / 10485.76)*0.01), 2) + " MiB";
} else if(size >= 1024) {
return Math.Round(size / 10.24)*0.01 + " KiB";
return decimal.Round((decimal)(Math.Round(size / 10.24)*0.01), 2) + " KiB";
} else return size + " bytes";
}

Expand Down
143 changes: 143 additions & 0 deletions KekUploadCLIClient/ProgressBar.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
using System;
using System.IO;
using System.Text;

namespace KekUploadCLIClient
{
/// <summary>
/// Console progressbar
/// </summary>
public class ProgressBar : IDisposable {

public float CurrentProgress => writer.CurrentProgress;

private TextWriter OriginalWriter;
private ProgressWriter writer;

public ProgressBar() {
OriginalWriter = Console.Out;
writer = new ProgressWriter(OriginalWriter);
Console.SetOut(writer);
}

public void Dispose() {
Console.SetOut(OriginalWriter);
writer.ClearProgressBar();
}

public void SetProgress(float f) {
writer.CurrentProgress = f;
writer.RedrawProgress();
}
public void SetProgress(int i) {
SetProgress((float)i);
}

public void Increment(float f) {
writer.CurrentProgress += f;
writer.RedrawProgress();
}

public void Increment(int i) {
Increment((float)i);
}

private class ProgressWriter : TextWriter {

public override Encoding Encoding => Encoding.UTF8;
public float CurrentProgress {
get { return _currentProgress; }
set {
_currentProgress = value;
if(_currentProgress > 100) {
_currentProgress = 100;
}else if(CurrentProgress < 0) {
_currentProgress = 0;
}
}
}

private float _currentProgress = 0;
private TextWriter consoleOut;
private const string ProgressTemplate = "[{0}] {1:n2}%";
private const int AllocatedTemplateSpace = 11;
private object SyncLock = new object();
public ProgressWriter(TextWriter _consoleOut) {
consoleOut = _consoleOut;
RedrawProgress();
}

private void DrawProgressBar() {
lock (SyncLock) {
int avalibleSpace = Console.BufferWidth - AllocatedTemplateSpace;
int percentAmmount = (int)((float)avalibleSpace * (CurrentProgress / 100));
var col = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.DarkMagenta;
string progressBar = string.Concat(new string('=', percentAmmount), new string(' ', avalibleSpace - percentAmmount));
consoleOut.Write(string.Format(ProgressTemplate, progressBar, CurrentProgress));
Console.ForegroundColor = col;
}
}

public void RedrawProgress() {
lock (SyncLock) {
int LastLineWidth = Console.CursorLeft;
var consoleH = Console.WindowTop + Console.WindowHeight - 1;
Console.SetCursorPosition(0, consoleH);
DrawProgressBar();
Console.SetCursorPosition(LastLineWidth, consoleH - 1);
}
}

private void ClearLineEnd() {
lock (SyncLock) {
int lineEndClear = Console.BufferWidth - Console.CursorLeft - 1;
consoleOut.Write(new string(' ', lineEndClear));
}
}

public void ClearProgressBar() {
lock (SyncLock) {
int LastLineWidth = Console.CursorLeft;
var consoleH = Console.WindowTop + Console.WindowHeight - 1;
Console.SetCursorPosition(0, consoleH);
ClearLineEnd();
Console.SetCursorPosition(LastLineWidth, consoleH - 1);
}
}

public override void Write(char value) {
lock (SyncLock) {
consoleOut.Write(value);
}
}

public override void Write(string? value) {
lock (SyncLock) {
consoleOut.Write(value);
}
}

public override void WriteLine(string? value) {
lock (SyncLock) {
consoleOut.Write(value);
consoleOut.Write(Environment.NewLine);
ClearLineEnd();
consoleOut.Write(Environment.NewLine);
RedrawProgress();
}
}

public override void WriteLine(string format, params object[] arg) {
WriteLine(string.Format(format, arg));
}

public override void WriteLine(int i) {
WriteLine(i.ToString());
}

}

}
}

0 comments on commit ca4e6eb

Please sign in to comment.