/// <inheritdoc />
    public async Task <string> DownloadAsync(string packageFolder, IProgress <double>?progress, CancellationToken token = default)
    {
        // Wait for background sync operation.
        await _initialiseTask;

        using var tempDownloadDir = new TemporaryFolderAllocation();
        using var tempExtractDir  = new TemporaryFolderAllocation();
        var tempDownloadPath = Path.Combine(tempDownloadDir.FolderPath, Path.GetRandomFileName());

        var progressSlicer = new ProgressSlicer(progress);

        // Download Package
        var downloadSlice = progressSlicer.Slice(0.9f);
        await PackageResolver.DownloadPackageAsync(Version !, tempDownloadPath, new ReleaseMetadataVerificationInfo()
        {
            FolderPath = tempDownloadPath
        }, downloadSlice, token);

        // Extract package.
        var extractSlice     = progressSlicer.Slice(0.1f);
        var archiveExtractor = new SevenZipSharpExtractor();
        await archiveExtractor.ExtractPackageAsync(tempDownloadPath, tempExtractDir.FolderPath, extractSlice, token);

        // Copy all packages from download.
        return(WebDownloadablePackage.CopyPackagesFromExtractFolderToTargetDir(packageFolder, tempExtractDir.FolderPath, token));
    }
예제 #2
0
    /// <summary>
    /// Creates a web downloadable package from a NuGet source.
    /// </summary>
    /// <param name="pkg">The search result.</param>
    /// <param name="repository">The NuGet repository to use.</param>
    /// <param name="getReadme">If true, tries to pull readme from the server.</param>
    /// <param name="getReleaseNotes">If true, tries to pull release notes from the server.</param>
    public static async Task <WebDownloadablePackage> FromNuGetAsync(IPackageSearchMetadata pkg, INugetRepository repository, bool getReadme = false, bool getReleaseNotes = false)
    {
        var result = new WebDownloadablePackage()
        {
            Name      = !string.IsNullOrEmpty(pkg.Title) ? pkg.Title : pkg.Identity.Id,
            Source    = repository.FriendlyName,
            Id        = pkg.Identity.Id,
            Authors   = pkg.Authors,
            Submitter = new Submitter()
            {
                UserName = pkg.Authors
            },
            Description   = pkg.Description,
            Version       = pkg.Identity.Version,
            ProjectUri    = pkg.ProjectUrl,
            DownloadCount = pkg.DownloadCount,
            Tags          = pkg.Tags?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
        };

        var resolver = GetNuGetUpdateResolver(pkg, repository);

        result._url = new Uri((await resolver.GetDownloadUrlAsync(pkg.Identity.Version, new ReleaseMetadataVerificationInfo(), CancellationToken.None)) !);
        _           = InitNuGetAsyncData(result, pkg, repository, resolver, getReadme, getReleaseNotes);

        if (pkg.IconUrl != null)
        {
            result.Images = new[] { new DownloadableImage()
                                    {
                                        Uri = pkg.IconUrl
                                    } }
        }
        ;

        return(result);
    }
예제 #3
0
    private static void GameBananaAddChangelog(GameBananaMod modItem, WebDownloadablePackage package)
    {
        if (!string.IsNullOrEmpty(package.Changelog))
        {
            return;
        }

        var updates = modItem.Updates;

        if (updates is not {
            Count : > 0
        })
예제 #4
0
    private static void GameBananaAddImages(GameBananaMod file, WebDownloadablePackage package)
    {
        if (file.PreviewMedia?.Images == null)
        {
            return;
        }

        var gbImages = file.PreviewMedia.Images;

        if (gbImages.Length <= 0)
        {
            return;
        }

        var images     = new DownloadableImage[gbImages.Length];
        var imagesSpan = new SpanList <DownloadableImage>(images);
        var thumbsSpan = new DownloadableImageThumbnail[GameBananaPreviewImage.MaxThumbnailCount];

        foreach (var gbImage in gbImages)
        {
            var baseUri = new Uri($"{gbImage.BaseUrl}/", UriKind.Absolute);
            var image   = new DownloadableImage()
            {
                Uri     = new Uri(baseUri, gbImage.File),
                Caption = gbImage.Caption
            };

            var thumbs = new SpanList <DownloadableImageThumbnail>(thumbsSpan);
            if (!string.IsNullOrEmpty(gbImage.FileWidth100))
            {
                thumbs.Add(new DownloadableImageThumbnail(new Uri(baseUri, gbImage.FileWidth100), 100));
            }

            if (!string.IsNullOrEmpty(gbImage.FileWidth220))
            {
                thumbs.Add(new DownloadableImageThumbnail(new Uri(baseUri, gbImage.FileWidth220), 220));
            }

            if (!string.IsNullOrEmpty(gbImage.FileWidth530))
            {
                thumbs.Add(new DownloadableImageThumbnail(new Uri(baseUri, gbImage.FileWidth530), 530));
            }

            if (thumbs.Length > 0)
            {
                image.Thumbnails = thumbs.AsSpan.ToArray();
            }

            imagesSpan.Add(image);
        }

        package.Images = images;
    }
예제 #5
0
    /// <inheritdoc />
    public async Task <IEnumerable <IDownloadablePackage> > SearchAsync(string text, int skip = 0, int take = 50, CancellationToken token = default)
    {
        var searchResults = await GetSearchResults(text, skip, take, token);

        var result = new List <IDownloadablePackage>();

        foreach (var res in searchResults)
        {
            result.Add(await WebDownloadablePackage.FromNuGetAsync(res, _repository, true, true));
        }

        return(result);
    }
예제 #6
0
    private static void AddResultsFromRawFiles(GameBananaMod gbApiItem, ConcurrentBag <IDownloadablePackage> results)
    {
        if (gbApiItem.ManagerIntegrations == null || gbApiItem.Files == null)
        {
            return;
        }

        // Check manager integrations.
        var hasMultipleReloadedFiles = CheckIfHasMultipleReloadedFiles(gbApiItem.ManagerIntegrations);

        foreach (var integratedFile in gbApiItem.ManagerIntegrations)
        {
            var fileId       = integratedFile.Key;
            var integrations = integratedFile.Value;

            // Build items.
            foreach (var integration in integrations)
            {
                if (!integration.IsReloadedDownloadUrl().GetValueOrDefault())
                {
                    continue;
                }

                var    url  = new Uri(integration.GetReloadedDownloadUrl());
                var    file = gbApiItem.Files.First(x => x.Id == fileId);
                string fileName;
                if (hasMultipleReloadedFiles)
                {
                    fileName = !string.IsNullOrEmpty(file.Description) ?
                               $"{gbApiItem.Name!}: {file.Description}" :
                               $"{gbApiItem.Name!}: {file.FileName}";
                }
                else
                {
                    fileName = $"{gbApiItem.Name!}";
                }

                var package = new WebDownloadablePackage(url, false)
                {
                    Name           = fileName,
                    Description    = HtmlUtilities.ConvertToPlainText(gbApiItem.Description),
                    MarkdownReadme = Singleton <Converter> .Instance.Convert(gbApiItem.Description)
                };

                GameBananaAddCommon(gbApiItem, file, package);
                results.Add(package);
            }
        }
    }
예제 #7
0
    private static void GameBananaAddSubmitter(GameBananaMod result, WebDownloadablePackage package)
    {
        var gbSubmitter  = result.Submitter;
        var pkgSubmitter = new Submitter
        {
            UserName   = gbSubmitter.Name,
            JoinDate   = gbSubmitter.JoinDate,
            ProfileUrl = new Uri(gbSubmitter.ProfileUrl)
        };

        if (gbSubmitter.AvatarUrl != null)
        {
            pkgSubmitter.AvatarUrl = new Uri(gbSubmitter.AvatarUrl);
        }

        package.Submitter = pkgSubmitter;
    }
예제 #8
0
    private static void DownloadModAndExit(string downloadUrl)
    {
        if (downloadUrl.StartsWith($"{Constants.ReloadedProtocol}:", StringComparison.InvariantCultureIgnoreCase))
        {
            downloadUrl = downloadUrl.Substring(Constants.ReloadedProtocol.Length + 1);
        }

        var package   = new WebDownloadablePackage(new Uri(downloadUrl), true);
        var viewModel = new DownloadPackageViewModel(package, IoC.Get <LoaderConfig>());

        _ = viewModel.StartDownloadAsync();

        Actions.ShowFetchPackageDialog(viewModel);
        Actions.DisplayMessagebox(Resources.PackageDownloaderDownloadCompleteTitle.Get(), Resources.PackageDownloaderDownloadCompleteDescription.Get(), new Actions.DisplayMessageBoxParams()
        {
            Type            = Actions.MessageBoxType.Ok,
            StartupLocation = Actions.WindowStartupLocation.CenterScreen,
            Timeout         = TimeSpan.FromSeconds(8)
        });
    }
    /// <inheritdoc />
    public async Task <ModDependencyResolveResult> ResolveAsync(string packageId, Dictionary <string, object>?pluginData = null, CancellationToken token = default)
    {
        var searchResult = await _repository.FindDependencies(packageId, true, true, token);

        var result = new ModDependencyResolveResult();

        foreach (var dependency in searchResult.Dependencies)
        {
            var package    = dependency.Generic;
            var repository = dependency.Repository;
            result.FoundDependencies.Add(await WebDownloadablePackage.FromNuGetAsync(package, repository));
        }

        foreach (var notFound in searchResult.PackagesNotFound)
        {
            result.NotFoundDependencies.Add(notFound);
        }

        return(result);
    }
예제 #10
0
    private static void GameBananaAddAuthors(GameBananaMod result, WebDownloadablePackage package)
    {
        if (result.Credits == null)
        {
            return;
        }

        var authors = new List <string>();

        foreach (var creditCategory in result.Credits)
        {
            foreach (var credit in creditCategory.Value)
            {
                if (!string.IsNullOrEmpty(credit.Name))
                {
                    authors.Add(credit.Name);
                }
            }
        }

        package.Authors = string.Join(", ", authors);
    }
예제 #11
0
    private static async Task InitNuGetAsyncData(WebDownloadablePackage package, IPackageSearchMetadata pkg,
                                                 INugetRepository repository, NuGetUpdateResolver updateResolver, bool getReadme, bool getReleaseNotes)
    {
        bool canGetReadme = getReadme && pkg.ReadmeUrl != null;

        var tasks       = new Task[2 + Convert.ToInt32(canGetReadme) + Convert.ToInt32(getReleaseNotes)];
        int currentTask = 0;

        tasks[currentTask++] = Task.Run(async() => package.Published = await InitNuGetPublishedAsync(pkg, repository));
        tasks[currentTask++] = Task.Run(async() => package.FileSize = await InitNuGetFileSizeAsync(updateResolver, pkg));
        if (canGetReadme)
        {
            tasks[currentTask++] = Task.Run(async() => package.MarkdownReadme = await SharedHttpClient.CachedAndCompressed.GetStringAsync(pkg.ReadmeUrl));
        }

        if (getReleaseNotes)
        {
            tasks[currentTask++] = Task.Run(async() => package.Changelog = await InitNuGetReleaseNotes(pkg, repository));
        }

        await Task.WhenAll(tasks);
    }
예제 #12
0
 private static void GameBananaAddCommon(GameBananaMod modItem, GameBananaModFile file, WebDownloadablePackage package)
 {
     package.Source        = SourceName;
     package.FileSize      = file.FileSize.GetValueOrDefault();
     package.ProjectUri    = new Uri(modItem.LinkToModPage);
     package.LikeCount     = modItem.LikeCount;
     package.ViewCount     = modItem.ViewCount;
     package.DownloadCount = modItem.DownloadCount;
     package.Published     = file.DateAdded;
     GameBananaAddAuthors(modItem, package);
     GameBananaAddSubmitter(modItem, package);
     GameBananaAddImages(modItem, package);
     GameBananaAddChangelog(modItem, package);
 }