Example #1
0
        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);
        }
Example #2
0
        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);
        }