public async Task <string> DownloadPackageAsync(string connectionID, RequestDownloadInfo requestInfo) { // cast RequestDownloadNuGetInfo info = (RequestDownloadNuGetInfo)requestInfo; // server response ServerResponse response = new ServerResponse() { payload = new Dictionary <string, string>() }; string _outputDirectory = $"{_environment.ContentRootPath}/wwwroot/{_configuration.GetValue<string>("DownloadPath")}"; // check if output directory exists if (!Directory.Exists(_outputDirectory)) { Directory.CreateDirectory(_outputDirectory); } string connectionSubName = $"nuget-{connectionID}-{DateTime.Now:yyyymmddHHmmss}"; string connectionDirectory = $"{_outputDirectory}/{connectionSubName}"; Directory.CreateDirectory(connectionDirectory); // send message response.payload.Clear(); response.payload.Add("Resource", $"{connectionSubName} created."); await _downloadHubContext.Clients.Client(connectionID).Response(response); ILogger logger = NullLogger.Instance; CancellationToken cancellationToken = CancellationToken.None; SourceCacheContext cache = new SourceCacheContext(); SourceRepository repository = Repository.Factory.GetCoreV3(info.repository); FindPackageByIdResource resource = await repository.GetResourceAsync <FindPackageByIdResource>(); // set all parent packages for (int i = 0; i < info.packageList.Count(); i++) { string packageId = info.packageList.ElementAt(i).packageId; string packageVersionValue = info.packageList.ElementAt(i).packageVersion; NuGetVersion packageVersion = new NuGetVersion(packageVersionValue); PackageInfo package = new PackageInfo { packageId = packageId, packageVersion = packageVersion }; if (package.packageVersion != null) { _downloadQueue.Enqueue(package); } else { FloatRange floatRange = null; if (info.preReleased == true) { // include pre-release floatRange = new FloatRange(NuGetVersionFloatBehavior.AbsoluteLatest); } else { // released floatRange = new FloatRange(NuGetVersionFloatBehavior.Major); } FloatRange fr = new FloatRange(NuGetVersionFloatBehavior.Major); VersionRange range = new VersionRange(floatRange: fr); package = await GetBestMatchPackageVersionsAsync(repository, packageId, range); } _downloadQueue.Enqueue(package); } // download counter int download_counter = 0; while (_downloadQueue.Count > 0) { PackageInfo package = _downloadQueue.Dequeue(); string validFileName = FileUtil.GetValidFileName(package.packageId); string packageFilePath = $"{connectionDirectory}/{validFileName}.{package.packageVersion}.nupkg"; if (_cacheDownloadedFileName.Contains($"{package.packageId}-{package.packageVersion}")) { continue; } else { _cacheDownloadedFileName.Add($"{package.packageId}-{package.packageVersion}"); } using FileStream packageStream = new FileStream(packageFilePath, FileMode.Create); await resource.CopyNupkgToStreamAsync( package.packageId, package.packageVersion, packageStream, cache, logger, cancellationToken); download_counter++; // starting if (download_counter == 1) { // send message response.payload.Clear(); response.payload.Add("DownloadCounter", $"starting..."); await _downloadHubContext.Clients.Client(connectionID).Response(response); } // check if send message is needed if (download_counter % MessageFrequency == 0) { // send message response.payload.Clear(); response.payload.Add("DownloadCounter", $"{download_counter}, {((float)download_counter / (float)(download_counter + _downloadQueue.Count)) * 100.0f}%"); await _downloadHubContext.Clients.Client(connectionID).Response(response); } Console.WriteLine($"Downloaded package {package.packageId} {package.packageVersion}"); using PackageArchiveReader packageReader = new PackageArchiveReader(packageStream); NuspecReader nuspecReader = await packageReader.GetNuspecReaderAsync(cancellationToken); Console.WriteLine($"Tags: {nuspecReader.GetTags()}"); Console.WriteLine($"Description: {nuspecReader.GetDescription()}"); using PackageArchiveReader reader = new PackageArchiveReader(packageStream); NuspecReader nuspec = reader.NuspecReader; Console.WriteLine($"ID: {nuspec.GetId()}"); Console.WriteLine($"Version: {nuspec.GetVersion()}"); Console.WriteLine($"Description: {nuspec.GetDescription()}"); Console.WriteLine($"Authors: {nuspec.GetAuthors()}"); if (info.withDependency == false) { Console.WriteLine("\nDependencies download is not need."); continue; } Console.WriteLine("\nStart download dependencies:"); foreach (var dependencyGroup in nuspec.GetDependencyGroups()) { Console.WriteLine($" - {dependencyGroup.TargetFramework.GetFrameworkString()}"); // check target framework if (!info.targetFramework.Contains("all", StringComparer.InvariantCultureIgnoreCase) && !info.targetFramework.Contains(dependencyGroup.TargetFramework.GetFrameworkString(), StringComparer.InvariantCultureIgnoreCase)) { Console.WriteLine($" -- {dependencyGroup.TargetFramework.GetFrameworkString()} not match target framework."); continue; } foreach (var dependency in dependencyGroup.Packages) { Console.WriteLine($" > {dependency.Id} {dependency.VersionRange}"); PackageInfo dependencyPackage = await GetBestMatchPackageVersionsAsync(repository, dependency.Id, dependency.VersionRange); Console.WriteLine($" -- best match version: {dependency.Id} {dependencyPackage.packageVersion}"); _downloadQueue.Enqueue(dependencyPackage); } } } // send message response.payload.Clear(); response.payload.Add("DownloadCounter", $"{download_counter}, {((float)download_counter / (float)(download_counter + _downloadQueue.Count)) * 100.0f}%"); await _downloadHubContext.Clients.Client(connectionID).Response(response); string zipFileName = $"{_outputDirectory}/{connectionSubName}.zip"; bool result = _compressService.CompressDirectory(connectionDirectory, zipFileName); if (result == true) { string readableSize = FileUtil.getFileHumanReadableSize(zipFileName); // send message response.payload.Clear(); response.payload.Add("CompressStatus", $"compressed ok, file sieze: {readableSize}."); await _downloadHubContext.Clients.Client(connectionID).Response(response); } else { // send message response.payload.Clear(); response.payload.Add("CompressStatus", $"compressed failed."); await _downloadHubContext.Clients.Client(connectionID).Response(response); } // delete directory Directory.Delete(connectionDirectory, true); return(connectionSubName); }
public async Task <string> DownloadPackageAsync(string connectionID, RequestDownloadInfo requestInfo) { // cast RequestDownloadNpmInfo info = (RequestDownloadNpmInfo)requestInfo; // server response ServerResponse response = new ServerResponse() { payload = new Dictionary <string, string>() }; string _outputDirectory = $"{_environment.ContentRootPath}/wwwroot/{_configuration.GetValue<string>("DownloadPath")}"; // check if output directory exists if (!Directory.Exists(_outputDirectory)) { Directory.CreateDirectory(_outputDirectory); } string connectionSubName = $"npm-{connectionID}-{DateTime.Now:yyyymmddHHmmss}"; string connectionDirectory = $"{_outputDirectory}/{connectionSubName}"; Directory.CreateDirectory(connectionDirectory); // send message response.payload.Clear(); response.payload.Add("Resource", $"{connectionSubName} created."); await _downloadHubContext.Clients.Client(connectionID).Response(response); // set all parent packages for (int i = 0; i < info.packageList.Count(); i++) { string packageId = info.packageList.ElementAt(i).packageId; string packageVersionValue = info.packageList.ElementAt(i).packageVersion; string setValue = $"{packageId}-{packageVersionValue}"; PackageInfo packageInfo = await GetPackageInfoByStringAsync(packageId, packageVersionValue, info.preReleased, info.repository); if (packageInfo != null) { packageInfo.depth = 0; _downloadQueue.Enqueue(packageInfo); _cacheForPackageVersion.Add(setValue); } } // download counter int download_counter = 0; while (_downloadQueue.Count > 0) { PackageInfo package = _downloadQueue.Dequeue(); string validFileName = FileUtil.GetValidFileName(package.packageId); string packageFilePath = $"{connectionDirectory}/{validFileName}-{package.packageVersion}.tgz"; if (_cacheDownloadedFileName.Contains($"{package.packageId}-{package.packageVersion}")) { continue; } else { _cacheDownloadedFileName.Add($"{package.packageId}-{package.packageVersion}"); } // Get specific package and version PackageVersion packageVerion = await GetPackageVersionAsync(info.repository, package.packageId, package.packageVersion); // Downlaod package if (packageVerion != null && packageVerion.dist != null && packageVerion.dist.tarball != null) { using var packageStream = new FileStream(packageFilePath, FileMode.Create); using var httpStream = await new HttpClient().GetStreamAsync(packageVerion.dist.tarball); await httpStream.CopyToAsync(packageStream); } else { Console.WriteLine($"Error: tarball url is null, {package.packageId}"); continue; } download_counter++; // starting if (download_counter == 1) { // send message response.payload.Clear(); response.payload.Add("DownloadCounter", $"starting..."); await _downloadHubContext.Clients.Client(connectionID).Response(response); } // check if send message is needed if (download_counter % MessageFrequency == 0) { Console.WriteLine($"DownloadCounter: {download_counter}, download queue: {_downloadQueue.Count}," + $" file: {_cacheDownloadedFileName.Count}, parse: {_cacheForPackageVersion.Count}," + $" versions: {_cacheForVersions.Count}, percent: {((float)download_counter / (float)(download_counter + _downloadQueue.Count)) * 100.0f} %"); // send message response.payload.Clear(); response.payload.Add("DownloadCounter", $"{download_counter}, {((float)download_counter / (float)(download_counter + _downloadQueue.Count)) * 100.0f}%"); await _downloadHubContext.Clients.Client(connectionID).Response(response); } Console.WriteLine($"Downloaded package {package.packageId} {package.packageVersion}"); //Console.WriteLine($"Author: {packageVerion.author}"); Console.WriteLine($"Description: {packageVerion.description}"); if (info.withDependency == false) { Console.WriteLine("\nDependencies download is not need."); continue; } Console.WriteLine("\nStart download dependencies:"); if (packageVerion.dependencies != null && (info.dependencyDepth == -1 || package.depth < info.dependencyDepth)) { foreach (var dependencyGroup in packageVerion.dependencies) { string packageId = dependencyGroup.Key; string packageVersionValue = dependencyGroup.Value; string setValue = $"{packageId}-{packageVersionValue}"; if (_cacheForPackageVersion.Contains(setValue) == true) { Console.WriteLine($"Already parsed: {setValue}"); continue; } PackageInfo packageInfo = await GetPackageInfoByStringAsync(packageId, packageVersionValue, info.preReleased, info.repository); if (packageInfo != null) { packageInfo.depth = package.depth + 1; if (info.dependencyDepth == -1 || packageInfo.depth <= info.dependencyDepth) { _downloadQueue.Enqueue(packageInfo); _cacheForPackageVersion.Add(setValue); } } } } if (info.withDevDependency == false) { Console.WriteLine("\nDev dependencies download is not need."); continue; } Console.WriteLine("\nStart download dev dependencies:"); if (packageVerion.devDependencies != null && (info.dependencyDepth == -1 || package.depth < info.dependencyDepth)) { foreach (var dependencyGroup in packageVerion.devDependencies) { string packageId = dependencyGroup.Key; string packageVersionValue = dependencyGroup.Value; string setValue = $"{packageId}-{packageVersionValue}"; if (_cacheForPackageVersion.Contains(setValue) == true) { Console.WriteLine($"Already parsed: {setValue}"); continue; } PackageInfo packageInfo = await GetPackageInfoByStringAsync(packageId, packageVersionValue, info.preReleased, info.repository); if (packageInfo != null) { packageInfo.depth = package.depth + 1; if (info.dependencyDepth == -1 || packageInfo.depth <= info.dependencyDepth) { _downloadQueue.Enqueue(packageInfo); _cacheForPackageVersion.Add(setValue); } } } } } Console.WriteLine($"DownloadCounter: {download_counter}, download queue: {_downloadQueue.Count}," + $" file: {_cacheDownloadedFileName.Count}, parse: {_cacheForPackageVersion.Count}," + $" versions: {_cacheForVersions.Count}, percent: {((float)download_counter / (float)(download_counter + _downloadQueue.Count)) * 100.0f} %"); // send message response.payload.Clear(); response.payload.Add("DownloadCounter", $"{download_counter}, {((float)download_counter / (float)(download_counter + _downloadQueue.Count)) * 100.0f}%"); await _downloadHubContext.Clients.Client(connectionID).Response(response); string zipFileName = $"{_outputDirectory}/{connectionSubName}.zip"; bool result = _compressService.CompressDirectory(connectionDirectory, zipFileName); if (result == true) { string readableSize = FileUtil.getFileHumanReadableSize(zipFileName); // send message response.payload.Clear(); response.payload.Add("CompressStatus", $"compressed ok, file sieze: {readableSize}."); await _downloadHubContext.Clients.Client(connectionID).Response(response);; } else { // send message response.payload.Clear(); response.payload.Add("CompressStatus", $"compressed failed."); await _downloadHubContext.Clients.Client(connectionID).Response(response); } // delete directory Directory.Delete(connectionDirectory, true); return(connectionSubName); }