Ejemplo n.º 1
0
        private void AddPackages(SyndicationFeed feed,
                                 Uri root,
                                 string rootStoragePath,
                                 IEnumerable <IVsixPackage> packages)
        {
            // See https://msdn.microsoft.com/en-us/library/hh266717.aspx
            var items = new List <SyndicationItem>();

            var orderedPackages = packages
                                  .OrderBy(pkg => pkg.DisplayName)
                                  .ThenBy(pkg => pkg.Id)
                                  .ToArray();

            OnBackgroundProgress(new VsixFeedBuilderProgressArgs(0, orderedPackages.Length, "Starting"));

            for (var pkgIdx = 0; pkgIdx < orderedPackages.Length; pkgIdx++)
            {
                var pkg = orderedPackages[pkgIdx];

                // Possibly normalize the file name for the package,
                // visual studio does not like special characters in the file download urls so it is best to clear these out
                pkg.File = FileCleaner.NormalizePackageFileName(pkg.File);
                var pkgFileName = Path.GetFileName(pkg.File);

                OnBackgroundProgress(new VsixFeedBuilderProgressArgs(pkgIdx + 1, orderedPackages.Length, pkgFileName));

                // Schema: https://msdn.microsoft.com/en-us/library/dd393754(v=vs.100).aspx
                // Extension Schema: https://msdn.microsoft.com/en-us/library/dd393700(v=vs.100).aspx
                var item = new SyndicationItem
                {
                    Id              = pkg.Id,
                    Title           = new TextSyndicationContent(pkg.DisplayName),
                    Summary         = new TextSyndicationContent(pkg.Description),
                    PublishDate     = new DateTimeOffset(File.GetLastWriteTimeUtc(pkg.File)),
                    LastUpdatedTime = new DateTimeOffset(File.GetLastWriteTimeUtc(pkg.File))
                };

                // Create the subfolder for the package contents on the local system, ensure that the path exists
                var packageFolderPath = Path.Combine(rootStoragePath, pkg.Id);
                Directory.CreateDirectory(packageFolderPath);

                // Create a mapping between the vsix id and the file name by placing a simple file in the root
                FileCounter.SetIdToVsixFile(pkg.Id, pkgFileName, _configStorage);

                item.Authors.Add(new SyndicationPerson {
                    Name = pkg.Publisher
                });

                // If the configuration specifies that the downloads should be tracked then route the downloads
                // through the DownloadModule for tracking, if tracking is off then serve the static files directly
                // from the file-system
                item.Content = SyndicationContent.CreateUrlContent(_configGallery.TrackDownloads
                                                                   ? new Uri($"../api/download/{pkg.Id}/{pkgFileName}", UriKind.Relative)
                                                                   : root.MakeRelativeUri(new Uri(pkg.File)), "application/octet-stream");

                // Only use the first category found, the developer should put the most important category first anyways
                var category = pkg.Categories.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x));
                if (category != null)
                {
                    item.Categories.Add(new SyndicationCategory(category.Trim().ToTitleCase()));
                }

                if (pkg.TrySaveIcon(packageFolderPath, out Uri iconUri))
                {
                    item.Links.Add(new SyndicationLink(root.MakeRelativeUri(iconUri), "icon", "", "", 0));
                }

                if (pkg.TrySavePreviewImage(packageFolderPath, out Uri previewUri))
                {
                    item.Links.Add(new SyndicationLink(root.MakeRelativeUri(previewUri), "previewimage", "", "", 0));
                }

                // Displays the "More Info" link if set
                if (pkg.MoreInfoUrl.IsUrl())
                {
                    item.Links.Add(new SyndicationLink(new Uri(pkg.MoreInfoUrl), "alternate", "", "", 0)); // Must be set to "alternate", rest does not need to be set
                }
                // Displays the "Release Notes" link if set
                if (pkg.ReleaseNotes.IsUrl())
                {
                    item.Links.Add(new SyndicationLink(new Uri(pkg.ReleaseNotes), "releasenotes", "", "", 0));
                }

                // Add the extensions to the item
                AddExtensions(item, pkg);

                // Now save the item
                items.Add(item);
            }
            OnBackgroundProgress(new VsixFeedBuilderProgressArgs(orderedPackages.Length, orderedPackages.Length, "All done"));

            // Save all the items into the feed object
            feed.Items = items;
        }