private async Task RunAsync(ProgressContext context, DirectoryInfo toolsDirectory, CancellationToken cancellationToken) { const double initialMaxValue = double.Epsilon; var globalProgress = context.AddTask("Downloading MongoDB", maxValue: initialMaxValue); var(communityServerVersion, communityServerDownloads) = await GetCommunityServerDownloadsAsync(cancellationToken); globalProgress.Description = $"Downloading MongoDB Community Server {communityServerVersion.Number}"; var(databaseToolsVersion, databaseToolsDownloads) = await GetDatabaseToolsDownloadsAsync(cancellationToken); globalProgress.Description = $"Downloading MongoDB Community Server {communityServerVersion.Number} and Database Tools {databaseToolsVersion.Number}"; var tasks = new List <Task>(); var allArchiveProgresses = new List <ProgressTask>(); foreach (var download in communityServerDownloads.Concat(databaseToolsDownloads)) { var archiveProgress = context.AddTask($"Downloading {download.Product} for {download.Platform} from {download.Archive.Url}", maxValue: initialMaxValue); var directoryName = $"mongodb-{download.Platform.ToString().ToLowerInvariant()}-{communityServerVersion.Number}-database-tools-{databaseToolsVersion.Number}"; var extractDirectory = new DirectoryInfo(Path.Combine(toolsDirectory.FullName, directoryName)); allArchiveProgresses.Add(archiveProgress); var progress = new DownloadProgress(archiveProgress, globalProgress, allArchiveProgresses, download, $"✅ Downloaded and extracted MongoDB Community Server {communityServerVersion.Number} and Database Tools {databaseToolsVersion.Number} into {new Uri(toolsDirectory.FullName).AbsoluteUri}"); tasks.Add(ProcessArchiveAsync(download, extractDirectory, progress, cancellationToken)); } await Task.WhenAll(tasks); }
private async Task ProcessArchiveAsync(Download download, DirectoryInfo extractDirectory, DownloadProgress progress, CancellationToken cancellationToken) { var archiveExtension = Path.GetExtension(download.Archive.Url.AbsolutePath); if (archiveExtension == ".zip") { await _extractor.DownloadExtractZipArchiveAsync(download, extractDirectory, progress, cancellationToken); } else { var archiveFileInfo = await DownloadArchiveAsync(download.Archive, progress, cancellationToken); _extractor.ExtractArchive(download, archiveFileInfo, extractDirectory, cancellationToken); } progress.ReportCompleted(); }
public async Task DownloadExtractZipArchiveAsync(Download download, DirectoryInfo extractDirectory, DownloadProgress progress, CancellationToken cancellationToken) { var bytesTransferred = 0L; using var headResponse = await _options.HttpClient.SendAsync(new HttpRequestMessage (HttpMethod.Head, download.Archive.Url), cancellationToken); var contentLength = headResponse.Content.Headers.ContentLength ?? 0; var cacheFile = new FileInfo(Path.Combine(_options.CacheDirectory.FullName, download.Archive.Url.Segments.Last())); await using var cacheStream = new FileStream(cacheFile.FullName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); var stopwatch = Stopwatch.StartNew(); await using var httpStream = new HttpStream(download.Archive.Url, cacheStream, ownStream: false, CachePageSize, cached: null); httpStream.RangeDownloaded += (_, args) => { bytesTransferred += args.Length; progress.Report(new CopyProgress(stopwatch.Elapsed, 0, bytesTransferred, contentLength)); }; using var zipFile = new ZipFile(httpStream); var binaryRegex = _options.Binaries[(download.Product, download.Platform)];