Skip to content

Commit

Permalink
Move ISimpleDownloadProgress to Redpoint.ProgressMonitor (#66)
Browse files Browse the repository at this point in the history
  • Loading branch information
hach-que authored Dec 1, 2024
1 parent 9c33053 commit d1faa24
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 111 deletions.
6 changes: 6 additions & 0 deletions UET/Redpoint.ProgressMonitor/ProgressMonitorExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
{
using Microsoft.Extensions.DependencyInjection;
using Redpoint.ProgressMonitor.Implementations;
#if NETCOREAPP
using Redpoint.ProgressMonitor.Utils;
#endif

/// <summary>
/// Extensions for registering progress monitoring services.
Expand All @@ -17,6 +20,9 @@ public static void AddProgressMonitor(this IServiceCollection services)
services.AddSingleton<IMonitorFactory, DefaultMonitorFactory>();
services.AddSingleton<IProgressFactory, DefaultProgressFactory>();
services.AddSingleton<IUtilities, DefaultUtilities>();
#if NETCOREAPP
services.AddSingleton<ISimpleDownloadProgress, DefaultSimpleDownloadProgress>();
#endif
}
}
}
101 changes: 101 additions & 0 deletions UET/Redpoint.ProgressMonitor/Utils/DefaultSimpleDownloadProgress.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#if NETCOREAPP

namespace Redpoint.ProgressMonitor.Utils
{
using Redpoint.ProgressMonitor;
using System;
using System.IO;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

internal class DefaultSimpleDownloadProgress : ISimpleDownloadProgress
{
private readonly IProgressFactory _progressFactory;
private readonly IMonitorFactory _monitorFactory;

public DefaultSimpleDownloadProgress(
IProgressFactory progressFactory,
IMonitorFactory monitorFactory)
{
_progressFactory = progressFactory;
_monitorFactory = monitorFactory;
}

private class DidOutput
{
public bool Did;
}

public async Task DownloadAndCopyToStreamAsync(
HttpClient client,
Uri downloadUrl,
Func<Stream, Task> copier,
CancellationToken cancellationToken)
{
var response = await client.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);

using var stream = new PositionAwareStream(
await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false),
response.Content.Headers.ContentLength!.Value);

using var cts = new CancellationTokenSource();
var progress = _progressFactory.CreateProgressForStream(stream);
var outputTrack = new DidOutput();
var monitorTask = Task.Run(async () =>
{
var consoleWidth = 0;
try
{
consoleWidth = Console.BufferWidth;
}
catch { }

var monitor = _monitorFactory.CreateByteBasedMonitor();
await monitor.MonitorAsync(
progress,
null,
(message, count) =>
{
if (consoleWidth != 0)
{
Console.Write($"\r {message}".PadRight(consoleWidth));
outputTrack.Did = true;
}
else if (count % 50 == 0)
{
Console.WriteLine($" {message}");
outputTrack.Did = true;
}
},
cts.Token).ConfigureAwait(false);
}, cts.Token);

await copier(stream).ConfigureAwait(false);

cts.Cancel();
try
{
await monitorTask.ConfigureAwait(false);
}
catch (OperationCanceledException)
{
}
if (outputTrack.Did)
{
var consoleWidth = 0;
try
{
consoleWidth = Console.BufferWidth;
}
catch { }
if (consoleWidth != 0)
{
Console.WriteLine();
}
}
}
}
}

#endif
32 changes: 32 additions & 0 deletions UET/Redpoint.ProgressMonitor/Utils/ISimpleDownloadProgress.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#if NETCOREAPP

namespace Redpoint.ProgressMonitor.Utils
{
using System;
using System.IO;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

/// <summary>
/// A utility interface which downloads a URL to a stream and emits progress information to the console.
/// </summary>
public interface ISimpleDownloadProgress
{
/// <summary>
/// Download the target URL using the specified <see cref="HttpClient"/>, passing the download stream to <paramref name="copier"/> (which is typically a lambda that calls <see cref="Stream.CopyToAsync(Stream, CancellationToken)"/>).
/// </summary>
/// <param name="client">The <see cref="HttpClient"/> to use for the download.</param>
/// <param name="downloadUrl">The URL to download.</param>
/// <param name="copier">The asynchronous function that the download stream will be passed to. When the returned task completes, the stream should have been fully written or consumed.</param>
/// <param name="cancellationToken">A token which can be used to cancel the download.</param>
/// <returns>An awaitable task.</returns>
Task DownloadAndCopyToStreamAsync(
HttpClient client,
Uri downloadUrl,
Func<Stream, Task> copier,
CancellationToken cancellationToken);
}
}

#endif

This file was deleted.

This file was deleted.

1 change: 1 addition & 0 deletions UET/Redpoint.Uet.SdkManagement/Sdk/LinuxSdkSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using System.Reflection;
using System.Text.RegularExpressions;
using Redpoint.Uet.SdkManagement.Sdk.VersionNumbers;
using Redpoint.ProgressMonitor.Utils;

[SupportedOSPlatform("windows")]
public class LinuxSdkSetup : ISdkSetup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.Extensions.Logging;
using Redpoint.IO;
using Redpoint.ProcessExecution;
using Redpoint.ProgressMonitor.Utils;
using System;
using System.Collections.Generic;
using System.IO.Compression;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ public static class SdkManagementServiceExtensions
{
public static void AddSdkManagement(this IServiceCollection services)
{
services.AddSingleton<ISimpleDownloadProgress, SimpleDownloadProgress>();
services.AddSingleton<ILocalSdkManager, DefaultLocalSdkManager>();

services.AddSingleton<IVersionNumberResolver, DefaultVersionNumberResolver>();
Expand Down

0 comments on commit d1faa24

Please sign in to comment.