mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Fix down/up progress
This commit is contained in:
@@ -1,9 +1,4 @@
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
|
||||
namespace Velopack.Flow;
|
||||
namespace Velopack.Flow;
|
||||
|
||||
public partial class Profile
|
||||
{
|
||||
@@ -12,91 +7,3 @@ public partial class Profile
|
||||
return DisplayName ?? Email ?? "<unknown>";
|
||||
}
|
||||
}
|
||||
|
||||
public partial class FlowApi
|
||||
{
|
||||
public virtual async Task DownloadInstallerLatestToFileAsync(string packageId, string channel, DownloadAssetType? assetType, string localFilePath,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (packageId == null)
|
||||
throw new ArgumentNullException(nameof(packageId));
|
||||
|
||||
if (channel == null)
|
||||
throw new ArgumentNullException(nameof(channel));
|
||||
|
||||
var client = _httpClient;
|
||||
|
||||
using var request = new HttpRequestMessage();
|
||||
request.Method = new HttpMethod("GET");
|
||||
|
||||
var urlBuilder = new StringBuilder();
|
||||
if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder.Append(_baseUrl);
|
||||
// Operation Path: "v1/download/{packageId}/{channel}"
|
||||
urlBuilder.Append("v1/download/");
|
||||
urlBuilder.Append(Uri.EscapeDataString(ConvertToString(packageId, CultureInfo.InvariantCulture)));
|
||||
urlBuilder.Append('/');
|
||||
urlBuilder.Append(Uri.EscapeDataString(ConvertToString(channel, CultureInfo.InvariantCulture)));
|
||||
urlBuilder.Append('?');
|
||||
if (assetType != null) {
|
||||
urlBuilder.Append(Uri.EscapeDataString("assetType")).Append('=')
|
||||
.Append(Uri.EscapeDataString(ConvertToString(assetType, CultureInfo.InvariantCulture))).Append('&');
|
||||
}
|
||||
|
||||
urlBuilder.Length--;
|
||||
|
||||
PrepareRequest(client, request, urlBuilder);
|
||||
|
||||
var url = urlBuilder.ToString();
|
||||
request.RequestUri = new Uri(url, UriKind.RelativeOrAbsolute);
|
||||
|
||||
PrepareRequest(client, request, url);
|
||||
|
||||
using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var headers = new Dictionary<string, IEnumerable<string>>();
|
||||
foreach (var item in response.Headers)
|
||||
headers[item.Key] = item.Value;
|
||||
if (response.Content != null && response.Content.Headers != null) {
|
||||
foreach (var item in response.Content.Headers)
|
||||
headers[item.Key] = item.Value;
|
||||
}
|
||||
|
||||
ProcessResponse(client, response);
|
||||
|
||||
var status = (int) response.StatusCode;
|
||||
if (status == (int) HttpStatusCode.NotFound) {
|
||||
string responseText = (response.Content == null) ? string.Empty :
|
||||
#if NET6_0_OR_GREATER
|
||||
await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
|
||||
#else
|
||||
await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
#endif
|
||||
|
||||
throw new ApiException("A server side error occurred.", status, responseText, headers, null);
|
||||
} else if (status is (int) HttpStatusCode.OK or (int) HttpStatusCode.NoContent) {
|
||||
using var fs = File.Create(localFilePath);
|
||||
if (response.Content != null) {
|
||||
#if NET6_0_OR_GREATER
|
||||
await response.Content.CopyToAsync(fs, cancellationToken);
|
||||
#else
|
||||
await response.Content.CopyToAsync(fs);
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
var responseData = response.Content == null ? null :
|
||||
#if NET6_0_OR_GREATER
|
||||
await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
|
||||
#else
|
||||
await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
#endif
|
||||
throw new ApiException(
|
||||
"The HTTP status code of the response was not expected (" + status + ").",
|
||||
status,
|
||||
responseData,
|
||||
headers,
|
||||
null);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
extern alias HttpFormatting;
|
||||
// ReSharper disable UseAwaitUsing
|
||||
|
||||
extern alias HttpFormatting;
|
||||
using Microsoft.Identity.Client;
|
||||
using Microsoft.Identity.Client.Extensions.Msal;
|
||||
using NuGet.Versioning;
|
||||
@@ -12,9 +14,7 @@ using Velopack.Packaging;
|
||||
using Velopack.Util;
|
||||
using System.Net;
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
using System.Net.Http.Json;
|
||||
#else
|
||||
#if !NET6_0_OR_GREATER
|
||||
using System.Net.Http;
|
||||
#endif
|
||||
|
||||
@@ -73,9 +73,8 @@ public class VelopackFlowServiceClient(
|
||||
{
|
||||
loginOptions ??= new VelopackFlowLoginOptions();
|
||||
FlowApi client = GetFlowApi();
|
||||
var serviceUrl = Options.VelopackBaseUrl ?? client.BaseUrl;
|
||||
if (!suppressOutput) {
|
||||
Logger.LogInformation("Preparing to login to Velopack ({serviceUrl})", serviceUrl);
|
||||
Logger.LogInformation("Preparing to login to Velopack ({serviceUrl})", client.BaseUrl);
|
||||
}
|
||||
|
||||
var authConfiguration = await GetAuthConfigurationAsync(client, cancellationToken);
|
||||
@@ -210,7 +209,6 @@ public class VelopackFlowServiceClient(
|
||||
$"Uploading {Path.GetFileName(filePath)}",
|
||||
async (report) => {
|
||||
await UploadReleaseAssetAsync(
|
||||
client,
|
||||
filePath,
|
||||
releaseGroup.Id,
|
||||
fileType,
|
||||
@@ -227,15 +225,10 @@ public class VelopackFlowServiceClient(
|
||||
ZipPackage? prevZip = await progress.RunTask(
|
||||
$"Downloading delta base for {version}",
|
||||
async (report) => {
|
||||
await DownloadLatestRelease(client, packageId, channel, prevVersion, report, cancellationToken);
|
||||
if (File.Exists(prevVersion)) {
|
||||
return new ZipPackage(prevVersion);
|
||||
}
|
||||
return null;
|
||||
return await DownloadLatestRelease(packageId, channel, prevVersion, report, cancellationToken);
|
||||
});
|
||||
|
||||
if (prevZip is not null) {
|
||||
|
||||
if (prevZip.Version! >= version) {
|
||||
throw new InvalidOperationException(
|
||||
$"Latest version in channel {channel} is greater than or equal to local (remote={prevZip.Version}, local={version})");
|
||||
@@ -260,7 +253,6 @@ public class VelopackFlowServiceClient(
|
||||
$"Uploading {Path.GetFileName(deltaPath)}",
|
||||
async (report) => {
|
||||
await UploadReleaseAssetAsync(
|
||||
client,
|
||||
deltaPath,
|
||||
releaseGroup.Id,
|
||||
FileType.Release,
|
||||
@@ -302,11 +294,18 @@ public class VelopackFlowServiceClient(
|
||||
}
|
||||
|
||||
|
||||
private static async Task DownloadLatestRelease(FlowApi client, string packageId, string channel, string localPath, Action<int> progress, CancellationToken cancellationToken)
|
||||
private async Task<ZipPackage?> DownloadLatestRelease(string packageId, string channel, string localPath, Action<int> progress,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
try {
|
||||
await client.DownloadInstallerLatestToFileAsync(packageId, channel, DownloadAssetType.Full, localPath, cancellationToken);
|
||||
} catch (ApiException e) when (e.StatusCode == (int) HttpStatusCode.NotFound) { }
|
||||
var client = GetFlowApi(progress);
|
||||
using var localFile = File.Create(localPath);
|
||||
using var file = await client.DownloadInstallerLatestAsync(packageId, channel, DownloadAssetType.Full, cancellationToken);
|
||||
await file.Stream.CopyToAsync(localFile, 81920, cancellationToken).ConfigureAwait(false);
|
||||
return new ZipPackage(localPath);
|
||||
} catch (ApiException e) when (e.StatusCode == (int) HttpStatusCode.NotFound) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task WaitUntilReleaseGroupLive(FlowApi client, Guid releaseGroupId, CancellationToken cancellationToken)
|
||||
@@ -338,7 +337,8 @@ public class VelopackFlowServiceClient(
|
||||
await client.CreateChannelAsync(request, cancellationToken);
|
||||
}
|
||||
|
||||
private static async Task<ReleaseGroup> CreateReleaseGroupAsync(FlowApi client, string packageId, SemanticVersion version, string channel, CancellationToken cancellationToken)
|
||||
private static async Task<ReleaseGroup> CreateReleaseGroupAsync(FlowApi client, string packageId, SemanticVersion version, string channel,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
CreateReleaseGroupRequest request = new() {
|
||||
ChannelIdentifier = channel,
|
||||
@@ -349,9 +349,10 @@ public class VelopackFlowServiceClient(
|
||||
return await client.CreateReleaseGroupAsync(request, cancellationToken);
|
||||
}
|
||||
|
||||
private static async Task UploadReleaseAssetAsync(FlowApi client, string filePath, Guid releaseGroupId, FileType fileType, Action<int> progress,
|
||||
private async Task UploadReleaseAssetAsync(string filePath, Guid releaseGroupId, FileType fileType, Action<int> progress,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var client = GetFlowApi(progress);
|
||||
using var stream = File.OpenRead(filePath);
|
||||
var file = new FileParameter(stream);
|
||||
await client.UploadReleaseAsync(releaseGroupId, fileType, file, cancellationToken);
|
||||
|
||||
Reference in New Issue
Block a user